Skip to content

Commit 207696b

Browse files
committed
tpm: use a map for tpm2_calc_ordinal_duration()
The current shenanigans for duration calculation introduce too much complexity for a trivial problem, and further the code is hard to patch and maintain. Address these issues with a flat look-up table, which is easy to understand and patch. If leaf driver specific patching is required in future, it is easy enough to make a copy of this table during driver initialization and add the chip parameter back. 'chip->duration' is retained for TPM 1.x. As the first entry for this new behavior address TCG spec update mentioned in this issue: raspberrypi/linux#7054 Therefore, for TPM_SelfTest the duration is set to 3000 ms. This does not categorize a as bug, given that this is introduced to the spec after the feature was originally made. Reviewed-by: Serge Hallyn <serge@hallyn.com> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
1 parent 8a81236 commit 207696b

File tree

4 files changed

+37
-99
lines changed

4 files changed

+37
-99
lines changed

drivers/char/tpm/tpm-interface.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(suspend_pcr,
5252
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
5353
{
5454
if (chip->flags & TPM_CHIP_FLAG_TPM2)
55-
return tpm2_calc_ordinal_duration(chip, ordinal);
55+
return tpm2_calc_ordinal_duration(ordinal);
5656
else
5757
return tpm1_calc_ordinal_duration(chip, ordinal);
5858
}

drivers/char/tpm/tpm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
299299
ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
300300
int tpm2_auto_startup(struct tpm_chip *chip);
301301
void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
302-
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
302+
unsigned long tpm2_calc_ordinal_duration(u32 ordinal);
303303
int tpm2_probe(struct tpm_chip *chip);
304304
int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
305305
int tpm2_find_cc(struct tpm_chip *chip, u32 cc);

drivers/char/tpm/tpm2-cmd.c

Lines changed: 32 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -28,120 +28,57 @@ static struct tpm2_hash tpm2_hash_map[] = {
2828

2929
int tpm2_get_timeouts(struct tpm_chip *chip)
3030
{
31-
/* Fixed timeouts for TPM2 */
3231
chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
3332
chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
3433
chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
3534
chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
36-
37-
/* PTP spec timeouts */
38-
chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT);
39-
chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM);
40-
chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG);
41-
42-
/* Key creation commands long timeouts */
43-
chip->duration[TPM_LONG_LONG] =
44-
msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
45-
4635
chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
47-
4836
return 0;
4937
}
5038

