aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2020-03-05 17:51:45 +0100
committerStefan Berger <stefanb@linux.vnet.ibm.com>2020-03-05 12:18:16 -0500
commitc294ac327ca99342b90bd3a83d2cef9b447afaa7 (patch)
tree108470da44a990530432574fe884aab807baee73
parent229de57ac50a1677879f38b98243b2d6d5e2c11b (diff)
hw/arm/virt: vTPM support
Let the TPM TIS SYSBUS device be dynamically instantiable in ARM virt. A device tree node is dynamically created (TPM via MMIO). The TPM Physical Presence interface (PPI) is not supported. To run with the swtmp TPM emulator, the qemu command line must be augmented with: -chardev socket,id=chrtpm,path=swtpm-sock \ -tpmdev emulator,id=tpm0,chardev=chrtpm \ -device tpm-tis-device,tpmdev=tpm0 \ swtpm/libtpms command line example: swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \ --ctrl type=unixio,path=swtpm-sock Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Message-id: 20200305165149.618-7-eric.auger@redhat.com Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
-rw-r--r--hw/arm/Kconfig1
-rw-r--r--hw/arm/sysbus-fdt.c33
-rw-r--r--hw/arm/virt.c7
3 files changed, 41 insertions, 0 deletions
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 61635f52c4..bc54fd61f9 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM_VIRT
imply VFIO_AMD_XGBE
imply VFIO_PLATFORM
imply VFIO_XGMAC
+ imply TPM_TIS_SYSBUS
select A15MPCORE
select ACPI
select ARM_SMMUV3
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 022fc97ecd..6b6906f4cf 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -30,6 +30,7 @@
#include "hw/arm/sysbus-fdt.h"
#include "qemu/error-report.h"
#include "sysemu/device_tree.h"
+#include "sysemu/tpm.h"
#include "hw/platform-bus.h"
#include "hw/vfio/vfio-platform.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
@@ -436,6 +437,37 @@ static bool vfio_platform_match(SysBusDevice *sbdev,
#endif /* CONFIG_LINUX */
+/*
+ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS
+ *
+ * See kernel documentation:
+ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
+ * Optional interrupt for command completion is not exposed
+ */
+static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+ PlatformBusFDTData *data = opaque;
+ PlatformBusDevice *pbus = data->pbus;
+ void *fdt = data->fdt;
+ const char *parent_node = data->pbus_node_name;
+ char *nodename;
+ uint32_t reg_attr[2];
+ uint64_t mmio_base;
+
+ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+ nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base);
+ qemu_fdt_add_subnode(fdt, nodename);
+
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio");
+
+ reg_attr[0] = cpu_to_be32(mmio_base);
+ reg_attr[1] = cpu_to_be32(0x5000);
+ qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t));
+
+ g_free(nodename);
+ return 0;
+}
+
static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
{
return 0;
@@ -456,6 +488,7 @@ static const BindingEntry bindings[] = {
TYPE_BINDING(TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node),
VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
#endif
+ TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
TYPE_BINDING("", NULL), /* last element */
};
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 856808599d..32d865a488 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -48,6 +48,7 @@
#include "sysemu/numa.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
+#include "sysemu/tpm.h"
#include "sysemu/kvm.h"
#include "hw/loader.h"
#include "exec/address-spaces.h"
@@ -2083,6 +2084,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->pci_allow_0_address = true;
@@ -2196,6 +2198,11 @@ type_init(machvirt_machine_init);
static void virt_machine_5_0_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ { TYPE_TPM_TIS_SYSBUS, "ppi", "false" },
+ };
+
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)