All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-11 12:01 ` Jarkko Sakkinen
  0 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2016-10-11 12:01 UTC (permalink / raw)
  To: tpmdd-devel
  Cc: Peter Huewe, Jarkko Sakkinen, Marcel Selhorst, Jason Gunthorpe,
	open list

From: Peter Huewe <peterhuewe@gmx.de>

In some weird cases it might be possible that the TPM does not set
STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
(STS=0x0C) In this case the driver gets stuck in the while loop of
tpm_tis_send_data and loops endlessly.

Checking the return value of wait_for_tpm_stat fixes this and the driver
bails out correctly.  While at it fixing all other users since if the
TPM does not manage to set STS.VALID within the reasonable timeframe
something is definitely wrong and the driver should react correctly.

Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_tis_core.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index e3bf31b..73f4c4b 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -180,11 +180,13 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	int size = 0, burstcnt, rc;
 
-	while (size < count &&
-	       wait_for_tpm_stat(chip,
+	while (size < count) {
+		rc = wait_for_tpm_stat(chip,
 				 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 				 chip->timeout_c,
-				 &priv->read_queue, true) == 0) {
+				 &priv->read_queue, true);
+		if (rc < 0)
+			return rc;
 		burstcnt = min_t(int, get_burstcount(chip), count - size);
 
 		rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality),
@@ -229,8 +231,11 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 		goto out;
 	}
 
-	wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-			  &priv->int_queue, false);
+	if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+				&priv->int_queue, false) < 0) {
+		size = -ETIME;
+		goto out;
+	}
 	status = tpm_tis_status(chip);
 	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
 		dev_err(&chip->dev, "Error left over data\n");
@@ -279,8 +284,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 
 		count += burstcnt;
 
-		wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-				  &priv->int_queue, false);
+		if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+					&priv->int_queue, false) < 0) {
+			rc = -ETIME;
+			goto out_err;
+		}
 		status = tpm_tis_status(chip);
 		if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
 			rc = -EIO;
@@ -293,8 +301,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 	if (rc < 0)
 		goto out_err;
 
-	wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-			  &priv->int_queue, false);
+	if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+				&priv->int_queue, false) < 0) {
+		rc = -ETIME;
+		goto out_err;
+	}
 	status = tpm_tis_status(chip);
 	if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) {
 		rc = -EIO;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-11 12:01 ` Jarkko Sakkinen
  0 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2016-10-11 12:01 UTC (permalink / raw)
  To: tpmdd-devel
  Cc: Peter Huewe, Jarkko Sakkinen, Marcel Selhorst, Jason Gunthorpe,
	open list

From: Peter Huewe <peterhuewe@gmx.de>

In some weird cases it might be possible that the TPM does not set
STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
(STS=0x0C) In this case the driver gets stuck in the while loop of
tpm_tis_send_data and loops endlessly.

Checking the return value of wait_for_tpm_stat fixes this and the driver
bails out correctly.  While at it fixing all other users since if the
TPM does not manage to set STS.VALID within the reasonable timeframe
something is definitely wrong and the driver should react correctly.

Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_tis_core.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index e3bf31b..73f4c4b 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -180,11 +180,13 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	int size = 0, burstcnt, rc;
 
-	while (size < count &&
-	       wait_for_tpm_stat(chip,
+	while (size < count) {
+		rc = wait_for_tpm_stat(chip,
 				 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 				 chip->timeout_c,
-				 &priv->read_queue, true) == 0) {
+				 &priv->read_queue, true);
+		if (rc < 0)
+			return rc;
 		burstcnt = min_t(int, get_burstcount(chip), count - size);
 
 		rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality),
@@ -229,8 +231,11 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 		goto out;
 	}
 
-	wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-			  &priv->int_queue, false);
+	if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+				&priv->int_queue, false) < 0) {
+		size = -ETIME;
+		goto out;
+	}
 	status = tpm_tis_status(chip);
 	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
 		dev_err(&chip->dev, "Error left over data\n");
@@ -279,8 +284,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 
 		count += burstcnt;
 
-		wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-				  &priv->int_queue, false);
+		if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+					&priv->int_queue, false) < 0) {
+			rc = -ETIME;
+			goto out_err;
+		}
 		status = tpm_tis_status(chip);
 		if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
 			rc = -EIO;
@@ -293,8 +301,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 	if (rc < 0)
 		goto out_err;
 
