* [PATCH 0/2] Fix TPM 1.2 resume
@ 2023-04-26 17:29 Jarkko Sakkinen
2023-04-26 17:29 ` [PATCH 1/2] tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume Jarkko Sakkinen
2023-04-26 17:29 ` [PATCH 2/2] tpm: Prevent hwrng from activating during resume Jarkko Sakkinen
0 siblings, 2 replies; 6+ messages in thread
From: Jarkko Sakkinen @ 2023-04-26 17:29 UTC (permalink / raw)
To: linux-integrity, linux-kernel
Cc: Jarkko Sakkinen, Vlastimil Babka, Jason A . Donenfeld,
Jason Gunthorpe
During TPM 1.2 resume, the first PCR read operation used inside
tpm1_do_selftest() fails. Fix two bugs that can prevent the
operation from working.
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Link: https://lore.kernel.org/linux-integrity/CS6UJMSTVA4L.FRQ5VL1I1EF4@suppilovahvero/T/#m236d62184229cc035605143fde10933bcde60065
Jarkko Sakkinen (2):
tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume
tpm: Prevent hwrng from activating during resume
drivers/char/tpm/tpm-chip.c | 4 +++
drivers/char/tpm/tpm-interface.c | 10 ++++++++
drivers/char/tpm/tpm_tis_core.c | 43 ++++++++++++++------------------
include/linux/tpm.h | 13 +++++-----
4 files changed, 40 insertions(+), 30 deletions(-)
--
2.39.2
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/2] tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume 2023-04-26 17:29 [PATCH 0/2] Fix TPM 1.2 resume Jarkko Sakkinen @ 2023-04-26 17:29 ` Jarkko Sakkinen 2023-04-27 15:11 ` Jerry Snitselaar 2023-04-26 17:29 ` [PATCH 2/2] tpm: Prevent hwrng from activating during resume Jarkko Sakkinen 1 sibling, 1 reply; 6+ messages in thread From: Jarkko Sakkinen @ 2023-04-26 17:29 UTC (permalink / raw) To: linux-integrity, linux-kernel, Peter Huewe, Jarkko Sakkinen, Jason Gunthorpe, Jerry Snitselaar, Stefan Berger, James Bottomley Cc: stable, Jason A . Donenfeld Before sending a TPM command, CLKRUN protocol must be disabled. This is not done in the case of tpm1_do_selftest() call site inside tpm_tis_resume(). Address this by decorating the calls with tpm_chip_{start,stop}, which arm and disarm the TPM chip for transmission, and take care of disabling and re-enabling CLKRUN, among other things. Cc: stable@vger.kernel.org Reported-by: Jason A. Donenfeld <Jason@zx2c4.com> Link: https://lore.kernel.org/linux-integrity/CS68AWILHXS4.3M36M1EKZLUMS@suppilovahvero/ Fixes: a3fbfae82b4c ("tpm: take TPM chip power gating out of tpm_transmit()") Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> --- drivers/char/tpm/tpm_tis_core.c | 43 +++++++++++++++------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index c2421162cf34..73707026e358 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -1209,25 +1209,20 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) u32 intmask; int rc; - if (chip->ops->clk_enable != NULL) - chip->ops->clk_enable(chip, true); - - /* reenable interrupts that device may have lost or - * BIOS/firmware may have disabled + /* + * Re-enable interrupts that device may have lost or BIOS/firmware may + * have disabled. */ rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq); - if (rc < 0) - goto out; + if (rc < 0) { + dev_err(&chip->dev, "Setting IRQ failed.\n"); + return; + } intmask = priv->int_mask | TPM_GLOBAL_INT_ENABLE; - - tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); - -out: - if (chip->ops->clk_enable != NULL) - chip->ops->clk_enable(chip, false); - - return; + rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); + if (rc < 0) + dev_err(&chip->dev, "Enabling interrupts failed.\n"); } int tpm_tis_resume(struct device *dev) @@ -1235,27 +1230,27 @@ int tpm_tis_resume(struct device *dev) struct tpm_chip *chip = dev_get_drvdata(dev); int ret; - ret = tpm_tis_request_locality(chip, 0); - if (ret < 0) + ret = tpm_chip_start(chip); + if (ret) return ret; if (chip->flags & TPM_CHIP_FLAG_IRQ) tpm_tis_reenable_interrupts(chip); - ret = tpm_pm_resume(dev); - if (ret) - goto out; - /* * TPM 1.2 requires self-test on resume. This function actually returns * an error code but for unknown reason it isn't handled. */ if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) tpm1_do_selftest(chip); -out: - tpm_tis_relinquish_locality(chip, 0); - return ret; + tpm_chip_stop(chip); + + ret = tpm_pm_resume(dev); + if (ret) + return ret; + + return 0; } EXPORT_SYMBOL_GPL(tpm_tis_resume); #endif -- 2.39.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume 2023-04-26 17:29 ` [PATCH 1/2] tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume Jarkko Sakkinen @ 2023-04-27 15:11 ` Jerry Snitselaar 0 siblings, 0 replies; 6+ messages in thread From: Jerry Snitselaar @ 2023-04-27 15:11 UTC (permalink / raw) To: Jarkko Sakkinen Cc: linux-integrity, linux-kernel, Peter Huewe, Jason Gunthorpe, Stefan Berger, James Bottomley, stable, Jason A . Donenfeld On Wed, Apr 26, 2023 at 08:29:27PM +0300, Jarkko Sakkinen wrote: > Before sending a TPM command, CLKRUN protocol must be disabled. This is not > done in the case of tpm1_do_selftest() call site inside tpm_tis_resume(). > > Address this by decorating the calls with tpm_chip_{start,stop}, which arm > and disarm the TPM chip for transmission, and take care of disabling and > re-enabling CLKRUN, among other things. > > Cc: stable@vger.kernel.org > Reported-by: Jason A. Donenfeld <Jason@zx2c4.com> > Link: https://lore.kernel.org/linux-integrity/CS68AWILHXS4.3M36M1EKZLUMS@suppilovahvero/ > Fixes: a3fbfae82b4c ("tpm: take TPM chip power gating out of tpm_transmit()") > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> > --- > drivers/char/tpm/tpm_tis_core.c | 43 +++++++++++++++------------------ > 1 file changed, 19 insertions(+), 24 deletions(-) Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c > index c2421162cf34..73707026e358 100644 > --- a/drivers/char/tpm/tpm_tis_core.c > +++ b/drivers/char/tpm/tpm_tis_core.c > @@ -1209,25 +1209,20 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) > u32 intmask; > int rc; > > - if (chip->ops->clk_enable != NULL) > - chip->ops->clk_enable(chip, true); > - > - /* reenable interrupts that device may have lost or > - * BIOS/firmware may have disabled > + /* > + * Re-enable interrupts that device may have lost or BIOS/firmware may > + * have disabled. > */ > rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq); > - if (rc < 0) > - goto out; > + if (rc < 0) { > + dev_err(&chip->dev, "Setting IRQ failed.\n"); > + return; > + } > > intmask = priv->int_mask | TPM_GLOBAL_INT_ENABLE; > - > - tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); > - > -out: > - if (chip->ops->clk_enable != NULL) > - chip->ops->clk_enable(chip, false); > - > - return; > + rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); > + if (rc < 0) > + dev_err(&chip->dev, "Enabling interrupts failed.\n"); > } > > int tpm_tis_resume(struct device *dev) > @@ -1235,27 +1230,27 @@ int tpm_tis_resume(struct device *dev) > struct tpm_chip *chip = dev_get_drvdata(dev); > int ret; > > - ret = tpm_tis_request_locality(chip, 0); > - if (ret < 0) > + ret = tpm_chip_start(chip); > + if (ret) > return ret; > > if (chip->flags & TPM_CHIP_FLAG_IRQ) > tpm_tis_reenable_interrupts(chip); > > - ret = tpm_pm_resume(dev); > - if (ret) > - goto out; > - > /* > * TPM 1.2 requires self-test on resume. This function actually returns > * an error code but for unknown reason it isn't handled. > */ > if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) > tpm1_do_selftest(chip); > -out: > - tpm_tis_relinquish_locality(chip, 0); > > - return ret; > + tpm_chip_stop(chip); > + > + ret = tpm_pm_resume(dev); > + if (ret) > + return ret; > + > + return 0; > } > EXPORT_SYMBOL_GPL(tpm_tis_resume); > #endif > -- > 2.39.2 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] tpm: Prevent hwrng from activating during resume 2023-04-26 17:29 [PATCH 0/2] Fix TPM 1.2 resume Jarkko Sakkinen 2023-04-26 17:29 ` [PATCH 1/2] tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume Jarkko Sakkinen @ 2023-04-26 17:29 ` Jarkko Sakkinen 2023-04-27 18:27 ` Jerry Snitselaar 1 sibling, 1 reply; 6+ messages in thread From: Jarkko Sakkinen @ 2023-04-26 17:29 UTC (permalink / raw) To: linux-integrity, linux-kernel, Peter Huewe, Jarkko Sakkinen, Jason Gunthorpe Cc: stable Set TPM_CHIP_FLAG_SUSPENDED in tpm_pm_suspend() and reset in tpm_pm_resume(). While the flag is set, tpm_hwrng() gives back zero bytes. This prevents hwrng from racing during resume. Cc: stable@vger.kernel.org Fixes: 6e592a065d51 ("tpm: Move Linux RNG connection to hwrng") Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> --- drivers/char/tpm/tpm-chip.c | 4 ++++ drivers/char/tpm/tpm-interface.c | 10 ++++++++++ include/linux/tpm.h | 13 +++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 6fdfa65a00c3..6f5ee27aeda1 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -572,6 +572,10 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) { struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); + /* Give back zero bytes, as TPM chip has not yet fully resumed: */ + if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) + return 0; + return tpm_get_random(chip, data, max); } diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 7e513b771832..0f941cb32eb1 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -412,6 +412,8 @@ int tpm_pm_suspend(struct device *dev) } suspended: + chip->flags |= TPM_CHIP_FLAG_SUSPENDED; + if (rc) dev_err(dev, "Ignoring error %d while suspending\n", rc); return 0; @@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev) if (chip == NULL) return -ENODEV; + chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED; + + /* + * Guarantee that SUSPENDED is written last, so that hwrng does not + * activate before the chip has been fully resumed. + */ + wmb(); + return 0; } EXPORT_SYMBOL_GPL(tpm_pm_resume); diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 4dc97b9f65fb..d7073dc45444 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -274,13 +274,14 @@ enum tpm2_cc_attrs { #define TPM_VID_ATML 0x1114 enum tpm_chip_flags { - TPM_CHIP_FLAG_TPM2 = BIT(1), - TPM_CHIP_FLAG_IRQ = BIT(2), - TPM_CHIP_FLAG_VIRTUAL = BIT(3), - TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), - TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), + TPM_CHIP_FLAG_SUSPENDED = BIT(0), + TPM_CHIP_FLAG_TPM2 = BIT(1), + TPM_CHIP_FLAG_IRQ = BIT(2), + TPM_CHIP_FLAG_VIRTUAL = BIT(3), + TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), + TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), - TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7), + TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7), }; #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) -- 2.39.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] tpm: Prevent hwrng from activating during resume 2023-04-26 17:29 ` [PATCH 2/2] tpm: Prevent hwrng from activating during resume Jarkko Sakkinen @ 2023-04-27 18:27 ` Jerry Snitselaar 2023-04-28 13:41 ` Jarkko Sakkinen 0 siblings, 1 reply; 6+ messages in thread From: Jerry Snitselaar @ 2023-04-27 18:27 UTC (permalink / raw) To: Jarkko Sakkinen Cc: linux-integrity, linux-kernel, Peter Huewe, Jason Gunthorpe, stable On Wed, Apr 26, 2023 at 08:29:28PM +0300, Jarkko Sakkinen wrote: > Set TPM_CHIP_FLAG_SUSPENDED in tpm_pm_suspend() and reset in > tpm_pm_resume(). While the flag is set, tpm_hwrng() gives back zero bytes. > This prevents hwrng from racing during resume. > > Cc: stable@vger.kernel.org > Fixes: 6e592a065d51 ("tpm: Move Linux RNG connection to hwrng") > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com > --- > drivers/char/tpm/tpm-chip.c | 4 ++++ > drivers/char/tpm/tpm-interface.c | 10 ++++++++++ > include/linux/tpm.h | 13 +++++++------ > 3 files changed, 21 insertions(+), 6 deletions(-) > > diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c > index 6fdfa65a00c3..6f5ee27aeda1 100644 > --- a/drivers/char/tpm/tpm-chip.c > +++ b/drivers/char/tpm/tpm-chip.c > @@ -572,6 +572,10 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) > { > struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); > > + /* Give back zero bytes, as TPM chip has not yet fully resumed: */ > + if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) > + return 0; > + > return tpm_get_random(chip, data, max); > } > > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c > index 7e513b771832..0f941cb32eb1 100644 > --- a/drivers/char/tpm/tpm-interface.c > +++ b/drivers/char/tpm/tpm-interface.c > @@ -412,6 +412,8 @@ int tpm_pm_suspend(struct device *dev) > } > > suspended: > + chip->flags |= TPM_CHIP_FLAG_SUSPENDED; > + > if (rc) > dev_err(dev, "Ignoring error %d while suspending\n", rc); > return 0; > @@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev) > if (chip == NULL) > return -ENODEV; > > + chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED; > + > + /* > + * Guarantee that SUSPENDED is written last, so that hwrng does not > + * activate before the chip has been fully resumed. > + */ > + wmb(); > + > return 0; > } > EXPORT_SYMBOL_GPL(tpm_pm_resume); > diff --git a/include/linux/tpm.h b/include/linux/tpm.h > index 4dc97b9f65fb..d7073dc45444 100644 > --- a/include/linux/tpm.h > +++ b/include/linux/tpm.h > @@ -274,13 +274,14 @@ enum tpm2_cc_attrs { > #define TPM_VID_ATML 0x1114 > > enum tpm_chip_flags { > - TPM_CHIP_FLAG_TPM2 = BIT(1), > - TPM_CHIP_FLAG_IRQ = BIT(2), > - TPM_CHIP_FLAG_VIRTUAL = BIT(3), > - TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), > - TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), > + TPM_CHIP_FLAG_SUSPENDED = BIT(0), > + TPM_CHIP_FLAG_TPM2 = BIT(1), > + TPM_CHIP_FLAG_IRQ = BIT(2), > + TPM_CHIP_FLAG_VIRTUAL = BIT(3), > + TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), > + TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), > TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), > - TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7), > + TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7), > }; > > #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) > -- > 2.39.2 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] tpm: Prevent hwrng from activating during resume 2023-04-27 18:27 ` Jerry Snitselaar @ 2023-04-28 13:41 ` Jarkko Sakkinen 0 siblings, 0 replies; 6+ messages in thread From: Jarkko Sakkinen @ 2023-04-28 13:41 UTC (permalink / raw) To: Jerry Snitselaar Cc: linux-integrity, linux-kernel, Peter Huewe, Jason Gunthorpe, stable On Thu Apr 27, 2023 at 9:27 PM EEST, Jerry Snitselaar wrote: > On Wed, Apr 26, 2023 at 08:29:28PM +0300, Jarkko Sakkinen wrote: > > Set TPM_CHIP_FLAG_SUSPENDED in tpm_pm_suspend() and reset in > > tpm_pm_resume(). While the flag is set, tpm_hwrng() gives back zero bytes. > > This prevents hwrng from racing during resume. > > > > Cc: stable@vger.kernel.org > > Fixes: 6e592a065d51 ("tpm: Move Linux RNG connection to hwrng") > > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> > > > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com Thanks Jerry! I'm planning to schedule these patches to rc2. So any tested-by's are welcome before that (I'll send it the following week of rc1 release). BR, Jarkko ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-04-28 13:41 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-26 17:29 [PATCH 0/2] Fix TPM 1.2 resume Jarkko Sakkinen
2023-04-26 17:29 ` [PATCH 1/2] tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume Jarkko Sakkinen
2023-04-27 15:11 ` Jerry Snitselaar
2023-04-26 17:29 ` [PATCH 2/2] tpm: Prevent hwrng from activating during resume Jarkko Sakkinen
2023-04-27 18:27 ` Jerry Snitselaar
2023-04-28 13:41 ` Jarkko Sakkinen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox