The helper will be called multiple times as we exit a loop and until we actually restart (via arm_cpu_exec_halt) we should leave the condition the same. Fixes: 6fd2fcdc61b (target/arm: teach arm_cpu_has_work about halting reasons) Signed-off-by: Alex Bennée --- include/hw/core/sysemu-cpu-ops.h | 3 +++ target/arm/cpu.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h index 8be6a84bd54..9a45596169a 100644 --- a/include/hw/core/sysemu-cpu-ops.h +++ b/include/hw/core/sysemu-cpu-ops.h @@ -18,6 +18,9 @@ typedef struct SysemuCPUOps { /** * @has_work: Callback for checking if there is work to do. + * + * This function should be idempotent (i.e. not change state) as + * it will likely be queried multiple times before a CPU resumes. */ bool (*has_work)(CPUState *cpu); /* MANDATORY NON-NULL */ /** diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 86aae36ae55..597e0626e7f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -158,7 +158,6 @@ static bool arm_cpu_has_work(CPUState *cs) * A wake-up event should only wake us if we are halted on a WFE */ if (cpu->env.halt_reason == HALT_WFE && cpu->env.event_register) { - cpu->env.halt_reason = NOT_HALTED; return true; } @@ -170,7 +169,6 @@ static bool arm_cpu_has_work(CPUState *cs) | CPU_INTERRUPT_NMI | CPU_INTERRUPT_VINMI | CPU_INTERRUPT_VFNMI | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR | CPU_INTERRUPT_EXITTB)) { - cpu->env.halt_reason = NOT_HALTED; return true; } @@ -878,6 +876,8 @@ bool arm_cpu_exec_halt(CPUState *cs) if (cpu->wfxt_timer) { timer_del(cpu->wfxt_timer); } + /* clear the halt reason */ + cpu->env.halt_reason = NOT_HALTED; } return leave_halt; } -- 2.47.3