From: "Alex Bennée" <alex.bennee@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org, Alexander Graf <agraf@csgraf.de>,
qemu-arm@nongnu.org, Pedro Barbuda <pbarbuda@microsoft.com>,
Mohamed Mediouni <mohamed@unpredictable.fr>
Subject: Re: [RFC PATCH 24/35] target/arm: remove event_register check from arm_cpu_has_work
Date: Fri, 10 Apr 2026 17:19:42 +0100 [thread overview]
Message-ID: <87y0iuiy8x.fsf@draig.linaro.org> (raw)
In-Reply-To: <87h5pjjgyj.fsf@draig.linaro.org> ("Alex Bennée"'s message of "Fri, 10 Apr 2026 10:35:32 +0100")
Alex Bennée <alex.bennee@linaro.org> writes:
> Peter Maydell <peter.maydell@linaro.org> writes:
>
>> On Fri, 20 Mar 2026 at 13:16, Alex Bennée <alex.bennee@linaro.org> wrote:
>>>
>>> The generation of events are not indications of work to be done and
>>> importantly for the case of WFI instructions not a reason to wake up.
>>> Remove the check.
>>
>> But an event *is* a reason for WFE to wake up, which is why this
>> check is here. In particular, the thing that tells accel/tcg
>> that the CPU should come out of halt (via cpu_handle_halt())
>> is whether cpu_exec_halt / cpu_has_work returns true. If we
>> don't check the event register here then another CPU setting
>> the event register won't cause this one to come out of WFE.
>
> So for the same-CPU case we do because we signal cpu_interrupt(cs,
> CPU_INTERRUPT_EXITTB) which is enough for has_work to return true but I
> can see the failure mode for cross-cpu SEV's when we kick all vCPUs in
> the helper would get stuck.
>
>> If we want to have WFE and WFI wakeup events to be separated
>> such that only WFE wakeup events resume a WFE and only
>> WFI wakeup events resume a WFI then we need to do something
>> more clever here, so that we track whether we're halted for
>> WFI, WFE, PSCI-power-off or whatever and our has_work function
>> can check the right condition.
>
> I guess we can add a cpu->halt_reason? I've already had to add a
> cpu->waiting_for_event for arm_wfxt_timer_cb and I guess it would be
> better to generalise that.
>
>> (Side question: are the only
>> cases where our arm CPUs halt WFE, WFI, power-off, or are
>> there any others I forgot about?)
>
> The only others I can find are debug events which all have their own
> logic (and we don't have "external" debug events modelled). YIELD is
> still a NOP and not really a sleep.
>
>> Incidentally, looking at the code above it will need fixing
>> for A-profile anyway, because a CPU in PSCI-power-off should
>> not be woken up by a WFE event. We get away with doing the
>> WFE event register check first because M-profile doesn't use
>> the PSCI powerdown stuff.
>
> Ok, that seals it.
I'm thinking something like this:
--8<---------------cut here---------------start------------->8---
modified target/arm/cpu.h
@@ -257,6 +257,19 @@ typedef enum ARMFPStatusFlavour {
} ARMFPStatusFlavour;
#define FPST_COUNT 10
+/**
+ * ARMHaltReason - the reason we have entered halt state
+ *
+ * To be able to correctly wake up via arm_cpu_has_work() we need to
+ * track the reason we went to sleep.
+ */
+typedef enum {
+ NOT_HALTED = 0,
+ HALT_PSCI,
+ HALT_WFI,
+ HALT_WFE
+} ARMHaltReason;
+
typedef struct CPUArchState {
/* Regs for current mode. */
uint32_t regs[16];
@@ -760,6 +773,9 @@ typedef struct CPUArchState {
/* Optional fault info across tlb lookup. */
ARMMMUFaultInfo *tlb_fi;
+ /* Reason the CPU is halted */
+ ARMHaltReason halt_reason;
+
/*
* The event register is shared by all ARM profiles (A/R/M),
* so it is stored in the top-level CPU state.
modified target/arm/arm-powerctl.c
@@ -78,6 +78,7 @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
/* Finally set the power status */
assert(bql_locked());
+ target_cpu->env.halt_reason = NOT_HALTED;
target_cpu->power_state = PSCI_ON;
}
@@ -240,6 +241,7 @@ static void arm_set_cpu_off_async_work(CPUState *target_cpu_state,
assert(bql_locked());
target_cpu->power_state = PSCI_OFF;
+ target_cpu->env.halt_reason = HALT_PSCI;
target_cpu_state->halted = 1;
target_cpu_state->exception_index = EXCP_HLT;
}
modified target/arm/cpu.c
@@ -144,18 +144,36 @@ static bool arm_cpu_has_work(CPUState *cs)
{
ARMCPU *cpu = ARM_CPU(cs);
- if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
- if (cpu->env.event_register) {
- return true;
- }
+ /*
+ * Only another PSCI call can wake the CPU up in which case the
+ * power_state would be set by reset.
+ */
+ if (cpu->power_state == PSCI_OFF) {
+ g_assert(cpu->env.halt_reason == HALT_PSCI);
+ return false;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Otherwise pretty much any IRQ would wake us up
+ */
+ if (cpu_test_interrupt(cs,
+ CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
+ | 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;
}
- return (cpu->power_state != PSCI_OFF)
- && cpu_test_interrupt(cs,
- CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
- | CPU_INTERRUPT_NMI | CPU_INTERRUPT_VINMI | CPU_INTERRUPT_VFNMI
- | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
- | CPU_INTERRUPT_EXITTB);
+ return false;
}
#endif /* !CONFIG_USER_ONLY */
modified target/arm/tcg/op_helper.c
@@ -403,6 +403,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
target_el);
}
+ env->halt_reason = HALT_WFI;
cs->exception_index = EXCP_HLT;
cs->halted = 1;
cpu_loop_exit(cs);
@@ -464,6 +465,7 @@ void HELPER(wfit)(CPUARMState *env, uint32_t rd)
} else {
timer_mod(cpu->wfxt_timer, nexttick);
}
+ env->halt_reason = HALT_WFI;
cs->exception_index = EXCP_HLT;
cs->halted = 1;
cpu_loop_exit(cs);
@@ -508,6 +510,7 @@ void HELPER(wfe)(CPUARMState *env)
return;
}
+ env->halt_reason = HALT_WFE;
cs->exception_index = EXCP_HLT;
cs->halted = 1;
cpu_loop_exit(cs);
--8<---------------cut here---------------end--------------->8---
>
>>
>> thanks
>> -- PMM
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2026-04-10 16:20 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-20 13:05 [RFC PATCH 00/35] target/arm: fully model WFxT instructions for A-profile Alex Bennée
2026-03-20 13:05 ` [RFC PATCH 01/35] target/arm: migrate basic syndrome helpers to registerfields Alex Bennée
2026-04-01 5:36 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 02/35] target/arm: migrate system/cp trap syndromes " Alex Bennée
2026-04-01 5:39 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 03/35] target/arm: migrate FP/SIMD " Alex Bennée
2026-04-01 5:43 ` Richard Henderson
2026-04-01 12:50 ` Alex Bennée
2026-04-01 15:48 ` Peter Maydell
2026-04-01 17:54 ` Pierrick Bouvier
2026-03-20 13:05 ` [RFC PATCH 04/35] target/arm: migrate eret " Alex Bennée
2026-04-05 23:21 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 05/35] target/arm: migrate SME " Alex Bennée
2026-04-05 23:22 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 06/35] target/arm: migrate PAC " Alex Bennée
2026-04-05 23:23 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 07/35] target/arm: migrate BTI " Alex Bennée
2026-04-05 23:28 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 08/35] target/arm: migrate BXJ " Alex Bennée
2026-04-05 23:29 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 09/35] target/arm: migrate Granule Protection traps " Alex Bennée
2026-04-05 23:30 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 10/35] target/arm: migrate fault syndromes " Alex Bennée
2026-04-05 23:32 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 11/35] target/arm: migrate debug " Alex Bennée
2026-04-05 23:37 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 12/35] target/arm: migrate wfx " Alex Bennée
2026-04-05 23:41 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 13/35] target/arm: migrate gcs " Alex Bennée
2026-04-05 23:43 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 14/35] target/arm: migrate memory op " Alex Bennée
2026-04-05 23:44 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 15/35] target/arm: migrate check_hcr_el2_trap to use syndrome helper Alex Bennée
2026-04-06 0:01 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 16/35] target/arm: use syndrome helpers in arm_cpu_do_interrupt_aarch32_hyp Alex Bennée
2026-04-06 0:06 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 17/35] target/arm: use syndrome helpers to set SAME_EL EC bit Alex Bennée
2026-04-06 0:07 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 18/35] target/arm: make whpx use syndrome helpers for decode Alex Bennée
2026-04-06 0:08 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 19/35] target/arm: make hvf " Alex Bennée
2026-04-06 0:08 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 20/35] target/arm: use syndrome helpers in merge_syn_data_abort Alex Bennée
2026-04-06 0:15 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 21/35] target/arm: use syndrome helpers to query VNCR bit Alex Bennée
2026-04-06 0:17 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 22/35] target/arm: remove old syndrome defines Alex Bennée
2026-04-06 0:17 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 23/35] target/arm: report register in WFIT syndromes Alex Bennée
2026-04-06 0:24 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 24/35] target/arm: remove event_register check from arm_cpu_has_work Alex Bennée
2026-04-10 8:47 ` Peter Maydell
2026-04-10 9:35 ` Alex Bennée
2026-04-10 16:19 ` Alex Bennée [this message]
2026-03-20 13:05 ` [RFC PATCH 25/35] target/arm: redefine event stream fields Alex Bennée
2026-04-06 0:30 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 26/35] target/arm: add gt_calc_next_event_stream Alex Bennée
2026-04-06 0:34 ` Richard Henderson
2026-03-20 13:05 ` [RFC PATCH 27/35] target/arm: wrap event_register in a union Alex Bennée
2026-04-06 0:37 ` Richard Henderson
2026-04-07 10:35 ` Alex Bennée
2026-04-08 5:41 ` Richard Henderson
2026-04-08 9:57 ` Peter Maydell
2026-03-20 13:05 ` [RFC PATCH 28/35] target/arm: ensure aarch64 DISAS_WFE will exit Alex Bennée
2026-04-06 3:00 ` Richard Henderson
2026-03-20 13:06 ` [RFC PATCH 29/35] target/arm: implements SEV/SEVL for all modes Alex Bennée
2026-04-06 3:22 ` Richard Henderson
2026-03-20 13:06 ` [RFC PATCH 30/35] target/arm: implement global monitor events Alex Bennée
2026-04-10 9:16 ` Peter Maydell
2026-03-20 13:06 ` [RFC PATCH 31/35] target/arm: enable event stream on WFE instructions Alex Bennée
2026-03-20 13:06 ` [RFC PATCH 32/35] target/arm: implement WFET Alex Bennée
2026-03-20 13:06 ` [RFC PATCH 33/35] tests/tcg: split stage 1 between devices and RAM Alex Bennée
2026-03-20 13:06 ` [RFC PATCH 34/35] tests/tcg: create a mini-gic3 library Alex Bennée
2026-03-20 13:06 ` [RFC PATCH 35/35] tests/tcg: add basic test for aarch64 wf[ie][t] insns Alex Bennée
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y0iuiy8x.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=agraf@csgraf.de \
--cc=mohamed@unpredictable.fr \
--cc=pbarbuda@microsoft.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.