From: Krystian Hebel <krystian.he...@3mdeb.com>

This adds code for placing of SLB and initialization of SLRT for AMD
SKINIT.

Signed-off-by: Krystian Hebel <krystian.he...@3mdeb.com>
Signed-off-by: Sergii Dmytruk <sergii.dmyt...@3mdeb.com>
---
 grub-core/Makefile.core.def    |  1 +
 grub-core/loader/i386/skinit.c | 98 ++++++++++++++++++++++++++++++++++
 include/grub/i386/skinit.h     | 34 ++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 grub-core/loader/i386/skinit.c
 create mode 100644 include/grub/i386/skinit.h

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index f2975713d..2fbe5a99c 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1877,6 +1877,7 @@ module = {
   x86 = loader/i386/txt/txt.c;
   x86 = loader/i386/txt/acmod.c;
   x86 = loader/i386/txt/verify.c;
+  x86 = loader/i386/skinit.c;
   enable = x86;
 };
 
diff --git a/grub-core/loader/i386/skinit.c b/grub-core/loader/i386/skinit.c
new file mode 100644
index 000000000..d536630a6
--- /dev/null
+++ b/grub-core/loader/i386/skinit.c
@@ -0,0 +1,98 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ *  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/cpu/relocator.h>
+#include <grub/dl.h>
+#include <grub/i386/skinit.h>
+#include <grub/i386/tpm.h>
+#include <grub/mm.h>
+#include <grub/slr_table.h>
+#include <grub/types.h>
+
+#define SLRT_SIZE  GRUB_PAGE_SIZE
+
+/* Offset to entry point. */
+#define SLB_ENTRY(slb)    ((const grub_uint16_t *) (slb))[0]
+/* Amount of data actually measured for DRTM. */
+#define SLB_MEASURED(slb) ((const grub_uint16_t *) (slb))[1]
+/* Offset to structure with extra info. */
+#define SLB_INFO(slb)     ((const grub_uint16_t *) (slb))[2]
+/* Offset to area for passing data to SKL. */
+#define SLB_PARAM(slb)    ((const grub_uint16_t *) (slb))[3]
+
+grub_err_t
+grub_skinit_boot_prepare (struct grub_relocator *rel,
+                          struct grub_slaunch_params *slparams)
+{
+  grub_uint32_t *apic = (grub_uint32_t *) 0xfee00300ULL;
+  const void *slb = grub_slaunch_module ();
+  grub_relocator_chunk_t ch;
+  grub_err_t err;
+  void *dce_mem;
+
+  if (slb == NULL)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "SLB module is missing");
+
+  /*
+   * Contrary to the TXT, on AMD we do not have vendor-provided blobs in
+   * reserved memory, we are using normal RAM
+   */
+  err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
+                                          0xffffffff - GRUB_SKINIT_SLB_SIZE,
+                                          GRUB_SKINIT_SLB_SIZE,
+                                          GRUB_SKINIT_SLB_ALIGN,
+                                          GRUB_RELOCATOR_PREFERENCE_LOW, 1);
+
+  if (err != GRUB_ERR_NONE)
+    return grub_error (err, "cannot alloc memory for SLB");
+
+  /*
+   * Send INIT IPI to all APs (CPUs other than this one).
+   *
+   * "AMD64 Architecture Programmer’s Manual, Rev. 3.42, Vol. 2" says 
"Depending
+   * on processor implementation, a fixed delay of no more than 1000 processor
+   * cycles may be necessary before executing SKINIT to ensure reliable sensing
+   * of APIC INIT state by the SKINIT."
+   *
+   * However, in tests it wasn't always enough (sometimes up to 7000 cycles
+   * were necessary), so send the IPIs before grub_memcpy()/grub_memset() to
+   * increase the delay before SKINIT is executed.
+   */
+  grub_dprintf ("slaunch", "broadcasting INIT\r\n");
+  *apic = 0x000c0500;
+
+  slparams->dce_base = get_physical_target_address (ch);
+  slparams->dce_size = SLB_MEASURED (slb);
+
+  dce_mem = get_virtual_current_address (ch);
+  grub_memcpy (dce_mem, slb, slparams->dce_size);
+
+  slparams->slr_table_base = slparams->dce_base + SLB_PARAM (slb);
+  slparams->slr_table_size = SLRT_SIZE;
+  slparams->slr_table_mem = (grub_uint8_t *) dce_mem + SLB_PARAM (slb);
+  grub_memset (slparams->slr_table_mem, 0, SLRT_SIZE);
+
+  grub_slaunch_init_slrt_storage (GRUB_SLR_AMD_SKINIT);
+
+  grub_dprintf ("slaunch", "grub_tpm_relinquish_locality\r\n");
+  grub_tpm_relinquish_locality (0);
+
+  grub_dprintf ("slaunch", "Invoke SKINIT\r\n");
+
+  return GRUB_ERR_NONE;
+}
diff --git a/include/grub/i386/skinit.h b/include/grub/i386/skinit.h
new file mode 100644
index 000000000..e2d5e4fbf
--- /dev/null
+++ b/include/grub/i386/skinit.h
@@ -0,0 +1,34 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2020  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/>.
+ *
+ *  Main secure launch definitions header file.
+ */
+
+#ifndef GRUB_I386_SKINIT_H
+#define GRUB_I386_SKINIT_H 1
+
+/* SLB is 64k, 64k-aligned. */
+#define GRUB_SKINIT_SLB_SIZE   0x10000
+#define GRUB_SKINIT_SLB_ALIGN  0x10000
+
+#include <grub/cpu/relocator.h>
+#include <grub/i386/slaunch.h>
+
+grub_err_t grub_skinit_boot_prepare (struct grub_relocator *rel,
+                                     struct grub_slaunch_params *slparams);
+
+#endif /* GRUB_I386_SKINIT_H */
-- 
2.46.0


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

Reply via email to