@@ -21,10 +21,12 @@
int tpm_read_log_efi(struct tpm_chip *chip)
{
+ struct efi_tcg2_final_events_table *final_tbl = NULL;
struct linux_efi_tpm_eventlog *log_tbl;
struct tpm_bios_log *log;
u32 log_size;
u8 tpm_log_version;
+ void *tmp;
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
return -ENODEV;
@@ -55,12 +57,41 @@ int tpm_read_log_efi(struct tpm_chip *chip)
if (!log->bios_event_log)
goto err_memunmap;
log->bios_event_log_end = log->bios_event_log + log_size;
-
tpm_log_version = log_tbl->version;
+
+ if (efi.tpm_final_log != EFI_INVALID_TABLE_ADDR &&
+ efi_tpm_final_log_size != 0) {
+ if (tpm_log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
+ final_tbl = memremap(efi.tpm_final_log,
+ sizeof(*final_tbl) + efi_tpm_final_log_size,
+ MEMREMAP_WB);
+ if (!final_tbl) {
+ pr_err("Could not map UEFI TPM final log\n");
+ kfree(log->bios_event_log);
+ goto err_memunmap;
+ }
+
+ tmp = krealloc(log->bios_event_log,
+ log_size + efi_tpm_final_log_size,
+ GFP_KERNEL);
+ if (!tmp) {
+ kfree(log->bios_event_log);
+ goto err_memunmap;
+ }
+
+ log->bios_event_log = tmp;
+ memcpy((void *)log->bios_event_log + log_size,
+ final_tbl->events, efi_tpm_final_log_size);
+ log->bios_event_log_end = log->bios_event_log +
+ log_size + efi_tpm_final_log_size;
+ }
+ }
+ memunmap(final_tbl);
memunmap(log_tbl);
return tpm_log_version;
err_memunmap:
+ memunmap(final_tbl);
memunmap(log_tbl);
return -ENOMEM;
}