[PATCH v3 16/18] KVM: arm64: Reject host power-on of a vCPU that EL2 holds powered off

Marc Zyngier maz at kernel.org
Wed Sep 16 09:43:20 PDT 2026


On Mon, 14 Sep 2026 12:33:36 +0100,
Fuad Tabba <fuad.tabba at linux.dev> 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 at linux.dev>
> ---
>  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.



More information about the linux-arm-kernel mailing list