forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
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,23 +83,44 @@
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
+ return -ENODEV;
7595
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;
96
+ tpm2_phy = (void *)tbl + sizeof(*tbl);
97
+ len = tpm2_phy->log_area_minimum_length;
98
+
99
+ start = tpm2_phy->log_area_start_address;
100
+ if (!start || !len)
101
+ return -ENODEV;
102
+
103
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
104
+ } else {
105
+ /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
106
+ status = acpi_get_table(ACPI_SIG_TCPA, 1,
107
+ (struct acpi_table_header **)&buff);
108
+ if (ACPI_FAILURE(status))
109
+ return -ENODEV;
110
+
111
+ switch (buff->platform_class) {
112
+ case BIOS_SERVER:
113
+ len = buff->server.log_max_len;
114
+ start = buff->server.log_start_addr;
115
+ break;
116
+ case BIOS_CLIENT:
117
+ default:
118
+ len = buff->client.log_max_len;
119
+ start = buff->client.log_start_addr;
120
+ break;
121
+ }
122
+
123
+ format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
86124 }
87125 if (!len) {
88126 dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
....@@ -96,6 +134,7 @@
96134
97135 log->bios_event_log_end = log->bios_event_log + len;
98136
137
+ ret = -EIO;
99138 virt = acpi_os_map_iomem(start, len);
100139 if (!virt)
101140 goto err;
....@@ -103,11 +142,19 @@
103142 memcpy_fromio(log->bios_event_log, virt, len);
104143
105144 acpi_os_unmap_iomem(virt, len);
106
- return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
145
+
146
+ if (chip->flags & TPM_CHIP_FLAG_TPM2 &&
147
+ !tpm_is_tpm2_log(log->bios_event_log, len)) {
148
+ /* try EFI log next */
149
+ ret = -ENODEV;
150
+ goto err;
151
+ }
152
+
153
+ return format;
107154
108155 err:
109156 kfree(log->bios_event_log);
110157 log->bios_event_log = NULL;
111
- return -EIO;
158
+ return ret;
112159
113160 }