* [PATCH 0/2] Hexagon: fix icinva
@ 2026-08-19 4:53 Brian Cain
2026-08-19 4:53 ` [PATCH 1/2] target/hexagon: invalidate translated code for user icinva Brian Cain
2026-08-19 4:53 ` [PATCH 2/2] tests/tcg/hexagon: add icinva test Brian Cain
0 siblings, 2 replies; 8+ messages in thread
From: Brian Cain @ 2026-08-19 4:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier, Brian Cain
icinva (icache invalidate addr) instruction was a nop, but this behavior
is not correct for userspace.
Also note that this checkpatch issue was bypassed because I believe
it's appropriate/acceptable to check the "guest" page size in a TCG test
case.
Patch 1/2 has no obvious style problems and is ready for submission.
2/2 Checking commit ea94abbfc875 (tests/tcg/hexagon: add icinva test)
ERROR: use qemu_real_host_page_size() instead of sysconf(_SC_PAGESIZE)
#74: FILE: tests/tcg/hexagon/icinva.c:56:
+ long pagesize = sysconf(_SC_PAGESIZE);
Brian Cain (2):
target/hexagon: invalidate translated code for user icinva
tests/tcg/hexagon: add icinva test
target/hexagon/gen_tcg.h | 9 ++++
target/hexagon/helper.h | 4 ++
target/hexagon/op_helper.c | 15 +++++++
target/hexagon/translate.c | 3 ++
tests/tcg/hexagon/icinva.c | 71 +++++++++++++++++++++++++++++++
tests/tcg/hexagon/Makefile.target | 2 +
6 files changed, 104 insertions(+)
create mode 100644 tests/tcg/hexagon/icinva.c
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] target/hexagon: invalidate translated code for user icinva
2026-08-19 4:53 [PATCH 0/2] Hexagon: fix icinva Brian Cain
@ 2026-08-19 4:53 ` Brian Cain
2026-08-20 18:37 ` Pierrick Bouvier
2026-08-19 4:53 ` [PATCH 2/2] tests/tcg/hexagon: add icinva test Brian Cain
1 sibling, 1 reply; 8+ messages in thread
From: Brian Cain @ 2026-08-19 4:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier, Brian Cain
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.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
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) ||
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] tests/tcg/hexagon: add icinva test
2026-08-19 4:53 [PATCH 0/2] Hexagon: fix icinva Brian Cain
2026-08-19 4:53 ` [PATCH 1/2] target/hexagon: invalidate translated code for user icinva Brian Cain
@ 2026-08-19 4:53 ` Brian Cain
2026-08-20 19:11 ` Pierrick Bouvier
1 sibling, 1 reply; 8+ messages in thread
From: Brian Cain @ 2026-08-19 4:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier, Brian Cain
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
tests/tcg/hexagon/icinva.c | 71 +++++++++++++++++++++++++++++++
tests/tcg/hexagon/Makefile.target | 2 +
2 files changed, 73 insertions(+)
create mode 100644 tests/tcg/hexagon/icinva.c
diff --git a/tests/tcg/hexagon/icinva.c b/tests/tcg/hexagon/icinva.c
new file mode 100644
index 00000000000..0252e0f899d
--- /dev/null
+++ b/tests/tcg/hexagon/icinva.c
@@ -0,0 +1,71 @@
+/*
+ * Test that icinva ends the current translation block.
+ *
+ * icinva only invalidates the emulator's cached translation for a
+ * code range; it doesn't retroactively fix up code that has already
+ * been decoded as part of the still-executing translation block. If
+ * icinva doesn't force a new TB to start right after it, a packet
+ * patched via a store immediately before icinva (with no
+ * change-of-flow in between) still runs the stale decode baked into
+ * the current TB instead of the freshly-patched instruction.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int err;
+
+#include "hex_test.h"
+
+/* Encoding of "r0 = #99" */
+#define ICINVA_NEW_INSN 0x7800cc60
+
+static uint32_t __attribute__((noinline)) test_icinva_smc(void)
+{
+ uint32_t result;
+
+ /*
+ * r1 = address of the "patch_slot" packet below (1:)
+ * Overwrite it with the "r0 = #99" encoding, invalidate the
+ * icache for that address, then fall straight through into it
+ * with no intervening jump/call.
+ */
+ asm volatile(
+ "r1 = ##1f\n"
+ "r2 = ##%[newinsn]\n"
+ "memw(r1) = r2\n"
+ "icinva(r1)\n"
+ "1:\n"
+ " r0 = #11\n"
+ "%[out] = r0\n"
+ : [out] "=r"(result)
+ : [newinsn] "i"(ICINVA_NEW_INSN)
+ : "r0", "r1", "r2", "memory"
+ );
+
+ return result;
+}
+
+int main(void)
+{
+ long pagesize = sysconf(_SC_PAGESIZE);
+ uintptr_t page = (uintptr_t)test_icinva_smc & ~(pagesize - 1);
+ uint32_t result;
+
+ if (mprotect((void *)page, 2 * pagesize,
+ PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
+ perror("mprotect");
+ return 1;
+ }
+
+ result = test_icinva_smc();
+ check32(result, 99);
+
+ puts(err ? "FAIL" : "PASS");
+ return err;
+}
diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target
index 61adf6356e4..27268e66b7a 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -60,6 +60,7 @@ HEX_TESTS += invalid-encoding
HEX_TESTS += multiple-writes
HEX_TESTS += unaligned_pc
HEX_TESTS += unaligned_data
+HEX_TESTS += icinva
HEX_TESTS += test_abs
HEX_TESTS += test_bitcnt
@@ -103,6 +104,7 @@ circ: circ.c hex_test.h
dual_stores: dual_stores.c hex_test.h
fpstuff: fpstuff.c hex_test.h
hex_sigsegv: hex_sigsegv.c hex_test.h
+icinva: icinva.c hex_test.h
load_align: load_align.c hex_test.h
load_unpack: load_unpack.c hex_test.h
mem_noshuf_exception: mem_noshuf_exception.c hex_test.h
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] target/hexagon: invalidate translated code for user icinva
2026-08-19 4:53 ` [PATCH 1/2] target/hexagon: invalidate translated code for user icinva Brian Cain
@ 2026-08-20 18:37 ` Pierrick Bouvier
2026-08-20 19:00 ` Brian Cain
0 siblings, 1 reply; 8+ messages in thread
From: Pierrick Bouvier @ 2026-08-20 18:37 UTC (permalink / raw)
To: Brian Cain, qemu-devel
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?
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> 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) ||
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] target/hexagon: invalidate translated code for user icinva
2026-08-20 18:37 ` Pierrick Bouvier
@ 2026-08-20 19:00 ` Brian Cain
2026-08-20 19:10 ` Pierrick Bouvier
2026-08-20 23:40 ` Richard Henderson
0 siblings, 2 replies; 8+ messages in thread
From: Brian Cain @ 2026-08-20 19:00 UTC (permalink / raw)
To: Pierrick Bouvier, qemu-devel
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.
>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
>> ---
>> 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) ||
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] target/hexagon: invalidate translated code for user icinva
2026-08-20 19:00 ` Brian Cain
@ 2026-08-20 19:10 ` Pierrick Bouvier
2026-08-20 23:40 ` Richard Henderson
1 sibling, 0 replies; 8+ messages in thread
From: Pierrick Bouvier @ 2026-08-20 19:10 UTC (permalink / raw)
To: Brian Cain, qemu-devel
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 <brian.cain@oss.qualcomm.com>
>>> ---
>>> 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 <pierrick.bouvier@oss.qualcomm.com>
Regards,
Pierrick
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] tests/tcg/hexagon: add icinva test
2026-08-19 4:53 ` [PATCH 2/2] tests/tcg/hexagon: add icinva test Brian Cain
@ 2026-08-20 19:11 ` Pierrick Bouvier
0 siblings, 0 replies; 8+ messages in thread
From: Pierrick Bouvier @ 2026-08-20 19:11 UTC (permalink / raw)
To: Brian Cain, qemu-devel
On 8/18/2026 9:53 PM, Brian Cain wrote:
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> tests/tcg/hexagon/icinva.c | 71 +++++++++++++++++++++++++++++++
> tests/tcg/hexagon/Makefile.target | 2 +
> 2 files changed, 73 insertions(+)
> create mode 100644 tests/tcg/hexagon/icinva.c
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] target/hexagon: invalidate translated code for user icinva
2026-08-20 19:00 ` Brian Cain
2026-08-20 19:10 ` Pierrick Bouvier
@ 2026-08-20 23:40 ` Richard Henderson
1 sibling, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2026-08-20 23:40 UTC (permalink / raw)
To: qemu-devel
On 8/20/26 12:00, 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.
We do the same in user mode, trapping the stores via read-only pages. See
handle_sigsegv_accerr_write and page_unprotect.
So why do you believe that you need to invalidate pages manually here?
r~
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-20 23:41 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19 4:53 [PATCH 0/2] Hexagon: fix icinva Brian Cain
2026-08-19 4:53 ` [PATCH 1/2] target/hexagon: invalidate translated code for user icinva Brian Cain
2026-08-20 18:37 ` Pierrick Bouvier
2026-08-20 19:00 ` Brian Cain
2026-08-20 19:10 ` Pierrick Bouvier
2026-08-20 23:40 ` Richard Henderson
2026-08-19 4:53 ` [PATCH 2/2] tests/tcg/hexagon: add icinva test Brian Cain
2026-08-20 19:11 ` Pierrick Bouvier
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.