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>
This commit is contained in:
Eric Auger 2020-03-05 17:51:45 +01:00 committed by Stefan Berger
parent 229de57ac5
commit c294ac327c
3 changed files with 41 additions and 0 deletions

View file

@ -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

View file

@ -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 */
};

View file

@ -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)