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

Re: [PATCH v3 04/22] x86/boot/slaunch-early: implement early initialization


  • To: Sergii Dmytruk <sergii.dmytruk@xxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: ross.philipson@xxxxxxxxxx
  • Date: Tue, 3 Jun 2025 09:17:29 -0700
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Bvz81MBFxNDPQYEaUfkbYf5tO+1avxRcX3L+dkWTGJw=; b=qre0/3e84ghZpeGjNnAb6DuCR1yRsM2wOO/1qKRLprLNrHSyQPvgHmilmDGcVyGhcsK/IhJm/GDTp1aesdEGIQ4VwPw4k3NvijU1KWM+jJWRHByvamBXs5LVjUq1gPPMVTlTf1y3AWGRVfBVlW//6TPgd9lyaYygwBBdMI3YCqGoWLaN5+1ywbOPvbk7tqHsrcfbGA4IM0NUWNY3iNehKv6P3yaHXEl+p4KaktHPzHvXoKdsArCjmVUOTqubMKmKoRIhCTvANiQKKgUarKmwGQfuR/QhWs11v3QUkYndqu2ohrWVnRduBxdDkziIdoKC0wJkqGyzixHhZWxv+yt+hQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=qKQz2sNV1QvTJwsj7lUNz7dt+beIJ0TMjaDZa5Hx9cgqvdZuucO5yem8LjqnamD595bqRdHPZqbNNoe0DplIVsyE196gApp9H4NK5ieywUZnE2JcvXwm8nJDxka2JEscE7YNPYt28suJPs2hapjvgXFRRKohqIGxvVQ3Xcw9V1k4ixEgdZOru/hbeZIrtRTwVhuL0PxmS3h+6bhHIOzpIzmYQKnx93EaFwjIhyMDse0M9uFB39JIeaqXP7ByGm/GEX2oamBcR0lAbrvAihXVviDG6O+rfkdlik8Yvpmo5ghFE4iEYcRRjW5j7IyPXIulpkPv3N+6NWE7OezuVHA5Wg==
  • Cc: Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>, trenchboot-devel@xxxxxxxxxxxxxxxx
  • Delivery-date: Tue, 03 Jun 2025 16:17:52 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 5/30/25 6:17 AM, Sergii Dmytruk wrote:
Make head.S invoke a C function to retrieve MBI and SLRT addresses in a
platform-specific way.  This is also the place to perform sanity checks
of DRTM.

Signed-off-by: Krystian Hebel <krystian.hebel@xxxxxxxxx>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@xxxxxxxxx>
---
  xen/arch/x86/Makefile                |  1 +
  xen/arch/x86/boot/Makefile           |  5 +++-
  xen/arch/x86/boot/head.S             | 43 ++++++++++++++++++++++++++++
  xen/arch/x86/boot/slaunch-early.c    | 41 ++++++++++++++++++++++++++
  xen/arch/x86/include/asm/intel-txt.h | 16 +++++++++++
  xen/arch/x86/include/asm/slaunch.h   | 26 +++++++++++++++++
  xen/arch/x86/slaunch.c               | 27 +++++++++++++++++
  7 files changed, 158 insertions(+), 1 deletion(-)
  create mode 100644 xen/arch/x86/boot/slaunch-early.c
  create mode 100644 xen/arch/x86/include/asm/slaunch.h
  create mode 100644 xen/arch/x86/slaunch.c

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index ce724a9daa..aa20eb42b5 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_COMPAT) += x86_64/physdev.o
  obj-$(CONFIG_X86_PSR) += psr.o
  obj-y += setup.o
  obj-y += shutdown.o
+obj-y += slaunch.o
  obj-y += smp.o
  obj-y += smpboot.o
  obj-y += spec_ctrl.o
diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
index ff0d61d7ac..5471b966dd 100644
--- a/xen/arch/x86/boot/Makefile
+++ b/xen/arch/x86/boot/Makefile
@@ -5,6 +5,7 @@ obj-bin-y += $(obj64)
  obj32 := cmdline.32.o
  obj32 += reloc.32.o
  obj32 += reloc-trampoline.32.o
