* [PATCH] tpm, tpm_tis: Workaround failed command reception on Infineon devices
@ 2025-03-06 9:00 Jonathan McDowell
2025-03-06 22:23 ` Jarkko Sakkinen
0 siblings, 1 reply; 9+ messages in thread
From: Jonathan McDowell @ 2025-03-06 9:00 UTC (permalink / raw)
To: Jarkko Sakkinen, Peter Huewe, Jason Gunthorpe, James Bottomley,
Stefan Berger
Cc: linux-integrity, linux-kernel
From: Jonathan McDowell <noodles@meta.com>
Some Infineon devices have a issue where the status register will get
stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
simply a matter of requiring a longer timeout; the work around is to
retry the command submission. Add appropriate logic to do this in the
send path.
This is fixed in later firmware revisions, but those are not always
available, and cannot generally be easily updated from outside a
firmware environment.
Testing has been performed with a simple repeated loop of doing a
TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
at:
https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
It can take several hours to reproduce, and millions of operations.
Signed-off-by: Jonathan McDowell <noodles@meta.com>
---
drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
drivers/char/tpm/tpm_tis_core.h | 1 +
include/linux/tpm.h | 1 +
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 167d71747666..e4eae206a353 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -464,7 +464,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false) < 0) {
- rc = -ETIME;
+ if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
+ rc = -EAGAIN;
+ else
+ rc = -ETIME;
goto out_err;
}
status = tpm_tis_status(chip);
@@ -481,7 +484,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false) < 0) {
- rc = -ETIME;
+ if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
+ rc = -EAGAIN;
+ else
+ rc = -ETIME;
goto out_err;
}
status = tpm_tis_status(chip);
@@ -546,9 +552,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
if (rc >= 0)
/* Data transfer done successfully */
break;
- else if (rc != -EIO)
+ else if (rc != EAGAIN && rc != -EIO)
/* Data transfer failed, not recoverable */
return rc;
+
+ usleep_range(priv->timeout_min, priv->timeout_max);
}
/* go and do it */
@@ -1144,6 +1152,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
}
+ if (priv->manufacturer_id == TPM_VID_IFX)
+ set_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags);
+
if (is_bsw()) {
priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
ILB_REMAP_SIZE);
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index 690ad8e9b731..ce97b58dc005 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -89,6 +89,7 @@ enum tpm_tis_flags {
TPM_TIS_INVALID_STATUS = 1,
TPM_TIS_DEFAULT_CANCELLATION = 2,
TPM_TIS_IRQ_TESTED = 3,
+ TPM_TIS_STATUS_WORKAROUND = 4,
};
struct tpm_tis_data {
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 20a40ade8030..6c3125300c00 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
#define TPM_VID_WINBOND 0x1050
#define TPM_VID_STM 0x104A
#define TPM_VID_ATML 0x1114
+#define TPM_VID_IFX 0x15D1
enum tpm_chip_flags {
TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
--
2.48.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-06 9:00 [PATCH] tpm, tpm_tis: Workaround failed command reception on Infineon devices Jonathan McDowell
@ 2025-03-06 22:23 ` Jarkko Sakkinen
2025-03-07 16:36 ` Jonathan McDowell
0 siblings, 1 reply; 9+ messages in thread
From: Jarkko Sakkinen @ 2025-03-06 22:23 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
On Thu, Mar 06, 2025 at 09:00:56AM +0000, Jonathan McDowell wrote:
> From: Jonathan McDowell <noodles@meta.com>
>
> Some Infineon devices have a issue where the status register will get
> stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
> simply a matter of requiring a longer timeout; the work around is to
> retry the command submission. Add appropriate logic to do this in the
> send path.
>
> This is fixed in later firmware revisions, but those are not always
> available, and cannot generally be easily updated from outside a
> firmware environment.
>
> Testing has been performed with a simple repeated loop of doing a
> TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
> at:
>
> https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
>
> It can take several hours to reproduce, and millions of operations.
>
> Signed-off-by: Jonathan McDowell <noodles@meta.com>
> ---
> drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
> drivers/char/tpm/tpm_tis_core.h | 1 +
> include/linux/tpm.h | 1 +
> 3 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 167d71747666..e4eae206a353 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -464,7 +464,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
>
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
> - rc = -ETIME;
> + if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
> + rc = -EAGAIN;
> + else
> + rc = -ETIME;
> goto out_err;
> }
> status = tpm_tis_status(chip);
> @@ -481,7 +484,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
>
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
> - rc = -ETIME;
> + if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
> + rc = -EAGAIN;
> + else
> + rc = -ETIME;
I'd encapsulate this inside wait_for_tpm_stat().
> goto out_err;
> }
> status = tpm_tis_status(chip);
> @@ -546,9 +552,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (rc >= 0)
> /* Data transfer done successfully */
> break;
> - else if (rc != -EIO)
> + else if (rc != EAGAIN && rc != -EIO)
> /* Data transfer failed, not recoverable */
> return rc;
> +
> + usleep_range(priv->timeout_min, priv->timeout_max);
> }
>
> /* go and do it */
> @@ -1144,6 +1152,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
> }
>
> + if (priv->manufacturer_id == TPM_VID_IFX)
> + set_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags);
> +
> if (is_bsw()) {
> priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
> ILB_REMAP_SIZE);
> diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
> index 690ad8e9b731..ce97b58dc005 100644
> --- a/drivers/char/tpm/tpm_tis_core.h
> +++ b/drivers/char/tpm/tpm_tis_core.h
> @@ -89,6 +89,7 @@ enum tpm_tis_flags {
> TPM_TIS_INVALID_STATUS = 1,
> TPM_TIS_DEFAULT_CANCELLATION = 2,
> TPM_TIS_IRQ_TESTED = 3,
> + TPM_TIS_STATUS_WORKAROUND = 4,
TPM_TIS_TIMEOUT_AGAIN or maybe *_REPEAT? The current name does
not tell anything.
> };
>
> struct tpm_tis_data {
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index 20a40ade8030..6c3125300c00 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
> #define TPM_VID_WINBOND 0x1050
> #define TPM_VID_STM 0x104A
> #define TPM_VID_ATML 0x1114
> +#define TPM_VID_IFX 0x15D1
>
> enum tpm_chip_flags {
> TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
> --
> 2.48.1
>
BR, Jarkko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-06 22:23 ` Jarkko Sakkinen
@ 2025-03-07 16:36 ` Jonathan McDowell
2025-03-07 16:45 ` Jarkko Sakkinen
0 siblings, 1 reply; 9+ messages in thread
From: Jonathan McDowell @ 2025-03-07 16:36 UTC (permalink / raw)
To: Jarkko Sakkinen
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
On Fri, Mar 07, 2025 at 12:23:11AM +0200, Jarkko Sakkinen wrote:
> On Thu, Mar 06, 2025 at 09:00:56AM +0000, Jonathan McDowell wrote:
> > From: Jonathan McDowell <noodles@meta.com>
> >
> > Some Infineon devices have a issue where the status register will get
> > stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
> > simply a matter of requiring a longer timeout; the work around is to
> > retry the command submission. Add appropriate logic to do this in the
> > send path.
> >
> > This is fixed in later firmware revisions, but those are not always
> > available, and cannot generally be easily updated from outside a
> > firmware environment.
> >
> > Testing has been performed with a simple repeated loop of doing a
> > TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
> > at:
> >
> > https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
> >
> > It can take several hours to reproduce, and millions of operations.
> >
> > Signed-off-by: Jonathan McDowell <noodles@meta.com>
> > ---
> > drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
> > drivers/char/tpm/tpm_tis_core.h | 1 +
> > include/linux/tpm.h | 1 +
> > 3 files changed, 16 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > index 167d71747666..e4eae206a353 100644
> > --- a/drivers/char/tpm/tpm_tis_core.c
> > +++ b/drivers/char/tpm/tpm_tis_core.c
> > @@ -464,7 +464,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> >
> > if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> > &priv->int_queue, false) < 0) {
> > - rc = -ETIME;
> > + if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
> > + rc = -EAGAIN;
> > + else
> > + rc = -ETIME;
> > goto out_err;
> > }
> > status = tpm_tis_status(chip);
> > @@ -481,7 +484,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> >
> > if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> > &priv->int_queue, false) < 0) {
> > - rc = -ETIME;
> > + if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
> > + rc = -EAGAIN;
> > + else
> > + rc = -ETIME;
>
> I'd encapsulate this inside wait_for_tpm_stat().
I think that gets a bit more complicated; this is an errata in the send
command path, for a stuck VALID bit, and the fix is to restart the whole
command send (i.e. we need to kick the TPM with tpm_tis_ready() etc).
I'm not sure returning EAGAIN in wait_for_tpm_stat() then makes
tpm_tis_send_data() any simpler.
> > goto out_err;
> > }
> > status = tpm_tis_status(chip);
> > @@ -546,9 +552,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> > if (rc >= 0)
> > /* Data transfer done successfully */
> > break;
> > - else if (rc != -EIO)
> > + else if (rc != EAGAIN && rc != -EIO)
> > /* Data transfer failed, not recoverable */
> > return rc;
> > +
> > + usleep_range(priv->timeout_min, priv->timeout_max);
> > }
> >
> > /* go and do it */
> > @@ -1144,6 +1152,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> > priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
> > }
> >
> > + if (priv->manufacturer_id == TPM_VID_IFX)
> > + set_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags);
> > +
> > if (is_bsw()) {
> > priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
> > ILB_REMAP_SIZE);
> > diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
> > index 690ad8e9b731..ce97b58dc005 100644
> > --- a/drivers/char/tpm/tpm_tis_core.h
> > +++ b/drivers/char/tpm/tpm_tis_core.h
> > @@ -89,6 +89,7 @@ enum tpm_tis_flags {
> > TPM_TIS_INVALID_STATUS = 1,
> > TPM_TIS_DEFAULT_CANCELLATION = 2,
> > TPM_TIS_IRQ_TESTED = 3,
> > + TPM_TIS_STATUS_WORKAROUND = 4,
>
> TPM_TIS_TIMEOUT_AGAIN or maybe *_REPEAT? The current name does
> not tell anything.
Yeah, TPM_TIS_STATUS_VALID_RETRY is perhaps clearer; it's not a timeout,
and we're looking to do a retry based on STS_VALID.
> > };
> >
> > struct tpm_tis_data {
> > diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> > index 20a40ade8030..6c3125300c00 100644
> > --- a/include/linux/tpm.h
> > +++ b/include/linux/tpm.h
> > @@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
> > #define TPM_VID_WINBOND 0x1050
> > #define TPM_VID_STM 0x104A
> > #define TPM_VID_ATML 0x1114
> > +#define TPM_VID_IFX 0x15D1
> >
> > enum tpm_chip_flags {
> > TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
J.
--
... "What's the philosophical difference between a killfile and the
automoderation?" "A killfile throws away good posts. Automoderation
throws away bad posts." -- Jonathan H N Chin to Calle Dybedahl
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-07 16:36 ` Jonathan McDowell
@ 2025-03-07 16:45 ` Jarkko Sakkinen
2025-03-10 12:19 ` [PATCH v2] " Jonathan McDowell
0 siblings, 1 reply; 9+ messages in thread
From: Jarkko Sakkinen @ 2025-03-07 16:45 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
On Fri, Mar 07, 2025 at 04:36:12PM +0000, Jonathan McDowell wrote:
> On Fri, Mar 07, 2025 at 12:23:11AM +0200, Jarkko Sakkinen wrote:
> > On Thu, Mar 06, 2025 at 09:00:56AM +0000, Jonathan McDowell wrote:
> > > From: Jonathan McDowell <noodles@meta.com>
> > >
> > > Some Infineon devices have a issue where the status register will get
> > > stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
> > > simply a matter of requiring a longer timeout; the work around is to
> > > retry the command submission. Add appropriate logic to do this in the
> > > send path.
> > >
> > > This is fixed in later firmware revisions, but those are not always
> > > available, and cannot generally be easily updated from outside a
> > > firmware environment.
> > >
> > > Testing has been performed with a simple repeated loop of doing a
> > > TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
> > > at:
> > >
> > > https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
> > >
> > > It can take several hours to reproduce, and millions of operations.
> > >
> > > Signed-off-by: Jonathan McDowell <noodles@meta.com>
> > > ---
> > > drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
> > > drivers/char/tpm/tpm_tis_core.h | 1 +
> > > include/linux/tpm.h | 1 +
> > > 3 files changed, 16 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > > index 167d71747666..e4eae206a353 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > @@ -464,7 +464,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> > >
> > > if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> > > &priv->int_queue, false) < 0) {
> > > - rc = -ETIME;
> > > + if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
> > > + rc = -EAGAIN;
> > > + else
> > > + rc = -ETIME;
> > > goto out_err;
> > > }
> > > status = tpm_tis_status(chip);
> > > @@ -481,7 +484,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> > >
> > > if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> > > &priv->int_queue, false) < 0) {
> > > - rc = -ETIME;
> > > + if (test_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags))
> > > + rc = -EAGAIN;
> > > + else
> > > + rc = -ETIME;
> >
> > I'd encapsulate this inside wait_for_tpm_stat().
>
> I think that gets a bit more complicated; this is an errata in the send
> command path, for a stuck VALID bit, and the fix is to restart the whole
> command send (i.e. we need to kick the TPM with tpm_tis_ready() etc).
> I'm not sure returning EAGAIN in wait_for_tpm_stat() then makes
> tpm_tis_send_data() any simpler.
OK, it is a fair argument. Let's keep it as it is.
>
> > > goto out_err;
> > > }
> > > status = tpm_tis_status(chip);
> > > @@ -546,9 +552,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> > > if (rc >= 0)
> > > /* Data transfer done successfully */
> > > break;
> > > - else if (rc != -EIO)
> > > + else if (rc != EAGAIN && rc != -EIO)
> > > /* Data transfer failed, not recoverable */
> > > return rc;
> > > +
> > > + usleep_range(priv->timeout_min, priv->timeout_max);
> > > }
> > >
> > > /* go and do it */
> > > @@ -1144,6 +1152,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> > > priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
> > > }
> > >
> > > + if (priv->manufacturer_id == TPM_VID_IFX)
> > > + set_bit(TPM_TIS_STATUS_WORKAROUND, &priv->flags);
> > > +
> > > if (is_bsw()) {
> > > priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
> > > ILB_REMAP_SIZE);
> > > diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
> > > index 690ad8e9b731..ce97b58dc005 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.h
> > > +++ b/drivers/char/tpm/tpm_tis_core.h
> > > @@ -89,6 +89,7 @@ enum tpm_tis_flags {
> > > TPM_TIS_INVALID_STATUS = 1,
> > > TPM_TIS_DEFAULT_CANCELLATION = 2,
> > > TPM_TIS_IRQ_TESTED = 3,
> > > + TPM_TIS_STATUS_WORKAROUND = 4,
> >
> > TPM_TIS_TIMEOUT_AGAIN or maybe *_REPEAT? The current name does
> > not tell anything.
>
> Yeah, TPM_TIS_STATUS_VALID_RETRY is perhaps clearer; it's not a timeout,
> and we're looking to do a retry based on STS_VALID.
WFM
>
> > > };
> > >
> > > struct tpm_tis_data {
> > > diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> > > index 20a40ade8030..6c3125300c00 100644
> > > --- a/include/linux/tpm.h
> > > +++ b/include/linux/tpm.h
> > > @@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
> > > #define TPM_VID_WINBOND 0x1050
> > > #define TPM_VID_STM 0x104A
> > > #define TPM_VID_ATML 0x1114
> > > +#define TPM_VID_IFX 0x15D1
> > >
> > > enum tpm_chip_flags {
> > > TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
>
> J.
>
> --
> ... "What's the philosophical difference between a killfile and the
> automoderation?" "A killfile throws away good posts. Automoderation
> throws away bad posts." -- Jonathan H N Chin to Calle Dybedahl
BR, Jarkko
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-07 16:45 ` Jarkko Sakkinen
@ 2025-03-10 12:19 ` Jonathan McDowell
2025-03-10 14:12 ` Paul Menzel
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Jonathan McDowell @ 2025-03-10 12:19 UTC (permalink / raw)
To: Jarkko Sakkinen
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
From: Jonathan McDowell <noodles@meta.com>
Some Infineon devices have a issue where the status register will get
stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
simply a matter of requiring a longer timeout; the work around is to
retry the command submission. Add appropriate logic to do this in the
send path.
This is fixed in later firmware revisions, but those are not always
available, and cannot generally be easily updated from outside a
firmware environment.
Testing has been performed with a simple repeated loop of doing a
TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
at:
https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
It can take several hours to reproduce, and several million operations.
Signed-off-by: Jonathan McDowell <noodles@meta.com>
---
v2: Rename flag to TPM_TIS_STATUS_VALID_RETRY
drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
drivers/char/tpm/tpm_tis_core.h | 1 +
include/linux/tpm.h | 1 +
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index c969a1793184..4ab69c3e103c 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -463,7 +463,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false) < 0) {
- rc = -ETIME;
+ if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
+ rc = -EAGAIN;
+ else
+ rc = -ETIME;
goto out_err;
}
status = tpm_tis_status(chip);
@@ -480,7 +483,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false) < 0) {
- rc = -ETIME;
+ if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
+ rc = -EAGAIN;
+ else
+ rc = -ETIME;
goto out_err;
}
status = tpm_tis_status(chip);
@@ -545,9 +551,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
if (rc >= 0)
/* Data transfer done successfully */
break;
- else if (rc != -EIO)
+ else if (rc != EAGAIN && rc != -EIO)
/* Data transfer failed, not recoverable */
return rc;
+
+ usleep_range(priv->timeout_min, priv->timeout_max);
}
/* go and do it */
@@ -1143,6 +1151,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
}
+ if (priv->manufacturer_id == TPM_VID_IFX)
+ set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags);
+
if (is_bsw()) {
priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
ILB_REMAP_SIZE);
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index 690ad8e9b731..970d02c337c7 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -89,6 +89,7 @@ enum tpm_tis_flags {
TPM_TIS_INVALID_STATUS = 1,
TPM_TIS_DEFAULT_CANCELLATION = 2,
TPM_TIS_IRQ_TESTED = 3,
+ TPM_TIS_STATUS_VALID_RETRY = 4,
};
struct tpm_tis_data {
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 20a40ade8030..6c3125300c00 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
#define TPM_VID_WINBOND 0x1050
#define TPM_VID_STM 0x104A
#define TPM_VID_ATML 0x1114
+#define TPM_VID_IFX 0x15D1
enum tpm_chip_flags {
TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
--
2.48.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-10 12:19 ` [PATCH v2] " Jonathan McDowell
@ 2025-03-10 14:12 ` Paul Menzel
2025-03-11 9:46 ` Jarkko Sakkinen
2025-03-21 16:49 ` Jonathan McDowell
2 siblings, 0 replies; 9+ messages in thread
From: Paul Menzel @ 2025-03-10 14:12 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Jarkko Sakkinen, Peter Huewe, Jason Gunthorpe, James Bottomley,
Stefan Berger, linux-integrity, linux-kernel
Dear Jonathan,
Some nits, should you resend. Feel free to ignore. The verb *work
around* is spelled with a space.
Am 10.03.25 um 13:19 schrieb Jonathan McDowell:
> From: Jonathan McDowell <noodles@meta.com>
>
> Some Infineon devices have a issue where the status register will get
> stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
> simply a matter of requiring a longer timeout; the work around is to
The noun without. ;-)
> retry the command submission. Add appropriate logic to do this in the
> send path.
Does the workaround have downsides?
> This is fixed in later firmware revisions, but those are not always
> available, and cannot generally be easily updated from outside a
> firmware environment.
Please mention the affected revisions. Is there an errata for tis.
> Testing has been performed with a simple repeated loop of doing a
> TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
> at:
>
> https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
Awesome. Thank you for sharing.
> It can take several hours to reproduce, and several million operations.
>
> Signed-off-by: Jonathan McDowell <noodles@meta.com>
> ---
> v2: Rename flag to TPM_TIS_STATUS_VALID_RETRY
>
> drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
> drivers/char/tpm/tpm_tis_core.h | 1 +
> include/linux/tpm.h | 1 +
> 3 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/
> tpm_tis_core.c
> index c969a1793184..4ab69c3e103c 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -463,7 +463,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip,
> const u8 *buf, size_t len)
>
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
> - rc = -ETIME;
> + if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
> + rc = -EAGAIN;
> + else
> + rc = -ETIME;
I’d use a ternary operator as the same variable is assigned to.
> goto out_err;
> }
> status = tpm_tis_status(chip);
> @@ -480,7 +483,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip,
> const u8 *buf, size_t len)
>
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
> - rc = -ETIME;
> + if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
> + rc = -EAGAIN;
> + else
> + rc = -ETIME;
> goto out_err;
> }
> status = tpm_tis_status(chip);
> @@ -545,9 +551,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip,
> const u8 *buf, size_t len)
> if (rc >= 0)
> /* Data transfer done successfully */
> break;
> - else if (rc != -EIO)
> + else if (rc != EAGAIN && rc != -EIO)
> /* Data transfer failed, not recoverable */
> return rc;
> +
> + usleep_range(priv->timeout_min, priv->timeout_max);
> }
>
> /* go and do it */
> @@ -1143,6 +1151,9 @@ int tpm_tis_core_init(struct device *dev, struct
> tpm_tis_data *priv, int irq,
> priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
> }
>
> + if (priv->manufacturer_id == TPM_VID_IFX)
> + set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags);
> +
> if (is_bsw()) {
> priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
> ILB_REMAP_SIZE);
> diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/
> tpm_tis_core.h
> index 690ad8e9b731..970d02c337c7 100644
> --- a/drivers/char/tpm/tpm_tis_core.h
> +++ b/drivers/char/tpm/tpm_tis_core.h
> @@ -89,6 +89,7 @@ enum tpm_tis_flags {
> TPM_TIS_INVALID_STATUS = 1,
> TPM_TIS_DEFAULT_CANCELLATION = 2,
> TPM_TIS_IRQ_TESTED = 3,
> + TPM_TIS_STATUS_VALID_RETRY = 4,
> };
>
> struct tpm_tis_data {
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index 20a40ade8030..6c3125300c00 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
> #define TPM_VID_WINBOND 0x1050
> #define TPM_VID_STM 0x104A
> #define TPM_VID_ATML 0x1114
> +#define TPM_VID_IFX 0x15D1
>
> enum tpm_chip_flags {
> TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-10 12:19 ` [PATCH v2] " Jonathan McDowell
2025-03-10 14:12 ` Paul Menzel
@ 2025-03-11 9:46 ` Jarkko Sakkinen
2025-03-21 16:49 ` Jonathan McDowell
2 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2025-03-11 9:46 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
On Mon, Mar 10, 2025 at 12:19:55PM +0000, Jonathan McDowell wrote:
> From: Jonathan McDowell <noodles@meta.com>
>
> Some Infineon devices have a issue where the status register will get
> stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
> simply a matter of requiring a longer timeout; the work around is to
> retry the command submission. Add appropriate logic to do this in the
> send path.
>
> This is fixed in later firmware revisions, but those are not always
> available, and cannot generally be easily updated from outside a
> firmware environment.
>
> Testing has been performed with a simple repeated loop of doing a
> TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
> at:
>
> https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
>
> It can take several hours to reproduce, and several million operations.
>
> Signed-off-by: Jonathan McDowell <noodles@meta.com>
> ---
> v2: Rename flag to TPM_TIS_STATUS_VALID_RETRY
>
> drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
> drivers/char/tpm/tpm_tis_core.h | 1 +
> include/linux/tpm.h | 1 +
> 3 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index c969a1793184..4ab69c3e103c 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -463,7 +463,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
> - rc = -ETIME;
> + if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
> + rc = -EAGAIN;
> + else
> + rc = -ETIME;
> goto out_err;
> }
> status = tpm_tis_status(chip);
> @@ -480,7 +483,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
> - rc = -ETIME;
> + if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
> + rc = -EAGAIN;
> + else
> + rc = -ETIME;
> goto out_err;
> }
> status = tpm_tis_status(chip);
> @@ -545,9 +551,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (rc >= 0)
> /* Data transfer done successfully */
> break;
> - else if (rc != -EIO)
> + else if (rc != EAGAIN && rc != -EIO)
> /* Data transfer failed, not recoverable */
> return rc;
> +
> + usleep_range(priv->timeout_min, priv->timeout_max);
> }
> /* go and do it */
> @@ -1143,6 +1151,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
> }
> + if (priv->manufacturer_id == TPM_VID_IFX)
> + set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags);
> +
> if (is_bsw()) {
> priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
> ILB_REMAP_SIZE);
> diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
> index 690ad8e9b731..970d02c337c7 100644
> --- a/drivers/char/tpm/tpm_tis_core.h
> +++ b/drivers/char/tpm/tpm_tis_core.h
> @@ -89,6 +89,7 @@ enum tpm_tis_flags {
> TPM_TIS_INVALID_STATUS = 1,
> TPM_TIS_DEFAULT_CANCELLATION = 2,
> TPM_TIS_IRQ_TESTED = 3,
> + TPM_TIS_STATUS_VALID_RETRY = 4,
> };
> struct tpm_tis_data {
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index 20a40ade8030..6c3125300c00 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
> #define TPM_VID_WINBOND 0x1050
> #define TPM_VID_STM 0x104A
> #define TPM_VID_ATML 0x1114
> +#define TPM_VID_IFX 0x15D1
> enum tpm_chip_flags {
> TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
> --
> 2.48.1
>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
BR, Jarkko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-10 12:19 ` [PATCH v2] " Jonathan McDowell
2025-03-10 14:12 ` Paul Menzel
2025-03-11 9:46 ` Jarkko Sakkinen
@ 2025-03-21 16:49 ` Jonathan McDowell
2025-03-22 21:10 ` Jarkko Sakkinen
2 siblings, 1 reply; 9+ messages in thread
From: Jonathan McDowell @ 2025-03-21 16:49 UTC (permalink / raw)
To: Jarkko Sakkinen
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
Jarkko, I've realised I've somehow introduced a typo in the patch below
that means it doesn't fire correctly; I'm not sure how this happened as
my local copy I was testing on is definitely correct. Would you like a
one line fix up patch, or can you manually fix it up in your tree?
This hunk:
>@@ -545,9 +551,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (rc >= 0)
> /* Data transfer done successfully */
> break;
>- else if (rc != -EIO)
>+ else if (rc != EAGAIN && rc != -EIO)
> /* Data transfer failed, not recoverable */
> return rc;
>+
>+ usleep_range(priv->timeout_min, priv->timeout_max);
> }
> /* go and do it */
should be "rc != -EAGAIN" - the "-" sign has somehow been lost.
Apologies for this, let me know what's easiest for you in terms of
resolving it.
On Mon, Mar 10, 2025 at 12:19:55PM +0000, Jonathan McDowell wrote:
>From: Jonathan McDowell <noodles@meta.com>
>
>Some Infineon devices have a issue where the status register will get
>stuck with a quick REQUEST_USE / COMMAND_READY sequence. This is not
>simply a matter of requiring a longer timeout; the work around is to
>retry the command submission. Add appropriate logic to do this in the
>send path.
>
>This is fixed in later firmware revisions, but those are not always
>available, and cannot generally be easily updated from outside a
>firmware environment.
>
>Testing has been performed with a simple repeated loop of doing a
>TPM2_CC_GET_CAPABILITY for TPM_CAP_PROP_MANUFACTURER using the Go code
>at:
>
> https://the.earth.li/~noodles/tpm-stuff/timeout-reproducer-simple.go
>
>It can take several hours to reproduce, and several million operations.
>
>Signed-off-by: Jonathan McDowell <noodles@meta.com>
>---
>v2: Rename flag to TPM_TIS_STATUS_VALID_RETRY
>
> drivers/char/tpm/tpm_tis_core.c | 17 ++++++++++++++---
> drivers/char/tpm/tpm_tis_core.h | 1 +
> include/linux/tpm.h | 1 +
> 3 files changed, 16 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
>index c969a1793184..4ab69c3e103c 100644
>--- a/drivers/char/tpm/tpm_tis_core.c
>+++ b/drivers/char/tpm/tpm_tis_core.c
>@@ -463,7 +463,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
>- rc = -ETIME;
>+ if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
>+ rc = -EAGAIN;
>+ else
>+ rc = -ETIME;
> goto out_err;
> }
> status = tpm_tis_status(chip);
>@@ -480,7 +483,10 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
> &priv->int_queue, false) < 0) {
>- rc = -ETIME;
>+ if (test_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags))
>+ rc = -EAGAIN;
>+ else
>+ rc = -ETIME;
> goto out_err;
> }
> status = tpm_tis_status(chip);
>@@ -545,9 +551,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> if (rc >= 0)
> /* Data transfer done successfully */
> break;
>- else if (rc != -EIO)
>+ else if (rc != EAGAIN && rc != -EIO)
> /* Data transfer failed, not recoverable */
> return rc;
>+
>+ usleep_range(priv->timeout_min, priv->timeout_max);
> }
> /* go and do it */
>@@ -1143,6 +1151,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
> }
>+ if (priv->manufacturer_id == TPM_VID_IFX)
>+ set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags);
>+
> if (is_bsw()) {
> priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
> ILB_REMAP_SIZE);
>diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
>index 690ad8e9b731..970d02c337c7 100644
>--- a/drivers/char/tpm/tpm_tis_core.h
>+++ b/drivers/char/tpm/tpm_tis_core.h
>@@ -89,6 +89,7 @@ enum tpm_tis_flags {
> TPM_TIS_INVALID_STATUS = 1,
> TPM_TIS_DEFAULT_CANCELLATION = 2,
> TPM_TIS_IRQ_TESTED = 3,
>+ TPM_TIS_STATUS_VALID_RETRY = 4,
> };
> struct tpm_tis_data {
>diff --git a/include/linux/tpm.h b/include/linux/tpm.h
>index 20a40ade8030..6c3125300c00 100644
>--- a/include/linux/tpm.h
>+++ b/include/linux/tpm.h
>@@ -335,6 +335,7 @@ enum tpm2_cc_attrs {
> #define TPM_VID_WINBOND 0x1050
> #define TPM_VID_STM 0x104A
> #define TPM_VID_ATML 0x1114
>+#define TPM_VID_IFX 0x15D1
> enum tpm_chip_flags {
> TPM_CHIP_FLAG_BOOTSTRAPPED = BIT(0),
>--
>2.48.1
>
>
J.
--
101 things you can't have too much of : 7 - Memory.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] tpm, tpm_tis: Workaround failed command reception on Infineon devices
2025-03-21 16:49 ` Jonathan McDowell
@ 2025-03-22 21:10 ` Jarkko Sakkinen
0 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2025-03-22 21:10 UTC (permalink / raw)
To: Jonathan McDowell
Cc: Peter Huewe, Jason Gunthorpe, James Bottomley, Stefan Berger,
linux-integrity, linux-kernel
On Fri, Mar 21, 2025 at 04:49:15PM +0000, Jonathan McDowell wrote:
> Jarkko, I've realised I've somehow introduced a typo in the patch below that
> means it doesn't fire correctly; I'm not sure how this happened as my local
> copy I was testing on is definitely correct. Would you like a one line fix
> up patch, or can you manually fix it up in your tree?
>
> This hunk:
>
> > @@ -545,9 +551,11 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> > if (rc >= 0)
> > /* Data transfer done successfully */
> > break;
> > - else if (rc != -EIO)
> > + else if (rc != EAGAIN && rc != -EIO)
> > /* Data transfer failed, not recoverable */
> > return rc;
> > +
> > + usleep_range(priv->timeout_min, priv->timeout_max);
> > }
> > /* go and do it */
>
> should be "rc != -EAGAIN" - the "-" sign has somehow been lost.
>
> Apologies for this, let me know what's easiest for you in terms of resolving
> it.
NP, I missed it too so we're in the same boat ;-)
I did:
$ git -P diff
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 4ab69c3e103c..ed0d3d8449b3 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -551,7 +551,7 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
if (rc >= 0)
/* Data transfer done successfully */
break;
- else if (rc != EAGAIN && rc != -EIO)
+ else if (rc != -EAGAIN && rc != -EIO)
/* Data transfer failed, not recoverable */
return rc;
Ping, if anything else.
BR, Jarkko
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-03-22 21:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-06 9:00 [PATCH] tpm, tpm_tis: Workaround failed command reception on Infineon devices Jonathan McDowell
2025-03-06 22:23 ` Jarkko Sakkinen
2025-03-07 16:36 ` Jonathan McDowell
2025-03-07 16:45 ` Jarkko Sakkinen
2025-03-10 12:19 ` [PATCH v2] " Jonathan McDowell
2025-03-10 14:12 ` Paul Menzel
2025-03-11 9:46 ` Jarkko Sakkinen
2025-03-21 16:49 ` Jonathan McDowell
2025-03-22 21:10 ` Jarkko Sakkinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).