-	wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-			  &priv->int_queue, false);
+	if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+				&priv->int_queue, false) < 0) {
+		rc = -ETIME;
+		goto out_err;
+	}
 	status = tpm_tis_status(chip);
 	if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) {
 		rc = -EIO;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-11 17:13   ` Jason Gunthorpe
  0 siblings, 0 replies; 9+ messages in thread
From: Jason Gunthorpe @ 2016-10-11 17:13 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel, Peter Huewe, Marcel Selhorst, open list

On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
> From: Peter Huewe <peterhuewe@gmx.de>
> 
> In some weird cases it might be possible that the TPM does not set
> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
> (STS=0x0C) In this case the driver gets stuck in the while loop of
> tpm_tis_send_data and loops endlessly.

Doesn't that exchange mean the TPM has lost synchronization with the
driver? Or maybe it crashed executing a command or something..

Please indicate what hardware is broken like this.. Or how did you get
it to do this?

Jason

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-11 17:13   ` Jason Gunthorpe
  0 siblings, 0 replies; 9+ messages in thread
From: Jason Gunthorpe @ 2016-10-11 17:13 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, open list

On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
> From: Peter Huewe <peterhuewe-Mmb7MZpHnFY@public.gmane.org>
> 
> In some weird cases it might be possible that the TPM does not set
> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
> (STS=0x0C) In this case the driver gets stuck in the while loop of
> tpm_tis_send_data and loops endlessly.

Doesn't that exchange mean the TPM has lost synchronization with the
driver? Or maybe it crashed executing a command or something..

Please indicate what hardware is broken like this.. Or how did you get
it to do this?

Jason

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-11 18:01     ` Peter Huewe
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Huewe @ 2016-10-11 18:01 UTC (permalink / raw)
  To: Jason Gunthorpe, Jarkko Sakkinen; +Cc: tpmdd-devel, Marcel Selhorst, open list



Hi
Am 11. Oktober 2016 19:13:13 MESZ, schrieb Jason Gunthorpe <jgunthorpe@obsidianresearch.com>:
>On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
>> From: Peter Huewe <peterhuewe@gmx.de>
>> 
>> In some weird cases it might be possible that the TPM does not set
>> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
>> (STS=0x0C) In this case the driver gets stuck in the while loop of
>> tpm_tis_send_data and loops endlessly.
>
>Doesn't that exchange mean the TPM has lost synchronization with the
>driver? Or maybe it crashed executing a command or something..

I saw that in the field on quite a few (similar) systems with our lpc tpms - so it affects end users.
Yes it is caused by some desynchronization or something similar.

If you manually send a commandReady by mmaping the memory region you can un-stuck the driver and the situation was never seen again on that system.

The exact reason how this happens is yet unknown, but the driver should definitely not be stuck in an endless loop (which zombies the application too) in that case but bail out as defined in the TIS protocol. The next access sends the cr which cures the unsynchronization.




Peter

-- 
Sent from my mobile

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-11 18:01     ` Peter Huewe
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Huewe @ 2016-10-11 18:01 UTC (permalink / raw)
  To: Jason Gunthorpe, Jarkko Sakkinen
  Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, open list



Hi
Am 11. Oktober 2016 19:13:13 MESZ, schrieb Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>:
>On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
>> From: Peter Huewe <peterhuewe-Mmb7MZpHnFY@public.gmane.org>
>> 
>> In some weird cases it might be possible that the TPM does not set
>> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
>> (STS=0x0C) In this case the driver gets stuck in the while loop of
>> tpm_tis_send_data and loops endlessly.
>
>Doesn't that exchange mean the TPM has lost synchronization with the
>driver? Or maybe it crashed executing a command or something..

I saw that in the field on quite a few (similar) systems with our lpc tpms - so it affects end users.
Yes it is caused by some desynchronization or something similar.

If you manually send a commandReady by mmaping the memory region you can un-stuck the driver and the situation was never seen again on that system.

The exact reason how this happens is yet unknown, but the driver should definitely not be stuck in an endless loop (which zombies the application too) in that case but bail out as defined in the TIS protocol. The next access sends the cr which cures the unsynchronization.




Peter

-- 
Sent from my mobile

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-12 12:16       ` Jarkko Sakkinen
  0 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2016-10-12 12:16 UTC (permalink / raw)
  To: Peter Huewe; +Cc: Jason Gunthorpe, tpmdd-devel, Marcel Selhorst, open list

On Tue, Oct 11, 2016 at 08:01:09PM +0200, Peter Huewe wrote:
> 
> 
> Hi
> Am 11. Oktober 2016 19:13:13 MESZ, schrieb Jason Gunthorpe <jgunthorpe@obsidianresearch.com>:
> >On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
> >> From: Peter Huewe <peterhuewe@gmx.de>
> >> 
> >> In some weird cases it might be possible that the TPM does not set
> >> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
> >> (STS=0x0C) In this case the driver gets stuck in the while loop of
> >> tpm_tis_send_data and loops endlessly.
> >
> >Doesn't that exchange mean the TPM has lost synchronization with the
> >driver? Or maybe it crashed executing a command or something..
> 
> I saw that in the field on quite a few (similar) systems with our lpc tpms - so it affects end users.
> Yes it is caused by some desynchronization or something similar.
> 
> If you manually send a commandReady by mmaping the memory region you can un-stuck the driver and the situation was never seen again on that system.
> 
> The exact reason how this happens is yet unknown, but the driver should definitely not be stuck in an endless loop (which zombies the application too) in that case but bail out as defined in the TIS protocol. The next access sends the cr which cures the unsynchronization.

Even as a sanity check return codes should be checked so in
any case I leaned towards applying this patch. It makes the
driver more robust.

/Jarkko

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
@ 2016-10-12 12:16       ` Jarkko Sakkinen
  0 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2016-10-12 12:16 UTC (permalink / raw)
  To: Peter Huewe; +Cc: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, open list

On Tue, Oct 11, 2016 at 08:01:09PM +0200, Peter Huewe wrote:
> 
> 
> Hi
> Am 11. Oktober 2016 19:13:13 MESZ, schrieb Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>:
> >On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
> >> From: Peter Huewe <peterhuewe-Mmb7MZpHnFY@public.gmane.org>
> >> 
> >> In some weird cases it might be possible that the TPM does not set
> >> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
> >> (STS=0x0C) In this case the driver gets stuck in the while loop of
> >> tpm_tis_send_data and loops endlessly.
> >
> >Doesn't that exchange mean the TPM has lost synchronization with the
> >driver? Or maybe it crashed executing a command or something..
> 
> I saw that in the field on quite a few (similar) systems with our lpc tpms - so it affects end users.
> Yes it is caused by some desynchronization or something similar.
> 
> If you manually send a commandReady by mmaping the memory region you can un-stuck the driver and the situation was never seen again on that system.
> 
> The exact reason how this happens is yet unknown, but the driver should definitely not be stuck in an endless loop (which zombies the application too) in that case but bail out as defined in the TIS protocol. The next access sends the cr which cures the unsynchronization.

Even as a sanity check return codes should be checked so in
any case I leaned towards applying this patch. It makes the
driver more robust.

/Jarkko

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] char/tpm: Check return code of wait_for_tpm_stat
  2016-10-12 12:16       ` Jarkko Sakkinen
  (?)
@ 2016-10-21 15:35       ` Jarkko Sakkinen
  -1 siblings, 0 replies; 9+ messages in thread
