From: "Xin Li (Intel)" 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) Signed-off-by: Sohil Mehta --- 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