[PATCH v2 3/3] x86/fred: Enable FRED right after init_mem_mapping()

From: Xin Li (Intel)
Date: Tue Jul 09 2024 - 11:42:39 EST


Enable FRED right after init_mem_mapping() to avoid #PF handler,
exc_page_fault(), fetching its faulting address from the stack
before FRED is enabled.

Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
Reported-by: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx>
Suggested-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Signed-off-by: Xin Li (Intel) <xin@xxxxxxxxx>
---
arch/x86/kernel/cpu/common.c | 6 +-----
arch/x86/kernel/setup.c | 11 ++++++++++-
arch/x86/kernel/smpboot.c | 6 ++++++
arch/x86/kernel/traps.c | 4 ++++
4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 6de12b3c1b04..42d4136ed6ac 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -2195,12 +2195,8 @@ void cpu_init_exception_handling(void)
/* GHCB needs to be setup to handle #VC. */
setup_ghcb();

- if (cpu_feature_enabled(X86_FEATURE_FRED)) {
- cpu_init_fred_exceptions();
- cpu_init_fred_rsps();
- } else {
+ if (!cpu_feature_enabled(X86_FEATURE_FRED))
load_current_idt();
- }
}

/*
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 728927e4ba51..36403b901eb2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -39,6 +39,7 @@
#include <asm/coco.h>
#include <asm/cpu.h>
#include <asm/efi.h>
+#include <asm/fred.h>
#include <asm/gart.h>
#include <asm/hypervisor.h>
#include <asm/io_apic.h>
@@ -1040,7 +1041,15 @@ void __init setup_arch(char **cmdline_p)

init_mem_mapping();

- idt_setup_early_pf();
+ /*
+ * init_mem_mapping() uses early IDT to setup memory mappings, thus FRED
+ * can't be enabled earlier than that, unless FRED adds support to setup
+ * memory mappings.
+ */
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ cpu_init_fred_exceptions();
+ else
+ idt_setup_early_pf();

/*
* Update mmu_cr4_features (and, indirectly, trampoline_cr4_features)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 0c35207320cb..0d83377f9dcd 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -64,6 +64,7 @@
#include <asm/acpi.h>
#include <asm/cacheinfo.h>
#include <asm/desc.h>
+#include <asm/fred.h>
#include <asm/nmi.h>
#include <asm/irq.h>
#include <asm/realmode.h>
@@ -248,6 +249,11 @@ static void notrace start_secondary(void *unused)

cpu_init_exception_handling();

+ if (cpu_feature_enabled(X86_FEATURE_FRED)) {
+ cpu_init_fred_exceptions();
+ cpu_init_fred_rsps();
+ }
+
/*
* Load the microcode before reaching the AP alive synchronization
* point below so it is not part of the full per CPU serialized
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 6afb41e6cbbb..81648bd07576 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -1407,6 +1407,10 @@ void __init trap_init(void)
/* Init cpu_entry_area before IST entries are set up */
setup_cpu_entry_areas();

+ /* FRED RSPs pointing to memory from CPU entry areas */
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ cpu_init_fred_rsps();
+
/* Init GHCB memory pages when running as an SEV-ES guest */
sev_es_init_vc_handling();

--
2.45.2