Skip to content

Commit f8ade83

Browse files
committed
KVM: x86: Explicitly configure supported XSS from {svm,vmx}_set_cpu_caps()
Explicitly configure KVM's supported XSS as part of each vendor's setup flow to fix a bug where clearing SHSTK and IBT in kvm_cpu_caps, e.g. due to lack of CET XFEATURE support, makes kvm-intel.ko unloadable when nested VMX is enabled, i.e. when nested=1. The late clearing results in nested_vmx_setup_{entry,exit}_ctls() clearing VM_{ENTRY,EXIT}_LOAD_CET_STATE when nested_vmx_setup_ctls_msrs() runs during the CPU compatibility checks, ultimately leading to a mismatched VMCS config due to the reference config having the CET bits set, but every CPU's "local" config having the bits cleared. Note, kvm_caps.supported_{xcr0,xss} are unconditionally initialized by kvm_x86_vendor_init(), before calling into vendor code, and not referenced between ops->hardware_setup() and their current/old location. Fixes: 69cc3e8 ("KVM: x86: Add XSS support for CET_KERNEL and CET_USER") Cc: stable@vger.kernel.org Cc: Mathias Krause <minipli@grsecurity.net> Cc: John Allen <john.allen@amd.com> Cc: Rick Edgecombe <rick.p.edgecombe@intel.com> Cc: Chao Gao <chao.gao@intel.com> Cc: Binbin Wu <binbin.wu@linux.intel.com> Cc: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Link: https://patch.msgid.link/20260128014310.3255561-2-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent e396a74 commit f8ade83

File tree

4 files changed

+23
-13
lines changed

4 files changed

+23
-13
lines changed

arch/x86/kvm/svm/svm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5284,6 +5284,8 @@ static __init void svm_set_cpu_caps(void)
52845284
*/
52855285
kvm_cpu_cap_clear(X86_FEATURE_BUS_LOCK_DETECT);
52865286
kvm_cpu_cap_clear(X86_FEATURE_MSR_IMM);
5287+
5288+
kvm_setup_xss_caps();
52875289
}
52885290

52895291
static __init int svm_hardware_setup(void)

arch/x86/kvm/vmx/vmx.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8051,6 +8051,8 @@ static __init void vmx_set_cpu_caps(void)
80518051
kvm_cpu_cap_clear(X86_FEATURE_SHSTK);
80528052
kvm_cpu_cap_clear(X86_FEATURE_IBT);
80538053
}
8054+
8055+
kvm_setup_xss_caps();
80548056
}
80558057

80568058
static bool vmx_is_io_intercepted(struct kvm_vcpu *vcpu,

arch/x86/kvm/x86.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9953,6 +9953,23 @@ static struct notifier_block pvclock_gtod_notifier = {
99539953
};
99549954
#endif
99559955

9956+
void kvm_setup_xss_caps(void)
9957+
{
9958+
if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
9959+
kvm_caps.supported_xss = 0;
9960+
9961+
if (!kvm_cpu_cap_has(X86_FEATURE_SHSTK) &&
9962+
!kvm_cpu_cap_has(X86_FEATURE_IBT))
9963+
kvm_caps.supported_xss &= ~XFEATURE_MASK_CET_ALL;
9964+
9965+
if ((kvm_caps.supported_xss & XFEATURE_MASK_CET_ALL) != XFEATURE_MASK_CET_ALL) {
9966+
kvm_cpu_cap_clear(X86_FEATURE_SHSTK);
9967+
kvm_cpu_cap_clear(X86_FEATURE_IBT);
9968+
kvm_caps.supported_xss &= ~XFEATURE_MASK_CET_ALL;
9969+
}
9970+
}
9971+
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_setup_xss_caps);
9972+
99569973
static inline void kvm_ops_update(struct kvm_x86_init_ops *ops)
99579974
{
99589975
memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
@@ -10125,19 +10142,6 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
1012510142
if (!tdp_enabled)
1012610143
kvm_caps.supported_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT;
1012710144

10128-
if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
10129-
kvm_caps.supported_xss = 0;
10130-
10131-
if (!kvm_cpu_cap_has(X86_FEATURE_SHSTK) &&
10132-
!kvm_cpu_cap_has(X86_FEATURE_IBT))
10133-
kvm_caps.supported_xss &= ~XFEATURE_MASK_CET_ALL;
10134-
10135-
if ((kvm_caps.supported_xss & XFEATURE_MASK_CET_ALL) != XFEATURE_MASK_CET_ALL) {
10136-
kvm_cpu_cap_clear(X86_FEATURE_SHSTK);
10137-
kvm_cpu_cap_clear(X86_FEATURE_IBT);
10138-
kvm_caps.supported_xss &= ~XFEATURE_MASK_CET_ALL;
10139-
}
10140-
1014110145
if (kvm_caps.has_tsc_control) {
1014210146
/*
1014310147
* Make sure the user can only configure tsc_khz values that

arch/x86/kvm/x86.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ extern struct kvm_host_values kvm_host;
471471

472472
extern bool enable_pmu;
473473

474+
void kvm_setup_xss_caps(void);
475+
474476
/*
475477
* Get a filtered version of KVM's supported XCR0 that strips out dynamic
476478
* features for which the current process doesn't (yet) have permission to use.

0 commit comments

Comments
 (0)