Re: [PATCH v16 23/51] KVM: x86: Allow setting CR4.CET if IBT or SHSTK is supported

Xiaoyao Li
2025-09-23T14:46:48Z

On 9/20/2025 6:32 AM, Sean Christopherson wrote:
> From: Yang Weijiang <weijiang.yang@intel.com>
>
> Drop X86_CR4_CET from CR4_RESERVED_BITS and instead mark CET as reserved
> if and only if IBT *and* SHSTK are unsupported, i.e. allow CR4.CET to be
> set if IBT or SHSTK is supported. This creates a virtualization hole if
> the CPU supports both IBT and SHSTK, but the kernel or vCPU model only
> supports one of the features. However, it's entirely legal for a CPU to
> have only one of IBT or SHSTK, i.e. the hole is a flaw in the architecture,
> not in KVM.
>
> More importantly, so long as KVM is careful to initialize and context
> switch both IBT and SHSTK state (when supported in hardware) if either
> feature is exposed to the guest, a misbehaving guest can only harm itself.
> E.g. VMX initializes host CET VMCS fields based solely on hardware
> capabilities.
>
> 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>
> [sean: split to separate patch, write changelog]
> Signed-off-by: Sean Christopherson <seanjc@google.com>

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>

> ---
> arch/x86/include/asm/kvm_host.h | 2 +-
> arch/x86/kvm/x86.h | 3 +++
> 2 files changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 554d83ff6135..39231da3a3ff 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -142,7 +142,7 @@
> | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
> | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \
> | X86_CR4_SMAP | X86_CR4_PKE | X86_CR4_UMIP \
> - | X86_CR4_LAM_SUP))
> + | X86_CR4_LAM_SUP | X86_CR4_CET))
>
> #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
>
> 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; \
> })
>