+obj32 += slaunch-early.32.o
obj64 := reloc-trampoline.o @@ -28,6 +29,8 @@ $(obj32): XEN_CFLAGS := $(CFLAGS_x86_32) -fpic
  $(obj)/%.32.o: $(src)/%.c FORCE
        $(call if_changed_rule,cc_o_c)
+$(obj)/slaunch-early.32.o: XEN_CFLAGS += -D__EARLY_SLAUNCH__
+
  orphan-handling-$(call ld-option,--orphan-handling=error) := 
--orphan-handling=error
  LDFLAGS_DIRECT-$(call ld-option,--warn-rwx-segments) := --no-warn-rwx-segments
  LDFLAGS_DIRECT += $(LDFLAGS_DIRECT-y)
@@ -81,7 +84,7 @@ cmd_combine = \
                --bin1      $(obj)/built-in-32.base.bin \
                --bin2      $(obj)/built-in-32.offset.bin \
                --map       $(obj)/built-in-32.base.map \
-              --exports   cmdline_parse_early,reloc,reloc_trampoline32 \
+              --exports   
cmdline_parse_early,reloc,reloc_trampoline32,slaunch_early_init \
                --output    $@
targets += built-in-32.S
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index a69107bd81..b4cf423c80 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -472,6 +472,10 @@ __start:
          /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
          xor     %edx,%edx
+ /* Check for TrenchBoot slaunch bootloader. */
+        cmp     $SLAUNCH_BOOTLOADER_MAGIC, %eax
+        je      .Lslaunch_proto
+
          /* Check for Multiboot2 bootloader. */
          cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
          je      .Lmultiboot2_proto
@@ -487,6 +491,45 @@ __start:
          cmovnz  MB_mem_lower(%ebx),%edx
          jmp     trampoline_bios_setup
+.Lslaunch_proto:
+        /*
+         * Upon reaching here, CPU state mostly matches the one setup by the
+         * bootloader with ESP, ESI and EDX being clobbered above.
+         */
+
+        /* Save information that TrenchBoot slaunch was used. */
+        movb    $1, sym_esi(slaunch_active)
+
+        /*
+         * Prepare space for output parameter of slaunch_early_init(), which is
+         * a structure of two uint32_t fields.
+         */
+        sub     $8, %esp
+
+        push    %esp                             /* pointer to output 
structure */
+        lea     sym_offs(__2M_rwdata_end), %ecx  /* end of target image */
+        lea     sym_offs(_start), %edx           /* target base address */
+        mov     %esi, %eax                       /* load base address */
+        /*
+         * slaunch_early_init(load/eax, tgt/edx, tgt_end/ecx, ret/stk) using
+         * fastcall calling convention.
+         */
+        call    slaunch_early_init
+        add     $4, %esp                         /* pop the fourth parameter */
+
+        /* Move outputs of slaunch_early_init() from stack into registers. */
+        pop     %eax  /* physical MBI address */
+        pop     %edx  /* physical SLRT address */
+
+        /* Save physical address of SLRT for C code. */
+        mov     %edx, sym_esi(slaunch_slrt)
+
+        /* Store MBI address in EBX where MB2 code expects it. */
+        mov     %eax, %ebx
+
+        /* Move magic number expected by Multiboot 2 to EAX and fall through. 
*/
+        movl    $MULTIBOOT2_BOOTLOADER_MAGIC, %eax
+
  .Lmultiboot2_proto:
          /* Skip Multiboot2 information fixed part. */
          lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx
