All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
@ 2017-04-26 10:41 Jarkko Sakkinen
  2017-04-26 11:50 ` Maciej S. Szmigiero
  0 siblings, 1 reply; 7+ messages in thread
From: Jarkko Sakkinen @ 2017-04-26 10:41 UTC (permalink / raw)
  To: mail; +Cc: stable, Jarkko Sakkinen

From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>

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.

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>
---
Backport of 1d70fe9d9c3a4 to v4.9
PS. I was not able to test this. Tried to check that diff is the same.
 drivers/char/tpm/tpm-interface.c | 54 ++++++++++++++++++++++++----------------
 drivers/char/tpm/tpm_tis.c       |  2 +-
 drivers/char/tpm/tpm_tis_core.c  |  6 ++---
 drivers/char/tpm/tpm_tis_core.h  |  2 +-
 4 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 3a9149cf0110..9788f839bb7c 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -488,10 +488,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
 
 int tpm_get_timeouts(struct tpm_chip *chip)
 {
+	cap_t cap;
 	struct tpm_cmd_t tpm_cmd;
-	unsigned long new_timeout[4];
-	unsigned long old_timeout[4];
 	struct duration_t *duration_cap;
+	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
 	ssize_t rc;
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
@@ -542,11 +542,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
 		return -EINVAL;
 
-	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
-	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
-	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
-	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
-	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
+	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
+	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
+	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
+	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
+	timeout_chip[0] = be32_to_cpu(cap.timeout.a);
+	timeout_chip[1] = be32_to_cpu(cap.timeout.b);
+	timeout_chip[2] = be32_to_cpu(cap.timeout.c);
+	timeout_chip[3] = be32_to_cpu(cap.timeout.d);
+	memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff));
 
 	/*
 	 * Provide ability for vendor overrides of timeout values in case
@@ -554,16 +558,24 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	 */
 	if (chip->ops->update_timeouts != NULL)
 		chip->timeout_adjusted =
-			chip->ops->update_timeouts(chip, new_timeout);
+			chip->ops->update_timeouts(chip, timeout_eff);
 
 	if (!chip->timeout_adjusted) {
-		/* Don't overwrite default if value is 0 */
-		if (new_timeout[0] != 0 && new_timeout[0] < 1000) {
-			int i;
+		/* Restore default if chip reported 0 */
+		int i;
 
+		for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) {
+			if (timeout_eff[i])
+				continue;
+
+			timeout_eff[i] = timeout_old[i];
+			chip->timeout_adjusted = true;
+		}
+
+		if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) {
 			/* timeouts in msec rather usec */
-			for (i = 0; i != ARRAY_SIZE(new_timeout); i++)
-				new_timeout[i] *= 1000;
+			for (i = 0; i != ARRAY_SIZE(timeout_eff); i++)
+				timeout_eff[i] *= 1000;
 			chip->timeout_adjusted = true;
 		}
 	}
@@ -572,16 +584,16 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	if (chip->timeout_adjusted) {
 		dev_info(&chip->dev,
 			 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
-			 old_timeout[0], new_timeout[0],
-			 old_timeout[1], new_timeout[1],
-			 old_timeout[2], new_timeout[2],
-			 old_timeout[3], new_timeout[3]);
+			 timeout_chip[0], timeout_eff[0],
+			 timeout_chip[1], timeout_eff[1],
+			 timeout_chip[2], timeout_eff[2],
+			 timeout_chip[3], timeout_eff[3]);
 	}
 
-	chip->timeout_a = usecs_to_jiffies(new_timeout[0]);
-	chip->timeout_b = usecs_to_jiffies(new_timeout[1]);
-	chip->timeout_c = usecs_to_jiffies(new_timeout[2]);
-	chip->timeout_d = usecs_to_jiffies(new_timeout[3]);
+	chip->timeout_a = usecs_to_jiffies(timeout_eff[0]);
+	chip->timeout_b = usecs_to_jiffies(timeout_eff[1]);
+	chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
+	chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);
 
 duration:
 	tpm_cmd.header.in = tpm_getcap_header;
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index eaf5730d79eb..a5abcdc9655b 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -157,7 +157,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 		irq = tpm_info->irq;
 
 	if (itpm)
-		phy->priv.flags |= TPM_TIS_ITPM_POSSIBLE;
+		phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND;
 
 	return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg,
 				 acpi_dev_handle);
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index e3bf31b37138..44e0ef479962 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -254,7 +254,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	int rc, status, burstcnt;
 	size_t count = 0;
-	bool itpm = priv->flags & TPM_TIS_ITPM_POSSIBLE;
+	bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND;
 
 	if (request_locality(chip, 0) < 0)
 		return -EBUSY;
@@ -718,7 +718,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		 (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2",
 		 vendor >> 16, rid);
 
-	if (!(priv->flags & TPM_TIS_ITPM_POSSIBLE)) {
+	if (!(priv->flags & TPM_TIS_ITPM_WORKAROUND)) {
 		probe = probe_itpm(chip);
 		if (probe < 0) {
 			rc = -ENODEV;
@@ -726,7 +726,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		}
 
 		if (!!probe)
-			priv->flags |= TPM_TIS_ITPM_POSSIBLE;
+			priv->flags |= TPM_TIS_ITPM_WORKAROUND;
 	}
 
 	/* Figure out the capabilities */
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index 9191aabbf9c2..e2212f021a02 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -80,7 +80,7 @@ enum tis_defaults {
 #define	TPM_RID(l)			(0x0F04 | ((l) << 12))
 
 enum tpm_tis_flags {
-	TPM_TIS_ITPM_POSSIBLE		= BIT(0),
+	TPM_TIS_ITPM_WORKAROUND		= BIT(0),
 };
 
 struct tpm_tis_data {
-- 
2.11.0


--amizlheiox3i4xbq--

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

* Re: [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
  2017-04-26 10:41 [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero Jarkko Sakkinen
@ 2017-04-26 11:50 ` Maciej S. Szmigiero
  2017-04-28 11:54   ` Jarkko Sakkinen
  0 siblings, 1 reply; 7+ messages in thread
From: Maciej S. Szmigiero @ 2017-04-26 11:50 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: stable

Jarkko,

I've sent you my comments to this backport on 2017.04.25 00:01:40 +0200.

Since it looks like you didn't get that message I will write them again
below, inline with the patch.

Maciej

On 04/26/17 12:41, Jarkko Sakkinen wrote:
> From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
> 
> 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.
> 
> 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>
> ---
> Backport of 1d70fe9d9c3a4 to v4.9
> PS. I was not able to test this. Tried to check that diff is the same.
>  drivers/char/tpm/tpm-interface.c | 54 ++++++++++++++++++++++++----------------
>  drivers/char/tpm/tpm_tis.c       |  2 +-
>  drivers/char/tpm/tpm_tis_core.c  |  6 ++---
>  drivers/char/tpm/tpm_tis_core.h  |  2 +-
>  4 files changed, 38 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index 3a9149cf0110..9788f839bb7c 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -488,10 +488,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
>  
>  int tpm_get_timeouts(struct tpm_chip *chip)
>  {
> +	cap_t cap;

This is not needed.

>  	struct tpm_cmd_t tpm_cmd;
> -	unsigned long new_timeout[4];
> -	unsigned long old_timeout[4];
>  	struct duration_t *duration_cap;
> +	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
>  	ssize_t rc;
>  
>  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> @@ -542,11 +542,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
>  		return -EINVAL;
>  
> -	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
> -	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
> -	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
> -	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
> -	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
> +	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
> +	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
> +	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
> +	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
> +	timeout_chip[0] = be32_to_cpu(cap.timeout.a);
> +	timeout_chip[1] = be32_to_cpu(cap.timeout.b);
> +	timeout_chip[2] = be32_to_cpu(cap.timeout.c);
> +	timeout_chip[3] = be32_to_cpu(cap.timeout.d);

These last 4 lines should be "= be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.X")
as in the removed ones.

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

* Re: [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
  2017-04-26 11:50 ` Maciej S. Szmigiero
