Use qatomic_set() when updating ARMCPU::power_state and CPUARMState::halt_reason. Read ARMCPU::power_state atomically in arm_cpu_has_work(), which can run without the BQL held.
Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- target/arm/arm-powerctl.c | 5 +++-- target/arm/cpu.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c index 1bd8a549cc9..fcac26d9190 100644 --- a/target/arm/arm-powerctl.c +++ b/target/arm/arm-powerctl.c @@ -50,8 +50,9 @@ void arm_set_cpu_power_state(ARMCPU *cpu, ARMPSCIState state) CPUARMState *env = &cpu->env; CPUState *cs = CPU(cpu); - cpu->power_state = state; - env->halt_reason = state == PSCI_OFF ? HALT_PSCI : NOT_HALTED; + qatomic_set(&cpu->power_state, state); + qatomic_set(&env->halt_reason, state == PSCI_OFF ? HALT_PSCI + : NOT_HALTED); if (!qemu_cpu_is_self(cs)) { qemu_cpu_kick(cs); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 76aa47ac503..5cfd3bcfc8e 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -149,7 +149,7 @@ static bool arm_cpu_has_work(CPUState *cs) * Only another PSCI call can wake the CPU up in which case the * power_state would be set by arm_set_cpu_on_and_reset_async_work() */ - if (cpu->power_state == PSCI_OFF) { + if (qatomic_read(&cpu->power_state) == PSCI_OFF) { g_assert(cpu->env.halt_reason == HALT_PSCI); return false; } -- 2.53.0
