hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/char/tpm/eventlog/acpi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2005 IBM Corporation
34 *
....@@ -11,12 +12,6 @@
1112 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
1213 *
1314 * Access to the event log extended by the TCG BIOS of PC platform
14
- *
15
- * This program is free software; you can redistribute it and/or
16
- * modify it under the terms of the GNU General Public License
17
- * as published by the Free Software Foundation; either version
18
- * 2 of the License, or (at your option) any later version.
19
- *
2015 */
2116
2217 #include <linux/seq_file.h>
....@@ -46,6 +41,27 @@
4641 };
4742 };
4843
44
+/* Check that the given log is indeed a TPM2 log. */
45
+static bool tpm_is_tpm2_log(void *bios_event_log, u64 len)
46
+{
47
+ struct tcg_efi_specid_event_head *efispecid;
48
+ struct tcg_pcr_event *event_header;
49
+ int n;
50
+
51
+ if (len < sizeof(*event_header))
52
+ return false;
53
+ len -= sizeof(*event_header);
54
+ event_header = bios_event_log;
55
+
56
+ if (len < sizeof(*efispecid))
57
+ return false;
58
+ efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
59
+
60
+ n = memcmp(efispecid->signature, TCG_SPECID_SIG,
61
+ sizeof(TCG_SPECID_SIG));
62
+ return n == 0;
63
+}
64
+
4965 /* read binary bios log */
5066 int tpm_read_log_acpi(struct tpm_chip *chip)
5167 {
....@@ -54,9 +70,10 @@
5470 void __iomem *virt;
5571 u64 len, start;
5672 struct tpm_bios_log *log;
57
-
58
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
59
- return -ENODEV;
73
+ struct acpi_table_tpm2 *tbl;
74
+ struct acpi_tpm2_phy *tpm2_phy;
75
+ int format;
76
+ int ret;
6077
6178 log = &chip->log;
6279
....@@ -66,24 +83,52 @@
6683 if (!chip->acpi_dev_handle)
6784 return -ENODEV;
6885
69
- /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
70
- status = acpi_get_table(ACPI_SIG_TCPA, 1,
71
- (struct acpi_table_header **)&buff);
86
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
87
+ status = acpi_get_table("TPM2", 1,
88
+ (struct acpi_table_header **)&tbl);
89
+ if (ACPI_FAILURE(status))
90
+ return -ENODEV;
7291
73
- if (ACPI_FAILURE(status))
74
- return -ENODEV;
92
+ if (tbl->header.length <
93
+ sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) {
94
+ acpi_put_table((struct acpi_table_header *)tbl);
95
+ return -ENODEV;
96
+ }
7597
76
- switch(buff->platform_class) {
77
- case BIOS_SERVER:
78
- len = buff->server.log_max_len;
79
- start = buff->server.log_start_addr;
80
- break;
81
- case BIOS_CLIENT:
82
- default:
83
- len = buff->client.log_max_len;
84
- start = buff->client.log_start_addr;
85
- break;
98
+ tpm2_phy = (void *)tbl + sizeof(*tbl);
99
+ len = tpm2_phy->log_area_minimum_length;
100
+
101
+ start = tpm2_phy->log_area_start_address;
102
+ if (!start || !len) {
103
+ acpi_put_table((struct acpi_table_header *)tbl);
104
+ return -ENODEV;
105
+ }
106
+
107
+ acpi_put_table((struct acpi_table_header *)tbl);
108
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
109
+ } else {
110
+ /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
111
+ status = acpi_get_table(ACPI_SIG_TCPA, 1,
112
+ (struct acpi_table_header **)&buff);
113
+ if (ACPI_FAILURE(status))
114
+ return -ENODEV;
115
+
116
+ switch (buff->platform_class) {
117
+ case BIOS_SERVER:
118
+ len = buff->server.log_max_len;
119
+ start = buff->server.log_start_addr;
120
+ break;
121
+ case BIOS_CLIENT:
122
+ default:
123
+ len = buff->client.log_max_len;
124
+ start = buff->client.log_start_addr;
125
+ break;
126
+ }
127
+
128
+ acpi_put_table((struct acpi_table_header *)buff);
129
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
86130 }
131
+
87132 if (!len) {
88133 dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
89134 return -EIO;
....@@ -96,18 +141,30 @@
96141
97142 log->bios_event_log_end = log->bios_event_log + len;
98143
144
+ ret = -EIO;
99145 virt = acpi_os_map_iomem(start, len);
100
- if (!virt)
146
+ if (!virt) {
147
+ dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__);
148
+ /* try EFI log next */
149
+ ret = -ENODEV;
101150 goto err;
151
+ }
102152
103153 memcpy_fromio(log->bios_event_log, virt, len);
104154
105155 acpi_os_unmap_iomem(virt, len);
106
- return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
156
+
157
+ if (chip->flags & TPM_CHIP_FLAG_TPM2 &&
158
+ !tpm_is_tpm2_log(log->bios_event_log, len)) {
159
+ /* try EFI log next */
160
+ ret = -ENODEV;
161
+ goto err;
162
+ }
163
+
164
+ return format;
107165
108166 err:
109167 kfree(log->bios_event_log);
110168 log->bios_event_log = NULL;
111
- return -EIO;
112
-
169
+ return ret;
113170 }