aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <james.morris@microsoft.com>2018-05-18 13:40:37 -0400
committerJames Morris <james.morris@microsoft.com>2018-05-18 13:40:37 -0400
commit82e5b03236e0eada87a59f4636c986dc319c6e78 (patch)
treebec5f1a1d99a56bbea7dfbf6f02156816353cde7
parent890e2abe1028c39e5399101a2c277219cd637aaa (diff)
parent424eaf910c329ab06ad03a527ef45dcf6a328f00 (diff)
Merge tag 'tpmdd-next-20180518' of git://git.infradead.org/users/jjs/linux-tpmdd into next-tpm
tpmdd updates for Linux 4.18 This purely a bug fix release. The only major change is to move the event log code to its own subdirectory because there starts to be so much of it.
-rw-r--r--drivers/char/tpm/Makefile10
-rw-r--r--drivers/char/tpm/eventlog/acpi.c (renamed from drivers/char/tpm/tpm_eventlog_acpi.c)3
-rw-r--r--drivers/char/tpm/eventlog/common.c195
-rw-r--r--drivers/char/tpm/eventlog/common.h35
-rw-r--r--drivers/char/tpm/eventlog/efi.c (renamed from drivers/char/tpm/tpm_eventlog_efi.c)6
-rw-r--r--drivers/char/tpm/eventlog/of.c (renamed from drivers/char/tpm/tpm_eventlog_of.c)11
-rw-r--r--drivers/char/tpm/eventlog/tpm1.c (renamed from drivers/char/tpm/tpm1_eventlog.c)200
-rw-r--r--drivers/char/tpm/eventlog/tpm2.c (renamed from drivers/char/tpm/tpm2_eventlog.c)3
-rw-r--r--drivers/char/tpm/st33zp24/spi.c4
-rw-r--r--drivers/char/tpm/st33zp24/st33zp24.c2
-rw-r--r--drivers/char/tpm/tpm-interface.c5
-rw-r--r--drivers/char/tpm/tpm.h32
-rw-r--r--drivers/char/tpm/tpm2-space.c3
-rw-r--r--drivers/char/tpm/tpm_crb.c10
-rw-r--r--drivers/char/tpm/tpm_tis_core.c58
15 files changed, 331 insertions, 246 deletions
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index acd758381c58..4e9c33ca1f8f 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -4,11 +4,11 @@
4# 4#
5obj-$(CONFIG_TCG_TPM) += tpm.o 5obj-$(CONFIG_TCG_TPM) += tpm.o
6tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ 6tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
7 tpm-dev-common.o tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \ 7 tpm-dev-common.o tpmrm-dev.o eventlog/common.o eventlog/tpm1.o \
8 tpm2-space.o 8 eventlog/tpm2.o tpm2-space.o
9tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.o 9tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
10tpm-$(CONFIG_EFI) += tpm_eventlog_efi.o 10tpm-$(CONFIG_EFI) += eventlog/efi.o
11tpm-$(CONFIG_OF) += tpm_eventlog_of.o 11tpm-$(CONFIG_OF) += eventlog/of.o
12obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o 12obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
13obj-$(CONFIG_TCG_TIS) += tpm_tis.o 13obj-$(CONFIG_TCG_TIS) += tpm_tis.o
14obj-$(CONFIG_TCG_TIS_SPI) += tpm_tis_spi.o 14obj-$(CONFIG_TCG_TIS_SPI) += tpm_tis_spi.o
diff --git a/drivers/char/tpm/tpm_eventlog_acpi.c b/drivers/char/tpm/eventlog/acpi.c
index 66f19e93c216..7c53b1973b62 100644
--- a/drivers/char/tpm/tpm_eventlog_acpi.c
+++ b/drivers/char/tpm/eventlog/acpi.c
@@ -27,7 +27,8 @@
27#include <linux/acpi.h> 27#include <linux/acpi.h>
28#include <linux/tpm_eventlog.h> 28#include <linux/tpm_eventlog.h>
29 29
30#include "tpm.h" 30#include "../tpm.h"
31#include "common.h"
31 32
32struct acpi_tcpa { 33struct acpi_tcpa {
33 struct acpi_table_header hdr; 34 struct acpi_table_header hdr;
diff --git a/drivers/char/tpm/eventlog/common.c b/drivers/char/tpm/eventlog/common.c
new file mode 100644
index 000000000000..5a8720df2b51
--- /dev/null
+++ b/drivers/char/tpm/eventlog/common.c
@@ -0,0 +1,195 @@
1/*
2 * Copyright (C) 2005, 2012 IBM Corporation
3 *
4 * Authors:
5 * Kent Yoder <key@linux.vnet.ibm.com>
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>
11 *
12 * Access to the event log created by a system's firmware / BIOS
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 *
19 */
20
21#include <linux/seq_file.h>
22#include <linux/fs.h>
23#include <linux/security.h>
24#include <linux/module.h>
25#include <linux/tpm_eventlog.h>
26
27#include "../tpm.h"
28#include "common.h"
29
30static int tpm_bios_measurements_open(struct inode *inode,
31 struct file *file)
32{
33 int err;
34 struct seq_file *seq;
35 struct tpm_chip_seqops *chip_seqops;
36 const struct seq_operations *seqops;
37 struct tpm_chip *chip;
38
39 inode_lock(inode);
40 if (!inode->i_private) {
41 inode_unlock(inode);
42 return -ENODEV;
43 }
44 chip_seqops = (struct tpm_chip_seqops *)inode->i_private;
45 seqops = chip_seqops->seqops;
46 chip = chip_seqops->chip;
47 get_device(&chip->dev);
48 inode_unlock(inode);
49
50 /* now register seq file */
51 err = seq_open(file, seqops);
52 if (!err) {
53 seq = file->private_data;
54 seq->private = chip;
55 }
56
57 return err;
58}
59
60static int tpm_bios_measurements_release(struct inode *inode,
61 struct file *file)
62{
63 struct seq_file *seq = (struct seq_file *)file->private_data;
64 struct tpm_chip *chip = (struct tpm_chip *)seq->private;
65
66 put_device(&chip->dev);
67
68 return seq_release(inode, file);
69}
70
71static const struct file_operations tpm_bios_measurements_ops = {
72 .owner = THIS_MODULE,
73 .open = tpm_bios_measurements_open,
74 .read = seq_read,
75 .llseek = seq_lseek,
76 .release = tpm_bios_measurements_release,
77};
78
79static int tpm_read_log(struct tpm_chip *chip)
80{
81 int rc;
82
83 if (chip->log.bios_event_log != NULL) {
84 dev_dbg(&chip->dev,
85 "%s: ERROR - event log already initialized\n",
86 __func__);
87 return -EFAULT;
88 }
89
90 rc = tpm_read_log_acpi(chip);
91 if (rc != -ENODEV)
92 return rc;
93
94 rc = tpm_read_log_efi(chip);
95 if (rc != -ENODEV)
96 return rc;
97
98 return tpm_read_log_of(chip);
99}
100
101/*
102 * tpm_bios_log_setup() - Read the event log from the firmware
103 * @chip: TPM chip to use.
104 *
105 * If an event log is found then the securityfs files are setup to
106 * export it to userspace, otherwise nothing is done.
107 *
108 * Returns -ENODEV if the firmware has no event log or securityfs is not
109 * supported.
110 */
111int tpm_bios_log_setup(struct tpm_chip *chip)
112{
113 const char *name = dev_name(&chip->dev);
114 unsigned int cnt;
115 int log_version;
116 int rc = 0;
117
118 rc = tpm_read_log(chip);
119 if (rc < 0)
120 return rc;
121 log_version = rc;
122
123 cnt = 0;
124 chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
125 /* NOTE: securityfs_create_dir can return ENODEV if securityfs is
126 * compiled out. The caller should ignore the ENODEV return code.
127 */
128 if (IS_ERR(chip->bios_dir[cnt]))
129 goto err;
130 cnt++;
131
132 chip->bin_log_seqops.chip = chip;
133 if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
134 chip->bin_log_seqops.seqops =
135 &tpm2_binary_b_measurements_seqops;
136 else
137 chip->bin_log_seqops.seqops =
138 &tpm1_binary_b_measurements_seqops;
139
140
141 chip->bios_dir[cnt] =
142 securityfs_create_file("binary_bios_measurements",
143 0440, chip->bios_dir[0],
144 (void *)&chip->bin_log_seqops,
145 &tpm_bios_measurements_ops);
146 if (IS_ERR(chip->bios_dir[cnt]))
147 goto err;
148 cnt++;
149
150 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
151
152 chip->ascii_log_seqops.chip = chip;
153 chip->ascii_log_seqops.seqops =
154 &tpm1_ascii_b_measurements_seqops;
155
156 chip->bios_dir[cnt] =
157 securityfs_create_file("ascii_bios_measurements",
158 0440, chip->bios_dir[0],
159 (void *)&chip->ascii_log_seqops,
160 &tpm_bios_measurements_ops);
161 if (IS_ERR(chip->bios_dir[cnt]))
162 goto err;
163 cnt++;
164 }
165
166 return 0;
167
168err:
169 rc = PTR_ERR(chip->bios_dir[cnt]);
170 chip->bios_dir[cnt] = NULL;
171 tpm_bios_log_teardown(chip);
172 return rc;
173}
174
175void tpm_bios_log_teardown(struct tpm_chip *chip)
176{
177 int i;
178 struct inode *inode;
179
180 /* securityfs_remove currently doesn't take care of handling sync
181 * between removal and opening of pseudo files. To handle this, a
182 * workaround is added by making i_private = NULL here during removal
183 * and to check it during open(), both within inode_lock()/unlock().
184 * This design ensures that open() either safely gets kref or fails.
185 */
186 for (i = (TPM_NUM_EVENT_LOG_FILES - 1); i >= 0; i--) {
187 if (chip->bios_dir[i]) {
188 inode = d_inode(chip->bios_dir[i]);
189 inode_lock(inode);
190 inode->i_private = NULL;
191 inode_unlock(inode);
192 securityfs_remove(chip->bios_dir[i]);
193 }
194 }
195}
diff --git a/drivers/char/tpm/eventlog/common.h b/drivers/char/tpm/eventlog/common.h
new file mode 100644
index 000000000000..47ff8136ceb5
--- /dev/null
+++ b/drivers/char/tpm/eventlog/common.h
@@ -0,0 +1,35 @@
1#ifndef __TPM_EVENTLOG_COMMON_H__
2#define __TPM_EVENTLOG_COMMON_H__
3
4#include "../tpm.h"
5
6extern const struct seq_operations tpm1_ascii_b_measurements_seqops;
7extern const struct seq_operations tpm1_binary_b_measurements_seqops;
8extern const struct seq_operations tpm2_binary_b_measurements_seqops;
9
10#if defined(CONFIG_ACPI)
11int tpm_read_log_acpi(struct tpm_chip *chip);
12#else
13static inline int tpm_read_log_acpi(struct tpm_chip *chip)
14{
15 return -ENODEV;
16}
17#endif
18#if defined(CONFIG_OF)
19int tpm_read_log_of(struct tpm_chip *chip);
20#else
21static inline int tpm_read_log_of(struct tpm_chip *chip)
22{
23 return -ENODEV;
24}
25#endif
26#if defined(CONFIG_EFI)
27int tpm_read_log_efi(struct tpm_chip *chip);
28#else
29static inline int tpm_read_log_efi(struct tpm_chip *chip)
30{
31 return -ENODEV;
32}
33#endif
34
35#endif
diff --git a/drivers/char/tpm/tpm_eventlog_efi.c b/drivers/char/tpm/eventlog/efi.c
index e3f9ffd341d2..3e673ab22cb4 100644
--- a/drivers/char/tpm/tpm_eventlog_efi.c
+++ b/drivers/char/tpm/eventlog/efi.c
@@ -14,7 +14,8 @@
14#include <linux/efi.h> 14#include <linux/efi.h>
15#include <linux/tpm_eventlog.h> 15#include <linux/tpm_eventlog.h>
16 16
17#include "tpm.h" 17#include "../tpm.h"
18#include "common.h"
18 19
19/* read binary bios log from EFI configuration table */ 20/* read binary bios log from EFI configuration table */
20int tpm_read_log_efi(struct tpm_chip *chip) 21int tpm_read_log_efi(struct tpm_chip *chip)
@@ -50,10 +51,9 @@ int tpm_read_log_efi(struct tpm_chip *chip)
50 } 51 }
51 52
52 /* malloc EventLog space */ 53 /* malloc EventLog space */
53 log->bios_event_log = kmalloc(log_size, GFP_KERNEL); 54 log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
54 if (!log->bios_event_log) 55 if (!log->bios_event_log)
55 goto err_memunmap; 56 goto err_memunmap;
56 memcpy(log->bios_event_log, log_tbl->log, log_size);
57 log->bios_event_log_end = log->bios_event_log + log_size; 57 log->bios_event_log_end = log->bios_event_log + log_size;
58 58
59 tpm_log_version = log_tbl->version; 59 tpm_log_version = log_tbl->version;
diff --git a/drivers/char/tpm/tpm_eventlog_of.c b/drivers/char/tpm/eventlog/of.c
index 96fd5646f866..bba5fba6cb3b 100644
--- a/drivers/char/tpm/tpm_eventlog_of.c
+++ b/drivers/char/tpm/eventlog/of.c
@@ -19,7 +19,8 @@
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/tpm_eventlog.h> 20#include <linux/tpm_eventlog.h>
21 21
22#include "tpm.h" 22#include "../tpm.h"
23#include "common.h"
23 24
24int tpm_read_log_of(struct tpm_chip *chip) 25int tpm_read_log_of(struct tpm_chip *chip)
25{ 26{
@@ -56,8 +57,8 @@ int tpm_read_log_of(struct tpm_chip *chip)
56 * but physical tpm needs the conversion. 57 * but physical tpm needs the conversion.
57 */ 58 */
58 if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0) { 59 if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0) {
59 size = be32_to_cpup(sizep); 60 size = be32_to_cpup((__force __be32 *)sizep);
60 base = be64_to_cpup(basep); 61 base = be64_to_cpup((__force __be64 *)basep);
61 } else { 62 } else {
62 size = *sizep; 63 size = *sizep;
63 base = *basep; 64 base = *basep;
@@ -68,14 +69,12 @@ int tpm_read_log_of(struct tpm_chip *chip)
68 return -EIO; 69 return -EIO;
69 } 70 }
70 71
71 log->bios_event_log = kmalloc(size, GFP_KERNEL); 72 log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
72 if (!log->bios_event_log) 73 if (!log->bios_event_log)
73 return -ENOMEM; 74 return -ENOMEM;
74 75
75 log->bios_event_log_end = log->bios_event_log + size; 76 log->bios_event_log_end = log->bios_event_log + size;
76 77
77 memcpy(log->bios_event_log, __va(base), size);
78
79 if (chip->flags & TPM_CHIP_FLAG_TPM2) 78 if (chip->flags & TPM_CHIP_FLAG_TPM2)
80 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; 79 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
81 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; 80 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
diff --git a/drivers/char/tpm/tpm1_eventlog.c b/drivers/char/tpm/eventlog/tpm1.c
index add798bd69d0..58c84784ba25 100644
--- a/drivers/char/tpm/tpm1_eventlog.c
+++ b/drivers/char/tpm/eventlog/tpm1.c
@@ -28,7 +28,8 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/tpm_eventlog.h> 29#include <linux/tpm_eventlog.h>
30 30
31#include "tpm.h" 31#include "../tpm.h"
32#include "common.h"
32 33
33 34
34static const char* tcpa_event_type_strings[] = { 35static const char* tcpa_event_type_strings[] = {
@@ -71,7 +72,7 @@ static const char* tcpa_pc_event_id_strings[] = {
71}; 72};
72 73
73/* returns pointer to start of pos. entry of tcg log */ 74/* returns pointer to start of pos. entry of tcg log */
74static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) 75static void *tpm1_bios_measurements_start(struct seq_file *m, loff_t *pos)
75{ 76{
76 loff_t i; 77 loff_t i;
77 struct tpm_chip *chip = m->private; 78 struct tpm_chip *chip = m->private;
@@ -118,7 +119,7 @@ static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
118 return addr; 119 return addr;
119} 120}
120 121
121static void *tpm_bios_measurements_next(struct seq_file *m, void *v, 122static void *tpm1_bios_measurements_next(struct seq_file *m, void *v,
122 loff_t *pos) 123 loff_t *pos)
123{ 124{
124 struct tcpa_event *event = v; 125 struct tcpa_event *event = v;
@@ -149,7 +150,7 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
149 return v; 150 return v;
150} 151}
151 152
152static void tpm_bios_measurements_stop(struct seq_file *m, void *v) 153static void tpm1_bios_measurements_stop(struct seq_file *m, void *v)
153{ 154{
154} 155}
155 156
@@ -232,7 +233,7 @@ static int get_event_name(char *dest, struct tcpa_event *event,
232 233
233} 234}
234 235
235static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) 236static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v)
236{ 237{
237 struct tcpa_event *event = v; 238 struct tcpa_event *event = v;
238 struct tcpa_event temp_event; 239 struct tcpa_event temp_event;
@@ -261,18 +262,7 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
261 262
262} 263}
263 264
264static int tpm_bios_measurements_release(struct inode *inode, 265static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)
265 struct file *file)
266{
267 struct seq_file *seq = (struct seq_file *)file->private_data;
268 struct tpm_chip *chip = (struct tpm_chip *)seq->private;
269
270 put_device(&chip->dev);
271
272 return seq_release(inode, file);
273}
274
275static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
276{ 266{
277 int len = 0; 267 int len = 0;
278 char *eventname; 268 char *eventname;
@@ -305,172 +295,16 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
305 return 0; 295 return 0;
306} 296}
307 297
308static const struct seq_operations tpm_ascii_b_measurements_seqops = { 298const struct seq_operations tpm1_ascii_b_measurements_seqops = {
309 .start = tpm_bios_measurements_start, 299 .start = tpm1_bios_measurements_start,
310 .next = tpm_bios_measurements_next, 300 .next = tpm1_bios_measurements_next,
311 .stop = tpm_bios_measurements_stop, 301 .stop = tpm1_bios_measurements_stop,
312 .show = tpm_ascii_bios_measurements_show, 302 .show = tpm1_ascii_bios_measurements_show,
313}; 303};
314 304
315static const struct seq_operations tpm_binary_b_measurements_seqops = { 305const struct seq_operations tpm1_binary_b_measurements_seqops = {
316 .start = tpm_bios_measurements_start, 306 .start = tpm1_bios_measurements_start,
317 .next = tpm_bios_measurements_next, 307 .next = tpm1_bios_measurements_next,
318 .stop = tpm_bios_measurements_stop, 308 .stop = tpm1_bios_measurements_stop,
319 .show = tpm_binary_bios_measurements_show, 309 .show = tpm1_binary_bios_measurements_show,
320};
321
322static int tpm_bios_measurements_open(struct inode *inode,
323 struct file *file)
324{
325 int err;
326 struct seq_file *seq;
327 struct tpm_chip_seqops *chip_seqops;
328 const struct seq_operations *seqops;
329 struct tpm_chip *chip;
330
331 inode_lock(inode);
332 if (!inode->i_private) {
333 inode_unlock(inode);
334 return -ENODEV;
335 }
336 chip_seqops = (struct tpm_chip_seqops *)inode->i_private;
337 seqops = chip_seqops->seqops;
338 chip = chip_seqops->chip;
339 get_device(&chip->dev);
340 inode_unlock(inode);
341
342 /* now register seq file */
343 err = seq_open(file, seqops);
344 if (!err) {
345 seq = file->private_data;
346 seq->private = chip;
347 }
348
349 return err;
350}
351
352static const struct file_operations tpm_bios_measurements_ops = {
353 .owner = THIS_MODULE,
354 .open = tpm_bios_measurements_open,
355 .read = seq_read,
356 .llseek = seq_lseek,
357 .release = tpm_bios_measurements_release,
358}; 310};
359
360static int tpm_read_log(struct tpm_chip *chip)
361{
362 int rc;
363
364 if (chip->log.bios_event_log != NULL) {
365 dev_dbg(&chip->dev,
366 "%s: ERROR - event log already initialized\n",
367 __func__);
368 return -EFAULT;
369 }
370
371 rc = tpm_read_log_acpi(chip);
372 if (rc != -ENODEV)
373 return rc;
374
375 rc = tpm_read_log_efi(chip);
376 if (rc != -ENODEV)
377 return rc;
378
379 return tpm_read_log_of(chip);
380}
381
382/*
383 * tpm_bios_log_setup() - Read the event log from the firmware
384 * @chip: TPM chip to use.
385 *
386 * If an event log is found then the securityfs files are setup to
387 * export it to userspace, otherwise nothing is done.
388 *
389 * Returns -ENODEV if the firmware has no event log or securityfs is not
390 * supported.
391 */
392int tpm_bios_log_setup(struct tpm_chip *chip)
393{
394 const char *name = dev_name(&chip->dev);
395 unsigned int cnt;
396 int log_version;
397 int rc = 0;
398
399 rc = tpm_read_log(chip);
400 if (rc < 0)
401 return rc;
402 log_version = rc;
403
404 cnt = 0;
405 chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
406 /* NOTE: securityfs_create_dir can return ENODEV if securityfs is
407 * compiled out. The caller should ignore the ENODEV return code.
408 */
409 if (IS_ERR(chip->bios_dir[cnt]))
410 goto err;
411 cnt++;
412
413 chip->bin_log_seqops.chip = chip;
414 if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
415 chip->bin_log_seqops.seqops =
416 &tpm2_binary_b_measurements_seqops;
417 else
418 chip->bin_log_seqops.seqops =
419 &tpm_binary_b_measurements_seqops;
420
421
422 chip->bios_dir[cnt] =
423 securityfs_create_file("binary_bios_measurements",
424 0440, chip->bios_dir[0],
425 (void *)&chip->bin_log_seqops,
426 &tpm_bios_measurements_ops);
427 if (IS_ERR(chip->bios_dir[cnt]))
428 goto err;
429 cnt++;
430
431 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
432
433 chip->ascii_log_seqops.chip = chip;
434 chip->ascii_log_seqops.seqops =
435 &tpm_ascii_b_measurements_seqops;
436
437 chip->bios_dir[cnt] =
438 securityfs_create_file("ascii_bios_measurements",
439 0440, chip->bios_dir[0],
440 (void *)&chip->ascii_log_seqops,
441 &tpm_bios_measurements_ops);
442 if (IS_ERR(chip->bios_dir[cnt]))
443 goto err;
444 cnt++;
445 }
446
447 return 0;
448
449err:
450 rc = PTR_ERR(chip->bios_dir[cnt]);
451 chip->bios_dir[cnt] = NULL;
452 tpm_bios_log_teardown(chip);
453 return rc;
454}
455
456void tpm_bios_log_teardown(struct tpm_chip *chip)
457{
458 int i;
459 struct inode *inode;
460
461 /* securityfs_remove currently doesn't take care of handling sync
462 * between removal and opening of pseudo files. To handle this, a
463 * workaround is added by making i_private = NULL here during removal
464 * and to check it during open(), both within inode_lock()/unlock().
465 * This design ensures that open() either safely gets kref or fails.
466 */
467 for (i = (TPM_NUM_EVENT_LOG_FILES - 1); i >= 0; i--) {
468 if (chip->bios_dir[i]) {
469 inode = d_inode(chip->bios_dir[i]);
470 inode_lock(inode);
471 inode->i_private = NULL;
472 inode_unlock(inode);
473 securityfs_remove(chip->bios_dir[i]);
474 }
475 }
476}
diff --git a/drivers/char/tpm/tpm2_eventlog.c b/drivers/char/tpm/eventlog/tpm2.c
index 1ce4411292ba..1b8fa9de2cac 100644
--- a/drivers/char/tpm/tpm2_eventlog.c
+++ b/drivers/char/tpm/eventlog/tpm2.c
@@ -23,7 +23,8 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/tpm_eventlog.h> 24#include <linux/tpm_eventlog.h>
25 25
26#include "tpm.h" 26#include "../tpm.h"
27#include "common.h"
27 28
28/* 29/*
29 * calc_tpm2_event_size() - calculate the event size, where event 30 * calc_tpm2_event_size() - calculate the event size, where event
diff --git a/drivers/char/tpm/st33zp24/spi.c b/drivers/char/tpm/st33zp24/spi.c
index 0fc4f20b5f83..d7909ab287a8 100644
--- a/drivers/char/tpm/st33zp24/spi.c
+++ b/drivers/char/tpm/st33zp24/spi.c
@@ -40,7 +40,7 @@
40#define ST33ZP24_OK 0x5A 40#define ST33ZP24_OK 0x5A
41#define ST33ZP24_UNDEFINED_ERR 0x80 41#define ST33ZP24_UNDEFINED_ERR 0x80
42#define ST33ZP24_BADLOCALITY 0x81 42#define ST33ZP24_BADLOCALITY 0x81
43#define ST33ZP24_TISREGISTER_UKNOWN 0x82 43#define ST33ZP24_TISREGISTER_UNKNOWN 0x82
44#define ST33ZP24_LOCALITY_NOT_ACTIVATED 0x83 44#define ST33ZP24_LOCALITY_NOT_ACTIVATED 0x83
45#define ST33ZP24_HASH_END_BEFORE_HASH_START 0x84 45#define ST33ZP24_HASH_END_BEFORE_HASH_START 0x84
46#define ST33ZP24_BAD_COMMAND_ORDER 0x85 46#define ST33ZP24_BAD_COMMAND_ORDER 0x85
@@ -84,7 +84,7 @@ static int st33zp24_status_to_errno(u8 code)
84 return 0; 84 return 0;
85 case ST33ZP24_UNDEFINED_ERR: 85 case ST33ZP24_UNDEFINED_ERR:
86 case ST33ZP24_BADLOCALITY: 86 case ST33ZP24_BADLOCALITY:
87 case ST33ZP24_TISREGISTER_UKNOWN: 87 case ST33ZP24_TISREGISTER_UNKNOWN:
88 case ST33ZP24_LOCALITY_NOT_ACTIVATED: 88 case ST33ZP24_LOCALITY_NOT_ACTIVATED:
89 case ST33ZP24_HASH_END_BEFORE_HASH_START: 89 case ST33ZP24_HASH_END_BEFORE_HASH_START:
90 case ST33ZP24_BAD_COMMAND_ORDER: 90 case ST33ZP24_BAD_COMMAND_ORDER:
diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
index f95b9c75175b..abd675bec88c 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -373,8 +373,6 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
373 int ret; 373 int ret;
374 u8 data; 374 u8 data;
375 375
376 if (!chip)
377 return -EBUSY;
378 if (len < TPM_HEADER_SIZE) 376 if (len < TPM_HEADER_SIZE)
379 return -EBUSY; 377 return -EBUSY;
380 378
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index c43a9e28995e..e32f6e85dc6d 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -489,7 +489,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
489 goto out; 489 goto out;
490 } 490 }
491 491
492 tpm_msleep(TPM_TIMEOUT); 492 tpm_msleep(TPM_TIMEOUT_POLL);
493 rmb(); 493 rmb();
494 } while (time_before(jiffies, stop)); 494 } while (time_before(jiffies, stop));
495 495
@@ -587,7 +587,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
587 */ 587 */
588 if (rc == TPM2_RC_TESTING && cc == TPM2_CC_SELF_TEST) 588 if (rc == TPM2_RC_TESTING && cc == TPM2_CC_SELF_TEST)
589 break; 589 break;
590 delay_msec *= 2; 590
591 if (delay_msec > TPM2_DURATION_LONG) { 591 if (delay_msec > TPM2_DURATION_LONG) {
592 if (rc == TPM2_RC_RETRY) 592 if (rc == TPM2_RC_RETRY)
593 dev_err(&chip->dev, "in retry loop\n"); 593 dev_err(&chip->dev, "in retry loop\n");
@@ -597,6 +597,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
597 break; 597 break;
598 } 598 }
599 tpm_msleep(delay_msec); 599 tpm_msleep(delay_msec);
600 delay_msec *= 2;
600 memcpy(buf, save, save_size); 601 memcpy(buf, save, save_size);
601 } 602 }
602 return ret; 603 return ret;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 7f2d0f489e9c..4426649e431c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -53,7 +53,10 @@ enum tpm_const {
53enum tpm_timeout { 53enum tpm_timeout {
54 TPM_TIMEOUT = 5, /* msecs */ 54 TPM_TIMEOUT = 5, /* msecs */
55 TPM_TIMEOUT_RETRY = 100, /* msecs */ 55 TPM_TIMEOUT_RETRY = 100, /* msecs */
56 TPM_TIMEOUT_RANGE_US = 300 /* usecs */ 56 TPM_TIMEOUT_RANGE_US = 300, /* usecs */
57 TPM_TIMEOUT_POLL = 1, /* msecs */
58 TPM_TIMEOUT_USECS_MIN = 100, /* usecs */
59 TPM_TIMEOUT_USECS_MAX = 500 /* usecs */
57}; 60};
58 61
59/* TPM addresses */ 62/* TPM addresses */
@@ -590,33 +593,6 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
590int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, 593int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
591 u32 cc, u8 *buf, size_t *bufsiz); 594 u32 cc, u8 *buf, size_t *bufsiz);
592 595
593extern const struct seq_operations tpm2_binary_b_measurements_seqops;
594
595#if defined(CONFIG_ACPI)
596int tpm_read_log_acpi(struct tpm_chip *chip);
597#else
598static inline int tpm_read_log_acpi(struct tpm_chip *chip)
599{
600 return -ENODEV;
601}
602#endif
603#if defined(CONFIG_OF)
604int tpm_read_log_of(struct tpm_chip *chip);
605#else
606static inline int tpm_read_log_of(struct tpm_chip *chip)
607{
608 return -ENODEV;
609}
610#endif
611#if defined(CONFIG_EFI)
612int tpm_read_log_efi(struct tpm_chip *chip);
613#else
614static inline int tpm_read_log_efi(struct tpm_chip *chip)
615{
616 return -ENODEV;
617}
618#endif
619
620int tpm_bios_log_setup(struct tpm_chip *chip); 596int tpm_bios_log_setup(struct tpm_chip *chip);
621void tpm_bios_log_teardown(struct tpm_chip *chip); 597void tpm_bios_log_teardown(struct tpm_chip *chip);
622#endif 598#endif
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 4e4014eabdb9..6122d3276f72 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -102,8 +102,9 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
102 * TPM_RC_REFERENCE_H0 means the session has been 102 * TPM_RC_REFERENCE_H0 means the session has been
103 * flushed outside the space 103 * flushed outside the space
104 */ 104 */
105 rc = -ENOENT; 105 *handle = 0;
106 tpm_buf_destroy(&tbuf); 106 tpm_buf_destroy(&tbuf);
107 return -ENOENT;
107 } else if (rc > 0) { 108 } else if (rc > 0) {
108 dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n", 109 dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
109 __func__, rc); 110 __func__, rc);
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 7f78482cd157..34fbc6cb097b 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -511,8 +511,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
511 511
512 priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address, 512 priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address,
513 sizeof(struct crb_regs_tail)); 513 sizeof(struct crb_regs_tail));
514 if (IS_ERR(priv->regs_t)) 514 if (IS_ERR(priv->regs_t)) {
515 return PTR_ERR(priv->regs_t); 515 ret = PTR_ERR(priv->regs_t);
516 goto out_relinquish_locality;
517 }
516 518
517 /* 519 /*
518 * PTT HW bug w/a: wake up the device to access 520 * PTT HW bug w/a: wake up the device to access
@@ -520,7 +522,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
520 */ 522 */
521 ret = crb_cmd_ready(dev, priv); 523 ret = crb_cmd_ready(dev, priv);
522 if (ret) 524 if (ret)
523 return ret; 525 goto out_relinquish_locality;
524 526
525 pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high); 527 pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high);
526 pa_low = ioread32(&priv->regs_t->ctrl_cmd_pa_low); 528 pa_low = ioread32(&priv->regs_t->ctrl_cmd_pa_low);
@@ -565,6 +567,8 @@ out:
565 567
566 crb_go_idle(dev, priv); 568 crb_go_idle(dev, priv);
567 569
570out_relinquish_locality:
571
568 __crb_relinquish_locality(dev, priv, 0); 572 __crb_relinquish_locality(dev, priv, 0);
569 573
570 return ret; 574 return ret;
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 5a1f47b43947..8b46aaa9e049 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -31,12 +31,6 @@
31#include "tpm.h" 31#include "tpm.h"
32#include "tpm_tis_core.h" 32#include "tpm_tis_core.h"
33 33
34/* This is a polling delay to check for status and burstcount.
35 * As per ddwg input, expectation is that status check and burstcount
36 * check should return within few usecs.
37 */
38#define TPM_POLL_SLEEP 1 /* msec */
39
40static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value); 34static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
41 35
42static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, 36static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
@@ -90,7 +84,8 @@ again:
90 } 84 }
91 } else { 85 } else {
92 do { 86 do {
93 tpm_msleep(TPM_POLL_SLEEP); 87 usleep_range(TPM_TIMEOUT_USECS_MIN,
88 TPM_TIMEOUT_USECS_MAX);
94 status = chip->ops->status(chip); 89 status = chip->ops->status(chip);
95 if ((status & mask) == mask) 90 if ((status & mask) == mask)
96 return 0; 91 return 0;
@@ -143,13 +138,58 @@ static bool check_locality(struct tpm_chip *chip, int l)
143 return false; 138 return false;
144} 139}
145 140
141static bool locality_inactive(struct tpm_chip *chip, int l)
142{
143 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
144 int rc;
145 u8 access;
146
147 rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
148 if (rc < 0)
149 return false;
150
151 if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
152 == TPM_ACCESS_VALID)
153 return true;
154
155 return false;
156}
157
146static int release_locality(struct tpm_chip *chip, int l) 158static int release_locality(struct tpm_chip *chip, int l)
147{ 159{
148 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); 160 struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
161 unsigned long stop, timeout;
162 long rc;
149 163
150 tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); 164 tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
151 165
152 return 0; 166 stop = jiffies + chip->timeout_a;
167
168 if (chip->flags & TPM_CHIP_FLAG_IRQ) {
169again:
170 timeout = stop - jiffies;
171 if ((long)timeout <= 0)
172 return -1;
173
174 rc = wait_event_interruptible_timeout(priv->int_queue,
175 (locality_inactive(chip, l)),
176 timeout);
177
178 if (rc > 0)
179 return 0;
180
181 if (rc == -ERESTARTSYS && freezing(current)) {
182 clear_thread_flag(TIF_SIGPENDING);
183 goto again;
184 }
185 } else {
186 do {
187 if (locality_inactive(chip, l))
188 return 0;
189 tpm_msleep(TPM_TIMEOUT);
190 } while (time_before(jiffies, stop));
191 }
192 return -1;
153} 193}
154 194
155static int request_locality(struct tpm_chip *chip, int l) 195static int request_locality(struct tpm_chip *chip, int l)
@@ -234,7 +274,7 @@ static int get_burstcount(struct tpm_chip *chip)
234 burstcnt = (value >> 8) & 0xFFFF; 274 burstcnt = (value >> 8) & 0xFFFF;
235 if (burstcnt) 275 if (burstcnt)
236 return burstcnt; 276 return burstcnt;
237 tpm_msleep(TPM_POLL_SLEEP); 277 usleep_range(TPM_TIMEOUT_USECS_MIN, TPM_TIMEOUT_USECS_MAX);
238 } while (time_before(jiffies, stop)); 278 } while (time_before(jiffies, stop));
239 return -EBUSY; 279 return -EBUSY;
240} 280}