* [PATCH 1/8] hw/hexagon: register the V68N_1024 machine
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:36 ` Pierrick Bouvier
2026-09-03 18:56 ` [PATCH 2/8] target/hexagon: read BADVA as an alias of BADVA0/1 Brian Cain
` (6 subsequent siblings)
7 siblings, 1 reply; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
This DSP definition file was present but not referenced. Also: add a
'sim' alias for this machine to indicate a recent machine with
memory-map resembling that used by 'hexagon-sim'.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
hw/hexagon/hexagon_dsp.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index 5b2b6e312b6..ff110234b09 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -29,6 +29,7 @@
#include "semihosting/semihost.h"
#include "machine_cfg_v66g_1024.h.inc"
+#include "machine_cfg_v68n_1024.h.inc"
#define TYPE_HEXAGON_DSP_MACHINE "hexagon-dsp-machine"
OBJECT_DECLARE_SIMPLE_TYPE(HexagonDspMachineState, HEXAGON_DSP_MACHINE)
@@ -181,6 +182,23 @@ static void v66g_1024_init(ObjectClass *oc, const void *data)
mc->default_cpus = 4;
}
+static void v68n_1024_config_init(MachineState *machine)
+{
+ hexagon_common_init(machine, v68_rev, &v68n_1024);
+}
+
+static void v68n_1024_init(ObjectClass *oc, const void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->desc = "Hexagon V68N_1024";
+ mc->alias = "sim";
+ mc->init = v68n_1024_config_init;
+ init_mc(mc);
+ mc->default_cpu_type = TYPE_HEXAGON_CPU_V68;
+ mc->default_cpus = 6;
+}
+
static const TypeInfo hexagon_machine_types[] = {
{
.name = TYPE_HEXAGON_COMMON_MACHINE,
@@ -199,6 +217,11 @@ static const TypeInfo hexagon_machine_types[] = {
.parent = TYPE_HEXAGON_DSP_MACHINE,
.class_init = v66g_1024_init,
},
+ {
+ .name = MACHINE_TYPE_NAME("V68N_1024"),
+ .parent = TYPE_HEXAGON_DSP_MACHINE,
+ .class_init = v68n_1024_init,
+ },
};
DEFINE_TYPES(hexagon_machine_types)
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 1/8] hw/hexagon: register the V68N_1024 machine
2026-09-03 18:56 ` [PATCH 1/8] hw/hexagon: register the V68N_1024 machine Brian Cain
@ 2026-09-03 19:36 ` Pierrick Bouvier
0 siblings, 0 replies; 20+ messages in thread
From: Pierrick Bouvier @ 2026-09-03 19:36 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Philippe Mathieu-Daudé
On 9/3/2026 11:56 AM, Brian Cain wrote:
> This DSP definition file was present but not referenced. Also: add a
> 'sim' alias for this machine to indicate a recent machine with
> memory-map resembling that used by 'hexagon-sim'.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> hw/hexagon/hexagon_dsp.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 2/8] target/hexagon: read BADVA as an alias of BADVA0/1
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
2026-09-03 18:56 ` [PATCH 1/8] hw/hexagon: register the V68N_1024 machine Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:36 ` Pierrick Bouvier
2026-09-03 18:56 ` [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts Brian Cain
` (5 subsequent siblings)
7 siblings, 1 reply; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
BADVA is sort of a virtual register: it reads back as either BADVA0
or BADVA1, selected by SSR[BVS]. sreg_read() instead returned the
separate copy that set_badva_regs() stores in t_sreg[HEX_SREG_BADVA].
Guest code that writes BADVA0/BADVA1 directly was reading back a stale BADVA.
Uncovered by the h2 hypervisor kernel/mem/tlbmiss test.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 71555a7ba36..5d64c5523bb 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1889,6 +1889,13 @@ static inline QEMU_ALWAYS_INLINE uint32_t sreg_read(CPUHexagonState *env,
HexagonCPU *cpu;
g_assert(bql_locked());
+ if (reg == HEX_SREG_BADVA) {
+ uint32_t ssr = env->t_sreg[HEX_SREG_SSR];
+ if (GET_SSR_FIELD(SSR_BVS, ssr)) {
+ return env->t_sreg[HEX_SREG_BADVA1];
+ }
+ return env->t_sreg[HEX_SREG_BADVA0];
+ }
if (reg < HEX_SREG_GLB_START) {
return env->t_sreg[reg];
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 2/8] target/hexagon: read BADVA as an alias of BADVA0/1
2026-09-03 18:56 ` [PATCH 2/8] target/hexagon: read BADVA as an alias of BADVA0/1 Brian Cain
@ 2026-09-03 19:36 ` Pierrick Bouvier
0 siblings, 0 replies; 20+ messages in thread
From: Pierrick Bouvier @ 2026-09-03 19:36 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Philippe Mathieu-Daudé
On 9/3/2026 11:56 AM, Brian Cain wrote:
> BADVA is sort of a virtual register: it reads back as either BADVA0
> or BADVA1, selected by SSR[BVS]. sreg_read() instead returned the
> separate copy that set_badva_regs() stores in t_sreg[HEX_SREG_BADVA].
>
> Guest code that writes BADVA0/BADVA1 directly was reading back a stale BADVA.
>
> Uncovered by the h2 hypervisor kernel/mem/tlbmiss test.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/op_helper.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
2026-09-03 18:56 ` [PATCH 1/8] hw/hexagon: register the V68N_1024 machine Brian Cain
2026-09-03 18:56 ` [PATCH 2/8] target/hexagon: read BADVA as an alias of BADVA0/1 Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:36 ` Pierrick Bouvier
2026-09-04 13:30 ` Philippe Mathieu-Daudé
2026-09-03 18:56 ` [PATCH 4/8] hw/intc: name the L2VIC edge trigger check Brian Cain
` (4 subsequent siblings)
7 siblings, 2 replies; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
hex_interrupt_update() used cpu_resume() to make a halted vCPU notice a
newly pending interrupt. cpu_resume() is meant for a vCPU stopped by the
vm-state machinery: besides kicking the thread it clears cpu->stop and
cpu->stopped, and resets exception_index to -1. Clearing the stop flags
can undo a pause requested via the monitor or by migration, and resetting
exception_index discards an exception the vCPU had already latched.
Only the kick is wanted here, so call qemu_cpu_kick() directly.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/hex_interrupts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/hexagon/hex_interrupts.c b/target/hexagon/hex_interrupts.c
index 7dde1294b2e..2b2834af95f 100644
--- a/target/hexagon/hex_interrupts.c
+++ b/target/hexagon/hex_interrupts.c
@@ -441,7 +441,7 @@ void hex_interrupt_update(CPUHexagonState *env)
const int exe_mode = get_exe_mode(hex_env);
if (exe_mode != HEX_EXE_MODE_OFF) {
cpu_interrupt(cs, CPU_INTERRUPT_SWI);
- cpu_resume(cs);
+ qemu_cpu_kick(cs);
}
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts
2026-09-03 18:56 ` [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts Brian Cain
@ 2026-09-03 19:36 ` Pierrick Bouvier
2026-09-04 13:30 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 20+ messages in thread
From: Pierrick Bouvier @ 2026-09-03 19:36 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Philippe Mathieu-Daudé
On 9/3/2026 11:56 AM, Brian Cain wrote:
> hex_interrupt_update() used cpu_resume() to make a halted vCPU notice a
> newly pending interrupt. cpu_resume() is meant for a vCPU stopped by the
> vm-state machinery: besides kicking the thread it clears cpu->stop and
> cpu->stopped, and resets exception_index to -1. Clearing the stop flags
> can undo a pause requested via the monitor or by migration, and resetting
> exception_index discards an exception the vCPU had already latched.
>
> Only the kick is wanted here, so call qemu_cpu_kick() directly.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/hex_interrupts.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts
2026-09-03 18:56 ` [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts Brian Cain
2026-09-03 19:36 ` Pierrick Bouvier
@ 2026-09-04 13:30 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-04 13:30 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Pierrick Bouvier
On 3/9/26 20:56, Brian Cain wrote:
> hex_interrupt_update() used cpu_resume() to make a halted vCPU notice a
> newly pending interrupt. cpu_resume() is meant for a vCPU stopped by the
> vm-state machinery: besides kicking the thread it clears cpu->stop and
> cpu->stopped, and resets exception_index to -1. Clearing the stop flags
> can undo a pause requested via the monitor or by migration, and resetting
> exception_index discards an exception the vCPU had already latched.
>
> Only the kick is wanted here, so call qemu_cpu_kick() directly.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> target/hexagon/hex_interrupts.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/hexagon/hex_interrupts.c b/target/hexagon/hex_interrupts.c
> index 7dde1294b2e..2b2834af95f 100644
> --- a/target/hexagon/hex_interrupts.c
> +++ b/target/hexagon/hex_interrupts.c
> @@ -441,7 +441,7 @@ void hex_interrupt_update(CPUHexagonState *env)
> const int exe_mode = get_exe_mode(hex_env);
> if (exe_mode != HEX_EXE_MODE_OFF) {
> cpu_interrupt(cs, CPU_INTERRUPT_SWI);
> - cpu_resume(cs);
> + qemu_cpu_kick(cs);
> }
> }
> }
This reminded me another patch I'm carrying locally after
your confirmation on
https://lore.kernel.org/qemu-devel/5a6e6e71-7c0e-4cdf-a578-efebcd1e1430@oss.qualcomm.com/:
-- >8 --
Author: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Date: Fri Aug 14 18:49:50 2026 +0200
target/hexagon: Do not open-code cpu_resume() in _resume_thread()
As the name imply, hexagon_resume_thread() wants to resume
the vCPU. Better call the appropriate cpu_resume() method,
hidding the vCPU 'kick' API.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
FIXME: can we safely remove "cs->halted = 0;"?
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 9ce260d7448..ced871f8ea6 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -225,8 +225,7 @@ static void hexagon_resume_thread(CPUHexagonState *env)
cs = env_cpu(env);
ASSERT_DIRECT_TO_GUEST_UNSET(env, cs->exception_index);
cs->halted = false;
- cs->exception_index = HEX_EVENT_NONE;
- qemu_cpu_kick(cs);
+ cpu_resume(cs);
}
---
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/8] hw/intc: name the L2VIC edge trigger check
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
` (2 preceding siblings ...)
2026-09-03 18:56 ` [PATCH 3/8] target/hexagon: kick vCPU when re-asserting interrupts Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:37 ` Pierrick Bouvier
2026-09-04 13:31 ` Philippe Mathieu-Daudé
2026-09-03 18:56 ` [PATCH 5/8] target/hexagon: assert guest register pair alignment Brian Cain
` (3 subsequent siblings)
7 siblings, 2 replies; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
Link: https://lore.kernel.org/qemu-devel/c3f2f4e2-79e9-4b3f-8bae-88c669a34c0b@oss.qualcomm.com/
Suggested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
hw/intc/hex-l2vic.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/hw/intc/hex-l2vic.c b/hw/intc/hex-l2vic.c
index a986f0bdf35..736f1be3b1d 100644
--- a/hw/intc/hex-l2vic.c
+++ b/hw/intc/hex-l2vic.c
@@ -92,7 +92,7 @@ typedef struct HexL2VICState {
DECLARE_BITMAP32(int_pending, L2VIC_INTERRUPT_MAX);
/* Which enabled interrupt is active */
DECLARE_BITMAP32(int_status, L2VIC_INTERRUPT_MAX);
- /* Edge or Level interrupt */
+ /* 1 for edge-triggered, 0 for level-triggered */
DECLARE_BITMAP32(int_type, L2VIC_INTERRUPT_MAX);
DECLARE_BITMAP32(int_group_n[4], L2VIC_INTERRUPT_MAX);
qemu_irq irq[8];
@@ -249,6 +249,11 @@ static inline bool vid_active(HexL2VICState *s)
return active_irq != size;
}
+static bool edge_triggered_irq(HexL2VICState *s, int irq)
+{
+ return test_bit32(irq, s->int_type);
+}
+
static bool l2vic_update(HexL2VICState *s, int irq)
{
bool pending;
@@ -270,7 +275,7 @@ static bool l2vic_update(HexL2VICState *s, int irq)
* enable bit set across deliveries -- the firmware enables once
* and expects the interrupt to remain enabled.
*/
- if (test_bit32(irq, s->int_type)) {
+ if (edge_triggered_irq(s, irq)) {
clear_bit32(irq, s->int_enable);
}
s->vid = irq;
@@ -299,7 +304,7 @@ static void l2vic_set_irq(void *opaque, int irq, int level)
if (level) {
set_bit32(irq, s->int_pending);
- } else if (!test_bit32(irq, s->int_type)) {
+ } else if (!edge_triggered_irq(s, irq)) {
clear_bit32(irq, s->int_pending);
}
l2vic_update(s, irq);
@@ -328,7 +333,7 @@ static void l2vic_write(void *opaque, hwaddr offset, uint64_t val,
while ((bit = ctz32(bits)) < 32) {
int irq = base_irq + bit;
- if (test_bit32(irq, s->int_type)) {
+ if (edge_triggered_irq(s, irq)) {
set_bit32(irq, s->int_pending);
}
bits &= ~(1u << bit);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 4/8] hw/intc: name the L2VIC edge trigger check
2026-09-03 18:56 ` [PATCH 4/8] hw/intc: name the L2VIC edge trigger check Brian Cain
@ 2026-09-03 19:37 ` Pierrick Bouvier
2026-09-04 13:31 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 20+ messages in thread
From: Pierrick Bouvier @ 2026-09-03 19:37 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Philippe Mathieu-Daudé
On 9/3/2026 11:56 AM, Brian Cain wrote:
> Link: https://lore.kernel.org/qemu-devel/c3f2f4e2-79e9-4b3f-8bae-88c669a34c0b@oss.qualcomm.com/
> Suggested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> hw/intc/hex-l2vic.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] hw/intc: name the L2VIC edge trigger check
2026-09-03 18:56 ` [PATCH 4/8] hw/intc: name the L2VIC edge trigger check Brian Cain
2026-09-03 19:37 ` Pierrick Bouvier
@ 2026-09-04 13:31 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-04 13:31 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Pierrick Bouvier
On 3/9/26 20:56, Brian Cain wrote:
> Link: https://lore.kernel.org/qemu-devel/c3f2f4e2-79e9-4b3f-8bae-88c669a34c0b@oss.qualcomm.com/
> Suggested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> hw/intc/hex-l2vic.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 5/8] target/hexagon: assert guest register pair alignment
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
` (3 preceding siblings ...)
2026-09-03 18:56 ` [PATCH 4/8] hw/intc: name the L2VIC edge trigger check Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:37 ` Pierrick Bouvier
2026-09-04 13:32 ` Philippe Mathieu-Daudé
2026-09-03 18:56 ` [PATCH 6/8] hexagon: raise imprecise exception for multi-TLB matches Brian Cain
` (2 subsequent siblings)
7 siblings, 2 replies; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
Link: https://lore.kernel.org/qemu-devel/f7f34a43-c1cc-4dd8-a859-9ab72e1b015f@oss.qualcomm.com/
Suggested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
target/hexagon/op_helper.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 5d64c5523bb..7ad99ced7ab 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1927,6 +1927,8 @@ uint32_t HELPER(greg_read)(CPUHexagonState *env, uint32_t reg)
uint64_t HELPER(greg_read_pair)(CPUHexagonState *env, uint32_t reg)
{
+ g_assert((reg & 1) == 0);
+
if (reg == HEX_GREG_G0 || reg == HEX_GREG_G2) {
return (uint64_t)(env->greg[reg]) |
(((uint64_t)(env->greg[reg + 1])) << 32);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 6/8] hexagon: raise imprecise exception for multi-TLB matches
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
` (4 preceding siblings ...)
2026-09-03 18:56 ` [PATCH 5/8] target/hexagon: assert guest register pair alignment Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:37 ` Pierrick Bouvier
2026-09-03 18:56 ` [PATCH 7/8] tests/functional/hexagon: add tests, update to v0.2.14 Brian Cain
2026-09-03 18:56 ` [PATCH 8/8] tests/functional/hexagon: update arch tests " Brian Cain
7 siblings, 1 reply; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
The TLB walk stopped at the first matching entry, so instruction and data
translations did not detect a second valid mapping for the same VA and ASID.
Scan the remaining entries after selecting the translation. On a second
match, retain the first entry for the access but record
HEX_CAUSE_IMPRECISE_MULTI_TLB_MATCH as a pending imprecise exception.
Move that exception out of the synchronous TLB-fill result and check for it
after every packet, rather than only packets containing tlbp. This delivers
the architectural imprecise exception after an ordinary memory access and
avoids treating it as a precise permission fault. Clear the pending state
when starting a new translation and after delivering the exception.
The v0.2.14 mmu_multi_tlb systest uncovered this bug.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
hw/hexagon/hexagon_tlb.c | 10 ++++++++++
target/hexagon/hex_mmu.c | 12 +++++++++---
target/hexagon/hexswi.c | 1 +
target/hexagon/translate.c | 22 ++++++++--------------
4 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index c76805abac9..157d03e51bf 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -326,6 +326,16 @@ bool hexagon_tlb_find_match(HexagonTLBState *tlb, uint32_t asid,
for (uint32_t i = 0; i < tlb->num_entries; i++) {
if (hex_tlb_entry_match(tlb->entries[i], asid, VA, access_type,
PA, prot, size, excp, cause_code, mmu_idx)) {
+ if (*excp == 0) {
+ for (i++; i < tlb->num_entries; i++) {
+ if (hex_tlb_entry_match_noperm(tlb->entries[i], asid,
+ VA)) {
+ *excp = HEX_EVENT_IMPRECISE;
+ *cause_code = HEX_CAUSE_IMPRECISE_MULTI_TLB_MATCH;
+ break;
+ }
+ }
+ }
return true;
}
}
diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index d6258c673d1..d6ee7c40798 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -71,10 +71,16 @@ bool hex_tlb_find_match(CPUHexagonState *env, uint32_t VA,
uint32_t ssr = env->t_sreg[HEX_SREG_SSR];
uint8_t asid = GET_SSR_FIELD(SSR_ASID, ssr);
int cause_code = 0;
+ bool found;
- bool found = hexagon_tlb_find_match(cpu->tlb, asid, VA, access_type,
- PA, prot, size, excp, &cause_code,
- mmu_idx);
+ env->imprecise_exception = 0;
+ found = hexagon_tlb_find_match(cpu->tlb, asid, VA, access_type,
+ PA, prot, size, excp, &cause_code,
+ mmu_idx);
+ if (*excp == HEX_EVENT_IMPRECISE) {
+ env->imprecise_exception = *excp;
+ *excp = 0;
+ }
if (cause_code) {
env->cause_code = cause_code;
}
diff --git a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c
index 75f0a9cc520..4705e915aea 100644
--- a/target/hexagon/hexswi.c
+++ b/target/hexagon/hexswi.c
@@ -934,6 +934,7 @@ void hexagon_cpu_do_interrupt(CPUState *cs)
break;
case HEX_EVENT_IMPRECISE:
+ env->imprecise_exception = 0;
if (get_exe_mode(env) == HEX_EXE_MODE_WAIT) {
env->gpr[HEX_REG_PC] = env->wait_next_pc - 4;
clear_wait_mode(env);
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index be75e5fdeb8..5d3d67e5d3e 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -1065,20 +1065,14 @@ static void update_exec_counters(DisasContext *ctx)
* A tlbp instruction may detect multiple TLB matches and set a pending
* imprecise exception. Raise it after the packet that ran the tlbp.
*/
-static void check_imprecise_exception(Packet *pkt)
+static void check_imprecise_exception(DisasContext *ctx)
{
- for (int i = 0; i < pkt->num_insns; i++) {
- if (pkt->insn[i].opcode == Y2_tlbp) {
- TCGv PC = tcg_constant_tl(pkt->pc);
- TCGLabel *label = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, hex_imprecise_exception,
- 0, label);
- gen_helper_raise_exception(tcg_env,
- hex_imprecise_exception, PC);
- gen_set_label(label);
- return;
- }
- }
+ TCGv PC = tcg_constant_tl(ctx->pkt.pc);
+ TCGLabel *label = gen_new_label();
+
+ tcg_gen_brcondi_tl(TCG_COND_EQ, hex_imprecise_exception, 0, label);
+ gen_helper_raise_exception(tcg_env, hex_imprecise_exception, PC);
+ gen_set_label(label);
}
#endif
@@ -1182,7 +1176,7 @@ static void gen_commit_packet(DisasContext *ctx)
}
#ifndef CONFIG_USER_ONLY
- check_imprecise_exception(&ctx->pkt);
+ check_imprecise_exception(ctx);
#endif
if (ctx->pkt_ends_tb || ctx->base.is_jmp == DISAS_NORETURN) {
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 6/8] hexagon: raise imprecise exception for multi-TLB matches
2026-09-03 18:56 ` [PATCH 6/8] hexagon: raise imprecise exception for multi-TLB matches Brian Cain
@ 2026-09-03 19:37 ` Pierrick Bouvier
0 siblings, 0 replies; 20+ messages in thread
From: Pierrick Bouvier @ 2026-09-03 19:37 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Philippe Mathieu-Daudé
On 9/3/2026 11:56 AM, Brian Cain wrote:
> The TLB walk stopped at the first matching entry, so instruction and data
> translations did not detect a second valid mapping for the same VA and ASID.
>
> Scan the remaining entries after selecting the translation. On a second
> match, retain the first entry for the access but record
> HEX_CAUSE_IMPRECISE_MULTI_TLB_MATCH as a pending imprecise exception.
>
> Move that exception out of the synchronous TLB-fill result and check for it
> after every packet, rather than only packets containing tlbp. This delivers
> the architectural imprecise exception after an ordinary memory access and
> avoids treating it as a precise permission fault. Clear the pending state
> when starting a new translation and after delivering the exception.
>
> The v0.2.14 mmu_multi_tlb systest uncovered this bug.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> hw/hexagon/hexagon_tlb.c | 10 ++++++++++
> target/hexagon/hex_mmu.c | 12 +++++++++---
> target/hexagon/hexswi.c | 1 +
> target/hexagon/translate.c | 22 ++++++++--------------
> 4 files changed, 28 insertions(+), 17 deletions(-)
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 7/8] tests/functional/hexagon: add tests, update to v0.2.14
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
` (5 preceding siblings ...)
2026-09-03 18:56 ` [PATCH 6/8] hexagon: raise imprecise exception for multi-TLB matches Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:38 ` Pierrick Bouvier
2026-09-03 18:56 ` [PATCH 8/8] tests/functional/hexagon: update arch tests " Brian Cain
7 siblings, 1 reply; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
Add tests for direct-to-guest interrupts, multi-TLB match case, {u,}timer
registers.
Update to the v0.2.14 tests and switch to the new 'sim' machine name.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
tests/functional/hexagon/test_systests.py | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/tests/functional/hexagon/test_systests.py b/tests/functional/hexagon/test_systests.py
index f36e015f502..983ee1672ce 100755
--- a/tests/functional/hexagon/test_systests.py
+++ b/tests/functional/hexagon/test_systests.py
@@ -21,8 +21,8 @@ class SysTestsStandaloneTests(QemuSystemTest):
SYSTEST_TIMEOUT_SEC = 30
ASSET_TARBALL = Asset(
- "https://github.com/qualcomm/qemu-hexagon-testing/releases/download/v0.2.11/systests_standalone.tar.gz",
- "b5777aa65245de7710a7a08d717953c1362be7c8b60d9014c9fee8b17610ad1c",
+ "https://github.com/qualcomm/qemu-hexagon-testing/releases/download/v0.2.14/systests_standalone.tar.gz",
+ "f0c535d746384126954757b6ce54452c5fe82624618c79862495eec24718a6ff",
)
def setUp(self):
@@ -34,7 +34,7 @@ def binary(self, name):
self.assertTrue(os.path.exists(path))
return path
- def run_exit_zero(self, binary_name, *extra_args, machine="V66G_1024"):
+ def run_exit_zero(self, binary_name, *extra_args, machine="sim"):
self.set_machine(machine)
self.set_vm_arg("-display", "none")
self.set_vm_arg("-kernel", self.binary(binary_name))
@@ -47,7 +47,7 @@ def run_exit_zero(self, binary_name, *extra_args, machine="V66G_1024"):
f"code {self.vm.exitcode()}, expected 0")
def run_console_pattern(self, binary_name, pattern, *extra_args,
- machine="V66G_1024"):
+ machine="sim"):
self.set_machine(machine)
self.set_vm_arg("-display", "none")
self.set_vm_arg("-kernel", self.binary(binary_name))
@@ -90,5 +90,14 @@ def test_access(self):
def test_semihost(self):
self.run_console_pattern("semihost", "PASS", "-append", "arg1", "arg2")
+ def test_dtg_interrupt(self):
+ self.run_exit_zero("dtg_interrupt")
+
+ def test_mmu_multi_tlb(self):
+ self.run_exit_zero("mmu_multi_tlb")
+
+ def test_timer_reg(self):
+ self.run_exit_zero("timer_reg")
+
if __name__ == "__main__":
QemuSystemTest.main()
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 7/8] tests/functional/hexagon: add tests, update to v0.2.14
2026-09-03 18:56 ` [PATCH 7/8] tests/functional/hexagon: add tests, update to v0.2.14 Brian Cain
@ 2026-09-03 19:38 ` Pierrick Bouvier
0 siblings, 0 replies; 20+ messages in thread
From: Pierrick Bouvier @ 2026-09-03 19:38 UTC (permalink / raw)
To: Brian Cain, qemu-devel; +Cc: Philippe Mathieu-Daudé
On 9/3/2026 11:56 AM, Brian Cain wrote:
> Add tests for direct-to-guest interrupts, multi-TLB match case, {u,}timer
> registers.
>
> Update to the v0.2.14 tests and switch to the new 'sim' machine name.
>
> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
> ---
> tests/functional/hexagon/test_systests.py | 17 +++++++++++++----
> 1 file changed, 13 insertions(+), 4 deletions(-)
>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 8/8] tests/functional/hexagon: update arch tests to v0.2.14
2026-09-03 18:56 [PATCH 0/8] hexagon: fixes for tlb, badva Brian Cain
` (6 preceding siblings ...)
2026-09-03 18:56 ` [PATCH 7/8] tests/functional/hexagon: add tests, update to v0.2.14 Brian Cain
@ 2026-09-03 18:56 ` Brian Cain
2026-09-03 19:38 ` Pierrick Bouvier
7 siblings, 1 reply; 20+ messages in thread
From: Brian Cain @ 2026-09-03 18:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Brian Cain, Philippe Mathieu-Daudé, Pierrick Bouvier
Some of the tests run longer now, extend the timeout to 180s
in order to keep it robust.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
tests/functional/hexagon/test_arch_tests.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/functional/hexagon/test_arch_tests.py b/tests/functional/hexagon/test_arch_tests.py
index 8e71386c186..5d7ce487436 100755
--- a/tests/functional/hexagon/test_arch_tests.py
+++ b/tests/functional/hexagon/test_arch_tests.py
@@ -17,12 +17,12 @@ class ArchTestsUart(QemuSystemTest):
Tests output results via UART.
"""
- timeout = 60
+ timeout = 180
ASSET_TARBALL = Asset(
"https://github.com/qualcomm/qemu-hexagon-testing/releases/"
- "download/v0.2.12/arch_tests_uart.tar.gz",
- "871a339bf78cac0ebaf1b2509bfcd5b249ad8190be33e0cf848283b2f6915323",
+ "download/v0.2.14/arch_tests_uart.tar.gz",
+ "ce93cb90b9d757c1946dfe8fe6abcec8292b08a66546ac51b2dd48650b05fa91",
)
def run_uart_test(self, test_name: str,
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread