All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Huewe <peterhuewe@gmx.de>
To: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>,
	Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: Andrew Lunn <andrew@lunn.ch>,
	tpmdd-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org,
	wsa@the-dreams.de, Bryan Freed <bfreed@chromium.org>
Subject: Re: [PATCH v3] tpm: Apply a sane minimum adapterlimit value for retransmission.
Date: Wed, 05 Apr 2017 12:05:32 +0200	[thread overview]
Message-ID: <384D02FC-BCCF-45F0-896D-058326EC6783@gmx.de> (raw)
In-Reply-To: <20170405090327.pssnm3mjcpajpoy6@intel.com>



Am 5. April 2017 11:03:27 MESZ schrieb Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>:
>On Tue, Mar 28, 2017 at 05:29:38PM +0200, Enric Balletbo i Serra wrote:
>> From: Bryan Freed <bfreed@chromium.org>
>> 
>> When the I2C Infineon part is attached to an I2C adapter that imposes
>> a size limitation, large requests will fail with -EOPNOTSUPP. Retry
>> them with a sane minimum size without re-issuing the 0x05 command
>> as this appears to occasionally put the TPM in a bad state.
>> 
>> Signed-off-by: Bryan Freed <bfreed@chromium.org>
>> [rework the patch to adapt to the feedback received]
>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
>> ---
>> This is a reworked version of the original patch based on the
>> suggestion made by Wolfram Sang to simply fall back to a sane minimum
>> when the maximum fails.
>> 
>> Changes since v2:
>>  - Do not remove faster transfers when chip is SLB9645 (Peter Huewe)
>>  - Remember the adapterlimit length once it fails to not generate
>extra
>>    i2c core messages (suggested by Andrew Lunn)
>> Changes since v1:
>>  - Check the correct return value (-EOPNOTSUPP instead of -EINVAL)
>>  - Fall back len to I2C_SMBUS_BLOCK_MAX if fails.
>> 
>>  drivers/char/tpm/tpm_i2c_infineon.c | 76
>+++++++++++++++++++++++++++----------
>>  1 file changed, 56 insertions(+), 20 deletions(-)
>> 
>> diff --git a/drivers/char/tpm/tpm_i2c_infineon.c
>b/drivers/char/tpm/tpm_i2c_infineon.c
>> index 62ee44e..fdefcdb 100644
>> --- a/drivers/char/tpm/tpm_i2c_infineon.c
>> +++ b/drivers/char/tpm/tpm_i2c_infineon.c
>> @@ -70,6 +70,7 @@ struct tpm_inf_dev {
>>  	u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
>>  	struct tpm_chip *chip;
>>  	enum i2c_chip_type chip_type;
>> +	unsigned int adapterlimit;
>>  };
>>  
>>  static struct tpm_inf_dev tpm_dev;
>> @@ -111,6 +112,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer,
>size_t len)
>>  
>>  	int rc = 0;
>>  	int count;
>> +	unsigned int msglen = len;
>>  
>>  	/* Lock the adapter for the duration of the whole sequence. */
>>  	if (!tpm_dev.client->adapter->algo->master_xfer)
>> @@ -131,27 +133,61 @@ static int iic_tpm_read(u8 addr, u8 *buffer,
>size_t len)
>>  			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
>>  		}
>>  	} else {
>> -		/* slb9635 protocol should work in all cases */
>> -		for (count = 0; count < MAX_COUNT; count++) {
>> -			rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
>> -			if (rc > 0)
>> -				break;	/* break here to skip sleep */
>> -
>> -			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
>> -		}
>> -
>> -		if (rc <= 0)
>> -			goto out;
>> -
>> -		/* After the TPM has successfully received the register address
>> -		 * it needs some time, thus we're sleeping here again, before
>> -		 * retrieving the data
>> +		/* Expect to send one command message and one data message, but
>> +		 * support looping over each or both if necessary.
>>  		 */
>> -		for (count = 0; count < MAX_COUNT; count++) {
>> -			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
>> -			rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
>> -			if (rc > 0)
>> -				break;
>> +		while (len > 0) {
>> +			/* slb9635 protocol should work in all cases */
>> +			for (count = 0; count < MAX_COUNT; count++) {
>> +				rc = __i2c_transfer(tpm_dev.client->adapter,
>> +						    &msg1, 1);
>> +				if (rc > 0)
>> +					break;	/* break here to skip sleep */
>> +
>> +				usleep_range(SLEEP_DURATION_LOW,
>> +					     SLEEP_DURATION_HI);
>> +			}
>> +
>> +			if (rc <= 0)
>> +				goto out;
>> +
>> +			/* After the TPM has successfully received the register
>> +			 * address it needs some time, thus we're sleeping here
>> +			 * again, before retrieving the data
>> +			 */
>> +			for (count = 0; count < MAX_COUNT; count++) {
>> +				if (tpm_dev.adapterlimit) {
>> +					msglen = min_t(unsigned int,
>> +						       tpm_dev.adapterlimit,
>> +						       len);
>> +					msg2.len = msglen;
>> +				}
>> +				usleep_range(SLEEP_DURATION_LOW,
>> +					     SLEEP_DURATION_HI);
>> +				rc = __i2c_transfer(tpm_dev.client->adapter,
>> +						    &msg2, 1);
>> +				if (rc > 0) {
>> +					/* Since len is unsigned, make doubly
>> +					 * sure we do not underflow it.
>> +					 */
>> +					if (msglen > len)
>> +						len = 0;
>> +					else
>> +						len -= msglen;
>> +					msg2.buf += msglen;
>> +					break;
>> +				}
>> +				/* If the I2C adapter rejected the request (e.g
>> +				 * when the quirk read_max_len < len) fall back
>> +				 * to a sane minimum value and try again.
>> +				 */
>> +				if (rc == -EOPNOTSUPP)
>> +					tpm_dev.adapterlimit =
>> +							I2C_SMBUS_BLOCK_MAX;
>> +			}
>> +
>> +			if (rc <= 0)
>> +				goto out;
>>  		}
>>  	}
>>  
>> -- 
>> 2.9.3
>> 
>
>Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>
>Peter, Andrew, anyone: Tested-by?
>

Not yet, I'll put it on my list to test.
Hopefully by next tuesday.
Peter

>/Jarkko

-- 
Sent from my mobile

WARNING: multiple messages have this Message-ID (diff)
From: Peter Huewe <peterhuewe-Mmb7MZpHnFY@public.gmane.org>
To: Jarkko Sakkinen
	<jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
	Enric Balletbo i Serra
	<enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
Cc: Bryan Freed <bfreed-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
	tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org
Subject: Re: [PATCH v3] tpm: Apply a sane minimum adapterlimit value for retransmission.
Date: Wed, 05 Apr 2017 12:05:32 +0200	[thread overview]
Message-ID: <384D02FC-BCCF-45F0-896D-058326EC6783@gmx.de> (raw)
In-Reply-To: <20170405090327.pssnm3mjcpajpoy6-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>



Am 5. April 2017 11:03:27 MESZ schrieb Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>:
>On Tue, Mar 28, 2017 at 05:29:38PM +0200, Enric Balletbo i Serra wrote:
>> From: Bryan Freed <bfreed-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>> 
>> When the I2C Infineon part is attached to an I2C adapter that imposes
>> a size limitation, large requests will fail with -EOPNOTSUPP. Retry
>> them with a sane minimum size without re-issuing the 0x05 command
>> as this appears to occasionally put the TPM in a bad state.
>> 
>> Signed-off-by: Bryan Freed <bfreed-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>> [rework the patch to adapt to the feedback received]
>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
>> ---
>> This is a reworked version of the original patch based on the
>> suggestion made by Wolfram Sang to simply fall back to a sane minimum
>> when the maximum fails.
>> 
>> Changes since v2:
>>  - Do not remove faster transfers when chip is SLB9645 (Peter Huewe)
>>  - Remember the adapterlimit length once it fails to not generate
>extra
>>    i2c core messages (suggested by Andrew Lunn)
>> Changes since v1:
>>  - Check the correct return value (-EOPNOTSUPP instead of -EINVAL)
>>  - Fall back len to I2C_SMBUS_BLOCK_MAX if fails.
>> 
>>  drivers/char/tpm/tpm_i2c_infineon.c | 76
>+++++++++++++++++++++++++++----------
>>  1 file changed, 56 insertions(+), 20 deletions(-)
>> 
>> diff --git a/drivers/char/tpm/tpm_i2c_infineon.c
>b/drivers/char/tpm/tpm_i2c_infineon.c
>> index 62ee44e..fdefcdb 100644
>> --- a/drivers/char/tpm/tpm_i2c_infineon.c
>> +++ b/drivers/char/tpm/tpm_i2c_infineon.c
>> @@ -70,6 +70,7 @@ struct tpm_inf_dev {
>>  	u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
>>  	struct tpm_chip *chip;
>>  	enum i2c_chip_type chip_type;
>> +	unsigned int adapterlimit;
>>  };
>>  
>>  static struct tpm_inf_dev tpm_dev;
>> @@ -111,6 +112,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer,
>size_t len)
>>  
>>  	int rc = 0;
>>  	int count;
>> +	unsigned int msglen = len;
>>  
>>  	/* Lock the adapter for the duration of the whole sequence. */
>>  	if (!tpm_dev.client->adapter->algo->master_xfer)
>> @@ -131,27 +133,61 @@ static int iic_tpm_read(u8 addr, u8 *buffer,
>size_t len)
>>  			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
>>  		}
>>  	} else {
>> -		/* slb9635 protocol should work in all cases */
>> -		for (count = 0; count < MAX_COUNT; count++) {
>> -			rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
>> -			if (rc > 0)
>> -				break;	/* break here to skip sleep */
>> -
>> -			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
>> -		}
>> -
>> -		if (rc <= 0)
>> -			goto out;
>> -
>> -		/* After the TPM has successfully received the register address
>> -		 * it needs some time, thus we're sleeping here again, before
>> -		 * retrieving the data
>> +		/* Expect to send one command message and one data message, but
>> +		 * support looping over each or both if necessary.
>>  		 */
>> -		for (count = 0; count < MAX_COUNT; count++) {
>> -			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
>> -			rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
>> -			if (rc > 0)
>> -				break;
>> +		while (len > 0) {
>> +			/* slb9635 protocol should work in all cases */
>> +			for (count = 0; count < MAX_COUNT; count++) {
>> +				rc = __i2c_transfer(tpm_dev.client->adapter,
>> +						    &msg1, 1);
>> +				if (rc > 0)
>> +					break;	/* break here to skip sleep */
>> +
>> +				usleep_range(SLEEP_DURATION_LOW,
>> +					     SLEEP_DURATION_HI);
>> +			}
>> +
>> +			if (rc <= 0)
>> +				goto out;
>> +
>> +			/* After the TPM has successfully received the register
>> +			 * address it needs some time, thus we're sleeping here
>> +			 * again, before retrieving the data
>> +			 */
>> +			for (count = 0; count < MAX_COUNT; count++) {
>> +				if (tpm_dev.adapterlimit) {
>> +					msglen = min_t(unsigned int,
>> +						       tpm_dev.adapterlimit,
>> +						       len);
>> +					msg2.len = msglen;
>> +				}
>> +				usleep_range(SLEEP_DURATION_LOW,
>> +					     SLEEP_DURATION_HI);
>> +				rc = __i2c_transfer(tpm_dev.client->adapter,
>> +						    &msg2, 1);
>> +				if (rc > 0) {
>> +					/* Since len is unsigned, make doubly
>> +					 * sure we do not underflow it.
>> +					 */
>> +					if (msglen > len)
>> +						len = 0;
>> +					else
>> +						len -= msglen;
>> +					msg2.buf += msglen;
>> +					break;
>> +				}
>> +				/* If the I2C adapter rejected the request (e.g
>> +				 * when the quirk read_max_len < len) fall back
>> +				 * to a sane minimum value and try again.
>> +				 */
>> +				if (rc == -EOPNOTSUPP)
>> +					tpm_dev.adapterlimit =
>> +							I2C_SMBUS_BLOCK_MAX;
>> +			}
>> +
>> +			if (rc <= 0)
>> +				goto out;
>>  		}
>>  	}
>>  
>> -- 
>> 2.9.3
>> 
>
>Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
>
>Peter, Andrew, anyone: Tested-by?
>

Not yet, I'll put it on my list to test.
Hopefully by next tuesday.
Peter

>/Jarkko

-- 
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

  reply	other threads:[~2017-04-05 10:06 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-28 15:29 [PATCH v3] tpm: Apply a sane minimum adapterlimit value for retransmission Enric Balletbo i Serra
2017-03-28 15:29 ` Enric Balletbo i Serra
2017-03-28 16:20 ` Andrew Lunn
2017-03-28 16:20   ` Andrew Lunn
2017-03-31  8:13 ` Jarkko Sakkinen
2017-04-05  9:03 ` Jarkko Sakkinen
2017-04-05 10:05   ` Peter Huewe [this message]
2017-04-05 10:05     ` Peter Huewe
2017-04-05 13:37     ` Jarkko Sakkinen
2017-04-05 13:37       ` Jarkko Sakkinen
2017-04-05 13:24   ` Andrew Lunn
2017-04-05 13:24     ` Andrew Lunn
2017-04-05 13:35     ` Jarkko Sakkinen
2017-04-05 13:35       ` Jarkko Sakkinen
2017-05-22  9:20 Enric Balletbo i Serra
2017-05-24 19:10 ` Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=384D02FC-BCCF-45F0-896D-058326EC6783@gmx.de \
    --to=peterhuewe@gmx.de \
    --cc=andrew@lunn.ch \
    --cc=bfreed@chromium.org \
    --cc=enric.balletbo@collabora.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tpmdd-devel@lists.sourceforge.net \
    --cc=wsa@the-dreams.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.