diff mbox series

[v2,4/4] x86/traps: Introduce early_traps_init() and simplify setup

Message ID 20250320201732.84094-1-andrew.cooper3@citrix.com (mailing list archive)
State New
Headers show
Series None | expand

Commit Message

Andrew Cooper March 20, 2025, 8:17 p.m. UTC
Something I overlooked when last cleaning up exception handling is that a TSS
is not necessary if IST isn't configured, and IST isn't necessary until we're
running guest code.

Introduce early_traps_init(), and rearrange the existing logic between this
and traps_init() later on boot, to allow defering TSS and IST setup.

In early_traps_init(), load the IDT and invalidate TR/LDTR; this sufficient
system-table setup to make exception handling work.  The setup of the BSPs
per-cpu variables stay early too; they're used on certain error paths.

Move load_system_tables() later into traps_init().  Note that it already
contains enable_each_ist(), so the call is simply dropped.

This removes some complexity prior to having exception support, and lays the
groundwork to not even allocate a TSS when using FRED.

No practical change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>

v2:
 * Keep this_cpu(idt) early.
---
 xen/arch/x86/include/asm/system.h |  1 -
 xen/arch/x86/include/asm/traps.h  |  1 +
 xen/arch/x86/setup.c              |  5 ++---
 xen/arch/x86/traps-setup.c        | 32 +++++++++++++++++++++++++++++++
 xen/arch/x86/traps.c              | 13 -------------
 5 files changed, 35 insertions(+), 17 deletions(-)


base-commit: 6e5fed7cb67c9f84653cdbd3924b8a119ef653be
prerequisite-patch-id: 832a3f5dd12d56454ae74d4ae08d1893c672733e
prerequisite-patch-id: 2f5a1dc0cf663d27c66076f809063764e7a99e61
prerequisite-patch-id: 1f25c130d5a1ee15884dfebad9f5d2a4e69f673a

Comments

Jan Beulich March 21, 2025, 7:32 a.m. UTC | #1
On 20.03.2025 21:17, Andrew Cooper wrote:
> Something I overlooked when last cleaning up exception handling is that a TSS
> is not necessary if IST isn't configured, and IST isn't necessary until we're
> running guest code.
> 
> Introduce early_traps_init(), and rearrange the existing logic between this
> and traps_init() later on boot, to allow defering TSS and IST setup.
> 
> In early_traps_init(), load the IDT and invalidate TR/LDTR; this sufficient
> system-table setup to make exception handling work.  The setup of the BSPs
> per-cpu variables stay early too; they're used on certain error paths.
> 
> Move load_system_tables() later into traps_init().  Note that it already
> contains enable_each_ist(), so the call is simply dropped.
> 
> This removes some complexity prior to having exception support, and lays the
> groundwork to not even allocate a TSS when using FRED.
> 
> No practical change.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
diff mbox series

Patch

diff --git a/xen/arch/x86/include/asm/system.h b/xen/arch/x86/include/asm/system.h
index 1bf6bd026852..8ceaaf45d1a0 100644
--- a/xen/arch/x86/include/asm/system.h
+++ b/xen/arch/x86/include/asm/system.h
@@ -263,7 +263,6 @@  static inline int local_irq_is_enabled(void)
 #define BROKEN_ACPI_Sx          0x0001
 #define BROKEN_INIT_AFTER_S1    0x0002
 
-void init_idt_traps(void);
 void load_system_tables(void);
 void subarch_percpu_traps_init(void);
 
diff --git a/xen/arch/x86/include/asm/traps.h b/xen/arch/x86/include/asm/traps.h
index 3d30aa6738d4..72c33a33e283 100644
--- a/xen/arch/x86/include/asm/traps.h
+++ b/xen/arch/x86/include/asm/traps.h
@@ -7,6 +7,7 @@ 
 #ifndef ASM_TRAP_H
 #define ASM_TRAP_H
 
+void early_traps_init(void);
 void traps_init(void);
 void percpu_traps_init(void);
 
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 993a6202a398..7d6e52a55f2f 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1087,14 +1087,13 @@  void asmlinkage __init noreturn __start_xen(void)
     };
     const char *hypervisor_name;
 
-    /* Critical region without IDT or TSS.  Any fault is deadly! */
+    /* Critical region without exception handling.  Any fault is deadly! */
 
     init_shadow_spec_ctrl_state();
 
     percpu_init_areas();
 
-    init_idt_traps();
-    load_system_tables();
+    early_traps_init();
 
     smp_prepare_boot_cpu();
     sort_exception_tables();
diff --git a/xen/arch/x86/traps-setup.c b/xen/arch/x86/traps-setup.c
index 1a7b42c14bf2..a8385b26ae9b 100644
--- a/xen/arch/x86/traps-setup.c
+++ b/xen/arch/x86/traps-setup.c
@@ -55,6 +55,36 @@  static void __init init_ler(void)
     setup_force_cpu_cap(X86_FEATURE_XEN_LBR);
 }
 
+/*
+ * Configure basic exception handling.  This is prior to parsing the command
+ * line or configuring a console, and needs to be as simple as possible.
+ *
+ * boot_gdt is already loaded, and bsp_idt[] is constructed without IST
+ * settings, so we don't need a TSS configured yet.
+ */
+void __init early_traps_init(void)
+{
+    const struct desc_ptr idtr = {
+        .base = (unsigned long)bsp_idt,
+        .limit = sizeof(bsp_idt) - 1,
+    };
+
+    lidt(&idtr);
+
+    /* Invalidate TR/LDTR as they're not set up yet. */
+    _set_tssldt_desc(boot_gdt + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
+                     0, 0, SYS_DESC_tss_avail);
+
+    ltr(TSS_SELECTOR);
+    lldt(0);
+
+    /* Set up the BSPs per-cpu references. */
+    this_cpu(idt) = bsp_idt;
+    this_cpu(gdt) = boot_gdt;
+    if ( IS_ENABLED(CONFIG_PV32) )
+        this_cpu(compat_gdt) = boot_compat_gdt;
+}
+
 /*
  * Configure complete exception, interrupt and syscall handling.
  */
@@ -63,6 +93,8 @@  void __init traps_init(void)
     /* Replace early pagefault with real pagefault handler. */
     _update_gate_addr_lower(&bsp_idt[X86_EXC_PF], entry_PF);
 
+    load_system_tables();
+
     init_ler();
 
     /* Cache {,compat_}gdt_l1e now that physically relocation is done. */
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 79d92f21acf5..25e0d5777e6e 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1858,19 +1858,6 @@  void asmlinkage do_entry_CP(struct cpu_user_regs *regs)
     panic("CONTROL-FLOW PROTECTION FAULT: #CP[%04x] %s\n", ec, err);
 }
 
-void __init init_idt_traps(void)
-{
-    /* Specify dedicated interrupt stacks for NMI, #DF, and #MC. */
-    enable_each_ist(bsp_idt);
-
-    /* CPU0 uses the master IDT. */
-    this_cpu(idt) = bsp_idt;
-
-    this_cpu(gdt) = boot_gdt;
-    if ( IS_ENABLED(CONFIG_PV32) )
-        this_cpu(compat_gdt) = boot_compat_gdt;
-}
-
 void asm_domain_crash_synchronous(unsigned long addr)
 {
     /*