[SeaBIOS] Saving a few bytes across a reboot

Laszlo Ersek lersek at redhat.com
Wed Jan 10 14:22:48 CET 2018


Stefan,

On 01/09/18 20:02, Stefan Berger wrote:

> Another twist is that Intel's EDK2 also implements this but the data
> structure layout is different and they use SMM + SMIs etc.
> 
> https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81

As I described in my investigation linked from
<https://bugzilla.tianocore.org/show_bug.cgi?id=594#c5>, we should not
include the Tcg2Smm driver in OVMF, for TPM enablement -- at least for
the short & mid terms.

What does the Tcg2Smm driver do? In section (2f), I described that the
driver installs two tables, "TPM2" and an "SSDT".

- The TPM2 table from this driver is unneeded, since QEMU generates its
  own TPM2 table, which describes the TPM device's access method --
  TIS+Cancel (method 6).

- The SSDT from the driver is again unneeded. It provides (via the _DSM
  method) an ACPI-level API that the OS can use, for talking to the TPM
  device. An implementation detail of this ACPI method is that it raises
  an SMI, for entering the firmware at an elevated privilege level (= in
  SMM). Then, the actual TPM hardware manipulation, or even the TPM
  *software emulation*, is performed by the firmware, in SMM.

This approach is totally ill-suited for the QEMU virtualization stack.
For starters, none of the firmware code exist -- as open source anyway
-- that would actually handle such ACPI->SMM requests. Second, I'm sure
we don't want to debug TPM software emulation running in SMM guest
firmware, rather than an actual QEMU device model.

Once we have a real device model, accessed via IO ports and/or MMIO
locations, perhaps in combination with request/response buffers
allocated in guest RAM, the SMI/SMM implementation detail falls away
completely. Our TPM emulation would attain its "privileged / protected"
status simply by existing in the hypervisor (QEMU).

So here's what should be done:

- QEMU should implement the TPM device model, using TIS+Cancel (method
  6) or CRB (method 7). These are collectively called "dTPM".

- QEMU should continue generating a TPM2 ACPI table, for describing one
  of the above access methods to the OS, as appropriate for the actual
  device model.

- OVMF should include the following drivers from edk2, without changes:
  - Tcg2Pei/Tcg2Pei.inf
  - Tcg2Dxe/Tcg2Dxe.inf

- OVMF should include the following drivers from edk2,
  - either verbatim (if they work out like that),
  - or with small customizations (if the drivers themselves offer
    sufficiently flexible knobs),
  - or else as modules duplicated / rewritten under OvmfPkg,
  - or they might even turn out unnecessary:

  - Tcg2Config/Tcg2ConfigPei.inf
  - Tcg2Config/Tcg2ConfigDxe.inf

> QEMU would also be generating the ACPI for this UEFI I suppose. So now
> who needs to adapt to whom? And can EDK2 be adapted to do something
> different or should it remain as-is and SeaBIOS would have to work
> similarly as EDK2 does? I don't know much about SMM / SMIs and how it
> work unfortunately and whether it can work from the OS when ACPI raises
> an SMI. Any opinions ?

To be honest, I don't understand SeaBIOS's role here (beyond executing
the linker/loader script from QEMU). To my knowledge, SeaBIOS does not
intend to be a TPM client. As far as I understand, only
- UEFI applications,
- and then the OS (UEFI-based, or traditional BIOS-based)
are expected to function as TPM clients.

Under the approach described near the top,

- UEFI clients (such as UEFI boot loaders) are satisfied by the
  inclusion of the "Tcg2Dxe/Tcg2Dxe.inf" driver in OVMF -- because said
  driver produces the EFI_TCG2_PROTOCOL;

- and the OS (regardless of UEFI or traditional BIOS) is satisfied by
  finding the TPM hardware description in the TPM2 table of QEMU, and
  then by talking to the TPM device model (implemented in QEMU) with its
  own native driver.

So... I'm missing the point of the thread starter message -- "Saving a
few bytes across a reboot". Save them for what purpose?

BTW, from the "TCG PC Client Platform TPM Profile (PTP) Specification",
it seems like the FIFO (TIS) interface is hard-coded *in the spec* at
FED4_0000h – FED4_4FFFh. So we don't even have to make that dynamic.

Regarding CRB (as an alternative to TIS+Cancel), I'm trying to wrap my
brain around the exact resources that the CRB interface requries.
Marc-André, can you summarize those?

Thanks,
Laszlo



More information about the SeaBIOS mailing list