1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2017 Google
6 * Thiebaud Weksteen <tweek@google.com>
9 #include <linux/device.h>
10 #include <linux/efi.h>
11 #include <linux/tpm_eventlog.h>
16 /* read binary bios log from EFI configuration table */
17 int tpm_read_log_efi(struct tpm_chip
*chip
)
20 struct efi_tcg2_final_events_table
*final_tbl
= NULL
;
21 int final_events_log_size
= efi_tpm_final_log_size
;
22 struct linux_efi_tpm_eventlog
*log_tbl
;
23 struct tpm_bios_log
*log
;
29 if (!(chip
->flags
& TPM_CHIP_FLAG_TPM2
))
32 if (efi
.tpm_log
== EFI_INVALID_TABLE_ADDR
)
37 log_tbl
= memremap(efi
.tpm_log
, sizeof(*log_tbl
), MEMREMAP_WB
);
39 pr_err("Could not map UEFI TPM log table !\n");
43 log_size
= log_tbl
->size
;
47 pr_warn("UEFI TPM log area empty\n");
51 log_tbl
= memremap(efi
.tpm_log
, sizeof(*log_tbl
) + log_size
,
54 pr_err("Could not map UEFI TPM log table payload!\n");
58 /* malloc EventLog space */
59 log
->bios_event_log
= devm_kmemdup(&chip
->dev
, log_tbl
->log
, log_size
, GFP_KERNEL
);
60 if (!log
->bios_event_log
) {
65 log
->bios_event_log_end
= log
->bios_event_log
+ log_size
;
66 tpm_log_version
= log_tbl
->version
;
68 ret
= tpm_log_version
;
70 if (efi
.tpm_final_log
== EFI_INVALID_TABLE_ADDR
||
71 final_events_log_size
== 0 ||
72 tpm_log_version
!= EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
)
75 final_tbl
= memremap(efi
.tpm_final_log
,
76 sizeof(*final_tbl
) + final_events_log_size
,
79 pr_err("Could not map UEFI TPM final log\n");
80 devm_kfree(&chip
->dev
, log
->bios_event_log
);
86 * The 'final events log' size excludes the 'final events preboot log'
89 final_events_log_size
-= log_tbl
->final_events_preboot_size
;
92 * Allocate memory for the 'combined log' where we will append the
93 * 'final events log' to.
95 tmp
= devm_krealloc(&chip
->dev
, log
->bios_event_log
,
96 log_size
+ final_events_log_size
,
99 devm_kfree(&chip
->dev
, log
->bios_event_log
);
104 log
->bios_event_log
= tmp
;
107 * Append any of the 'final events log' that didn't also end up in the
108 * 'main log'. Events can be logged in both if events are generated
109 * between GetEventLog() and ExitBootServices().
111 memcpy((void *)log
->bios_event_log
+ log_size
,
112 final_tbl
->events
+ log_tbl
->final_events_preboot_size
,
113 final_events_log_size
);
115 * The size of the 'combined log' is the size of the 'main log' plus
116 * the size of the 'final events log'.
118 log
->bios_event_log_end
= log
->bios_event_log
+
119 log_size
+ final_events_log_size
;