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.he...@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 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel