x86/fred: Invoke FRED initialization code to enable FRED
authorH. Peter Anvin (Intel) <hpa@zytor.com>
Tue, 5 Dec 2023 10:50:24 +0000 (02:50 -0800)
committerBorislav Petkov (AMD) <bp@alien8.de>
Wed, 31 Jan 2024 21:03:36 +0000 (22:03 +0100)
Let cpu_init_exception_handling() call cpu_init_fred_exceptions() to
initialize FRED. However if FRED is unavailable or disabled, it falls
back to set up TSS IST and initialize IDT.

Co-developed-by: Xin Li <xin3.li@intel.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Tested-by: Shan Kang <shan.kang@intel.com>
Link: https://lore.kernel.org/r/20231205105030.8698-36-xin3.li@intel.com
arch/x86/kernel/cpu/common.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/traps.c

index 4f5e4aa35e5a9e90c4bd09bd5a4ce4b7ebf04391..cf82e3181f7a6164287f0787316b55e01fa831d4 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/microcode.h>
 #include <asm/intel-family.h>
 #include <asm/cpu_device_id.h>
+#include <asm/fred.h>
 #include <asm/uv/uv.h>
 #include <asm/ia32.h>
 #include <asm/set_memory.h>
@@ -2107,7 +2108,15 @@ void syscall_init(void)
        /* The default user and kernel segments */
        wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
 
-       idt_syscall_init();
+       /*
+        * Except the IA32_STAR MSR, there is NO need to setup SYSCALL and
+        * SYSENTER MSRs for FRED, because FRED uses the ring 3 FRED
+        * entrypoint for SYSCALL and SYSENTER, and ERETU is the only legit
+        * instruction to return to ring 3 (both sysexit and sysret cause
+        * #UD when FRED is enabled).
+        */
+       if (!cpu_feature_enabled(X86_FEATURE_FRED))
+               idt_syscall_init();
 }
 
 #else  /* CONFIG_X86_64 */
@@ -2213,8 +2222,9 @@ void cpu_init_exception_handling(void)
        /* paranoid_entry() gets the CPU number from the GDT */
        setup_getcpu(cpu);
 
-       /* IST vectors need TSS to be set up. */
-       tss_setup_ist(tss);
+       /* For IDT mode, IST vectors need to be set in TSS. */
+       if (!cpu_feature_enabled(X86_FEATURE_FRED))
+               tss_setup_ist(tss);
        tss_setup_io_bitmap(tss);
        set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
 
@@ -2223,8 +2233,10 @@ void cpu_init_exception_handling(void)
        /* GHCB needs to be setup to handle #VC. */
        setup_ghcb();
 
-       /* Finally load the IDT */
-       load_current_idt();
+       if (cpu_feature_enabled(X86_FEATURE_FRED))
+               cpu_init_fred_exceptions();
+       else
+               load_current_idt();
 }
 
 /*
index c683666876f1c7026acf5b4d63b93381181e1801..f79c5edc0b892da8e3dff9afda2324ae0dae5944 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/setup.h>
 #include <asm/i8259.h>
 #include <asm/traps.h>
+#include <asm/fred.h>
 #include <asm/prom.h>
 
 /*
@@ -96,7 +97,11 @@ void __init native_init_IRQ(void)
        /* Execute any quirks before the call gates are initialised: */
        x86_init.irqs.pre_vector_init();
 
-       idt_setup_apic_and_irq_gates();
+       if (cpu_feature_enabled(X86_FEATURE_FRED))
+               fred_complete_exception_setup();
+       else
+               idt_setup_apic_and_irq_gates();
+
        lapic_assign_system_vectors();
 
        if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) {
index 1b19a170f5e35ea875a699657f8be8cb2aae3f74..6cb31df3d5ffbe64c8ffce560a48ad5c3c0e5de2 100644 (file)
@@ -1438,7 +1438,10 @@ void __init trap_init(void)
 
        /* Initialize TSS before setting up traps so ISTs work */
        cpu_init_exception_handling();
+
        /* Setup traps as cpu_init() might #GP */
-       idt_setup_traps();
+       if (!cpu_feature_enabled(X86_FEATURE_FRED))
+               idt_setup_traps();
+
        cpu_init();
 }