grub-devel
[Top][All Lists]
Advanced

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

[PATCH] Implement relocator for SKINIT


From: Krystian Hebel
Subject: [PATCH] Implement relocator for SKINIT
Date: Wed, 18 Dec 2019 12:28:03 +0100

SKINIT is AMD's implementation of Dynamic Root of Trust for Measurement
(DRTM). It's operation is described in section 15.27 of AMD Architecture
Programmer’s Manual Volume 2 [1].

SKINIT instruction takes only one argument in EAX register - a pointer
to the SLB (Secure Launch Block). No other registers are preserved by
SKINIT, so there is no need to set the rest of CPU state.

The patch implements the relocator only. The rest of the requirements
(SLB alignment, TPM state, APs in INIT state) must be ensured by code
calling this relocator.

[1]: https://www.amd.com/system/files/TechDocs/24593.pdf

Signed-off-by: Krystian Hebel <address@hidden>
---
 grub-core/Makefile.core.def                |  2 +
 grub-core/lib/i386/relocator_slaunch.c     | 71 ++++++++++++++++++++++
 grub-core/lib/i386/relocator_slaunch_asm.S | 37 +++++++++++
 include/grub/i386/relocator.h              |  4 ++
 4 files changed, 114 insertions(+)
 create mode 100644 grub-core/lib/i386/relocator_slaunch.c
 create mode 100644 grub-core/lib/i386/relocator_slaunch_asm.S

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 23459a7fca37..1d5b0d96f1fc 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1644,6 +1644,8 @@ module = {
   x86_64_xen = lib/x86_64/xen/relocator.S;
   xen = lib/i386/relocator_common_c.c;
   x86_64_efi = lib/x86_64/efi/relocator.c;
+  x86 = lib/i386/relocator_slaunch_asm.S;
+  x86 = lib/i386/relocator_slaunch.c;
 
   extra_dist = lib/i386/relocator_common.S;
   extra_dist = kern/powerpc/cache_flush.S;
diff --git a/grub-core/lib/i386/relocator_slaunch.c 
b/grub-core/lib/i386/relocator_slaunch.c
new file mode 100644
index 000000000000..458091d93dcc
--- /dev/null
+++ b/grub-core/lib/i386/relocator_slaunch.c
@@ -0,0 +1,71 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *  Copyright (C) 2019 3mdeb Embedded Systems Consulting
+ *
+ *  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/mm.h>
+#include <grub/misc.h>
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/term.h>
+
+#include <grub/i386/relocator.h>
+#include <grub/relocator_private.h>
+#include <grub/i386/relocator_private.h>
+#include <grub/i386/pc/int.h>
+
+extern grub_uint8_t grub_relocator_skinit_start;
+extern grub_uint8_t grub_relocator_skinit_end;
+extern grub_uint32_t *grub_relocator_skinit_slb;
+
+
+#define RELOCATOR_SIZEOF(x)    (&grub_relocator##x##_end - 
&grub_relocator##x##_start)
+
+grub_err_t
+grub_relocator_skinit_boot (struct grub_relocator *rel,
+                      grub_uint32_t *slb,
+                      int avoid_efi_bootservices)
+{
+  grub_err_t err;
+  void *relst;
+  grub_relocator_chunk_t ch;
+
+  err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000,
+                                         0x100000000 - RELOCATOR_SIZEOF 
(_skinit),
+                                         RELOCATOR_SIZEOF (_skinit), 16,
+                                         GRUB_RELOCATOR_PREFERENCE_LOW,
+                                         avoid_efi_bootservices);
+  if (err)
+    return err;
+
+  grub_relocator_skinit_slb = slb;
+
+  grub_memmove (get_virtual_current_address (ch), &grub_relocator_skinit_start,
+               RELOCATOR_SIZEOF (_skinit));
+
+  err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
+                                      &relst, NULL);
+  if (err)
+    return err;
+
+  asm volatile ("cli");
+  ((void (*) (void)) relst) ();
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/lib/i386/relocator_slaunch_asm.S 
b/grub-core/lib/i386/relocator_slaunch_asm.S
new file mode 100644
index 000000000000..0d19c743131d
--- /dev/null
+++ b/grub-core/lib/i386/relocator_slaunch_asm.S
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2019 3mdeb Embedded Systems Consulting
+ *
+ *  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/>.
+ */
+
+/*
+ * skinit resets the CPU state. Assuming we are already in protected mode
+ * (doesn't matter if it is legacy, compatibility or long mode) with CPL=0,
+ * there is no additional setup to be done.
+ */
+
+#include <grub/symbol.h>
+
+       .p2align        4       /* force 16-byte alignment */
+
+VARIABLE(grub_relocator_skinit_start)
+
+       /* mov imm32, %eax */
+       .byte   0xb8
+VARIABLE(grub_relocator_skinit_slb)
+       .long   0
+
+       skinit
+VARIABLE(grub_relocator_skinit_end)
diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h
index 2a56c3b54750..c7d651bfe634 100644
--- a/include/grub/i386/relocator.h
+++ b/include/grub/i386/relocator.h
@@ -90,6 +90,10 @@ grub_err_t grub_relocator64_boot (struct grub_relocator *rel,
                                  struct grub_relocator64_state state,
                                  grub_addr_t min_addr, grub_addr_t max_addr);
 
+grub_err_t grub_relocator_skinit_boot (struct grub_relocator *rel,
+                                 grub_uint32_t *slb,
+                                 int avoid_efi_bootservices);
+
 #ifdef GRUB_MACHINE_EFI
 #ifdef __x86_64__
 grub_err_t grub_relocator64_efi_boot (struct grub_relocator *rel,
-- 
2.17.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]