]>
Commit | Line | Data |
---|---|---|
7f55bd9d GKH |
1 | From 24ebe6670de3d1f0dca11c9eb372134c7ab05503 Mon Sep 17 00:00:00 2001 |
2 | From: Rajiv Andrade <srajiv@linux.vnet.ibm.com> | |
3 | Date: Tue, 24 Apr 2012 17:38:17 -0300 | |
4 | Subject: TPM: chip disabled state erronously being reported as error | |
5 | ||
6 | From: Rajiv Andrade <srajiv@linux.vnet.ibm.com> | |
7 | ||
8 | commit 24ebe6670de3d1f0dca11c9eb372134c7ab05503 upstream. | |
9 | ||
10 | tpm_do_selftest() attempts to read a PCR in order to | |
11 | decide if one can rely on the TPM being used or not. | |
12 | The function that's used by __tpm_pcr_read() does not | |
13 | expect the TPM to be disabled or deactivated, and if so, | |
14 | reports an error. | |
15 | ||
16 | It's fine if the TPM returns this error when trying to | |
17 | use it for the first time after a power cycle, but it's | |
18 | definitely not if it already returned success for a | |
19 | previous attempt to read one of its PCRs. | |
20 | ||
21 | The tpm_do_selftest() was modified so that the driver only | |
22 | reports this return code as an error when it really is. | |
23 | ||
24 | Reported-and-tested-by: Paul Bolle <pebolle@tiscali.nl> | |
25 | Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
27 | ||
28 | --- | |
29 | drivers/char/tpm/tpm.c | 12 ++++++++++-- | |
30 | 1 file changed, 10 insertions(+), 2 deletions(-) | |
31 | ||
32 | --- a/drivers/char/tpm/tpm.c | |
33 | +++ b/drivers/char/tpm/tpm.c | |
34 | @@ -827,10 +827,10 @@ EXPORT_SYMBOL_GPL(tpm_pcr_extend); | |
35 | int tpm_do_selftest(struct tpm_chip *chip) | |
36 | { | |
37 | int rc; | |
38 | - u8 digest[TPM_DIGEST_SIZE]; | |
39 | unsigned int loops; | |
40 | unsigned int delay_msec = 1000; | |
41 | unsigned long duration; | |
42 | + struct tpm_cmd_t cmd; | |
43 | ||
44 | duration = tpm_calc_ordinal_duration(chip, | |
45 | TPM_ORD_CONTINUE_SELFTEST); | |
46 | @@ -845,7 +845,15 @@ int tpm_do_selftest(struct tpm_chip *chi | |
47 | return rc; | |
48 | ||
49 | do { | |
50 | - rc = __tpm_pcr_read(chip, 0, digest); | |
51 | + /* Attempt to read a PCR value */ | |
52 | + cmd.header.in = pcrread_header; | |
53 | + cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0); | |
54 | + rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE); | |
55 | + | |
56 | + if (rc < TPM_HEADER_SIZE) | |
57 | + return -EFAULT; | |
58 | + | |
59 | + rc = be32_to_cpu(cmd.header.out.return_code); | |
60 | if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) { | |
61 | dev_info(chip->dev, | |
62 | "TPM is disabled/deactivated (0x%X)\n", rc); |