From: Omar Sandoval <osandov@osandov.com>
To: James Bottomley <James.Bottomley@hansenpartnership.com>
Cc: Peter Huewe <peterhuewe@gmx.de>,
Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>,
Jason Gunthorpe <jgg@ziepe.ca>,
linux-integrity@vger.kernel.org
Subject: Re: [PATCH] tpm_tis: work around status register bug in STMicroelectronics TPM
Date: Wed, 15 Apr 2020 17:24:42 -0700 [thread overview]
Message-ID: <20200416002442.GB673482@vader> (raw)
In-Reply-To: <20200416001605.GA673482@vader>
[-- Attachment #1: Type: text/plain, Size: 1154 bytes --]
On Wed, Apr 15, 2020 at 05:16:05PM -0700, Omar Sandoval wrote:
> On Wed, Apr 15, 2020 at 04:51:39PM -0700, James Bottomley wrote:
> > On Wed, 2020-04-15 at 15:45 -0700, Omar Sandoval wrote:
> > > From: Omar Sandoval <osandov@fb.com>
> > >
> > > We've encountered a particular model of STMicroelectronics TPM that
> > > transiently returns a bad value in the status register. This causes
> > > the kernel to believe that the TPM is ready to receive a command when
> > > it actually isn't, which in turn causes the send to time out in
> > > get_burstcount(). In testing, reading the status register one extra
> > > time convinces the TPM to return a valid value.
> >
> > Interesting, I've got a very early upgradeable nuvoton that seems to be
> > behaving like this.
>
> I'll attach the userspace reproducer I used to figure this out. I'd be
> interested to see if it times out on your TPM, too. Note that it bangs
> on /dev/mem and assumes that the MMIO address is 0xfed40000. That seems
> to be the hard-coded address for x86 in the kernel, but just to be safe
> you might want to check `grep MSFT0101 /proc/iomem`.
Forgot to attach it, of course...
[-- Attachment #2: test_tpm_tis.c --]
[-- Type: text/plain, Size: 2123 bytes --]
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
enum tis_access {
TPM_ACCESS_VALID = 0x80,
TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
TPM_ACCESS_REQUEST_PENDING = 0x04,
TPM_ACCESS_REQUEST_USE = 0x02,
};
enum tis_status {
TPM_STS_VALID = 0x80,
TPM_STS_COMMAND_READY = 0x40,
TPM_STS_GO = 0x20,
TPM_STS_DATA_AVAIL = 0x10,
TPM_STS_DATA_EXPECT = 0x08,
};
#define TPM_ACCESS(l) (0x0000 | ((l) << 12))
#define TPM_STS(l) (0x0018 | ((l) << 12))
int main(void)
{
int fd;
void *map;
volatile uint8_t *access;
volatile uint8_t *sts;
unsigned long long i;
fd = open("/dev/mem", O_RDWR | O_DSYNC);
if (fd == -1) {
perror("open");
return EXIT_FAILURE;
}
map = mmap(NULL, 0x5000, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
0xfed40000);
if (map == MAP_FAILED) {
perror("mmap");
return EXIT_FAILURE;
}
access = (uint8_t *)map + TPM_ACCESS(0);
sts = (uint8_t *)map + TPM_STS(0);
i = 0;
for (;;) {
struct timespec stop, now;
uint32_t burstcnt;
uint8_t sts_read;
*access = TPM_ACCESS_REQUEST_USE;
while ((*access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) !=
(TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
;
sts_read = *sts;
#if 0
if (sts_read == 0xff)
sts_read = *sts;
#endif
if (!(sts_read & TPM_STS_COMMAND_READY)) {
*sts = TPM_STS_COMMAND_READY;
while (!(*sts & TPM_STS_COMMAND_READY))
;
}
clock_gettime(CLOCK_MONOTONIC, &stop);
stop.tv_sec += 1;
for (;;) {
burstcnt = ((*(volatile uint32_t *)sts) >> 8) & 0xffff;
if (burstcnt)
break;
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_sec > stop.tv_sec ||
(now.tv_sec == stop.tv_sec &&
now.tv_nsec >= stop.tv_nsec)) {
fprintf(stderr, "Timed out after %llu iterations\n", i);
i = 0;
break;
}
}
*access = TPM_ACCESS_ACTIVE_LOCALITY;
while ((*access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) !=
TPM_ACCESS_VALID)
;
i++;
}
return EXIT_SUCCESS;
}
next prev parent reply other threads:[~2020-04-16 0:24 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-15 22:45 [PATCH] tpm_tis: work around status register bug in STMicroelectronics TPM Omar Sandoval
2020-04-15 23:51 ` James Bottomley
2020-04-16 0:16 ` Omar Sandoval
2020-04-16 0:24 ` Omar Sandoval [this message]
2020-04-16 18:02 ` James Bottomley
2020-04-17 23:55 ` Jarkko Sakkinen
2020-04-18 0:12 ` James Bottomley
2020-04-20 20:46 ` Jarkko Sakkinen
2020-04-20 22:28 ` James Bottomley
2020-04-21 14:36 ` Mimi Zohar
2020-04-21 20:25 ` Jarkko Sakkinen
2020-04-21 20:31 ` Mimi Zohar
2020-04-21 20:23 ` Jarkko Sakkinen
2020-04-21 22:08 ` James Bottomley
2020-04-16 17:09 ` Jarkko Sakkinen
2020-04-16 17:56 ` James Bottomley
2020-08-27 15:24 ` Jason Andryuk
2020-08-28 23:18 ` Jarkko Sakkinen
2020-08-29 0:12 ` Jason Andryuk
2020-08-31 13:55 ` Jarkko Sakkinen
2020-09-04 12:03 ` Jarkko Sakkinen
2020-04-16 17:08 ` Jarkko Sakkinen
2020-04-16 18:54 ` Omar Sandoval
2020-04-17 23:54 ` 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=20200416002442.GB673482@vader \
--to=osandov@osandov.com \
--cc=James.Bottomley@hansenpartnership.com \
--cc=jarkko.sakkinen@linux.intel.com \
--cc=jgg@ziepe.ca \
--cc=linux-integrity@vger.kernel.org \
--cc=peterhuewe@gmx.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 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).