Re: [PATCH v9 06/22] x86/cea: Export __this_cpu_ist_top_va() to KVM

From: Xin Li

Date: Sat Mar 07 2026 - 02:55:54 EST




> On Jan 30, 2026, at 5:46 AM, Borislav Petkov <bp@xxxxxxxxx> wrote:
>
> On Sun, Oct 26, 2025 at 01:18:54PM -0700, Xin Li (Intel) wrote:
>> @@ -36,6 +41,7 @@ noinstr unsigned long __this_cpu_ist_top_va(enum exception_stack_ordering stack)
>> {
>> return __this_cpu_ist_bottom_va(stack) + EXCEPTION_STKSZ;
>> }
>> +EXPORT_SYMBOL_FOR_MODULES(__this_cpu_ist_top_va, "kvm-intel");
>
> Why is this function name still kept with the "__" prefix but it is being
> exported at the same time?
>
> It looks to me like we're exporting the wrong thing as the "__" kinda says it
> is an internal helper.
>
> Just drop the prefix and call it something more sensible please. The caller
> couldn't care less about "ist_top_va".

Sean suggested to replace direct, raw use of __this_cpu_ist_top_va() with
a self-explanatory this_cpu_fred_rsp() helper for better readability.

https://lore.kernel.org/lkml/aahchI7oiFrjFAmb@xxxxxxxxxx/

So __this_cpu_ist_top_va() no longer needs to be exported, thus no need to
do the renaming.

The new patch is below:

commit 7f0d77e48751bd2f3f65f93eaf466257382a25b9
Author: Xin Li <xin@xxxxxxxxx>
Date: Fri Oct 24 11:52:32 2025 -0700

x86/fred: Export this_cpu_fred_rsp() for KVM usage

Introduce and export this_cpu_fred_rsp() to provide KVM with a self-
explanatory interface for retrieving per-CPU FRED regular stacks for
stack levels 1->3.

FRED introduced new fields in the VMCS host-state area for stack levels
1–>3 (HOST_IA32_FRED_RSP[123]), which correspond to the per-CPU FRED
regular stacks for stack levels 1->3. KVM must populate these fields
each time a vCPU is loaded onto a CPU to ensure a complete valid FRED
event delivery context immediately after any VM-Exits.

Signed-off-by: Xin Li <xin@xxxxxxxxx>
---

Change in v10:
* Replace direct, raw use of __this_cpu_ist_top_va() with a self-
explanatory this_cpu_fred_rsp() helper for better readability (Sean).

diff --git a/arch/x86/include/asm/fred.h b/arch/x86/include/asm/fred.h
index 2bb65677c079..7eea65bfc838 100644
--- a/arch/x86/include/asm/fred.h
+++ b/arch/x86/include/asm/fred.h
@@ -35,6 +35,13 @@

#ifndef __ASSEMBLER__

+enum fred_stack_level {
+ FRED_STACK_LEVEL_0,
+ FRED_STACK_LEVEL_1,
+ FRED_STACK_LEVEL_2,
+ FRED_STACK_LEVEL_3
+};
+
#ifdef CONFIG_X86_FRED
#include <linux/kernel.h>
#include <linux/sched/task_stack.h>
@@ -105,6 +112,8 @@ static __always_inline void fred_update_rsp0(void)
__this_cpu_write(fred_rsp0, rsp0);
}
}
+
+unsigned long this_cpu_fred_rsp(enum fred_stack_level lvl);
#else /* CONFIG_X86_FRED */
static __always_inline unsigned long fred_event_data(struct pt_regs *regs) { return 0; }
static inline void cpu_init_fred_exceptions(void) { }
@@ -113,6 +122,7 @@ static inline void fred_complete_exception_setup(void) { }
static inline void fred_entry_from_kvm(unsigned int type, unsigned int vector) { }
static inline void fred_sync_rsp0(unsigned long rsp0) { }
static inline void fred_update_rsp0(void) { }
+static unsigned long this_cpu_fred_rsp(enum fred_stack_level lvl) { return 0; }
#endif /* CONFIG_X86_FRED */
#endif /* !__ASSEMBLER__ */

diff --git a/arch/x86/kernel/fred.c b/arch/x86/kernel/fred.c
index 433c4a6f1773..363c53701012 100644
--- a/arch/x86/kernel/fred.c
+++ b/arch/x86/kernel/fred.c
@@ -72,6 +72,23 @@ void cpu_init_fred_exceptions(void)
setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
}

+unsigned long this_cpu_fred_rsp(enum fred_stack_level lvl)
+{
+ switch (lvl) {
+ case FRED_STACK_LEVEL_0:
+ return __this_cpu_read(fred_rsp0);
+ case FRED_STACK_LEVEL_1:
+ return __this_cpu_ist_top_va(ESTACK_DB);
+ case FRED_STACK_LEVEL_2:
+ return __this_cpu_ist_top_va(ESTACK_NMI);
+ case FRED_STACK_LEVEL_3:
+ return __this_cpu_ist_top_va(ESTACK_DF);
+ default:
+ BUG();
+ }
+}
+EXPORT_SYMBOL_FOR_MODULES(this_cpu_fred_rsp, "kvm-intel");
+
/* Must be called after setup_cpu_entry_areas() */
void cpu_init_fred_rsps(void)
{
@@ -87,7 +104,7 @@ void cpu_init_fred_rsps(void)
FRED_STKLVL(X86_TRAP_DF, FRED_DF_STACK_LEVEL));

/* The FRED equivalents to IST stacks... */
- wrmsrq(MSR_IA32_FRED_RSP1, __this_cpu_ist_top_va(ESTACK_DB));
- wrmsrq(MSR_IA32_FRED_RSP2, __this_cpu_ist_top_va(ESTACK_NMI));
- wrmsrq(MSR_IA32_FRED_RSP3, __this_cpu_ist_top_va(ESTACK_DF));
+ wrmsrq(MSR_IA32_FRED_RSP1, this_cpu_fred_rsp(FRED_STACK_LEVEL_1));
+ wrmsrq(MSR_IA32_FRED_RSP2, this_cpu_fred_rsp(FRED_STACK_LEVEL_2));
+ wrmsrq(MSR_IA32_FRED_RSP3, this_cpu_fred_rsp(FRED_STACK_LEVEL_3));
}