hexagon_cpu_mmu_index() runs very often - each TB.  Taking the BQL to
read syscfg is overkill.

Signed-off-by: Brian Cain <[email protected]>
---
 include/hw/hexagon/hexagon_globalreg.h | 6 ++++++
 hw/hexagon/hexagon_globalreg.c         | 9 +++++++--
 target/hexagon/cpu.c                   | 9 ++++++---
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/include/hw/hexagon/hexagon_globalreg.h 
b/include/hw/hexagon/hexagon_globalreg.h
index 2d5c3c166b1..dfd21e78663 100644
--- a/include/hw/hexagon/hexagon_globalreg.h
+++ b/include/hw/hexagon/hexagon_globalreg.h
@@ -59,6 +59,12 @@ uint32_t 
hexagon_globalreg_masked_value(HexagonGlobalRegState *s, uint32_t reg,
 void hexagon_globalreg_write_masked(HexagonGlobalRegState *s, uint32_t reg,
                                     uint32_t value);
 
+/*
+ * SYSCFG, without the BQL: for the translator, which asks for it on every
+ * translation block lookup and can't afford to contend for the lock.
+ */
+uint32_t hexagon_globalreg_read_syscfg_unlocked(HexagonGlobalRegState *s);
+
 /* Global performance cycle counter access */
 uint64_t hexagon_globalreg_read_pcycle(HexagonGlobalRegState *s);
 uint64_t hexagon_globalreg_get_pcycle_base(HexagonGlobalRegState *s);
diff --git a/hw/hexagon/hexagon_globalreg.c b/hw/hexagon/hexagon_globalreg.c
index 22ec4020665..8b50fec770a 100644
--- a/hw/hexagon/hexagon_globalreg.c
+++ b/hw/hexagon/hexagon_globalreg.c
@@ -252,7 +252,7 @@ static uint32_t get_reg_value(HexagonGlobalRegState *s, 
uint32_t reg)
         return reg == HEX_SREG_PCYCLELO ?
                 (uint32_t)value : (uint32_t)(value >> 32);
     }
-    return s->regs[reg];
+    return qatomic_read(&s->regs[reg]);
 }
 
 static void set_reg_value(HexagonGlobalRegState *s, uint32_t reg,
@@ -266,7 +266,7 @@ static void set_reg_value(HexagonGlobalRegState *s, 
uint32_t reg,
         return;
     }
 
-    s->regs[reg] = value;
+    qatomic_set(&s->regs[reg], value);
     if (pcycle_enable) {
         s->g_pcycle_base = 0;
         if (s->pcycle_running) {
@@ -281,6 +281,11 @@ static void set_reg_value(HexagonGlobalRegState *s, 
uint32_t reg,
     }
 }
 
+uint32_t hexagon_globalreg_read_syscfg_unlocked(HexagonGlobalRegState *s)
+{
+    return s ? qatomic_read(&s->regs[HEX_SREG_SYSCFG]) : 0;
+}
+
 uint32_t hexagon_globalreg_read(HexagonGlobalRegState *s, uint32_t reg,
                                 uint32_t htid)
 {
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 281d201250b..607dddf7e7c 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -572,11 +572,14 @@ static int hexagon_cpu_mmu_index(CPUState *cs, bool 
ifetch)
     HexagonCPU *cpu = HEXAGON_CPU(cs);
     int cpu_mode;
 
-    BQL_LOCK_GUARD();
+    /*
+     * No BQL: this runs for every translation block lookup, and the vCPU
+     * threads would otherwise queue up on it.  SYSCFG is read atomically and
+     * the rest is this vCPU's own state.
+     */
     if (cpu->globalregs) {
         uint32_t syscfg =
-            hexagon_globalreg_read(cpu->globalregs, HEX_SREG_SYSCFG,
-                                   env->threadId);
+            hexagon_globalreg_read_syscfg_unlocked(cpu->globalregs);
         uint8_t mmuen = GET_SYSCFG_FIELD(SYSCFG_MMUEN, syscfg);
         if (!mmuen) {
             return MMU_KERNEL_IDX;
-- 
2.34.1

Reply via email to