diff --git a/xen/arch/x86/boot/slaunch-early.c 
b/xen/arch/x86/boot/slaunch-early.c
new file mode 100644
index 0000000000..c9d364bcd5
--- /dev/null
+++ b/xen/arch/x86/boot/slaunch-early.c
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved.
+ */
+
+#include <xen/slr-table.h>
+#include <xen/types.h>
+#include <asm/intel-txt.h>
+
+struct early_init_results
+{
+    uint32_t mbi_pa;
+    uint32_t slrt_pa;
+} __packed;
+
+void asmlinkage slaunch_early_init(uint32_t load_base_addr,
+                                   uint32_t tgt_base_addr,
+                                   uint32_t tgt_end_addr,
+                                   struct early_init_results *result)
+{
+    void *txt_heap;
+    const struct txt_os_mle_data *os_mle;
+    const struct slr_table *slrt;
+    const struct slr_entry_intel_info *intel_info;
+
+    txt_heap = txt_init();
+    os_mle = txt_os_mle_data_start(txt_heap);
+
+    result->slrt_pa = os_mle->slrt;
+    result->mbi_pa = 0;
+
+    slrt = (const struct slr_table *)(uintptr_t)os_mle->slrt;
+
+    intel_info = (const struct slr_entry_intel_info *)
+        slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
+    if ( intel_info == NULL || intel_info->hdr.size != sizeof(*intel_info) )
+        return;

Since these are the x86/TXT bits, it seems at this point, not finding the TXT info structure would be fatal, no?

+
+    result->mbi_pa = intel_info->boot_params_base;
+}
diff --git a/xen/arch/x86/include/asm/intel-txt.h 
b/xen/arch/x86/include/asm/intel-txt.h
index cc2d312f4d..7658457e9d 100644
--- a/xen/arch/x86/include/asm/intel-txt.h
+++ b/xen/arch/x86/include/asm/intel-txt.h
@@ -292,6 +292,22 @@ static inline void *txt_sinit_mle_data_start(const void 
*heap)
             sizeof(uint64_t);
  }
+static inline void *txt_init(void)
+{
+    void *txt_heap;
+
+    /* Clear the TXT error register for a clean start of the day. */
+    txt_write(TXTCR_ERRORCODE, 0);
+
+    txt_heap = _p(txt_read(TXTCR_HEAP_BASE));
+
+    if ( txt_os_mle_data_size(txt_heap) < sizeof(struct txt_os_mle_data) ||
+         txt_os_sinit_data_size(txt_heap) < sizeof(struct txt_os_sinit_data) )
+        txt_reset(SLAUNCH_ERROR_GENERIC);

I know the list of error codes pulled in are from the patches for Linux Secure Launch which seems right. The Xen work is free to add more specific error codes e.g. somewhere like here. We could even consider using regions in the vendor error code space for different things like generic errors vs architecture specific ones vs etc.

Thanks
Ross

+
+    return txt_heap;
+}
+
  #endif /* __ASSEMBLY__ */
#endif /* X86_INTEL_TXT_H */
diff --git a/xen/arch/x86/include/asm/slaunch.h 
b/xen/arch/x86/include/asm/slaunch.h
new file mode 100644
index 0000000000..df42defd92
--- /dev/null
+++ b/xen/arch/x86/include/asm/slaunch.h
@@ -0,0 +1,26 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved.
+ */
+
+#ifndef X86_SLAUNCH_H
+#define X86_SLAUNCH_H
+
+#include <xen/types.h>
+
+/* Indicates an active Secure Launch boot. */
+extern bool slaunch_active;
+
+/*
+ * Holds physical address of SLRT.  Use slaunch_get_slrt() to access SLRT
+ * instead of mapping where this points to.
+ */
+extern uint32_t slaunch_slrt;
+
+/*
+ * Retrieves pointer to SLRT.  Checks table's validity and maps it as 
necessary.
+ */
+struct slr_table *slaunch_get_slrt(void);
+
+#endif /* X86_SLAUNCH_H */
diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c
new file mode 100644
index 0000000000..a3e6ab8d71
--- /dev/null
+++ b/xen/arch/x86/slaunch.c
@@ -0,0 +1,27 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved.
+ */
+
+#include <xen/compiler.h>
+#include <xen/init.h>
+#include <xen/macros.h>
+#include <xen/types.h>
+#include <asm/slaunch.h>
+
+/*
+ * These variables are assigned to by the code near Xen's entry point.
+ *
+ * slaunch_active is not __initdata to allow checking for an active Secure
+ * Launch boot.
+ */
+bool slaunch_active;
+uint32_t __initdata slaunch_slrt; /* physical address */
+
+/* Using slaunch_active in head.S assumes it's a single byte in size, so 
enforce
+ * this assumption. */
+static void __maybe_unused compile_time_checks(void)
+{
+    BUILD_BUG_ON(sizeof(slaunch_active) != 1);
+}




 


Rackspace

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