Re: [PATCH 2/2] KVM: arm64: Block ID register changes after we rely on the values

From: Fuad Tabba

Date: Sun Aug 02 2026 - 13:14:24 EST


Hi Mark,

On Fri, 31 Jul 2026 at 21:46, Mark Brown <broonie@xxxxxxxxxx> wrote:
...
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 958d7ef78785..3b423db56d3c 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2427,9 +2427,10 @@ static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>
> /*
> * Once the VM has started the ID registers are immutable. Reject any
> - * write that does not match the final register value.
> + * write that does not match the final register value once we have
> + * got far enough into first running the VM to use the values.
> */
> - if (kvm_vm_has_ran_once(vcpu->kvm)) {
> + if (vcpu_id_regs_final(vcpu)) {
> if (val != read_id_reg(vcpu, rd))
> ret = -EBUSY;
...
> @@ -5811,6 +5812,8 @@ static int kvm_vm_finalize_sys_regs(struct kvm *kvm)
> kvm_vgic_finalize_idregs(kvm);
> }
>
> + set_bit(KVM_ARCH_FLAG_ID_REGS_FINAL, &kvm->arch.flags);
> +
> return 0;
> }
>

The flag fixes this. One consistency point: set_id_reg() and
set_imp_id_reg() now gate on the new flag, but
kvm_vm_finalize_sys_regs() still returns early on
kvm_vm_has_ran_once(), and so does the KVM_BUG_ON() in
kvm_set_vm_id_reg(). Could both move to kvm_id_regs_final(), so one
predicate expresses the invariant? If so I think they would need to
move together, since on a retried first run kvm_vm_finalize_sys_regs()
re-runs and re-writes the ID regs via kvm_set_vm_id_reg(), so
switching only the BUG_ON would trip it.

Separately, would a selftest for that failed-run path be worth adding,
checking that KVM_SET_ONE_REG on an ID reg and KVM_CREATE_DEVICE both
return -EBUSY?

Cheers,
/fuad