Re: [PATCH v10 11/28] KVM: x86: Add a helper to detect if FRED is enabled for a vCPU
From: Sohil Mehta
Date: Wed Nov 04 2026 - 19:02:20 EST
On 10/23/2026 2:21 AM, Binbin Wu wrote:
> On 9/12/2026 5:36 AM, Sohil Mehta wrote:
>> +/*
>> + * It's enough to check just CR4.FRED (X86_CR4_FRED) to tell if
>> + * a vCPU is running with FRED enabled, because:
>> + * 1) CR4.FRED can be set to 1 only _after_ IA32_EFER.LMA = 1.
>> + * 2) To leave IA-32e mode, CR4.FRED must be cleared first.
>
> It seems KVM doesn't enforce it in kvm_set_cr0() for 2).
>
I think the comment is slightly misleading. The spec doesn't directly
enforce leaving IA-32e mode with CR4.FRED. It is just expected to be
unreachable.
1) Based on FRED spec section 4.2 Enabling in CR4, setting CR4.FRED
prevents compatibility mode entry while CPL = 0.
2) But leaving IA-32e can only happen when CR0.PG is cleared which can
only be done in compatibility mode while CPL = 0.
Currently, for KVM, the CPU enforces the first one and the second one is
enforced by kvm_set_cr0().
Is the suggestion to add an explicit check in kvm_set_cr0() that
mirrors the PCIDE one? But there isn't a fault specified by the spec for
this case.
Sean also requested negative tests for things like leaving 64-bit mode
with FRED=1. But, I am not sure how to test this.
AI tells me such a mode change can happen with emulated far transfer
through an MMIO far pointer. "em_jmp_far(), em_call_far(), em_ret_far()
and __load_segment_descriptor() have no FRED checks, so none of them
raise the #GP that FRED spec 8.2 requires."
Chao had brought up enhancing emulator code and making it FRED aware
[1]. I am wondering if we should revisit it?
[1]: https://lore.kernel.org/all/aapnI6KN7Flal8kg@xxxxxxxxx/
Please let me know if I misunderstood something.
>> + */
>> +static inline bool is_fred_enabled(struct kvm_vcpu *vcpu)
>> +{
>> +#ifdef CONFIG_X86_64
>
> Nit:
> This seems to be unnecessary.
> X86_CR4_FRED is defined as 0 in non 64-bit build.
>
Unfortunately, that 0 is exactly why it's needed. kvm_is_cr4_bit_set()
has
BUILD_BUG_ON(!is_power_of_2(cr4_bit));
So, compilation fails on i386 :(
Though, it would be better to get rid of the #ifdef and change it to:
return IS_ENABLED(CONFIG_X86_64) && kvm_is_cr4_bit_set(vcpu,
X86_CR4_FRED);
>> + return kvm_is_cr4_bit_set(vcpu, X86_CR4_FRED);
>> +#else
>> + return false;
>> +#endif
>> +}
>> +