[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <aYTeZY1DoJUyrGzo@google.com>
Date: Thu, 5 Feb 2026 10:16:05 -0800
From: Sean Christopherson <seanjc@...gle.com>
To: Jim Mattson <jmattson@...gle.com>
Cc: Paolo Bonzini <pbonzini@...hat.com>, Jonathan Corbet <corbet@....net>,
Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
Dave Hansen <dave.hansen@...ux.intel.com>, x86@...nel.org,
"H. Peter Anvin" <hpa@...or.com>, Maxim Levitsky <mlevitsk@...hat.com>, kvm@...r.kernel.org,
linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] KVM: VMX: Add quirk to allow L1 to set FREEZE_IN_SMM in vmcs12
On Thu, Feb 05, 2026, Jim Mattson wrote:
> On Thu, Feb 5, 2026 at 6:47 AM Sean Christopherson <seanjc@...gle.com> wrote:
> > > > In other words, unless I'm missing something, the only reasonable option is to
> > > > run the guest with FREEZE_IN_SMM=1, which means ignoring the guest's wishes.
> > > > Or I guess another way to look at it: you can have any color car you want, as
> > > > long as it's black :-)
> > >
> > > I would be happy with FREEZE_IN_SMM=1. I'm not happy with the host
> > > dictating FREEZE_IN_SMM=0.
> >
> > Yep, make sense.
>
> Perhaps we should ignore both L0 and L1, and arbitrarily set
> FREEZE_IN_SMM=1 for both vmcs01 and vmcs02 when MPT is enabled.
Hmm, I like that idea even more, because it's waaay simpler to implement. Argh,
the wrinkle is that KVM doesn't actually know if DEBUGCTLMSR_FREEZE_IN_SMM is
supported. Oh, nice, it's reported in PERF_CAPABILITIES.
IA32_DEBUGCTL.FREEZE_WHILE_SMM is supported if
IA32_PERF_CAPABILITIES.FREEZE_WHILE_SMM[Bit 12] is reporting 1
Arguably, this is a fix for mediated PMU support. Because as you pointed out,
we can freeze PMCs on SMI for mediated vPMUs without impacting host profiling,
unlike the legacy vCPU where it being a weird extension of perf means we can't
deny guest profiling without breaking host perf usage.
This? (untested)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 4d3566bb1a93..5563f68158bb 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -324,6 +324,7 @@
#define PERF_CAP_PEBS_TRAP BIT_ULL(6)
#define PERF_CAP_ARCH_REG BIT_ULL(7)
#define PERF_CAP_PEBS_FORMAT 0xf00
+#define PERF_CAP_FREEZE_IN_SMM BIT_ULL(12)
#define PERF_CAP_FW_WRITES BIT_ULL(13)
#define PERF_CAP_PEBS_BASELINE BIT_ULL(14)
#define PERF_CAP_PEBS_TIMING_INFO BIT_ULL(17)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 27acafd03381..ef0d8108ff42 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -8119,13 +8119,12 @@ void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
static __init u64 vmx_get_perf_capabilities(void)
{
u64 perf_cap = PERF_CAP_FW_WRITES;
- u64 host_perf_cap = 0;
if (!enable_pmu)
return 0;
if (boot_cpu_has(X86_FEATURE_PDCM))
- rdmsrq(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+ rdmsrq(MSR_IA32_PERF_CAPABILITIES, kvm_host.perf_capabilities);
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR) &&
!enable_mediated_pmu) {
@@ -8139,11 +8138,11 @@ static __init u64 vmx_get_perf_capabilities(void)
if (!vmx_lbr_caps.has_callstack)
memset(&vmx_lbr_caps, 0, sizeof(vmx_lbr_caps));
else if (vmx_lbr_caps.nr)
- perf_cap |= host_perf_cap & PERF_CAP_LBR_FMT;
+ perf_cap |= kvm_host.perf_capabilities & PERF_CAP_LBR_FMT;
}
if (vmx_pebs_supported()) {
- perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
+ perf_cap |= kvm_host.perf_capabilities & PERF_CAP_PEBS_MASK;
/*
* Disallow adaptive PEBS as it is functionally broken, can be
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 70bfe81dea54..e780d0e06b61 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -408,6 +408,11 @@ static inline void vmx_guest_debugctl_write(struct kvm_vcpu *vcpu, u64 val)
WARN_ON_ONCE(val & VMX_HOST_OWNED_DEBUGCTL_BITS);
val |= vcpu->arch.host_debugctl & VMX_HOST_OWNED_DEBUGCTL_BITS;
+
+ if (kvm_vcpu_has_mediated_pmu(vcpu) &&
+ (kvm_host.perf_capabilities & PERF_CAP_FREEZE_IN_SMM))
+ val |= DEBUGCTLMSR_FREEZE_IN_SMM;
+
vmcs_write64(GUEST_IA32_DEBUGCTL, val);
}
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 70e81f008030..e0084e1063d0 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -52,6 +52,7 @@ struct kvm_host_values {
u64 xss;
u64 s_cet;
u64 arch_capabilities;
+ u64 perf_capabilities;
};
void kvm_spurious_fault(void);
Powered by blists - more mailing lists