On 8/20/2026 12:00 PM, Brian Cain wrote:
> 
> On 8/20/2026 1:37 PM, Pierrick Bouvier wrote:
>> On 8/18/2026 9:53 PM, Brian Cain wrote:
>>> Route linux-user icinva through a helper that invalidates the addressed
>>> icache line under mmap_lock
>>>
>>> For system mode icinva has nothing left to do, so it stays a nop.
>>>
>> Why does system mode icinva is a nop?
>> Shouldn't we invalidate translated code also?
> 
> The normal behavior of instruction translation in QEMU is conservative
> relative to the ISA constraint.  QEMU will invalidate translated blocks
> that become dirty/stale from a store instruction, so icinva can't flush
> anything: it's already flushed.
>

I see, it's related to the fact we emulate mmu in system mode.

>>> Signed-off-by: Brian Cain <[email protected]>
>>> ---
>>>   target/hexagon/gen_tcg.h   |  9 +++++++++
>>>   target/hexagon/helper.h    |  4 ++++
>>>   target/hexagon/op_helper.c | 15 +++++++++++++++
>>>   target/hexagon/translate.c |  3 +++
>>>   4 files changed, 31 insertions(+)
>>>
>>> diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
>>> index 40e03781d36..1d25391282a 100644
>>> --- a/target/hexagon/gen_tcg.h
>>> +++ b/target/hexagon/gen_tcg.h
>>> @@ -497,8 +497,17 @@
>>>       do { RsV = RsV; } while (0)
>>>   #define fGEN_TCG_Y2_dccleana(SHORTCODE) \
>>>       do { RsV = RsV; } while (0)
>>> +
>>> +#ifdef CONFIG_USER_ONLY
>>> +#define fGEN_TCG_Y2_icinva(SHORTCODE) \
>>> +    gen_helper_insn_cache_op(tcg_env, RsV, \
>>> +                             tcg_constant_tl(insn->slot), \
>>> +                             tcg_constant_tl(ctx->mem_idx), \
>>> +                             tcg_constant_tl(ctx->pkt.pc))
>>> +#else
>>>   #define fGEN_TCG_Y2_icinva(SHORTCODE) \
>>>       do { RsV = RsV; } while (0)
>>> +#endif
>>>     /*
>>>    * allocframe(#uiV)
>>> diff --git a/target/hexagon/helper.h b/target/hexagon/helper.h
>>> index 78dc28ca9e5..a5a5c123533 100644
>>> --- a/target/hexagon/helper.h
>>> +++ b/target/hexagon/helper.h
>>> @@ -113,6 +113,10 @@ DEF_HELPER_FLAGS_4(gvec_sabsdiff_w,
>>> TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
>>>   DEF_HELPER_FLAGS_4(gvec_uabsdiff_b, TCG_CALL_NO_RWG, void, ptr,
>>> ptr, ptr, i32)
>>>   DEF_HELPER_FLAGS_4(gvec_uabsdiff_h, TCG_CALL_NO_RWG, void, ptr,
>>> ptr, ptr, i32)
>>>   +#if defined(CONFIG_USER_ONLY)
>>> +DEF_HELPER_5(insn_cache_op, void, env, i32, int, int, i32)
>>> +#endif
>>> +
>>>   #if !defined(CONFIG_USER_ONLY)
>>>   DEF_HELPER_3(raise_stack_overflow, void, env, i32, i32)
>>>   DEF_HELPER_2(swi, void, env, i32)
>>> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
>>> index 23894ff3d28..84f5564b1e6 100644
>>> --- a/target/hexagon/op_helper.c
>>> +++ b/target/hexagon/op_helper.c
>>> @@ -23,6 +23,9 @@
>>>   #include "qemu/main-loop.h"
>>>   #include "cpu.h"
>>>   #include "exec/helper-proto.h"
>>> +#include "exec/mmap-lock.h"
>>> +#include "exec/target_page.h"
>>> +#include "exec/translation-block.h"
>>>   #include "fpu/softfloat.h"
>>>   #include "exec/cpu-interrupt.h"
>>>   #include "internal.h"
>>> @@ -311,6 +314,18 @@ int32_t HELPER(vacsh_pred)(CPUHexagonState *env,
>>>       return PeV;
>>>   }
>>>   +#ifdef CONFIG_USER_ONLY
>>> +void HELPER(insn_cache_op)(CPUHexagonState *env, target_ulong RsV,
>>> +                           int slot, int mmu_idx, target_ulong PC)
>>> +{
>>> +    target_ulong start = RsV & ~31;
>>> +
>>> +    mmap_lock();
>>> +    tb_invalidate_phys_range(env_cpu(env), start, start + 31);
>>> +    mmap_unlock();
>>> +}
>>> +#endif
>>> +
>>>   int64_t HELPER(cabacdecbin_val)(int64_t RssV, int64_t RttV)
>>>   {
>>>       int64_t RddV = 0;
>>> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
>>> index 06a8159d283..1560c412732 100644
>>> --- a/target/hexagon/translate.c
>>> +++ b/target/hexagon/translate.c
>>> @@ -354,6 +354,9 @@ static bool pkt_ends_tb(Packet *pkt)
>>>       if (pkt->pkt_has_cof) {
>>>           return true;
>>>       }
>>> +    if (check_for_attrib(pkt, A_ICFLUSHOP)) {
>>> +        return true;
>>> +    }
>>>   #ifndef CONFIG_USER_ONLY
>>>       /* System mode instructions that end TLB */
>>>       if (check_for_opcode(pkt, Y2_swi) ||


Reviewed-by: Pierrick Bouvier <[email protected]>

Regards,
Pierrick

Reply via email to