grub-devel
[Top][All Lists]
Advanced

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

[GRUB PATCH RFC 19/22] i386/slaunch: Add code for searching for DRTM eve


From: Krystian Hebel
Subject: [GRUB PATCH RFC 19/22] i386/slaunch: Add code for searching for DRTM event log in ACPI
Date: Tue, 10 Nov 2020 15:44:57 +0100

TCG D-RTM Architecture Specification defines DRTM ACPI table. Its fields
include Event Log base and size.

Note that not all of the firmware vendors fill that table, so leave the
previous allocation as a fallback.

Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com>
---
 grub-core/loader/i386/linux.c   |  20 +++---
 grub-core/loader/i386/slaunch.c | 113 ++++++++++++++++++++++++++++++++
 include/grub/i386/slaunch.h     |   1 +
 3 files changed, 126 insertions(+), 8 deletions(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 1b4d40b82843..d83912c17aad 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -248,16 +248,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
                      slparams.mle_ptab_mem, (unsigned long) 
slparams.mle_ptab_target,
                      (unsigned) slparams.mle_ptab_size);
 
-       if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
-                                             0xffffffff - 
GRUB_SLAUNCH_TPM_EVT_LOG_SIZE,
-                                             GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, 
GRUB_PAGE_SIZE,
-                                             GRUB_RELOCATOR_PREFERENCE_NONE, 
1))
-         goto fail;
+       grub_get_drtm_evt_log (&slparams);
+       if (slparams.tpm_evt_log_size == 0)
+       {
+         if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
+                                               0xffffffff - 
GRUB_SLAUNCH_TPM_EVT_LOG_SIZE,
+                                               GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, 
GRUB_PAGE_SIZE,
+                                               GRUB_RELOCATOR_PREFERENCE_NONE, 
1))
+           goto fail;
 
-       slparams.tpm_evt_log_base = get_physical_target_address (ch);
-       slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE;
+         slparams.tpm_evt_log_base = get_physical_target_address (ch);
+         slparams.tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE;
 
-       grub_memset (get_virtual_current_address (ch), 0, 
slparams.tpm_evt_log_size);
+         grub_memset (get_virtual_current_address (ch), 0, 
slparams.tpm_evt_log_size);
+       }
 
        grub_dprintf ("linux", "tpm_evt_log_base = %lx, tpm_evt_log_size = 
%x\n",
                      (unsigned long) slparams.tpm_evt_log_base,
diff --git a/grub-core/loader/i386/slaunch.c b/grub-core/loader/i386/slaunch.c
index 72d09236b2ae..3acd177afd3b 100644
--- a/grub-core/loader/i386/slaunch.c
+++ b/grub-core/loader/i386/slaunch.c
@@ -29,9 +29,12 @@
 #include <grub/i386/mmio.h>
 #include <grub/i386/slaunch.h>
 #include <grub/i386/txt.h>
+#include <grub/acpi.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
+#define GRUB_ACPI_DRTM_SIGNATURE "DRTM"
+
 static grub_uint32_t slp = SLP_NONE;
 
 static void *slaunch_module = NULL;
@@ -171,6 +174,116 @@ grub_cmd_slaunch_state (grub_command_t cmd __attribute__ 
((unused)),
   return GRUB_ERR_NONE;
 }
 
+/*
+ * See section 4.2.2 of TCG D-RTM Architecture Specification
+ * 
https://trustedcomputinggroup.org/wp-content/uploads/TCG_D-RTM_Architecture_v1-0_Published_06172013.pdf
+ */
+struct drtm_t {
+  struct grub_acpi_table_header hdr;
+  grub_uint64_t DL_Entry_Base;
+  grub_uint64_t DL_Entry_Length;
+  grub_uint32_t DL_Entry32;
+  grub_uint64_t DL_Entry64;
+  grub_uint64_t DLME_Exit;
+  grub_uint64_t Log_Area_Start;
+  grub_uint32_t Log_Area_Length;
+  grub_uint64_t Architecture_Dependent;
+  grub_uint32_t DRT_Flags;
+  grub_uint8_t  var_len_fields[];
+} __attribute__ (( packed ));
+
+static struct drtm_t *
+search_drtm_in_rsdt (struct grub_acpi_table_header *t)
+{
+  grub_uint32_t len;
+  grub_uint32_t *desc;
+
+  len = t->length - sizeof (*t);
+  desc = (grub_uint32_t *) (t + 1);
+
+  for (; len >= sizeof (*desc); desc++, len -= sizeof (*desc)) {
+
+    t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
+
+    if (t == NULL)
+      continue;
+
+    if (grub_memcmp (t->signature, GRUB_ACPI_DRTM_SIGNATURE,
+                    sizeof (t->signature)) == 0)
+      return (struct drtm_t *)t;
+  }
+
+  return NULL;
+}
+
+static struct drtm_t *
+search_drtm_in_xsdt (struct grub_acpi_table_header *t)
+{
+  grub_uint32_t len;
+  grub_uint64_t *desc;
+
+  len = t->length - sizeof (*t);
+  desc = (grub_uint64_t *) (t + 1);
+
+  for (; len >= sizeof (*desc); desc++, len -= sizeof (*desc)) {
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+    if (*desc >= (1ULL << 32))
+      {
+       grub_printf ("Unreachable table\n");
+       continue;
+      }
+#endif
+
+    t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
+
+    if (t == NULL)
+      continue;
+
+    if (grub_memcmp (t->signature, GRUB_ACPI_DRTM_SIGNATURE,
+                    sizeof (t->signature)) == 0)
+      return (struct drtm_t *)t;
+  }
+
+  return NULL;
+}
+
+static struct drtm_t *
+get_drtm_acpi_table (void)
+{
+  struct drtm_t *drtm = NULL;
+  struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1();
+
+  if (rsdp1)
+    drtm = search_drtm_in_rsdt ((void *) (grub_addr_t) rsdp1->rsdt_addr);
+
+  if (!drtm) {
+    struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
+    if (!rsdp2)
+      grub_dprintf ("slaunch", "No RSDP\n");
+    else
+      drtm = search_drtm_in_xsdt ((void *) (grub_addr_t) rsdp2->xsdt_addr);
+  }
+
+  return drtm;
+}
+
+void grub_get_drtm_evt_log (struct grub_slaunch_params *slparams)
+{
+  struct drtm_t *drtm = get_drtm_acpi_table ();
+
+  slparams->tpm_evt_log_base = 0;
+  slparams->tpm_evt_log_size = 0;
+
+  if (drtm != NULL)
+  {
+    slparams->tpm_evt_log_base = drtm->Log_Area_Start;
+    slparams->tpm_evt_log_size = drtm->Log_Area_Length;
+
+    grub_memset ((void *)(grub_addr_t)drtm->Log_Area_Start, 0, 
drtm->Log_Area_Length);
+  }
+}
+
 static grub_command_t cmd_slaunch, cmd_slaunch_module, cmd_slaunch_state;
 
 GRUB_MOD_INIT (slaunch)
diff --git a/include/grub/i386/slaunch.h b/include/grub/i386/slaunch.h
index 151236d5ff7a..e5c32152d285 100644
--- a/include/grub/i386/slaunch.h
+++ b/include/grub/i386/slaunch.h
@@ -48,6 +48,7 @@ struct grub_slaunch_params
   grub_uint32_t tpm_evt_log_size;
 };
 
+void grub_get_drtm_evt_log (struct grub_slaunch_params *slparams);
 extern grub_uint32_t grub_slaunch_platform_type (void);
 extern void *grub_slaunch_module (void);
 
-- 
2.17.1




reply via email to

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