1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2005 IBM Corporation
6 * Seiji Munetoh <munetoh@jp.ibm.com>
7 * Stefan Berger <stefanb@us.ibm.com>
8 * Reiner Sailer <sailer@watson.ibm.com>
9 * Kylene Hall <kjhall@us.ibm.com>
10 * Nayna Jain <nayna@linux.vnet.ibm.com>
12 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
14 * Access to the event log extended by the TCG BIOS of PC platform
17 #include <linux/device.h>
18 #include <linux/seq_file.h>
20 #include <linux/security.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/acpi.h>
24 #include <linux/tpm_eventlog.h>
30 struct acpi_table_header hdr
;
34 u32 log_max_len __packed
;
35 u64 log_start_addr __packed
;
39 u64 log_max_len __packed
;
40 u64 log_start_addr __packed
;
45 /* Check that the given log is indeed a TPM2 log. */
46 static bool tpm_is_tpm2_log(void *bios_event_log
, u64 len
)
48 struct tcg_efi_specid_event_head
*efispecid
;
49 struct tcg_pcr_event
*event_header
;
52 if (len
< sizeof(*event_header
))
54 len
-= sizeof(*event_header
);
55 event_header
= bios_event_log
;
57 if (len
< sizeof(*efispecid
))
59 efispecid
= (struct tcg_efi_specid_event_head
*)event_header
->event
;
61 n
= memcmp(efispecid
->signature
, TCG_SPECID_SIG
,
62 sizeof(TCG_SPECID_SIG
));
66 /* read binary bios log */
67 int tpm_read_log_acpi(struct tpm_chip
*chip
)
69 struct acpi_tcpa
*buff
;
73 struct tpm_bios_log
*log
;
74 struct acpi_table_tpm2
*tbl
;
75 struct acpi_tpm2_phy
*tpm2_phy
;
81 /* Unfortuntely ACPI does not associate the event log with a specific
82 * TPM, like PPI. Thus all ACPI TPMs will read the same log.
84 if (!chip
->acpi_dev_handle
)
87 if (chip
->flags
& TPM_CHIP_FLAG_TPM2
) {
88 status
= acpi_get_table("TPM2", 1,
89 (struct acpi_table_header
**)&tbl
);
90 if (ACPI_FAILURE(status
))
93 if (tbl
->header
.length
<
94 sizeof(*tbl
) + sizeof(struct acpi_tpm2_phy
)) {
95 acpi_put_table((struct acpi_table_header
*)tbl
);
99 tpm2_phy
= (void *)tbl
+ sizeof(*tbl
);
100 len
= tpm2_phy
->log_area_minimum_length
;
102 start
= tpm2_phy
->log_area_start_address
;
103 if (!start
|| !len
) {
104 acpi_put_table((struct acpi_table_header
*)tbl
);
108 acpi_put_table((struct acpi_table_header
*)tbl
);
109 format
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
;
111 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
112 status
= acpi_get_table(ACPI_SIG_TCPA
, 1,
113 (struct acpi_table_header
**)&buff
);
114 if (ACPI_FAILURE(status
))
117 switch (buff
->platform_class
) {
119 len
= buff
->server
.log_max_len
;
120 start
= buff
->server
.log_start_addr
;
124 len
= buff
->client
.log_max_len
;
125 start
= buff
->client
.log_start_addr
;
129 acpi_put_table((struct acpi_table_header
*)buff
);
130 format
= EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;
134 dev_warn(&chip
->dev
, "%s: TCPA log area empty\n", __func__
);
138 /* malloc EventLog space */
139 log
->bios_event_log
= devm_kmalloc(&chip
->dev
, len
, GFP_KERNEL
);
140 if (!log
->bios_event_log
)
143 log
->bios_event_log_end
= log
->bios_event_log
+ len
;
145 virt
= acpi_os_map_iomem(start
, len
);
147 dev_warn(&chip
->dev
, "%s: Failed to map ACPI memory\n", __func__
);
148 /* try EFI log next */
153 memcpy_fromio(log
->bios_event_log
, virt
, len
);
155 acpi_os_unmap_iomem(virt
, len
);
157 if (chip
->flags
& TPM_CHIP_FLAG_TPM2
&&
158 !tpm_is_tpm2_log(log
->bios_event_log
, len
)) {
159 /* try EFI log next */
167 devm_kfree(&chip
->dev
, log
->bios_event_log
);
168 log
->bios_event_log
= NULL
;