@ 2017-04-28 11:54   ` Jarkko Sakkinen
  2017-04-28 22:32     ` Maciej S. Szmigiero
  0 siblings, 1 reply; 7+ messages in thread
From: Jarkko Sakkinen @ 2017-04-28 11:54 UTC (permalink / raw)
  To: Maciej S. Szmigiero; +Cc: stable

On Wed, Apr 26, 2017 at 01:50:08PM +0200, Maciej S. Szmigiero wrote:
> Jarkko,
> 
> I've sent you my comments to this backport on 2017.04.25 00:01:40 +0200.
> 
> Since it looks like you didn't get that message I will write them again
> below, inline with the patch.
> 
> Maciej
> 
> On 04/26/17 12:41, Jarkko Sakkinen wrote:
> > From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
> > 
> > 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.
> > 
> > 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>
> > ---
> > Backport of 1d70fe9d9c3a4 to v4.9
> > PS. I was not able to test this. Tried to check that diff is the same.
> >  drivers/char/tpm/tpm-interface.c | 54 ++++++++++++++++++++++++----------------
> >  drivers/char/tpm/tpm_tis.c       |  2 +-
> >  drivers/char/tpm/tpm_tis_core.c  |  6 ++---
> >  drivers/char/tpm/tpm_tis_core.h  |  2 +-
> >  4 files changed, 38 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> > index 3a9149cf0110..9788f839bb7c 100644
> > --- a/drivers/char/tpm/tpm-interface.c
> > +++ b/drivers/char/tpm/tpm-interface.c
> > @@ -488,10 +488,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
> >  
> >  int tpm_get_timeouts(struct tpm_chip *chip)
> >  {
> > +	cap_t cap;
> 
> This is not needed.
> 
> >  	struct tpm_cmd_t tpm_cmd;
> > -	unsigned long new_timeout[4];
> > -	unsigned long old_timeout[4];
> >  	struct duration_t *duration_cap;
> > +	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
> >  	ssize_t rc;
> >  
> >  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> > @@ -542,11 +542,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
> >  	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
> >  		return -EINVAL;
> >  
> > -	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
> > -	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
> > -	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
> > -	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
> > -	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
> > +	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
> > +	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
> > +	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
> > +	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
> > +	timeout_chip[0] = be32_to_cpu(cap.timeout.a);
> > +	timeout_chip[1] = be32_to_cpu(cap.timeout.b);
> > +	timeout_chip[2] = be32_to_cpu(cap.timeout.c);
> > +	timeout_chip[3] = be32_to_cpu(cap.timeout.d);
> 
> These last 4 lines should be "= be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.X")
> as in the removed ones.

