Page MenuHomeFreeBSD

bhyve: enable TPM2 passthrough
ClosedPublic

Authored by corvink on Nov 12 2021, 2:43 PM.
Tags
Referenced Files
Unknown Object (File)
Wed, Oct 30, 4:07 PM
Unknown Object (File)
Mon, Oct 28, 8:22 PM
Unknown Object (File)
Sun, Oct 27, 7:56 PM
Unknown Object (File)
Sat, Oct 26, 7:42 PM
Unknown Object (File)
Wed, Oct 16, 12:36 PM
Unknown Object (File)
Tue, Oct 15, 5:52 AM
Unknown Object (File)
Oct 4 2024, 9:49 AM
Unknown Object (File)
Oct 4 2024, 9:48 AM

Details

Summary

Description:
Add cmdline option for TPM emulation

How to use TPM2 passthrough:
Add -l tpm2,passthru,/dev/tpmX to your bhyve cmd line.

bhyve -c 2 -m 4G -A -H -P -w \
  -s 0,hostbridge \
  -s 4,virtio-blk,/root/win/win10.img \
  -s 5,virtio-net,tap10 \
  -s 20,xhci,tablet \
  -s 29,fbuf,tcp=0.0.0.0:5900,wait \
  -s 31,lpc \
  -l com1,stdio \
  -l bootrom,/usr/local/share/uefi-firmware/BHYVE_CODE.fd \
  -l tpm2,passthru,/dev/tpm0 \
  win10

Tested Scenarios:

OS
UbuntuWorking
WindowsWorking

Tested with Intels fTPM device.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

I understand this would probably be a thing for someone else to implement later. But allowing backing by https://github.com/stefanberger/swtpm would be a nice feature.

I understand this would probably be a thing for someone else to implement later. But allowing backing by https://github.com/stefanberger/swtpm would be a nice feature.

Thanks for that hint.
I'd like to implement a swtpm in the future. It will require some more work to do. Don't know when I'm able to do it.

This patch allows a guest direct access to the physical TPM. It doesn't emulate the TPM.

corvink edited the summary of this revision. (Show Details)
  • split into multiple commits
markj added inline comments.
usr.sbin/bhyve/bhyve.8
554
usr.sbin/bhyve/bhyve_config.5
143

This is typically /dev/tpm0?

147

Which versions are supported?

usr.sbin/bhyve/pci_lpc.c
267

Why do we hang the TPM device off of the LPC? arm64 won't have an LPC driver, but there's no reason to exclude TPM emulation/passthrough on arm64 AFAIK...

corvink added inline comments.
usr.sbin/bhyve/pci_lpc.c
267

I just needed a place to add it. Afaik, some TPMs are attached to the LPC. Where would you like to add this option?

usr.sbin/bhyve/bhyve_config.5
146

What are the valid types?

  • mention supported tpm types in man page
corvink marked an inline comment as done.
usr.sbin/bhyve/pci_lpc.c
267

@jhb @markj Where should we hang off the TPM device?

I think to address Mark's concern you would just need to have a tpm_init with the new code currently added to lpc_init. I would perhaps suggest that we need a init_devices function called from main that would call init_pci and then this new tpm_init. Eventually we might want to have a linker set or C++ constructors or something for device models to register init routines, but for now just adding a static call to tpm_init would be ok.

corvink added reviewers: jhb, markj.
  • create a init_devices and init_tpm function
In D32961#944105, @jhb wrote:

I think to address Mark's concern you would just need to have a tpm_init with the new code currently added to lpc_init. I would perhaps suggest that we need a init_devices function called from main that would call init_pci and then this new tpm_init. Eventually we might want to have a linker set or C++ constructors or something for device models to register init routines, but for now just adding a static call to tpm_init would be ok.

The latest revision of the patch gets us part of the way there, but TPM config is still a subtree of the LPC config. I am not sure what the right solution is. For arm64 I have simply been extending the -o option, so one writes -o console=stdio -o bootrom=u-boot.bin, for example. Maybe we should start adopting that for amd64 as well, handling backward compatibility? In any case, I suppose this doesn't need to block the change.

usr.sbin/bhyve/bhyverun.c
1211

The opening brace should be on its own line.

1474

IMHO there is not much use in adding this function. The perror() call below does not tell you whether init_pci() or init_tpm() failed. I would just inline it.

If there is a particular reason init_pci() needs to be called first (I don't see one?), it should be documented in a comment.

This revision is now accepted and ready to land.Aug 16 2023, 8:35 PM
This revision was automatically updated to reflect the committed changes.