Page MenuHomeFreeBSD

tpm: crb: make the Pluton startmethod more resilient
AcceptedPublic

Authored by kevans on Thu, Sep 3, 3:38 AM.
Tags
None
Referenced Files
F170334913: D59327.id185795.diff
Fri, Sep 4, 8:42 AM
F170333983: D59327.id185665.diff
Fri, Sep 4, 8:36 AM
F170314791: D59327.diff
Fri, Sep 4, 6:58 AM
Unknown Object (File)
Thu, Sep 3, 12:04 PM
Unknown Object (File)
Thu, Sep 3, 11:07 AM
Unknown Object (File)
Thu, Sep 3, 9:41 AM
Unknown Object (File)
Thu, Sep 3, 8:16 AM
Unknown Object (File)
Thu, Sep 3, 7:13 AM
Subscribers

Details

Reviewers
kbowling
chs
markj
Summary

The original implementation assumed that the start/reply doorbells
lived within the device _CRS space, but that isn't always the case. On
my AMD Ryzen 7640U-based frame.work laptop, device memory runs from
0xc0500000-0xc0500fff while the doorbells are up around 0xc0508000.

Stop sanity checking the addresses and just map them in to work reliably
whether they're within the device range or not.

pluton_wait_reply is cribbed from tpm_wait_for_u32, but rewritten
slightly to read in just one place and to read one last time before
giving up at the end of the timeout, just in case.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 76486
Build 73369: arc lint + arc unit

Event Timeline

kevans requested review of this revision.Thu, Sep 3, 3:38 AM
kbowling requested changes to this revision.Thu, Sep 3, 7:25 AM
kbowling added inline comments.
sys/dev/tpm/tpm_crb.c
694

AFAICT this lost the do not wait and can it can be flipped and returned like:

if (timeout <= 0)
        return (true);
This revision now requires changes to proceed.Thu, Sep 3, 7:25 AM
sys/dev/tpm/tpm_crb.c
694

It was somewhat intentional (I should have renamed pluton_wait_reply in this branch when I rewrote it's semantics, but it only does one trip through the loop for timeout <= 0), but it occurs to me that that was probably wrong. I would suspect there's almost never a response immediately available, though, and just returning true was maybe the right answer for those scenarios.

sys/dev/tpm/tpm_crb.c
694

Makes sense but I think you need to handle it first in pluton wait_reply?

something like:

static bool
pluton_wait_reply(struct tpmcrb_sc *crb_sc, int32_t timeout)
{
      if (timeout <= 0)
              return (true);

      do {
              if (bus_space_read_4(crb_sc->pluton.bst,
                  crb_sc->pluton.reply_bsh, 0) == 1)
                      return (true);

              pause("TPM in polling mode", 1);
              timeout -= tick;
      } while (timeout > 0);

      return (bus_space_read_4(crb_sc->pluton.bst,
          crb_sc->pluton.reply_bsh, 0) == 1);
}
kevans marked 2 inline comments as done.

review feedback: go with the first suggestion, and leave pluton_wait_reply() to
always poll for a reply at least once. The timeout == 0 case shouldn't really
happen in practice today, but it's worth defining the semantics now.

This revision is now accepted and ready to land.Fri, Sep 4, 3:38 AM