Re: [PATCH v10 07/28] KVM: VMX: Initialize VMCS FRED fields
From: Binbin Wu
Date: Fri Oct 23 2026 - 03:20:16 EST
On 9/12/2026 5:36 AM, Sohil Mehta wrote:
> From: "Xin Li (Intel)" <xin@xxxxxxxxx>
>
> Initialize host VMCS FRED fields with host FRED MSRs' value and
> guest VMCS FRED fields to 0.
>
> FRED CPU state is managed in 9 new FRED MSRs:
> IA32_FRED_CONFIG,
> IA32_FRED_STKLVLS,
> IA32_FRED_RSP0,
> IA32_FRED_RSP1,
> IA32_FRED_RSP2,
> IA32_FRED_RSP3,
> IA32_FRED_SSP1,
> IA32_FRED_SSP2,
> IA32_FRED_SSP3,
> as well as a few existing CPU registers and MSRs:
> CR4.FRED,
> IA32_STAR,
> IA32_KERNEL_GS_BASE,
> IA32_PL0_SSP (also known as IA32_FRED_SSP0).
>
> CR4, IA32_KERNEL_GS_BASE and IA32_STAR are already well managed.
> Except IA32_FRED_RSP0 and IA32_FRED_SSP0, all other FRED CPU state
> MSRs have corresponding VMCS fields in both the host-state and
> guest-state areas. So KVM just needs to initialize them, and with
> proper VM entry/exit FRED controls, a FRED CPU will keep tracking
> host and guest FRED CPU state in VMCS automatically.
>
> Signed-off-by: Xin Li (Intel) <xin@xxxxxxxxx>
> Signed-off-by: Sohil Mehta <sohil.mehta@xxxxxxxxx>
> Reviewed-by: Chao Gao <chao.gao@xxxxxxxxx>
> Reviewed-by: Binbin Wu <binbin.wu@xxxxxxxxxxxxxxx>
> ---
> v10:
> - s/rdmsrl/rdmsrq (Chao)
> - Remove a terse comment which doesn't help at all (Sean).
> - Replace direct, raw use of __this_cpu_ist_top_va() with a self-
> explanatory this_cpu_fred_rsp() helper for better readability (Sean).
> - Add cpu_feature_enabled(X86_FEATURE_FRED) to patch out accesses to
> VMCS FRED fields (Sean).
> - Remove "#ifdef CONFIG_X86_64" after switching to this_cpu_fred_rsp()
> (Sean).
[...]
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 2a2218e0983b..dc80ca5f804d 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -1562,6 +1562,12 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu)
> (unsigned long)(cpu_entry_stack(cpu) + 1));
> }
>
> + if (cpu_feature_enabled(X86_FEATURE_FRED) && kvm_cpu_cap_has(X86_FEATURE_FRED)) {
Nit:
I was wondering why cpu_feature_enabled(X86_FEATURE_FRED) was needed for a while.
Sorry I missed the version history :(
This seems to be the first time this cpu_feature_enabled() && kvm_cpu_cap_has() combination is used,
maybe have a mention in the changelog?
> + vmcs_write64(HOST_IA32_FRED_RSP1, this_cpu_fred_rsp(FRED_STACK_LEVEL_1));
> + vmcs_write64(HOST_IA32_FRED_RSP2, this_cpu_fred_rsp(FRED_STACK_LEVEL_2));
> + vmcs_write64(HOST_IA32_FRED_RSP3, this_cpu_fred_rsp(FRED_STACK_LEVEL_3));
> + }
> +
> vmx->loaded_vmcs->cpu = cpu;
> }
> }
> @@ -4500,6 +4506,17 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
> */
> vmcs_write16(HOST_DS_SELECTOR, 0);
> vmcs_write16(HOST_ES_SELECTOR, 0);
> +
> + if (cpu_feature_enabled(X86_FEATURE_FRED) && kvm_cpu_cap_has(X86_FEATURE_FRED)) {
> + /* FRED CONFIG and STKLVLS are the same on all CPUs */
> + vmcs_write64(HOST_IA32_FRED_CONFIG, kvm_host.fred_config);
> + vmcs_write64(HOST_IA32_FRED_STKLVLS, kvm_host.fred_stklvls);
> +
> + /* Linux doesn't support kernel shadow stacks, thus SSPs are 0s */
> + vmcs_write64(HOST_IA32_FRED_SSP1, 0);
> + vmcs_write64(HOST_IA32_FRED_SSP2, 0);
> + vmcs_write64(HOST_IA32_FRED_SSP3, 0);
> + }
> #else
> vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
> vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */
> @@ -5030,6 +5047,17 @@ static void init_vmcs(struct vcpu_vmx *vmx)
> }
>
> vmx_setup_uret_msrs(vmx);
> +
> + if (cpu_feature_enabled(X86_FEATURE_FRED) && kvm_cpu_cap_has(X86_FEATURE_FRED)) {
> + vmcs_write64(GUEST_IA32_FRED_CONFIG, 0);
> + vmcs_write64(GUEST_IA32_FRED_RSP1, 0);
> + vmcs_write64(GUEST_IA32_FRED_RSP2, 0);
> + vmcs_write64(GUEST_IA32_FRED_RSP3, 0);
> + vmcs_write64(GUEST_IA32_FRED_STKLVLS, 0);
> + vmcs_write64(GUEST_IA32_FRED_SSP1, 0);
> + vmcs_write64(GUEST_IA32_FRED_SSP2, 0);
> + vmcs_write64(GUEST_IA32_FRED_SSP3, 0);
> + }
> }
>
> static void __vmx_vcpu_reset(struct kvm_vcpu *vcpu)
> @@ -8883,6 +8911,11 @@ __init int vmx_hardware_setup(void)
>
> kvm_caps.inapplicable_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT;
>
> + if (cpu_feature_enabled(X86_FEATURE_FRED) && kvm_cpu_cap_has(X86_FEATURE_FRED)) {
> + rdmsrq(MSR_IA32_FRED_CONFIG, kvm_host.fred_config);
> + rdmsrq(MSR_IA32_FRED_STKLVLS, kvm_host.fred_stklvls);
> + }
> +
> return 0;
> }
>