[PATCH v10 16/28] KVM: x86: Mark CR4.FRED as not reserved

From: Sohil Mehta

Date: Fri Sep 11 2026 - 17:43:58 EST


From: "Xin Li (Intel)" <xin@xxxxxxxxx>

The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when
guest cpu cap has FRED, i.e.,
1) All of FRED KVM support is in place.
2) Guest enumerates FRED.

Otherwise it is still a reserved bit.

Signed-off-by: Xin Li (Intel) <xin@xxxxxxxxx>
Signed-off-by: Sohil Mehta <sohil.mehta@xxxxxxxxx>
---
v10:
- Check CR4.FRED against IA-32e mode in kvm_set_cr4() instead of
__kvm_is_valid_cr4(), so that KVM_SET_SREGS no longer rejects a CR4
and EFER pair that are loaded together (e.g., when restoring a FRED
guest)
---
arch/x86/kvm/regs.c | 7 +++++++
arch/x86/kvm/regs.h | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/regs.c b/arch/x86/kvm/regs.c
index 8f66438989e4..ba6c8856b4ff 100644
--- a/arch/x86/kvm/regs.c
+++ b/arch/x86/kvm/regs.c
@@ -429,6 +429,13 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
return 1;
}

+ /*
+ * FRED can not be enabled when EFER.LMA=0. Note, MOV to CR4 outside
+ * 64-bit mode clears CR4[63:32] so only emulation can get here.
+ */
+ if ((cr4 & X86_CR4_FRED) && !is_long_mode(vcpu))
+ return 1;
+
if ((cr4 & X86_CR4_CET) && !kvm_is_cr0_bit_set(vcpu, X86_CR0_WP))
return 1;

diff --git a/arch/x86/kvm/regs.h b/arch/x86/kvm/regs.h
index ef46918daf43..5db01693ad07 100644
--- a/arch/x86/kvm/regs.h
+++ b/arch/x86/kvm/regs.h
@@ -28,7 +28,7 @@ static_assert(!(KVM_POSSIBLE_CR0_GUEST_BITS & X86_CR0_PDPTR_BITS));
| 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_CET))
+ | X86_CR4_LAM_SUP | X86_CR4_CET | X86_CR4_FRED))

#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)

@@ -423,6 +423,8 @@ static inline bool __kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
if (!__cpu_has(__c, X86_FEATURE_SHSTK) && \
!__cpu_has(__c, X86_FEATURE_IBT)) \
__reserved_bits |= X86_CR4_CET; \
+ if (!__cpu_has(__c, X86_FEATURE_FRED)) \
+ __reserved_bits |= X86_CR4_FRED; \
__reserved_bits; \
})

--
2.43.0