On Wed, Sep 30, 2026 at 10:48:12PM +0100, Mark Brown wrote:

> Fixes: 663abf04ee4d ("KVM: arm64: Make PIR{,E0}_EL1 save/restore conditional 
> on FEAT_TCRX")
> Signed-off-by: Mark Brown <[email protected]>

Great, this looks like the most sensible way of resolving the issue with
userland being able to trigger a kernel oops due to the save/restore
registers optimisations.

It's also entirely sensible to disallow completely broken configurations
like this.

LGTM so:

Reviewed-by: Lorenzo Stoakes (ARM) <[email protected]>

> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 44aae52c473d..3ae293798b27 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c

> @@ -5928,6 +5946,9 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu)
>               kvm_vgic_finalize_idregs(kvm);
>       }
>
> +     if (!kvm_validate_id_regs(vcpu->kvm))
> +             return -EINVAL;
> +

Seems like the right place to put it as part of the finalisation process,
run once per VM and guaranteeing the invariant so it's guaranteed that
ctx_has_s1pie() -> ctxt_has_tcrx() and ctx_has_s1poe() -> ctxt_has_tcrx().

(Just working it through for my own understanding), tracing through it ends
up at struct kvm_arch->id_regs[]:

kvm_has_tcr2()
  -> kvm_has_feat()
    -> __kvm_has_feat()
      -> kvm_cmp_feat()
        -> kvm_cmp_feat_unsigned()
          -> get_idreg_field_unsigned()
            -> kvm_read_vm_id_reg()
              -> __vm_id_reg()
                -> ka->id_regs[]

Which will all have been populated by here. however failing at this point
will stop KVM_ARCH_FLAG_HAS_RUN_ONCE from being set (also obviously your
other series separately fixes the issue with KVM_ARCH_FLAG_FGU_INITIALIZED
being set with !KVM_ARCH_FLAG_HAS_RUN_ONCE).

--
Cheers, Lorenzo

Reply via email to