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