aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorMaciej S. Szmigiero <mail@maciej.szmigiero.name>2017-01-13 16:37:00 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-08 01:47:55 -0400
commit1b7f385e049c46ae723126ccea343165e26a943f (patch)
tree9b0c981c7ddd33102e322c46acd485d1ec573b1b /drivers/char
parentd8fd99d4721d4a33c928ee0de8370b294a2df150 (diff)
tpm_tis: use default timeout value if chip reports it as zero
commit 1d70fe9d9c3a4c627f9757cbba5d628687b121c1 upstream. Since commit 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access") Atmel 3203 TPM on ThinkPad X61S (TPM firmware version 13.9) no longer works. The initialization proceeds fine until we get and start using chip-reported timeouts - and the chip reports C and D timeouts of zero. It turns out that until commit 8e54caf407b98e ("tpm: Provide a generic means to override the chip returned timeouts") we had actually let default timeout values remain in this case, so let's bring back this behavior to make chips like Atmel 3203 work again. Use a common code that was introduced by that commit so a warning is printed in this case and /sys/class/tpm/tpm*/timeouts correctly says the timeouts aren't chip-original. This is a backport for 4.9 kernel version of the original commit, with renaming of "TPM_TIS_ITPM_POSSIBLE" flag removed since it was only a cosmetic change and not a part of the real bug fix. Fixes: 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access") Cc: stable@vger.kernel.org Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm-interface.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 3a9149cf0110..d0ac2d56520f 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -489,8 +489,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
489int tpm_get_timeouts(struct tpm_chip *chip) 489int tpm_get_timeouts(struct tpm_chip *chip)
490{ 490{
491 struct tpm_cmd_t tpm_cmd; 491 struct tpm_cmd_t tpm_cmd;
492 unsigned long new_timeout[4]; 492 unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
493 unsigned long old_timeout[4];
494 struct duration_t *duration_cap; 493 struct duration_t *duration_cap;
495 ssize_t rc; 494 ssize_t rc;
496 495
@@ -542,11 +541,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
542 != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32)) 541 != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
543 return -EINVAL; 542 return -EINVAL;
544 543
545 old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a); 544 timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
546 old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b); 545 timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
547 old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c); 546 timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
548 old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d); 547 timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
549 memcpy(new_timeout, old_timeout, sizeof(new_timeout)); 548 timeout_chip[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
549 timeout_chip[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
550 timeout_chip[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
551 timeout_chip[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
552 memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff));
550 553
551 /* 554 /*
552 * Provide ability for vendor overrides of timeout values in case 555 * Provide ability for vendor overrides of timeout values in case
@@ -554,16 +557,24 @@ int tpm_get_timeouts(struct tpm_chip *chip)
554 */ 557 */
555 if (chip->ops->update_timeouts != NULL) 558 if (chip->ops->update_timeouts != NULL)
556 chip->timeout_adjusted = 559 chip->timeout_adjusted =
557 chip->ops->update_timeouts(chip, new_timeout); 560 chip->ops->update_timeouts(chip, timeout_eff);
558 561
559 if (!chip->timeout_adjusted) { 562 if (!chip->timeout_adjusted) {
560 /* Don't overwrite default if value is 0 */ 563 /* Restore default if chip reported 0 */
561 if (new_timeout[0] != 0 && new_timeout[0] < 1000) { 564 int i;
562 int i;
563 565
566 for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) {
567 if (timeout_eff[i])
568 continue;
569
570 timeout_eff[i] = timeout_old[i];
571 chip->timeout_adjusted = true;
572 }
573
574 if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) {
564 /* timeouts in msec rather usec */ 575 /* timeouts in msec rather usec */
565 for (i = 0; i != ARRAY_SIZE(new_timeout); i++) 576 for (i = 0; i != ARRAY_SIZE(timeout_eff); i++)
566 new_timeout[i] *= 1000; 577 timeout_eff[i] *= 1000;
567 chip->timeout_adjusted = true; 578 chip->timeout_adjusted = true;
568 } 579 }
569 } 580 }
@@ -572,16 +583,16 @@ int tpm_get_timeouts(struct tpm_chip *chip)
572 if (chip->timeout_adjusted) { 583 if (chip->timeout_adjusted) {
573 dev_info(&chip->dev, 584 dev_info(&chip->dev,
574 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n", 585 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
575 old_timeout[0], new_timeout[0], 586 timeout_chip[0], timeout_eff[0],
576 old_timeout[1], new_timeout[1], 587 timeout_chip[1], timeout_eff[1],
577 old_timeout[2], new_timeout[2], 588 timeout_chip[2], timeout_eff[2],
578 old_timeout[3], new_timeout[3]); 589 timeout_chip[3], timeout_eff[3]);
579 } 590 }
580 591
581 chip->timeout_a = usecs_to_jiffies(new_timeout[0]); 592 chip->timeout_a = usecs_to_jiffies(timeout_eff[0]);
582 chip->timeout_b = usecs_to_jiffies(new_timeout[1]); 593 chip->timeout_b = usecs_to_jiffies(timeout_eff[1]);
583 chip->timeout_c = usecs_to_jiffies(new_timeout[2]); 594 chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
584 chip->timeout_d = usecs_to_jiffies(new_timeout[3]); 595 chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);
585 596
586duration: 597duration:
587 tpm_cmd.header.in = tpm_getcap_header; 598 tpm_cmd.header.in = tpm_getcap_header;