Adding TPM support for ARM SBSA-Ref machine
Goal
Supporting a ARM64 server like platform that has TPM support.
Technical details
This change request the qemu sbsa-ref machine type to add a TPM create routine during machine initialization.
The backend can be the same as the rest of TPM support, by using swtpm.
Additional information
Here is a proposed change where a new memory region is added to the machine initialization routine:
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index e3195d5449..84bc7d9adb 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -28,6 +28,8 @@
#include "sysemu/numa.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
+#include "sysemu/tpm.h"
+#include "sysemu/tpm_backend.h"
#include "exec/hwaddr.h"
#include "kvm_arm.h"
#include "hw/arm/boot.h"
@@ -94,6 +96,7 @@ enum {
SBSA_SECURE_MEM,
SBSA_AHCI,
SBSA_XHCI,
+ SBSA_TPM,
};
struct SBSAMachineState {
@@ -132,6 +135,7 @@ static const MemMapEntry sbsa_ref_memmap[] = {
/* Space here reserved for more SMMUs */
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
[SBSA_XHCI] = { 0x60110000, 0x00010000 },
+ [SBSA_TPM] = { 0x60120000, 0x00010000 },
/* Space here reserved for other devices */
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
/* 32-bit address PCIE MMIO space */
@@ -629,6 +633,24 @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
}
}
+static void create_tpm(SBSAMachineState *sbsa, PCIBus *bus)
+{
+ Error *errp = NULL;
+ DeviceState *dev;
+
+ TPMBackend *be = qemu_find_tpm_be("tpm0");
+ if (be == NULL) {
+ error_report("Couldn't find tmp0 backend");
+ return;
+ }
+
+ dev = qdev_new(TYPE_TPM_TIS_SYSBUS);
+ object_property_set_link(OBJECT(dev), "tpmdev", OBJECT(be), &errp);
+ object_property_set_str(OBJECT(dev), "tpmdev", be->id, &errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, sbsa_ref_memmap[SBSA_TPM].base);
+}
+
static void create_pcie(SBSAMachineState *sms)
{
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
@@ -686,6 +708,8 @@ static void create_pcie(SBSAMachineState *sms)
pci_create_simple(pci->bus, -1, "bochs-display");
create_smmu(sms, pci->bus);
+
+ create_tpm(sms, pci->bus);
}
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
With such, the tpm can get used when setting the TPM base address to be 0x60120000 with the following launching command:
qemu-system-aarch64 -machine sbsa-ref,gic-version=3,acpi=off \
-cpu host -m 4G \
-nographic -accel kvm \
-chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device virtio-blk-pci,drive=drv0 \
-drive format=qcow2,file=hda.qcow2,if=none,id=drv0 \
-drive if=pflash,format=raw,file=flash0.img,readonly=on \
-drive if=pflash,format=raw,file=flash1.img