From: sashiko-bot@kernel.org
To: "Shivansh Dhiman" <shivansh.dhiman@amd.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v2 09/12] KVM: nSVM: Propagate LBRv2 state across nested transitions
Date: Mon, 19 Oct 2026 21:31:17 +0000 [thread overview]
Message-ID: <sashiko-outbox-178260@kernel.org> (raw)
In-Reply-To: <20261019210532.378628-10-shivansh.dhiman@amd.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] KVM: nSVM: wrong LBRv2 capability checks in svm_copy_vmrun_state() and nested.c
- [High] KVM: nSVM: missing mediated PMU check for LBRv2 in nested transitions
- [High] KVM: nSVM: missing svm_update_lbrv() in svm_set_nested_state()
--
commit a61dcc1b0377ffbac74e374ce3dc16b1683a68e0
Author: Shivansh Dhiman <shivansh.dhiman@amd.com>
KVM: nSVM: Propagate LBRv2 state across nested transitions
This commit adds the svm_copy_lbrs_v2() macro and updates nested SVM
transitions (VMRUN, #VMEXIT, and VMCB state caching/copying) to propagate
LBRv2 state between vmcb01, vmcb02, and vmcb12.
> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> index af0ef678433d7..b356a091e320c 100644
> --- a/arch/x86/kvm/svm/nested.c
> +++ b/arch/x86/kvm/svm/nested.c
> @@ -608,6 +608,9 @@ static void __nested_copy_vmcb_save_to_cache(struct vmcb_save_area_cached *to,
> to->g_pat = from->g_pat;
>
> svm_copy_lbrs(to, from);
> +
> + if (kvm_cpu_cap_has(X86_FEATURE_AMD_LBR_V2))
> + svm_copy_lbrs_v2(to, from);
> }
>
> void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm,
> @@ -819,8 +822,17 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm)
> */
> svm_copy_lbrs(&vmcb02->save, save);
> vmcb02->save.dbgctl &= svm_get_supported_debugctl(vcpu);
> +
> + if (guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2)) {
> + svm_copy_lbrs_v2(&vmcb02->save, save);
> + vmcb02->save.dbg_extn_cfg &= ~DBG_EXTN_CFG_RESERVED_BITS;
> + vmcb02->save.lbr_select &= ~LBR_SELECT_RESERVED_BITS;
> + }
> } else {
> svm_copy_lbrs(&vmcb02->save, &vmcb01->save);
> +
> + if (guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2))
> + svm_copy_lbrs_v2(&vmcb02->save, &vmcb01->save);
> }
> vmcb_mark_dirty(vmcb02, VMCB_LBR);
> svm_update_lbrv(&svm->vcpu);
[Severity: High]
Should the checks in nested_vmcb02_prepare_save() (as well as
nested_svm_vmexit_update_vmcb12() and nested_svm_vmexit() below) use
svm_lbrv2_supported(vcpu) instead of only checking
guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2)?
In arch/x86/kvm/svm/svm.c, per-vCPU LBRv2 support is gated by
svm_lbrv2_supported(vcpu), which requires both X86_FEATURE_AMD_LBR_V2 and
kvm_vcpu_has_mediated_pmu(vcpu):
arch/x86/kvm/svm/svm.c:svm_lbrv2_supported() {
return guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2) &&
kvm_vcpu_has_mediated_pmu(vcpu);
}
All L1 MSR accesses (svm_get_msr(), svm_set_msr()) and intercept
calculations (svm_lbrv2_active(), svm_recalc_lbrv2_msr_intercepts()) check
svm_lbrv2_supported(vcpu) because hardware LBRv2 requires the mediated PMU
to schedule out host perf contexts via perf_load_guest_context().
If a VM is configured where guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2)
is true in guest CPUID, but kvm_vcpu_has_mediated_pmu(vcpu) is false (for
example, if the PMU is disabled via KVM_CAP_PMU_CAPABILITY with
KVM_PMU_CAP_DISABLE, or when running without an in-kernel irqchip), L1 can
set SVM_MISC2_ENABLE_V_LBR in vmcb12->control.misc_ctl2 and
DBG_EXTN_CFG_LBRV2EN in vmcb12->save.dbg_extn_cfg and execute VMRUN.
nested_vmcb02_prepare_save() will copy save->dbg_extn_cfg, save->lbr_select,
and save->lbr[] into vmcb02->save, and svm_update_lbrv() will enable
SVM_MISC2_ENABLE_V_LBR in vmcb02->control.misc_ctl2. On VMRUN of vmcb02,
hardware will load vmcb02->save.dbg_extn_cfg with DBG_EXTN_CFG_LBRV2EN set
and record branches into the hardware LBR stack while L2 executes, even
though kvm_mediated_pmu_load() did not call perf_load_guest_context() to
switch out host perf LBRv2 state.
> @@ -1236,6 +1248,12 @@ void svm_copy_vmrun_state(struct kvm_vcpu *vcpu, struct vmcb_save_area *to_save,
> svm_copy_lbrs(to_save, from_save);
> to_save->dbgctl &= svm_get_supported_debugctl(vcpu);
> }
> +
> + if (kvm_cpu_cap_has(X86_FEATURE_AMD_LBR_V2)) {
> + svm_copy_lbrs_v2(to_save, from_save);
> + to_save->dbg_extn_cfg &= ~DBG_EXTN_CFG_RESERVED_BITS;
> + to_save->lbr_select &= ~LBR_SELECT_RESERVED_BITS;
> + }
> }
[Severity: High]
Can gating svm_copy_vmrun_state() (and __nested_copy_vmcb_save_to_cache()
above) on the host capability kvm_cpu_cap_has(X86_FEATURE_AMD_LBR_V2)
instead of svm_lbrv2_supported(vcpu) corrupt L1's HSAVE page on SMM entry
and allow L1 to activate hardware LBRv2 when LBRv2 is not enabled for the
vCPU?
When an SMI arrives while a vCPU without LBRv2 enabled is running L2,
svm_enter_smm() calls svm_copy_vmrun_state():
arch/x86/kvm/svm/svm.c:svm_enter_smm() {
...
svm_copy_vmrun_state(vcpu, m_save.map.hva + 0x400, &svm->vmcb01.ptr->save);
...
}
Because svm_copy_vmrun_state() checks
kvm_cpu_cap_has(X86_FEATURE_AMD_LBR_V2), KVM writes 272 bytes (dbg_extn_cfg
at offset 0x698, lbr[16] at 0xa70..0xb6f, and lbr_select at 0xb70) into L1's
MSR_VM_HSAVE_PA page even when LBRv2 is not exposed to the guest.
Conversely, on RSM in svm_leave_smm() or during KVM_SET_NESTED_STATE in
svm_set_nested_state():
arch/x86/kvm/svm/svm.c:svm_leave_smm() {
...
svm_copy_vmrun_state(vcpu, &svm->vmcb01.ptr->save, m_save.map.hva + 0x400);
...
}
svm_copy_vmrun_state() copies dbg_extn_cfg (including DBG_EXTN_CFG_LBRV2EN),
lbr_select, and lbr[16] from the guest-controlled HSAVE page (or userspace
buffer) into vmcb01->save even when !svm_lbrv2_supported(vcpu). On a
subsequent nested #VMEXIT from L2 to L1, nested_svm_vmexit() skips
svm_copy_lbrs_v2(&vmcb01->save, &vmcb02->save) because
guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2) is false, leaving
DBG_EXTN_CFG_LBRV2EN set in vmcb01->save.dbg_extn_cfg. If L1 then enables
SVM_MISC2_ENABLE_V_LBR (for example, by setting DEBUGCTLMSR_LBR in
MSR_IA32_DEBUGCTLMSR), hardware VMRUN will load vmcb01->save.dbg_extn_cfg
into physical hardware.
[Severity: High]
Also, when svm_set_nested_state() calls svm_copy_vmrun_state() to restore
nested state while in guest mode, does svm_set_nested_state() also need a
call to svm_update_lbrv(vcpu)?
During nested state restore in svm_set_nested_state():
arch/x86/kvm/svm/nested.c:svm_set_nested_state() {
...
svm_copy_vmrun_state(vcpu, &svm->vmcb01.ptr->save, save);
nested_copy_vmcb_control_to_cache(svm, ctl);
svm_switch_vmcb(svm, &svm->nested.vmcb02);
if (use_separate_l2_pat)
vmcb_set_gpat(svm->vmcb, kvm_state->hdr.svm.gpat);
nested_vmcb02_prepare_control(svm);
...
}
nested_vmcb02_prepare_control() leaves SVM_MISC2_ENABLE_V_LBR to
svm_update_lbrv(), which is normally called at the end of
nested_vmcb02_prepare_save() during VMRUN, but svm_set_nested_state() never
calls nested_vmcb02_prepare_save() or svm_update_lbrv(vcpu).
If userspace restores MSRs via KVM_SET_MSRS before KVM_SET_NESTED_STATE,
svm_set_msr() for MSR_AMD_DBG_EXTN_CFG (with DBG_EXTN_CFG_LBRV2EN) or
MSR_IA32_DEBUGCTLMSR (with DEBUGCTLMSR_LBR) runs while svm->vmcb points to
vmcb01. svm_update_lbrv() sets SVM_MISC2_ENABLE_V_LBR in
vmcb01->control.misc_ctl2 and disables interception of the LBR/LBRv2 MSRs in
svm->msrpm. When svm_set_nested_state() then moves vmcb01->save to
vmcb02->save and switches to vmcb02 without calling svm_update_lbrv(vcpu),
vmcb02->control.misc_ctl2 is left with SVM_MISC2_ENABLE_V_LBR cleared while
the LBR/LBRv2 MSRs remain unintercepted in msrpm01/msrpm02.
Even if KVM_SET_NESTED_STATE is called before KVM_SET_MSRS, if L1 enabled
SVM_MISC2_ENABLE_V_LBR in vmcb12 while L2's dbgctl and dbg_extn_cfg are 0,
svm_set_msr() breaks out early because the save area values are already 0,
leaving SVM_MISC2_ENABLE_V_LBR cleared in vmcb02->control.misc_ctl2.
[ ... ]
> @@ -1305,9 +1323,13 @@ static int nested_svm_vmexit_update_vmcb12(struct kvm_vcpu *vcpu)
> if (guest_cpu_cap_has(vcpu, X86_FEATURE_NRIPS))
> vmcb12->control.next_rip = vmcb02->control.next_rip;
>
> - if (svm->nested.ctl.misc_ctl2 & SVM_MISC2_ENABLE_V_LBR)
> + if (svm->nested.ctl.misc_ctl2 & SVM_MISC2_ENABLE_V_LBR) {
> svm_copy_lbrs(&vmcb12->save, &vmcb02->save);
>
> + if (guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2))
> + svm_copy_lbrs_v2(&vmcb12->save, &vmcb02->save);
> + }
> +
> vmcb12->control.event_inj = 0;
> vmcb12->control.event_inj_err = 0;
> vmcb12->control.int_ctl = svm->nested.ctl.int_ctl;
> @@ -1384,6 +1406,10 @@ void nested_svm_vmexit(struct vcpu_svm *svm)
>
> if (!(svm->nested.ctl.misc_ctl2 & SVM_MISC2_ENABLE_V_LBR)) {
> svm_copy_lbrs(&vmcb01->save, &vmcb02->save);
> +
> + if (guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_LBR_V2))
> + svm_copy_lbrs_v2(&vmcb01->save, &vmcb02->save);
> +
> vmcb_mark_dirty(vmcb01, VMCB_LBR);
> }
>
[ ... ]
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261019210532.378628-1-shivansh.dhiman@amd.com?part=9
next prev parent reply other threads:[~2026-10-19 21:31 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 21:05 [PATCH v2 00/12] KVM: SVM: Add support for AMD LBR Extension v2 Shivansh Dhiman
2026-10-19 21:05 ` [PATCH v2 01/12] KVM: SVM: Add VMCB fields for LBRv2 virtualization Shivansh Dhiman
2026-10-19 22:09 ` Jim Mattson
2026-10-19 21:05 ` [PATCH v2 02/12] KVM: SVM: Add the LbrExtV2 CPUID feature bit Shivansh Dhiman
2026-10-19 22:15 ` Jim Mattson
2026-10-19 21:05 ` [PATCH v2 03/12] KVM: SVM: Emulate guest accesses to LBRv2 MSRs Shivansh Dhiman
2026-10-19 23:26 ` Jim Mattson
2026-10-19 21:05 ` [PATCH v2 04/12] KVM: SVM: Enable hardware-assisted LBRv2 virtualization Shivansh Dhiman
2026-10-19 21:33 ` sashiko-bot
2026-10-19 21:05 ` [PATCH v2 05/12] KVM: x86: Add support for Live Migration Shivansh Dhiman
2026-10-19 21:05 ` [PATCH v2 06/12] perf/x86: Expose the LBR stack depth via x86_pmu_capability Shivansh Dhiman
2026-10-19 21:05 ` [PATCH v2 07/12] KVM: SVM: Advertise LbrExtV2 to userspace Shivansh Dhiman
2026-10-19 21:27 ` sashiko-bot
2026-10-19 21:05 ` [PATCH v2 08/12] KVM: SVM: Support LBRv2 virtualization for SEV-ES guests Shivansh Dhiman
2026-10-19 21:05 ` [PATCH v2 09/12] KVM: nSVM: Propagate LBRv2 state across nested transitions Shivansh Dhiman
2026-10-19 21:31 ` sashiko-bot [this message]
2026-10-19 21:05 ` [PATCH v2 10/12] KVM: nSVM: Pass through LBRv2 MSRs to L2 Shivansh Dhiman
2026-10-19 21:36 ` sashiko-bot
2026-10-19 21:05 ` [PATCH v2 11/12] KVM: SVM: Add LBR/PMC freeze support Shivansh Dhiman
2026-10-19 21:27 ` sashiko-bot
2026-10-19 21:05 ` [PATCH v2 12/12] KVM: x86: Use SCATTERED_F() for PERFMON_V2 Shivansh Dhiman
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=sashiko-outbox-178260@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shivansh.dhiman@amd.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox