From 27bcb7ea807e2b7d588f8a81cd24a59750321eda Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 3 Jun 2026 14:05:01 +0800 Subject: [PATCH] KVM: SVM: Intercept SPEC_CTRL unless the guest has a SPEC_CTRL MSR When the host supports Virtual SPEC_CTRL (V_SPEC_CTRL), init_vmcb() unconditionally disables interception of MSR_IA32_SPEC_CTRL, i.e. passes the MSR through to the guest, without regard for the guest's CPUID. On such hardware a guest RDMSR/WRMSR of IA32_SPEC_CTRL is serviced directly from the VMCB save area and never exits to KVM, so a guest whose CPUID advertises none of SPEC_CTRL, AMD_IBRS, AMD_STIBP or AMD_SSBD can freely read and write the MSR instead of taking the #GP it would see on bare metal. svm_get_msr()/svm_set_msr() already reject the access for such a guest. They return 1 (and KVM injects #GP) when !guest_has_spec_ctrl_msr(), but the passthrough bypasses those handlers entirely. The passthrough is also programmed in init_vmcb(), before the guest CPUID has been configured, so it cannot take the guest's feature set into account in the first place. This is observable with kvm-unit-tests. On a V_SPEC_CTRL-capable host (e.g. AMD Zen2+, Hygon Gen4), ./run_test.sh msr64 reports: FAIL: Expected #GP on RDMSR(SPEC_CTRL), got vector 0 FAIL: Expected #GP on WRMSR(SPEC_CTRL, 0x0), got vector 0 Drop the unconditional passthrough from init_vmcb() and instead program the SPEC_CTRL intercept from svm_vcpu_after_set_cpuid(), gated on guest_has_spec_ctrl_msr(). SPEC_CTRL now stays intercepted for guests without the MSR (so KVM injects #GP) and is passed through only once the guest's CPUID shows it has the MSR. The on-demand passthrough that svm_set_msr() performs after the guest's first legitimate write is unaffected. This is the SPEC_CTRL portion of the upstream MSR-interception rework merged in v6.17, which moved the decision into svm_recalc_msr_intercepts(): Commit 160f143cc1317a599ef44c8d35a1328f2dd7a14d It is applied here as a minimal fix against the v6.6 set_msr_interception() API rather than backporting the full series. Hygon-SIG: commit none KVM: SVM: Intercept SPEC_CTRL unless the guest has a SPEC_CTRL MSR Fixes: d00b99c514b3 ("KVM: SVM: Add support for Virtual SPEC_CTRL") Signed-off-by: Wei Wang Tested-by: Yongwei Xu --- arch/x86/kvm/svm/svm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index a0537decfb10..d57fb78a6337 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1404,7 +1404,12 @@ static void init_vmcb(struct kvm_vcpu *vcpu) * of MSR_IA32_SPEC_CTRL. */ if (boot_cpu_has(X86_FEATURE_V_SPEC_CTRL)) - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_SPEC_CTRL, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_SPEC_CTRL, + !!guest_has_spec_ctrl_msr(vcpu), + !!guest_has_spec_ctrl_msr(vcpu)); + else + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_SPEC_CTRL, + !svm->spec_ctrl, !svm->spec_ctrl); if (kvm_vcpu_apicv_active(vcpu)) avic_init_vmcb(svm, vmcb); -- Gitee