[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1.1 08/22] x86/traps: Introduce percpu_early_traps_init() and set up exception handling earlier



As things stand, we set up AP/S3 exception handling marginally after the
fragile activity of setting up shadow stacks.  Shadow stack setup is going to
get more complicated under FRED.

Introduce percpu_early_traps_init() and call it ahead of setting up shadow
stacks.  To start with, call load_system_tables() which is sufficient to set
up full exception handling.

In order to handle exceptions, current and the speculation controls needs to
work.  cpu_smpboot_alloc() already constructs some of the AP's top-of-stack
block, so have it set up a little more.  Zero the whole structure to subsume
other misc setup.

This gets us complete exception coverage of setting up shadow stacks, rather
than dying with a triple fault.

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

v2:
 * Rename to percpu_early_traps_init()
 * Reorder setup
---
 xen/arch/x86/acpi/wakeup_prot.S |  5 +++--
 xen/arch/x86/boot/x86_64.S      |  5 ++++-
 xen/arch/x86/smpboot.c          | 19 ++++++-------------
 xen/arch/x86/traps-setup.c      | 12 ++++++++++++
 4 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/xen/arch/x86/acpi/wakeup_prot.S b/xen/arch/x86/acpi/wakeup_prot.S
index 92af6230b31f..cc40fddc38d4 100644
--- a/xen/arch/x86/acpi/wakeup_prot.S
+++ b/xen/arch/x86/acpi/wakeup_prot.S
@@ -63,6 +63,9 @@ LABEL(s3_resume)
         pushq   %rax
         lretq
 1:
+        /* Set up early exceptions and CET before entering C properly. */
+        call    percpu_early_traps_init
+
 #if defined(CONFIG_XEN_SHSTK) || defined(CONFIG_XEN_IBT)
         call    xen_msr_s_cet_value
         test    %eax, %eax
@@ -117,8 +120,6 @@ LABEL(s3_resume)
 .L_cet_done:
 #endif /* CONFIG_XEN_SHSTK || CONFIG_XEN_IBT */
 
-        call    load_system_tables
-
         /* Restore CR4 from the cpuinfo block. */
         GET_STACK_END(bx)
         mov     STACK_CPUINFO_FIELD(cr4)(%rbx), %rax
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 95a6b6cf63bd..d0e7449a149f 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -30,7 +30,10 @@ ENTRY(__high_start)
         test    %ebx,%ebx
         jz      .L_bsp
 
-        /* APs.  Set up CET before entering C properly. */
+        /* APs.  Set up early exceptions and CET before entering C properly. */
+
+        call    percpu_early_traps_init
+
 #if defined(CONFIG_XEN_SHSTK) || defined(CONFIG_XEN_IBT)
         call    xen_msr_s_cet_value
         test    %eax, %eax
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index ce4862dde5a7..efb5adb3a12a 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -327,12 +327,7 @@ void asmlinkage start_secondary(void)
     struct cpu_info *info = get_cpu_info();
     unsigned int cpu = smp_processor_id();
 
-    /* Critical region without IDT or TSS.  Any fault is deadly! */
-
-    set_current(idle_vcpu[cpu]);
-    this_cpu(curr_vcpu) = idle_vcpu[cpu];
     rdmsrl(MSR_EFER, this_cpu(efer));
-    init_shadow_spec_ctrl_state(info);
 
     /*
      * Just as during early bootstrap, it is convenient here to disable
@@ -352,14 +347,6 @@ void asmlinkage start_secondary(void)
      */
     spin_debug_disable();
 
-    get_cpu_info()->use_pv_cr3 = false;
-    get_cpu_info()->xen_cr3 = 0;
-    get_cpu_info()->pv_cr3 = 0;
-
-    load_system_tables();
-
-    /* Full exception support from here on in. */
-
     if ( cpu_has_pks )
         wrpkrs_and_cache(0); /* Must be before setting CR4.PKS */
 
@@ -1064,9 +1051,15 @@ static int cpu_smpboot_alloc(unsigned int cpu)
             goto out;
 
     info = get_cpu_info_from_stack((unsigned long)stack_base[cpu]);
+    memset(info, 0, sizeof(*info));
     info->processor_id = cpu;
     info->per_cpu_offset = __per_cpu_offset[cpu];
 
+    init_shadow_spec_ctrl_state(info);
+
+    info->current_vcpu = idle_vcpu[cpu]; /* set_current() */
+    per_cpu(curr_vcpu, cpu) = idle_vcpu[cpu];
+
     gdt = per_cpu(gdt, cpu) ?: alloc_xenheap_pages(0, memflags);
     if ( gdt == NULL )
         goto out;
diff --git a/xen/arch/x86/traps-setup.c b/xen/arch/x86/traps-setup.c
index 99257bbb16ec..758c67b335bd 100644
--- a/xen/arch/x86/traps-setup.c
+++ b/xen/arch/x86/traps-setup.c
@@ -127,3 +127,15 @@ void percpu_traps_init(void)
     if ( cpu_has_xen_lbr )
         wrmsrl(MSR_IA32_DEBUGCTLMSR, IA32_DEBUGCTLMSR_LBR);
 }
+
+/*
+ * Configure exception handling on APs and S3.  Called before entering C
+ * properly, and before shadow stacks are activated.
+ *
+ * boot_gdt is currently loaded, and we must switch to our local GDT.  The
+ * local IDT has unknown IST-ness.
+ */
+void asmlinkage percpu_early_traps_init(void)
+{
+    load_system_tables();
+}
-- 
2.39.5




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.