diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -217,6 +217,8 @@ .Cm com1 , com2 , com3 , and .Cm com4 , +the TPM module +.Cm tpm , the boot ROM device .Cm bootrom , the @@ -540,6 +542,23 @@ Use the host TTY device for serial port I/O. .El .Pp +TPM device backends: +.Bl -tag -width 10n +.It Ar type Ns \&, Ns Ar path Ns Op Cm \&, Ns Ar tpm-device-options +Emulate a TPM device. +.El +.Pp +The +.Ar tpm-device-options +are: +.Bl -tag -width 10n +.It Cm version= Ns Ar version +Version of the TPM device according to the TCG specification. +Defaults to +.Cm 2.0 +.El +.El +.Pp Boot ROM device backends: .Bl -tag -width 10n .It Ar romfile Ns Op Cm \&, Ns Ar varfile @@ -625,6 +644,26 @@ loader variable as described in .Xr vmm 4 . .Pp +TPM devices: +.Bl -tag -width 10n +.It Ns Ar type +Specifies the type of the TPM device. +.Pp +Supported types: +.Bl -tag -width 10n +.It Cm passthru +.El +.It Cm version= Ns Ar version +The +.Ar version +of the emulated TPM device according to the TCG specification. +.Pp +Supported versions: +.Bl -tag -width 10n +.It Cm 2.0 +.El +.El +.Pp Virtio console device backends: .Bl -bullet .Sm off diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5 --- a/usr.sbin/bhyve/bhyve_config.5 +++ b/usr.sbin/bhyve/bhyve_config.5 @@ -139,6 +139,14 @@ This value only works when loaded with UEFI mode for VNC, and used a VNC client that don't support QEMU Extended Key Event Message (e.g. TightVNC). +.It Va tpm.path Ta string Ta Ta +Path to the host TPM device. +This is typically /dev/tpm0. +.It Va tpm.type Ta string Ta Ta +Type of the TPM device passed to the guest. +.It Va tpm.version Ta string Ta 2.0 Ta +Version of the TPM device according to the TCG specification. +Currently, only version 2.0 is supported. .It Va rtc.use_localtime Ta bool Ta true Ta The real time clock uses the local time of the host. If this is set to false, the real time clock uses UTC. diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c --- a/usr.sbin/bhyve/pci_lpc.c +++ b/usr.sbin/bhyve/pci_lpc.c @@ -53,6 +53,7 @@ #include "pci_lpc.h" #include "pci_passthru.h" #include "pctestdev.h" +#include "tpm_device.h" #include "uart_emul.h" #define IO_ICU1 0x20 @@ -70,6 +71,7 @@ SYSRES_IO(NMISC_PORT, 1); static struct pci_devinst *lpc_bridge; +static struct tpm_device *lpc_tpm; #define LPC_UART_NUM 4 static struct lpc_uart_softc { @@ -97,7 +99,7 @@ { int unit, error; char *str, *cpy, *lpcdev, *node_name; - const char *romfile, *varfile; + const char *romfile, *varfile, *tpm_type, *tpm_path; error = -1; str = cpy = strdup(opts); @@ -128,6 +130,27 @@ error = 0; goto done; } + if (strcasecmp(lpcdev, "tpm") == 0) { + nvlist_t *nvl = create_config_node("tpm"); + + tpm_type = strsep(&str, ","); + if (tpm_type == NULL) { + errx(4, "invalid tpm type \"%s\"", opts); + } + set_config_value_node(nvl, "type", tpm_type); + + tpm_path = strsep(&str, ","); + if (tpm_path == NULL) { + errx(4, "invalid tpm path \"%s\"", opts); + } + set_config_value_node(nvl, "path", tpm_path); + + pci_parse_legacy_config(find_config_node("tpm"), str); + + set_config_value_node_if_unset(nvl, "version", "2.0"); + error = 0; + goto done; + } for (unit = 0; unit < LPC_UART_NUM; unit++) { if (strcasecmp(lpcdev, lpc_uart_names[unit]) == 0) { asprintf(&node_name, "lpc.%s.path", @@ -161,6 +184,7 @@ printf("bootrom\n"); for (i = 0; i < LPC_UART_NUM; i++) printf("%s\n", lpc_uart_names[i]); + printf("tpm\n"); printf("%s\n", pctestdev_getname()); } @@ -237,6 +261,7 @@ char *node_name; int unit, error; const nvlist_t *nvl; + nvlist_t *nvl_tpm; nvl = find_config_node("lpc"); if (nvl != NULL && nvlist_exists(nvl, "bootrom")) { @@ -245,6 +270,16 @@ return (error); } + nvl_tpm = find_config_node("tpm"); + if (nvl_tpm != NULL) { + error = tpm_device_create(&lpc_tpm, ctx, nvl_tpm); + if (error) { + warnx("%s: unable to create a TPM device (%d)", + __func__, error); + return (error); + } + } + /* COM1 and COM2 */ for (unit = 0; unit < LPC_UART_NUM; unit++) { sc = &lpc_uart_softc[unit];