From: Ross Philipson <ross.philip...@oracle.com>

Signed-off-by: Ross Philipson <ross.philip...@oracle.com>
Signed-off-by: Sergii Dmytruk <sergii.dmyt...@3mdeb.com>
---
 grub-core/loader/efi/dltrampoline.S | 94 +++++++++++++++++++++++++++++
 grub-core/loader/slaunch/dlstub.c   | 93 ++++++++++++++++++++++++++++
 2 files changed, 187 insertions(+)
 create mode 100644 grub-core/loader/efi/dltrampoline.S
 create mode 100644 grub-core/loader/slaunch/dlstub.c

diff --git a/grub-core/loader/efi/dltrampoline.S 
b/grub-core/loader/efi/dltrampoline.S
new file mode 100644
index 000000000..461e14271
--- /dev/null
+++ b/grub-core/loader/efi/dltrampoline.S
@@ -0,0 +1,94 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2024, Oracle and/or its affiliates.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+
+#define GRUB_SMX_LEAF_SENTER   4
+#define CS_SEL32               0x0008
+#define DS_SEL                 0x0010
+
+#define CR0_PE  0x00000001
+#define CR0_MP  0x00000002
+#define CR0_TS  0x00000008
+#define CR0_NE  0x00000020
+
+       .file   "dltrampoline.S"
+       .text
+
+       .code64
+       .globl  dl_entry_trampoline
+dl_entry_trampoline:
+       /* %edi should contain dl_context pointer */
+       call    EXT_C(dl_entry)
+       ud2
+
+       .globl  dl_trampoline
+dl_trampoline:
+       cli
+       leaq    dl_gdt_base(%rip), %rax
+       leaq    dl_gdt(%rip), %rbx
+       movl    %ebx, (%eax)
+       lgdt    dl_gdtr(%rip)
+
+       /* Setup target to ret to compat mode */
+       leal    1f(%rip), %ecx
+       pushq   $CS_SEL32
+       pushq   %rcx
+       lretq
+
+       .code32
+1:     /* Now in IA-32e compatibility mode load data segments and do senter */
+       movw    $DS_SEL, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %ss
+       movw    %ax, %fs
+       movw    %ax, %gs
+
+       movl    $GRUB_SMX_LEAF_SENTER, %eax
+       movl    %edi, %ebx
+       movl    %esi, %ecx
+       xorl    %edx, %edx
+       getsec
+
+       .align 8
+dl_gdt:
+       /* Null Segment */
+       .quad   0
+       /* 32b Code Segment */
+       .word   0xffff /* Limit 1 */
+       .word   0x0000 /* Base 1 */
+       .byte   0x00   /* Base 2 */
+       .byte   0x9b   /* P=1 DPL=0 S=1 Type=0010 C=0 W=1 A=1 */
+       .byte   0xcf   /* G=1 D=1 L=0 AVL=0 Limit 2 */
+       .byte   0x00   /* Base 3 */
+       /* Data Segment, can be used both in 32b and 64b */
+       .word   0xffff /* Limit 1 */
+       .word   0x0000 /* Base 1 */
+       .byte   0x00   /* Base 2 */
+       .byte   0x93   /* P=1 DPL=0 S=1 Type=0010 C=0 W=1 A=1 */
+       .byte   0xcf   /* G=1 D=1 L=0 AVL=0 Limit 2 */
+       .byte   0x00   /* Base 3 */
+
+       .word   0
+dl_gdtr:
+       .word   23 /* Limit */
+dl_gdt_base:
+       .long   0  /* Base */
+       .long   0
diff --git a/grub-core/loader/slaunch/dlstub.c 
b/grub-core/loader/slaunch/dlstub.c
new file mode 100644
index 000000000..d3c28645e
--- /dev/null
+++ b/grub-core/loader/slaunch/dlstub.c
@@ -0,0 +1,93 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2024, Oracle and/or its affiliates.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/normal.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/slr_table.h>
+#include <grub/slaunch.h>
+#include <grub/cpu/relocator.h>
+#include <grub/i386/msr.h>
+#include <grub/i386/mmio.h>
+#include <grub/i386/txt.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+extern void dl_trampoline(grub_uint32_t dce_base, grub_uint32_t dce_size);
+
+void dl_entry (grub_uint64_t dl_ctx)
+{
+  struct grub_slr_bl_context *bl_ctx = (struct grub_slr_bl_context 
*)(grub_addr_t)dl_ctx;
+  struct grub_slaunch_params *slparams = (struct grub_slaunch_params 
*)(grub_addr_t)bl_ctx->context;
+  struct grub_relocator32_state state = {0};
+  grub_err_t err;
+
+  state.edi = slparams->platform_type;
+
+  if (slparams->platform_type == SLP_INTEL_TXT)
+    {
+      if (slparams->boot_type == GRUB_SL_BOOT_TYPE_EFI)
+        grub_update_slrt_policy (slparams);
+
+      err = grub_set_mtrrs_for_acmod ((void *)(grub_addr_t)slparams->dce_base);
+      if (err)
+        {
+          grub_error (GRUB_ERR_BAD_DEVICE, N_("setting MTRRs for TXT SINIT 
failed"));
+          return;
+        }
+
+      err = grub_txt_prepare_cpu ();
+      if ( err )
+        {
+          grub_error (GRUB_ERR_BAD_DEVICE, N_("prepare CPU for TXT SENTER 
failed"));
+          return;
+        }
+    }
+  else
+    {
+      grub_error (GRUB_ERR_BUG, N_("unknown dynamic launch platform: %d"), 
slparams->platform_type);
+      return;
+    }
+
+  if (!(grub_rdmsr (GRUB_MSR_X86_APICBASE) & GRUB_MSR_X86_APICBASE_BSP))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, N_("x86 dynamic launch event must be 
performed on the BSP"));
+      return;
+    }
+
+  if (slparams->boot_type == GRUB_SL_BOOT_TYPE_LINUX)
+    {
+      /* Configure relocator GETSEC[SENTER] call. */
+      state.eax = GRUB_SMX_LEAF_SENTER;
+      state.ebx = slparams->dce_base;
+      state.ecx = slparams->dce_size;
+      state.edx = 0;
+      grub_relocator32_boot (slparams->relocator, state, 0);
+    }
+  else if (slparams->boot_type == GRUB_SL_BOOT_TYPE_EFI)
+    {
+      dl_trampoline (slparams->dce_base, slparams->dce_size);
+    }
+  else
+    {
+      grub_error (GRUB_ERR_BUG, N_("unknown dynamic launch boot type: %d"), 
slparams->boot_type);
+    }
+}
-- 
2.47.1


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to