hexagon_modify_ssr() flushed the softtlb on any change to SSR.EX, UM, GM,
or ASID, but only ASID affects translation.  EX/UM/GM just pick the mode,
which is already captured in mmu_idx.

EX toggles on every exception entry/rte, so the flush created a feedback
loop where a TLB miss wiped the softtlb and guaranteed the next accesses
missed too.

Rename hex_mmu_mode_change() to hex_mmu_asid_change() to match what now
triggers it, and narrow it to this thread's mmu indices: the ASID lives in
the thread's private SSR, so other CPUs are unaffected.

Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/hex_mmu.h    |  2 +-
 target/hexagon/cpu_helper.c | 17 +++--------------
 target/hexagon/hex_mmu.c    |  7 ++++---
 3 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/target/hexagon/hex_mmu.h b/target/hexagon/hex_mmu.h
index 0c49404448c..9b6ea5b967b 100644
--- a/target/hexagon/hex_mmu.h
+++ b/target/hexagon/hex_mmu.h
@@ -17,7 +17,7 @@ extern void hex_tlb_invalidate_asid(CPUHexagonState *env, 
uint32_t asid);
 extern uint32_t hex_tlb_lookup(CPUHexagonState *env, uint32_t ssr, uint32_t 
VA);
 extern void hex_mmu_on(CPUHexagonState *env);
 extern void hex_mmu_off(CPUHexagonState *env);
-extern void hex_mmu_mode_change(CPUHexagonState *env);
+extern void hex_mmu_asid_change(CPUHexagonState *env);
 extern bool hex_tlb_find_match(CPUHexagonState *env, uint32_t VA,
                                MMUAccessType access_type, hwaddr *PA, int 
*prot,
                                uint64_t *size, int32_t *excp, int mmu_idx);
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 919fcbc7c97..baffe6bbaa9 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -192,27 +192,17 @@ unsigned hexagon_hvx_select_context(CPUHexagonState *env, 
uint32_t ssr)
 
 void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old)
 {
-    bool old_EX, old_UM, old_GM, old_IE;
-    bool new_EX, new_UM, new_GM, new_IE;
+    bool old_EX, old_IE;
+    bool new_EX, new_IE;
     uint8_t old_asid, new_asid;
 
     g_assert(bql_locked());
 
     old_EX = GET_SSR_FIELD(SSR_EX, old);
-    old_UM = GET_SSR_FIELD(SSR_UM, old);
-    old_GM = GET_SSR_FIELD(SSR_GM, old);
     old_IE = GET_SSR_FIELD(SSR_IE, old);
     new_EX = GET_SSR_FIELD(SSR_EX, new);
-    new_UM = GET_SSR_FIELD(SSR_UM, new);
-    new_GM = GET_SSR_FIELD(SSR_GM, new);
     new_IE = GET_SSR_FIELD(SSR_IE, new);
 
-    if ((old_EX != new_EX) ||
-        (old_UM != new_UM) ||
-        (old_GM != new_GM)) {
-        hex_mmu_mode_change(env);
-    }
-
     bool xa_changed = GET_SSR_FIELD(SSR_XA, new) != GET_SSR_FIELD(SSR_XA, old);
     bool xe_changed = GET_SSR_FIELD(SSR_XE, new) != GET_SSR_FIELD(SSR_XE, old);
 
@@ -228,8 +218,7 @@ void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, 
uint32_t old)
     old_asid = GET_SSR_FIELD(SSR_ASID, old);
     new_asid = GET_SSR_FIELD(SSR_ASID, new);
     if (new_asid != old_asid) {
-        CPUState *cs = env_cpu(env);
-        tlb_flush(cs);
+        hex_mmu_asid_change(env);
     }
 
     /* See if the interrupts have been enabled or we have exited EX mode */
diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index 2e0e4ab705b..9a0e29ae212 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -73,11 +73,12 @@ void hex_mmu_off(CPUHexagonState *env)
     tlb_flush(cs);
 }
 
-void hex_mmu_mode_change(CPUHexagonState *env)
+void hex_mmu_asid_change(CPUHexagonState *env)
 {
-    qemu_log_mask(CPU_LOG_MMU, "Hexagon mode change!\n");
     CPUState *cs = env_cpu(env);
-    tlb_flush(cs);
+
+    qemu_log_mask(CPU_LOG_MMU, "Hexagon ASID change!\n");
+    tlb_flush_by_mmuidx(cs, MMU_IDX_ALL);
 }
 
 bool hex_tlb_find_match(CPUHexagonState *env, uint32_t VA,
-- 
2.34.1

Reply via email to