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
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();
}
#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);
{
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
#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)
#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)
/*
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 */