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

[xen staging] x86: Support booting under Secure Startup via SKINIT



commit e4283bf38aae6c2f88cdbdaeef0f005a1a5f6c78
Author:     Norbert KamiÅ?ski <norbert.kaminski@xxxxxxxxx>
AuthorDate: Tue Jan 12 21:27:43 2021 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Jan 29 12:04:01 2021 +0000

    x86: Support booting under Secure Startup via SKINIT
    
    For now, this is simply enough logic to let Xen come up after the bootloader
    has executed an SKINIT instruction to begin a Secure Startup.
    
    During a Secure Startup, the BSP operates with the GIF clear (blocks all
    external interrupts, even SMI/NMI), and INIT_REDIRECTION active (converts 
INIT
    IPIs to #SX exceptions, if e.g. the platform needs to scrub secrets before
    resetting).  To afford APs the same Secure Startup protections as the BSP, 
the
    INIT IPI must be skipped, and SIPI must be the first interrupt seen.
    
    Full details are available in AMD APM Vol2 15.27 "Secure Startup with 
SKINIT"
    
    Introduce skinit_enable_intr() and call it from cpu_init(), next to the
    enable_nmis() which performs a related function for tboot startups.
    
    Also introduce ap_boot_method to control the sequence of actions for AP 
boot.
    
    Signed-off-by: Marek Kasiewicz <marek.kasiewicz@xxxxxxxxx>
    Signed-off-by: Norbert KamiÅ?ski <norbert.kaminski@xxxxxxxxx>
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/cpu/common.c        | 32 ++++++++++++++++++++++++++++++++
 xen/arch/x86/smpboot.c           | 12 +++++++++++-
 xen/include/asm-x86/cpufeature.h |  1 +
 xen/include/asm-x86/msr-index.h  |  1 +
 xen/include/asm-x86/processor.h  |  6 ++++++
 5 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index a684519a20..e5c3caf41d 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -834,6 +834,29 @@ void load_system_tables(void)
        BUG_ON(system_state != SYS_STATE_early_boot && (stack_bottom & 0xf));
 }
 
+static void skinit_enable_intr(void)
+{
+       uint64_t val;
+
+       /*
+        * If the platform is performing a Secure Launch via SKINIT
+        * INIT_REDIRECTION flag will be active.
+        */
+       if ( !cpu_has_skinit || rdmsr_safe(MSR_K8_VM_CR, val) ||
+            !(val & VM_CR_INIT_REDIRECTION) )
+               return;
+
+       ap_boot_method = AP_BOOT_SKINIT;
+
+       /*
+        * We don't yet handle #SX.  Disable INIT_REDIRECTION first, before
+        * enabling GIF, so a pending INIT resets us, rather than causing a
+        * panic due to an unknown exception.
+        */
+       wrmsrl(MSR_K8_VM_CR, val & ~VM_CR_INIT_REDIRECTION);
+       asm volatile ( "stgi" ::: "memory" );
+}
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -865,6 +888,15 @@ void cpu_init(void)
        write_debugreg(6, X86_DR6_DEFAULT);
        write_debugreg(7, X86_DR7_DEFAULT);
 
+       /*
+        * If the platform is performing a Secure Launch via SKINIT, GIF is
+        * clear to prevent external interrupts interfering with Secure
+        * Startup.  Re-enable all interrupts now that we are suitably set up.
+        *
+        * Refer to AMD APM Vol2 15.27 "Secure Startup with SKINIT".
+        */
+       skinit_enable_intr();
+
        /* Enable NMIs.  Our loader (e.g. Tboot) may have left them disabled. */
        enable_nmis();
 }
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 61ce923189..82c1012e89 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -49,6 +49,7 @@
 #include <mach_apic.h>
 
 unsigned long __read_mostly trampoline_phys;
+enum ap_boot_method __read_mostly ap_boot_method = AP_BOOT_NORMAL;
 
 /* representing HT siblings of each logical CPU */
 DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask);
@@ -424,7 +425,16 @@ static int wakeup_secondary_cpu(int phys_apicid, unsigned 
long start_eip)
 {
     unsigned long send_status = 0, accept_status = 0;
     int maxlvt, timeout, i;
-    bool send_INIT = true;
+
+    /*
+     * Normal AP startup uses an INIT-SIPI-SIPI sequence.
+     *
+     * When using SKINIT for Secure Startup, the INIT IPI must be skipped, so
+     * that SIPI is the first interrupt the AP sees.
+     *
+     * Refer to AMD APM Vol2 15.27 "Secure Startup with SKINIT".
+     */
+    bool send_INIT = ap_boot_method != AP_BOOT_SKINIT;
 
     /*
      * Some versions of tboot might be able to handle the entire wake sequence
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index ad3d84bdde..f62e526a96 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -76,6 +76,7 @@
 #define cpu_has_svm             boot_cpu_has(X86_FEATURE_SVM)
 #define cpu_has_sse4a           boot_cpu_has(X86_FEATURE_SSE4A)
 #define cpu_has_xop             boot_cpu_has(X86_FEATURE_XOP)
+#define cpu_has_skinit          boot_cpu_has(X86_FEATURE_SKINIT)
 #define cpu_has_fma4            boot_cpu_has(X86_FEATURE_FMA4)
 #define cpu_has_tbm             boot_cpu_has(X86_FEATURE_TBM)
 
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index ff583cf0ed..1f5a5d0e38 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -117,6 +117,7 @@
 #define  PASID_VALID                        (_AC(1, ULL) << 31)
 
 #define MSR_K8_VM_CR                        0xc0010114
+#define  VM_CR_INIT_REDIRECTION             (_AC(1, ULL) <<  1)
 #define  VM_CR_SVM_DISABLE                  (_AC(1, ULL) <<  4)
 
 /*
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 9acb80fdcd..d5f467d245 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -631,6 +631,12 @@ static inline uint8_t get_cpu_family(uint32_t raw, uint8_t 
*model,
 extern int8_t opt_tsx, cpu_has_tsx_ctrl;
 void tsx_init(void);
 
+enum ap_boot_method {
+    AP_BOOT_NORMAL,
+    AP_BOOT_SKINIT,
+};
+extern enum ap_boot_method ap_boot_method;
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_X86_PROCESSOR_H */
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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