Gah. The problem is that I do not have means to test this patch
with HW where it occured. Can you send an updated version to
stable as you have means to test it? Thank you.

/Jarkko

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

* Re: [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
  2017-04-28 11:54   ` Jarkko Sakkinen
@ 2017-04-28 22:32     ` Maciej S. Szmigiero
  2017-04-29 11:18       ` Jarkko Sakkinen
  0 siblings, 1 reply; 7+ messages in thread
From: Maciej S. Szmigiero @ 2017-04-28 22:32 UTC (permalink / raw)
  To: Jarkko Sakkinen; +Cc: stable

On 04/28/17 13:54, Jarkko Sakkinen wrote:
> On Wed, Apr 26, 2017 at 01:50:08PM +0200, Maciej S. Szmigiero wrote:
>> Jarkko,
>>
>> I've sent you my comments to this backport on 2017.04.25 00:01:40 +0200.
>>
>> Since it looks like you didn't get that message I will write them again
>> below, inline with the patch.
>>
>> Maciej
>>
>> On 04/26/17 12:41, Jarkko Sakkinen wrote:
>>> From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
>>>
>>> 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.
>>>
>>> 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>
>>> ---
>>> Backport of 1d70fe9d9c3a4 to v4.9
>>> PS. I was not able to test this. Tried to check that diff is the same.
>>>  drivers/char/tpm/tpm-interface.c | 54 ++++++++++++++++++++++++----------------
>>>  drivers/char/tpm/tpm_tis.c       |  2 +-
>>>  drivers/char/tpm/tpm_tis_core.c  |  6 ++---
>>>  drivers/char/tpm/tpm_tis_core.h  |  2 +-
>>>  4 files changed, 38 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
>>> index 3a9149cf0110..9788f839bb7c 100644
>>> --- a/drivers/char/tpm/tpm-interface.c
>>> +++ b/drivers/char/tpm/tpm-interface.c
>>> @@ -488,10 +488,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
>>>  
>>>  int tpm_get_timeouts(struct tpm_chip *chip)
>>>  {
>>> +	cap_t cap;
>>
>> This is not needed.
>>
>>>  	struct tpm_cmd_t tpm_cmd;
>>> -	unsigned long new_timeout[4];
>>> -	unsigned long old_timeout[4];
>>>  	struct duration_t *duration_cap;
>>> +	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
>>>  	ssize_t rc;
>>>  
>>>  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
>>> @@ -542,11 +542,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>>>  	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
>>>  		return -EINVAL;
>>>  
>>> -	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
>>> -	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
>>> -	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
>>> -	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
>>> -	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
>>> +	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
>>> +	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
>>> +	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
>>> +	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
>>> +	timeout_chip[0] = be32_to_cpu(cap.timeout.a);
>>> +	timeout_chip[1] = be32_to_cpu(cap.timeout.b);
>>> +	timeout_chip[2] = be32_to_cpu(cap.timeout.c);
>>> +	timeout_chip[3] = be32_to_cpu(cap.timeout.d);
>>
>> These last 4 lines should be "= be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.X")
>> as in the removed ones.
> 
> Gah. The problem is that I do not have means to test this patch
> with HW where it occured. Can you send an updated version to
> stable as you have means to test it? Thank you.

Yes, I can do it but it might take a few days.

> /Jarkko

Maciej

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

* Re: [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
  2017-04-28 22:32     ` Maciej S. Szmigiero
@ 2017-04-29 11:18       ` Jarkko Sakkinen
  0 siblings, 0 replies; 7+ messages in thread
From: Jarkko Sakkinen @ 2017-04-29 11:18 UTC (permalink / raw)
  To: Maciej S. Szmigiero; +Cc: stable

On Sat, Apr 29, 2017 at 12:32:54AM +0200, Maciej S. Szmigiero wrote:
> On 04/28/17 13:54, Jarkko Sakkinen wrote:
> > On Wed, Apr 26, 2017 at 01:50:08PM +0200, Maciej S. Szmigiero wrote:
> >> Jarkko,
> >>
> >> I've sent you my comments to this backport on 2017.04.25 00:01:40 +0200.
> >>
> >> Since it looks like you didn't get that message I will write them again
> >> below, inline with the patch.
> >>
> >> Maciej
> >>
> >> On 04/26/17 12:41, Jarkko Sakkinen wrote:
> >>> From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
> >>>
> >>> 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.
> >>>
> >>> 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>
> >>> ---
> >>> Backport of 1d70fe9d9c3a4 to v4.9
> >>> PS. I was not able to test this. Tried to check that diff is the same.
> >>>  drivers/char/tpm/tpm-interface.c | 54 ++++++++++++++++++++++++----------------
> >>>  drivers/char/tpm/tpm_tis.c       |  2 +-
> >>>  drivers/char/tpm/tpm_tis_core.c  |  6 ++---
> >>>  drivers/char/tpm/tpm_tis_core.h  |  2 +-
> >>>  4 files changed, 38 insertions(+), 26 deletions(-)
> >>>
> >>> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> >>> index 3a9149cf0110..9788f839bb7c 100644
> >>> --- a/drivers/char/tpm/tpm-interface.c
> >>> +++ b/drivers/char/tpm/tpm-interface.c
> >>> @@ -488,10 +488,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
> >>>  
> >>>  int tpm_get_timeouts(struct tpm_chip *chip)
> >>>  {
> >>> +	cap_t cap;
> >>
> >> This is not needed.
> >>
> >>>  	struct tpm_cmd_t tpm_cmd;
> >>> -	unsigned long new_timeout[4];
> >>> -	unsigned long old_timeout[4];
> >>>  	struct duration_t *duration_cap;
> >>> +	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
> >>>  	ssize_t rc;
> >>>  
> >>>  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> >>> @@ -542,11 +542,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
> >>>  	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
> >>>  		return -EINVAL;
> >>>  
> >>> -	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
> >>> -	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
> >>> -	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
> >>> -	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
> >>> -	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
> >>> +	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
> >>> +	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
> >>> +	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
> >>> +	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
> >>> +	timeout_chip[0] = be32_to_cpu(cap.timeout.a);
> >>> +	timeout_chip[1] = be32_to_cpu(cap.timeout.b);
> >>> +	timeout_chip[2] = be32_to_cpu(cap.timeout.c);
> >>> +	timeout_chip[3] = be32_to_cpu(cap.timeout.d);
> >>
> >> These last 4 lines should be "= be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.X")
> >> as in the removed ones.
> > 
> > Gah. The problem is that I do not have means to test this patch
> > with HW where it occured. Can you send an updated version to
> > stable as you have means to test it? Thank you.
> 
> Yes, I can do it but it might take a few days.

Sorry for these confusing patches but it's too easy to fsck up
if you have to do things blind :-) Thank you, I appreciate this!

/Jarkko

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

* Re: [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
  2017-05-02 22:34 Maciej S. Szmigiero
@ 2017-05-03 12:50 ` Jarkko Sakkinen
  0 siblings, 0 replies; 7+ messages in thread
From: Jarkko Sakkinen @ 2017-05-03 12:50 UTC (permalink / raw)
  To: Maciej S. Szmigiero; +Cc: stable, tpmdd-devel

On Wed, May 03, 2017 at 12:34:08AM +0200, Maciej S. Szmigiero wrote:
> 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.
> 
> Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
> Cc: <stable@vger.kernel.org> # 4.9.x

Thanks for doing this and sorry for messing things up, not one,
but *two* times.

Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

/Jarkko

> ---
>  drivers/char/tpm/tpm-interface.c | 53 ++++++++++++++++++++++++----------------
>  1 file 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)
>  int tpm_get_timeouts(struct tpm_chip *chip)
>  {
>  	struct tpm_cmd_t tpm_cmd;
> -	unsigned long new_timeout[4];
> -	unsigned long old_timeout[4];
> +	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
>  	struct duration_t *duration_cap;
>  	ssize_t rc;
>  
> @@ -542,11 +541,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
>  		return -EINVAL;
>  
> -	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
> -	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
> -	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
> -	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
> -	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
> +	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
> +	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
> +	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
> +	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
> +	timeout_chip[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
> +	timeout_chip[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
> +	timeout_chip[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
> +	timeout_chip[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
> +	memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff));
>  
>  	/*
>  	 * Provide ability for vendor overrides of timeout values in case
> @@ -554,16 +557,24 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  	 */
>  	if (chip->ops->update_timeouts != NULL)
>  		chip->timeout_adjusted =
> -			chip->ops->update_timeouts(chip, new_timeout);
> +			chip->ops->update_timeouts(chip, timeout_eff);
>  
>  	if (!chip->timeout_adjusted) {
> -		/* Don't overwrite default if value is 0 */
> -		if (new_timeout[0] != 0 && new_timeout[0] < 1000) {
> -			int i;
> +		/* Restore default if chip reported 0 */
> +		int i;
>  
> +		for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) {
> +			if (timeout_eff[i])
> +				continue;
> +
> +			timeout_eff[i] = timeout_old[i];
> +			chip->timeout_adjusted = true;
> +		}
> +
> +		if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) {
>  			/* timeouts in msec rather usec */
> -			for (i = 0; i != ARRAY_SIZE(new_timeout); i++)
> -				new_timeout[i] *= 1000;
> +			for (i = 0; i != ARRAY_SIZE(timeout_eff); i++)
> +				timeout_eff[i] *= 1000;
>  			chip->timeout_adjusted = true;
>  		}
>  	}
> @@ -572,16 +583,16 @@ int tpm_get_timeouts(struct tpm_chip *chip)
>  	if (chip->timeout_adjusted) {
>  		dev_info(&chip->dev,
>  			 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
> -			 old_timeout[0], new_timeout[0],
> -			 old_timeout[1], new_timeout[1],
> -			 old_timeout[2], new_timeout[2],
> -			 old_timeout[3], new_timeout[3]);
> +			 timeout_chip[0], timeout_eff[0],
> +			 timeout_chip[1], timeout_eff[1],
> +			 timeout_chip[2], timeout_eff[2],
> +			 timeout_chip[3], timeout_eff[3]);
>  	}
>  
> -	chip->timeout_a = usecs_to_jiffies(new_timeout[0]);
> -	chip->timeout_b = usecs_to_jiffies(new_timeout[1]);
> -	chip->timeout_c = usecs_to_jiffies(new_timeout[2]);
> -	chip->timeout_d = usecs_to_jiffies(new_timeout[3]);
> +	chip->timeout_a = usecs_to_jiffies(timeout_eff[0]);
> +	chip->timeout_b = usecs_to_jiffies(timeout_eff[1]);
> +	chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
> +	chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);
>  
>  duration:
>  	tpm_cmd.header.in = tpm_getcap_header;

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

