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

From: Fuad Tabba

Date: Wed Sep 16 2026 - 15:25:59 EST


Hi Marc,

On Wed, 16 Sept 2026 at 17:43, Marc Zyngier <maz@xxxxxxxxxx> wrote:
[...]
> > 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?

Yes. The bool kept the VMM's STOPPED and EL2's off apart without a new
userspace-visible value, but a distinct mp_state value does that and
lets the VMM see why RUNNABLE is rejected.

It's set where the bool is set today, on the guest's CPU_OFF and at
hyp vCPU creation for a vCPU that starts STOPPED, and only the guest's
CPU_ON sets it back to RUNNABLE. KVM_SET_MP_STATE returns -EPERM for
RUNNABLE and SUSPENDED on it and -EINVAL for the value itself, STOPPED
and kvm_prepare_system_event() leave it in place, and
kvm_arm_vcpu_stopped() returns true for it.

KVM_MP_STATE_UNINITIALIZED looks like the closest fit, a vCPU the
guest has yet to bring up. I'll use that in v4 unless you'd rather
another.

Cheers,
/fuad