From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Mark Brown <broonie@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>,
Joey Gouly <joey.gouly@arm.com>,
Steffen Eiden <seiden@linux.ibm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Fuad Tabba <fuad.tabba@linux.dev>,
Peter Maydell <peter.maydell@linaro.org>,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 1/3] KVM: arm64: Finalize guest-wide sysregs prior to per-vCPU sysregs
Date: Mon, 28 Sep 2026 14:26:39 +0100 [thread overview]
Message-ID: <arpdF-fHx54xWiZB@gremlin> (raw)
In-Reply-To: <20260901-kvm-arm64-idreg-final-v3-1-a0ffa06fa872@kernel.org>
On Tue, Sep 01, 2026 at 07:18:48PM +0100, Mark Brown wrote:
> In commit d82d09d5ba4b ("KVM: arm64: Don't skip per-vcpu NV
> initialisation") the NV register sanitisation was moved earlier in
> kvm_finalize_sys_regs() so that it runs for each vCPU rather than only
> once per guest. This means that for the first vCPU it runs prior to vGIC
> finalization, but the vGIC finalization updates the ID registers which
> the NV initialization uses so we may end up with a mismatch. For
> example, HFGRTR_EL2.ICC_IGRPENn_EL1 depends on GICv3 being enabled in
> ID_AA64PFR0_EL1.GIC so may be mistakenly marked or not marked as RES0.
Hand me some rope here, but I'm thinking this GIC case is because of:
kvm_init_nv_sysregs()
-> get_reg_fixed_bits(kvm, HFGRTR_EL2)
-> compute_reg_resx_bits()
-> compute_resx_bits()
[ does the dependency checks ]
?
Generally speaking it seems like a good idea that the broader system
registers are set up prior to nested in any case.
>
> Split the initialization which runs once per guest into a separate
> function and run that before the per-vCPU initialisation for NV,
> renaming the per-vCPU function to make it clear that it does per-vCPU
> setup.
>
> Fixes: d82d09d5ba4b ("KVM: arm64: Don't skip per-vcpu NV initialisation")
> Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
> Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
> Signed-off-by: Mark Brown <broonie@kernel.org>
One nit below but LGTM, so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> arch/arm64/kvm/arm.c | 2 +-
> arch/arm64/kvm/sys_regs.c | 40 ++++++++++++++++++++++++++--------------
> arch/arm64/kvm/sys_regs.h | 2 +-
> 3 files changed, 28 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 8b080804bc90..4f044280dec0 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -949,7 +949,7 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> return ret;
> }
>
> - ret = kvm_finalize_sys_regs(vcpu);
> + ret = kvm_vcpu_finalize_sys_regs(vcpu);
> if (ret)
> return ret;
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 44aae52c473d..880f84248427 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -5861,25 +5861,14 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
> }
>
> /*
> - * Perform last adjustments to the ID registers that are implied by the
> + * Do system register finalization that is shared by the whole guest. This
> + * includes last adjustments to the ID registers that are implied by the
> * configuration outside of the ID regs themselves, as well as any
> * initialisation that directly depend on these ID registers (such as
> * RES0/RES1 behaviours). This is not the place to configure traps though.
> - *
> - * Because this can be called once per CPU, changes must be idempotent.
> */
> -int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu)
> +static int kvm_vm_finalize_sys_regs(struct kvm *kvm)
> {
> - struct kvm *kvm = vcpu->kvm;
> -
> - guard(mutex)(&kvm->arch.config_lock);
NIT: Maybe worth a comment or an assert that the config_lock is held here?
> -
> - if (vcpu_has_nv(vcpu)) {
> - int ret = kvm_init_nv_sysregs(vcpu);
> - if (ret)
> - return ret;
> - }
> -
> if (kvm_vm_has_ran_once(kvm))
> return 0;
>
> @@ -5931,6 +5920,29 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu)
> return 0;
> }
>
> +/*
> + * Because this can be called once per CPU, changes must be idempotent.
> + */
> +int kvm_vcpu_finalize_sys_regs(struct kvm_vcpu *vcpu)
> +{
> + struct kvm *kvm = vcpu->kvm;
> + int ret;
> +
> + guard(mutex)(&kvm->arch.config_lock);
> +
> + ret = kvm_vm_finalize_sys_regs(kvm);
> + if (ret)
> + return ret;
> +
> + if (vcpu_has_nv(vcpu)) {
> + ret = kvm_init_nv_sysregs(vcpu);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> int __init kvm_sys_reg_table_init(void)
> {
> const struct sys_reg_desc *gicv3_regs;
> diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
> index bd56a45abbf9..a3cccad2766f 100644
> --- a/arch/arm64/kvm/sys_regs.h
> +++ b/arch/arm64/kvm/sys_regs.h
> @@ -254,7 +254,7 @@ int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
>
> bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index);
>
> -int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu);
> +int kvm_vcpu_finalize_sys_regs(struct kvm_vcpu *vcpu);
>
> #define AA32(_x) .aarch32_map = AA32_##_x
> #define Op0(_x) .Op0 = _x
>
> --
> 2.47.3
>
>
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-09-28 13:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 18:18 [PATCH v3 0/3] KVM: arm64: ID register finalisation fixes Mark Brown
2026-09-01 18:18 ` [PATCH v3 1/3] KVM: arm64: Finalize guest-wide sysregs prior to per-vCPU sysregs Mark Brown
2026-09-01 18:43 ` sashiko-bot
2026-09-28 13:26 ` Lorenzo Stoakes (ARM) [this message]
2026-09-01 18:18 ` [PATCH v3 2/3] KVM: arm64: Block ID register changes after we rely on the values Mark Brown
2026-09-28 14:36 ` Lorenzo Stoakes (ARM)
2026-09-28 16:22 ` Mark Brown
2026-09-01 18:18 ` [PATCH v3 3/3] KVM: arm64: selftests: Check ID regs are immutable after a failed run Mark Brown
2026-09-28 14:46 ` Lorenzo Stoakes (ARM)
2026-09-28 16:31 ` Mark Brown
2026-09-29 9:57 ` Lorenzo Stoakes (ARM)
2026-09-28 16:56 ` Fuad Tabba
2026-09-29 9:57 ` Lorenzo Stoakes (ARM)
2026-09-28 14:52 ` [PATCH v3 0/3] KVM: arm64: ID register finalisation fixes Lorenzo Stoakes (ARM)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=arpdF-fHx54xWiZB@gremlin \
--to=ljs@kernel.org \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=fuad.tabba@linux.dev \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=peter.maydell@linaro.org \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.