[RFC PATCH 4/9] x86: Split up Secure Launch setup and finalize functions

From: Sergii Dmytruk
Date: Thu Dec 12 2024 - 08:44:23 EST


From: Ross Philipson <ross.philipson@xxxxxxxxxx>

Split up the setup and findalize functions internally to determine
the type of launch and call the appropriate function (TXT or SKINIT
version).

Signed-off-by: Ross Philipson <ross.philipson@xxxxxxxxxx>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@xxxxxxxxx>
---
arch/x86/include/asm/svm.h | 2 ++
arch/x86/kernel/setup.c | 2 +-
arch/x86/kernel/slaunch.c | 69 +++++++++++++++++++++++++++++++-------
include/linux/slaunch.h | 4 +--
4 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f0dea3750ca9..e9755f6562c8 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -575,6 +575,8 @@ struct vmcb {

#define SVM_CPUID_FUNC 0x8000000a

+#define SVM_VM_CR_INIT_REDIRECTION 1
+
#define SVM_SELECTOR_S_SHIFT 4
#define SVM_SELECTOR_DPL_SHIFT 5
#define SVM_SELECTOR_P_SHIFT 7
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d915f21306aa..e8bff04201b5 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -939,7 +939,7 @@ void __init setup_arch(char **cmdline_p)
early_gart_iommu_check();
#endif

- slaunch_setup_txt();
+ slaunch_setup();

/*
* partially used pages are not usable - thus
diff --git a/arch/x86/kernel/slaunch.c b/arch/x86/kernel/slaunch.c
index c828d46f3271..7a8ecc8c08a8 100644
--- a/arch/x86/kernel/slaunch.c
+++ b/arch/x86/kernel/slaunch.c
@@ -18,6 +18,7 @@
#include <asm/tlbflush.h>
#include <asm/e820/api.h>
#include <asm/setup.h>
+#include <asm/svm.h>
#include <asm/realmode.h>
#include <linux/slr_table.h>
#include <linux/slaunch.h>
@@ -437,21 +438,11 @@ void __init slaunch_fixup_jump_vector(void)
* Intel TXT specific late stub setup and validation called from within
* x86 specific setup_arch().
*/
-void __init slaunch_setup_txt(void)
+static void __init slaunch_setup_txt(void)
{
u64 one = TXT_REGVALUE_ONE, val;
void __iomem *txt;

- if (!boot_cpu_has(X86_FEATURE_SMX))
- return;
-
- /*
- * If booted through secure launch entry point, the loadflags
- * option will be set.
- */
- if (!(boot_params.hdr.loadflags & SLAUNCH_FLAG))
- return;
-
/*
* See if SENTER was done by reading the status register in the
* public space. If the public register space cannot be read, TXT may
@@ -523,6 +514,42 @@ void __init slaunch_setup_txt(void)
pr_info("Intel TXT setup complete\n");
}

+/*
+ * AMD SKINIT specific late stub setup and validation called from within
+ * x86 specific setup_arch().
+ */
+static void __init slaunch_setup_skinit(void)
+{
+ u64 val;
+
+ /*
+ * If the platform is performing a Secure Launch via SKINIT
+ * INIT_REDIRECTION flag will be active.
+ */
+ rdmsrl(MSR_VM_CR, val);
+ if (!(val & (1 << SVM_VM_CR_INIT_REDIRECTION)))
+ return;
+
+ /* Set flags on BSP so subsequent code knows it was a SKINIT launch */
+ sl_flags |= (SL_FLAG_ACTIVE|SL_FLAG_ARCH_SKINIT);
+ pr_info("AMD SKINIT setup complete\n");
+}
+
+void __init slaunch_setup(void)
+{
+ /*
+ * If booted through secure launch entry point, the loadflags
+ * option will be set.
+ */
+ if (!(boot_params.hdr.loadflags & SLAUNCH_FLAG))
+ return;
+
+ if (boot_cpu_has(X86_FEATURE_SMX))
+ slaunch_setup_txt();
+ else if (boot_cpu_has(X86_FEATURE_SKINIT))
+ slaunch_setup_skinit();
+}
+
static inline void smx_getsec_sexit(void)
{
asm volatile ("getsec\n"
@@ -533,7 +560,7 @@ static inline void smx_getsec_sexit(void)
* Used during kexec and on reboot paths to finalize the TXT state
* and do an SEXIT exiting the DRTM and disabling SMX mode.
*/
-void slaunch_finalize(int do_sexit)
+static void slaunch_finalize_txt(int do_sexit)
{
u64 one = TXT_REGVALUE_ONE, val;
void __iomem *config;
@@ -594,3 +621,21 @@ void slaunch_finalize(int do_sexit)

pr_info("TXT SEXIT complete.\n");
}
+
+/*
+ * Used during kexec and on reboot paths to finalize the SKINIT.
+ */
+static void slaunch_finalize_skinit(void)
+{
+ /* AMD CPUs with PSP-supported DRTM */
+ if (!slaunch_is_skinit_psp())
+ return;
+}
+
+void slaunch_finalize(int do_sexit)
+{
+ if (boot_cpu_has(X86_FEATURE_SMX))
+ slaunch_finalize_txt(do_sexit);
+ else if (boot_cpu_has(X86_FEATURE_SKINIT))
+ slaunch_finalize_skinit();
+}
diff --git a/include/linux/slaunch.h b/include/linux/slaunch.h
index ab01fb6aee15..869b78d8c299 100644
--- a/include/linux/slaunch.h
+++ b/include/linux/slaunch.h
@@ -536,7 +536,7 @@ static inline int tpm2_log_event(struct txt_heap_event_log_pointer2_1_element *e
/*
* External functions avalailable in mainline kernel.
*/
-void slaunch_setup_txt(void);
+void slaunch_setup(void);
void slaunch_fixup_jump_vector(void);
u32 slaunch_get_flags(void);
struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
@@ -552,7 +552,7 @@ void slaunch_psp_finalize(void);

#else

-static inline void slaunch_setup_txt(void)
+static inline void slaunch_setup(void)
{
}

--
2.47.1