From: Jarkko Sakkinen @ 2016-10-21 15:35 UTC (permalink / raw)
  To: Peter Huewe; +Cc: Jason Gunthorpe, tpmdd-devel, Marcel Selhorst, open list

On Wed, Oct 12, 2016 at 03:16:06PM +0300, Jarkko Sakkinen wrote:
> On Tue, Oct 11, 2016 at 08:01:09PM +0200, Peter Huewe wrote:
> > 
> > 
> > Hi
> > Am 11. Oktober 2016 19:13:13 MESZ, schrieb Jason Gunthorpe <jgunthorpe@obsidianresearch.com>:
> > >On Tue, Oct 11, 2016 at 03:01:01PM +0300, Jarkko Sakkinen wrote:
> > >> From: Peter Huewe <peterhuewe@gmx.de>
> > >> 
> > >> In some weird cases it might be possible that the TPM does not set
> > >> STS.VALID within the given timeout time (or ever) but sets STS.EXPECT
> > >> (STS=0x0C) In this case the driver gets stuck in the while loop of
> > >> tpm_tis_send_data and loops endlessly.
> > >
> > >Doesn't that exchange mean the TPM has lost synchronization with the
> > >driver? Or maybe it crashed executing a command or something..
> > 
> > I saw that in the field on quite a few (similar) systems with our lpc tpms - so it affects end users.
> > Yes it is caused by some desynchronization or something similar.
> > 
> > If you manually send a commandReady by mmaping the memory region you can un-stuck the driver and the situation was never seen again on that system.
> > 
> > The exact reason how this happens is yet unknown, but the driver should definitely not be stuck in an endless loop (which zombies the application too) in that case but bail out as defined in the TIS protocol. The next access sends the cr which cures the unsynchronization.
> 
> Even as a sanity check return codes should be checked so in
> any case I leaned towards applying this patch. It makes the
> driver more robust.

I applied this.

/Jarkko

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-10-21 15:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-11 12:01 [PATCH] char/tpm: Check return code of wait_for_tpm_stat Jarkko Sakkinen
2016-10-11 12:01 ` Jarkko Sakkinen
2016-10-11 17:13 ` Jason Gunthorpe
2016-10-11 17:13   ` Jason Gunthorpe
2016-10-11 18:01   ` Peter Huewe
2016-10-11 18:01     ` Peter Huewe
2016-10-12 12:16     ` Jarkko Sakkinen
2016-10-12 12:16       ` Jarkko Sakkinen
2016-10-21 15:35       ` Jarkko Sakkinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.