From 608cc69cd20f42a982fa3d599f7844bb4c1cd32e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Sun, 14 Jan 2024 20:11:11 -0800 Subject: [PATCH] Switch to using BQL_LOCK_GUARD() macro This lock is scope-bound - so we will avoid errors when adding new early return statements. BQL_LOCK_GUARD is an architecture-independent QEMU idiom to replace the hexagon-specific {UN,}LOCK_IOTHREAD(). The hexagon-specific macro was a pseudo-nested lock but we don't seem to need that flexibility if we move the lock acquisition up to a consistent place high enough in the call stack. Signed-off-by: Brian Cain --- target/hexagon/cpu.c | 1 + target/hexagon/cpu.h | 10 ----- target/hexagon/cpu_helper.c | 41 ++++++------------ target/hexagon/hex_interrupts.c | 17 ++------ target/hexagon/hex_mmu.c | 9 +--- target/hexagon/hexswi.c | 8 ++-- target/hexagon/op_helper.c | 75 +++++++++++++-------------------- target/hexagon/pmu.h | 6 +-- 8 files changed, 55 insertions(+), 112 deletions(-) diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 709b17485196..d295156853d6 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -571,6 +571,7 @@ static void hexagon_restore_state_to_opc(CPUState *cs, #if !defined(CONFIG_USER_ONLY) void hexagon_cpu_soft_reset(CPUHexagonState *env) { + BQL_LOCK_GUARD(); ARCH_SET_SYSTEM_REG(env, HEX_SREG_SSR, 0); hexagon_ssr_set_cause(env, HEX_CAUSE_RESET); diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index 313508608769..5b86137d5e59 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -303,16 +303,6 @@ typedef struct PMUState { } PMUState; #endif -#define LOCK_IOTHREAD(VAR) \ - if (!(VAR)) { \ - qemu_mutex_lock_iothread(); \ - } -#define UNLOCK_IOTHREAD(VAR) \ - if (!(VAR)) { \ - qemu_mutex_unlock_iothread(); \ - } - - struct Einfo { uint8_t valid; uint8_t type; diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c index 7d108f5a1fb7..1ee298c32bcd 100644 --- a/target/hexagon/cpu_helper.c +++ b/target/hexagon/cpu_helper.c @@ -337,48 +337,41 @@ void hexagon_touch_memory(CPUHexagonState *env, uint32_t start_addr, static void set_enable_mask(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); const uint32_t modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); thread_enabled_mask |= 0x1 << env->threadId; SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_E, thread_enabled_mask); - UNLOCK_IOTHREAD(exception_context); } static uint32_t clear_enable_mask(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); const uint32_t modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); thread_enabled_mask &= ~(0x1 << env->threadId); SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_E, thread_enabled_mask); - UNLOCK_IOTHREAD(exception_context); return thread_enabled_mask; } static void set_wait_mode(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); const uint32_t modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl); thread_wait_mask |= 0x1 << env->threadId; SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W, thread_wait_mask); - UNLOCK_IOTHREAD(exception_context); } void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); if (qemu_loglevel_mask(LOG_GUEST_ERROR) && (ATOMIC_LOAD(env->k0_lock_state) != HEX_LOCK_UNLOCKED || @@ -395,13 +388,11 @@ void hexagon_wait_thread(CPUHexagonState *env, target_ulong PC) */ if ((cs->exception_index != HEX_EVENT_NONE) || (cpu_has_work(cs))) { - UNLOCK_IOTHREAD(exception_context); return; } set_wait_mode(env); env->wait_next_pc = PC + 4; - UNLOCK_IOTHREAD(exception_context); cpu_stop_current(); } @@ -426,12 +417,11 @@ static void hexagon_resume_thread(CPUHexagonState *env, uint32_t ei) void hexagon_resume_threads(CPUHexagonState *current_env, uint32_t mask) { - const bool exception_context = qemu_mutex_iothread_locked(); CPUState *cs; CPUHexagonState *env; bool found; - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); for (int htid = 0 ; htid < THREADS_MAX ; ++htid) { if (!(mask & (0x1 << htid))) { continue; @@ -457,11 +447,12 @@ void hexagon_resume_threads(CPUHexagonState *current_env, uint32_t mask) } hexagon_resume_thread(env, HEX_EVENT_NONE); } - UNLOCK_IOTHREAD(exception_context); } static void do_start_thread(CPUState *cs, run_on_cpu_data tbd) { + BQL_LOCK_GUARD(); + HexagonCPU *cpu = HEXAGON_CPU(cs); CPUHexagonState *env = &cpu->env; @@ -510,8 +501,9 @@ static target_ulong get_thread0_r2(void) void hexagon_stop_thread(CPUHexagonState *env) { + BQL_LOCK_GUARD(); HexagonCPU *cpu = env_archcpu(env); - #if HEX_DEBUG +#if HEX_DEBUG HEX_DEBUG_LOG("%s: htid %d, cpu %p\n", __func__, ARCH_GET_SYSTEM_REG(env, HEX_SREG_HTID), cpu); #endif @@ -645,7 +637,7 @@ const char *get_exe_mode_str(CPUHexagonState *env) int get_exe_mode(CPUHexagonState *env) { - g_assert(qemu_mutex_iothread_locked()); + g_assert(bql_locked()); target_ulong modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); @@ -675,21 +667,17 @@ int get_exe_mode(CPUHexagonState *env) void clear_wait_mode(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); const uint32_t modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl); thread_wait_mask &= ~(0x1 << env->threadId); SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W, thread_wait_mask); - UNLOCK_IOTHREAD(exception_context); } void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); - + g_assert(bql_locked()); const uint32_t old = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SSR); SET_SYSTEM_FIELD(env, HEX_SREG_SSR, SSR_EX, 1); @@ -697,7 +685,6 @@ void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause) const uint32_t new = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SSR); hexagon_modify_ssr(env, new, old); - UNLOCK_IOTHREAD(exception_context); } static MMVector VRegs[VECTOR_UNIT_MAX][NUM_VREGS]; @@ -705,8 +692,7 @@ static MMQReg QRegs[VECTOR_UNIT_MAX][NUM_QREGS]; void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); bool old_EX = GET_SSR_FIELD(SSR_EX, old); bool old_UM = GET_SSR_FIELD(SSR_UM, old); @@ -792,7 +778,6 @@ void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old) (!new_EX && old_EX)) { hex_interrupt_update(env); } - UNLOCK_IOTHREAD(exception_context); } void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, diff --git a/target/hexagon/hex_interrupts.c b/target/hexagon/hex_interrupts.c index f08ffcd3fbef..ca2b2f26c14f 100644 --- a/target/hexagon/hex_interrupts.c +++ b/target/hexagon/hex_interrupts.c @@ -227,7 +227,6 @@ bool hex_check_interrupts(CPUHexagonState *env) bool int_handled = false; bool ssr_ex = get_ssr_ex(env); int max_ints; - const bool exception_context = qemu_mutex_iothread_locked(); bool schedcfgen; /* Early exit if nothing pending */ @@ -237,7 +236,7 @@ bool hex_check_interrupts(CPUHexagonState *env) } max_ints = reg_field_info[IPENDAD_IPEND].width; - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); /* Only check priorities when schedcfgen is set */ schedcfgen = get_schedcfgen(env); for (int i = 0; i < max_ints; i++) { @@ -286,14 +285,12 @@ bool hex_check_interrupts(CPUHexagonState *env) } else if (int_handled) { assert(!cs->halted); } - UNLOCK_IOTHREAD(exception_context); return int_handled; } void hex_clear_interrupts(CPUHexagonState *env, uint32_t mask, uint32_t type) { - const bool exception_context = qemu_mutex_iothread_locked(); if (mask == 0) { return; } @@ -301,15 +298,14 @@ void hex_clear_interrupts(CPUHexagonState *env, uint32_t mask, uint32_t type) /* * Notify all CPUs that the interrupt has happened */ - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); clear_ipend(env, mask); hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); } void hex_raise_interrupts(CPUHexagonState *env, uint32_t mask, uint32_t type) { - const bool exception_context = qemu_mutex_iothread_locked(); + g_assert(bql_locked()); if (mask == 0) { return; } @@ -317,18 +313,15 @@ void hex_raise_interrupts(CPUHexagonState *env, uint32_t mask, uint32_t type) /* * Notify all CPUs that the interrupt has happened */ - LOCK_IOTHREAD(exception_context); set_ipend(env, mask); hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); } void hex_interrupt_update(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); CPUState *cs; - LOCK_IOTHREAD(exception_context); + g_assert(bql_locked()); if (get_ipend(env) != 0) { CPU_FOREACH(cs) { HexagonCPU *hex_cpu = HEXAGON_CPU(cs); @@ -340,6 +333,4 @@ void hex_interrupt_update(CPUHexagonState *env) } } } - - UNLOCK_IOTHREAD(exception_context); } diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c index 3a631e4d6127..233dab6f4988 100644 --- a/target/hexagon/hex_mmu.c +++ b/target/hexagon/hex_mmu.c @@ -534,15 +534,13 @@ static inline void print_thread_states(const char *str) void hex_tlb_lock(CPUHexagonState *env) { qemu_log_mask(CPU_LOG_MMU, "hex_tlb_lock: %d\n", env->threadId); - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); uint32_t syscfg = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SYSCFG); uint8_t tlb_lock = GET_SYSCFG_FIELD(SYSCFG_TLBLOCK, syscfg); if (tlb_lock) { if (ATOMIC_LOAD(env->tlb_lock_state) == HEX_LOCK_OWNER) { qemu_log_mask(CPU_LOG_MMU, "Already the owner\n"); - UNLOCK_IOTHREAD(exception_context); return; } qemu_log_mask(CPU_LOG_MMU, "\tWaiting\n"); @@ -558,14 +556,11 @@ void hex_tlb_lock(CPUHexagonState *env) qemu_log_mask(CPU_LOG_MMU, "Threads after hex_tlb_lock:\n"); print_thread_states("\tThread"); } - UNLOCK_IOTHREAD(exception_context); } void hex_tlb_unlock(CPUHexagonState *env) { qemu_log_mask(CPU_LOG_MMU, "hex_tlb_unlock: %d\n", env->threadId); - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); /* Nothing to do if the TLB isn't locked by this thread */ uint32_t syscfg = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SYSCFG); @@ -573,7 +568,6 @@ void hex_tlb_unlock(CPUHexagonState *env) if ((tlb_lock == 0) || (ATOMIC_LOAD(env->tlb_lock_state) != HEX_LOCK_OWNER)) { qemu_log_mask(CPU_LOG_MMU, "\tNot owner\n"); - UNLOCK_IOTHREAD(exception_context); return; } @@ -631,6 +625,5 @@ void hex_tlb_unlock(CPUHexagonState *env) qemu_log_mask(CPU_LOG_MMU, "Threads after hex_tlb_unlock:\n"); print_thread_states("\tThread"); } - UNLOCK_IOTHREAD(exception_context); } diff --git a/target/hexagon/hexswi.c b/target/hexagon/hexswi.c index c3517d7a7f26..886471ae0d9f 100644 --- a/target/hexagon/hexswi.c +++ b/target/hexagon/hexswi.c @@ -115,7 +115,7 @@ static int MapError(int ERR) static int sim_handle_trap_functional(CPUHexagonState *env) { - g_assert(qemu_mutex_iothread_locked()); + g_assert(bql_locked()); target_ulong ssr = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SSR); target_ulong what_swi = ARCH_GET_THREAD_REG(env, HEX_REG_R00); @@ -1008,7 +1008,7 @@ static int sim_handle_trap_functional(CPUHexagonState *env) static int sim_handle_trap(CPUHexagonState *env) { - g_assert(qemu_mutex_iothread_locked()); + g_assert(bql_locked()); int retval = 0; target_ulong what_swi = ARCH_GET_THREAD_REG(env, HEX_REG_R00); @@ -1064,8 +1064,7 @@ void hexagon_cpu_do_interrupt(CPUState *cs) { HexagonCPU *cpu = HEXAGON_CPU(cs); CPUHexagonState *env = &cpu->env; - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); HEX_DEBUG_LOG("%s: tid %d, event 0x%x, cause 0x%x\n", __func__, env->threadId, cs->exception_index, env->cause_code); @@ -1295,7 +1294,6 @@ void hexagon_cpu_do_interrupt(CPUState *cs) } cs->exception_index = HEX_EVENT_NONE; - UNLOCK_IOTHREAD(exception_context); } void register_trap_exception(CPUHexagonState *env, int traptype, int imm, diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index d3e54932ed67..cc8c083284b6 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -630,11 +630,13 @@ void HELPER(insn_cache_op)(CPUHexagonState *env, target_ulong RsV, void HELPER(swi)(CPUHexagonState *env, uint32_t mask) { + BQL_LOCK_GUARD(); hex_raise_interrupts(env, mask, CPU_INTERRUPT_SWI); } void HELPER(cswi)(CPUHexagonState *env, uint32_t mask) { + BQL_LOCK_GUARD(); hex_clear_interrupts(env, mask, CPU_INTERRUPT_SWI); } @@ -658,37 +660,35 @@ static void hexagon_clear_last_irq(CPUHexagonState *env, uint32_t offset) void HELPER(ciad)(CPUHexagonState *env, uint32_t mask) { - const bool exception_context = qemu_mutex_iothread_locked(); uint32_t ipendad; uint32_t iad; - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); ipendad = READ_SREG(HEX_SREG_IPENDAD); iad = fGET_FIELD(ipendad, IPENDAD_IAD); fSET_FIELD(ipendad, IPENDAD_IAD, iad & ~(mask)); ARCH_SET_SYSTEM_REG(env, HEX_SREG_IPENDAD, ipendad); hexagon_clear_last_irq(env, L2VIC_VID_0); hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); } void HELPER(siad)(CPUHexagonState *env, uint32_t mask) { - const bool exception_context = qemu_mutex_iothread_locked(); uint32_t ipendad; uint32_t iad; - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); ipendad = READ_SREG(HEX_SREG_IPENDAD); iad = fGET_FIELD(ipendad, IPENDAD_IAD); fSET_FIELD(ipendad, IPENDAD_IAD, iad | mask); ARCH_SET_SYSTEM_REG(env, HEX_SREG_IPENDAD, ipendad); hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); } void HELPER(wait)(CPUHexagonState *env, target_ulong PC) { + BQL_LOCK_GUARD(); + if (!fIN_DEBUG_MODE(fGET_TNUM())) { hexagon_wait_thread(env, PC); } @@ -696,6 +696,7 @@ void HELPER(wait)(CPUHexagonState *env, target_ulong PC) void HELPER(resume)(CPUHexagonState *env, uint32_t mask) { + BQL_LOCK_GUARD(); hexagon_resume_threads(env, mask); } #endif @@ -1686,6 +1687,7 @@ void HELPER(debug_print_vec)(CPUHexagonState *env, int rnum, void *vecptr) #ifndef CONFIG_USER_ONLY void HELPER(modify_ssr)(CPUHexagonState *env, uint32_t new, uint32_t old) { + BQL_LOCK_GUARD(); hexagon_modify_ssr(env, new, old); } #endif @@ -1695,9 +1697,6 @@ void HELPER(modify_ssr)(CPUHexagonState *env, uint32_t new, uint32_t old) #if HEX_DEBUG static void print_thread(const char *str, CPUState *cs) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); - HexagonCPU *cpu = HEXAGON_CPU(cs); CPUHexagonState *thread = &cpu->env; bool is_stopped = cpu_is_stopped(cs); @@ -1716,7 +1715,6 @@ static void print_thread(const char *str, CPUState *cs) lock_state == HEX_LOCK_WAITING ? "waiting" : lock_state == HEX_LOCK_OWNER ? "owner" : "unknown"); - UNLOCK_IOTHREAD(exception_context); } static void print_thread_states(const char *str) @@ -1739,14 +1737,12 @@ static void hex_k0_lock(CPUHexagonState *env) { HEX_DEBUG_LOG("Before hex_k0_lock: %d\n", env->threadId); print_thread_states("\tThread"); - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); uint32_t syscfg = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SYSCFG); if (GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg)) { if (ATOMIC_LOAD(env->k0_lock_state) == HEX_LOCK_OWNER) { HEX_DEBUG_LOG("Already the owner\n"); - UNLOCK_IOTHREAD(exception_context); return; } HEX_DEBUG_LOG("\tWaiting\n"); @@ -1758,7 +1754,6 @@ static void hex_k0_lock(CPUHexagonState *env) SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1); } - UNLOCK_IOTHREAD(exception_context); HEX_DEBUG_LOG("After hex_k0_lock: %d\n", env->threadId); print_thread_states("\tThread"); } @@ -2027,12 +2022,11 @@ void cancel_slot(CPUHexagonState *env, uint32_t slot) #ifndef CONFIG_USER_ONLY void HELPER(iassignw)(CPUHexagonState *env, uint32_t src) { - const bool exception_context = qemu_mutex_iothread_locked(); uint32_t modectl; uint32_t thread_enabled_mask; CPUState *cpu; - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); @@ -2051,20 +2045,18 @@ void HELPER(iassignw)(CPUHexagonState *env, uint32_t src) } } hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); } uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src) { - const bool exception_context = qemu_mutex_iothread_locked(); uint32_t modectl; uint32_t thread_enabled_mask; uint32_t intbitpos; uint32_t dest_reg; CPUState *cpu; - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); modectl = ARCH_GET_SYSTEM_REG(env, HEX_SREG_MODECTL); thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); /* src fields are in same position as modectl, but mean different things */ @@ -2078,7 +2070,7 @@ uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src) dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId; } } - UNLOCK_IOTHREAD(exception_context); + return dest_reg; } @@ -2158,12 +2150,10 @@ uint64_t HELPER(creg_read_pair)(CPUHexagonState *env, uint32_t reg) static inline QEMU_ALWAYS_INLINE uint32_t sreg_read(CPUHexagonState *env, uint32_t reg) { + g_assert(bql_locked()); if ((reg == HEX_SREG_VID) || (reg == HEX_SREG_VID1)) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); const uint32_t vid = hexagon_find_last_irq(env, reg); ARCH_SET_SYSTEM_REG(env, reg, vid); - UNLOCK_IOTHREAD(exception_context); } else if ((reg == HEX_SREG_TIMERLO) || (reg == HEX_SREG_TIMERHI)) { uint32_t low = 0; uint32_t high = 0; @@ -2184,11 +2174,13 @@ static inline QEMU_ALWAYS_INLINE uint32_t sreg_read(CPUHexagonState *env, uint32_t HELPER(sreg_read)(CPUHexagonState *env, uint32_t reg) { + BQL_LOCK_GUARD(); return sreg_read(env, reg); } uint64_t HELPER(sreg_read_pair)(CPUHexagonState *env, uint32_t reg) { + BQL_LOCK_GUARD(); if (reg == HEX_SREG_TIMERLO) { uint32_t low = 0; uint32_t high = 0; @@ -2313,6 +2305,7 @@ static bool handle_pmu_sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t old = ARCH_GET_SYSTEM_REG(env, reg); uint32_t new = val; + g_assert(bql_locked()); if (reg == HEX_SREG_PMUSTID0 || reg == HEX_SREG_PMUSTID1) { if (old != new) { qemu_log_mask(LOG_UNIMP, "PMUSTID settings not implemented."); @@ -2357,13 +2350,11 @@ static inline QEMU_ALWAYS_INLINE void sreg_write(CPUHexagonState *env, uint32_t reg, uint32_t val) { + g_assert(bql_locked()); if ((reg == HEX_SREG_VID) || (reg == HEX_SREG_VID1)) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); hexagon_set_vid(env, (reg == HEX_SREG_VID) ? L2VIC_VID_0 : L2VIC_VID_1, val); ARCH_SET_SYSTEM_REG(env, reg, val); - UNLOCK_IOTHREAD(exception_context); } else if (reg == HEX_SREG_SYSCFG) { modify_syscfg(env, val); } else if (reg == HEX_SREG_IMASK) { @@ -2375,10 +2366,7 @@ static inline QEMU_ALWAYS_INLINE void sreg_write(CPUHexagonState *env, hexagon_set_sys_pcycle_count_high(env, val); } else if (!handle_pmu_sreg_write(env, reg, val)) { if (reg >= HEX_SREG_GLB_START) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); ARCH_SET_SYSTEM_REG(env, reg, val); - UNLOCK_IOTHREAD(exception_context); } else { ARCH_SET_SYSTEM_REG(env, reg, val); } @@ -2399,12 +2387,14 @@ void HELPER(check_ccr_write)(CPUHexagonState *env, uint32_t new, uint32_t old) void HELPER(sreg_write)(CPUHexagonState *env, uint32_t reg, uint32_t val) { + BQL_LOCK_GUARD(); sreg_write(env, reg, val); } void HELPER(sreg_write_pair)(CPUHexagonState *env, uint32_t reg, uint64_t val) { + BQL_LOCK_GUARD(); sreg_write(env, reg, val & 0xFFFFFFFF); sreg_write(env, reg + 1, val >> 32); } @@ -2456,12 +2446,11 @@ static void resched(CPUHexagonState *env); void HELPER(setprio)(CPUHexagonState *env, uint32_t thread, uint32_t prio) { - const bool exception_context = qemu_mutex_iothread_locked(); CPUState *cs; g_assert(env->processor_ptr->thread_system_mask != 0); - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); thread &= env->processor_ptr->thread_system_mask; CPU_FOREACH(cs) { HexagonCPU *found_cpu = HEXAGON_CPU(cs); @@ -2471,22 +2460,19 @@ void HELPER(setprio)(CPUHexagonState *env, uint32_t thread, uint32_t prio) qemu_log_mask(CPU_LOG_INT, "%s: tid %d prio = 0x%x\n", __func__, found_env->threadId, prio); resched(env); - UNLOCK_IOTHREAD(exception_context); return; } } - UNLOCK_IOTHREAD(exception_context); /* should never execute */ g_assert_not_reached(); } void HELPER(setimask)(CPUHexagonState *env, uint32_t pred, uint32_t imask) { - const bool exception_context = qemu_mutex_iothread_locked(); CPUState *cs; g_assert(env->processor_ptr->thread_system_mask != 0); - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); pred &= env->processor_ptr->thread_system_mask; CPU_FOREACH(cs) { HexagonCPU *found_cpu = HEXAGON_CPU(cs); @@ -2497,12 +2483,10 @@ void HELPER(setimask)(CPUHexagonState *env, uint32_t pred, uint32_t imask) qemu_log_mask(CPU_LOG_INT, "%s: tid %d imask 0x%x\n", __func__, found_env->threadId, imask); hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); return; } } hex_interrupt_update(env); - UNLOCK_IOTHREAD(exception_context); } void HELPER(start)(CPUHexagonState *env, uint32_t imask) @@ -2515,6 +2499,7 @@ void HELPER(stop)(CPUHexagonState *env) hexagon_stop_thread(env); } + typedef struct { CPUState *cs; CPUHexagonState *env; @@ -2522,7 +2507,6 @@ typedef struct { static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); uint32_t schedcfg; uint32_t schedcfg_en; int int_number; @@ -2531,14 +2515,13 @@ static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env) uint32_t bestwait_reg; uint32_t best_prio; - LOCK_IOTHREAD(exception_context); + BQL_LOCK_GUARD(); qemu_log_mask(CPU_LOG_INT, "%s: check resched\n", __func__); schedcfg = ARCH_GET_SYSTEM_REG(env, HEX_SREG_SCHEDCFG); schedcfg_en = GET_FIELD(SCHEDCFG_EN, schedcfg); int_number = GET_FIELD(SCHEDCFG_INTNO, schedcfg); if (!schedcfg_en) { - UNLOCK_IOTHREAD(exception_context); return; } @@ -2571,7 +2554,6 @@ static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env) SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO, 0x1ff); hex_raise_interrupts(env, 1 << int_number, CPU_INTERRUPT_SWI); } - UNLOCK_IOTHREAD(exception_context); } void HELPER(resched)(CPUHexagonState *env) @@ -2583,6 +2565,8 @@ void HELPER(nmi)(CPUHexagonState *env, uint32_t thread_mask) { bool found = false; CPUState *cs = NULL; + + BQL_LOCK_GUARD(); CPU_FOREACH (cs) { HexagonCPU *cpu = HEXAGON_CPU(cs); CPUHexagonState *thread_env = &cpu->env; @@ -2605,11 +2589,10 @@ void HELPER(nmi)(CPUHexagonState *env, uint32_t thread_mask) */ static uint32_t get_ready_count(CPUHexagonState *env) { - const bool exception_context = qemu_mutex_iothread_locked(); - LOCK_IOTHREAD(exception_context); - uint32_t ready_count = 0; CPUState *cs; + + g_assert(bql_locked()); CPU_FOREACH(cs) { HexagonCPU *cpu = HEXAGON_CPU(cs); CPUHexagonState *thread_env = &cpu->env; @@ -2621,7 +2604,6 @@ static uint32_t get_ready_count(CPUHexagonState *env) ready_count += 1; } } - UNLOCK_IOTHREAD(exception_context); return ready_count; } @@ -2630,6 +2612,7 @@ static uint32_t get_ready_count(CPUHexagonState *env) */ void HELPER(inc_gcycle_xt)(CPUHexagonState *env) { + BQL_LOCK_GUARD(); uint32_t num_threads = get_ready_count(env); if (1 <= num_threads && num_threads <= 6) { env->g_gcycle[num_threads - 1]++; @@ -2639,6 +2622,7 @@ void HELPER(inc_gcycle_xt)(CPUHexagonState *env) void HELPER(cpu_limit)(CPUHexagonState *env, target_ulong PC, target_ulong next_PC) { + BQL_LOCK_GUARD(); uint32_t ready_count = get_ready_count(env); env->gpr[HEX_REG_QEMU_CPU_TB_CNT]++; @@ -2654,6 +2638,7 @@ void HELPER(cpu_limit)(CPUHexagonState *env, target_ulong PC, void HELPER(pending_interrupt)(CPUHexagonState *env) { + BQL_LOCK_GUARD(); hex_interrupt_update(env); } #endif diff --git a/target/hexagon/pmu.h b/target/hexagon/pmu.h index 2528ef039633..c7238e5d1944 100644 --- a/target/hexagon/pmu.h +++ b/target/hexagon/pmu.h @@ -60,17 +60,17 @@ static inline int pmu_committed_pkt_thread(int event) } #define pmu_lock() \ - bool __needs_pmu_lock = !qemu_mutex_iothread_locked(); \ + bool __needs_pmu_lock = !bql_locked(); \ do { \ if (__needs_pmu_lock) { \ - qemu_mutex_lock_iothread(); \ + bql_lock(); \ } \ } while (0) #define pmu_unlock() \ do { \ if (__needs_pmu_lock) { \ - qemu_mutex_unlock_iothread(); \ + bql_unlock(); \ } \ } while (0)