* [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero
@ 2017-05-02 22:34 Maciej S. Szmigiero
  2017-05-03 12:50 ` Jarkko Sakkinen
  0 siblings, 1 reply; 7+ messages in thread
From: Maciej S. Szmigiero @ 2017-05-02 22:34 UTC (permalink / raw)
  To: stable; +Cc: Jarkko Sakkinen, tpmdd-devel

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.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Cc: <stable@vger.kernel.org> # 4.9.x
---
 drivers/char/tpm/tpm-interface.c | 53 ++++++++++++++++++++++++----------------
 1 file 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)
 int tpm_get_timeouts(struct tpm_chip *chip)
 {
 	struct tpm_cmd_t tpm_cmd;
-	unsigned long new_timeout[4];
-	unsigned long old_timeout[4];
+	unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
 	struct duration_t *duration_cap;
 	ssize_t rc;
 
@@ -542,11 +541,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
 		return -EINVAL;
 
-	old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
-	old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
-	old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
-	old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
-	memcpy(new_timeout, old_timeout, sizeof(new_timeout));
+	timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
+	timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
+	timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
+	timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
+	timeout_chip[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
+	timeout_chip[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
+	timeout_chip[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
+	timeout_chip[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
+	memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff));
 
 	/*
 	 * Provide ability for vendor overrides of timeout values in case
@@ -554,16 +557,24 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	 */
 	if (chip->ops->update_timeouts != NULL)
 		chip->timeout_adjusted =
-			chip->ops->update_timeouts(chip, new_timeout);
+			chip->ops->update_timeouts(chip, timeout_eff);
 
 	if (!chip->timeout_adjusted) {
-		/* Don't overwrite default if value is 0 */
-		if (new_timeout[0] != 0 && new_timeout[0] < 1000) {
-			int i;
+		/* Restore default if chip reported 0 */
+		int i;
 
+		for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) {
+			if (timeout_eff[i])
+				continue;
+
+			timeout_eff[i] = timeout_old[i];
+			chip->timeout_adjusted = true;
+		}
+
+		if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) {
 			/* timeouts in msec rather usec */
-			for (i = 0; i != ARRAY_SIZE(new_timeout); i++)
-				new_timeout[i] *= 1000;
+			for (i = 0; i != ARRAY_SIZE(timeout_eff); i++)
+				timeout_eff[i] *= 1000;
 			chip->timeout_adjusted = true;
 		}
 	}
@@ -572,16 +583,16 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	if (chip->timeout_adjusted) {
 		dev_info(&chip->dev,
 			 HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
-			 old_timeout[0], new_timeout[0],
-			 old_timeout[1], new_timeout[1],
-			 old_timeout[2], new_timeout[2],
-			 old_timeout[3], new_timeout[3]);
+			 timeout_chip[0], timeout_eff[0],
+			 timeout_chip[1], timeout_eff[1],
+			 timeout_chip[2], timeout_eff[2],
+			 timeout_chip[3], timeout_eff[3]);
 	}
 
-	chip->timeout_a = usecs_to_jiffies(new_timeout[0]);
-	chip->timeout_b = usecs_to_jiffies(new_timeout[1]);
-	chip->timeout_c = usecs_to_jiffies(new_timeout[2]);
-	chip->timeout_d = usecs_to_jiffies(new_timeout[3]);
+	chip->timeout_a = usecs_to_jiffies(timeout_eff[0]);
+	chip->timeout_b = usecs_to_jiffies(timeout_eff[1]);
+	chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
+	chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);
 
 duration:
 	tpm_cmd.header.in = tpm_getcap_header;

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

end of thread, other threads:[~2017-05-03 12:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-26 10:41 [PATCH v4.9 backport] tpm_tis: use default timeout value if chip reports it as zero Jarkko Sakkinen
2017-04-26 11:50 ` Maciej S. Szmigiero
2017-04-28 11:54   ` Jarkko Sakkinen
2017-04-28 22:32     ` Maciej S. Szmigiero
2017-04-29 11:18       ` Jarkko Sakkinen
2017-05-02 22:34 Maciej S. Szmigiero
2017-05-03 12:50 ` 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.