hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/char/tpm/tpm_ppi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012-2014 Intel Corporation
34 *
....@@ -9,18 +10,14 @@
910 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
1011 *
1112 * This file contains implementation of the sysfs interface for PPI.
12
- *
13
- * This program is free software; you can redistribute it and/or
14
- * modify it under the terms of the GNU General Public License
15
- * as published by the Free Software Foundation; version 2
16
- * of the License.
1713 */
1814
1915
2016 #include <linux/acpi.h>
2117 #include "tpm.h"
2218
23
-#define TPM_PPI_REVISION_ID 1
19
+#define TPM_PPI_REVISION_ID_1 1
20
+#define TPM_PPI_REVISION_ID_2 2
2421 #define TPM_PPI_FN_VERSION 1
2522 #define TPM_PPI_FN_SUBREQ 2
2623 #define TPM_PPI_FN_GETREQ 3
....@@ -28,7 +25,7 @@
2825 #define TPM_PPI_FN_GETRSP 5
2926 #define TPM_PPI_FN_SUBREQ2 7
3027 #define TPM_PPI_FN_GETOPR 8
31
-#define PPI_TPM_REQ_MAX 22
28
+#define PPI_TPM_REQ_MAX 101 /* PPI 1.3 for TPM 2 */
3229 #define PPI_VS_REQ_START 128
3330 #define PPI_VS_REQ_END 255
3431
....@@ -36,14 +33,18 @@
3633 GUID_INIT(0x3DDDFAA6, 0x361B, 0x4EB4,
3734 0xA4, 0x24, 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53);
3835
36
+static bool tpm_ppi_req_has_parameter(u64 req)
37
+{
38
+ return req == 23;
39
+}
40
+
3941 static inline union acpi_object *
4042 tpm_eval_dsm(acpi_handle ppi_handle, int func, acpi_object_type type,
41
- union acpi_object *argv4)
43
+ union acpi_object *argv4, u64 rev)
4244 {
4345 BUG_ON(!ppi_handle);
4446 return acpi_evaluate_dsm_typed(ppi_handle, &tpm_ppi_guid,
45
- TPM_PPI_REVISION_ID,
46
- func, argv4, type);
47
+ rev, func, argv4, type);
4748 }
4849
4950 static ssize_t tpm_show_ppi_version(struct device *dev,
....@@ -60,9 +61,14 @@
6061 ssize_t size = -EINVAL;
6162 union acpi_object *obj;
6263 struct tpm_chip *chip = to_tpm_chip(dev);
64
+ u64 rev = TPM_PPI_REVISION_ID_2;
65
+ u64 req;
66
+
67
+ if (strcmp(chip->ppi_version, "1.2") < 0)
68
+ rev = TPM_PPI_REVISION_ID_1;
6369
6470 obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETREQ,
65
- ACPI_TYPE_PACKAGE, NULL);
71
+ ACPI_TYPE_PACKAGE, NULL, rev);
6672 if (!obj)
6773 return -ENXIO;
6874
....@@ -72,7 +78,23 @@
7278 * error. The second is pending TPM operation requested by the OS, 0
7379 * means none and >0 means operation value.
7480 */
75
- if (obj->package.count == 2 &&
81
+ if (obj->package.count == 3 &&
82
+ obj->package.elements[0].type == ACPI_TYPE_INTEGER &&
83
+ obj->package.elements[1].type == ACPI_TYPE_INTEGER &&
84
+ obj->package.elements[2].type == ACPI_TYPE_INTEGER) {
85
+ if (obj->package.elements[0].integer.value)
86
+ size = -EFAULT;
87
+ else {
88
+ req = obj->package.elements[1].integer.value;
89
+ if (tpm_ppi_req_has_parameter(req))
90
+ size = scnprintf(buf, PAGE_SIZE,
91
+ "%llu %llu\n", req,
92
+ obj->package.elements[2].integer.value);
93
+ else
94
+ size = scnprintf(buf, PAGE_SIZE,
95
+ "%llu\n", req);
96
+ }
97
+ } else if (obj->package.count == 2 &&
7698 obj->package.elements[0].type == ACPI_TYPE_INTEGER &&
7799 obj->package.elements[1].type == ACPI_TYPE_INTEGER) {
78100 if (obj->package.elements[0].integer.value)
....@@ -94,9 +116,10 @@
94116 u32 req;
95117 u64 ret;
96118 int func = TPM_PPI_FN_SUBREQ;
97
- union acpi_object *obj, tmp;
98
- union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
119
+ union acpi_object *obj, tmp[2];
120
+ union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(2, tmp);
99121 struct tpm_chip *chip = to_tpm_chip(dev);
122
+ u64 rev = TPM_PPI_REVISION_ID_1;
100123
101124 /*
102125 * the function to submit TPM operation request to pre-os environment
....@@ -104,7 +127,7 @@
104127 * version 1.1
105128 */
106129 if (acpi_check_dsm(chip->acpi_dev_handle, &tpm_ppi_guid,
107
- TPM_PPI_REVISION_ID, 1 << TPM_PPI_FN_SUBREQ2))
130
+ TPM_PPI_REVISION_ID_1, 1 << TPM_PPI_FN_SUBREQ2))
108131 func = TPM_PPI_FN_SUBREQ2;
109132
110133 /*
....@@ -113,20 +136,29 @@
113136 * string/package type. For PPI version 1.0 and 1.1, use buffer type
114137 * for compatibility, and use package type since 1.2 according to spec.
115138 */
116
- if (strcmp(chip->ppi_version, "1.2") < 0) {
139
+ if (strcmp(chip->ppi_version, "1.3") == 0) {
140
+ if (sscanf(buf, "%llu %llu", &tmp[0].integer.value,
141
+ &tmp[1].integer.value) != 2)
142
+ goto ppi12;
143
+ rev = TPM_PPI_REVISION_ID_2;
144
+ tmp[0].type = ACPI_TYPE_INTEGER;
145
+ tmp[1].type = ACPI_TYPE_INTEGER;
146
+ } else if (strcmp(chip->ppi_version, "1.2") < 0) {
117147 if (sscanf(buf, "%d", &req) != 1)
118148 return -EINVAL;
119149 argv4.type = ACPI_TYPE_BUFFER;
120150 argv4.buffer.length = sizeof(req);
121151 argv4.buffer.pointer = (u8 *)&req;
122152 } else {
123
- tmp.type = ACPI_TYPE_INTEGER;
124
- if (sscanf(buf, "%llu", &tmp.integer.value) != 1)
153
+ppi12:
154
+ argv4.package.count = 1;
155
+ tmp[0].type = ACPI_TYPE_INTEGER;
156
+ if (sscanf(buf, "%llu", &tmp[0].integer.value) != 1)
125157 return -EINVAL;
126158 }
127159
128160 obj = tpm_eval_dsm(chip->acpi_dev_handle, func, ACPI_TYPE_INTEGER,
129
- &argv4);
161
+ &argv4, rev);
130162 if (!obj) {
131163 return -ENXIO;
132164 } else {
....@@ -170,7 +202,7 @@
170202 if (strcmp(chip->ppi_version, "1.2") < 0)
171203 obj = &tmp;
172204 obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETACT,
173
- ACPI_TYPE_INTEGER, obj);
205
+ ACPI_TYPE_INTEGER, obj, TPM_PPI_REVISION_ID_1);
174206 if (!obj) {
175207 return -ENXIO;
176208 } else {
....@@ -196,7 +228,7 @@
196228 struct tpm_chip *chip = to_tpm_chip(dev);
197229
198230 obj = tpm_eval_dsm(chip->acpi_dev_handle, TPM_PPI_FN_GETRSP,
199
- ACPI_TYPE_PACKAGE, NULL);
231
+ ACPI_TYPE_PACKAGE, NULL, TPM_PPI_REVISION_ID_1);
200232 if (!obj)
201233 return -ENXIO;
202234
....@@ -264,7 +296,7 @@
264296 "User not required",
265297 };
266298
267
- if (!acpi_check_dsm(dev_handle, &tpm_ppi_guid, TPM_PPI_REVISION_ID,
299
+ if (!acpi_check_dsm(dev_handle, &tpm_ppi_guid, TPM_PPI_REVISION_ID_1,
268300 1 << TPM_PPI_FN_GETOPR))
269301 return -EPERM;
270302
....@@ -272,7 +304,8 @@
272304 for (i = start; i <= end; i++) {
273305 tmp.integer.value = i;
274306 obj = tpm_eval_dsm(dev_handle, TPM_PPI_FN_GETOPR,
275
- ACPI_TYPE_INTEGER, &argv);
307
+ ACPI_TYPE_INTEGER, &argv,
308
+ TPM_PPI_REVISION_ID_1);
276309 if (!obj) {
277310 return -ENOMEM;
278311 } else {
....@@ -338,12 +371,13 @@
338371 return;
339372
340373 if (!acpi_check_dsm(chip->acpi_dev_handle, &tpm_ppi_guid,
341
- TPM_PPI_REVISION_ID, 1 << TPM_PPI_FN_VERSION))
374
+ TPM_PPI_REVISION_ID_1, 1 << TPM_PPI_FN_VERSION))
342375 return;
343376
344377 /* Cache PPI version string. */
345378 obj = acpi_evaluate_dsm_typed(chip->acpi_dev_handle, &tpm_ppi_guid,
346
- TPM_PPI_REVISION_ID, TPM_PPI_FN_VERSION,
379
+ TPM_PPI_REVISION_ID_1,
380
+ TPM_PPI_FN_VERSION,
347381 NULL, ACPI_TYPE_STRING);
348382 if (obj) {
349383 strlcpy(chip->ppi_version, obj->string.pointer,