aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHamza Attak <hamza@hpe.com>2017-08-14 14:09:16 -0400
committerJames Morris <james.l.morris@oracle.com>2017-09-24 00:51:00 -0400
commit9f3fc7bcddcb51234e23494531f93ab60475e1c3 (patch)
treef788e5570ade80f9cb8661330f6f9ff2f2e46e0a
parent5d0e4d78149b9745ea34848e950e734f7db3b95f (diff)
tpm: replace msleep() with usleep_range() in TPM 1.2/2.0 generic drivers
The patch simply replaces all msleep function calls with usleep_range calls in the generic drivers. Tested with an Infineon TPM 1.2, using the generic tpm-tis module, for a thousand PCR extends, we see results going from 1m57s unpatched to 40s with the new patch. We obtain similar results when using the original and patched tpm_infineon driver, which is also part of the patch. Similarly with a STM TPM 2.0, using the CRB driver, it takes about 20ms per extend unpatched and around 7ms with the new patch. Note that the PCR consistency is untouched with this patch, each TPM has been tested with 10 million extends and the aggregated PCR value is continuously verified to be correct. As an extension of this work, this could potentially and easily be applied to other vendor's drivers. Still, these changes are not included in the proposed patch as they are untested. Signed-off-by: Hamza Attak <hamza@hpe.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> Signed-off-by: James Morris <james.l.morris@oracle.com>
-rw-r--r--drivers/char/tpm/tpm-interface.c10
-rw-r--r--drivers/char/tpm/tpm.h9
-rw-r--r--drivers/char/tpm/tpm2-cmd.c2
-rw-r--r--drivers/char/tpm/tpm_infineon.c6
-rw-r--r--drivers/char/tpm/tpm_tis_core.c8
5 files changed, 21 insertions, 14 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index fe597e6c55c4..1d6729be4cd6 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -455,7 +455,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
455 goto out; 455 goto out;
456 } 456 }
457 457
458 msleep(TPM_TIMEOUT); /* CHECK */ 458 tpm_msleep(TPM_TIMEOUT);
459 rmb(); 459 rmb();
460 } while (time_before(jiffies, stop)); 460 } while (time_before(jiffies, stop));
461 461
@@ -970,7 +970,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
970 dev_info( 970 dev_info(
971 &chip->dev, HW_ERR 971 &chip->dev, HW_ERR
972 "TPM command timed out during continue self test"); 972 "TPM command timed out during continue self test");
973 msleep(delay_msec); 973 tpm_msleep(delay_msec);
974 continue; 974 continue;
975 } 975 }
976 976
@@ -985,7 +985,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
985 } 985 }
986 if (rc != TPM_WARN_DOING_SELFTEST) 986 if (rc != TPM_WARN_DOING_SELFTEST)
987 return rc; 987 return rc;
988 msleep(delay_msec); 988 tpm_msleep(delay_msec);
989 } while (--loops > 0); 989 } while (--loops > 0);
990 990
991 return rc; 991 return rc;
@@ -1085,7 +1085,7 @@ again:
1085 } 1085 }
1086 } else { 1086 } else {
1087 do { 1087 do {
1088 msleep(TPM_TIMEOUT); 1088 tpm_msleep(TPM_TIMEOUT);
1089 status = chip->ops->status(chip); 1089 status = chip->ops->status(chip);
1090 if ((status & mask) == mask) 1090 if ((status & mask) == mask)
1091 return 0; 1091 return 0;
@@ -1150,7 +1150,7 @@ int tpm_pm_suspend(struct device *dev)
1150 */ 1150 */
1151 if (rc != TPM_WARN_RETRY) 1151 if (rc != TPM_WARN_RETRY)
1152 break; 1152 break;
1153 msleep(TPM_TIMEOUT_RETRY); 1153 tpm_msleep(TPM_TIMEOUT_RETRY);
1154 } 1154 }
1155 1155
1156 if (rc) 1156 if (rc)
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 04fbff2edbf3..2d5466a72e40 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -50,7 +50,8 @@ enum tpm_const {
50 50
51enum tpm_timeout { 51enum tpm_timeout {
52 TPM_TIMEOUT = 5, /* msecs */ 52 TPM_TIMEOUT = 5, /* msecs */
53 TPM_TIMEOUT_RETRY = 100 /* msecs */ 53 TPM_TIMEOUT_RETRY = 100, /* msecs */
54 TPM_TIMEOUT_RANGE_US = 300 /* usecs */
54}; 55};
55 56
56/* TPM addresses */ 57/* TPM addresses */
@@ -527,6 +528,12 @@ int tpm_pm_resume(struct device *dev);
527int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, 528int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
528 wait_queue_head_t *queue, bool check_cancel); 529 wait_queue_head_t *queue, bool check_cancel);
529 530
531static inline void tpm_msleep(unsigned int delay_msec)
532{
533 usleep_range(delay_msec * 1000,
534 (delay_msec * 1000) + TPM_TIMEOUT_RANGE_US);
535};
536
530struct tpm_chip *tpm_chip_find_get(int chip_num); 537struct tpm_chip *tpm_chip_find_get(int chip_num);
531__must_check int tpm_try_get_ops(struct tpm_chip *chip); 538__must_check int tpm_try_get_ops(struct tpm_chip *chip);
532void tpm_put_ops(struct tpm_chip *chip); 539void tpm_put_ops(struct tpm_chip *chip);
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index f7f34b2aa981..e1a41b788f08 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -899,7 +899,7 @@ static int tpm2_do_selftest(struct tpm_chip *chip)
899 if (rc != TPM2_RC_TESTING) 899 if (rc != TPM2_RC_TESTING)
900 break; 900 break;
901 901
902 msleep(delay_msec); 902 tpm_msleep(delay_msec);
903 } 903 }
904 904
905 return rc; 905 return rc;
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 3b1b9f9322d5..d8f10047fbba 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -191,7 +191,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
191 /* check the status-register if wait_for_bit is set */ 191 /* check the status-register if wait_for_bit is set */
192 if (status & 1 << wait_for_bit) 192 if (status & 1 << wait_for_bit)
193 break; 193 break;
194 msleep(TPM_MSLEEP_TIME); 194 tpm_msleep(TPM_MSLEEP_TIME);
195 } 195 }
196 if (i == TPM_MAX_TRIES) { /* timeout occurs */ 196 if (i == TPM_MAX_TRIES) { /* timeout occurs */
197 if (wait_for_bit == STAT_XFE) 197 if (wait_for_bit == STAT_XFE)
@@ -226,7 +226,7 @@ static void tpm_wtx(struct tpm_chip *chip)
226 wait_and_send(chip, TPM_CTRL_WTX); 226 wait_and_send(chip, TPM_CTRL_WTX);
227 wait_and_send(chip, 0x00); 227 wait_and_send(chip, 0x00);
228 wait_and_send(chip, 0x00); 228 wait_and_send(chip, 0x00);
229 msleep(TPM_WTX_MSLEEP_TIME); 229 tpm_msleep(TPM_WTX_MSLEEP_TIME);
230} 230}
231 231
232static void tpm_wtx_abort(struct tpm_chip *chip) 232static void tpm_wtx_abort(struct tpm_chip *chip)
@@ -237,7 +237,7 @@ static void tpm_wtx_abort(struct tpm_chip *chip)
237 wait_and_send(chip, 0x00); 237 wait_and_send(chip, 0x00);
238 wait_and_send(chip, 0x00); 238 wait_and_send(chip, 0x00);
239 number_of_wtx = 0; 239 number_of_wtx = 0;
240 msleep(TPM_WTX_MSLEEP_TIME); 240 tpm_msleep(TPM_WTX_MSLEEP_TIME);
241} 241}
242 242
243static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) 243static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index b617b2eeb080..63bc6c3b949e 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -51,7 +51,7 @@ static int wait_startup(struct tpm_chip *chip, int l)
51 51
52 if (access & TPM_ACCESS_VALID) 52 if (access & TPM_ACCESS_VALID)
53 return 0; 53 return 0;
54 msleep(TPM_TIMEOUT); 54 tpm_msleep(TPM_TIMEOUT);
55 } while (time_before(jiffies, stop)); 55 } while (time_before(jiffies, stop));
56 return -1; 56 return -1;
57} 57}
@@ -117,7 +117,7 @@ again:
117 do { 117 do {
118 if (check_locality(chip, l)) 118 if (check_locality(chip, l))
119 return l; 119 return l;
120 msleep(TPM_TIMEOUT); 120 tpm_msleep(TPM_TIMEOUT);
121 } while (time_before(jiffies, stop)); 121 } while (time_before(jiffies, stop));
122 } 122 }
123 return -1; 123 return -1;
@@ -164,7 +164,7 @@ static int get_burstcount(struct tpm_chip *chip)
164 burstcnt = (value >> 8) & 0xFFFF; 164 burstcnt = (value >> 8) & 0xFFFF;
165 if (burstcnt) 165 if (burstcnt)
166 return burstcnt; 166 return burstcnt;
167 msleep(TPM_TIMEOUT); 167 tpm_msleep(TPM_TIMEOUT);
168 } while (time_before(jiffies, stop)); 168 } while (time_before(jiffies, stop));
169 return -EBUSY; 169 return -EBUSY;
170} 170}
@@ -396,7 +396,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
396 priv->irq = irq; 396 priv->irq = irq;
397 chip->flags |= TPM_CHIP_FLAG_IRQ; 397 chip->flags |= TPM_CHIP_FLAG_IRQ;
398 if (!priv->irq_tested) 398 if (!priv->irq_tested)
399 msleep(1); 399 tpm_msleep(1);
400 if (!priv->irq_tested) 400 if (!priv->irq_tested)
401 disable_interrupts(chip); 401 disable_interrupts(chip);
402 priv->irq_tested = true; 402 priv->irq_tested = true;