diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2018-03-10 10:15:45 -0500 |
---|---|---|
committer | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2018-03-23 04:18:06 -0400 |
commit | 076d356460273e3c702f46fc87471b508fb55e7b (patch) | |
tree | b19fca82f9222da0cd5bb0a30851563fe60a27c2 | |
parent | 09b17f321c15879833bbe072cf28e3f0625d3fb7 (diff) |
tpm2: add longer timeouts for creation commands.
TPM2_CC_Create(0x153) and TPM2_CC_CreatePrimary (0x131) involve generation
of crypto keys which can be a computationally intensive task. The timeout
is set to 3min. Rather than increasing default timeout a new constant is
added, to not stall for too long on regular commands failures.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 3 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 28 | ||||
-rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 8 |
3 files changed, 26 insertions, 13 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 43ded5dfc7d9..47aacecdc85c 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
@@ -696,6 +696,8 @@ int tpm_get_timeouts(struct tpm_chip *chip) | |||
696 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); | 696 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); |
697 | chip->duration[TPM_LONG] = | 697 | chip->duration[TPM_LONG] = |
698 | msecs_to_jiffies(TPM2_DURATION_LONG); | 698 | msecs_to_jiffies(TPM2_DURATION_LONG); |
699 | chip->duration[TPM_LONG_LONG] = | ||
700 | msecs_to_jiffies(TPM2_DURATION_LONG_LONG); | ||
699 | 701 | ||
700 | chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS; | 702 | chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS; |
701 | return 0; | 703 | return 0; |
@@ -784,6 +786,7 @@ int tpm_get_timeouts(struct tpm_chip *chip) | |||
784 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_medium)); | 786 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_medium)); |
785 | chip->duration[TPM_LONG] = | 787 | chip->duration[TPM_LONG] = |
786 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_long)); | 788 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_long)); |
789 | chip->duration[TPM_LONG_LONG] = 0; /* not used under 1.2 */ | ||
787 | 790 | ||
788 | /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above | 791 | /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above |
789 | * value wrong and apparently reports msecs rather than usecs. So we | 792 | * value wrong and apparently reports msecs rather than usecs. So we |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index b0ee61e5d414..ab3bcdd4d328 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -67,7 +67,9 @@ enum tpm_duration { | |||
67 | TPM_SHORT = 0, | 67 | TPM_SHORT = 0, |
68 | TPM_MEDIUM = 1, | 68 | TPM_MEDIUM = 1, |
69 | TPM_LONG = 2, | 69 | TPM_LONG = 2, |
70 | TPM_LONG_LONG = 3, | ||
70 | TPM_UNDEFINED, | 71 | TPM_UNDEFINED, |
72 | TPM_NUM_DURATIONS = TPM_UNDEFINED, | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | #define TPM_WARN_RETRY 0x800 | 75 | #define TPM_WARN_RETRY 0x800 |
@@ -79,15 +81,20 @@ enum tpm_duration { | |||
79 | #define TPM_HEADER_SIZE 10 | 81 | #define TPM_HEADER_SIZE 10 |
80 | 82 | ||
81 | enum tpm2_const { | 83 | enum tpm2_const { |
82 | TPM2_PLATFORM_PCR = 24, | 84 | TPM2_PLATFORM_PCR = 24, |
83 | TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), | 85 | TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), |
84 | TPM2_TIMEOUT_A = 750, | 86 | }; |
85 | TPM2_TIMEOUT_B = 2000, | 87 | |
86 | TPM2_TIMEOUT_C = 200, | 88 | enum tpm2_timeouts { |
87 | TPM2_TIMEOUT_D = 30, | 89 | TPM2_TIMEOUT_A = 750, |
88 | TPM2_DURATION_SHORT = 20, | 90 | TPM2_TIMEOUT_B = 2000, |
89 | TPM2_DURATION_MEDIUM = 750, | 91 | TPM2_TIMEOUT_C = 200, |
90 | TPM2_DURATION_LONG = 2000, | 92 | TPM2_TIMEOUT_D = 30, |
93 | TPM2_DURATION_SHORT = 20, | ||
94 | TPM2_DURATION_MEDIUM = 750, | ||
95 | TPM2_DURATION_LONG = 2000, | ||
96 | TPM2_DURATION_LONG_LONG = 300000, | ||
97 | TPM2_DURATION_DEFAULT = 120000, | ||
91 | }; | 98 | }; |
92 | 99 | ||
93 | enum tpm2_structures { | 100 | enum tpm2_structures { |
@@ -123,6 +130,7 @@ enum tpm2_algorithms { | |||
123 | 130 | ||
124 | enum tpm2_command_codes { | 131 | enum tpm2_command_codes { |
125 | TPM2_CC_FIRST = 0x011F, | 132 | TPM2_CC_FIRST = 0x011F, |
133 | TPM2_CC_CREATE_PRIMARY = 0x0131, | ||
126 | TPM2_CC_SELF_TEST = 0x0143, | 134 | TPM2_CC_SELF_TEST = 0x0143, |
127 | TPM2_CC_STARTUP = 0x0144, | 135 | TPM2_CC_STARTUP = 0x0144, |
128 | TPM2_CC_SHUTDOWN = 0x0145, | 136 | TPM2_CC_SHUTDOWN = 0x0145, |
@@ -227,7 +235,7 @@ struct tpm_chip { | |||
227 | unsigned long timeout_c; /* jiffies */ | 235 | unsigned long timeout_c; /* jiffies */ |
228 | unsigned long timeout_d; /* jiffies */ | 236 | unsigned long timeout_d; /* jiffies */ |
229 | bool timeout_adjusted; | 237 | bool timeout_adjusted; |
230 | unsigned long duration[3]; /* jiffies */ | 238 | unsigned long duration[TPM_NUM_DURATIONS]; /* jiffies */ |
231 | bool duration_adjusted; | 239 | bool duration_adjusted; |
232 | 240 | ||
233 | struct dentry *bios_dir[TPM_NUM_EVENT_LOG_FILES]; | 241 | struct dentry *bios_dir[TPM_NUM_EVENT_LOG_FILES]; |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index a700f8f9ead7..c1ddbbba406e 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
@@ -90,6 +90,8 @@ static struct tpm2_hash tpm2_hash_map[] = { | |||
90 | * of time the chip could take to return the result. The values | 90 | * of time the chip could take to return the result. The values |
91 | * of the SHORT, MEDIUM, and LONG durations are taken from the | 91 | * of the SHORT, MEDIUM, and LONG durations are taken from the |
92 | * PC Client Profile (PTP) specification. | 92 | * PC Client Profile (PTP) specification. |
93 | * LONG_LONG is for commands that generates keys which empirically | ||
94 | * takes longer time on some systems. | ||
93 | */ | 95 | */ |
94 | static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | 96 | static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { |
95 | TPM_UNDEFINED, /* 11F */ | 97 | TPM_UNDEFINED, /* 11F */ |
@@ -110,7 +112,7 @@ static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | |||
110 | TPM_UNDEFINED, /* 12e */ | 112 | TPM_UNDEFINED, /* 12e */ |
111 | TPM_UNDEFINED, /* 12f */ | 113 | TPM_UNDEFINED, /* 12f */ |
112 | TPM_UNDEFINED, /* 130 */ | 114 | TPM_UNDEFINED, /* 130 */ |
113 | TPM_UNDEFINED, /* 131 */ | 115 | TPM_LONG_LONG, /* 131 */ |
114 | TPM_UNDEFINED, /* 132 */ | 116 | TPM_UNDEFINED, /* 132 */ |
115 | TPM_UNDEFINED, /* 133 */ | 117 | TPM_UNDEFINED, /* 133 */ |
116 | TPM_UNDEFINED, /* 134 */ | 118 | TPM_UNDEFINED, /* 134 */ |
@@ -144,7 +146,7 @@ static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | |||
144 | TPM_UNDEFINED, /* 150 */ | 146 | TPM_UNDEFINED, /* 150 */ |
145 | TPM_UNDEFINED, /* 151 */ | 147 | TPM_UNDEFINED, /* 151 */ |
146 | TPM_UNDEFINED, /* 152 */ | 148 | TPM_UNDEFINED, /* 152 */ |
147 | TPM_UNDEFINED, /* 153 */ | 149 | TPM_LONG_LONG, /* 153 */ |
148 | TPM_UNDEFINED, /* 154 */ | 150 | TPM_UNDEFINED, /* 154 */ |
149 | TPM_UNDEFINED, /* 155 */ | 151 | TPM_UNDEFINED, /* 155 */ |
150 | TPM_UNDEFINED, /* 156 */ | 152 | TPM_UNDEFINED, /* 156 */ |
@@ -821,7 +823,7 @@ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal) | |||
821 | duration = chip->duration[index]; | 823 | duration = chip->duration[index]; |
822 | 824 | ||
823 | if (duration <= 0) | 825 | if (duration <= 0) |
824 | duration = 2 * 60 * HZ; | 826 | duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT); |
825 | 827 | ||
826 | return duration; | 828 | return duration; |
827 | } | 829 | } |