| From 0178f9d0f60ba07e09bab57381a3ef18e2c1fd7f Mon Sep 17 00:00:00 2001 |
| From: Jarkko Sakkinen <jarkko@kernel.org> |
| Date: Wed, 9 Jun 2021 16:26:19 +0300 |
| Subject: tpm: Replace WARN_ONCE() with dev_err_once() in tpm_tis_status() |
| |
| From: Jarkko Sakkinen <jarkko@kernel.org> |
| |
| commit 0178f9d0f60ba07e09bab57381a3ef18e2c1fd7f upstream. |
| |
| Do not tear down the system when getting invalid status from a TPM chip. |
| This can happen when panic-on-warn is used. |
| |
| Instead, introduce TPM_TIS_INVALID_STATUS bitflag and use it to trigger |
| once the error reporting per chip. In addition, print out the value of |
| TPM_STS for improved forensics. |
| |
| Link: https://lore.kernel.org/keyrings/YKzlTR1AzUigShtZ@kroah.com/ |
| Fixes: 55707d531af6 ("tpm_tis: Add a check for invalid status") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/char/tpm/tpm_tis_core.c | 25 ++++++++++++++++++------- |
| drivers/char/tpm/tpm_tis_core.h | 3 ++- |
| 2 files changed, 20 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/char/tpm/tpm_tis_core.c |
| +++ b/drivers/char/tpm/tpm_tis_core.c |
| @@ -196,13 +196,24 @@ static u8 tpm_tis_status(struct tpm_chip |
| return 0; |
| |
| if (unlikely((status & TPM_STS_READ_ZERO) != 0)) { |
| - /* |
| - * If this trips, the chances are the read is |
| - * returning 0xff because the locality hasn't been |
| - * acquired. Usually because tpm_try_get_ops() hasn't |
| - * been called before doing a TPM operation. |
| - */ |
| - WARN_ONCE(1, "TPM returned invalid status\n"); |
| + if (!test_and_set_bit(TPM_TIS_INVALID_STATUS, &priv->flags)) { |
| + /* |
| + * If this trips, the chances are the read is |
| + * returning 0xff because the locality hasn't been |
| + * acquired. Usually because tpm_try_get_ops() hasn't |
| + * been called before doing a TPM operation. |
| + */ |
| + dev_err(&chip->dev, "invalid TPM_STS.x 0x%02x, dumping stack for forensics\n", |
| + status); |
| + |
| + /* |
| + * Dump stack for forensics, as invalid TPM_STS.x could be |
| + * potentially triggered by impaired tpm_try_get_ops() or |
| + * tpm_find_get_ops(). |
| + */ |
| + dump_stack(); |
| + } |
| + |
| return 0; |
| } |
| |
| --- a/drivers/char/tpm/tpm_tis_core.h |
| +++ b/drivers/char/tpm/tpm_tis_core.h |
| @@ -83,6 +83,7 @@ enum tis_defaults { |
| |
| enum tpm_tis_flags { |
| TPM_TIS_ITPM_WORKAROUND = BIT(0), |
| + TPM_TIS_INVALID_STATUS = BIT(1), |
| }; |
| |
| struct tpm_tis_data { |
| @@ -90,7 +91,7 @@ struct tpm_tis_data { |
| int locality; |
| int irq; |
| bool irq_tested; |
| - unsigned int flags; |
| + unsigned long flags; |
| void __iomem *ilb_base_addr; |
| u16 clkrun_enabled; |
| wait_queue_head_t int_queue; |