Re: [PATCH v15 19/41] KVM: x86: Enable CET virtualization for VMX and advertise to userspace

Binbin Wu
2025-09-18T01:57:21Z

On 9/13/2025 7:22 AM, Sean Christopherson wrote:
> From: Yang Weijiang <weijiang.yang@intel.com>
>
> Expose CET features to guest if KVM/host can support them, clear CPUID
> feature bits if KVM/host cannot support.
>
> Set CPUID feature bits so that CET features are available in guest CPUID.
> Add CR4.CET bit support in order to allow guest set CET master control
> bit.
>
> Disable KVM CET feature if unrestricted_guest is unsupported/disabled as
> KVM does not support emulating CET.
>
> The CET load-bits in VM_ENTRY/VM_EXIT control fields should be set to make
> guest CET xstates isolated from host's.
>
> On platforms with VMX_BASIC[bit56] == 0, inject #CP at VMX entry with error
> code will fail, and if VMX_BASIC[bit56] == 1, #CP injection with or without
> error code is allowed. Disable CET feature bits if the MSR bit is cleared
> so that nested VMM can inject #CP if and only if VMX_BASIC[bit56] == 1.
>
> Don't expose CET feature if either of {U,S}_CET xstate bits is cleared
> in host XSS or if XSAVES isn't supported.
>
> CET MSRs are reset to 0s after RESET, power-up and INIT, clear guest CET
> xsave-area fields so that guest CET MSRs are reset to 0s after the events.
>
> Meanwhile explicitly disable SHSTK and IBT for SVM because CET KVM enabling
> for SVM is not ready.
>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> Signed-off-by: Mathias Krause <minipli@grsecurity.net>
> Tested-by: Mathias Krause <minipli@grsecurity.net>
> Tested-by: John Allen <john.allen@amd.com>
> Tested-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

One nit below.

[...]
> \
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 15f208c44cbd..c78acab2ff3f 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -226,7 +226,8 @@ static struct kvm_user_return_msrs __percpu *user_return_msrs;
> * PT via guest XSTATE would clobber perf state), i.e. KVM doesn't support
> * IA32_XSS[bit 8] (guests can/must use RDMSR/WRMSR to save/restore PT MSRs).
> */
> -#define KVM_SUPPORTED_XSS 0
> +#define KVM_SUPPORTED_XSS (XFEATURE_MASK_CET_USER | \
> + XFEATURE_MASK_CET_KERNEL)

Since XFEATURE_MASK_CET_USER and XFEATURE_MASK_CET_KERNEL are always checked or
set together, does it make sense to use a macro for the two bits?

>
> bool __read_mostly allow_smaller_maxphyaddr = 0;
> EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr);
> @@ -10080,6 +10081,20 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
> if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
> kvm_caps.supported_xss = 0;
>
> + if (!kvm_cpu_cap_has(X86_FEATURE_SHSTK) &&
> + !kvm_cpu_cap_has(X86_FEATURE_IBT))
> + kvm_caps.supported_xss &= ~(XFEATURE_MASK_CET_USER |
> + XFEATURE_MASK_CET_KERNEL);
> +
> + if ((kvm_caps.supported_xss & (XFEATURE_MASK_CET_USER |
> + XFEATURE_MASK_CET_KERNEL)) !=
> + (XFEATURE_MASK_CET_USER | XFEATURE_MASK_CET_KERNEL)) {
> + kvm_cpu_cap_clear(X86_FEATURE_SHSTK);
> + kvm_cpu_cap_clear(X86_FEATURE_IBT);
> + kvm_caps.supported_xss &= ~(XFEATURE_MASK_CET_USER |
> + XFEATURE_MASK_CET_KERNEL);
> + }
> +
> if (kvm_caps.has_tsc_control) {
> /*
> * Make sure the user can only configure tsc_khz values that
> @@ -12735,10 +12750,11 @@ static void kvm_xstate_reset(struct kvm_vcpu *vcpu, bool init_event)
> /*
> * On INIT, only select XSTATE components are zeroed, most components
> * are unchanged. Currently, the only components that are zeroed and
> - * supported by KVM are MPX related.
> + * supported by KVM are MPX and CET related.
> */
> xfeatures_mask = (kvm_caps.supported_xcr0 | kvm_caps.supported_xss) &
> - (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
> + (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR |
> + XFEATURE_MASK_CET_USER | XFEATURE_MASK_CET_KERNEL);
> if (!xfeatures_mask)
> return;
>
> diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
> index 65cbd454c4f1..f3dc77f006f9 100644
> --- a/arch/x86/kvm/x86.h
> +++ b/arch/x86/kvm/x86.h
> @@ -680,6 +680,9 @@ static inline bool __kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
> __reserved_bits |= X86_CR4_PCIDE; \
> if (!__cpu_has(__c, X86_FEATURE_LAM)) \
> __reserved_bits |= X86_CR4_LAM_SUP; \
> + if (!__cpu_has(__c, X86_FEATURE_SHSTK) && \
> + !__cpu_has(__c, X86_FEATURE_IBT)) \
> + __reserved_bits |= X86_CR4_CET; \
> __reserved_bits; \
> })
>