51-
/**
52-
* tpm2_ordinal_duration_index() - returns an index to the chip duration table
53-
* @ordinal: TPM command ordinal.
54-
*
55-
* The function returns an index to the chip duration table
56-
* (enum tpm_duration), that describes the maximum amount of
57-
* time the chip could take to return the result for a particular ordinal.
58-
*
59-
* The values of the MEDIUM, and LONG durations are taken
60-
* from the PC Client Profile (PTP) specification (750, 2000 msec)
61-
*
62-
* LONG_LONG is for commands that generates keys which empirically takes
63-
* a longer time on some systems.
64-
*
65-
* Return:
66-
* * TPM_MEDIUM
67-
* * TPM_LONG
68-
* * TPM_LONG_LONG
69-
* * TPM_UNDEFINED
39+
/*
40+
* Contains the maximum durations in milliseconds for TPM2 commands.
7041
*/
71-
static u8 tpm2_ordinal_duration_index(u32 ordinal)
72-
{
73-
switch (ordinal) {
74-
/* Startup */
75-
case TPM2_CC_STARTUP: /* 144 */
76-
return TPM_MEDIUM;
77-
78-
case TPM2_CC_SELF_TEST: /* 143 */
79-
return TPM_LONG;
80-
81-
case TPM2_CC_GET_RANDOM: /* 17B */
82-
return TPM_LONG;
83-
84-
case TPM2_CC_SEQUENCE_UPDATE: /* 15C */
85-
return TPM_MEDIUM;
86-
case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */
87-
return TPM_MEDIUM;
88-
case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */
89-
return TPM_MEDIUM;
90-
case TPM2_CC_HASH_SEQUENCE_START: /* 186 */
91-
return TPM_MEDIUM;
92-
93-
case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
94-
return TPM_LONG_LONG;
95-
96-
case TPM2_CC_PCR_EXTEND: /* 182 */
97-
return TPM_MEDIUM;
98-
99-
case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
100-
return TPM_LONG;
101-
case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
102-
return TPM_LONG;
103-
104-
case TPM2_CC_GET_CAPABILITY: /* 17A */
105-
return TPM_MEDIUM;
106-
107-
case TPM2_CC_NV_READ: /* 14E */
108-
return TPM_LONG;
109-
110-
case TPM2_CC_CREATE_PRIMARY: /* 131 */
111-
return TPM_LONG_LONG;
112-
case TPM2_CC_CREATE: /* 153 */
113-
return TPM_LONG_LONG;
114-
case TPM2_CC_CREATE_LOADED: /* 191 */
115-
return TPM_LONG_LONG;
116-
117-
default:
118-
return TPM_UNDEFINED;
119-
}
120-
}
42+
static const struct {
43+
unsigned long ordinal;
44+
unsigned long duration;
45+
} tpm2_ordinal_duration_map[] = {
46+
{TPM2_CC_STARTUP, 750},
47+
{TPM2_CC_SELF_TEST, 3000},
48+
{TPM2_CC_GET_RANDOM, 2000},
49+
{TPM2_CC_SEQUENCE_UPDATE, 750},
50+
{TPM2_CC_SEQUENCE_COMPLETE, 750},
51+
{TPM2_CC_EVENT_SEQUENCE_COMPLETE, 750},
52+
{TPM2_CC_HASH_SEQUENCE_START, 750},
53+
{TPM2_CC_VERIFY_SIGNATURE, 30000},
54+
{TPM2_CC_PCR_EXTEND, 750},
55+
{TPM2_CC_HIERARCHY_CONTROL, 2000},
56+
{TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000},
57+
{TPM2_CC_GET_CAPABILITY, 750},
58+
{TPM2_CC_NV_READ, 2000},
59+
{TPM2_CC_CREATE_PRIMARY, 30000},
60+
{TPM2_CC_CREATE, 30000},
61+
{TPM2_CC_CREATE_LOADED, 30000},
62+
};
12163

12264
/**
123-
* tpm2_calc_ordinal_duration() - calculate the maximum command duration
124-
* @chip: TPM chip to use.
65+
* tpm2_calc_ordinal_duration() - Calculate the maximum command duration
12566
* @ordinal: TPM command ordinal.
12667
*
127-
* The function returns the maximum amount of time the chip could take
128-
* to return the result for a particular ordinal in jiffies.
129-
*
130-
* Return: A maximal duration time for an ordinal in jiffies.
68+
* Returns the maximum amount of time the chip is expected by kernel to
69+
* take in jiffies.
13170
*/
132-
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
71+
unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
13372
{
134-
unsigned int index;
73+
int i;
13574

136-
index = tpm2_ordinal_duration_index(ordinal);
75+
for (i = 0; i < ARRAY_SIZE(tpm2_ordinal_duration_map); i++)
76+
if (ordinal == tpm2_ordinal_duration_map[i].ordinal)
77+
return msecs_to_jiffies(tpm2_ordinal_duration_map[i].duration);
13778

138-
if (index != TPM_UNDEFINED)
139-
return chip->duration[index];
140-
else
141-
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
79+
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
14280
}
14381

144-
14582
struct tpm2_pcr_read_out {
14683
__be32 update_cnt;
14784
__be32 pcr_selects_cnt;

include/linux/tpm.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,11 @@ enum tpm2_timeouts {
228228
TPM2_TIMEOUT_B = 4000,
229229
TPM2_TIMEOUT_C = 200,
230230
TPM2_TIMEOUT_D = 30,
231+
};
232+
233+
enum tpm2_durations {
231234
TPM2_DURATION_SHORT = 20,
232-
TPM2_DURATION_MEDIUM = 750,
233235
TPM2_DURATION_LONG = 2000,
234-
TPM2_DURATION_LONG_LONG = 300000,
235236
TPM2_DURATION_DEFAULT = 120000,
236237
};
237238

0 commit comments

Comments
 (0)