Re: [PATCH v3 16/18] KVM: arm64: Reject host power-on of a vCPU that EL2 holds powered off
From: Marc Zyngier
Date: Wed Sep 16 2026 - 12:51:26 EST
On Mon, 14 Sep 2026 12:33:36 +0100,
Fuad Tabba <fuad.tabba@xxxxxxxxx> wrote:
>
> A protected vCPU's power state belongs to EL2, which changes it only
> on the guest's own PSCI calls. KVM_SET_MP_STATE(RUNNABLE) on a vCPU
> EL2 holds powered off changes the host's copy alone, and the guest's
> next CPU_ON of that vCPU then fails: mp_state is no longer STOPPED, so
> the host returns ALREADY_ON, and the guest's retry fails the same way
> until the VMM stops the vCPU again. SUSPENDED has the same effect.
>
> Track at the host whether EL2 holds a protected vCPU powered off and
> return -EPERM for both writes in that state. STOPPED stays permitted,
> so a VMM can pause a vCPU, and RUNNABLE on a vCPU EL2 has powered on,
> so it can resume one.
>
> The guest's CPU_ON is gated on the same record rather than on STOPPED.
> A VMM that sets STOPPED between the target's CPU_OFF exit and the
> host's power-off of it would otherwise let the CPU_ON through, and the
> power-off would then record the target powered off while EL2 holds it
> ON_PENDING, with no way back before VM teardown. Gated on the record,
> that CPU_ON returns ALREADY_ON and the retry succeeds once the
> power-off has run.
>
> Signed-off-by: Fuad Tabba <fuad.tabba@xxxxxxxxx>
> ---
> arch/arm64/include/asm/kvm_host.h | 2 ++
> arch/arm64/kvm/arm.c | 19 +++++++++++++++++++
> arch/arm64/kvm/pkvm.c | 21 +++++++++++++++++----
> arch/arm64/kvm/psci.c | 10 +++++++++-
> 4 files changed, 47 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 37d0721d39a45..2e2c051dd8e62 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -922,6 +922,8 @@ struct kvm_vcpu_arch {
> /* vcpu power state */
> struct kvm_mp_state mp_state;
> spinlock_t mp_state_lock;
> + /* EL2 holds the protected vCPU powered off. Under mp_state_lock. */
> + bool pkvm_powered_off;
I'm definitely not keen on yet another random boolean to describe some
new state. We already have mp_state. Why can't we use one of the
unused encodings and check that, since it very much looks like a case
of "let userspace change the MP_STATE unless EL2 says otherwise".
Can that be made to work?
M.
--
Without deviation from the norm, progress is not possible.