linux/arch/x86/kvm
Yosry Ahmed 8a4821412c KVM: nSVM: Fix and simplify LBR virtualization handling with nested
The current scheme for handling LBRV when nested is used is very
complicated, especially when L1 does not enable LBRV (i.e. does not set
LBR_CTL_ENABLE_MASK).

To avoid copying LBRs between VMCB01 and VMCB02 on every nested
transition, the current implementation switches between using VMCB01 or
VMCB02 as the source of truth for the LBRs while L2 is running. If L2
enables LBR, VMCB02 is used as the source of truth. When L2 disables
LBR, the LBRs are copied to VMCB01 and VMCB01 is used as the source of
truth. This introduces significant complexity, and incorrect behavior in
some cases.

For example, on a nested #VMEXIT, the LBRs are only copied from VMCB02
to VMCB01 if LBRV is enabled in VMCB01. This is because L2's writes to
MSR_IA32_DEBUGCTLMSR to enable LBR are intercepted and propagated to
VMCB01 instead of VMCB02. However, LBRV is only enabled in VMCB02 when
L2 is running.

This means that if L2 enables LBR and exits to L1, the LBRs will not be
propagated from VMCB02 to VMCB01, because LBRV is disabled in VMCB01.

There is no meaningful difference in CPUID rate in L2 when copying LBRs
on every nested transition vs. the current approach, so do the simple
and correct thing and always copy LBRs between VMCB01 and VMCB02 on
nested transitions (when LBRV is disabled by L1). Drop the conditional
LBRs copying in __svm_{enable/disable}_lbrv() as it is now unnecessary.

VMCB02 becomes the only source of truth for LBRs when L2 is running,
regardless of LBRV being enabled by L1, drop svm_get_lbr_vmcb() and use
svm->vmcb directly in its place.

Fixes: 1d5a1b5860 ("KVM: x86: nSVM: correctly virtualize LBR msrs when L2 is running")
Cc: stable@vger.kernel.org
Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
Link: https://patch.msgid.link/20251108004524.1600006-4-yosry.ahmed@linux.dev
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-11-09 08:50:13 +01:00
..
mmu KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
svm KVM: nSVM: Fix and simplify LBR virtualization handling with nested 2025-11-09 08:50:13 +01:00
vmx KVM: VMX: Fix check for valid GVA on an EPT violation 2025-11-06 06:06:18 -08:00
.gitignore
Kconfig - Remove a bunch of asm implementing condition flags testing in KVM's 2025-10-11 11:19:16 -07:00
Makefile KVM: x86: Fold irq_comm.c into irq.c 2025-06-20 13:52:52 -07:00
cpuid.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
cpuid.h Merge branch 'kvm-tdx-initial' into HEAD 2025-04-07 07:36:33 -04:00
debugfs.c
emulate.c - Remove a bunch of asm implementing condition flags testing in KVM's 2025-10-11 11:19:16 -07:00
fpu.h
hyperv.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
hyperv.h KVM: x86: Drop superfluous kvm_hv_set_sint() => kvm_hv_synic_set_irq() wrapper 2025-06-20 13:52:43 -07:00
i8254.c Significant patch series in this pull request: 2025-08-03 16:23:09 -07:00
i8254.h KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation 2025-06-20 13:52:52 -07:00
i8259.c KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation 2025-06-20 13:52:52 -07:00
ioapic.c arch/x86/kvm/ioapic: Remove license boilerplate with bad FSF address 2025-08-19 11:59:29 -07:00
ioapic.h KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation 2025-06-20 13:52:52 -07:00
irq.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
irq.h KVM: x86: Move kvm_irq_delivery_to_apic() from irq.c to lapic.c 2025-09-10 12:05:09 -07:00
kvm-asm-offsets.c
kvm_cache_regs.h KVM: VMX: Make CR4.CET a guest owned bit 2025-09-23 10:03:09 -07:00
kvm_emulate.h KVM: x86: Don't (re)check L1 intercepts when completing userspace I/O 2025-08-19 10:53:40 -07:00
kvm_onhyperv.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
kvm_onhyperv.h
lapic.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
lapic.h KVM: x86: Move kvm_intr_is_single_vcpu() to lapic.c 2025-09-30 13:40:02 -04:00
mmu.h KVM: x86/mmu: WARN on attempt to check permissions for Shadow Stack #PF 2025-09-23 09:16:53 -07:00
mtrr.c KVM: x86: drop x86.h include from cpuid.h 2024-11-01 09:22:23 -07:00
pmu.c KVM: x86/pmu: Don't try to get perf capabilities for hybrid CPUs 2025-10-10 14:25:12 -07:00
pmu.h Generic: 2025-10-06 12:37:34 -07:00
reverse_cpuid.h KVM: x86: Advertise support for the immediate form of MSR instructions 2025-08-19 11:59:47 -07:00
smm.c KVM: x86: Export KVM-internal symbols for sub-modules only 2025-09-30 13:40:02 -04:00
smm.h KVM: x86: Save and reload SSP to/from SMRAM 2025-09-23 09:11:22 -07:00
trace.h KVM: x86: Define AMD's #HV, #VC, and #SX exception vectors 2025-09-23 09:29:03 -07:00
tss.h
x86.c KVM: x86: Call out MSR_IA32_S_CET is not handled by XSAVES 2025-11-04 09:14:26 -08:00
x86.h KVM: x86: Allow setting CR4.CET if IBT or SHSTK is supported 2025-09-23 09:17:48 -07:00
xen.c KVM: x86/xen: Fix cleanup logic in emulation of Xen schedop poll hypercalls 2025-07-23 23:48:54 +02:00
xen.h KVM: x86: Update Xen TSC leaves during CPUID emulation 2025-02-25 07:09:55 -08:00