[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260123221542.2498217-3-seanjc@google.com>
Date: Fri, 23 Jan 2026 14:15:41 -0800
From: Sean Christopherson <seanjc@...gle.com>
To: Sean Christopherson <seanjc@...gle.com>, Paolo Bonzini <pbonzini@...hat.com>
Cc: kvm@...r.kernel.org, linux-kernel@...r.kernel.org,
Mathias Krause <minipli@...ecurity.net>, John Allen <john.allen@....com>,
Rick Edgecombe <rick.p.edgecombe@...el.com>, Chao Gao <chao.gao@...el.com>,
Binbin Wu <binbin.wu@...ux.intel.com>, Xiaoyao Li <xiaoyao.li@...el.com>,
Jim Mattson <jmattson@...gle.com>
Subject: [PATCH 2/3] KVM: x86: Harden against unexpected adjustments to kvm_cpu_caps
Add a flag to track when KVM is actively configuring its CPU caps, and
WARN if a cap is set or cleared if KVM isn't in its configuration stage.
Modifying CPU caps after {svm,vmx}_set_cpu_caps() can be fatal to KVM, as
vendor setup code expects the CPU caps to be frozen at that point, e.g.
will do additional configuration based on the caps.
Signed-off-by: Sean Christopherson <seanjc@...gle.com>
---
arch/x86/kvm/cpuid.c | 8 ++++++++
arch/x86/kvm/cpuid.h | 4 ++++
2 files changed, 12 insertions(+)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 267e59b405c1..2f01511135c2 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -36,6 +36,9 @@
u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_cpu_caps);
+bool kvm_is_configuring_cpu_caps __read_mostly;
+EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_is_configuring_cpu_caps);
+
struct cpuid_xstate_sizes {
u32 eax;
u32 ebx;
@@ -830,6 +833,9 @@ void kvm_initialize_cpu_caps(void)
{
memset(kvm_cpu_caps, 0, sizeof(kvm_cpu_caps));
+ WARN_ON_ONCE(kvm_is_configuring_cpu_caps);
+ kvm_is_configuring_cpu_caps = true;
+
BUILD_BUG_ON(sizeof(kvm_cpu_caps) - (NKVMCAPINTS * sizeof(*kvm_cpu_caps)) >
sizeof(boot_cpu_data.x86_capability));
@@ -1305,6 +1311,8 @@ void kvm_finalize_cpu_caps(void)
kvm_cpu_cap_clear(X86_FEATURE_IBT);
kvm_caps.supported_xss &= ~XFEATURE_MASK_CET_ALL;
}
+
+ kvm_is_configuring_cpu_caps = false;
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_finalize_cpu_caps);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index 3b0b4b1adb97..07175dff24d6 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -8,6 +8,8 @@
#include <uapi/asm/kvm_para.h>
extern u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
+extern bool kvm_is_configuring_cpu_caps __read_mostly;
+
void kvm_initialize_cpu_caps(void);
void kvm_finalize_cpu_caps(void);
@@ -189,6 +191,7 @@ static __always_inline void kvm_cpu_cap_clear(unsigned int x86_feature)
{
unsigned int x86_leaf = __feature_leaf(x86_feature);
+ WARN_ON_ONCE(!kvm_is_configuring_cpu_caps);
kvm_cpu_caps[x86_leaf] &= ~__feature_bit(x86_feature);
}
@@ -196,6 +199,7 @@ static __always_inline void kvm_cpu_cap_set(unsigned int x86_feature)
{
unsigned int x86_leaf = __feature_leaf(x86_feature);
+ WARN_ON_ONCE(!kvm_is_configuring_cpu_caps);
kvm_cpu_caps[x86_leaf] |= __feature_bit(x86_feature);
}
--
2.52.0.457.g6b5491de43-goog
Powered by blists - more mailing lists