All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device
@ 2023-11-14  2:09 Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 01/14] tpm_crb: refactor common code Joelle van Dyne
                   ` (15 more replies)
  0 siblings, 16 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel

The impetus for this patch set is to get TPM 2.0 working on Windows 11 ARM64.
Windows' tpm.sys does not seem to work on a TPM TIS device (as verified with
VMWare's implementation). However, the current TPM CRB device uses a fixed
system bus address that is reserved for RAM in ARM64 Virt machines.

In the process of adding the TPM CRB SysBus device, we also went ahead and
cleaned up some of the existing TPM hardware code and fixed some bugs. We used
the TPM TIS devices as a template for the TPM CRB devices and refactored out
common code. We moved the ACPI DSDT generation to the device in order to handle
dynamic base address requirements as well as reduce redundent code in different
machine ACPI generation. We also changed the tpm_crb device to use the ISA bus
instead of depending on the default system bus as the device only was built for
the PC configuration.

Another change is that the TPM CRB registers are now mapped in the same way that
the pflash ROM devices are mapped. It is a memory region whose writes are
trapped as MMIO accesses. This was needed because Apple Silicon does not decode
LDP (AARCH64 load pair of registers) caused page faults. @agraf suggested that
we do this to avoid having to do AARCH64 decoding in the HVF backend's fault
handler.

Unfortunately, it seems like the LDP fault still happens on HVF but the issue
seems to be in the HVF backend which needs to be fixed in a separate patch.

One last thing that's needed to get Windows 11 to recognize the TPM 2.0 device
is for the OVMF firmware to setup the TPM device. Currently, OVMF for ARM64 Virt
only recognizes the TPM TIS device through a FDT entry. A workaround is to
falsely identify the TPM CRB device as a TPM TIS device in the FDT node but this
causes issues for Linux. A proper fix would involve adding an ACPI device driver
in OVMF.

This has been tested on ARM64 with `tpm-crb-device` and on x86_64 with
`tpm-crb`. Additional testing should be performed on other architectures (RISCV
and Loongarch for example) as well as migration cases.

v5:
- Fixed a typo in "tpm_crb: use a single read-as-mem/write-as-mmio mapping"
- Fixed ACPI tables not being created for pc CRB device

v4:
- Fixed broken test blobs

v3:
- Support backwards and forwards migration of existing tpm-crb device
- Dropped patch which moved tpm-crb to ISA bus due to migration concerns
- Unified `tpm_sysbus_plug` handler for ARM and Loongarch
- Added ACPI table tests for tpm-crb-device
- Refactored TPM CRB tests to run on tpm-crb-device for ARM Virt

v2:
- Fixed an issue where VMstate restore from an older version failed due to name
  collision of the memory block.
- In the ACPI table generation for CRB devices, the check for TPM 2.0 backend is
  moved to the device realize as CRB does not support TPM 1.0. It will error in
  that case.
- Dropped the patch to fix crash when PPI is enabled on TIS SysBus device since
  a separate patch submitted by Stefan Berger disables such an option.
- Fixed an issue where we default tpmEstablished=0 when it should be 1.
- In TPM CRB SysBus's ACPI entry, we accidently changed _UID from 0 to 1. This
  shouldn't be an issue but we changed it back just in case.
- Added a patch to migrate saved VMstate from an older version with the regs
  saved separately instead of as a RAM block.

Joelle van Dyne (14):
  tpm_crb: refactor common code
  tpm_crb: CTRL_RSP_ADDR is 64-bits wide
  tpm_ppi: refactor memory space initialization
  tpm_crb: use a single read-as-mem/write-as-mmio mapping
  tpm_crb: move ACPI table building to device interface
  tpm-sysbus: add plug handler for TPM on SysBus
  hw/arm/virt: connect TPM to platform bus
  hw/loongarch/virt: connect TPM to platform bus
  tpm_tis_sysbus: move DSDT AML generation to device
  tests: acpi: prepare for TPM CRB tests
  tpm_crb_sysbus: introduce TPM CRB SysBus device
  tests: acpi: implement TPM CRB tests for ARM virt
  tests: acpi: updated expected blobs for TPM CRB
  tests: add TPM-CRB sysbus tests for aarch64

 docs/specs/tpm.rst                        |   2 +
 hw/tpm/tpm_crb.h                          |  79 ++++++
 hw/tpm/tpm_ppi.h                          |  10 +-
 include/hw/acpi/tpm.h                     |   3 +-
 include/sysemu/tpm.h                      |   7 +
 tests/qtest/tpm-tests.h                   |   2 +
 tests/qtest/tpm-util.h                    |   4 +-
 hw/acpi/aml-build.c                       |   7 +-
 hw/arm/virt-acpi-build.c                  |  38 +--
 hw/arm/virt.c                             |   8 +
 hw/core/sysbus-fdt.c                      |   1 +
 hw/i386/acpi-build.c                      |  16 +-
 hw/loongarch/acpi-build.c                 |  38 +--
 hw/loongarch/virt.c                       |   8 +
 hw/riscv/virt.c                           |   1 +
 hw/tpm/tpm-sysbus.c                       |  47 ++++
 hw/tpm/tpm_crb.c                          | 302 ++++++----------------
 hw/tpm/tpm_crb_common.c                   | 262 +++++++++++++++++++
 hw/tpm/tpm_crb_sysbus.c                   | 162 ++++++++++++
 hw/tpm/tpm_ppi.c                          |   5 +-
 hw/tpm/tpm_tis_isa.c                      |   5 +-
 hw/tpm/tpm_tis_sysbus.c                   |  37 +++
 tests/qtest/bios-tables-test.c            |  47 +++-
 tests/qtest/tpm-crb-device-swtpm-test.c   |  72 ++++++
 tests/qtest/tpm-crb-device-test.c         |  71 +++++
 tests/qtest/tpm-crb-swtpm-test.c          |   2 +
 tests/qtest/tpm-crb-test.c                | 121 +--------
 tests/qtest/tpm-tests.c                   | 121 +++++++++
 tests/qtest/tpm-tis-device-swtpm-test.c   |   2 +-
 tests/qtest/tpm-tis-device-test.c         |   2 +-
 tests/qtest/tpm-tis-i2c-test.c            |   3 +
 tests/qtest/tpm-tis-swtpm-test.c          |   2 +-
 tests/qtest/tpm-tis-test.c                |   2 +-
 tests/qtest/tpm-util.c                    |  16 +-
 hw/arm/Kconfig                            |   1 +
 hw/loongarch/Kconfig                      |   2 +
 hw/riscv/Kconfig                          |   1 +
 hw/tpm/Kconfig                            |   5 +
 hw/tpm/meson.build                        |   5 +
 hw/tpm/trace-events                       |   2 +-
 tests/data/acpi/q35/DSDT.crb.tpm2         | Bin 0 -> 8355 bytes
 tests/data/acpi/q35/TPM2.crb.tpm2         | Bin 0 -> 76 bytes
 tests/data/acpi/virt/DSDT.crb-device.tpm2 | Bin 0 -> 5276 bytes
 tests/data/acpi/virt/TPM2.crb-device.tpm2 | Bin 0 -> 76 bytes
 tests/qtest/meson.build                   |   4 +
 45 files changed, 1057 insertions(+), 468 deletions(-)
 create mode 100644 hw/tpm/tpm_crb.h
 create mode 100644 hw/tpm/tpm-sysbus.c
 create mode 100644 hw/tpm/tpm_crb_common.c
 create mode 100644 hw/tpm/tpm_crb_sysbus.c
 create mode 100644 tests/qtest/tpm-crb-device-swtpm-test.c
 create mode 100644 tests/qtest/tpm-crb-device-test.c
 create mode 100644 tests/data/acpi/q35/DSDT.crb.tpm2
 create mode 100644 tests/data/acpi/q35/TPM2.crb.tpm2
 create mode 100644 tests/data/acpi/virt/DSDT.crb-device.tpm2
 create mode 100644 tests/data/acpi/virt/TPM2.crb-device.tpm2

-- 
2.41.0



^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v5 01/14] tpm_crb: refactor common code
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 02/14] tpm_crb: CTRL_RSP_ADDR is 64-bits wide Joelle van Dyne
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Berger, Stefan Berger

In preparation for the SysBus variant, we move common code styled
after the TPM TIS devices.

To maintain compatibility, we do not rename the existing tpm-crb
device.

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 docs/specs/tpm.rst      |   1 +
 hw/tpm/tpm_crb.h        |  76 +++++++++++
 hw/tpm/tpm_crb.c        | 270 ++++++----------------------------------
 hw/tpm/tpm_crb_common.c | 216 ++++++++++++++++++++++++++++++++
 hw/tpm/meson.build      |   1 +
 hw/tpm/trace-events     |   2 +-
 6 files changed, 331 insertions(+), 235 deletions(-)
 create mode 100644 hw/tpm/tpm_crb.h
 create mode 100644 hw/tpm/tpm_crb_common.c

diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
index efe124a148..2bc29c9804 100644
--- a/docs/specs/tpm.rst
+++ b/docs/specs/tpm.rst
@@ -45,6 +45,7 @@ operating system.
 
 QEMU files related to TPM CRB interface:
  - ``hw/tpm/tpm_crb.c``
+ - ``hw/tpm/tpm_crb_common.c``
 
 SPAPR interface
 ---------------
diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
new file mode 100644
index 0000000000..da3a0cf256
--- /dev/null
+++ b/hw/tpm/tpm_crb.h
@@ -0,0 +1,76 @@
+/*
+ * tpm_crb.h - QEMU's TPM CRB interface emulator
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * tpm_crb is a device for TPM 2.0 Command Response Buffer (CRB) Interface
+ * as defined in TCG PC Client Platform TPM Profile (PTP) Specification
+ * Family “2.0” Level 00 Revision 01.03 v22
+ */
+#ifndef TPM_TPM_CRB_H
+#define TPM_TPM_CRB_H
+
+#include "exec/memory.h"
+#include "hw/acpi/tpm.h"
+#include "sysemu/tpm_backend.h"
+#include "tpm_ppi.h"
+
+#define CRB_CTRL_CMD_SIZE (TPM_CRB_ADDR_SIZE - A_CRB_DATA_BUFFER)
+
+typedef struct TPMCRBState {
+    TPMBackend *tpmbe;
+    TPMBackendCmd cmd;
+    uint32_t regs[TPM_CRB_R_MAX];
+    MemoryRegion mmio;
+    MemoryRegion cmdmem;
+
+    size_t be_buffer_size;
+
+    bool ppi_enabled;
+    TPMPPI ppi;
+} TPMCRBState;
+
+#define CRB_INTF_TYPE_CRB_ACTIVE 0b1
+#define CRB_INTF_VERSION_CRB 0b1
+#define CRB_INTF_CAP_LOCALITY_0_ONLY 0b0
+#define CRB_INTF_CAP_IDLE_FAST 0b0
+#define CRB_INTF_CAP_XFER_SIZE_64 0b11
+#define CRB_INTF_CAP_FIFO_NOT_SUPPORTED 0b0
+#define CRB_INTF_CAP_CRB_SUPPORTED 0b1
+#define CRB_INTF_IF_SELECTOR_CRB 0b1
+
+enum crb_loc_ctrl {
+    CRB_LOC_CTRL_REQUEST_ACCESS = BIT(0),
+    CRB_LOC_CTRL_RELINQUISH = BIT(1),
+    CRB_LOC_CTRL_SEIZE = BIT(2),
+    CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT = BIT(3),
+};
+
+enum crb_ctrl_req {
+    CRB_CTRL_REQ_CMD_READY = BIT(0),
+    CRB_CTRL_REQ_GO_IDLE = BIT(1),
+};
+
+enum crb_start {
+    CRB_START_INVOKE = BIT(0),
+};
+
+enum crb_cancel {
+    CRB_CANCEL_INVOKE = BIT(0),
+};
+
+#define TPM_CRB_NO_LOCALITY 0xff
+
+void tpm_crb_request_completed(TPMCRBState *s, int ret);
+enum TPMVersion tpm_crb_get_version(TPMCRBState *s);
+int tpm_crb_pre_save(TPMCRBState *s);
+void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr);
+void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp);
+
+#endif /* TPM_TPM_CRB_H */
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index ea930da545..3ef4977fb5 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -31,257 +31,62 @@
 #include "tpm_ppi.h"
 #include "trace.h"
 #include "qom/object.h"
+#include "tpm_crb.h"
 
 struct CRBState {
     DeviceState parent_obj;
 
-    TPMBackend *tpmbe;
-    TPMBackendCmd cmd;
-    uint32_t regs[TPM_CRB_R_MAX];
-    MemoryRegion mmio;
-    MemoryRegion cmdmem;
-
-    size_t be_buffer_size;
-
-    bool ppi_enabled;
-    TPMPPI ppi;
+    TPMCRBState state;
 };
 typedef struct CRBState CRBState;
 
 DECLARE_INSTANCE_CHECKER(CRBState, CRB,
                          TYPE_TPM_CRB)
 
-#define CRB_INTF_TYPE_CRB_ACTIVE 0b1
-#define CRB_INTF_VERSION_CRB 0b1
-#define CRB_INTF_CAP_LOCALITY_0_ONLY 0b0
-#define CRB_INTF_CAP_IDLE_FAST 0b0
-#define CRB_INTF_CAP_XFER_SIZE_64 0b11
-#define CRB_INTF_CAP_FIFO_NOT_SUPPORTED 0b0
-#define CRB_INTF_CAP_CRB_SUPPORTED 0b1
-#define CRB_INTF_IF_SELECTOR_CRB 0b1
-
-#define CRB_CTRL_CMD_SIZE (TPM_CRB_ADDR_SIZE - A_CRB_DATA_BUFFER)
-
-enum crb_loc_ctrl {
-    CRB_LOC_CTRL_REQUEST_ACCESS = BIT(0),
-    CRB_LOC_CTRL_RELINQUISH = BIT(1),
-    CRB_LOC_CTRL_SEIZE = BIT(2),
-    CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT = BIT(3),
-};
-
-enum crb_ctrl_req {
-    CRB_CTRL_REQ_CMD_READY = BIT(0),
-    CRB_CTRL_REQ_GO_IDLE = BIT(1),
-};
-
-enum crb_start {
-    CRB_START_INVOKE = BIT(0),
-};
-
-enum crb_cancel {
-    CRB_CANCEL_INVOKE = BIT(0),
-};
-
-#define TPM_CRB_NO_LOCALITY 0xff
-
-static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
-                                  unsigned size)
-{
-    CRBState *s = CRB(opaque);
-    void *regs = (void *)&s->regs + (addr & ~3);
-    unsigned offset = addr & 3;
-    uint32_t val = *(uint32_t *)regs >> (8 * offset);
-
-    switch (addr) {
-    case A_CRB_LOC_STATE:
-        val |= !tpm_backend_get_tpm_established_flag(s->tpmbe);
-        break;
-    }
-
-    trace_tpm_crb_mmio_read(addr, size, val);
-
-    return val;
-}
-
-static uint8_t tpm_crb_get_active_locty(CRBState *s)
-{
-    if (!ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, locAssigned)) {
-        return TPM_CRB_NO_LOCALITY;
-    }
-    return ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, activeLocality);
-}
-
-static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
-                               uint64_t val, unsigned size)
-{
-    CRBState *s = CRB(opaque);
-    uint8_t locty =  addr >> 12;
-
-    trace_tpm_crb_mmio_write(addr, size, val);
-
-    switch (addr) {
-    case A_CRB_CTRL_REQ:
-        switch (val) {
-        case CRB_CTRL_REQ_CMD_READY:
-            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
-                             tpmIdle, 0);
-            break;
-        case CRB_CTRL_REQ_GO_IDLE:
-            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
-                             tpmIdle, 1);
-            break;
-        }
-        break;
-    case A_CRB_CTRL_CANCEL:
-        if (val == CRB_CANCEL_INVOKE &&
-            s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
-            tpm_backend_cancel_cmd(s->tpmbe);
-        }
-        break;
-    case A_CRB_CTRL_START:
-        if (val == CRB_START_INVOKE &&
-            !(s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
-            tpm_crb_get_active_locty(s) == locty) {
-            void *mem = memory_region_get_ram_ptr(&s->cmdmem);
-
-            s->regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
-            s->cmd = (TPMBackendCmd) {
-                .in = mem,
-                .in_len = MIN(tpm_cmd_get_size(mem), s->be_buffer_size),
-                .out = mem,
-                .out_len = s->be_buffer_size,
-            };
-
-            tpm_backend_deliver_request(s->tpmbe, &s->cmd);
-        }
-        break;
-    case A_CRB_LOC_CTRL:
-        switch (val) {
-        case CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT:
-            /* not loc 3 or 4 */
-            break;
-        case CRB_LOC_CTRL_RELINQUISH:
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
-                             locAssigned, 0);
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
-                             Granted, 0);
-            break;
-        case CRB_LOC_CTRL_REQUEST_ACCESS:
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
-                             Granted, 1);
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
-                             beenSeized, 0);
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
-                             locAssigned, 1);
-            break;
-        }
-        break;
-    }
-}
-
-static const MemoryRegionOps tpm_crb_memory_ops = {
-    .read = tpm_crb_mmio_read,
-    .write = tpm_crb_mmio_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 4,
-    },
-};
-
-static void tpm_crb_request_completed(TPMIf *ti, int ret)
+static void tpm_crb_none_request_completed(TPMIf *ti, int ret)
 {
     CRBState *s = CRB(ti);
 
-    s->regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
-    if (ret != 0) {
-        ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
-                         tpmSts, 1); /* fatal error */
-    }
-    memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE);
+    tpm_crb_request_completed(&s->state, ret);
 }
 
-static enum TPMVersion tpm_crb_get_version(TPMIf *ti)
+static enum TPMVersion tpm_crb_none_get_version(TPMIf *ti)
 {
     CRBState *s = CRB(ti);
 
-    return tpm_backend_get_tpm_version(s->tpmbe);
+    return tpm_crb_get_version(&s->state);
 }
 
-static int tpm_crb_pre_save(void *opaque)
+static int tpm_crb_none_pre_save(void *opaque)
 {
     CRBState *s = opaque;
 
-    tpm_backend_finish_sync(s->tpmbe);
-
-    return 0;
+    return tpm_crb_pre_save(&s->state);
 }
 
-static const VMStateDescription vmstate_tpm_crb = {
+static const VMStateDescription vmstate_tpm_crb_none = {
     .name = "tpm-crb",
-    .pre_save = tpm_crb_pre_save,
+    .pre_save = tpm_crb_none_pre_save,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(regs, CRBState, TPM_CRB_R_MAX),
+        VMSTATE_UINT32_ARRAY(state.regs, CRBState, TPM_CRB_R_MAX),
         VMSTATE_END_OF_LIST(),
     }
 };
 
-static Property tpm_crb_properties[] = {
-    DEFINE_PROP_TPMBE("tpmdev", CRBState, tpmbe),
-    DEFINE_PROP_BOOL("ppi", CRBState, ppi_enabled, true),
+static Property tpm_crb_none_properties[] = {
+    DEFINE_PROP_TPMBE("tpmdev", CRBState, state.tpmbe),
+    DEFINE_PROP_BOOL("ppi", CRBState, state.ppi_enabled, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void tpm_crb_reset(void *dev)
+static void tpm_crb_none_reset(void *dev)
 {
     CRBState *s = CRB(dev);
 
-    if (s->ppi_enabled) {
-        tpm_ppi_reset(&s->ppi);
-    }
-    tpm_backend_reset(s->tpmbe);
-
-    memset(s->regs, 0, sizeof(s->regs));
-
-    ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
-                     tpmRegValidSts, 1);
-    ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
-                     tpmIdle, 1);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     InterfaceType, CRB_INTF_TYPE_CRB_ACTIVE);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     InterfaceVersion, CRB_INTF_VERSION_CRB);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     CapLocality, CRB_INTF_CAP_LOCALITY_0_ONLY);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     CapCRBIdleBypass, CRB_INTF_CAP_IDLE_FAST);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     CapDataXferSizeSupport, CRB_INTF_CAP_XFER_SIZE_64);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     CapFIFO, CRB_INTF_CAP_FIFO_NOT_SUPPORTED);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     CapCRB, CRB_INTF_CAP_CRB_SUPPORTED);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     InterfaceSelector, CRB_INTF_IF_SELECTOR_CRB);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
-                     RID, 0b0000);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID2,
-                     VID, PCI_VENDOR_ID_IBM);
-
-    s->regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
-    s->regs[R_CRB_CTRL_CMD_LADDR] = TPM_CRB_ADDR_BASE + A_CRB_DATA_BUFFER;
-    s->regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
-    s->regs[R_CRB_CTRL_RSP_ADDR] = TPM_CRB_ADDR_BASE + A_CRB_DATA_BUFFER;
-
-    s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
-                            CRB_CTRL_CMD_SIZE);
-
-    if (tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size) < 0) {
-        exit(1);
-    }
+    return tpm_crb_reset(&s->state, TPM_CRB_ADDR_BASE);
 }
 
-static void tpm_crb_realize(DeviceState *dev, Error **errp)
+static void tpm_crb_none_realize(DeviceState *dev, Error **errp)
 {
     CRBState *s = CRB(dev);
 
@@ -289,64 +94,61 @@ static void tpm_crb_realize(DeviceState *dev, Error **errp)
         error_setg(errp, "at most one TPM device is permitted");
         return;
     }
-    if (!s->tpmbe) {
+    if (!s->state.tpmbe) {
         error_setg(errp, "'tpmdev' property is required");
         return;
     }
 
-    memory_region_init_io(&s->mmio, OBJECT(s), &tpm_crb_memory_ops, s,
-        "tpm-crb-mmio", sizeof(s->regs));
-    memory_region_init_ram(&s->cmdmem, OBJECT(s),
-        "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
+    tpm_crb_init_memory(OBJECT(s), &s->state, errp);
 
     memory_region_add_subregion(get_system_memory(),
-        TPM_CRB_ADDR_BASE, &s->mmio);
+        TPM_CRB_ADDR_BASE, &s->state.mmio);
     memory_region_add_subregion(get_system_memory(),
-        TPM_CRB_ADDR_BASE + sizeof(s->regs), &s->cmdmem);
+        TPM_CRB_ADDR_BASE + sizeof(s->state.regs), &s->state.cmdmem);
 
-    if (s->ppi_enabled) {
-        tpm_ppi_init(&s->ppi, get_system_memory(),
+    if (s->state.ppi_enabled) {
+        tpm_ppi_init(&s->state.ppi, get_system_memory(),
                      TPM_PPI_ADDR_BASE, OBJECT(s));
     }
 
     if (xen_enabled()) {
-        tpm_crb_reset(dev);
+        tpm_crb_none_reset(dev);
     } else {
-        qemu_register_reset(tpm_crb_reset, dev);
+        qemu_register_reset(tpm_crb_none_reset, dev);
     }
 }
 
-static void tpm_crb_class_init(ObjectClass *klass, void *data)
+static void tpm_crb_none_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     TPMIfClass *tc = TPM_IF_CLASS(klass);
 
-    dc->realize = tpm_crb_realize;
-    device_class_set_props(dc, tpm_crb_properties);
-    dc->vmsd  = &vmstate_tpm_crb;
+    dc->realize = tpm_crb_none_realize;
+    device_class_set_props(dc, tpm_crb_none_properties);
+    dc->vmsd  = &vmstate_tpm_crb_none;
     dc->user_creatable = true;
     tc->model = TPM_MODEL_TPM_CRB;
-    tc->get_version = tpm_crb_get_version;
-    tc->request_completed = tpm_crb_request_completed;
+    tc->get_version = tpm_crb_none_get_version;
+    tc->request_completed = tpm_crb_none_request_completed;
 
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
-static const TypeInfo tpm_crb_info = {
+static const TypeInfo tpm_crb_none_info = {
     .name = TYPE_TPM_CRB,
     /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(CRBState),
-    .class_init  = tpm_crb_class_init,
+    .class_init  = tpm_crb_none_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_TPM_IF },
         { }
     }
 };
 
-static void tpm_crb_register(void)
+static void tpm_crb_none_register(void)
 {
-    type_register_static(&tpm_crb_info);
+    type_register_static(&tpm_crb_none_info);
 }
 
-type_init(tpm_crb_register)
+type_init(tpm_crb_none_register)
diff --git a/hw/tpm/tpm_crb_common.c b/hw/tpm/tpm_crb_common.c
new file mode 100644
index 0000000000..fa463f295f
--- /dev/null
+++ b/hw/tpm/tpm_crb_common.c
@@ -0,0 +1,216 @@
+/*
+ * tpm_crb.c - QEMU's TPM CRB interface emulator
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * tpm_crb is a device for TPM 2.0 Command Response Buffer (CRB) Interface
+ * as defined in TCG PC Client Platform TPM Profile (PTP) Specification
+ * Family “2.0” Level 00 Revision 01.03 v22
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
+#include "hw/qdev-properties.h"
+#include "hw/pci/pci_ids.h"
+#include "hw/acpi/tpm.h"
+#include "migration/vmstate.h"
+#include "sysemu/tpm_backend.h"
+#include "sysemu/tpm_util.h"
+#include "tpm_prop.h"
+#include "tpm_ppi.h"
+#include "trace.h"
+#include "qom/object.h"
+#include "tpm_crb.h"
+
+static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
+                                  unsigned size)
+{
+    TPMCRBState *s = opaque;
+    void *regs = (void *)&s->regs + (addr & ~3);
+    unsigned offset = addr & 3;
+    uint32_t val = *(uint32_t *)regs >> (8 * offset);
+
+    switch (addr) {
+    case A_CRB_LOC_STATE:
+        val |= !tpm_backend_get_tpm_established_flag(s->tpmbe);
+        break;
+    }
+
+    trace_tpm_crb_mmio_read(addr, size, val);
+
+    return val;
+}
+
+static uint8_t tpm_crb_get_active_locty(TPMCRBState *s)
+{
+    if (!ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, locAssigned)) {
+        return TPM_CRB_NO_LOCALITY;
+    }
+    return ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, activeLocality);
+}
+
+static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
+                               uint64_t val, unsigned size)
+{
+    TPMCRBState *s = opaque;
+    uint8_t locty =  addr >> 12;
+
+    trace_tpm_crb_mmio_write(addr, size, val);
+
+    switch (addr) {
+    case A_CRB_CTRL_REQ:
+        switch (val) {
+        case CRB_CTRL_REQ_CMD_READY:
+            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+                             tpmIdle, 0);
+            break;
+        case CRB_CTRL_REQ_GO_IDLE:
+            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+                             tpmIdle, 1);
+            break;
+        }
+        break;
+    case A_CRB_CTRL_CANCEL:
+        if (val == CRB_CANCEL_INVOKE &&
+            s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
+            tpm_backend_cancel_cmd(s->tpmbe);
+        }
+        break;
+    case A_CRB_CTRL_START:
+        if (val == CRB_START_INVOKE &&
+            !(s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
+            tpm_crb_get_active_locty(s) == locty) {
+            void *mem = memory_region_get_ram_ptr(&s->cmdmem);
+
+            s->regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
+            s->cmd = (TPMBackendCmd) {
+                .in = mem,
+                .in_len = MIN(tpm_cmd_get_size(mem), s->be_buffer_size),
+                .out = mem,
+                .out_len = s->be_buffer_size,
+            };
+
+            tpm_backend_deliver_request(s->tpmbe, &s->cmd);
+        }
+        break;
+    case A_CRB_LOC_CTRL:
+        switch (val) {
+        case CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT:
+            /* not loc 3 or 4 */
+            break;
+        case CRB_LOC_CTRL_RELINQUISH:
+            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
+                             locAssigned, 0);
+            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
+                             Granted, 0);
+            break;
+        case CRB_LOC_CTRL_REQUEST_ACCESS:
+            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
+                             Granted, 1);
+            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
+                             beenSeized, 0);
+            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
+                             locAssigned, 1);
+            break;
+        }
+        break;
+    }
+}
+
+const MemoryRegionOps tpm_crb_memory_ops = {
+    .read = tpm_crb_mmio_read,
+    .write = tpm_crb_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+void tpm_crb_request_completed(TPMCRBState *s, int ret)
+{
+    s->regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
+    if (ret != 0) {
+        ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+                         tpmSts, 1); /* fatal error */
+    }
+    memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE);
+}
+
+enum TPMVersion tpm_crb_get_version(TPMCRBState *s)
+{
+    return tpm_backend_get_tpm_version(s->tpmbe);
+}
+
+int tpm_crb_pre_save(TPMCRBState *s)
+{
+    tpm_backend_finish_sync(s->tpmbe);
+
+    return 0;
+}
+
+void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr)
+{
+    if (s->ppi_enabled) {
+        tpm_ppi_reset(&s->ppi);
+    }
+    tpm_backend_reset(s->tpmbe);
+
+    memset(s->regs, 0, sizeof(s->regs));
+
+    ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
+                     tpmRegValidSts, 1);
+    ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+                     tpmIdle, 1);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     InterfaceType, CRB_INTF_TYPE_CRB_ACTIVE);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     InterfaceVersion, CRB_INTF_VERSION_CRB);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     CapLocality, CRB_INTF_CAP_LOCALITY_0_ONLY);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     CapCRBIdleBypass, CRB_INTF_CAP_IDLE_FAST);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     CapDataXferSizeSupport, CRB_INTF_CAP_XFER_SIZE_64);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     CapFIFO, CRB_INTF_CAP_FIFO_NOT_SUPPORTED);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     CapCRB, CRB_INTF_CAP_CRB_SUPPORTED);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     InterfaceSelector, CRB_INTF_IF_SELECTOR_CRB);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+                     RID, 0b0000);
+    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID2,
+                     VID, PCI_VENDOR_ID_IBM);
+
+    baseaddr += A_CRB_DATA_BUFFER;
+    s->regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
+    s->regs[R_CRB_CTRL_CMD_LADDR] = (uint32_t)baseaddr;
+    s->regs[R_CRB_CTRL_CMD_HADDR] = (uint32_t)(baseaddr >> 32);
+    s->regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
+    s->regs[R_CRB_CTRL_RSP_ADDR] = (uint32_t)baseaddr;
+
+    s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
+                            CRB_CTRL_CMD_SIZE);
+
+    if (tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size) < 0) {
+        exit(1);
+    }
+}
+
+void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp)
+{
+    memory_region_init_io(&s->mmio, obj, &tpm_crb_memory_ops, s,
+        "tpm-crb-mmio", sizeof(s->regs));
+    memory_region_init_ram(&s->cmdmem, obj,
+        "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
+}
diff --git a/hw/tpm/meson.build b/hw/tpm/meson.build
index 6968e60b3f..cb8204d5bc 100644
--- a/hw/tpm/meson.build
+++ b/hw/tpm/meson.build
@@ -3,6 +3,7 @@ system_ss.add(when: 'CONFIG_TPM_TIS_ISA', if_true: files('tpm_tis_isa.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS_SYSBUS', if_true: files('tpm_tis_sysbus.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS_I2C', if_true: files('tpm_tis_i2c.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb.c'))
+system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb_common.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS', if_true: files('tpm_ppi.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_ppi.c'))
 
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index fa882dfefe..3ab1bdb97b 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -1,6 +1,6 @@
 # See docs/devel/tracing.rst for syntax documentation.
 
-# tpm_crb.c
+# tpm_crb_common.c
 tpm_crb_mmio_read(uint64_t addr, unsigned size, uint32_t val) "CRB read 0x%016" PRIx64 " len:%u val: 0x%" PRIx32
 tpm_crb_mmio_write(uint64_t addr, unsigned size, uint32_t val) "CRB write 0x%016" PRIx64 " len:%u val: 0x%" PRIx32
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 02/14] tpm_crb: CTRL_RSP_ADDR is 64-bits wide
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 01/14] tpm_crb: refactor common code Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 03/14] tpm_ppi: refactor memory space initialization Joelle van Dyne
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Stefan Berger,
	Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Thomas Huth,
	Laurent Vivier, Paolo Bonzini

The register is actually 64-bits but in order to make this more clear
than the specification, we define two 32-bit registers:
CTRL_RSP_LADDR and CTRL_RSP_HADDR to match the CTRL_CMD_* naming. This
deviates from the specs but is way more clear.

Previously, the only CRB device uses a fixed system address so this
was not an issue. However, once we support SysBus CRB device, the
address can be anywhere in 64-bit space.

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 include/hw/acpi/tpm.h      | 3 ++-
 hw/tpm/tpm_crb_common.c    | 3 ++-
 tests/qtest/tpm-crb-test.c | 2 +-
 tests/qtest/tpm-util.c     | 2 +-
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h
index 579c45f5ba..f60bfe2789 100644
--- a/include/hw/acpi/tpm.h
+++ b/include/hw/acpi/tpm.h
@@ -174,7 +174,8 @@ REG32(CRB_CTRL_CMD_SIZE, 0x58)
 REG32(CRB_CTRL_CMD_LADDR, 0x5C)
 REG32(CRB_CTRL_CMD_HADDR, 0x60)
 REG32(CRB_CTRL_RSP_SIZE, 0x64)
-REG32(CRB_CTRL_RSP_ADDR, 0x68)
+REG32(CRB_CTRL_RSP_LADDR, 0x68)
+REG32(CRB_CTRL_RSP_HADDR, 0x6C)
 REG32(CRB_DATA_BUFFER, 0x80)
 
 #define TPM_CRB_ADDR_BASE           0xFED40000
diff --git a/hw/tpm/tpm_crb_common.c b/hw/tpm/tpm_crb_common.c
index fa463f295f..01b35808f6 100644
--- a/hw/tpm/tpm_crb_common.c
+++ b/hw/tpm/tpm_crb_common.c
@@ -197,7 +197,8 @@ void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr)
     s->regs[R_CRB_CTRL_CMD_LADDR] = (uint32_t)baseaddr;
     s->regs[R_CRB_CTRL_CMD_HADDR] = (uint32_t)(baseaddr >> 32);
     s->regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
-    s->regs[R_CRB_CTRL_RSP_ADDR] = (uint32_t)baseaddr;
+    s->regs[R_CRB_CTRL_RSP_LADDR] = (uint32_t)baseaddr;
+    s->regs[R_CRB_CTRL_RSP_HADDR] = (uint32_t)(baseaddr >> 32);
 
     s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
                             CRB_CTRL_CMD_SIZE);
diff --git a/tests/qtest/tpm-crb-test.c b/tests/qtest/tpm-crb-test.c
index 396ae3f91c..9d30fe8293 100644
--- a/tests/qtest/tpm-crb-test.c
+++ b/tests/qtest/tpm-crb-test.c
@@ -28,7 +28,7 @@ static void tpm_crb_test(const void *data)
     uint32_t csize = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_SIZE);
     uint64_t caddr = readq(TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_LADDR);
     uint32_t rsize = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_SIZE);
-    uint64_t raddr = readq(TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_ADDR);
+    uint64_t raddr = readq(TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_LADDR);
     uint8_t locstate = readb(TPM_CRB_ADDR_BASE + A_CRB_LOC_STATE);
     uint32_t locctrl = readl(TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL);
     uint32_t locsts = readl(TPM_CRB_ADDR_BASE + A_CRB_LOC_STS);
diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
index 1c0319e6e7..dd02057fc0 100644
--- a/tests/qtest/tpm-util.c
+++ b/tests/qtest/tpm-util.c
@@ -25,7 +25,7 @@ void tpm_util_crb_transfer(QTestState *s,
                            unsigned char *rsp, size_t rsp_size)
 {
     uint64_t caddr = qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_LADDR);
-    uint64_t raddr = qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_ADDR);
+    uint64_t raddr = qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_LADDR);
 
     qtest_writeb(s, TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL, 1);
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 03/14] tpm_ppi: refactor memory space initialization
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 01/14] tpm_crb: refactor common code Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 02/14] tpm_crb: CTRL_RSP_ADDR is 64-bits wide Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 04/14] tpm_crb: use a single read-as-mem/write-as-mmio mapping Joelle van Dyne
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Berger, Stefan Berger

Instead of calling `memory_region_add_subregion` directly, we defer to
the caller to do it. This allows us to re-use the code for a SysBus
device.

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 hw/tpm/tpm_ppi.h        | 10 +++-------
 hw/tpm/tpm_crb.c        |  4 ++--
 hw/tpm/tpm_crb_common.c |  3 +++
 hw/tpm/tpm_ppi.c        |  5 +----
 hw/tpm/tpm_tis_isa.c    |  5 +++--
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/tpm/tpm_ppi.h b/hw/tpm/tpm_ppi.h
index bf5d4a300f..30863c6438 100644
--- a/hw/tpm/tpm_ppi.h
+++ b/hw/tpm/tpm_ppi.h
@@ -20,17 +20,13 @@ typedef struct TPMPPI {
 } TPMPPI;
 
 /**
- * tpm_ppi_init:
+ * tpm_ppi_init_memory:
  * @tpmppi: a TPMPPI
- * @m: the address-space / MemoryRegion to use
- * @addr: the address of the PPI region
  * @obj: the owner object
  *
- * Register the TPM PPI memory region at @addr on the given address
- * space for the object @obj.
+ * Creates the TPM PPI memory region.
  **/
-void tpm_ppi_init(TPMPPI *tpmppi, MemoryRegion *m,
-                  hwaddr addr, Object *obj);
+void tpm_ppi_init_memory(TPMPPI *tpmppi, Object *obj);
 
 /**
  * tpm_ppi_reset:
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index 3ef4977fb5..598c3e0161 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -107,8 +107,8 @@ static void tpm_crb_none_realize(DeviceState *dev, Error **errp)
         TPM_CRB_ADDR_BASE + sizeof(s->state.regs), &s->state.cmdmem);
 
     if (s->state.ppi_enabled) {
-        tpm_ppi_init(&s->state.ppi, get_system_memory(),
-                     TPM_PPI_ADDR_BASE, OBJECT(s));
+        memory_region_add_subregion(get_system_memory(),
+            TPM_PPI_ADDR_BASE, &s->state.ppi.ram);
     }
 
     if (xen_enabled()) {
diff --git a/hw/tpm/tpm_crb_common.c b/hw/tpm/tpm_crb_common.c
index 01b35808f6..bee0b71fee 100644
--- a/hw/tpm/tpm_crb_common.c
+++ b/hw/tpm/tpm_crb_common.c
@@ -214,4 +214,7 @@ void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp)
         "tpm-crb-mmio", sizeof(s->regs));
     memory_region_init_ram(&s->cmdmem, obj,
         "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
+    if (s->ppi_enabled) {
+        tpm_ppi_init_memory(&s->ppi, obj);
+    }
 }
diff --git a/hw/tpm/tpm_ppi.c b/hw/tpm/tpm_ppi.c
index 7f74e26ec6..40cab59afa 100644
--- a/hw/tpm/tpm_ppi.c
+++ b/hw/tpm/tpm_ppi.c
@@ -44,14 +44,11 @@ void tpm_ppi_reset(TPMPPI *tpmppi)
     }
 }
 
-void tpm_ppi_init(TPMPPI *tpmppi, MemoryRegion *m,
-                  hwaddr addr, Object *obj)
+void tpm_ppi_init_memory(TPMPPI *tpmppi, Object *obj)
 {
     tpmppi->buf = qemu_memalign(qemu_real_host_page_size(),
                                 HOST_PAGE_ALIGN(TPM_PPI_ADDR_SIZE));
     memory_region_init_ram_device_ptr(&tpmppi->ram, obj, "tpm-ppi",
                                       TPM_PPI_ADDR_SIZE, tpmppi->buf);
     vmstate_register_ram(&tpmppi->ram, DEVICE(obj));
-
-    memory_region_add_subregion(m, addr, &tpmppi->ram);
 }
diff --git a/hw/tpm/tpm_tis_isa.c b/hw/tpm/tpm_tis_isa.c
index 0367401586..d596f38c0f 100644
--- a/hw/tpm/tpm_tis_isa.c
+++ b/hw/tpm/tpm_tis_isa.c
@@ -134,8 +134,9 @@ static void tpm_tis_isa_realizefn(DeviceState *dev, Error **errp)
                                 TPM_TIS_ADDR_BASE, &s->mmio);
 
     if (s->ppi_enabled) {
-        tpm_ppi_init(&s->ppi, isa_address_space(ISA_DEVICE(dev)),
-                     TPM_PPI_ADDR_BASE, OBJECT(dev));
+        tpm_ppi_init_memory(&s->ppi, OBJECT(dev));
+        memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
+                                    TPM_PPI_ADDR_BASE, &s->ppi.ram);
     }
 }
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 04/14] tpm_crb: use a single read-as-mem/write-as-mmio mapping
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (2 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 03/14] tpm_ppi: refactor memory space initialization Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14 15:46   ` Stefan Berger
  2023-11-14  2:09 ` [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface Joelle van Dyne
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Berger

On Apple Silicon, when Windows performs a LDP on the CRB MMIO space,
the exception is not decoded by hardware and we cannot trap the MMIO
read. This led to the idea from @agraf to use the same mapping type as
ROM devices: namely that reads should be seen as memory type and
writes should trap as MMIO.

Once that was done, the second memory mapping of the command buffer
region was redundent and was removed.

A note about the removal of the read trap for `CRB_LOC_STATE`:
The only usage was to return the most up-to-date value for
`tpmEstablished`. However, `tpmEstablished` is only cleared when a
TPM2_HashStart operation is called which only exists for locality 4.
We do not handle locality 4. Indeed, the comment for the write handler
of `CRB_LOC_CTRL` makes the same argument for why it is not calling
the backend to reset the `tpmEstablished` bit (to 1).
As this bit is unused, we do not need to worry about updating it for
reads.

In order to maintain migration compatibility with older versions of
QEMU, we store a copy of the register data and command data which is
used only during save/restore.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 hw/tpm/tpm_crb.h        |   5 +-
 hw/tpm/tpm_crb.c        |  30 ++++++++-
 hw/tpm/tpm_crb_common.c | 145 +++++++++++++++++++++++-----------------
 3 files changed, 114 insertions(+), 66 deletions(-)

diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
index da3a0cf256..36863e1664 100644
--- a/hw/tpm/tpm_crb.h
+++ b/hw/tpm/tpm_crb.h
@@ -26,9 +26,7 @@
 typedef struct TPMCRBState {
     TPMBackend *tpmbe;
     TPMBackendCmd cmd;
-    uint32_t regs[TPM_CRB_R_MAX];
     MemoryRegion mmio;
-    MemoryRegion cmdmem;
 
     size_t be_buffer_size;
 
@@ -72,5 +70,8 @@ enum TPMVersion tpm_crb_get_version(TPMCRBState *s);
 int tpm_crb_pre_save(TPMCRBState *s);
 void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr);
 void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp);
+void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void *saved_cmdmem);
+void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
+                      const void *saved_cmdmem);
 
 #endif /* TPM_TPM_CRB_H */
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index 598c3e0161..99c64dd72a 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -37,6 +37,10 @@ struct CRBState {
     DeviceState parent_obj;
 
     TPMCRBState state;
+
+    /* These states are only for migration */
+    uint32_t saved_regs[TPM_CRB_R_MAX];
+    MemoryRegion saved_cmdmem;
 };
 typedef struct CRBState CRBState;
 
@@ -57,18 +61,36 @@ static enum TPMVersion tpm_crb_none_get_version(TPMIf *ti)
     return tpm_crb_get_version(&s->state);
 }
 
+/**
+ * For migrating to an older version of QEMU
+ */
 static int tpm_crb_none_pre_save(void *opaque)
 {
     CRBState *s = opaque;
+    void *saved_cmdmem = memory_region_get_ram_ptr(&s->saved_cmdmem);
 
+    tpm_crb_mem_save(&s->state, s->saved_regs, saved_cmdmem);
     return tpm_crb_pre_save(&s->state);
 }
 
+/**
+ * For migrating from an older version of QEMU
+ */
+static int tpm_crb_none_post_load(void *opaque, int version_id)
+{
+    CRBState *s = opaque;
+    void *saved_cmdmem = memory_region_get_ram_ptr(&s->saved_cmdmem);
+
+    tpm_crb_mem_load(&s->state, s->saved_regs, saved_cmdmem);
+    return 0;
+}
+
 static const VMStateDescription vmstate_tpm_crb_none = {
     .name = "tpm-crb",
     .pre_save = tpm_crb_none_pre_save,
+    .post_load = tpm_crb_none_post_load,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(state.regs, CRBState, TPM_CRB_R_MAX),
+        VMSTATE_UINT32_ARRAY(saved_regs, CRBState, TPM_CRB_R_MAX),
         VMSTATE_END_OF_LIST(),
     }
 };
@@ -101,10 +123,12 @@ static void tpm_crb_none_realize(DeviceState *dev, Error **errp)
 
     tpm_crb_init_memory(OBJECT(s), &s->state, errp);
 
+    /* only used for migration */
+    memory_region_init_ram(&s->saved_cmdmem, OBJECT(s),
+        "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
+
     memory_region_add_subregion(get_system_memory(),
         TPM_CRB_ADDR_BASE, &s->state.mmio);
-    memory_region_add_subregion(get_system_memory(),
-        TPM_CRB_ADDR_BASE + sizeof(s->state.regs), &s->state.cmdmem);
 
     if (s->state.ppi_enabled) {
         memory_region_add_subregion(get_system_memory(),
diff --git a/hw/tpm/tpm_crb_common.c b/hw/tpm/tpm_crb_common.c
index bee0b71fee..f96a8cf299 100644
--- a/hw/tpm/tpm_crb_common.c
+++ b/hw/tpm/tpm_crb_common.c
@@ -31,31 +31,12 @@
 #include "qom/object.h"
 #include "tpm_crb.h"
 
-static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
-                                  unsigned size)
+static uint8_t tpm_crb_get_active_locty(TPMCRBState *s, uint32_t *regs)
 {
-    TPMCRBState *s = opaque;
-    void *regs = (void *)&s->regs + (addr & ~3);
-    unsigned offset = addr & 3;
-    uint32_t val = *(uint32_t *)regs >> (8 * offset);
-
-    switch (addr) {
-    case A_CRB_LOC_STATE:
-        val |= !tpm_backend_get_tpm_established_flag(s->tpmbe);
-        break;
-    }
-
-    trace_tpm_crb_mmio_read(addr, size, val);
-
-    return val;
-}
-
-static uint8_t tpm_crb_get_active_locty(TPMCRBState *s)
-{
-    if (!ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, locAssigned)) {
+    if (!ARRAY_FIELD_EX32(regs, CRB_LOC_STATE, locAssigned)) {
         return TPM_CRB_NO_LOCALITY;
     }
-    return ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, activeLocality);
+    return ARRAY_FIELD_EX32(regs, CRB_LOC_STATE, activeLocality);
 }
 
 static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
@@ -63,35 +44,49 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
 {
     TPMCRBState *s = opaque;
     uint8_t locty =  addr >> 12;
+    uint32_t *regs;
+    void *mem;
 
     trace_tpm_crb_mmio_write(addr, size, val);
+    regs = memory_region_get_ram_ptr(&s->mmio);
+    mem = &regs[R_CRB_DATA_BUFFER];
+    assert(regs);
+
+    /* receive TPM command bytes in DATA_BUFFER */
+    if (addr >= A_CRB_DATA_BUFFER) {
+        assert(addr + size <= TPM_CRB_ADDR_SIZE);
+        assert(size <= sizeof(val));
+        memcpy(mem + addr - A_CRB_DATA_BUFFER, &val, size);
+        memory_region_set_dirty(&s->mmio, addr, size);
+        return;
+    }
 
+    /* otherwise we are doing MMIO writes */
     switch (addr) {
     case A_CRB_CTRL_REQ:
         switch (val) {
         case CRB_CTRL_REQ_CMD_READY:
-            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+            ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
                              tpmIdle, 0);
             break;
         case CRB_CTRL_REQ_GO_IDLE:
-            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+            ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
                              tpmIdle, 1);
             break;
         }
         break;
     case A_CRB_CTRL_CANCEL:
         if (val == CRB_CANCEL_INVOKE &&
-            s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
+            regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
             tpm_backend_cancel_cmd(s->tpmbe);
         }
         break;
     case A_CRB_CTRL_START:
         if (val == CRB_START_INVOKE &&
-            !(s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
-            tpm_crb_get_active_locty(s) == locty) {
-            void *mem = memory_region_get_ram_ptr(&s->cmdmem);
+            !(regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
+            tpm_crb_get_active_locty(s, regs) == locty) {
 
-            s->regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
+            regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
             s->cmd = (TPMBackendCmd) {
                 .in = mem,
                 .in_len = MIN(tpm_cmd_get_size(mem), s->be_buffer_size),
@@ -108,26 +103,27 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
             /* not loc 3 or 4 */
             break;
         case CRB_LOC_CTRL_RELINQUISH:
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
+            ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
                              locAssigned, 0);
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
+            ARRAY_FIELD_DP32(regs, CRB_LOC_STS,
                              Granted, 0);
             break;
         case CRB_LOC_CTRL_REQUEST_ACCESS:
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
+            ARRAY_FIELD_DP32(regs, CRB_LOC_STS,
                              Granted, 1);
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
+            ARRAY_FIELD_DP32(regs, CRB_LOC_STS,
                              beenSeized, 0);
-            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
+            ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
                              locAssigned, 1);
             break;
         }
         break;
     }
+
+    memory_region_set_dirty(&s->mmio, 0, A_CRB_DATA_BUFFER);
 }
 
 const MemoryRegionOps tpm_crb_memory_ops = {
-    .read = tpm_crb_mmio_read,
     .write = tpm_crb_mmio_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
     .valid = {
@@ -138,12 +134,16 @@ const MemoryRegionOps tpm_crb_memory_ops = {
 
 void tpm_crb_request_completed(TPMCRBState *s, int ret)
 {
-    s->regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
+    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
+
+    assert(regs);
+    regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
     if (ret != 0) {
-        ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+        ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
                          tpmSts, 1); /* fatal error */
     }
-    memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE);
+
+    memory_region_set_dirty(&s->mmio, 0, TPM_CRB_ADDR_SIZE);
 }
 
 enum TPMVersion tpm_crb_get_version(TPMCRBState *s)
@@ -160,45 +160,50 @@ int tpm_crb_pre_save(TPMCRBState *s)
 
 void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr)
 {
+    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
+
+    assert(regs);
     if (s->ppi_enabled) {
         tpm_ppi_reset(&s->ppi);
     }
     tpm_backend_reset(s->tpmbe);
 
-    memset(s->regs, 0, sizeof(s->regs));
+    memset(regs, 0, TPM_CRB_ADDR_SIZE);
 
-    ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
+    ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
                      tpmRegValidSts, 1);
-    ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
+    ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
+                     tpmEstablished, 1);
+    ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
                      tpmIdle, 1);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      InterfaceType, CRB_INTF_TYPE_CRB_ACTIVE);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      InterfaceVersion, CRB_INTF_VERSION_CRB);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      CapLocality, CRB_INTF_CAP_LOCALITY_0_ONLY);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      CapCRBIdleBypass, CRB_INTF_CAP_IDLE_FAST);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      CapDataXferSizeSupport, CRB_INTF_CAP_XFER_SIZE_64);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      CapFIFO, CRB_INTF_CAP_FIFO_NOT_SUPPORTED);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      CapCRB, CRB_INTF_CAP_CRB_SUPPORTED);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      InterfaceSelector, CRB_INTF_IF_SELECTOR_CRB);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
                      RID, 0b0000);
-    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID2,
+    ARRAY_FIELD_DP32(regs, CRB_INTF_ID2,
                      VID, PCI_VENDOR_ID_IBM);
 
     baseaddr += A_CRB_DATA_BUFFER;
-    s->regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
-    s->regs[R_CRB_CTRL_CMD_LADDR] = (uint32_t)baseaddr;
-    s->regs[R_CRB_CTRL_CMD_HADDR] = (uint32_t)(baseaddr >> 32);
-    s->regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
-    s->regs[R_CRB_CTRL_RSP_LADDR] = (uint32_t)baseaddr;
-    s->regs[R_CRB_CTRL_RSP_HADDR] = (uint32_t)(baseaddr >> 32);
+    regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
+    regs[R_CRB_CTRL_CMD_LADDR] = (uint32_t)baseaddr;
+    regs[R_CRB_CTRL_CMD_HADDR] = (uint32_t)(baseaddr >> 32);
+    regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
+    regs[R_CRB_CTRL_RSP_LADDR] = (uint32_t)baseaddr;
+    regs[R_CRB_CTRL_RSP_HADDR] = (uint32_t)(baseaddr >> 32);
 
     s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
                             CRB_CTRL_CMD_SIZE);
@@ -206,15 +211,33 @@ void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr)
     if (tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size) < 0) {
         exit(1);
     }
+
+    memory_region_rom_device_set_romd(&s->mmio, true);
+    memory_region_set_dirty(&s->mmio, 0, TPM_CRB_ADDR_SIZE);
 }
 
 void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp)
 {
-    memory_region_init_io(&s->mmio, obj, &tpm_crb_memory_ops, s,
-        "tpm-crb-mmio", sizeof(s->regs));
-    memory_region_init_ram(&s->cmdmem, obj,
-        "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
+    memory_region_init_rom_device_nomigrate(&s->mmio, obj, &tpm_crb_memory_ops,
+        s, "tpm-crb-mem", TPM_CRB_ADDR_SIZE, errp);
     if (s->ppi_enabled) {
         tpm_ppi_init_memory(&s->ppi, obj);
     }
 }
+
+void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void *saved_cmdmem)
+{
+    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
+
+    memcpy(saved_regs, regs, A_CRB_DATA_BUFFER);
+    memcpy(saved_cmdmem, &regs[R_CRB_DATA_BUFFER], CRB_CTRL_CMD_SIZE);
+}
+
+void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
+                      const void *saved_cmdmem)
+{
+    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
+
+    memcpy(regs, saved_regs, A_CRB_DATA_BUFFER);
+    memcpy(&regs[R_CRB_DATA_BUFFER], saved_cmdmem, CRB_CTRL_CMD_SIZE);
+}
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (3 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 04/14] tpm_crb: use a single read-as-mem/write-as-mmio mapping Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14 16:37   ` Stefan Berger
  2023-11-14  2:09 ` [PATCH v5 06/14] tpm-sysbus: add plug handler for TPM on SysBus Joelle van Dyne
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Michael S. Tsirkin, Igor Mammedov, Ani Sinha,
	Paolo Bonzini, Richard Henderson, Eduardo Habkost,
	Marcel Apfelbaum, Stefan Berger

This logic is similar to TPM TIS ISA device. Since TPM CRB can only
support TPM 2.0 backends, we check for this in realize.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 hw/tpm/tpm_crb.h        |  2 ++
 hw/i386/acpi-build.c    | 16 +---------------
 hw/tpm/tpm_crb.c        | 16 ++++++++++++++++
 hw/tpm/tpm_crb_common.c | 19 +++++++++++++++++++
 4 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
index 36863e1664..e6a86e3fd1 100644
--- a/hw/tpm/tpm_crb.h
+++ b/hw/tpm/tpm_crb.h
@@ -73,5 +73,7 @@ void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp);
 void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void *saved_cmdmem);
 void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
                       const void *saved_cmdmem);
+void tpm_crb_build_aml(TPMIf *ti, Aml *scope, uint32_t baseaddr, uint32_t size,
+                       bool build_ppi);
 
 #endif /* TPM_TPM_CRB_H */
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 80db183b78..7491cee2af 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1792,21 +1792,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 
 #ifdef CONFIG_TPM
     if (TPM_IS_CRB(tpm)) {
-        dev = aml_device("TPM");
-        aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
-        aml_append(dev, aml_name_decl("_STR",
-                                      aml_string("TPM 2.0 Device")));
-        crs = aml_resource_template();
-        aml_append(crs, aml_memory32_fixed(TPM_CRB_ADDR_BASE,
-                                           TPM_CRB_ADDR_SIZE, AML_READ_WRITE));
-        aml_append(dev, aml_name_decl("_CRS", crs));
-
-        aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
-        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
-
-        tpm_build_ppi_acpi(tpm, dev);
-
-        aml_append(sb_scope, dev);
+        call_dev_aml_func(DEVICE(tpm), scope);
     }
 #endif
 
diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
index 99c64dd72a..8d57295b15 100644
--- a/hw/tpm/tpm_crb.c
+++ b/hw/tpm/tpm_crb.c
@@ -19,6 +19,8 @@
 #include "qemu/module.h"
 #include "qapi/error.h"
 #include "exec/address-spaces.h"
+#include "hw/acpi/acpi_aml_interface.h"
+#include "hw/acpi/tpm.h"
 #include "hw/qdev-properties.h"
 #include "hw/pci/pci_ids.h"
 #include "hw/acpi/tpm.h"
@@ -121,6 +123,11 @@ static void tpm_crb_none_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    if (tpm_crb_none_get_version(TPM_IF(s)) != TPM_VERSION_2_0) {
+        error_setg(errp, "TPM CRB only supports TPM 2.0 backends");
+        return;
+    }
+
     tpm_crb_init_memory(OBJECT(s), &s->state, errp);
 
     /* only used for migration */
@@ -142,10 +149,17 @@ static void tpm_crb_none_realize(DeviceState *dev, Error **errp)
     }
 }
 
+static void build_tpm_crb_none_aml(AcpiDevAmlIf *adev, Aml *scope)
+{
+    tpm_crb_build_aml(TPM_IF(adev), scope, TPM_CRB_ADDR_BASE, TPM_CRB_ADDR_SIZE,
+                      true);
+}
+
 static void tpm_crb_none_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     TPMIfClass *tc = TPM_IF_CLASS(klass);
+    AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
 
     dc->realize = tpm_crb_none_realize;
     device_class_set_props(dc, tpm_crb_none_properties);
@@ -154,6 +168,7 @@ static void tpm_crb_none_class_init(ObjectClass *klass, void *data)
     tc->model = TPM_MODEL_TPM_CRB;
     tc->get_version = tpm_crb_none_get_version;
     tc->request_completed = tpm_crb_none_request_completed;
+    adevc->build_dev_aml = build_tpm_crb_none_aml;
 
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
@@ -166,6 +181,7 @@ static const TypeInfo tpm_crb_none_info = {
     .class_init  = tpm_crb_none_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_TPM_IF },
+        { TYPE_ACPI_DEV_AML_IF },
         { }
     }
 };
diff --git a/hw/tpm/tpm_crb_common.c b/hw/tpm/tpm_crb_common.c
index f96a8cf299..09ca55eece 100644
--- a/hw/tpm/tpm_crb_common.c
+++ b/hw/tpm/tpm_crb_common.c
@@ -241,3 +241,22 @@ void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
     memcpy(regs, saved_regs, A_CRB_DATA_BUFFER);
     memcpy(&regs[R_CRB_DATA_BUFFER], saved_cmdmem, CRB_CTRL_CMD_SIZE);
 }
+
+void tpm_crb_build_aml(TPMIf *ti, Aml *scope, uint32_t baseaddr, uint32_t size,
+                       bool build_ppi)
+{
+    Aml *dev, *crs;
+
+    dev = aml_device("TPM");
+    aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
+    aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
+    aml_append(dev, aml_name_decl("_UID", aml_int(1)));
+    aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));
+    crs = aml_resource_template();
+    aml_append(crs, aml_memory32_fixed(baseaddr, size, AML_READ_WRITE));
+    aml_append(dev, aml_name_decl("_CRS", crs));
+    if (build_ppi) {
+        tpm_build_ppi_acpi(ti, dev);
+    }
+    aml_append(scope, dev);
+}
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 06/14] tpm-sysbus: add plug handler for TPM on SysBus
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (4 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 07/14] hw/arm/virt: connect TPM to platform bus Joelle van Dyne
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Berger, Stefan Berger

TPM needs to know its own base address in order to generate its DSDT
device entry.

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 include/sysemu/tpm.h |  4 ++++
 hw/tpm/tpm-sysbus.c  | 47 ++++++++++++++++++++++++++++++++++++++++++++
 hw/tpm/meson.build   |  1 +
 3 files changed, 52 insertions(+)
 create mode 100644 hw/tpm/tpm-sysbus.c

diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 1ee568b3b6..ffd300e607 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -12,6 +12,8 @@
 #ifndef QEMU_TPM_H
 #define QEMU_TPM_H
 
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
 #include "qapi/qapi-types-tpm.h"
 #include "qom/object.h"
 
@@ -78,6 +80,8 @@ static inline TPMVersion tpm_get_version(TPMIf *ti)
     return TPM_IF_GET_CLASS(ti)->get_version(ti);
 }
 
+void tpm_sysbus_plug(TPMIf *tpmif, Object *pbus, hwaddr pbus_base);
+
 #else /* CONFIG_TPM */
 
 #define tpm_init()  (0)
diff --git a/hw/tpm/tpm-sysbus.c b/hw/tpm/tpm-sysbus.c
new file mode 100644
index 0000000000..732ce34c73
--- /dev/null
+++ b/hw/tpm/tpm-sysbus.c
@@ -0,0 +1,47 @@
+/*
+ * tpm-sysbus.c - Support functions for SysBus TPM devices
+ *
+ * Copyright (c) 2023 QEMU contributors
+ *
+ * Authors:
+ *   Joelle van Dyne <j@getutm.app>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/tpm.h"
+#include "hw/platform-bus.h"
+#include "hw/sysbus.h"
+#include "qapi/error.h"
+
+/**
+ * Called from a machine's pre_plug handler to set the device's physical addr.
+ */
+void tpm_sysbus_plug(TPMIf *tpmif, Object *pbus, hwaddr pbus_base)
+{
+    PlatformBusDevice *pbusdev = PLATFORM_BUS_DEVICE(pbus);
+    SysBusDevice *sbdev = SYS_BUS_DEVICE(tpmif);
+    MemoryRegion *sbdev_mr;
+    hwaddr tpm_base;
+    uint64_t tpm_size;
+
+    /* exit early if TPM is not a sysbus device */
+    if (!object_dynamic_cast(OBJECT(tpmif), TYPE_SYS_BUS_DEVICE)) {
+        return;
+    }
+
+    assert(object_dynamic_cast(pbus, TYPE_PLATFORM_BUS_DEVICE));
+
+    tpm_base = platform_bus_get_mmio_addr(pbusdev, sbdev, 0);
+    assert(tpm_base != -1);
+
+    tpm_base += pbus_base;
+
+    sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
+    tpm_size = memory_region_size(sbdev_mr);
+
+    object_property_set_uint(OBJECT(sbdev), "x-baseaddr",
+                             tpm_base, &error_abort);
+    object_property_set_uint(OBJECT(sbdev), "x-size",
+                             tpm_size, &error_abort);
+}
diff --git a/hw/tpm/meson.build b/hw/tpm/meson.build
index cb8204d5bc..3060ac05e8 100644
--- a/hw/tpm/meson.build
+++ b/hw/tpm/meson.build
@@ -1,6 +1,7 @@
 system_ss.add(when: 'CONFIG_TPM_TIS', if_true: files('tpm_tis_common.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS_ISA', if_true: files('tpm_tis_isa.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS_SYSBUS', if_true: files('tpm_tis_sysbus.c'))
+system_ss.add(when: 'CONFIG_TPM_TIS_SYSBUS', if_true: files('tpm-sysbus.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS_I2C', if_true: files('tpm_tis_i2c.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb_common.c'))
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 07/14] hw/arm/virt: connect TPM to platform bus
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (5 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 06/14] tpm-sysbus: add plug handler for TPM on SysBus Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 08/14] hw/loongarch/virt: " Joelle van Dyne
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Berger, Peter Maydell, open list:Virt

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 hw/arm/virt.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 85e3c5ba9d..36e2506420 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2811,6 +2811,13 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
         vms->virtio_iommu_bdf = pci_get_bdf(pdev);
         create_virtio_iommu_dt_bindings(vms);
     }
+
+#ifdef CONFIG_TPM
+    if (object_dynamic_cast(OBJECT(dev), TYPE_TPM_IF)) {
+        tpm_sysbus_plug(TPM_IF(dev), OBJECT(vms->platform_bus_dev),
+                        vms->memmap[VIRT_PLATFORM_BUS].base);
+    }
+#endif
 }
 
 static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 08/14] hw/loongarch/virt: connect TPM to platform bus
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (6 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 07/14] hw/arm/virt: connect TPM to platform bus Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 09/14] tpm_tis_sysbus: move DSDT AML generation to device Joelle van Dyne
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Berger, Paolo Bonzini, Song Gao

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 hw/loongarch/virt.c  | 7 +++++++
 hw/loongarch/Kconfig | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4b7dc67a2d..feed0f8bbf 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1004,6 +1004,13 @@ static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev,
     } else if (memhp_type_supported(dev)) {
         virt_mem_plug(hotplug_dev, dev, errp);
     }
+
+#ifdef CONFIG_TPM
+    if (object_dynamic_cast(OBJECT(dev), TYPE_TPM_IF)) {
+        tpm_sysbus_plug(TPM_IF(dev), OBJECT(lams->platform_bus_dev),
+                        VIRT_PLATFORM_BUS_BASEADDRESS);
+    }
+#endif
 }
 
 static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 5727efed6d..25da190ffc 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -5,6 +5,7 @@ config LOONGARCH_VIRT
     imply VIRTIO_VGA
     imply PCI_DEVICES
     imply NVDIMM
+    imply TPM_TIS_SYSBUS
     select SERIAL
     select VIRTIO_PCI
     select PLATFORM_BUS
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 09/14] tpm_tis_sysbus: move DSDT AML generation to device
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (7 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 08/14] hw/loongarch/virt: " Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 10/14] tests: acpi: prepare for TPM CRB tests Joelle van Dyne
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Shannon Zhao, Peter Maydell,
	Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Song Gao,
	Stefan Berger, open list:ARM ACPI Subsystem

This reduces redundant code in different machine types with ACPI table
generation. Additionally, this will allow us to support different TPM
interfaces with the same AML logic. Finally, this matches up with the
TPM TIS ISA implementation.

Ideally, we would be able to call `qbus_build_aml` and avoid any TPM
specific code in the ACPI table generation. However, currently we
still have to call `build_tpm2` anyways and it does not look like
most other ACPI devices support the `ACPI_DEV_AML_IF` interface.

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 hw/arm/virt-acpi-build.c  | 38 ++------------------------------------
 hw/loongarch/acpi-build.c | 38 ++------------------------------------
 hw/tpm/tpm_tis_sysbus.c   | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+), 72 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8bc35a483c..499d30eb5d 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -35,6 +35,7 @@
 #include "target/arm/cpu.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/acpi_aml_interface.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/acpi/aml-build.h"
@@ -208,41 +209,6 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap,
     aml_append(scope, dev);
 }
 
-#ifdef CONFIG_TPM
-static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineState *vms)
-{
-    PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
-    hwaddr pbus_base = vms->memmap[VIRT_PLATFORM_BUS].base;
-    SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
-    MemoryRegion *sbdev_mr;
-    hwaddr tpm_base;
-
-    if (!sbdev) {
-        return;
-    }
-
-    tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
-    assert(tpm_base != -1);
-
-    tpm_base += pbus_base;
-
-    sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
-
-    Aml *dev = aml_device("TPM0");
-    aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
-    aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
-    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-
-    Aml *crs = aml_resource_template();
-    aml_append(crs,
-               aml_memory32_fixed(tpm_base,
-                                  (uint32_t)memory_region_size(sbdev_mr),
-                                  AML_READ_WRITE));
-    aml_append(dev, aml_name_decl("_CRS", crs));
-    aml_append(scope, dev);
-}
-#endif
-
 #define ID_MAPPING_ENTRY_SIZE 20
 #define SMMU_V3_ENTRY_SIZE 68
 #define ROOT_COMPLEX_ENTRY_SIZE 36
@@ -891,7 +857,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 
     acpi_dsdt_add_power_button(scope);
 #ifdef CONFIG_TPM
-    acpi_dsdt_add_tpm(scope, vms);
+    call_dev_aml_func(DEVICE(tpm_find()), scope);
 #endif
 
     aml_append(dsdt, scope);
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index ae292fc543..1969bfc8f9 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -14,6 +14,7 @@
 #include "target/loongarch/cpu.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/acpi_aml_interface.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "migration/vmstate.h"
@@ -328,41 +329,6 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
     aml_append(scope, dev);
 }
 
-#ifdef CONFIG_TPM
-static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
-{
-    PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
-    hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
-    SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
-    MemoryRegion *sbdev_mr;
-    hwaddr tpm_base;
-
-    if (!sbdev) {
-        return;
-    }
-
-    tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
-    assert(tpm_base != -1);
-
-    tpm_base += pbus_base;
-
-    sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
-
-    Aml *dev = aml_device("TPM0");
-    aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
-    aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
-    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-
-    Aml *crs = aml_resource_template();
-    aml_append(crs,
-               aml_memory32_fixed(tpm_base,
-                                  (uint32_t)memory_region_size(sbdev_mr),
-                                  AML_READ_WRITE));
-    aml_append(dev, aml_name_decl("_CRS", crs));
-    aml_append(scope, dev);
-}
-#endif
-
 /* build DSDT */
 static void
 build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
@@ -379,7 +345,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
     build_la_ged_aml(dsdt, machine);
     build_flash_aml(dsdt, lams);
 #ifdef CONFIG_TPM
-    acpi_dsdt_add_tpm(dsdt, lams);
+    call_dev_aml_func(DEVICE(tpm_find()), dsdt);
 #endif
     /* System State Package */
     scope = aml_scope("\\");
diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c
index 2fc550f119..462b0e1571 100644
--- a/hw/tpm/tpm_tis_sysbus.c
+++ b/hw/tpm/tpm_tis_sysbus.c
@@ -30,6 +30,7 @@
 #include "hw/sysbus.h"
 #include "tpm_tis.h"
 #include "qom/object.h"
+#include "hw/acpi/acpi_aml_interface.h"
 
 struct TPMStateSysBus {
     /*< private >*/
@@ -37,6 +38,8 @@ struct TPMStateSysBus {
 
     /*< public >*/
     TPMState state; /* not a QOM object */
+    uint64_t baseaddr;
+    uint64_t size;
 };
 
 OBJECT_DECLARE_SIMPLE_TYPE(TPMStateSysBus, TPM_TIS_SYSBUS)
@@ -93,6 +96,10 @@ static void tpm_tis_sysbus_reset(DeviceState *dev)
 static Property tpm_tis_sysbus_properties[] = {
     DEFINE_PROP_UINT32("irq", TPMStateSysBus, state.irq_num, TPM_TIS_IRQ),
     DEFINE_PROP_TPMBE("tpmdev", TPMStateSysBus, state.be_driver),
+    DEFINE_PROP_UINT64("x-baseaddr", TPMStateSysBus, baseaddr,
+                       TPM_TIS_ADDR_BASE),
+    DEFINE_PROP_UINT64("x-size", TPMStateSysBus, size,
+                       TPM_TIS_ADDR_SIZE),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -125,10 +132,38 @@ static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
     }
 }
 
+static void build_tpm_tis_sysbus_aml(AcpiDevAmlIf *adev, Aml *scope)
+{
+    Aml *dev, *crs;
+    TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(adev);
+    TPMIf *ti = TPM_IF(sbdev);
+
+    dev = aml_device("TPM");
+    if (tpm_tis_sysbus_get_tpm_version(ti) == TPM_VERSION_2_0) {
+        aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
+        aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
+    } else {
+        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31")));
+    }
+    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+    aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));
+    crs = aml_resource_template();
+    aml_append(crs, aml_memory32_fixed(sbdev->baseaddr, sbdev->size,
+                                      AML_READ_WRITE));
+    /*
+     * FIXME: TPM_TIS_IRQ=5 conflicts with PNP0C0F irqs,
+     * fix default TPM_TIS_IRQ value there to use some unused IRQ
+     */
+    /* aml_append(crs, aml_irq_no_flags(sbdev->state.irq_num)); */
+    aml_append(dev, aml_name_decl("_CRS", crs));
+    aml_append(scope, dev);
+}
+
 static void tpm_tis_sysbus_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     TPMIfClass *tc = TPM_IF_CLASS(klass);
+    AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
 
     device_class_set_props(dc, tpm_tis_sysbus_properties);
     dc->vmsd  = &vmstate_tpm_tis_sysbus;
@@ -139,6 +174,7 @@ static void tpm_tis_sysbus_class_init(ObjectClass *klass, void *data)
     tc->request_completed = tpm_tis_sysbus_request_completed;
     tc->get_version = tpm_tis_sysbus_get_tpm_version;
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    adevc->build_dev_aml = build_tpm_tis_sysbus_aml;
 }
 
 static const TypeInfo tpm_tis_sysbus_info = {
@@ -149,6 +185,7 @@ static const TypeInfo tpm_tis_sysbus_info = {
     .class_init  = tpm_tis_sysbus_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_TPM_IF },
+        { TYPE_ACPI_DEV_AML_IF },
         { }
     }
 };
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 10/14] tests: acpi: prepare for TPM CRB tests
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (8 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 09/14] tpm_tis_sysbus: move DSDT AML generation to device Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 11/14] tpm_crb_sysbus: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++
 tests/data/acpi/q35/DSDT.crb.tpm2           | 0
 tests/data/acpi/q35/TPM2.crb.tpm2           | 0
 tests/data/acpi/virt/DSDT.crb-device.tpm2   | 0
 tests/data/acpi/virt/TPM2.crb-device.tpm2   | 0
 5 files changed, 4 insertions(+)
 create mode 100644 tests/data/acpi/q35/DSDT.crb.tpm2
 create mode 100644 tests/data/acpi/q35/TPM2.crb.tpm2
 create mode 100644 tests/data/acpi/virt/DSDT.crb-device.tpm2
 create mode 100644 tests/data/acpi/virt/TPM2.crb-device.tpm2

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..c2d1924c2f 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,5 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT.crb.tpm2",
+"tests/data/acpi/q35/TPM2.crb.tpm2",
+"tests/data/acpi/virt/DSDT.crb.tpm2",
+"tests/data/acpi/virt/TPM2.crb.tpm2",
diff --git a/tests/data/acpi/q35/DSDT.crb.tpm2 b/tests/data/acpi/q35/DSDT.crb.tpm2
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/data/acpi/q35/TPM2.crb.tpm2 b/tests/data/acpi/q35/TPM2.crb.tpm2
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/data/acpi/virt/DSDT.crb-device.tpm2 b/tests/data/acpi/virt/DSDT.crb-device.tpm2
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/data/acpi/virt/TPM2.crb-device.tpm2 b/tests/data/acpi/virt/TPM2.crb-device.tpm2
new file mode 100644
index 0000000000..e69de29bb2
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 11/14] tpm_crb_sysbus: introduce TPM CRB SysBus device
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (9 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 10/14] tests: acpi: prepare for TPM CRB tests Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt Joelle van Dyne
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Stefan Berger,
	Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
	Peter Maydell, Song Gao, Palmer Dabbelt, Alistair Francis,
	Bin Meng, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	open list:ARM TCG CPUs, open list:RISC-V TCG CPUs

This SysBus variant of the CRB interface supports dynamically locating
the MMIO interface so that Virt machines can use it. This interface
is currently the only one supported by QEMU that works on Windows 11
ARM64 as 'tpm-tis-device' does not work with current Windows drivers.
We largely follow that device as a template.

To try out this device with Windows 11 before OVMF is updated, you
will need to modify `sysbus-fdt.c` and change the added line from:

```c
    TYPE_BINDING(TYPE_TPM_CRB_SYSBUS, no_fdt_node),
```

to

```c
    TYPE_BINDING(TYPE_TPM_CRB_SYSBUS, add_tpm_tis_fdt_node),
```

This change was not included because it can confuse Linux (although
from testing, it seems like Linux is able to properly ignore the
device from the TPM TIS driver and recognize it from the ACPI device
in the TPM CRB driver). A proper fix would require OVMF to recognize
the ACPI device and not depend on the FDT node for recognizing TPM.

The command line to try out this device with SWTPM is:

```
$ qemu-system-aarch64 \
    -chardev socket,id=chrtpm0,path=tpm.sock \
    -tpmdev emulator,id=tpm0,chardev=chrtpm0 \
    -device tpm-crb-device,tpmdev=tpm0
```

along with SWTPM:

```
$ swtpm \
    --ctrl type=unixio,path=tpm.sock,terminate \
    --tpmstate backend-uri=file://tpm.data \
    --tpm2
```

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 docs/specs/tpm.rst      |   1 +
 include/sysemu/tpm.h    |   3 +
 hw/acpi/aml-build.c     |   7 +-
 hw/arm/virt.c           |   1 +
 hw/core/sysbus-fdt.c    |   1 +
 hw/loongarch/virt.c     |   1 +
 hw/riscv/virt.c         |   1 +
 hw/tpm/tpm_crb_sysbus.c | 162 ++++++++++++++++++++++++++++++++++++++++
 hw/arm/Kconfig          |   1 +
 hw/loongarch/Kconfig    |   1 +
 hw/riscv/Kconfig        |   1 +
 hw/tpm/Kconfig          |   5 ++
 hw/tpm/meson.build      |   3 +
 13 files changed, 187 insertions(+), 1 deletion(-)
 create mode 100644 hw/tpm/tpm_crb_sysbus.c

diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
index 2bc29c9804..95aeb49220 100644
--- a/docs/specs/tpm.rst
+++ b/docs/specs/tpm.rst
@@ -46,6 +46,7 @@ operating system.
 QEMU files related to TPM CRB interface:
  - ``hw/tpm/tpm_crb.c``
  - ``hw/tpm/tpm_crb_common.c``
+ - ``hw/tpm/tpm_crb_sysbus.c``
 
 SPAPR interface
 ---------------
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index ffd300e607..bab30fa546 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -49,6 +49,7 @@ struct TPMIfClass {
 #define TYPE_TPM_TIS_ISA            "tpm-tis"
 #define TYPE_TPM_TIS_SYSBUS         "tpm-tis-device"
 #define TYPE_TPM_CRB                "tpm-crb"
+#define TYPE_TPM_CRB_SYSBUS         "tpm-crb-device"
 #define TYPE_TPM_SPAPR              "tpm-spapr"
 #define TYPE_TPM_TIS_I2C            "tpm-tis-i2c"
 
@@ -58,6 +59,8 @@ struct TPMIfClass {
     object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_SYSBUS)
 #define TPM_IS_CRB(chr)                             \
     object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
+#define TPM_IS_CRB_SYSBUS(chr)                      \
+    object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB_SYSBUS)
 #define TPM_IS_SPAPR(chr)                           \
     object_dynamic_cast(OBJECT(chr), TYPE_TPM_SPAPR)
 #define TPM_IS_TIS_I2C(chr)                      \
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index af66bde0f5..acc654382e 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -31,6 +31,7 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_bridge.h"
 #include "qemu/cutils.h"
+#include "qom/object.h"
 
 static GArray *build_alloc_array(void)
 {
@@ -2218,7 +2219,7 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
 {
     uint8_t start_method_params[12] = {};
     unsigned log_addr_offset;
-    uint64_t control_area_start_address;
+    uint64_t baseaddr, control_area_start_address;
     TPMIf *tpmif = tpm_find();
     uint32_t start_method;
     AcpiTable table = { .sig = "TPM2", .rev = 4,
@@ -2236,6 +2237,10 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
     } else if (TPM_IS_CRB(tpmif)) {
         control_area_start_address = TPM_CRB_ADDR_CTRL;
         start_method = TPM2_START_METHOD_CRB;
+    } else if (TPM_IS_CRB_SYSBUS(tpmif)) {
+        baseaddr = object_property_get_uint(OBJECT(tpmif), "x-baseaddr", NULL);
+        control_area_start_address = baseaddr + A_CRB_CTRL_REQ;
+        start_method = TPM2_START_METHOD_CRB;
     } else {
         g_assert_not_reached();
     }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 36e2506420..e6152a2f51 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2955,6 +2955,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
 #ifdef CONFIG_TPM
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_CRB_SYSBUS);
 #endif
     mc->block_default_type = IF_VIRTIO;
     mc->no_cdrom = 1;
diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
index eebcd28f9a..9c783f88eb 100644
--- a/hw/core/sysbus-fdt.c
+++ b/hw/core/sysbus-fdt.c
@@ -493,6 +493,7 @@ static const BindingEntry bindings[] = {
 #endif
 #ifdef CONFIG_TPM
     TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
+    TYPE_BINDING(TYPE_TPM_CRB_SYSBUS, no_fdt_node),
 #endif
     TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
     TYPE_BINDING("", NULL), /* last element */
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index feed0f8bbf..9d5ad2bc8e 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1114,6 +1114,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 #ifdef CONFIG_TPM
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_CRB_SYSBUS);
 #endif
 }
 
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index c7fc97e273..4cce0b14ab 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1702,6 +1702,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 #ifdef CONFIG_TPM
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_CRB_SYSBUS);
 #endif
 
 
diff --git a/hw/tpm/tpm_crb_sysbus.c b/hw/tpm/tpm_crb_sysbus.c
new file mode 100644
index 0000000000..7edeae3665
--- /dev/null
+++ b/hw/tpm/tpm_crb_sysbus.c
@@ -0,0 +1,162 @@
+/*
+ * tpm_crb_sysbus.c - QEMU's TPM CRB interface emulator
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *   Joelle van Dyne <j@getutm.app>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * tpm_crb is a device for TPM 2.0 Command Response Buffer (CRB) Interface
+ * as defined in TCG PC Client Platform TPM Profile (PTP) Specification
+ * Family “2.0” Level 00 Revision 01.03 v22
+ */
+
+#include "qemu/osdep.h"
+#include "hw/acpi/acpi_aml_interface.h"
+#include "hw/acpi/tpm.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "tpm_prop.h"
+#include "hw/sysbus.h"
+#include "qapi/visitor.h"
+#include "qom/object.h"
+#include "sysemu/tpm_util.h"
+#include "trace.h"
+#include "tpm_crb.h"
+
+struct TPMCRBStateSysBus {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    TPMCRBState state;
+    uint64_t baseaddr;
+    uint64_t size;
+};
+
+OBJECT_DECLARE_SIMPLE_TYPE(TPMCRBStateSysBus, TPM_CRB_SYSBUS)
+
+static void tpm_crb_sysbus_request_completed(TPMIf *ti, int ret)
+{
+    TPMCRBStateSysBus *s = TPM_CRB_SYSBUS(ti);
+
+    return tpm_crb_request_completed(&s->state, ret);
+}
+
+static enum TPMVersion tpm_crb_sysbus_get_tpm_version(TPMIf *ti)
+{
+    TPMCRBStateSysBus *s = TPM_CRB_SYSBUS(ti);
+
+    return tpm_crb_get_version(&s->state);
+}
+
+static int tpm_crb_sysbus_pre_save(void *opaque)
+{
+    TPMCRBStateSysBus *s = opaque;
+
+    return tpm_crb_pre_save(&s->state);
+}
+
+static const VMStateDescription vmstate_tpm_crb_sysbus = {
+    .name = "tpm-crb-sysbus",
+    .pre_save = tpm_crb_sysbus_pre_save,
+    .fields = (VMStateField[]) {
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
+static Property tpm_crb_sysbus_properties[] = {
+    DEFINE_PROP_TPMBE("tpmdev", TPMCRBStateSysBus, state.tpmbe),
+    DEFINE_PROP_UINT64("x-baseaddr", TPMCRBStateSysBus,
+                       baseaddr, TPM_CRB_ADDR_BASE),
+    DEFINE_PROP_UINT64("x-size", TPMCRBStateSysBus,
+                       size, TPM_CRB_ADDR_SIZE),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void tpm_crb_sysbus_initfn(Object *obj)
+{
+    TPMCRBStateSysBus *s = TPM_CRB_SYSBUS(obj);
+
+    tpm_crb_init_memory(obj, &s->state, NULL);
+
+    vmstate_register_ram(&s->state.mmio, DEVICE(obj));
+
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->state.mmio);
+}
+
+static void tpm_crb_sysbus_reset(DeviceState *dev)
+{
+    TPMCRBStateSysBus *s = TPM_CRB_SYSBUS(dev);
+
+    return tpm_crb_reset(&s->state, s->baseaddr);
+}
+
+static void tpm_crb_sysbus_realizefn(DeviceState *dev, Error **errp)
+{
+    TPMCRBStateSysBus *s = TPM_CRB_SYSBUS(dev);
+
+    if (!tpm_find()) {
+        error_setg(errp, "at most one TPM device is permitted");
+        return;
+    }
+
+    if (!s->state.tpmbe) {
+        error_setg(errp, "'tpmdev' property is required");
+        return;
+    }
+
+    if (tpm_crb_sysbus_get_tpm_version(TPM_IF(s)) != TPM_VERSION_2_0) {
+        error_setg(errp, "TPM CRB only supports TPM 2.0 backends");
+        return;
+    }
+}
+
+static void build_tpm_crb_sysbus_aml(AcpiDevAmlIf *adev, Aml *scope)
+{
+    TPMCRBStateSysBus *s = TPM_CRB_SYSBUS(adev);
+
+    tpm_crb_build_aml(TPM_IF(adev), scope, s->baseaddr, s->size, false);
+}
+
+static void tpm_crb_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    TPMIfClass *tc = TPM_IF_CLASS(klass);
+    AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
+
+    device_class_set_props(dc, tpm_crb_sysbus_properties);
+    dc->vmsd  = &vmstate_tpm_crb_sysbus;
+    tc->model = TPM_MODEL_TPM_CRB;
+    dc->realize = tpm_crb_sysbus_realizefn;
+    dc->user_creatable = true;
+    dc->reset = tpm_crb_sysbus_reset;
+    tc->request_completed = tpm_crb_sysbus_request_completed;
+    tc->get_version = tpm_crb_sysbus_get_tpm_version;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    adevc->build_dev_aml = build_tpm_crb_sysbus_aml;
+}
+
+static const TypeInfo tpm_crb_sysbus_info = {
+    .name = TYPE_TPM_CRB_SYSBUS,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TPMCRBStateSysBus),
+    .instance_init = tpm_crb_sysbus_initfn,
+    .class_init  = tpm_crb_sysbus_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_TPM_IF },
+        { TYPE_ACPI_DEV_AML_IF },
+        { }
+    }
+};
+
+static void tpm_crb_sysbus_register(void)
+{
+    type_register_static(&tpm_crb_sysbus_info);
+}
+
+type_init(tpm_crb_sysbus_register)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3ada335a24..f524994fd3 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_CRB_SYSBUS
     imply TPM_TIS_SYSBUS
     imply TPM_TIS_I2C
     imply NVDIMM
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 25da190ffc..70544f3ce5 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -6,6 +6,7 @@ config LOONGARCH_VIRT
     imply PCI_DEVICES
     imply NVDIMM
     imply TPM_TIS_SYSBUS
+    imply TPM_CRB_SYSBUS
     select SERIAL
     select VIRTIO_PCI
     select PLATFORM_BUS
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index b6a5eb4452..d824cb58f9 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -29,6 +29,7 @@ config RISCV_VIRT
     imply PCI_DEVICES
     imply VIRTIO_VGA
     imply TEST_DEVICES
+    imply TPM_CRB_SYSBUS
     imply TPM_TIS_SYSBUS
     select RISCV_NUMA
     select GOLDFISH_RTC
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
index a46663288c..28139c456a 100644
--- a/hw/tpm/Kconfig
+++ b/hw/tpm/Kconfig
@@ -25,6 +25,11 @@ config TPM_CRB
     depends on TPM && PC
     select TPM_BACKEND
 
+config TPM_CRB_SYSBUS
+    bool
+    depends on TPM
+    select TPM_BACKEND
+
 config TPM_SPAPR
     bool
     default y
diff --git a/hw/tpm/meson.build b/hw/tpm/meson.build
index 3060ac05e8..f2536c99e3 100644
--- a/hw/tpm/meson.build
+++ b/hw/tpm/meson.build
@@ -5,6 +5,9 @@ system_ss.add(when: 'CONFIG_TPM_TIS_SYSBUS', if_true: files('tpm-sysbus.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS_I2C', if_true: files('tpm_tis_i2c.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb_common.c'))
+system_ss.add(when: 'CONFIG_TPM_CRB_SYSBUS', if_true: files('tpm_crb_sysbus.c'))
+system_ss.add(when: 'CONFIG_TPM_CRB_SYSBUS', if_true: files('tpm_crb_common.c'))
+system_ss.add(when: 'CONFIG_TPM_CRB_SYSBUS', if_true: files('tpm-sysbus.c'))
 system_ss.add(when: 'CONFIG_TPM_TIS', if_true: files('tpm_ppi.c'))
 system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_ppi.c'))
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (10 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 11/14] tpm_crb_sysbus: introduce TPM CRB SysBus device Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  9:36   ` Marc-André Lureau
  2023-11-14  2:09 ` [PATCH v5 13/14] tests: acpi: updated expected blobs for TPM CRB Joelle van Dyne
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 tests/qtest/bios-tables-test.c | 43 ++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 71af5cf69f..bb4ebf00c1 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1447,6 +1447,28 @@ static void test_acpi_piix4_tcg_numamem(void)
 
 uint64_t tpm_tis_base_addr;
 
+static test_data tcg_tpm_test_data(const char *machine)
+{
+    if (g_strcmp0(machine, "virt") == 0) {
+        test_data data = {
+            .machine = "virt",
+            .tcg_only = true,
+            .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+            .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+            .cd =
+               "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+            .ram_start = 0x40000000ULL,
+            .scan_len = 128ULL * 1024 * 1024,
+        };
+        return data;
+    } else {
+        test_data data = {
+            .machine = machine,
+        };
+        return data;
+    }
+}
+
 static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
                               uint64_t base, enum TPMVersion tpm_version)
 {
@@ -1454,7 +1476,7 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
                                           machine, tpm_if);
     char *tmp_path = g_dir_make_tmp(tmp_dir_name, NULL);
     TPMTestState test;
-    test_data data = {};
+    test_data data = tcg_tpm_test_data(machine);
     GThread *thread;
     const char *suffix = tpm_version == TPM_VERSION_2_0 ? "tpm2" : "tpm12";
     char *args, *variant = g_strdup_printf(".%s.%s", tpm_if, suffix);
@@ -1474,13 +1496,14 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
     thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
     tpm_emu_test_wait_cond(&test);
 
-    data.machine = machine;
     data.variant = variant;
 
     args = g_strdup_printf(
+        " %s"
         " -chardev socket,id=chr,path=%s"
         " -tpmdev emulator,id=dev,chardev=chr"
         " -device tpm-%s,tpmdev=dev",
+        g_strcmp0(machine, "virt") == 0 ? "-cpu cortex-a57" : "",
         test.addr->u.q_unix.path, tpm_if);
 
     test_acpi_one(args, &data);
@@ -1506,6 +1529,16 @@ static void test_acpi_q35_tcg_tpm12_tis(void)
     test_acpi_tcg_tpm("q35", "tis", 0xFED40000, TPM_VERSION_1_2);
 }
 
+static void test_acpi_q35_tcg_tpm2_crb(void)
+{
+    test_acpi_tcg_tpm("q35", "crb", 0xFED40000, TPM_VERSION_2_0);
+}
+
+static void test_acpi_virt_tcg_tpm2_crb(void)
+{
+    test_acpi_tcg_tpm("virt", "crb-device", 0xFED40000, TPM_VERSION_2_0);
+}
+
 static void test_acpi_tcg_dimm_pxm(const char *machine)
 {
     test_data data = {};
@@ -2212,6 +2245,9 @@ int main(int argc, char *argv[])
                 qtest_add_func("acpi/q35/tpm12-tis",
                                test_acpi_q35_tcg_tpm12_tis);
             }
+            if (tpm_model_is_available("-machine q35", "tpm-crb")) {
+                qtest_add_func("acpi/q35/tpm2-crb", test_acpi_q35_tcg_tpm2_crb);
+            }
             qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
             qtest_add_func("acpi/q35/no-acpi-hotplug",
                            test_acpi_q35_tcg_no_acpi_hotplug);
@@ -2301,6 +2337,9 @@ int main(int argc, char *argv[])
                 qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
             }
         }
+        if (tpm_model_is_available("-machine virt", "tpm-crb")) {
+            qtest_add_func("acpi/virt/tpm2-crb", test_acpi_virt_tcg_tpm2_crb);
+        }
     }
     ret = g_test_run();
     boot_sector_cleanup(disk);
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 13/14] tests: acpi: updated expected blobs for TPM CRB
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (11 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  2:09 ` [PATCH v5 14/14] tests: add TPM-CRB sysbus tests for aarch64 Joelle van Dyne
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha

Signed-off-by: Joelle van Dyne <j@getutm.app>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
---
 tests/qtest/bios-tables-test-allowed-diff.h |   4 ----
 tests/data/acpi/q35/DSDT.crb.tpm2           | Bin 0 -> 8355 bytes
 tests/data/acpi/q35/TPM2.crb.tpm2           | Bin 0 -> 76 bytes
 tests/data/acpi/virt/DSDT.crb-device.tpm2   | Bin 0 -> 5276 bytes
 tests/data/acpi/virt/TPM2.crb-device.tpm2   | Bin 0 -> 76 bytes
 5 files changed, 4 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index c2d1924c2f..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,5 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/DSDT.crb.tpm2",
-"tests/data/acpi/q35/TPM2.crb.tpm2",
-"tests/data/acpi/virt/DSDT.crb.tpm2",
-"tests/data/acpi/virt/TPM2.crb.tpm2",
diff --git a/tests/data/acpi/q35/DSDT.crb.tpm2 b/tests/data/acpi/q35/DSDT.crb.tpm2
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fb89ae0ac6d4346e33156e9e4d3718698a0a1a8e 100644
GIT binary patch
literal 8355
zcmb7JOKcm*8J^`sS}m8-l3H7S#U`8>eWXYzJ1?|oP;!?qOOz=tWv8G4E+waxod8)R
zF%Ty(AS*!P_|$}T&?B8HKyU4-*Ba=hz4_JvJ@wE_u0;`_qJIC(jy<!afQkol|Jm>R
z|M_Nj=UdMBf#3Umi815V>Lsrkl&WuZyb?YJV~mdJ*J)+0vi^==Z48WDDr5BT<oGeZ
zs;2uBzq-*dezzTd8HVqF8XCihZGPq4-yB9C-wihzfo^U_mPH57%HklX4*I*Tg^t%M
zn}cS{w=0h<(;Rr>C~XclT0V1EX9t%8FLUoL=J{8a$7|Wqc45(S`t5&S`0mW9UwnDx
z{mR3i|KnHp-m)?PoX4+;-wP3ag&&31>2U0PF}iNtCOSX2JYM`_#7~Phht5PHwLGvz
z6Qx?-d&^zP*8HHIAHOoX!J<OiVBz@07or1?Uj6&OgO@*Sf4=l>`}kkI_Fg!iy?@<G
z?S+wb=WfUt8cvOFShG<vn__tuViewHY#0s2$^PzZez)Rr<@wH9r|gxN8Ps=!!Wrw-
zr%R04H01R8)BgVcU&JAEZZT)oeSrp#2Cl!;@q(U_duUr`|Bgd}hxUyUzWh>uC#YS-
zrTUv~WpJ%1@T%q7MVzRvwYx^{k)ToFRo6D!rB2I#qtrL5tKJH8&vm@o#Z>=UiuU)T
zZ9+u1jO&bY^nXCjd(3^l0?srP<%;MljIp6xo$K)N^k)t=pcpkO!Uqsv2HV7CxINlr
zqfHxQv(Ii1jp6O#EyJ39I>6&|+UO?|M4RF=n4OkaXRbZKuMuri<m_HHXnY;-TYhhL
zy1h<u<-MI^E|Wv8)wPux6UPRQ>#S%~yOl!FkU<(jlNIwB^beO&;Npl_0M3hZoCl~3
ziHZCio8nAh<A|6Nnqr&@C}$!hCVIoMY0i{ANHbzeXj(7<<xGUclvOgEDSMFNObN{h
zrtCaIRcBVyndM9g%?hUMJVI6HjHYvjGbMCJ*NIToIjiZM)pXA4IuWWmO--k%=`?kn
z2vwbPn$9^*=bWw+p{mo;bXuBDOV^1|)tS?D<}{r-T_-|Sr>*I<HJ!Gu6QQazuj$Nd
zI`g_tgsRSYP3OF(b6(epP}RAh>0HosF6cTDsyZD_r=#g~be#xQodr#2LDN~#bs|)C
z7B!tkO=nTpiBQ$KsOenPbS~;T5vn>}O{c5rbakBwRh>sPokujCM|7PCRh>sQokumD
zM|GVDRh_UgF=z2vX-U($r0Ybe>O7|DJf`V9rt3tg>O9Vwm3SsR&Y9JCvO6xA-qVnn
zevCb#F;8gB6FL*2$~>ttPioAQIuoJFJf$&DY0OhP6QRm{Mq@ssF`v<y2vz23&XjZf
zY0i{${At0I6E{L)N+&s^)jXrsJfqh{C~BH8(28Q9ji80n+)ND|qi}4X2vAl8X#}z;
z3{>FwO=K`)$^IEADxgmc6rq#`0~J_lpbC@>R6w5?C_?l`8mPd=5!FOi>6pZnBSr>_
z5Iy2p7^uL;QLK?O$v_2EhN?~&s7TA1Fi-_b28vL+A{i(`sS^e&u$&14RiI>`0?KQW
zfg+STVW0xbnJ`cVN(L&RoJj_XQ0jz%3M^;BKouw%sDN@N87M+|Jz<~%%b74x1xf}g
zpqxnticso=feI{V!ax-$8K{7ACK)I~sS^e&u$&14RiI>`0?L_Wpa`W-7^uK<CJa=8
zl7R{+XOe*;lsaLc0?U~&Pz6c`DxjQ628vMXgn<eyXTm@gC>f}LawZulLa7r5DzKah
z16818paRO7WS|J8P8g`bawZH^fs%m=C})y^B9uB|paRR8Fi-_b1}dPONd}5g>V$y`
zEN8+%6(|{~fN~}oC_<?d1}d<e2?JH2WS|1dnPi{{rA`>Az;Y%GRDqI#3Mglifg+ST
zVW0xbnJ`cVN(L&RoJj_XQ0jz%3M^;BKouw%sDN@N87M-j69y`<oCyO}pk$x|%9&)K
z2&GOKsK9b23{-)VfeI*Rl7S+WI$@xQ6az)18Yn{5KoKeisxV=o3X=>}VUmF=Oc<!b
zgn=qdGEjv{2C6V&pb8TPsxZkw6($*|!i0e;Oc<!bBm-5LWS|NY28u{tT^J}LTrobF
zWS|If8DvOIIkqrRL~?9lporwyl7S+WV@n2#5NjYO2Cz^zwnzNW>K^?eeK12m6?d_<
zj{pDTxsR-!ZMJ94?O8eZrPjLForCRm%Y}I>_t^}a<4Xy**ga~qviNRAA8lI;jE<0~
zTkh|!&cf#_awW!I5bG}{N(Y6b*5YULY%UFlVwi&&W>a>HxeJ4!S7Ce9g-&<9;uZ#e
zD`2<j*xKPO3$&m?2(QcIr9sdQjC<R0AE-RF$JMKe>c%0eSC#5jUcHL`snx6Q^y=0A
zZkx1=wHT~I#oDdZA<BD7d5@R(66L)E%6oBnKOx@23fTWW_P$cy=jHuGdH;a&eq6qm
zET1_<`I=I`#>>|d<!c9&uf^r-$@1All&>r0>%4qDQNDga`FdQwkt{!Ri1H1ke1n&7
zB+54qDBp<7H<RUO4^h6UlyCC#%|!X;0p*)0pP}g}S>6%l<>Y}^13d0xaZ+z{XZRzJ
zA9}9ibjioqD(LC(zA%wav`tMn@mv=5ba;uFNGIB+rki-q7WH&^vzSOH+NP$Pcy3%h
z9bPvk(uuaI=_a0oBYHZ#gG{6oZBx@t+}B6-ba*kDNGIB+rkl7=m-KXaTbW2F+Vpfz
z+Z4<HHM7~N_2lhmV9KLK|Nc(1(`z%lc|ZC-$FOwmP`r4#w&s^QU4Kw=U*XOZQA-$6
z)9}O4a>B9w`6y(g5bLpfY&`$@Xvls$wAsJ@o85ys!qRAYy<p9Mg1;b?oZ-(J7S!EA
zqa&_kzT$OS<#PEI=3IJRbg^k&eK9T9+dJJ_AbV?JjzDkoUT34!eCPe>?VG<Yz5C{S
z@7#QM>&^FA-|#xCEAc~<x2%Tojs1;n*teh#(>m7dzp*X5f9Ho3R9MOD)Yc5IwH6p&
zw|&{b%6pl<>IO@DUfaj&evy!AFQ~1S0QW1s5|*u7Yb`Tk)QE@g!d1R8fDVaH#%h+!
z)D5w%l64DSul~!_*cxrKPdrGy?lxzzZBUu(KYR7Xj4G4_(7J!J8O0*n2^l3%kc7xu
zz<U40nbnoO&~0Z)*5L{n$yCTNHNRUw>IL4Kd4LSlTdQ3uruHMY6&csQ@{6NuM#Qc~
zMi{Z-SF84KMxk+k3r%6Pl`P2xCmV55#!L5;t+*^(UytWTLu(&pzK*7yA3rxSa&+CJ
zt-I96A-g$5uO7TQet81M?+jeNEh`;O3=B?!cXNxj-D(-J??wqX*%n=LXxr*9PZu|l
z3;nsdIenPhbKa$(XCE-k)9;pv{209G`joMWtW>g<pf{3@80M+H>wo+j-P81RGuqX`
zeQoa1-Hj)pUFj8amdUViL9fH^JT?}4ITFLRuitP_;^DzGFsPN!v-pXp2Z`<}r+q{`
zS$sc;Pa+p{)}Qa@SqgI$KKt}#G>pggW7{y%ZrIp?VeC7cer!L9^VmLO>_2>SkDsTv
z>HU3ro2E~SY1@7#cDDW~&agjdXC7id@OyFQ;p_LF$5vsSO|+3Z+7^RQ?L#r9pIt8l
zonp_G?>ts8-HEA;+LbvBlXS0Q<;1kf=djXDX~w`FWPkT!rqk?n`COPtf<c-xA5P|a
zXg{=#W0-z_bQR@;3xncJ#z5b3{L-LkW~`Kj^*cl_(-~6Y{Osvv=<mKzzv2nI%&*tl
z8@TM}37zP%lXbE*>pHcQS7~x{+9&8L_IGnZxjZlj6~7BLKMu;Ti2zs3VDRu@*=N|@
z#KC!aaDfh>+zska!DnbbZ*|vGR%qFdm*GYFcYgX}n#vH8&KmSD2mi>{tMuj3mv1td
z*?NtR>-5#2ucq1GeQBlYqcdVlJPl7IO|f|$vyL>3kcG^^?RJe_!|&M?zpBr*FKs+w
zE#Rd_VVPF;ENvb4ch9eOddo6*2IB<>!{00g>sa}Q@j?27v}vB*;hE2Sm)cJ_S)iwL
z9;Y9tnR(XXoO9it_oO#D)FJ2PsUsFK!#v9j>drz?uf*e?Vi-zlsKyOxG&nXrlX!Wk
HVR!t0z{JvO

literal 0
HcmV?d00001

diff --git a/tests/data/acpi/q35/TPM2.crb.tpm2 b/tests/data/acpi/q35/TPM2.crb.tpm2
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9d89c5becc0fc4558a0556daf46e152181f2eb51 100644
GIT binary patch
literal 76
zcmWFu@HO&bU|?Wja`Jcf2v%^42yj*a0!E-1hz+7az=7e)KM>6hB2WNG#ec9c0JCKY
A0RR91

literal 0
HcmV?d00001

diff --git a/tests/data/acpi/virt/DSDT.crb-device.tpm2 b/tests/data/acpi/virt/DSDT.crb-device.tpm2
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1b3a8ef4cb3ab093402f4bdb2a349b3d0d015ad5 100644
GIT binary patch
literal 5276
zcmZvg%WoT16o>D`lh__VVmr?JVHZlpGaB1Xla{u`9y^IkoEVSWAf=KkRYjC+Dp6G`
z6;jBeh3;r1RxE-P3H}TuR_xfZV9kbqfF0&{=guVOsAr^%=gi#m&Hcv5@$qf?&Hj%?
zrAB^f?0Q>%x$$Y&D`T^iQu<iG=3Z=CcL#oBuzxh?xvrZSY_*%2y4P(ZSXGI^?RHb`
zA6@fyJJGdXXUlafmGD|(;Pw3coHPAAsWdRDa!P$SrY!3MqNm7R+t~9q4EK{(=Qg-i
z<of-(lR~mrw+tfhWDQ~@ITL2q?K{0_O4~cVU8Js@-}Wr?{N|1t32*LFM8({lBlK-w
zLyV|%L?uKt^en0p!WoemHepmLqb4$95@U=oYLszVWY`iTK^T`QV?|_)N(_fERw(0&
z$QY9tX~MWd8LJ{AE-|u%u}T?hA|oL&a)hx)8COL{QeqSc<0@fP!Vd>8F~^Y@MZ&m7
z8Dg384@p$&Q-tv$Wyp1!mgX@-7}qI7uG5Ufm?MlElp)t?R$?p=#!bqQ>vUXVED^>>
zlp)t?PGXb^W1TYOI?YRrHwdFn8FHN#B*sO;Xi$b+rxOz65@C3RQI+eoC^6n9j3#Bs
zbvh|A-X)9{Wyp0pB{AM7j19_=>vURTEEC2iWyp0pBQadU*rE)%PG==Xl`z_rA=l}g
z#JEftw<trd(|L(;g)ly*47pAhB*q$HY*U6@r;8Hf8ewz@qbAqslEk=97(0|9*J(*&
z+$4<Mkg@Y~*K3FK=<amgy1Rzv!$W&yqMGhvTASE68arogiQn(#OU^=9d8(}*sIqeL
z*Tm5i^-$f%tJ095@#yyY6Wd=phlP}#8V=Q_-*%Nbws2fgg|t5Jj3B5+K@34n6*6{u
zIJA_`!MHHeSs0i#*Md9@jY6FXelQkYk{KIDIx`xI7D(R_LxW6&Iy1UUEXa&z5K}rc
z8X7a17#d_E)R~x3a2GqsjAmd5nbA<ROrd3viI94ZGSAT<Gx8iYnbG7CQqM8wiKZ0u
ziH4%ZqMit;XPkM)nP;4PBBY)P=9yrgXvwH2Lh6}ho@l4d(+eI+l6xYgo(}VLm?v5|
z>WPqgrkH1nd8W80Lh6}jo@wTZmXCTOq@Ee(nPHw8?un3kW|?P}d7?$6o(QSuIP)B5
zp5xpTA@#)18B^my73Y{IT1x7Pkb35sXP$ZHxhF#ESzw+8=7|=RdLpEr6U=jhc}{Ro
zgwzv16p3e%d7@>do(QSuB=ekPo|D`YA@!VMo>R;dEiUy$NIj>S=QQ)2=AH<tCw^QK
z&l%>4mY8}Xq@J_PbC!9|a!-WRbB=k=F;BG6)Dt1~oM)c%%yXW5BBY)R%yWTxqUENZ
z2&v~H^IT+}i`)|-^;}|}OUx53I`u?IJxk29#5_yf6QS|kKWf|htu#O1^p~>dZk&A)
zcd;yybyC4n#GAoaI=**bJ69YV_&whWQDMixP*^9RsEY#1oI69^(z6O1T!zx?1(fxc
zz%u7JD{OQ*3+o1ybxB~Eb0Mpk8+eVnI>rA`m0QQoJdUln^Z4708o|GFY(u@XUf|P}
zMt2cxx#93X{j&_)a2Z#uG<pEDp=rT3#8peZe2?S=mk;$dy#>+vPM?3O68`OOS0%iD
zZ(9{Nl7n5}vtJ%4uenz_*@_>3o}X}X`<=gP|CSckf7p9m|MkY7pS?VAYz(O4HG$XK
zBOPdtKB#HbGre<4dVi98b^Or!8doa8=*r2|tK(>#Ii1rNAL+sR{OQ3@S#w_Bq;h&t
z{9w@ZJNC&1Gn+qFfB)NG`Kt5%^go^1-@MLA^7spNnvYqQ-eIAuWA|D<t46)hrE9L{
zxUW5*;61?8DXpJB8hwQC8?$cKh~Hh-D|4Hz=D?J=S(dBl#uLkO8C(eYrp{y5J0|t8
z)k9y3cQlc7?EP<2I`mq8Yr9-r9JKEAlaF+8?<9Bp?4G0hz31J%Uc))uKbqAC^z-DI
zd%<qU?sq%kL^}RP->tZM4G{fq1{ccJWw+dX@Z{nB2POj_8@<G*f34#IoGtEQRuFuu
F{s$^RBs~BC

literal 0
HcmV?d00001

diff --git a/tests/data/acpi/virt/TPM2.crb-device.tpm2 b/tests/data/acpi/virt/TPM2.crb-device.tpm2
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b2d9268351fcfdc634131e326bfafdd306dc639c 100644
GIT binary patch
literal 76
zcmWFu@HO&bU|?W5<mB({5v<@85#X!<1dKp25F12;fCB>q4~S+55hwtp;-oW32mq=x
B2mt^9

literal 0
HcmV?d00001

-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v5 14/14] tests: add TPM-CRB sysbus tests for aarch64
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (12 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 13/14] tests: acpi: updated expected blobs for TPM CRB Joelle van Dyne
@ 2023-11-14  2:09 ` Joelle van Dyne
  2023-11-14  9:38 ` [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Marc-André Lureau
  2024-04-30 11:54 ` Peter Maydell
  15 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14  2:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Joelle van Dyne, Stefan Berger, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha, Thomas Huth, Laurent Vivier,
	Paolo Bonzini, Stefan Berger

- Factor out common test code from tpm-crb-test.c -> tpm-tests.c
- Store device addr in `tpm_device_base_addr` (unify with TIS tests)
- Add new tests for aarch64

Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 tests/qtest/tpm-tests.h                 |   2 +
 tests/qtest/tpm-util.h                  |   4 +-
 tests/qtest/bios-tables-test.c          |   4 +-
 tests/qtest/tpm-crb-device-swtpm-test.c |  72 ++++++++++++++
 tests/qtest/tpm-crb-device-test.c       |  71 ++++++++++++++
 tests/qtest/tpm-crb-swtpm-test.c        |   2 +
 tests/qtest/tpm-crb-test.c              | 121 +-----------------------
 tests/qtest/tpm-tests.c                 | 121 ++++++++++++++++++++++++
 tests/qtest/tpm-tis-device-swtpm-test.c |   2 +-
 tests/qtest/tpm-tis-device-test.c       |   2 +-
 tests/qtest/tpm-tis-i2c-test.c          |   3 +
 tests/qtest/tpm-tis-swtpm-test.c        |   2 +-
 tests/qtest/tpm-tis-test.c              |   2 +-
 tests/qtest/tpm-util.c                  |  16 ++--
 tests/qtest/meson.build                 |   4 +
 15 files changed, 295 insertions(+), 133 deletions(-)
 create mode 100644 tests/qtest/tpm-crb-device-swtpm-test.c
 create mode 100644 tests/qtest/tpm-crb-device-test.c

diff --git a/tests/qtest/tpm-tests.h b/tests/qtest/tpm-tests.h
index 07ba60d26e..c1bfb2f914 100644
--- a/tests/qtest/tpm-tests.h
+++ b/tests/qtest/tpm-tests.h
@@ -24,4 +24,6 @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
                                    const char *ifmodel,
                                    const char *machine_options);
 
+void tpm_test_crb(const void *data);
+
 #endif /* TESTS_TPM_TESTS_H */
diff --git a/tests/qtest/tpm-util.h b/tests/qtest/tpm-util.h
index 0cb28dd6e5..c99380684e 100644
--- a/tests/qtest/tpm-util.h
+++ b/tests/qtest/tpm-util.h
@@ -15,10 +15,10 @@
 
 #include "io/channel-socket.h"
 
-extern uint64_t tpm_tis_base_addr;
+extern uint64_t tpm_device_base_addr;
 
 #define TIS_REG(LOCTY, REG) \
-    (tpm_tis_base_addr + ((LOCTY) << 12) + REG)
+    (tpm_device_base_addr + ((LOCTY) << 12) + REG)
 
 typedef void (tx_func)(QTestState *s,
                        const unsigned char *req, size_t req_size,
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index bb4ebf00c1..01e0a4aa00 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1445,7 +1445,7 @@ static void test_acpi_piix4_tcg_numamem(void)
     free_test_data(&data);
 }
 
-uint64_t tpm_tis_base_addr;
+uint64_t tpm_device_base_addr;
 
 static test_data tcg_tpm_test_data(const char *machine)
 {
@@ -1481,7 +1481,7 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
     const char *suffix = tpm_version == TPM_VERSION_2_0 ? "tpm2" : "tpm12";
     char *args, *variant = g_strdup_printf(".%s.%s", tpm_if, suffix);
 
-    tpm_tis_base_addr = base;
+    tpm_device_base_addr = base;
 
     module_call_init(MODULE_INIT_QOM);
 
diff --git a/tests/qtest/tpm-crb-device-swtpm-test.c b/tests/qtest/tpm-crb-device-swtpm-test.c
new file mode 100644
index 0000000000..332add5ca6
--- /dev/null
+++ b/tests/qtest/tpm-crb-device-swtpm-test.c
@@ -0,0 +1,72 @@
+/*
+ * QTest testcase for TPM CRB talking to external swtpm and swtpm migration
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *  with parts borrowed from migration-test.c that is:
+ *     Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *   Stefan Berger <stefanb@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+#include "qemu/module.h"
+#include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+uint64_t tpm_device_base_addr = 0xc000000;
+#define MACHINE_OPTIONS "-machine virt,gic-version=max -accel tcg"
+
+typedef struct TestState {
+    char *src_tpm_path;
+    char *dst_tpm_path;
+    char *uri;
+} TestState;
+
+static void tpm_crb_swtpm_test(const void *data)
+{
+    const TestState *ts = data;
+
+    tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer,
+                        "tpm-crb-device", MACHINE_OPTIONS);
+}
+
+static void tpm_crb_swtpm_migration_test(const void *data)
+{
+    const TestState *ts = data;
+
+    tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
+                                  tpm_util_crb_transfer, "tpm-crb-device",
+                                  MACHINE_OPTIONS);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+    TestState ts = { 0 };
+
+    ts.src_tpm_path = g_dir_make_tmp("qemu-tpm-crb-swtpm-test.XXXXXX", NULL);
+    ts.dst_tpm_path = g_dir_make_tmp("qemu-tpm-crb-swtpm-test.XXXXXX", NULL);
+    ts.uri = g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path);
+
+    module_call_init(MODULE_INIT_QOM);
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_data_func("/tpm/crb-swtpm/test", &ts, tpm_crb_swtpm_test);
+    qtest_add_data_func("/tpm/crb-swtpm-migration/test", &ts,
+                        tpm_crb_swtpm_migration_test);
+    ret = g_test_run();
+
+    tpm_util_rmdir(ts.dst_tpm_path);
+    g_free(ts.dst_tpm_path);
+    tpm_util_rmdir(ts.src_tpm_path);
+    g_free(ts.src_tpm_path);
+    g_free(ts.uri);
+
+    return ret;
+}
diff --git a/tests/qtest/tpm-crb-device-test.c b/tests/qtest/tpm-crb-device-test.c
new file mode 100644
index 0000000000..17d09a57fd
--- /dev/null
+++ b/tests/qtest/tpm-crb-device-test.c
@@ -0,0 +1,71 @@
+/*
+ * QTest testcase for TPM CRB
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Authors:
+ *   Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <glib/gstdio.h>
+
+#include "hw/acpi/tpm.h"
+#include "io/channel-socket.h"
+#include "libqtest-single.h"
+#include "qemu/module.h"
+#include "tpm-emu.h"
+#include "tpm-tests.h"
+
+/*
+ * As the Sysbus tpm-crb-device is instantiated on the ARM virt
+ * platform bus and it is the only sysbus device dynamically
+ * instantiated, it gets plugged at its base address
+ */
+uint64_t tpm_device_base_addr = 0xc000000;
+
+int main(int argc, char **argv)
+{
+    int ret;
+    char *args, *tmp_path = g_dir_make_tmp("qemu-tpm-crb-test.XXXXXX", NULL);
+    GThread *thread;
+    TPMTestState test;
+
+    module_call_init(MODULE_INIT_QOM);
+    g_test_init(&argc, &argv, NULL);
+
+    test.addr = g_new0(SocketAddress, 1);
+    test.addr->type = SOCKET_ADDRESS_TYPE_UNIX;
+    test.addr->u.q_unix.path = g_build_filename(tmp_path, "sock", NULL);
+    g_mutex_init(&test.data_mutex);
+    g_cond_init(&test.data_cond);
+    test.data_cond_signal = false;
+    test.tpm_version = TPM_VERSION_2_0;
+
+    thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
+    tpm_emu_test_wait_cond(&test);
+
+    args = g_strdup_printf(
+        "-machine virt,gic-version=max -accel tcg "
+        "-chardev socket,id=chr,path=%s "
+        "-tpmdev emulator,id=dev,chardev=chr "
+        "-device tpm-crb-device,tpmdev=dev",
+        test.addr->u.q_unix.path);
+    qtest_start(args);
+
+    qtest_add_data_func("/tpm-crb/test", &test, tpm_test_crb);
+    ret = g_test_run();
+
+    qtest_end();
+
+    g_thread_join(thread);
+    g_unlink(test.addr->u.q_unix.path);
+    qapi_free_SocketAddress(test.addr);
+    g_rmdir(tmp_path);
+    g_free(tmp_path);
+    g_free(args);
+    return ret;
+}
diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c
index ffeb1c396b..08862210a4 100644
--- a/tests/qtest/tpm-crb-swtpm-test.c
+++ b/tests/qtest/tpm-crb-swtpm-test.c
@@ -19,6 +19,8 @@
 #include "tpm-tests.h"
 #include "hw/acpi/tpm.h"
 
+uint64_t tpm_device_base_addr = TPM_CRB_ADDR_BASE;
+
 typedef struct TestState {
     char *src_tpm_path;
     char *dst_tpm_path;
diff --git a/tests/qtest/tpm-crb-test.c b/tests/qtest/tpm-crb-test.c
index 9d30fe8293..51614abc70 100644
--- a/tests/qtest/tpm-crb-test.c
+++ b/tests/qtest/tpm-crb-test.c
@@ -18,124 +18,9 @@
 #include "libqtest-single.h"
 #include "qemu/module.h"
 #include "tpm-emu.h"
+#include "tpm-tests.h"
 
-#define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
-
-static void tpm_crb_test(const void *data)
-{
-    const TPMTestState *s = data;
-    uint32_t intfid = readl(TPM_CRB_ADDR_BASE + A_CRB_INTF_ID);
-    uint32_t csize = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_SIZE);
-    uint64_t caddr = readq(TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_LADDR);
-    uint32_t rsize = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_SIZE);
-    uint64_t raddr = readq(TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_LADDR);
-    uint8_t locstate = readb(TPM_CRB_ADDR_BASE + A_CRB_LOC_STATE);
-    uint32_t locctrl = readl(TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL);
-    uint32_t locsts = readl(TPM_CRB_ADDR_BASE + A_CRB_LOC_STS);
-    uint32_t sts = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_STS);
-
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, InterfaceType), ==, 1);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, InterfaceVersion), ==, 1);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapLocality), ==, 0);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapCRBIdleBypass), ==, 0);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapDataXferSizeSupport),
-                    ==, 3);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapFIFO), ==, 0);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapCRB), ==, 1);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, InterfaceSelector), ==, 1);
-    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, RID), ==, 0);
-
-    g_assert_cmpint(csize, >=, 128);
-    g_assert_cmpint(rsize, >=, 128);
-    g_assert_cmpint(caddr, >, TPM_CRB_ADDR_BASE);
-    g_assert_cmpint(raddr, >, TPM_CRB_ADDR_BASE);
-
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmEstablished), ==, 1);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, locAssigned), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, activeLocality), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, reserved), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmRegValidSts), ==, 1);
-
-    g_assert_cmpint(locctrl, ==, 0);
-
-    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, Granted), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, beenSeized), ==, 0);
-
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 1);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
-
-    /* request access to locality 0 */
-    writeb(TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL, 1);
-
-    /* granted bit must be set now */
-    locsts = readl(TPM_CRB_ADDR_BASE + A_CRB_LOC_STS);
-    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, Granted), ==, 1);
-    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, beenSeized), ==, 0);
-
-    /* we must have an assigned locality */
-    locstate = readb(TPM_CRB_ADDR_BASE + A_CRB_LOC_STATE);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmEstablished), ==, 1);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, locAssigned), ==, 1);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, activeLocality), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, reserved), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmRegValidSts), ==, 1);
-
-    /* set into ready state */
-    writel(TPM_CRB_ADDR_BASE + A_CRB_CTRL_REQ, 1);
-
-    /* TPM must not be in the idle state */
-    sts = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_STS);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 0);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
-
-    memwrite(caddr, TPM_CMD, sizeof(TPM_CMD));
-
-    uint32_t start = 1;
-    uint64_t end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
-    writel(TPM_CRB_ADDR_BASE + A_CRB_CTRL_START, start);
-    do {
-        start = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_START);
-        if ((start & 1) == 0) {
-            break;
-        }
-    } while (g_get_monotonic_time() < end_time);
-    start = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_START);
-    g_assert_cmpint(start & 1, ==, 0);
-
-    /* TPM must still not be in the idle state */
-    sts = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_STS);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 0);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
-
-    struct tpm_hdr tpm_msg;
-    memread(raddr, &tpm_msg, sizeof(tpm_msg));
-    g_assert_cmpmem(&tpm_msg, sizeof(tpm_msg), s->tpm_msg, sizeof(*s->tpm_msg));
-
-    /* set TPM into idle state */
-    writel(TPM_CRB_ADDR_BASE + A_CRB_CTRL_REQ, 2);
-
-    /* idle state must be indicated now */
-    sts = readl(TPM_CRB_ADDR_BASE + A_CRB_CTRL_STS);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 1);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
-
-    /* relinquish locality */
-    writel(TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL, 2);
-
-    /* Granted flag must be cleared */
-    sts = readl(TPM_CRB_ADDR_BASE + A_CRB_LOC_STS);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_LOC_STS, Granted), ==, 0);
-    g_assert_cmpint(FIELD_EX32(sts, CRB_LOC_STS, beenSeized), ==, 0);
-
-    /* no locality may be assigned */
-    locstate = readb(TPM_CRB_ADDR_BASE + A_CRB_LOC_STATE);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmEstablished), ==, 1);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, locAssigned), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, activeLocality), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, reserved), ==, 0);
-    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmRegValidSts), ==, 1);
-
-}
+uint64_t tpm_device_base_addr = TPM_CRB_ADDR_BASE;
 
 int main(int argc, char **argv)
 {
@@ -165,7 +50,7 @@ int main(int argc, char **argv)
         test.addr->u.q_unix.path);
     qtest_start(args);
 
-    qtest_add_data_func("/tpm-crb/test", &test, tpm_crb_test);
+    qtest_add_data_func("/tpm-crb/test", &test, tpm_test_crb);
     ret = g_test_run();
 
     qtest_end();
diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c
index fb94496bbd..83c5536136 100644
--- a/tests/qtest/tpm-tests.c
+++ b/tests/qtest/tpm-tests.c
@@ -15,7 +15,10 @@
 #include "qemu/osdep.h"
 #include <glib/gstdio.h>
 
+#include "hw/registerfields.h"
+#include "hw/acpi/tpm.h"
 #include "libqtest-single.h"
+#include "tpm-emu.h"
 #include "tpm-tests.h"
 
 static bool
@@ -130,3 +133,121 @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
     g_unlink(src_tpm_addr->u.q_unix.path);
     qapi_free_SocketAddress(src_tpm_addr);
 }
+
+#define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
+
+void tpm_test_crb(const void *data)
+{
+    const TPMTestState *s = data;
+    uint32_t intfid = readl(tpm_device_base_addr + A_CRB_INTF_ID);
+    uint32_t csize = readl(tpm_device_base_addr + A_CRB_CTRL_CMD_SIZE);
+    uint64_t caddr = readq(tpm_device_base_addr + A_CRB_CTRL_CMD_LADDR);
+    uint32_t rsize = readl(tpm_device_base_addr + A_CRB_CTRL_RSP_SIZE);
+    uint64_t raddr = readq(tpm_device_base_addr + A_CRB_CTRL_RSP_LADDR);
+    uint8_t locstate = readb(tpm_device_base_addr + A_CRB_LOC_STATE);
+    uint32_t locctrl = readl(tpm_device_base_addr + A_CRB_LOC_CTRL);
+    uint32_t locsts = readl(tpm_device_base_addr + A_CRB_LOC_STS);
+    uint32_t sts = readl(tpm_device_base_addr + A_CRB_CTRL_STS);
+
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, InterfaceType), ==, 1);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, InterfaceVersion), ==, 1);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapLocality), ==, 0);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapCRBIdleBypass), ==, 0);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapDataXferSizeSupport),
+                    ==, 3);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapFIFO), ==, 0);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, CapCRB), ==, 1);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, InterfaceSelector), ==, 1);
+    g_assert_cmpint(FIELD_EX32(intfid, CRB_INTF_ID, RID), ==, 0);
+
+    g_assert_cmpint(csize, >=, 128);
+    g_assert_cmpint(rsize, >=, 128);
+    g_assert_cmpint(caddr, >, tpm_device_base_addr);
+    g_assert_cmpint(raddr, >, tpm_device_base_addr);
+
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmEstablished), ==, 1);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, locAssigned), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, activeLocality), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, reserved), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmRegValidSts), ==, 1);
+
+    g_assert_cmpint(locctrl, ==, 0);
+
+    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, Granted), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, beenSeized), ==, 0);
+
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 1);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
+
+    /* request access to locality 0 */
+    writeb(tpm_device_base_addr + A_CRB_LOC_CTRL, 1);
+
+    /* granted bit must be set now */
+    locsts = readl(tpm_device_base_addr + A_CRB_LOC_STS);
+    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, Granted), ==, 1);
+    g_assert_cmpint(FIELD_EX32(locsts, CRB_LOC_STS, beenSeized), ==, 0);
+
+    /* we must have an assigned locality */
+    locstate = readb(tpm_device_base_addr + A_CRB_LOC_STATE);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmEstablished), ==, 1);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, locAssigned), ==, 1);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, activeLocality), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, reserved), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmRegValidSts), ==, 1);
+
+    /* set into ready state */
+    writel(tpm_device_base_addr + A_CRB_CTRL_REQ, 1);
+
+    /* TPM must not be in the idle state */
+    sts = readl(tpm_device_base_addr + A_CRB_CTRL_STS);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 0);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
+
+    memwrite(caddr, TPM_CMD, sizeof(TPM_CMD));
+
+    uint32_t start = 1;
+    uint64_t end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
+    writel(tpm_device_base_addr + A_CRB_CTRL_START, start);
+    do {
+        start = readl(tpm_device_base_addr + A_CRB_CTRL_START);
+        if ((start & 1) == 0) {
+            break;
+        }
+    } while (g_get_monotonic_time() < end_time);
+    start = readl(tpm_device_base_addr + A_CRB_CTRL_START);
+    g_assert_cmpint(start & 1, ==, 0);
+
+    /* TPM must still not be in the idle state */
+    sts = readl(tpm_device_base_addr + A_CRB_CTRL_STS);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 0);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
+
+    struct tpm_hdr tpm_msg;
+    memread(raddr, &tpm_msg, sizeof(tpm_msg));
+    g_assert_cmpmem(&tpm_msg, sizeof(tpm_msg), s->tpm_msg, sizeof(*s->tpm_msg));
+
+    /* set TPM into idle state */
+    writel(tpm_device_base_addr + A_CRB_CTRL_REQ, 2);
+
+    /* idle state must be indicated now */
+    sts = readl(tpm_device_base_addr + A_CRB_CTRL_STS);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmIdle), ==, 1);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_CTRL_STS, tpmSts), ==, 0);
+
+    /* relinquish locality */
+    writel(tpm_device_base_addr + A_CRB_LOC_CTRL, 2);
+
+    /* Granted flag must be cleared */
+    sts = readl(tpm_device_base_addr + A_CRB_LOC_STS);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_LOC_STS, Granted), ==, 0);
+    g_assert_cmpint(FIELD_EX32(sts, CRB_LOC_STS, beenSeized), ==, 0);
+
+    /* no locality may be assigned */
+    locstate = readb(tpm_device_base_addr + A_CRB_LOC_STATE);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmEstablished), ==, 1);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, locAssigned), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, activeLocality), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, reserved), ==, 0);
+    g_assert_cmpint(FIELD_EX32(locstate, CRB_LOC_STATE, tpmRegValidSts), ==, 1);
+
+}
diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c b/tests/qtest/tpm-tis-device-swtpm-test.c
index 517a077005..54d1cedc6f 100644
--- a/tests/qtest/tpm-tis-device-swtpm-test.c
+++ b/tests/qtest/tpm-tis-device-swtpm-test.c
@@ -21,7 +21,7 @@
 #include "tpm-tis-util.h"
 #include "hw/acpi/tpm.h"
 
-uint64_t tpm_tis_base_addr = 0xc000000;
+uint64_t tpm_device_base_addr = 0xc000000;
 #define MACHINE_OPTIONS "-machine virt,gic-version=max -accel tcg"
 
 typedef struct TestState {
diff --git a/tests/qtest/tpm-tis-device-test.c b/tests/qtest/tpm-tis-device-test.c
index 3ddefb51ec..4f6609ae98 100644
--- a/tests/qtest/tpm-tis-device-test.c
+++ b/tests/qtest/tpm-tis-device-test.c
@@ -27,7 +27,7 @@
  * platform bus and it is the only sysbus device dynamically
  * instantiated, it gets plugged at its base address
  */
-uint64_t tpm_tis_base_addr = 0xc000000;
+uint64_t tpm_device_base_addr = 0xc000000;
 
 int main(int argc, char **argv)
 {
diff --git a/tests/qtest/tpm-tis-i2c-test.c b/tests/qtest/tpm-tis-i2c-test.c
index 3a1af026f2..9495cc1739 100644
--- a/tests/qtest/tpm-tis-i2c-test.c
+++ b/tests/qtest/tpm-tis-i2c-test.c
@@ -39,6 +39,9 @@
 #define I2C_SLAVE_ADDR   0x2e
 #define I2C_DEV_BUS_NUM  10
 
+/* unused but needed for tpm-util.c to link */
+uint64_t tpm_device_base_addr;
+
 static const uint8_t TPM_CMD[12] =
     "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00";
 
diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c
index 105e42e21d..5bfbbc0a67 100644
--- a/tests/qtest/tpm-tis-swtpm-test.c
+++ b/tests/qtest/tpm-tis-swtpm-test.c
@@ -20,7 +20,7 @@
 #include "tpm-tis-util.h"
 #include "hw/acpi/tpm.h"
 
-uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
+uint64_t tpm_device_base_addr = TPM_TIS_ADDR_BASE;
 
 typedef struct TestState {
     char *src_tpm_path;
diff --git a/tests/qtest/tpm-tis-test.c b/tests/qtest/tpm-tis-test.c
index a4a25ba745..7661568aa8 100644
--- a/tests/qtest/tpm-tis-test.c
+++ b/tests/qtest/tpm-tis-test.c
@@ -22,7 +22,7 @@
 #include "tpm-emu.h"
 #include "tpm-tis-util.h"
 
-uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
+uint64_t tpm_device_base_addr = TPM_TIS_ADDR_BASE;
 
 int main(int argc, char **argv)
 {
diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
index dd02057fc0..1608901a76 100644
--- a/tests/qtest/tpm-util.c
+++ b/tests/qtest/tpm-util.c
@@ -24,18 +24,20 @@ void tpm_util_crb_transfer(QTestState *s,
                            const unsigned char *req, size_t req_size,
                            unsigned char *rsp, size_t rsp_size)
 {
-    uint64_t caddr = qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_CMD_LADDR);
-    uint64_t raddr = qtest_readq(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_RSP_LADDR);
+    uint64_t caddr = qtest_readq(s, tpm_device_base_addr +
+                                    A_CRB_CTRL_CMD_LADDR);
+    uint64_t raddr = qtest_readq(s, tpm_device_base_addr +
+                                    A_CRB_CTRL_RSP_LADDR);
 
-    qtest_writeb(s, TPM_CRB_ADDR_BASE + A_CRB_LOC_CTRL, 1);
+    qtest_writeb(s, tpm_device_base_addr + A_CRB_LOC_CTRL, 1);
 
     qtest_memwrite(s, caddr, req, req_size);
 
     uint32_t sts, start = 1;
     uint64_t end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
-    qtest_writel(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_START, start);
+    qtest_writel(s, tpm_device_base_addr + A_CRB_CTRL_START, start);
     while (true) {
-        start = qtest_readl(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_START);
+        start = qtest_readl(s, tpm_device_base_addr + A_CRB_CTRL_START);
         if ((start & 1) == 0) {
             break;
         }
@@ -43,9 +45,9 @@ void tpm_util_crb_transfer(QTestState *s,
             break;
         }
     };
-    start = qtest_readl(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_START);
+    start = qtest_readl(s, tpm_device_base_addr + A_CRB_CTRL_START);
     g_assert_cmpint(start & 1, ==, 0);
-    sts = qtest_readl(s, TPM_CRB_ADDR_BASE + A_CRB_CTRL_STS);
+    sts = qtest_readl(s, tpm_device_base_addr + A_CRB_CTRL_STS);
     g_assert_cmpint(sts & 1, ==, 0);
 
     qtest_memread(s, raddr, rsp, rsp_size);
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 47dabf91d0..386f71df4d 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -215,6 +215,8 @@ qtests_aarch64 = \
   (cpu != 'arm' and unpack_edk2_blobs ? ['bios-tables-test'] : []) +                            \
   (config_all.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ?            \
     ['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) +                                         \
+  (config_all.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_CRB_SYSBUS') ?            \
+    ['tpm-crb-device-test', 'tpm-crb-device-swtpm-test'] : []) +                                         \
   (config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
   (config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test', 'xlnx-versal-trng-test'] : []) + \
   (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) +  \
@@ -313,6 +315,8 @@ qtests = {
   'qos-test': [chardev, io, qos_test_ss.apply(config_targetos, strict: false).sources()],
   'tpm-crb-swtpm-test': [io, tpmemu_files],
   'tpm-crb-test': [io, tpmemu_files],
+  'tpm-crb-device-swtpm-test': [io, tpmemu_files],
+  'tpm-crb-device-test': [io, tpmemu_files],
   'tpm-tis-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
   'tpm-tis-test': [io, tpmemu_files, 'tpm-tis-util.c'],
   'tpm-tis-i2c-test': [io, tpmemu_files, 'qtest_aspeed.c'],
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-14  2:09 ` [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt Joelle van Dyne
@ 2023-11-14  9:36   ` Marc-André Lureau
  2023-11-14 13:04     ` Stefan Berger
  2023-11-14 18:03     ` Stefan Berger
  0 siblings, 2 replies; 35+ messages in thread
From: Marc-André Lureau @ 2023-11-14  9:36 UTC (permalink / raw)
  To: Joelle van Dyne
  Cc: qemu-devel, Stefan Berger, Michael S. Tsirkin, Igor Mammedov, Ani Sinha

Hi

On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>

nit: you also added tests for x86, could be a different patch?

For arm, the test fails until next patch with:

# starting QEMU: exec ./qemu-system-aarch64 -qtest
unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
chardev=char0,mode=control -display none -audio none -machine virt
-accel tcg -nodefaults -nographic -drive
if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
-drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
-cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
-cpu cortex-a57 -chardev
socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
-tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
-accel qtest
Warning! zero length expected file 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
Warning! zero length expected file 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
acpi-test: Warning!  binary file mismatch. Actual
[aml:/tmp/aml-GO4ME2], Expected
[aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
See source file tests/qtest/bios-tables-test.c for instructions on how
to update expected files.
acpi-test: Warning!  binary file mismatch. Actual
[aml:/tmp/aml-6N4ME2], Expected
[aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
See source file tests/qtest/bios-tables-test.c for instructions on how
to update expected files.
to see ASL diff between mismatched files install IASL, rebuild QEMU
from scratch and re-run tests with V=1 environment variable set**
ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
failed: (all_tables_match)
not ok /aarch64/acpi/virt/tpm2-crb -
ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
failed: (all_tables_match)
Bail out!
qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
Resource temporarily unavailable
Unexpected error in qio_channel_socket_writev() at ../io/channel-socket.c:622:
/home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
to write to socket: Bad file descriptor

> ---
>  tests/qtest/bios-tables-test.c | 43 ++++++++++++++++++++++++++++++++--
>  1 file changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> index 71af5cf69f..bb4ebf00c1 100644
> --- a/tests/qtest/bios-tables-test.c
> +++ b/tests/qtest/bios-tables-test.c
> @@ -1447,6 +1447,28 @@ static void test_acpi_piix4_tcg_numamem(void)
>
>  uint64_t tpm_tis_base_addr;
>
> +static test_data tcg_tpm_test_data(const char *machine)
> +{
> +    if (g_strcmp0(machine, "virt") == 0) {
> +        test_data data = {
> +            .machine = "virt",
> +            .tcg_only = true,
> +            .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
> +            .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
> +            .cd =
> +               "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
> +            .ram_start = 0x40000000ULL,
> +            .scan_len = 128ULL * 1024 * 1024,
> +        };
> +        return data;
> +    } else {
> +        test_data data = {
> +            .machine = machine,
> +        };
> +        return data;
> +    }
> +}
> +
>  static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
>                                uint64_t base, enum TPMVersion tpm_version)
>  {
> @@ -1454,7 +1476,7 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
>                                            machine, tpm_if);
>      char *tmp_path = g_dir_make_tmp(tmp_dir_name, NULL);
>      TPMTestState test;
> -    test_data data = {};
> +    test_data data = tcg_tpm_test_data(machine);
>      GThread *thread;
>      const char *suffix = tpm_version == TPM_VERSION_2_0 ? "tpm2" : "tpm12";
>      char *args, *variant = g_strdup_printf(".%s.%s", tpm_if, suffix);
> @@ -1474,13 +1496,14 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if,
>      thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
>      tpm_emu_test_wait_cond(&test);
>
> -    data.machine = machine;
>      data.variant = variant;
>
>      args = g_strdup_printf(
> +        " %s"
>          " -chardev socket,id=chr,path=%s"
>          " -tpmdev emulator,id=dev,chardev=chr"
>          " -device tpm-%s,tpmdev=dev",
> +        g_strcmp0(machine, "virt") == 0 ? "-cpu cortex-a57" : "",
>          test.addr->u.q_unix.path, tpm_if);
>
>      test_acpi_one(args, &data);
> @@ -1506,6 +1529,16 @@ static void test_acpi_q35_tcg_tpm12_tis(void)
>      test_acpi_tcg_tpm("q35", "tis", 0xFED40000, TPM_VERSION_1_2);
>  }
>
> +static void test_acpi_q35_tcg_tpm2_crb(void)
> +{
> +    test_acpi_tcg_tpm("q35", "crb", 0xFED40000, TPM_VERSION_2_0);
> +}
> +
> +static void test_acpi_virt_tcg_tpm2_crb(void)
> +{
> +    test_acpi_tcg_tpm("virt", "crb-device", 0xFED40000, TPM_VERSION_2_0);
> +}
> +
>  static void test_acpi_tcg_dimm_pxm(const char *machine)
>  {
>      test_data data = {};
> @@ -2212,6 +2245,9 @@ int main(int argc, char *argv[])
>                  qtest_add_func("acpi/q35/tpm12-tis",
>                                 test_acpi_q35_tcg_tpm12_tis);
>              }
> +            if (tpm_model_is_available("-machine q35", "tpm-crb")) {
> +                qtest_add_func("acpi/q35/tpm2-crb", test_acpi_q35_tcg_tpm2_crb);
> +            }
>              qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
>              qtest_add_func("acpi/q35/no-acpi-hotplug",
>                             test_acpi_q35_tcg_no_acpi_hotplug);
> @@ -2301,6 +2337,9 @@ int main(int argc, char *argv[])
>                  qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
>              }
>          }
> +        if (tpm_model_is_available("-machine virt", "tpm-crb")) {
> +            qtest_add_func("acpi/virt/tpm2-crb", test_acpi_virt_tcg_tpm2_crb);
> +        }
>      }
>      ret = g_test_run();
>      boot_sector_cleanup(disk);
> --
> 2.41.0
>
>


-- 
Marc-André Lureau


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (13 preceding siblings ...)
  2023-11-14  2:09 ` [PATCH v5 14/14] tests: add TPM-CRB sysbus tests for aarch64 Joelle van Dyne
@ 2023-11-14  9:38 ` Marc-André Lureau
  2023-11-14 19:25   ` Joelle van Dyne
  2024-04-30 11:54 ` Peter Maydell
  15 siblings, 1 reply; 35+ messages in thread
From: Marc-André Lureau @ 2023-11-14  9:38 UTC (permalink / raw)
  To: Joelle van Dyne; +Cc: qemu-devel

Hi

On Tue, Nov 14, 2023 at 6:10 AM Joelle van Dyne <j@getutm.app> wrote:
>
> The impetus for this patch set is to get TPM 2.0 working on Windows 11 ARM64.
> Windows' tpm.sys does not seem to work on a TPM TIS device (as verified with
> VMWare's implementation). However, the current TPM CRB device uses a fixed
> system bus address that is reserved for RAM in ARM64 Virt machines.
>
> In the process of adding the TPM CRB SysBus device, we also went ahead and
> cleaned up some of the existing TPM hardware code and fixed some bugs. We used
> the TPM TIS devices as a template for the TPM CRB devices and refactored out
> common code. We moved the ACPI DSDT generation to the device in order to handle
> dynamic base address requirements as well as reduce redundent code in different
> machine ACPI generation. We also changed the tpm_crb device to use the ISA bus
> instead of depending on the default system bus as the device only was built for
> the PC configuration.
>
> Another change is that the TPM CRB registers are now mapped in the same way that
> the pflash ROM devices are mapped. It is a memory region whose writes are
> trapped as MMIO accesses. This was needed because Apple Silicon does not decode
> LDP (AARCH64 load pair of registers) caused page faults. @agraf suggested that
> we do this to avoid having to do AARCH64 decoding in the HVF backend's fault
> handler.
>
> Unfortunately, it seems like the LDP fault still happens on HVF but the issue
> seems to be in the HVF backend which needs to be fixed in a separate patch.
>
> One last thing that's needed to get Windows 11 to recognize the TPM 2.0 device
> is for the OVMF firmware to setup the TPM device. Currently, OVMF for ARM64 Virt
> only recognizes the TPM TIS device through a FDT entry. A workaround is to
> falsely identify the TPM CRB device as a TPM TIS device in the FDT node but this
> causes issues for Linux. A proper fix would involve adding an ACPI device driver
> in OVMF.
>
> This has been tested on ARM64 with `tpm-crb-device` and on x86_64 with
> `tpm-crb`. Additional testing should be performed on other architectures (RISCV
> and Loongarch for example) as well as migration cases.
>
> v5:
> - Fixed a typo in "tpm_crb: use a single read-as-mem/write-as-mmio mapping"
> - Fixed ACPI tables not being created for pc CRB device
>
> v4:
> - Fixed broken test blobs
>
> v3:
> - Support backwards and forwards migration of existing tpm-crb device
> - Dropped patch which moved tpm-crb to ISA bus due to migration concerns
> - Unified `tpm_sysbus_plug` handler for ARM and Loongarch
> - Added ACPI table tests for tpm-crb-device
> - Refactored TPM CRB tests to run on tpm-crb-device for ARM Virt
>
> v2:
> - Fixed an issue where VMstate restore from an older version failed due to name
>   collision of the memory block.
> - In the ACPI table generation for CRB devices, the check for TPM 2.0 backend is
>   moved to the device realize as CRB does not support TPM 1.0. It will error in
>   that case.
> - Dropped the patch to fix crash when PPI is enabled on TIS SysBus device since
>   a separate patch submitted by Stefan Berger disables such an option.
> - Fixed an issue where we default tpmEstablished=0 when it should be 1.
> - In TPM CRB SysBus's ACPI entry, we accidently changed _UID from 0 to 1. This
>   shouldn't be an issue but we changed it back just in case.
> - Added a patch to migrate saved VMstate from an older version with the regs
>   saved separately instead of as a RAM block.
>
> Joelle van Dyne (14):
>   tpm_crb: refactor common code
>   tpm_crb: CTRL_RSP_ADDR is 64-bits wide
>   tpm_ppi: refactor memory space initialization
>   tpm_crb: use a single read-as-mem/write-as-mmio mapping
>   tpm_crb: move ACPI table building to device interface
>   tpm-sysbus: add plug handler for TPM on SysBus
>   hw/arm/virt: connect TPM to platform bus
>   hw/loongarch/virt: connect TPM to platform bus
>   tpm_tis_sysbus: move DSDT AML generation to device
>   tests: acpi: prepare for TPM CRB tests
>   tpm_crb_sysbus: introduce TPM CRB SysBus device
>   tests: acpi: implement TPM CRB tests for ARM virt
>   tests: acpi: updated expected blobs for TPM CRB
>   tests: add TPM-CRB sysbus tests for aarch64

The series looks good to me.
Have you checked there are no regressions with Windows HLK?

thanks

>
>  docs/specs/tpm.rst                        |   2 +
>  hw/tpm/tpm_crb.h                          |  79 ++++++
>  hw/tpm/tpm_ppi.h                          |  10 +-
>  include/hw/acpi/tpm.h                     |   3 +-
>  include/sysemu/tpm.h                      |   7 +
>  tests/qtest/tpm-tests.h                   |   2 +
>  tests/qtest/tpm-util.h                    |   4 +-
>  hw/acpi/aml-build.c                       |   7 +-
>  hw/arm/virt-acpi-build.c                  |  38 +--
>  hw/arm/virt.c                             |   8 +
>  hw/core/sysbus-fdt.c                      |   1 +
>  hw/i386/acpi-build.c                      |  16 +-
>  hw/loongarch/acpi-build.c                 |  38 +--
>  hw/loongarch/virt.c                       |   8 +
>  hw/riscv/virt.c                           |   1 +
>  hw/tpm/tpm-sysbus.c                       |  47 ++++
>  hw/tpm/tpm_crb.c                          | 302 ++++++----------------
>  hw/tpm/tpm_crb_common.c                   | 262 +++++++++++++++++++
>  hw/tpm/tpm_crb_sysbus.c                   | 162 ++++++++++++
>  hw/tpm/tpm_ppi.c                          |   5 +-
>  hw/tpm/tpm_tis_isa.c                      |   5 +-
>  hw/tpm/tpm_tis_sysbus.c                   |  37 +++
>  tests/qtest/bios-tables-test.c            |  47 +++-
>  tests/qtest/tpm-crb-device-swtpm-test.c   |  72 ++++++
>  tests/qtest/tpm-crb-device-test.c         |  71 +++++
>  tests/qtest/tpm-crb-swtpm-test.c          |   2 +
>  tests/qtest/tpm-crb-test.c                | 121 +--------
>  tests/qtest/tpm-tests.c                   | 121 +++++++++
>  tests/qtest/tpm-tis-device-swtpm-test.c   |   2 +-
>  tests/qtest/tpm-tis-device-test.c         |   2 +-
>  tests/qtest/tpm-tis-i2c-test.c            |   3 +
>  tests/qtest/tpm-tis-swtpm-test.c          |   2 +-
>  tests/qtest/tpm-tis-test.c                |   2 +-
>  tests/qtest/tpm-util.c                    |  16 +-
>  hw/arm/Kconfig                            |   1 +
>  hw/loongarch/Kconfig                      |   2 +
>  hw/riscv/Kconfig                          |   1 +
>  hw/tpm/Kconfig                            |   5 +
>  hw/tpm/meson.build                        |   5 +
>  hw/tpm/trace-events                       |   2 +-
>  tests/data/acpi/q35/DSDT.crb.tpm2         | Bin 0 -> 8355 bytes
>  tests/data/acpi/q35/TPM2.crb.tpm2         | Bin 0 -> 76 bytes
>  tests/data/acpi/virt/DSDT.crb-device.tpm2 | Bin 0 -> 5276 bytes
>  tests/data/acpi/virt/TPM2.crb-device.tpm2 | Bin 0 -> 76 bytes
>  tests/qtest/meson.build                   |   4 +
>  45 files changed, 1057 insertions(+), 468 deletions(-)
>  create mode 100644 hw/tpm/tpm_crb.h
>  create mode 100644 hw/tpm/tpm-sysbus.c
>  create mode 100644 hw/tpm/tpm_crb_common.c
>  create mode 100644 hw/tpm/tpm_crb_sysbus.c
>  create mode 100644 tests/qtest/tpm-crb-device-swtpm-test.c
>  create mode 100644 tests/qtest/tpm-crb-device-test.c
>  create mode 100644 tests/data/acpi/q35/DSDT.crb.tpm2
>  create mode 100644 tests/data/acpi/q35/TPM2.crb.tpm2
>  create mode 100644 tests/data/acpi/virt/DSDT.crb-device.tpm2
>  create mode 100644 tests/data/acpi/virt/TPM2.crb-device.tpm2
>
> --
> 2.41.0
>
>


-- 
Marc-André Lureau


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-14  9:36   ` Marc-André Lureau
@ 2023-11-14 13:04     ` Stefan Berger
  2023-11-14 18:03     ` Stefan Berger
  1 sibling, 0 replies; 35+ messages in thread
From: Stefan Berger @ 2023-11-14 13:04 UTC (permalink / raw)
  To: Marc-André Lureau, Joelle van Dyne
  Cc: qemu-devel, Michael S. Tsirkin, Igor Mammedov, Ani Sinha



On 11/14/23 04:36, Marc-André Lureau wrote:
> Hi
> 
> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>
>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> 
> nit: you also added tests for x86, could be a different patch?
> 
> For arm, the test fails until next patch with:
> 
> # starting QEMU: exec ./qemu-system-aarch64 -qtest
> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
> chardev=char0,mode=control -display none -audio none -machine virt
> -accel tcg -nodefaults -nographic -drive
> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
> -cpu cortex-a57 -chardev
> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
> -accel qtest
> Warning! zero length expected file 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
> Warning! zero length expected file 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
> acpi-test: Warning!  binary file mismatch. Actual
> [aml:/tmp/aml-GO4ME2], Expected
> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
> See source file tests/qtest/bios-tables-test.c for instructions on how
> to update expected files.
> acpi-test: Warning!  binary file mismatch. Actual
> [aml:/tmp/aml-6N4ME2], Expected
> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
> See source file tests/qtest/bios-tables-test.c for instructions on how
> to update expected files.
> to see ASL diff between mismatched files install IASL, rebuild QEMU
> from scratch and re-run tests with V=1 environment variable set**
> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> failed: (all_tables_match)
> not ok /aarch64/acpi/virt/tpm2-crb -
> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> failed: (all_tables_match)
> Bail out!
> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
> Resource temporarily unavailable
> Unexpected error in qio_channel_socket_writev() at ../io/channel-socket.c:622:
> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
> to write to socket: Bad file descriptor

I had seen errors like these as well. However, the first error appears 
when applying the series after getting it using 'b4 am' -- it complains 
about patch 13. I always take patch 13 & 14 from my email client.

Both of these here pass:

QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/bios-tables-test
QTEST_QEMU_BINARY=./qemu-system-x86_64 ./tests/qtest/bios-tables-test



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 04/14] tpm_crb: use a single read-as-mem/write-as-mmio mapping
  2023-11-14  2:09 ` [PATCH v5 04/14] tpm_crb: use a single read-as-mem/write-as-mmio mapping Joelle van Dyne
@ 2023-11-14 15:46   ` Stefan Berger
  0 siblings, 0 replies; 35+ messages in thread
From: Stefan Berger @ 2023-11-14 15:46 UTC (permalink / raw)
  To: Joelle van Dyne, qemu-devel; +Cc: Stefan Berger



On 11/13/23 21:09, Joelle van Dyne wrote:
> On Apple Silicon, when Windows performs a LDP on the CRB MMIO space,
> the exception is not decoded by hardware and we cannot trap the MMIO
> read. This led to the idea from @agraf to use the same mapping type as
> ROM devices: namely that reads should be seen as memory type and
> writes should trap as MMIO.
> 
> Once that was done, the second memory mapping of the command buffer
> region was redundent and was removed.
> 
> A note about the removal of the read trap for `CRB_LOC_STATE`:
> The only usage was to return the most up-to-date value for
> `tpmEstablished`. However, `tpmEstablished` is only cleared when a
> TPM2_HashStart operation is called which only exists for locality 4.
> We do not handle locality 4. Indeed, the comment for the write handler
> of `CRB_LOC_CTRL` makes the same argument for why it is not calling
> the backend to reset the `tpmEstablished` bit (to 1).
> As this bit is unused, we do not need to worry about updating it for
> reads.
> 
> In order to maintain migration compatibility with older versions of
> QEMU, we store a copy of the register data and command data which is
> used only during save/restore.
> 
> Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
>   hw/tpm/tpm_crb.h        |   5 +-
>   hw/tpm/tpm_crb.c        |  30 ++++++++-
>   hw/tpm/tpm_crb_common.c | 145 +++++++++++++++++++++++-----------------
>   3 files changed, 114 insertions(+), 66 deletions(-)
> 
> diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
> index da3a0cf256..36863e1664 100644
> --- a/hw/tpm/tpm_crb.h
> +++ b/hw/tpm/tpm_crb.h
> @@ -26,9 +26,7 @@
>   typedef struct TPMCRBState {
>       TPMBackend *tpmbe;
>       TPMBackendCmd cmd;
> -    uint32_t regs[TPM_CRB_R_MAX];
>       MemoryRegion mmio;
> -    MemoryRegion cmdmem;
> 
>       size_t be_buffer_size;
> 
> @@ -72,5 +70,8 @@ enum TPMVersion tpm_crb_get_version(TPMCRBState *s);
>   int tpm_crb_pre_save(TPMCRBState *s);
>   void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr);
>   void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp);
> +void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void *saved_cmdmem);
> +void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
> +                      const void *saved_cmdmem);
> 
>   #endif /* TPM_TPM_CRB_H */
> diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c
> index 598c3e0161..99c64dd72a 100644
> --- a/hw/tpm/tpm_crb.c
> +++ b/hw/tpm/tpm_crb.c
> @@ -37,6 +37,10 @@ struct CRBState {
>       DeviceState parent_obj;
> 
>       TPMCRBState state;
> +
> +    /* These states are only for migration */
> +    uint32_t saved_regs[TPM_CRB_R_MAX];
> +    MemoryRegion saved_cmdmem;
>   };
>   typedef struct CRBState CRBState;
> 
> @@ -57,18 +61,36 @@ static enum TPMVersion tpm_crb_none_get_version(TPMIf *ti)
>       return tpm_crb_get_version(&s->state);
>   }
> 
> +/**
> + * For migrating to an older version of QEMU
> + */
>   static int tpm_crb_none_pre_save(void *opaque)
>   {
>       CRBState *s = opaque;
> +    void *saved_cmdmem = memory_region_get_ram_ptr(&s->saved_cmdmem);
> 
> +    tpm_crb_mem_save(&s->state, s->saved_regs, saved_cmdmem);
>       return tpm_crb_pre_save(&s->state);
>   }
> 
> +/**
> + * For migrating from an older version of QEMU
> + */
> +static int tpm_crb_none_post_load(void *opaque, int version_id)
> +{
> +    CRBState *s = opaque;
> +    void *saved_cmdmem = memory_region_get_ram_ptr(&s->saved_cmdmem);
> +
> +    tpm_crb_mem_load(&s->state, s->saved_regs, saved_cmdmem);
> +    return 0;
> +}
> +
>   static const VMStateDescription vmstate_tpm_crb_none = {
>       .name = "tpm-crb",
>       .pre_save = tpm_crb_none_pre_save,
> +    .post_load = tpm_crb_none_post_load,
>       .fields = (VMStateField[]) {
> -        VMSTATE_UINT32_ARRAY(state.regs, CRBState, TPM_CRB_R_MAX),
> +        VMSTATE_UINT32_ARRAY(saved_regs, CRBState, TPM_CRB_R_MAX),
>           VMSTATE_END_OF_LIST(),
>       }
>   };
> @@ -101,10 +123,12 @@ static void tpm_crb_none_realize(DeviceState *dev, Error **errp)
> 
>       tpm_crb_init_memory(OBJECT(s), &s->state, errp);
> 
> +    /* only used for migration */
> +    memory_region_init_ram(&s->saved_cmdmem, OBJECT(s),
> +        "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
> +
>       memory_region_add_subregion(get_system_memory(),
>           TPM_CRB_ADDR_BASE, &s->state.mmio);
> -    memory_region_add_subregion(get_system_memory(),
> -        TPM_CRB_ADDR_BASE + sizeof(s->state.regs), &s->state.cmdmem);
> 
>       if (s->state.ppi_enabled) {
>           memory_region_add_subregion(get_system_memory(),
> diff --git a/hw/tpm/tpm_crb_common.c b/hw/tpm/tpm_crb_common.c
> index bee0b71fee..f96a8cf299 100644
> --- a/hw/tpm/tpm_crb_common.c
> +++ b/hw/tpm/tpm_crb_common.c
> @@ -31,31 +31,12 @@
>   #include "qom/object.h"
>   #include "tpm_crb.h"
> 
> -static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
> -                                  unsigned size)
> +static uint8_t tpm_crb_get_active_locty(TPMCRBState *s, uint32_t *regs)
>   {
> -    TPMCRBState *s = opaque;
> -    void *regs = (void *)&s->regs + (addr & ~3);
> -    unsigned offset = addr & 3;
> -    uint32_t val = *(uint32_t *)regs >> (8 * offset);
> -
> -    switch (addr) {
> -    case A_CRB_LOC_STATE:
> -        val |= !tpm_backend_get_tpm_established_flag(s->tpmbe);
> -        break;
> -    }
> -
> -    trace_tpm_crb_mmio_read(addr, size, val);
> -
> -    return val;
> -}
> -
> -static uint8_t tpm_crb_get_active_locty(TPMCRBState *s)
> -{
> -    if (!ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, locAssigned)) {
> +    if (!ARRAY_FIELD_EX32(regs, CRB_LOC_STATE, locAssigned)) {
>           return TPM_CRB_NO_LOCALITY;
>       }
> -    return ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, activeLocality);
> +    return ARRAY_FIELD_EX32(regs, CRB_LOC_STATE, activeLocality);
>   }
> 
>   static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
> @@ -63,35 +44,49 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
>   {
>       TPMCRBState *s = opaque;
>       uint8_t locty =  addr >> 12;
> +    uint32_t *regs;
> +    void *mem;
> 
>       trace_tpm_crb_mmio_write(addr, size, val);
> +    regs = memory_region_get_ram_ptr(&s->mmio);
> +    mem = &regs[R_CRB_DATA_BUFFER];
> +    assert(regs);
> +
> +    /* receive TPM command bytes in DATA_BUFFER */
> +    if (addr >= A_CRB_DATA_BUFFER) {
> +        assert(addr + size <= TPM_CRB_ADDR_SIZE);
> +        assert(size <= sizeof(val));
> +        memcpy(mem + addr - A_CRB_DATA_BUFFER, &val, size);
> +        memory_region_set_dirty(&s->mmio, addr, size);
> +        return;
> +    }
> 
> +    /* otherwise we are doing MMIO writes */
>       switch (addr) {
>       case A_CRB_CTRL_REQ:
>           switch (val) {
>           case CRB_CTRL_REQ_CMD_READY:
> -            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
> +            ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
>                                tpmIdle, 0);
>               break;
>           case CRB_CTRL_REQ_GO_IDLE:
> -            ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
> +            ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
>                                tpmIdle, 1);
>               break;
>           }
>           break;
>       case A_CRB_CTRL_CANCEL:
>           if (val == CRB_CANCEL_INVOKE &&
> -            s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
> +            regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
>               tpm_backend_cancel_cmd(s->tpmbe);
>           }
>           break;
>       case A_CRB_CTRL_START:
>           if (val == CRB_START_INVOKE &&
> -            !(s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
> -            tpm_crb_get_active_locty(s) == locty) {
> -            void *mem = memory_region_get_ram_ptr(&s->cmdmem);
> +            !(regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
> +            tpm_crb_get_active_locty(s, regs) == locty) {
> 
> -            s->regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
> +            regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
>               s->cmd = (TPMBackendCmd) {
>                   .in = mem,
>                   .in_len = MIN(tpm_cmd_get_size(mem), s->be_buffer_size),
> @@ -108,26 +103,27 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
>               /* not loc 3 or 4 */
>               break;
>           case CRB_LOC_CTRL_RELINQUISH:
> -            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
> +            ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
>                                locAssigned, 0);
> -            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
> +            ARRAY_FIELD_DP32(regs, CRB_LOC_STS,
>                                Granted, 0);
>               break;
>           case CRB_LOC_CTRL_REQUEST_ACCESS:
> -            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
> +            ARRAY_FIELD_DP32(regs, CRB_LOC_STS,
>                                Granted, 1);
> -            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
> +            ARRAY_FIELD_DP32(regs, CRB_LOC_STS,
>                                beenSeized, 0);
> -            ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
> +            ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
>                                locAssigned, 1);
>               break;
>           }
>           break;
>       }
> +
> +    memory_region_set_dirty(&s->mmio, 0, A_CRB_DATA_BUFFER);
>   }
> 
>   const MemoryRegionOps tpm_crb_memory_ops = {
> -    .read = tpm_crb_mmio_read,
>       .write = tpm_crb_mmio_write,
>       .endianness = DEVICE_LITTLE_ENDIAN,
>       .valid = {
> @@ -138,12 +134,16 @@ const MemoryRegionOps tpm_crb_memory_ops = {
> 
>   void tpm_crb_request_completed(TPMCRBState *s, int ret)
>   {
> -    s->regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
> +    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
> +
> +    assert(regs);
> +    regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
>       if (ret != 0) {
> -        ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
> +        ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
>                            tpmSts, 1); /* fatal error */
>       }
> -    memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE);
> +
> +    memory_region_set_dirty(&s->mmio, 0, TPM_CRB_ADDR_SIZE);
>   }
> 
>   enum TPMVersion tpm_crb_get_version(TPMCRBState *s)
> @@ -160,45 +160,50 @@ int tpm_crb_pre_save(TPMCRBState *s)
> 
>   void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr)
>   {
> +    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
> +
> +    assert(regs);
>       if (s->ppi_enabled) {
>           tpm_ppi_reset(&s->ppi);
>       }
>       tpm_backend_reset(s->tpmbe);
> 
> -    memset(s->regs, 0, sizeof(s->regs));
> +    memset(regs, 0, TPM_CRB_ADDR_SIZE);
> 
> -    ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
> +    ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
>                        tpmRegValidSts, 1);
> -    ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
> +    ARRAY_FIELD_DP32(regs, CRB_LOC_STATE,
> +                     tpmEstablished, 1);
> +    ARRAY_FIELD_DP32(regs, CRB_CTRL_STS,
>                        tpmIdle, 1);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        InterfaceType, CRB_INTF_TYPE_CRB_ACTIVE);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        InterfaceVersion, CRB_INTF_VERSION_CRB);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        CapLocality, CRB_INTF_CAP_LOCALITY_0_ONLY);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        CapCRBIdleBypass, CRB_INTF_CAP_IDLE_FAST);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        CapDataXferSizeSupport, CRB_INTF_CAP_XFER_SIZE_64);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        CapFIFO, CRB_INTF_CAP_FIFO_NOT_SUPPORTED);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        CapCRB, CRB_INTF_CAP_CRB_SUPPORTED);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        InterfaceSelector, CRB_INTF_IF_SELECTOR_CRB);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID,
>                        RID, 0b0000);
> -    ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID2,
> +    ARRAY_FIELD_DP32(regs, CRB_INTF_ID2,
>                        VID, PCI_VENDOR_ID_IBM);
> 
>       baseaddr += A_CRB_DATA_BUFFER;
> -    s->regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
> -    s->regs[R_CRB_CTRL_CMD_LADDR] = (uint32_t)baseaddr;
> -    s->regs[R_CRB_CTRL_CMD_HADDR] = (uint32_t)(baseaddr >> 32);
> -    s->regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
> -    s->regs[R_CRB_CTRL_RSP_LADDR] = (uint32_t)baseaddr;
> -    s->regs[R_CRB_CTRL_RSP_HADDR] = (uint32_t)(baseaddr >> 32);
> +    regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
> +    regs[R_CRB_CTRL_CMD_LADDR] = (uint32_t)baseaddr;
> +    regs[R_CRB_CTRL_CMD_HADDR] = (uint32_t)(baseaddr >> 32);
> +    regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
> +    regs[R_CRB_CTRL_RSP_LADDR] = (uint32_t)baseaddr;
> +    regs[R_CRB_CTRL_RSP_HADDR] = (uint32_t)(baseaddr >> 32);
> 
>       s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
>                               CRB_CTRL_CMD_SIZE);
> @@ -206,15 +211,33 @@ void tpm_crb_reset(TPMCRBState *s, uint64_t baseaddr)
>       if (tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size) < 0) {
>           exit(1);
>       }
> +
> +    memory_region_rom_device_set_romd(&s->mmio, true);
> +    memory_region_set_dirty(&s->mmio, 0, TPM_CRB_ADDR_SIZE);
>   }
> 
>   void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp)
>   {
> -    memory_region_init_io(&s->mmio, obj, &tpm_crb_memory_ops, s,
> -        "tpm-crb-mmio", sizeof(s->regs));
> -    memory_region_init_ram(&s->cmdmem, obj,
> -        "tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
> +    memory_region_init_rom_device_nomigrate(&s->mmio, obj, &tpm_crb_memory_ops,
> +        s, "tpm-crb-mem", TPM_CRB_ADDR_SIZE, errp);
>       if (s->ppi_enabled) {
>           tpm_ppi_init_memory(&s->ppi, obj);
>       }
>   }
> +
> +void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void *saved_cmdmem)
> +{
> +    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
> +
> +    memcpy(saved_regs, regs, A_CRB_DATA_BUFFER);
> +    memcpy(saved_cmdmem, &regs[R_CRB_DATA_BUFFER], CRB_CTRL_CMD_SIZE);
> +}
> +
> +void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
> +                      const void *saved_cmdmem)
> +{
> +    uint32_t *regs = memory_region_get_ram_ptr(&s->mmio);
> +
> +    memcpy(regs, saved_regs, A_CRB_DATA_BUFFER);
> +    memcpy(&regs[R_CRB_DATA_BUFFER], saved_cmdmem, CRB_CTRL_CMD_SIZE);
> +}


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface
  2023-11-14  2:09 ` [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface Joelle van Dyne
@ 2023-11-14 16:37   ` Stefan Berger
  2023-11-14 16:44     ` Stefan Berger
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-14 16:37 UTC (permalink / raw)
  To: Joelle van Dyne, qemu-devel
  Cc: Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost, Marcel Apfelbaum,
	Stefan Berger



On 11/13/23 21:09, Joelle van Dyne wrote:
> This logic is similar to TPM TIS ISA device. Since TPM CRB can only
> support TPM 2.0 backends, we check for this in realize.
> 
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> ---
>   hw/tpm/tpm_crb.h        |  2 ++
>   hw/i386/acpi-build.c    | 16 +---------------
>   hw/tpm/tpm_crb.c        | 16 ++++++++++++++++
>   hw/tpm/tpm_crb_common.c | 19 +++++++++++++++++++
>   4 files changed, 38 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
> index 36863e1664..e6a86e3fd1 100644
> --- a/hw/tpm/tpm_crb.h
> +++ b/hw/tpm/tpm_crb.h
> @@ -73,5 +73,7 @@ void tpm_crb_init_memory(Object *obj, TPMCRBState *s, Error **errp);
>   void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void *saved_cmdmem);
>   void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
>                         const void *saved_cmdmem);
> +void tpm_crb_build_aml(TPMIf *ti, Aml *scope, uint32_t baseaddr, uint32_t size,
> +                       bool build_ppi);
> 
>   #endif /* TPM_TPM_CRB_H */
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 80db183b78..7491cee2af 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1792,21 +1792,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> 
>   #ifdef CONFIG_TPM
>       if (TPM_IS_CRB(tpm)) {
> -        dev = aml_device("TPM");
> -        aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
> -        aml_append(dev, aml_name_decl("_STR",
> -                                      aml_string("TPM 2.0 Device")));
> -        crs = aml_resource_template();
> -        aml_append(crs, aml_memory32_fixed(TPM_CRB_ADDR_BASE,
> -                                           TPM_CRB_ADDR_SIZE, AML_READ_WRITE));
> -        aml_append(dev, aml_name_decl("_CRS", crs));
> -
> -        aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
> -        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
> -
> -        tpm_build_ppi_acpi(tpm, dev);
> -
> -        aml_append(sb_scope, dev);
> +        call_dev_aml_func(DEVICE(tpm), scope);

For an x86_64 VM we have to call it directly otherwise the ACPI table 
won't be there.

         tpm_crb_build_aml(tpm, sb_scope, TPM_CRB_ADDR_BASE, 
TPM_CRB_ADDR_SIZE, true);




^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface
  2023-11-14 16:37   ` Stefan Berger
@ 2023-11-14 16:44     ` Stefan Berger
  2023-11-14 19:29       ` Joelle van Dyne
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-14 16:44 UTC (permalink / raw)
  To: Joelle van Dyne, qemu-devel
  Cc: Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost, Marcel Apfelbaum,
	Stefan Berger



On 11/14/23 11:37, Stefan Berger wrote:
> 
> 
> On 11/13/23 21:09, Joelle van Dyne wrote:
>> This logic is similar to TPM TIS ISA device. Since TPM CRB can only
>> support TPM 2.0 backends, we check for this in realize.
>>
>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>> ---
>>   hw/tpm/tpm_crb.h        |  2 ++
>>   hw/i386/acpi-build.c    | 16 +---------------
>>   hw/tpm/tpm_crb.c        | 16 ++++++++++++++++
>>   hw/tpm/tpm_crb_common.c | 19 +++++++++++++++++++
>>   4 files changed, 38 insertions(+), 15 deletions(-)
>>
>> diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
>> index 36863e1664..e6a86e3fd1 100644
>> --- a/hw/tpm/tpm_crb.h
>> +++ b/hw/tpm/tpm_crb.h
>> @@ -73,5 +73,7 @@ void tpm_crb_init_memory(Object *obj, TPMCRBState 
>> *s, Error **errp);
>>   void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void 
>> *saved_cmdmem);
>>   void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
>>                         const void *saved_cmdmem);
>> +void tpm_crb_build_aml(TPMIf *ti, Aml *scope, uint32_t baseaddr, 
>> uint32_t size,
>> +                       bool build_ppi);
>>
>>   #endif /* TPM_TPM_CRB_H */
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index 80db183b78..7491cee2af 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -1792,21 +1792,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>>
>>   #ifdef CONFIG_TPM
>>       if (TPM_IS_CRB(tpm)) {
>> -        dev = aml_device("TPM");
>> -        aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
>> -        aml_append(dev, aml_name_decl("_STR",
>> -                                      aml_string("TPM 2.0 Device")));
>> -        crs = aml_resource_template();
>> -        aml_append(crs, aml_memory32_fixed(TPM_CRB_ADDR_BASE,
>> -                                           TPM_CRB_ADDR_SIZE, 
>> AML_READ_WRITE));
>> -        aml_append(dev, aml_name_decl("_CRS", crs));
>> -
>> -        aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
>> -        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
>> -
>> -        tpm_build_ppi_acpi(tpm, dev);
>> -
>> -        aml_append(sb_scope, dev);
>> +        call_dev_aml_func(DEVICE(tpm), scope);
> 
> For an x86_64 VM we have to call it directly otherwise the ACPI table 
> won't be there.
> 
>          tpm_crb_build_aml(tpm, sb_scope, TPM_CRB_ADDR_BASE, 
> TPM_CRB_ADDR_SIZE, true);
> 
> 
I looks like a good place for the moved code would be in hw/acpi/tpm.c


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-14  9:36   ` Marc-André Lureau
  2023-11-14 13:04     ` Stefan Berger
@ 2023-11-14 18:03     ` Stefan Berger
  2023-11-14 21:05       ` Stefan Berger
  1 sibling, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-14 18:03 UTC (permalink / raw)
  To: Marc-André Lureau, Joelle van Dyne
  Cc: qemu-devel, Michael S. Tsirkin, Igor Mammedov, Ani Sinha



On 11/14/23 04:36, Marc-André Lureau wrote:
> Hi
> 
> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>
>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> 
> nit: you also added tests for x86, could be a different patch?
> 
> For arm, the test fails until next patch with:
> 
> # starting QEMU: exec ./qemu-system-aarch64 -qtest
> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
> chardev=char0,mode=control -display none -audio none -machine virt
> -accel tcg -nodefaults -nographic -drive
> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
> -cpu cortex-a57 -chardev
> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
> -accel qtest
> Warning! zero length expected file 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
> Warning! zero length expected file 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
> acpi-test: Warning!  binary file mismatch. Actual
> [aml:/tmp/aml-GO4ME2], Expected
> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
> See source file tests/qtest/bios-tables-test.c for instructions on how
> to update expected files.
> acpi-test: Warning!  binary file mismatch. Actual
> [aml:/tmp/aml-6N4ME2], Expected
> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
> See source file tests/qtest/bios-tables-test.c for instructions on how
> to update expected files.
> to see ASL diff between mismatched files install IASL, rebuild QEMU
> from scratch and re-run tests with V=1 environment variable set**
> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> failed: (all_tables_match)
> not ok /aarch64/acpi/virt/tpm2-crb -
> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> failed: (all_tables_match)
> Bail out!
> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
> Resource temporarily unavailable
> Unexpected error in qio_channel_socket_writev() at ../io/channel-socket.c:622:
> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
> to write to socket: Bad file descriptor
> 

Travis testing on s390x I see the following failures for this patchset 
(search for 'ERROR'):

https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363

Summary of Failures:

134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test 
   ERROR           0.70s   killed by signal 6 SIGABRT

219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test 
   ERROR           0.88s   killed by signal 6 SIGABRT


Summary of Failures:

271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test 
          ERROR           0.59s   killed by signal 6 SIGABRT


My guess is it's an endianess issue on big endian machines due to 
reading from the ROM device where we lost the .endianess:

+const MemoryRegionOps tpm_crb_memory_ops = {
+    .read = tpm_crb_mmio_read,
+    .write = tpm_crb_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device
  2023-11-14  9:38 ` [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Marc-André Lureau
@ 2023-11-14 19:25   ` Joelle van Dyne
  2023-11-20  8:29     ` Marc-André Lureau
  0 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14 19:25 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: Joelle van Dyne, qemu-devel

On Tue, Nov 14, 2023 at 1:38 AM Marc-André Lureau
<marcandre.lureau@gmail.com> wrote:
>
> Hi
>
> On Tue, Nov 14, 2023 at 6:10 AM Joelle van Dyne <j@getutm.app> wrote:
> >
> > The impetus for this patch set is to get TPM 2.0 working on Windows 11 ARM64.
> > Windows' tpm.sys does not seem to work on a TPM TIS device (as verified with
> > VMWare's implementation). However, the current TPM CRB device uses a fixed
> > system bus address that is reserved for RAM in ARM64 Virt machines.
> >
> > In the process of adding the TPM CRB SysBus device, we also went ahead and
> > cleaned up some of the existing TPM hardware code and fixed some bugs. We used
> > the TPM TIS devices as a template for the TPM CRB devices and refactored out
> > common code. We moved the ACPI DSDT generation to the device in order to handle
> > dynamic base address requirements as well as reduce redundent code in different
> > machine ACPI generation. We also changed the tpm_crb device to use the ISA bus
> > instead of depending on the default system bus as the device only was built for
> > the PC configuration.
> >
> > Another change is that the TPM CRB registers are now mapped in the same way that
> > the pflash ROM devices are mapped. It is a memory region whose writes are
> > trapped as MMIO accesses. This was needed because Apple Silicon does not decode
> > LDP (AARCH64 load pair of registers) caused page faults. @agraf suggested that
> > we do this to avoid having to do AARCH64 decoding in the HVF backend's fault
> > handler.
> >
> > Unfortunately, it seems like the LDP fault still happens on HVF but the issue
> > seems to be in the HVF backend which needs to be fixed in a separate patch.
> >
> > One last thing that's needed to get Windows 11 to recognize the TPM 2.0 device
> > is for the OVMF firmware to setup the TPM device. Currently, OVMF for ARM64 Virt
> > only recognizes the TPM TIS device through a FDT entry. A workaround is to
> > falsely identify the TPM CRB device as a TPM TIS device in the FDT node but this
> > causes issues for Linux. A proper fix would involve adding an ACPI device driver
> > in OVMF.
> >
> > This has been tested on ARM64 with `tpm-crb-device` and on x86_64 with
> > `tpm-crb`. Additional testing should be performed on other architectures (RISCV
> > and Loongarch for example) as well as migration cases.
> >
> > v5:
> > - Fixed a typo in "tpm_crb: use a single read-as-mem/write-as-mmio mapping"
> > - Fixed ACPI tables not being created for pc CRB device
> >
> > v4:
> > - Fixed broken test blobs
> >
> > v3:
> > - Support backwards and forwards migration of existing tpm-crb device
> > - Dropped patch which moved tpm-crb to ISA bus due to migration concerns
> > - Unified `tpm_sysbus_plug` handler for ARM and Loongarch
> > - Added ACPI table tests for tpm-crb-device
> > - Refactored TPM CRB tests to run on tpm-crb-device for ARM Virt
> >
> > v2:
> > - Fixed an issue where VMstate restore from an older version failed due to name
> >   collision of the memory block.
> > - In the ACPI table generation for CRB devices, the check for TPM 2.0 backend is
> >   moved to the device realize as CRB does not support TPM 1.0. It will error in
> >   that case.
> > - Dropped the patch to fix crash when PPI is enabled on TIS SysBus device since
> >   a separate patch submitted by Stefan Berger disables such an option.
> > - Fixed an issue where we default tpmEstablished=0 when it should be 1.
> > - In TPM CRB SysBus's ACPI entry, we accidently changed _UID from 0 to 1. This
> >   shouldn't be an issue but we changed it back just in case.
> > - Added a patch to migrate saved VMstate from an older version with the regs
> >   saved separately instead of as a RAM block.
> >
> > Joelle van Dyne (14):
> >   tpm_crb: refactor common code
> >   tpm_crb: CTRL_RSP_ADDR is 64-bits wide
> >   tpm_ppi: refactor memory space initialization
> >   tpm_crb: use a single read-as-mem/write-as-mmio mapping
> >   tpm_crb: move ACPI table building to device interface
> >   tpm-sysbus: add plug handler for TPM on SysBus
> >   hw/arm/virt: connect TPM to platform bus
> >   hw/loongarch/virt: connect TPM to platform bus
> >   tpm_tis_sysbus: move DSDT AML generation to device
> >   tests: acpi: prepare for TPM CRB tests
> >   tpm_crb_sysbus: introduce TPM CRB SysBus device
> >   tests: acpi: implement TPM CRB tests for ARM virt
> >   tests: acpi: updated expected blobs for TPM CRB
> >   tests: add TPM-CRB sysbus tests for aarch64
>
> The series looks good to me.
> Have you checked there are no regressions with Windows HLK?
I don't have any experience with Windows HLK. Is there any guide on
running it with QEMU? Preferably with a prebuilt image? Or maybe
someone in the mailing list can run it?

>
> thanks
>
> >
> >  docs/specs/tpm.rst                        |   2 +
> >  hw/tpm/tpm_crb.h                          |  79 ++++++
> >  hw/tpm/tpm_ppi.h                          |  10 +-
> >  include/hw/acpi/tpm.h                     |   3 +-
> >  include/sysemu/tpm.h                      |   7 +
> >  tests/qtest/tpm-tests.h                   |   2 +
> >  tests/qtest/tpm-util.h                    |   4 +-
> >  hw/acpi/aml-build.c                       |   7 +-
> >  hw/arm/virt-acpi-build.c                  |  38 +--
> >  hw/arm/virt.c                             |   8 +
> >  hw/core/sysbus-fdt.c                      |   1 +
> >  hw/i386/acpi-build.c                      |  16 +-
> >  hw/loongarch/acpi-build.c                 |  38 +--
> >  hw/loongarch/virt.c                       |   8 +
> >  hw/riscv/virt.c                           |   1 +
> >  hw/tpm/tpm-sysbus.c                       |  47 ++++
> >  hw/tpm/tpm_crb.c                          | 302 ++++++----------------
> >  hw/tpm/tpm_crb_common.c                   | 262 +++++++++++++++++++
> >  hw/tpm/tpm_crb_sysbus.c                   | 162 ++++++++++++
> >  hw/tpm/tpm_ppi.c                          |   5 +-
> >  hw/tpm/tpm_tis_isa.c                      |   5 +-
> >  hw/tpm/tpm_tis_sysbus.c                   |  37 +++
> >  tests/qtest/bios-tables-test.c            |  47 +++-
> >  tests/qtest/tpm-crb-device-swtpm-test.c   |  72 ++++++
> >  tests/qtest/tpm-crb-device-test.c         |  71 +++++
> >  tests/qtest/tpm-crb-swtpm-test.c          |   2 +
> >  tests/qtest/tpm-crb-test.c                | 121 +--------
> >  tests/qtest/tpm-tests.c                   | 121 +++++++++
> >  tests/qtest/tpm-tis-device-swtpm-test.c   |   2 +-
> >  tests/qtest/tpm-tis-device-test.c         |   2 +-
> >  tests/qtest/tpm-tis-i2c-test.c            |   3 +
> >  tests/qtest/tpm-tis-swtpm-test.c          |   2 +-
> >  tests/qtest/tpm-tis-test.c                |   2 +-
> >  tests/qtest/tpm-util.c                    |  16 +-
> >  hw/arm/Kconfig                            |   1 +
> >  hw/loongarch/Kconfig                      |   2 +
> >  hw/riscv/Kconfig                          |   1 +
> >  hw/tpm/Kconfig                            |   5 +
> >  hw/tpm/meson.build                        |   5 +
> >  hw/tpm/trace-events                       |   2 +-
> >  tests/data/acpi/q35/DSDT.crb.tpm2         | Bin 0 -> 8355 bytes
> >  tests/data/acpi/q35/TPM2.crb.tpm2         | Bin 0 -> 76 bytes
> >  tests/data/acpi/virt/DSDT.crb-device.tpm2 | Bin 0 -> 5276 bytes
> >  tests/data/acpi/virt/TPM2.crb-device.tpm2 | Bin 0 -> 76 bytes
> >  tests/qtest/meson.build                   |   4 +
> >  45 files changed, 1057 insertions(+), 468 deletions(-)
> >  create mode 100644 hw/tpm/tpm_crb.h
> >  create mode 100644 hw/tpm/tpm-sysbus.c
> >  create mode 100644 hw/tpm/tpm_crb_common.c
> >  create mode 100644 hw/tpm/tpm_crb_sysbus.c
> >  create mode 100644 tests/qtest/tpm-crb-device-swtpm-test.c
> >  create mode 100644 tests/qtest/tpm-crb-device-test.c
> >  create mode 100644 tests/data/acpi/q35/DSDT.crb.tpm2
> >  create mode 100644 tests/data/acpi/q35/TPM2.crb.tpm2
> >  create mode 100644 tests/data/acpi/virt/DSDT.crb-device.tpm2
> >  create mode 100644 tests/data/acpi/virt/TPM2.crb-device.tpm2
> >
> > --
> > 2.41.0
> >
> >
>
>
> --
> Marc-André Lureau


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface
  2023-11-14 16:44     ` Stefan Berger
@ 2023-11-14 19:29       ` Joelle van Dyne
  0 siblings, 0 replies; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-14 19:29 UTC (permalink / raw)
  To: Stefan Berger
  Cc: Joelle van Dyne, qemu-devel, Michael S. Tsirkin, Igor Mammedov,
	Ani Sinha, Paolo Bonzini, Richard Henderson, Eduardo Habkost,
	Marcel Apfelbaum, Stefan Berger

On Tue, Nov 14, 2023 at 8:44 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
>
>
>
> On 11/14/23 11:37, Stefan Berger wrote:
> >
> >
> > On 11/13/23 21:09, Joelle van Dyne wrote:
> >> This logic is similar to TPM TIS ISA device. Since TPM CRB can only
> >> support TPM 2.0 backends, we check for this in realize.
> >>
> >> Signed-off-by: Joelle van Dyne <j@getutm.app>
> >> ---
> >>   hw/tpm/tpm_crb.h        |  2 ++
> >>   hw/i386/acpi-build.c    | 16 +---------------
> >>   hw/tpm/tpm_crb.c        | 16 ++++++++++++++++
> >>   hw/tpm/tpm_crb_common.c | 19 +++++++++++++++++++
> >>   4 files changed, 38 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/hw/tpm/tpm_crb.h b/hw/tpm/tpm_crb.h
> >> index 36863e1664..e6a86e3fd1 100644
> >> --- a/hw/tpm/tpm_crb.h
> >> +++ b/hw/tpm/tpm_crb.h
> >> @@ -73,5 +73,7 @@ void tpm_crb_init_memory(Object *obj, TPMCRBState
> >> *s, Error **errp);
> >>   void tpm_crb_mem_save(TPMCRBState *s, uint32_t *saved_regs, void
> >> *saved_cmdmem);
> >>   void tpm_crb_mem_load(TPMCRBState *s, const uint32_t *saved_regs,
> >>                         const void *saved_cmdmem);
> >> +void tpm_crb_build_aml(TPMIf *ti, Aml *scope, uint32_t baseaddr,
> >> uint32_t size,
> >> +                       bool build_ppi);
> >>
> >>   #endif /* TPM_TPM_CRB_H */
> >> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> >> index 80db183b78..7491cee2af 100644
> >> --- a/hw/i386/acpi-build.c
> >> +++ b/hw/i386/acpi-build.c
> >> @@ -1792,21 +1792,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> >>
> >>   #ifdef CONFIG_TPM
> >>       if (TPM_IS_CRB(tpm)) {
> >> -        dev = aml_device("TPM");
> >> -        aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
> >> -        aml_append(dev, aml_name_decl("_STR",
> >> -                                      aml_string("TPM 2.0 Device")));
> >> -        crs = aml_resource_template();
> >> -        aml_append(crs, aml_memory32_fixed(TPM_CRB_ADDR_BASE,
> >> -                                           TPM_CRB_ADDR_SIZE,
> >> AML_READ_WRITE));
> >> -        aml_append(dev, aml_name_decl("_CRS", crs));
> >> -
> >> -        aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
> >> -        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
> >> -
> >> -        tpm_build_ppi_acpi(tpm, dev);
> >> -
> >> -        aml_append(sb_scope, dev);
> >> +        call_dev_aml_func(DEVICE(tpm), scope);
> >
> > For an x86_64 VM we have to call it directly otherwise the ACPI table
> > won't be there.
> >
> >          tpm_crb_build_aml(tpm, sb_scope, TPM_CRB_ADDR_BASE,
> > TPM_CRB_ADDR_SIZE, true);
> >
> >
> I looks like a good place for the moved code would be in hw/acpi/tpm.c

The change in v5 is that we call "call_dev_aml_func" which calls
"tpm_crb_build_aml" from tpm_crb.c (later moved to tpm_crb_common.c).
I think it's a better place for it because TPM TIS has a different
ACPI table and both can be handled correctly by call_dev_aml_func. In
the previous versions when we moved TPM CRB to ISA there was no need
to manually call "call_dev_aml_func" because the function for building
the ISA bus called it. However, I think this is still better in case
it is decided in the future to move the CRB device on ISA or another
bus and it makes the code more manageable with more TPM types.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-14 18:03     ` Stefan Berger
@ 2023-11-14 21:05       ` Stefan Berger
  2023-11-15  0:12         ` Stefan Berger
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-14 21:05 UTC (permalink / raw)
  To: Marc-André Lureau, Joelle van Dyne
  Cc: qemu-devel, Michael S. Tsirkin, Igor Mammedov, Ani Sinha



On 11/14/23 13:03, Stefan Berger wrote:
> 
> 
> On 11/14/23 04:36, Marc-André Lureau wrote:
>> Hi
>>
>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>>
>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>
>> nit: you also added tests for x86, could be a different patch?
>>
>> For arm, the test fails until next patch with:
>>
>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
>> chardev=char0,mode=control -display none -audio none -machine virt
>> -accel tcg -nodefaults -nographic -drive
>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
>> -cpu cortex-a57 -chardev
>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
>> -accel qtest
>> Warning! zero length expected file 
>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
>> Warning! zero length expected file 
>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
>> acpi-test: Warning!  binary file mismatch. Actual
>> [aml:/tmp/aml-GO4ME2], Expected
>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
>> See source file tests/qtest/bios-tables-test.c for instructions on how
>> to update expected files.
>> acpi-test: Warning!  binary file mismatch. Actual
>> [aml:/tmp/aml-6N4ME2], Expected
>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
>> See source file tests/qtest/bios-tables-test.c for instructions on how
>> to update expected files.
>> to see ASL diff between mismatched files install IASL, rebuild QEMU
>> from scratch and re-run tests with V=1 environment variable set**
>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>> failed: (all_tables_match)
>> not ok /aarch64/acpi/virt/tpm2-crb -
>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>> failed: (all_tables_match)
>> Bail out!
>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
>> Resource temporarily unavailable
>> Unexpected error in qio_channel_socket_writev() at 
>> ../io/channel-socket.c:622:
>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
>> to write to socket: Bad file descriptor
>>
> 
> Travis testing on s390x I see the following failures for this patchset 
> (search for 'ERROR'):
> 
> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
> 
> Summary of Failures:
> 
> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test   
> ERROR           0.70s   killed by signal 6 SIGABRT
> 
> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test   
> ERROR           0.88s   killed by signal 6 SIGABRT
> 
> 
> Summary of Failures:
> 
> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test          
> ERROR           0.59s   killed by signal 6 SIGABRT
> 
> 
> My guess is it's an endianess issue on big endian machines due to 
> reading from the ROM device where we lost the .endianess:
> 
> +const MemoryRegionOps tpm_crb_memory_ops = {
> +    .read = tpm_crb_mmio_read,
> +    .write = tpm_crb_mmio_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +    .valid = {
> +        .min_access_size = 1,
> +        .max_access_size = 4,
> +    },
> +};
> 

I think we need a 2nd set of registers to support the endianess 
conversion. It's not exactly nice, though. Basically the saved_regs 
could be used for this directly, even though I did not do that but 
introduced n_regs: 
https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91 


This patch allows the tests on s390x to run farther but the execution of 
the command doesn't seem to work maybe due to command data that were 
also written in wrong endianess. I don't know. I would have to get 
access to a big endian / s390 machine to be able to fix it.



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-14 21:05       ` Stefan Berger
@ 2023-11-15  0:12         ` Stefan Berger
  2023-11-24  0:56           ` Joelle van Dyne
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-15  0:12 UTC (permalink / raw)
  To: Marc-André Lureau, Joelle van Dyne
  Cc: qemu-devel, Michael S. Tsirkin, Igor Mammedov, Ani Sinha



On 11/14/23 16:05, Stefan Berger wrote:
> 
> 
> On 11/14/23 13:03, Stefan Berger wrote:
>>
>>
>> On 11/14/23 04:36, Marc-André Lureau wrote:
>>> Hi
>>>
>>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>>>
>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>>
>>> nit: you also added tests for x86, could be a different patch?
>>>
>>> For arm, the test fails until next patch with:
>>>
>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
>>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
>>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
>>> chardev=char0,mode=control -display none -audio none -machine virt
>>> -accel tcg -nodefaults -nographic -drive
>>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
>>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
>>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
>>> -cpu cortex-a57 -chardev
>>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
>>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
>>> -accel qtest
>>> Warning! zero length expected file 
>>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
>>> Warning! zero length expected file 
>>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
>>> acpi-test: Warning!  binary file mismatch. Actual
>>> [aml:/tmp/aml-GO4ME2], Expected
>>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>> to update expected files.
>>> acpi-test: Warning!  binary file mismatch. Actual
>>> [aml:/tmp/aml-6N4ME2], Expected
>>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>> to update expected files.
>>> to see ASL diff between mismatched files install IASL, rebuild QEMU
>>> from scratch and re-run tests with V=1 environment variable set**
>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>> failed: (all_tables_match)
>>> not ok /aarch64/acpi/virt/tpm2-crb -
>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>> failed: (all_tables_match)
>>> Bail out!
>>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
>>> Resource temporarily unavailable
>>> Unexpected error in qio_channel_socket_writev() at 
>>> ../io/channel-socket.c:622:
>>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
>>> to write to socket: Bad file descriptor
>>>
>>
>> Travis testing on s390x I see the following failures for this patchset 
>> (search for 'ERROR'):
>>
>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
>>
>> Summary of Failures:
>>
>> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test 
>> ERROR           0.70s   killed by signal 6 SIGABRT
>>
>> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test 
>> ERROR           0.88s   killed by signal 6 SIGABRT
>>
>>
>> Summary of Failures:
>>
>> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test 
>> ERROR           0.59s   killed by signal 6 SIGABRT
>>
>>
>> My guess is it's an endianess issue on big endian machines due to 
>> reading from the ROM device where we lost the .endianess:
>>
>> +const MemoryRegionOps tpm_crb_memory_ops = {
>> +    .read = tpm_crb_mmio_read,
>> +    .write = tpm_crb_mmio_write,
>> +    .endianness = DEVICE_LITTLE_ENDIAN,
>> +    .valid = {
>> +        .min_access_size = 1,
>> +        .max_access_size = 4,
>> +    },
>> +};
>>
> 
> I think we need a 2nd set of registers to support the endianess 
> conversion. It's not exactly nice, though. Basically the saved_regs 
> could be used for this directly, even though I did not do that but 
> introduced n_regs: 
> https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
> 
> This patch allows the tests on s390x to run farther but the execution of 
> the command doesn't seem to work maybe due to command data that were 
> also written in wrong endianess. I don't know. I would have to get 
> access to a big endian / s390 machine to be able to fix it.
> 
> 

The latest version now passes on Travis s390x: 
https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device
  2023-11-14 19:25   ` Joelle van Dyne
@ 2023-11-20  8:29     ` Marc-André Lureau
  2023-11-20 15:01       ` Stefan Berger
  0 siblings, 1 reply; 35+ messages in thread
From: Marc-André Lureau @ 2023-11-20  8:29 UTC (permalink / raw)
  To: Joelle van Dyne, Stefan Berger; +Cc: qemu-devel

Hi

On Tue, Nov 14, 2023 at 11:25 PM Joelle van Dyne <j@getutm.app> wrote:
>
> On Tue, Nov 14, 2023 at 1:38 AM Marc-André Lureau
> <marcandre.lureau@gmail.com> wrote:
> >
> > Hi
> >
> > On Tue, Nov 14, 2023 at 6:10 AM Joelle van Dyne <j@getutm.app> wrote:
> > >
> > > The impetus for this patch set is to get TPM 2.0 working on Windows 11 ARM64.
> > > Windows' tpm.sys does not seem to work on a TPM TIS device (as verified with
> > > VMWare's implementation). However, the current TPM CRB device uses a fixed
> > > system bus address that is reserved for RAM in ARM64 Virt machines.
> > >
> > > In the process of adding the TPM CRB SysBus device, we also went ahead and
> > > cleaned up some of the existing TPM hardware code and fixed some bugs. We used
> > > the TPM TIS devices as a template for the TPM CRB devices and refactored out
> > > common code. We moved the ACPI DSDT generation to the device in order to handle
> > > dynamic base address requirements as well as reduce redundent code in different
> > > machine ACPI generation. We also changed the tpm_crb device to use the ISA bus
> > > instead of depending on the default system bus as the device only was built for
> > > the PC configuration.
> > >
> > > Another change is that the TPM CRB registers are now mapped in the same way that
> > > the pflash ROM devices are mapped. It is a memory region whose writes are
> > > trapped as MMIO accesses. This was needed because Apple Silicon does not decode
> > > LDP (AARCH64 load pair of registers) caused page faults. @agraf suggested that
> > > we do this to avoid having to do AARCH64 decoding in the HVF backend's fault
> > > handler.
> > >
> > > Unfortunately, it seems like the LDP fault still happens on HVF but the issue
> > > seems to be in the HVF backend which needs to be fixed in a separate patch.
> > >
> > > One last thing that's needed to get Windows 11 to recognize the TPM 2.0 device
> > > is for the OVMF firmware to setup the TPM device. Currently, OVMF for ARM64 Virt
> > > only recognizes the TPM TIS device through a FDT entry. A workaround is to
> > > falsely identify the TPM CRB device as a TPM TIS device in the FDT node but this
> > > causes issues for Linux. A proper fix would involve adding an ACPI device driver
> > > in OVMF.
> > >
> > > This has been tested on ARM64 with `tpm-crb-device` and on x86_64 with
> > > `tpm-crb`. Additional testing should be performed on other architectures (RISCV
> > > and Loongarch for example) as well as migration cases.
> > >
> > > v5:
> > > - Fixed a typo in "tpm_crb: use a single read-as-mem/write-as-mmio mapping"
> > > - Fixed ACPI tables not being created for pc CRB device
> > >
> > > v4:
> > > - Fixed broken test blobs
> > >
> > > v3:
> > > - Support backwards and forwards migration of existing tpm-crb device
> > > - Dropped patch which moved tpm-crb to ISA bus due to migration concerns
> > > - Unified `tpm_sysbus_plug` handler for ARM and Loongarch
> > > - Added ACPI table tests for tpm-crb-device
> > > - Refactored TPM CRB tests to run on tpm-crb-device for ARM Virt
> > >
> > > v2:
> > > - Fixed an issue where VMstate restore from an older version failed due to name
> > >   collision of the memory block.
> > > - In the ACPI table generation for CRB devices, the check for TPM 2.0 backend is
> > >   moved to the device realize as CRB does not support TPM 1.0. It will error in
> > >   that case.
> > > - Dropped the patch to fix crash when PPI is enabled on TIS SysBus device since
> > >   a separate patch submitted by Stefan Berger disables such an option.
> > > - Fixed an issue where we default tpmEstablished=0 when it should be 1.
> > > - In TPM CRB SysBus's ACPI entry, we accidently changed _UID from 0 to 1. This
> > >   shouldn't be an issue but we changed it back just in case.
> > > - Added a patch to migrate saved VMstate from an older version with the regs
> > >   saved separately instead of as a RAM block.
> > >
> > > Joelle van Dyne (14):
> > >   tpm_crb: refactor common code
> > >   tpm_crb: CTRL_RSP_ADDR is 64-bits wide
> > >   tpm_ppi: refactor memory space initialization
> > >   tpm_crb: use a single read-as-mem/write-as-mmio mapping
> > >   tpm_crb: move ACPI table building to device interface
> > >   tpm-sysbus: add plug handler for TPM on SysBus
> > >   hw/arm/virt: connect TPM to platform bus
> > >   hw/loongarch/virt: connect TPM to platform bus
> > >   tpm_tis_sysbus: move DSDT AML generation to device
> > >   tests: acpi: prepare for TPM CRB tests
> > >   tpm_crb_sysbus: introduce TPM CRB SysBus device
> > >   tests: acpi: implement TPM CRB tests for ARM virt
> > >   tests: acpi: updated expected blobs for TPM CRB
> > >   tests: add TPM-CRB sysbus tests for aarch64
> >
> > The series looks good to me.
> > Have you checked there are no regressions with Windows HLK?
> I don't have any experience with Windows HLK. Is there any guide on
> running it with QEMU? Preferably with a prebuilt image? Or maybe
> someone in the mailing list can run it?
>

I haven't done it for a while. (it wasn't that hard, just a bit
tedious: install a Controller on a Windows Server VM, and set up a
target VM)

There is also AutoHCK, but I never managed to use it.
(https://github.com/HCK-CI/AutoHCK)

For the current results, they are summarized here:
https://github.com/stefanberger/libtpms/wiki/Testing-of-libtpms-Functionality

Stefan, do you have a working setup? I'll try to make one if it can help.


> >
> > thanks
> >
> > >
> > >  docs/specs/tpm.rst                        |   2 +
> > >  hw/tpm/tpm_crb.h                          |  79 ++++++
> > >  hw/tpm/tpm_ppi.h                          |  10 +-
> > >  include/hw/acpi/tpm.h                     |   3 +-
> > >  include/sysemu/tpm.h                      |   7 +
> > >  tests/qtest/tpm-tests.h                   |   2 +
> > >  tests/qtest/tpm-util.h                    |   4 +-
> > >  hw/acpi/aml-build.c                       |   7 +-
> > >  hw/arm/virt-acpi-build.c                  |  38 +--
> > >  hw/arm/virt.c                             |   8 +
> > >  hw/core/sysbus-fdt.c                      |   1 +
> > >  hw/i386/acpi-build.c                      |  16 +-
> > >  hw/loongarch/acpi-build.c                 |  38 +--
> > >  hw/loongarch/virt.c                       |   8 +
> > >  hw/riscv/virt.c                           |   1 +
> > >  hw/tpm/tpm-sysbus.c                       |  47 ++++
> > >  hw/tpm/tpm_crb.c                          | 302 ++++++----------------
> > >  hw/tpm/tpm_crb_common.c                   | 262 +++++++++++++++++++
> > >  hw/tpm/tpm_crb_sysbus.c                   | 162 ++++++++++++
> > >  hw/tpm/tpm_ppi.c                          |   5 +-
> > >  hw/tpm/tpm_tis_isa.c                      |   5 +-
> > >  hw/tpm/tpm_tis_sysbus.c                   |  37 +++
> > >  tests/qtest/bios-tables-test.c            |  47 +++-
> > >  tests/qtest/tpm-crb-device-swtpm-test.c   |  72 ++++++
> > >  tests/qtest/tpm-crb-device-test.c         |  71 +++++
> > >  tests/qtest/tpm-crb-swtpm-test.c          |   2 +
> > >  tests/qtest/tpm-crb-test.c                | 121 +--------
> > >  tests/qtest/tpm-tests.c                   | 121 +++++++++
> > >  tests/qtest/tpm-tis-device-swtpm-test.c   |   2 +-
> > >  tests/qtest/tpm-tis-device-test.c         |   2 +-
> > >  tests/qtest/tpm-tis-i2c-test.c            |   3 +
> > >  tests/qtest/tpm-tis-swtpm-test.c          |   2 +-
> > >  tests/qtest/tpm-tis-test.c                |   2 +-
> > >  tests/qtest/tpm-util.c                    |  16 +-
> > >  hw/arm/Kconfig                            |   1 +
> > >  hw/loongarch/Kconfig                      |   2 +
> > >  hw/riscv/Kconfig                          |   1 +
> > >  hw/tpm/Kconfig                            |   5 +
> > >  hw/tpm/meson.build                        |   5 +
> > >  hw/tpm/trace-events                       |   2 +-
> > >  tests/data/acpi/q35/DSDT.crb.tpm2         | Bin 0 -> 8355 bytes
> > >  tests/data/acpi/q35/TPM2.crb.tpm2         | Bin 0 -> 76 bytes
> > >  tests/data/acpi/virt/DSDT.crb-device.tpm2 | Bin 0 -> 5276 bytes
> > >  tests/data/acpi/virt/TPM2.crb-device.tpm2 | Bin 0 -> 76 bytes
> > >  tests/qtest/meson.build                   |   4 +
> > >  45 files changed, 1057 insertions(+), 468 deletions(-)
> > >  create mode 100644 hw/tpm/tpm_crb.h
> > >  create mode 100644 hw/tpm/tpm-sysbus.c
> > >  create mode 100644 hw/tpm/tpm_crb_common.c
> > >  create mode 100644 hw/tpm/tpm_crb_sysbus.c
> > >  create mode 100644 tests/qtest/tpm-crb-device-swtpm-test.c
> > >  create mode 100644 tests/qtest/tpm-crb-device-test.c
> > >  create mode 100644 tests/data/acpi/q35/DSDT.crb.tpm2
> > >  create mode 100644 tests/data/acpi/q35/TPM2.crb.tpm2
> > >  create mode 100644 tests/data/acpi/virt/DSDT.crb-device.tpm2
> > >  create mode 100644 tests/data/acpi/virt/TPM2.crb-device.tpm2
> > >
> > > --
> > > 2.41.0
> > >
> > >
> >
> >
> > --
> > Marc-André Lureau



--
Marc-André Lureau


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device
  2023-11-20  8:29     ` Marc-André Lureau
@ 2023-11-20 15:01       ` Stefan Berger
  0 siblings, 0 replies; 35+ messages in thread
From: Stefan Berger @ 2023-11-20 15:01 UTC (permalink / raw)
  To: Marc-André Lureau, Joelle van Dyne; +Cc: qemu-devel



On 11/20/23 03:29, Marc-André Lureau wrote:
> Hi
> 
> On Tue, Nov 14, 2023 at 11:25 PM Joelle van Dyne <j@getutm.app> wrote:
>>
>> On Tue, Nov 14, 2023 at 1:38 AM Marc-André Lureau
>> <marcandre.lureau@gmail.com> wrote:
>>>
>>> Hi
>>>
>>> On Tue, Nov 14, 2023 at 6:10 AM Joelle van Dyne <j@getutm.app> wrote:
>>>>
>>>> The impetus for this patch set is to get TPM 2.0 working on Windows 11 ARM64.
>>>> Windows' tpm.sys does not seem to work on a TPM TIS device (as verified with
>>>> VMWare's implementation). However, the current TPM CRB device uses a fixed
>>>> system bus address that is reserved for RAM in ARM64 Virt machines.
>>>>
>>>> In the process of adding the TPM CRB SysBus device, we also went ahead and
>>>> cleaned up some of the existing TPM hardware code and fixed some bugs. We used
>>>> the TPM TIS devices as a template for the TPM CRB devices and refactored out
>>>> common code. We moved the ACPI DSDT generation to the device in order to handle
>>>> dynamic base address requirements as well as reduce redundent code in different
>>>> machine ACPI generation. We also changed the tpm_crb device to use the ISA bus
>>>> instead of depending on the default system bus as the device only was built for
>>>> the PC configuration.
>>>>
>>>> Another change is that the TPM CRB registers are now mapped in the same way that
>>>> the pflash ROM devices are mapped. It is a memory region whose writes are
>>>> trapped as MMIO accesses. This was needed because Apple Silicon does not decode
>>>> LDP (AARCH64 load pair of registers) caused page faults. @agraf suggested that
>>>> we do this to avoid having to do AARCH64 decoding in the HVF backend's fault
>>>> handler.
>>>>
>>>> Unfortunately, it seems like the LDP fault still happens on HVF but the issue
>>>> seems to be in the HVF backend which needs to be fixed in a separate patch.
>>>>
>>>> One last thing that's needed to get Windows 11 to recognize the TPM 2.0 device
>>>> is for the OVMF firmware to setup the TPM device. Currently, OVMF for ARM64 Virt
>>>> only recognizes the TPM TIS device through a FDT entry. A workaround is to
>>>> falsely identify the TPM CRB device as a TPM TIS device in the FDT node but this
>>>> causes issues for Linux. A proper fix would involve adding an ACPI device driver
>>>> in OVMF.
>>>>
>>>> This has been tested on ARM64 with `tpm-crb-device` and on x86_64 with
>>>> `tpm-crb`. Additional testing should be performed on other architectures (RISCV
>>>> and Loongarch for example) as well as migration cases.
>>>>
>>>> v5:
>>>> - Fixed a typo in "tpm_crb: use a single read-as-mem/write-as-mmio mapping"
>>>> - Fixed ACPI tables not being created for pc CRB device
>>>>
>>>> v4:
>>>> - Fixed broken test blobs
>>>>
>>>> v3:
>>>> - Support backwards and forwards migration of existing tpm-crb device
>>>> - Dropped patch which moved tpm-crb to ISA bus due to migration concerns
>>>> - Unified `tpm_sysbus_plug` handler for ARM and Loongarch
>>>> - Added ACPI table tests for tpm-crb-device
>>>> - Refactored TPM CRB tests to run on tpm-crb-device for ARM Virt
>>>>
>>>> v2:
>>>> - Fixed an issue where VMstate restore from an older version failed due to name
>>>>    collision of the memory block.
>>>> - In the ACPI table generation for CRB devices, the check for TPM 2.0 backend is
>>>>    moved to the device realize as CRB does not support TPM 1.0. It will error in
>>>>    that case.
>>>> - Dropped the patch to fix crash when PPI is enabled on TIS SysBus device since
>>>>    a separate patch submitted by Stefan Berger disables such an option.
>>>> - Fixed an issue where we default tpmEstablished=0 when it should be 1.
>>>> - In TPM CRB SysBus's ACPI entry, we accidently changed _UID from 0 to 1. This
>>>>    shouldn't be an issue but we changed it back just in case.
>>>> - Added a patch to migrate saved VMstate from an older version with the regs
>>>>    saved separately instead of as a RAM block.
>>>>
>>>> Joelle van Dyne (14):
>>>>    tpm_crb: refactor common code
>>>>    tpm_crb: CTRL_RSP_ADDR is 64-bits wide
>>>>    tpm_ppi: refactor memory space initialization
>>>>    tpm_crb: use a single read-as-mem/write-as-mmio mapping
>>>>    tpm_crb: move ACPI table building to device interface
>>>>    tpm-sysbus: add plug handler for TPM on SysBus
>>>>    hw/arm/virt: connect TPM to platform bus
>>>>    hw/loongarch/virt: connect TPM to platform bus
>>>>    tpm_tis_sysbus: move DSDT AML generation to device
>>>>    tests: acpi: prepare for TPM CRB tests
>>>>    tpm_crb_sysbus: introduce TPM CRB SysBus device
>>>>    tests: acpi: implement TPM CRB tests for ARM virt
>>>>    tests: acpi: updated expected blobs for TPM CRB
>>>>    tests: add TPM-CRB sysbus tests for aarch64
>>>
>>> The series looks good to me.
>>> Have you checked there are no regressions with Windows HLK?
>> I don't have any experience with Windows HLK. Is there any guide on
>> running it with QEMU? Preferably with a prebuilt image? Or maybe
>> someone in the mailing list can run it?
>>
> 
> I haven't done it for a while. (it wasn't that hard, just a bit
> tedious: install a Controller on a Windows Server VM, and set up a
> target VM)
> 
> There is also AutoHCK, but I never managed to use it.
> (https://github.com/HCK-CI/AutoHCK)
> 
> For the current results, they are summarized here:
> https://github.com/stefanberger/libtpms/wiki/Testing-of-libtpms-Functionality
> 
> Stefan, do you have a working setup? I'll try to make one if it can help.

Once we have the fixes for big endian support I can run some tests. It 
should be rather quick to verify that the CRB interface still works, 
even with Linux. What I would be more concerned are suspend/upgrade or 
downgrade/resume tests.

    Stefan

> 
> 
>>>
>>> thanks
>>>
>>>>
>>>>   docs/specs/tpm.rst                        |   2 +
>>>>   hw/tpm/tpm_crb.h                          |  79 ++++++
>>>>   hw/tpm/tpm_ppi.h                          |  10 +-
>>>>   include/hw/acpi/tpm.h                     |   3 +-
>>>>   include/sysemu/tpm.h                      |   7 +
>>>>   tests/qtest/tpm-tests.h                   |   2 +
>>>>   tests/qtest/tpm-util.h                    |   4 +-
>>>>   hw/acpi/aml-build.c                       |   7 +-
>>>>   hw/arm/virt-acpi-build.c                  |  38 +--
>>>>   hw/arm/virt.c                             |   8 +
>>>>   hw/core/sysbus-fdt.c                      |   1 +
>>>>   hw/i386/acpi-build.c                      |  16 +-
>>>>   hw/loongarch/acpi-build.c                 |  38 +--
>>>>   hw/loongarch/virt.c                       |   8 +
>>>>   hw/riscv/virt.c                           |   1 +
>>>>   hw/tpm/tpm-sysbus.c                       |  47 ++++
>>>>   hw/tpm/tpm_crb.c                          | 302 ++++++----------------
>>>>   hw/tpm/tpm_crb_common.c                   | 262 +++++++++++++++++++
>>>>   hw/tpm/tpm_crb_sysbus.c                   | 162 ++++++++++++
>>>>   hw/tpm/tpm_ppi.c                          |   5 +-
>>>>   hw/tpm/tpm_tis_isa.c                      |   5 +-
>>>>   hw/tpm/tpm_tis_sysbus.c                   |  37 +++
>>>>   tests/qtest/bios-tables-test.c            |  47 +++-
>>>>   tests/qtest/tpm-crb-device-swtpm-test.c   |  72 ++++++
>>>>   tests/qtest/tpm-crb-device-test.c         |  71 +++++
>>>>   tests/qtest/tpm-crb-swtpm-test.c          |   2 +
>>>>   tests/qtest/tpm-crb-test.c                | 121 +--------
>>>>   tests/qtest/tpm-tests.c                   | 121 +++++++++
>>>>   tests/qtest/tpm-tis-device-swtpm-test.c   |   2 +-
>>>>   tests/qtest/tpm-tis-device-test.c         |   2 +-
>>>>   tests/qtest/tpm-tis-i2c-test.c            |   3 +
>>>>   tests/qtest/tpm-tis-swtpm-test.c          |   2 +-
>>>>   tests/qtest/tpm-tis-test.c                |   2 +-
>>>>   tests/qtest/tpm-util.c                    |  16 +-
>>>>   hw/arm/Kconfig                            |   1 +
>>>>   hw/loongarch/Kconfig                      |   2 +
>>>>   hw/riscv/Kconfig                          |   1 +
>>>>   hw/tpm/Kconfig                            |   5 +
>>>>   hw/tpm/meson.build                        |   5 +
>>>>   hw/tpm/trace-events                       |   2 +-
>>>>   tests/data/acpi/q35/DSDT.crb.tpm2         | Bin 0 -> 8355 bytes
>>>>   tests/data/acpi/q35/TPM2.crb.tpm2         | Bin 0 -> 76 bytes
>>>>   tests/data/acpi/virt/DSDT.crb-device.tpm2 | Bin 0 -> 5276 bytes
>>>>   tests/data/acpi/virt/TPM2.crb-device.tpm2 | Bin 0 -> 76 bytes
>>>>   tests/qtest/meson.build                   |   4 +
>>>>   45 files changed, 1057 insertions(+), 468 deletions(-)
>>>>   create mode 100644 hw/tpm/tpm_crb.h
>>>>   create mode 100644 hw/tpm/tpm-sysbus.c
>>>>   create mode 100644 hw/tpm/tpm_crb_common.c
>>>>   create mode 100644 hw/tpm/tpm_crb_sysbus.c
>>>>   create mode 100644 tests/qtest/tpm-crb-device-swtpm-test.c
>>>>   create mode 100644 tests/qtest/tpm-crb-device-test.c
>>>>   create mode 100644 tests/data/acpi/q35/DSDT.crb.tpm2
>>>>   create mode 100644 tests/data/acpi/q35/TPM2.crb.tpm2
>>>>   create mode 100644 tests/data/acpi/virt/DSDT.crb-device.tpm2
>>>>   create mode 100644 tests/data/acpi/virt/TPM2.crb-device.tpm2
>>>>
>>>> --
>>>> 2.41.0
>>>>
>>>>
>>>
>>>
>>> --
>>> Marc-André Lureau
> 
> 
> 
> --
> Marc-André Lureau


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-15  0:12         ` Stefan Berger
@ 2023-11-24  0:56           ` Joelle van Dyne
  2023-11-24 16:17             ` Stefan Berger
  0 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-24  0:56 UTC (permalink / raw)
  To: Stefan Berger
  Cc: Marc-André Lureau, Joelle van Dyne, qemu-devel,
	Michael S. Tsirkin, Igor Mammedov, Ani Sinha

On Tue, Nov 14, 2023 at 4:12 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
>
>
>
> On 11/14/23 16:05, Stefan Berger wrote:
> >
> >
> > On 11/14/23 13:03, Stefan Berger wrote:
> >>
> >>
> >> On 11/14/23 04:36, Marc-André Lureau wrote:
> >>> Hi
> >>>
> >>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
> >>>>
> >>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
> >>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> >>>
> >>> nit: you also added tests for x86, could be a different patch?
> >>>
> >>> For arm, the test fails until next patch with:
> >>>
> >>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
> >>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
> >>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
> >>> chardev=char0,mode=control -display none -audio none -machine virt
> >>> -accel tcg -nodefaults -nographic -drive
> >>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
> >>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
> >>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
> >>> -cpu cortex-a57 -chardev
> >>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
> >>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
> >>> -accel qtest
> >>> Warning! zero length expected file
> >>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
> >>> Warning! zero length expected file
> >>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
> >>> acpi-test: Warning!  binary file mismatch. Actual
> >>> [aml:/tmp/aml-GO4ME2], Expected
> >>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
> >>> See source file tests/qtest/bios-tables-test.c for instructions on how
> >>> to update expected files.
> >>> acpi-test: Warning!  binary file mismatch. Actual
> >>> [aml:/tmp/aml-6N4ME2], Expected
> >>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
> >>> See source file tests/qtest/bios-tables-test.c for instructions on how
> >>> to update expected files.
> >>> to see ASL diff between mismatched files install IASL, rebuild QEMU
> >>> from scratch and re-run tests with V=1 environment variable set**
> >>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> >>> failed: (all_tables_match)
> >>> not ok /aarch64/acpi/virt/tpm2-crb -
> >>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> >>> failed: (all_tables_match)
> >>> Bail out!
> >>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
> >>> Resource temporarily unavailable
> >>> Unexpected error in qio_channel_socket_writev() at
> >>> ../io/channel-socket.c:622:
> >>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
> >>> to write to socket: Bad file descriptor
> >>>
> >>
> >> Travis testing on s390x I see the following failures for this patchset
> >> (search for 'ERROR'):
> >>
> >> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
> >>
> >> Summary of Failures:
> >>
> >> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test
> >> ERROR           0.70s   killed by signal 6 SIGABRT
> >>
> >> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test
> >> ERROR           0.88s   killed by signal 6 SIGABRT
> >>
> >>
> >> Summary of Failures:
> >>
> >> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test
> >> ERROR           0.59s   killed by signal 6 SIGABRT
> >>
> >>
> >> My guess is it's an endianess issue on big endian machines due to
> >> reading from the ROM device where we lost the .endianess:
> >>
> >> +const MemoryRegionOps tpm_crb_memory_ops = {
> >> +    .read = tpm_crb_mmio_read,
> >> +    .write = tpm_crb_mmio_write,
> >> +    .endianness = DEVICE_LITTLE_ENDIAN,
> >> +    .valid = {
> >> +        .min_access_size = 1,
> >> +        .max_access_size = 4,
> >> +    },
> >> +};
> >>
> >
> > I think we need a 2nd set of registers to support the endianess
> > conversion. It's not exactly nice, though. Basically the saved_regs
> > could be used for this directly, even though I did not do that but
> > introduced n_regs:
> > https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
> >
> > This patch allows the tests on s390x to run farther but the execution of
> > the command doesn't seem to work maybe due to command data that were
> > also written in wrong endianess. I don't know. I would have to get
> > access to a big endian / s390 machine to be able to fix it.
> >
> >
>
> The latest version now passes on Travis s390x:
> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220
>

Are the tests failing on S390X due to the added code or are they
failing because previously it was untested? I don't think the original
code took account of endianness and that should be fixed, but feels
like it should be in a separate patch set?


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-24  0:56           ` Joelle van Dyne
@ 2023-11-24 16:17             ` Stefan Berger
  2023-11-24 16:21               ` Joelle van Dyne
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-24 16:17 UTC (permalink / raw)
  To: Joelle van Dyne
  Cc: Marc-André Lureau, qemu-devel, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha



On 11/23/23 19:56, Joelle van Dyne wrote:
> On Tue, Nov 14, 2023 at 4:12 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>
>>
>>
>> On 11/14/23 16:05, Stefan Berger wrote:
>>>
>>>
>>> On 11/14/23 13:03, Stefan Berger wrote:
>>>>
>>>>
>>>> On 11/14/23 04:36, Marc-André Lureau wrote:
>>>>> Hi
>>>>>
>>>>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>>>>>
>>>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>>>>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>>>>
>>>>> nit: you also added tests for x86, could be a different patch?
>>>>>
>>>>> For arm, the test fails until next patch with:
>>>>>
>>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
>>>>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
>>>>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
>>>>> chardev=char0,mode=control -display none -audio none -machine virt
>>>>> -accel tcg -nodefaults -nographic -drive
>>>>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
>>>>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
>>>>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
>>>>> -cpu cortex-a57 -chardev
>>>>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
>>>>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
>>>>> -accel qtest
>>>>> Warning! zero length expected file
>>>>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
>>>>> Warning! zero length expected file
>>>>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
>>>>> acpi-test: Warning!  binary file mismatch. Actual
>>>>> [aml:/tmp/aml-GO4ME2], Expected
>>>>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>>>> to update expected files.
>>>>> acpi-test: Warning!  binary file mismatch. Actual
>>>>> [aml:/tmp/aml-6N4ME2], Expected
>>>>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>>>> to update expected files.
>>>>> to see ASL diff between mismatched files install IASL, rebuild QEMU
>>>>> from scratch and re-run tests with V=1 environment variable set**
>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>>>> failed: (all_tables_match)
>>>>> not ok /aarch64/acpi/virt/tpm2-crb -
>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>>>> failed: (all_tables_match)
>>>>> Bail out!
>>>>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
>>>>> Resource temporarily unavailable
>>>>> Unexpected error in qio_channel_socket_writev() at
>>>>> ../io/channel-socket.c:622:
>>>>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
>>>>> to write to socket: Bad file descriptor
>>>>>
>>>>
>>>> Travis testing on s390x I see the following failures for this patchset
>>>> (search for 'ERROR'):
>>>>
>>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
>>>>
>>>> Summary of Failures:
>>>>
>>>> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test
>>>> ERROR           0.70s   killed by signal 6 SIGABRT
>>>>
>>>> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test
>>>> ERROR           0.88s   killed by signal 6 SIGABRT
>>>>
>>>>
>>>> Summary of Failures:
>>>>
>>>> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test
>>>> ERROR           0.59s   killed by signal 6 SIGABRT
>>>>
>>>>
>>>> My guess is it's an endianess issue on big endian machines due to
>>>> reading from the ROM device where we lost the .endianess:
>>>>
>>>> +const MemoryRegionOps tpm_crb_memory_ops = {
>>>> +    .read = tpm_crb_mmio_read,
>>>> +    .write = tpm_crb_mmio_write,
>>>> +    .endianness = DEVICE_LITTLE_ENDIAN,
>>>> +    .valid = {
>>>> +        .min_access_size = 1,
>>>> +        .max_access_size = 4,
>>>> +    },
>>>> +};
>>>>
>>>
>>> I think we need a 2nd set of registers to support the endianess
>>> conversion. It's not exactly nice, though. Basically the saved_regs
>>> could be used for this directly, even though I did not do that but
>>> introduced n_regs:
>>> https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
>>>
>>> This patch allows the tests on s390x to run farther but the execution of
>>> the command doesn't seem to work maybe due to command data that were
>>> also written in wrong endianess. I don't know. I would have to get
>>> access to a big endian / s390 machine to be able to fix it.
>>>
>>>
>>
>> The latest version now passes on Travis s390x:
>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220
>>
> 
> Are the tests failing on S390X due to the added code or are they
> failing because previously it was untested? I don't think the original
> code took account of endianness and that should be fixed, but feels
> like it should be in a separate patch set?

They are failing because something like the topmost one or two patches 
as in this branch here are missing for a big endian host:

https://github.com/stefanberger/qemu-tpm/tree/joelle.v5%2B2nd_registers


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-24 16:17             ` Stefan Berger
@ 2023-11-24 16:21               ` Joelle van Dyne
  2023-11-24 16:26                 ` Stefan Berger
  0 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-24 16:21 UTC (permalink / raw)
  To: Stefan Berger
  Cc: Joelle van Dyne, Marc-André Lureau, qemu-devel,
	Michael S. Tsirkin, Igor Mammedov, Ani Sinha

On Fri, Nov 24, 2023 at 8:17 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
>
>
>
> On 11/23/23 19:56, Joelle van Dyne wrote:
> > On Tue, Nov 14, 2023 at 4:12 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
> >>
> >>
> >>
> >> On 11/14/23 16:05, Stefan Berger wrote:
> >>>
> >>>
> >>> On 11/14/23 13:03, Stefan Berger wrote:
> >>>>
> >>>>
> >>>> On 11/14/23 04:36, Marc-André Lureau wrote:
> >>>>> Hi
> >>>>>
> >>>>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
> >>>>>>
> >>>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
> >>>>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> >>>>>
> >>>>> nit: you also added tests for x86, could be a different patch?
> >>>>>
> >>>>> For arm, the test fails until next patch with:
> >>>>>
> >>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
> >>>>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
> >>>>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
> >>>>> chardev=char0,mode=control -display none -audio none -machine virt
> >>>>> -accel tcg -nodefaults -nographic -drive
> >>>>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
> >>>>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
> >>>>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
> >>>>> -cpu cortex-a57 -chardev
> >>>>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
> >>>>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
> >>>>> -accel qtest
> >>>>> Warning! zero length expected file
> >>>>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
> >>>>> Warning! zero length expected file
> >>>>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
> >>>>> acpi-test: Warning!  binary file mismatch. Actual
> >>>>> [aml:/tmp/aml-GO4ME2], Expected
> >>>>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
> >>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
> >>>>> to update expected files.
> >>>>> acpi-test: Warning!  binary file mismatch. Actual
> >>>>> [aml:/tmp/aml-6N4ME2], Expected
> >>>>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
> >>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
> >>>>> to update expected files.
> >>>>> to see ASL diff between mismatched files install IASL, rebuild QEMU
> >>>>> from scratch and re-run tests with V=1 environment variable set**
> >>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> >>>>> failed: (all_tables_match)
> >>>>> not ok /aarch64/acpi/virt/tpm2-crb -
> >>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> >>>>> failed: (all_tables_match)
> >>>>> Bail out!
> >>>>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
> >>>>> Resource temporarily unavailable
> >>>>> Unexpected error in qio_channel_socket_writev() at
> >>>>> ../io/channel-socket.c:622:
> >>>>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
> >>>>> to write to socket: Bad file descriptor
> >>>>>
> >>>>
> >>>> Travis testing on s390x I see the following failures for this patchset
> >>>> (search for 'ERROR'):
> >>>>
> >>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
> >>>>
> >>>> Summary of Failures:
> >>>>
> >>>> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test
> >>>> ERROR           0.70s   killed by signal 6 SIGABRT
> >>>>
> >>>> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test
> >>>> ERROR           0.88s   killed by signal 6 SIGABRT
> >>>>
> >>>>
> >>>> Summary of Failures:
> >>>>
> >>>> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test
> >>>> ERROR           0.59s   killed by signal 6 SIGABRT
> >>>>
> >>>>
> >>>> My guess is it's an endianess issue on big endian machines due to
> >>>> reading from the ROM device where we lost the .endianess:
> >>>>
> >>>> +const MemoryRegionOps tpm_crb_memory_ops = {
> >>>> +    .read = tpm_crb_mmio_read,
> >>>> +    .write = tpm_crb_mmio_write,
> >>>> +    .endianness = DEVICE_LITTLE_ENDIAN,
> >>>> +    .valid = {
> >>>> +        .min_access_size = 1,
> >>>> +        .max_access_size = 4,
> >>>> +    },
> >>>> +};
> >>>>
> >>>
> >>> I think we need a 2nd set of registers to support the endianess
> >>> conversion. It's not exactly nice, though. Basically the saved_regs
> >>> could be used for this directly, even though I did not do that but
> >>> introduced n_regs:
> >>> https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
> >>>
> >>> This patch allows the tests on s390x to run farther but the execution of
> >>> the command doesn't seem to work maybe due to command data that were
> >>> also written in wrong endianess. I don't know. I would have to get
> >>> access to a big endian / s390 machine to be able to fix it.
> >>>
> >>>
> >>
> >> The latest version now passes on Travis s390x:
> >> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220
> >>
> >
> > Are the tests failing on S390X due to the added code or are they
> > failing because previously it was untested? I don't think the original
> > code took account of endianness and that should be fixed, but feels
> > like it should be in a separate patch set?
>
> They are failing because something like the topmost one or two patches
> as in this branch here are missing for a big endian host:
>
> https://github.com/stefanberger/qemu-tpm/tree/joelle.v5%2B2nd_registers

Right, but is this issue new due to the patchset? i.e. if just the
tests were added without the other patches, would they still fail? If
so, I think the fixes should be in another patchset while we disable
them in this patchset.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-24 16:21               ` Joelle van Dyne
@ 2023-11-24 16:26                 ` Stefan Berger
  2023-11-25  2:39                   ` Joelle van Dyne
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Berger @ 2023-11-24 16:26 UTC (permalink / raw)
  To: Joelle van Dyne
  Cc: Marc-André Lureau, qemu-devel, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha



On 11/24/23 11:21, Joelle van Dyne wrote:
> On Fri, Nov 24, 2023 at 8:17 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>
>>
>>
>> On 11/23/23 19:56, Joelle van Dyne wrote:
>>> On Tue, Nov 14, 2023 at 4:12 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>>>
>>>>
>>>>
>>>> On 11/14/23 16:05, Stefan Berger wrote:
>>>>>
>>>>>
>>>>> On 11/14/23 13:03, Stefan Berger wrote:
>>>>>>
>>>>>>
>>>>>> On 11/14/23 04:36, Marc-André Lureau wrote:
>>>>>>> Hi
>>>>>>>
>>>>>>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>>>>>>>
>>>>>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>>>>>>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>>>>>>
>>>>>>> nit: you also added tests for x86, could be a different patch?
>>>>>>>
>>>>>>> For arm, the test fails until next patch with:
>>>>>>>
>>>>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
>>>>>>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
>>>>>>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
>>>>>>> chardev=char0,mode=control -display none -audio none -machine virt
>>>>>>> -accel tcg -nodefaults -nographic -drive
>>>>>>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
>>>>>>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
>>>>>>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
>>>>>>> -cpu cortex-a57 -chardev
>>>>>>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
>>>>>>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
>>>>>>> -accel qtest
>>>>>>> Warning! zero length expected file
>>>>>>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
>>>>>>> Warning! zero length expected file
>>>>>>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
>>>>>>> acpi-test: Warning!  binary file mismatch. Actual
>>>>>>> [aml:/tmp/aml-GO4ME2], Expected
>>>>>>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
>>>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>>>>>> to update expected files.
>>>>>>> acpi-test: Warning!  binary file mismatch. Actual
>>>>>>> [aml:/tmp/aml-6N4ME2], Expected
>>>>>>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
>>>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>>>>>> to update expected files.
>>>>>>> to see ASL diff between mismatched files install IASL, rebuild QEMU
>>>>>>> from scratch and re-run tests with V=1 environment variable set**
>>>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>>>>>> failed: (all_tables_match)
>>>>>>> not ok /aarch64/acpi/virt/tpm2-crb -
>>>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>>>>>> failed: (all_tables_match)
>>>>>>> Bail out!
>>>>>>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
>>>>>>> Resource temporarily unavailable
>>>>>>> Unexpected error in qio_channel_socket_writev() at
>>>>>>> ../io/channel-socket.c:622:
>>>>>>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
>>>>>>> to write to socket: Bad file descriptor
>>>>>>>
>>>>>>
>>>>>> Travis testing on s390x I see the following failures for this patchset
>>>>>> (search for 'ERROR'):
>>>>>>
>>>>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
>>>>>>
>>>>>> Summary of Failures:
>>>>>>
>>>>>> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test
>>>>>> ERROR           0.70s   killed by signal 6 SIGABRT
>>>>>>
>>>>>> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test
>>>>>> ERROR           0.88s   killed by signal 6 SIGABRT
>>>>>>
>>>>>>
>>>>>> Summary of Failures:
>>>>>>
>>>>>> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test
>>>>>> ERROR           0.59s   killed by signal 6 SIGABRT
>>>>>>
>>>>>>
>>>>>> My guess is it's an endianess issue on big endian machines due to
>>>>>> reading from the ROM device where we lost the .endianess:
>>>>>>
>>>>>> +const MemoryRegionOps tpm_crb_memory_ops = {
>>>>>> +    .read = tpm_crb_mmio_read,
>>>>>> +    .write = tpm_crb_mmio_write,
>>>>>> +    .endianness = DEVICE_LITTLE_ENDIAN,
>>>>>> +    .valid = {
>>>>>> +        .min_access_size = 1,
>>>>>> +        .max_access_size = 4,
>>>>>> +    },
>>>>>> +};
>>>>>>
>>>>>
>>>>> I think we need a 2nd set of registers to support the endianess
>>>>> conversion. It's not exactly nice, though. Basically the saved_regs
>>>>> could be used for this directly, even though I did not do that but
>>>>> introduced n_regs:
>>>>> https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
>>>>>
>>>>> This patch allows the tests on s390x to run farther but the execution of
>>>>> the command doesn't seem to work maybe due to command data that were
>>>>> also written in wrong endianess. I don't know. I would have to get
>>>>> access to a big endian / s390 machine to be able to fix it.
>>>>>
>>>>>
>>>>
>>>> The latest version now passes on Travis s390x:
>>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220
>>>>
>>>
>>> Are the tests failing on S390X due to the added code or are they
>>> failing because previously it was untested? I don't think the original
>>> code took account of endianness and that should be fixed, but feels
>>> like it should be in a separate patch set?
>>
>> They are failing because something like the topmost one or two patches
>> as in this branch here are missing for a big endian host:
>>
>> https://github.com/stefanberger/qemu-tpm/tree/joelle.v5%2B2nd_registers
> 
> Right, but is this issue new due to the patchset? i.e. if just the

Yes, it is due to this patchset. The reason is that CRB switched to a 
ROMD interface where the fact that the MMIO registers are little endian 
got lost for existing x86_64 support.

> tests were added without the other patches, would they still fail? If
> so, I think the fixes should be in another patchset while we disable
> them in this patchset.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-24 16:26                 ` Stefan Berger
@ 2023-11-25  2:39                   ` Joelle van Dyne
  2023-11-27 14:12                     ` Stefan Berger
  0 siblings, 1 reply; 35+ messages in thread
From: Joelle van Dyne @ 2023-11-25  2:39 UTC (permalink / raw)
  To: Stefan Berger
  Cc: Joelle van Dyne, Marc-André Lureau, qemu-devel,
	Michael S. Tsirkin, Igor Mammedov, Ani Sinha

On Fri, Nov 24, 2023 at 8:26 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
>
>
>
> On 11/24/23 11:21, Joelle van Dyne wrote:
> > On Fri, Nov 24, 2023 at 8:17 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
> >>
> >>
> >>
> >> On 11/23/23 19:56, Joelle van Dyne wrote:
> >>> On Tue, Nov 14, 2023 at 4:12 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 11/14/23 16:05, Stefan Berger wrote:
> >>>>>
> >>>>>
> >>>>> On 11/14/23 13:03, Stefan Berger wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 11/14/23 04:36, Marc-André Lureau wrote:
> >>>>>>> Hi
> >>>>>>>
> >>>>>>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
> >>>>>>>>
> >>>>>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
> >>>>>>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> >>>>>>>
> >>>>>>> nit: you also added tests for x86, could be a different patch?
> >>>>>>>
> >>>>>>> For arm, the test fails until next patch with:
> >>>>>>>
> >>>>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
> >>>>>>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
> >>>>>>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
> >>>>>>> chardev=char0,mode=control -display none -audio none -machine virt
> >>>>>>> -accel tcg -nodefaults -nographic -drive
> >>>>>>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
> >>>>>>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
> >>>>>>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
> >>>>>>> -cpu cortex-a57 -chardev
> >>>>>>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
> >>>>>>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
> >>>>>>> -accel qtest
> >>>>>>> Warning! zero length expected file
> >>>>>>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
> >>>>>>> Warning! zero length expected file
> >>>>>>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
> >>>>>>> acpi-test: Warning!  binary file mismatch. Actual
> >>>>>>> [aml:/tmp/aml-GO4ME2], Expected
> >>>>>>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
> >>>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
> >>>>>>> to update expected files.
> >>>>>>> acpi-test: Warning!  binary file mismatch. Actual
> >>>>>>> [aml:/tmp/aml-6N4ME2], Expected
> >>>>>>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
> >>>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
> >>>>>>> to update expected files.
> >>>>>>> to see ASL diff between mismatched files install IASL, rebuild QEMU
> >>>>>>> from scratch and re-run tests with V=1 environment variable set**
> >>>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> >>>>>>> failed: (all_tables_match)
> >>>>>>> not ok /aarch64/acpi/virt/tpm2-crb -
> >>>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
> >>>>>>> failed: (all_tables_match)
> >>>>>>> Bail out!
> >>>>>>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
> >>>>>>> Resource temporarily unavailable
> >>>>>>> Unexpected error in qio_channel_socket_writev() at
> >>>>>>> ../io/channel-socket.c:622:
> >>>>>>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
> >>>>>>> to write to socket: Bad file descriptor
> >>>>>>>
> >>>>>>
> >>>>>> Travis testing on s390x I see the following failures for this patchset
> >>>>>> (search for 'ERROR'):
> >>>>>>
> >>>>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
> >>>>>>
> >>>>>> Summary of Failures:
> >>>>>>
> >>>>>> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test
> >>>>>> ERROR           0.70s   killed by signal 6 SIGABRT
> >>>>>>
> >>>>>> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test
> >>>>>> ERROR           0.88s   killed by signal 6 SIGABRT
> >>>>>>
> >>>>>>
> >>>>>> Summary of Failures:
> >>>>>>
> >>>>>> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test
> >>>>>> ERROR           0.59s   killed by signal 6 SIGABRT
> >>>>>>
> >>>>>>
> >>>>>> My guess is it's an endianess issue on big endian machines due to
> >>>>>> reading from the ROM device where we lost the .endianess:
> >>>>>>
> >>>>>> +const MemoryRegionOps tpm_crb_memory_ops = {
> >>>>>> +    .read = tpm_crb_mmio_read,
> >>>>>> +    .write = tpm_crb_mmio_write,
> >>>>>> +    .endianness = DEVICE_LITTLE_ENDIAN,
> >>>>>> +    .valid = {
> >>>>>> +        .min_access_size = 1,
> >>>>>> +        .max_access_size = 4,
> >>>>>> +    },
> >>>>>> +};
> >>>>>>
> >>>>>
> >>>>> I think we need a 2nd set of registers to support the endianess
> >>>>> conversion. It's not exactly nice, though. Basically the saved_regs
> >>>>> could be used for this directly, even though I did not do that but
> >>>>> introduced n_regs:
> >>>>> https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
> >>>>>
> >>>>> This patch allows the tests on s390x to run farther but the execution of
> >>>>> the command doesn't seem to work maybe due to command data that were
> >>>>> also written in wrong endianess. I don't know. I would have to get
> >>>>> access to a big endian / s390 machine to be able to fix it.
> >>>>>
> >>>>>
> >>>>
> >>>> The latest version now passes on Travis s390x:
> >>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220
> >>>>
> >>>
> >>> Are the tests failing on S390X due to the added code or are they
> >>> failing because previously it was untested? I don't think the original
> >>> code took account of endianness and that should be fixed, but feels
> >>> like it should be in a separate patch set?
> >>
> >> They are failing because something like the topmost one or two patches
> >> as in this branch here are missing for a big endian host:
> >>
> >> https://github.com/stefanberger/qemu-tpm/tree/joelle.v5%2B2nd_registers
> >
> > Right, but is this issue new due to the patchset? i.e. if just the
>
> Yes, it is due to this patchset. The reason is that CRB switched to a
> ROMD interface where the fact that the MMIO registers are little endian
> got lost for existing x86_64 support.
>
> > tests were added without the other patches, would they still fail? If
> > so, I think the fixes should be in another patchset while we disable
> > them in this patchset.

I see, how do you want to best integrate your changes? Do you want me
to squash your changes into the patch that introduces the code? Or do
you want them to be separate commits?


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt
  2023-11-25  2:39                   ` Joelle van Dyne
@ 2023-11-27 14:12                     ` Stefan Berger
  0 siblings, 0 replies; 35+ messages in thread
From: Stefan Berger @ 2023-11-27 14:12 UTC (permalink / raw)
  To: Joelle van Dyne
  Cc: Marc-André Lureau, qemu-devel, Michael S. Tsirkin,
	Igor Mammedov, Ani Sinha



On 11/24/23 21:39, Joelle van Dyne wrote:
> On Fri, Nov 24, 2023 at 8:26 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>
>>
>>
>> On 11/24/23 11:21, Joelle van Dyne wrote:
>>> On Fri, Nov 24, 2023 at 8:17 AM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>>>
>>>>
>>>>
>>>> On 11/23/23 19:56, Joelle van Dyne wrote:
>>>>> On Tue, Nov 14, 2023 at 4:12 PM Stefan Berger <stefanb@linux.ibm.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 11/14/23 16:05, Stefan Berger wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 11/14/23 13:03, Stefan Berger wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 11/14/23 04:36, Marc-André Lureau wrote:
>>>>>>>>> Hi
>>>>>>>>>
>>>>>>>>> On Tue, Nov 14, 2023 at 6:12 AM Joelle van Dyne <j@getutm.app> wrote:
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>>>>>>>>>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>>>>>>>>
>>>>>>>>> nit: you also added tests for x86, could be a different patch?
>>>>>>>>>
>>>>>>>>> For arm, the test fails until next patch with:
>>>>>>>>>
>>>>>>>>> # starting QEMU: exec ./qemu-system-aarch64 -qtest
>>>>>>>>> unix:/tmp/qtest-991279.sock -qtest-log /dev/null -chardev
>>>>>>>>> socket,path=/tmp/qtest-991279.qmp,id=char0 -mon
>>>>>>>>> chardev=char0,mode=control -display none -audio none -machine virt
>>>>>>>>> -accel tcg -nodefaults -nographic -drive
>>>>>>>>> if=pflash,format=raw,file=pc-bios/edk2-aarch64-code.fd,readonly=on
>>>>>>>>> -drive if=pflash,format=raw,file=pc-bios/edk2-arm-vars.fd,snapshot=on
>>>>>>>>> -cdrom tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
>>>>>>>>> -cpu cortex-a57 -chardev
>>>>>>>>> socket,id=chr,path=/tmp/qemu-test_acpi_virt_tcg_crb-device.KZ3GE2/sock
>>>>>>>>> -tpmdev emulator,id=dev,chardev=chr -device tpm-crb-device,tpmdev=dev
>>>>>>>>> -accel qtest
>>>>>>>>> Warning! zero length expected file
>>>>>>>>> 'tests/data/acpi/virt/TPM2.crb-device.tpm2'
>>>>>>>>> Warning! zero length expected file
>>>>>>>>> 'tests/data/acpi/virt/DSDT.crb-device.tpm2'
>>>>>>>>> acpi-test: Warning!  binary file mismatch. Actual
>>>>>>>>> [aml:/tmp/aml-GO4ME2], Expected
>>>>>>>>> [aml:tests/data/acpi/virt/TPM2.crb-device.tpm2].
>>>>>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>>>>>>>> to update expected files.
>>>>>>>>> acpi-test: Warning!  binary file mismatch. Actual
>>>>>>>>> [aml:/tmp/aml-6N4ME2], Expected
>>>>>>>>> [aml:tests/data/acpi/virt/DSDT.crb-device.tpm2].
>>>>>>>>> See source file tests/qtest/bios-tables-test.c for instructions on how
>>>>>>>>> to update expected files.
>>>>>>>>> to see ASL diff between mismatched files install IASL, rebuild QEMU
>>>>>>>>> from scratch and re-run tests with V=1 environment variable set**
>>>>>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>>>>>>>> failed: (all_tables_match)
>>>>>>>>> not ok /aarch64/acpi/virt/tpm2-crb -
>>>>>>>>> ERROR:../tests/qtest/bios-tables-test.c:538:test_acpi_asl: assertion
>>>>>>>>> failed: (all_tables_match)
>>>>>>>>> Bail out!
>>>>>>>>> qemu-system-aarch64: tpm-emulator: Could not cleanly shutdown the TPM:
>>>>>>>>> Resource temporarily unavailable
>>>>>>>>> Unexpected error in qio_channel_socket_writev() at
>>>>>>>>> ../io/channel-socket.c:622:
>>>>>>>>> /home/elmarco/src/qemu/buildall/tests/qtest/bios-tables-test: Unable
>>>>>>>>> to write to socket: Bad file descriptor
>>>>>>>>>
>>>>>>>>
>>>>>>>> Travis testing on s390x I see the following failures for this patchset
>>>>>>>> (search for 'ERROR'):
>>>>>>>>
>>>>>>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267230363
>>>>>>>>
>>>>>>>> Summary of Failures:
>>>>>>>>
>>>>>>>> 134/320 qemu:qtest+qtest-aarch64 / qtest-aarch64/tpm-crb-device-test
>>>>>>>> ERROR           0.70s   killed by signal 6 SIGABRT
>>>>>>>>
>>>>>>>> 219/320 qemu:qtest+qtest-x86_64 / qtest-x86_64/tpm-crb-test
>>>>>>>> ERROR           0.88s   killed by signal 6 SIGABRT
>>>>>>>>
>>>>>>>>
>>>>>>>> Summary of Failures:
>>>>>>>>
>>>>>>>> 271/537 qemu:qtest+qtest-i386 / qtest-i386/tpm-crb-test
>>>>>>>> ERROR           0.59s   killed by signal 6 SIGABRT
>>>>>>>>
>>>>>>>>
>>>>>>>> My guess is it's an endianess issue on big endian machines due to
>>>>>>>> reading from the ROM device where we lost the .endianess:
>>>>>>>>
>>>>>>>> +const MemoryRegionOps tpm_crb_memory_ops = {
>>>>>>>> +    .read = tpm_crb_mmio_read,
>>>>>>>> +    .write = tpm_crb_mmio_write,
>>>>>>>> +    .endianness = DEVICE_LITTLE_ENDIAN,
>>>>>>>> +    .valid = {
>>>>>>>> +        .min_access_size = 1,
>>>>>>>> +        .max_access_size = 4,
>>>>>>>> +    },
>>>>>>>> +};
>>>>>>>>
>>>>>>>
>>>>>>> I think we need a 2nd set of registers to support the endianess
>>>>>>> conversion. It's not exactly nice, though. Basically the saved_regs
>>>>>>> could be used for this directly, even though I did not do that but
>>>>>>> introduced n_regs:
>>>>>>> https://github.com/stefanberger/qemu-tpm/commit/90f6b21c0dd93dbb13d9e80a628f5b631fd07d91
>>>>>>>
>>>>>>> This patch allows the tests on s390x to run farther but the execution of
>>>>>>> the command doesn't seem to work maybe due to command data that were
>>>>>>> also written in wrong endianess. I don't know. I would have to get
>>>>>>> access to a big endian / s390 machine to be able to fix it.
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> The latest version now passes on Travis s390x:
>>>>>> https://app.travis-ci.com/github/stefanberger/qemu-tpm/builds/267245220
>>>>>>
>>>>>
>>>>> Are the tests failing on S390X due to the added code or are they
>>>>> failing because previously it was untested? I don't think the original
>>>>> code took account of endianness and that should be fixed, but feels
>>>>> like it should be in a separate patch set?
>>>>
>>>> They are failing because something like the topmost one or two patches
>>>> as in this branch here are missing for a big endian host:
>>>>
>>>> https://github.com/stefanberger/qemu-tpm/tree/joelle.v5%2B2nd_registers
>>>
>>> Right, but is this issue new due to the patchset? i.e. if just the
>>
>> Yes, it is due to this patchset. The reason is that CRB switched to a
>> ROMD interface where the fact that the MMIO registers are little endian
>> got lost for existing x86_64 support.
>>
>>> tests were added without the other patches, would they still fail? If
>>> so, I think the fixes should be in another patchset while we disable
>>> them in this patchset.
> 
> I see, how do you want to best integrate your changes? Do you want me
> to squash your changes into the patch that introduces the code? Or do
> you want them to be separate commits?

I think squashing them in would be the right thing to do. You may want 
to append _LE to the macros in the 2nd patch if you take them.

     Stefan


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device
  2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
                   ` (14 preceding siblings ...)
  2023-11-14  9:38 ` [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Marc-André Lureau
@ 2024-04-30 11:54 ` Peter Maydell
  15 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2024-04-30 11:54 UTC (permalink / raw)
  To: Joelle van Dyne; +Cc: qemu-devel

On Tue, 14 Nov 2023 at 02:10, Joelle van Dyne <j@getutm.app> wrote:
> The impetus for this patch set is to get TPM 2.0 working on Windows 11 ARM64.
> Windows' tpm.sys does not seem to work on a TPM TIS device (as verified with
> VMWare's implementation). However, the current TPM CRB device uses a fixed
> system bus address that is reserved for RAM in ARM64 Virt machines.
>
> In the process of adding the TPM CRB SysBus device, we also went ahead and
> cleaned up some of the existing TPM hardware code and fixed some bugs. We used
> the TPM TIS devices as a template for the TPM CRB devices and refactored out
> common code. We moved the ACPI DSDT generation to the device in order to handle
> dynamic base address requirements as well as reduce redundent code in different
> machine ACPI generation. We also changed the tpm_crb device to use the ISA bus
> instead of depending on the default system bus as the device only was built for
> the PC configuration.
>
> Another change is that the TPM CRB registers are now mapped in the same way that
> the pflash ROM devices are mapped. It is a memory region whose writes are
> trapped as MMIO accesses. This was needed because Apple Silicon does not decode
> LDP (AARCH64 load pair of registers) caused page faults. @agraf suggested that
> we do this to avoid having to do AARCH64 decoding in the HVF backend's fault
> handler.

I had a conversation about this on IRC a week or so back (though I
forget who with, sorry) that made me realise there's a problem with this
approach, and I wanted to write that up for the mailing list.

The problem with turning this into a memory-backed device rather than
an MMIO backed device is that it breaks KVM on Arm CPUs which don't
have FEAT_S2FWB (i.e. anything older than Armv8.4). This is because
without FEAT_S2FWB the guest and host will disagree about the memory
attributes of the region:
 * the host knows this is RAM backed and it's normal-cacheable
   (certainly as far as the mapping that QEMU itself has)
 * the guest thinks it's real hardware device registers and maps it
   as Device
The resulting mismatch in cacheability attributes can cause unexpected
behaviour where the guest and QEMU views of the memory contents don't
necessarily match up. (This is the same underlying issue that means
that you can't use QEMU devices that emulate VGA framebuffers on
AArch64 KVM without FEAT_S2FWB.)

With FEAT_S2FWB the problem goes away because the hypervisor can
override the guest's specified memory attributes to get rid of
the attribute mismatch.

So given that this would cause a regression for KVM, my preference
is to stick with the current "the device is backed by MMIO read
and write functions in the normal way". If a particular guest is
trying to access it with LDP/STP that is best fixed in the guest.

Potentially we could emulate (interpret) some subset of complex
load/store insns in QEMU at the point where we get the "took a
data abort but no syndrome information". This ought to be doable
in a way that's shareable between hvf and KVM, and we can write
a decodetree file for the insns we want to interpret. (I would
not try to share with TCG decodetree, though the patterns can
probably be copied across.)

thanks
-- PMM


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2024-04-30 11:55 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-14  2:09 [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 01/14] tpm_crb: refactor common code Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 02/14] tpm_crb: CTRL_RSP_ADDR is 64-bits wide Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 03/14] tpm_ppi: refactor memory space initialization Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 04/14] tpm_crb: use a single read-as-mem/write-as-mmio mapping Joelle van Dyne
2023-11-14 15:46   ` Stefan Berger
2023-11-14  2:09 ` [PATCH v5 05/14] tpm_crb: move ACPI table building to device interface Joelle van Dyne
2023-11-14 16:37   ` Stefan Berger
2023-11-14 16:44     ` Stefan Berger
2023-11-14 19:29       ` Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 06/14] tpm-sysbus: add plug handler for TPM on SysBus Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 07/14] hw/arm/virt: connect TPM to platform bus Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 08/14] hw/loongarch/virt: " Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 09/14] tpm_tis_sysbus: move DSDT AML generation to device Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 10/14] tests: acpi: prepare for TPM CRB tests Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 11/14] tpm_crb_sysbus: introduce TPM CRB SysBus device Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 12/14] tests: acpi: implement TPM CRB tests for ARM virt Joelle van Dyne
2023-11-14  9:36   ` Marc-André Lureau
2023-11-14 13:04     ` Stefan Berger
2023-11-14 18:03     ` Stefan Berger
2023-11-14 21:05       ` Stefan Berger
2023-11-15  0:12         ` Stefan Berger
2023-11-24  0:56           ` Joelle van Dyne
2023-11-24 16:17             ` Stefan Berger
2023-11-24 16:21               ` Joelle van Dyne
2023-11-24 16:26                 ` Stefan Berger
2023-11-25  2:39                   ` Joelle van Dyne
2023-11-27 14:12                     ` Stefan Berger
2023-11-14  2:09 ` [PATCH v5 13/14] tests: acpi: updated expected blobs for TPM CRB Joelle van Dyne
2023-11-14  2:09 ` [PATCH v5 14/14] tests: add TPM-CRB sysbus tests for aarch64 Joelle van Dyne
2023-11-14  9:38 ` [PATCH v5 00/14] tpm: introduce TPM CRB SysBus device Marc-André Lureau
2023-11-14 19:25   ` Joelle van Dyne
2023-11-20  8:29     ` Marc-André Lureau
2023-11-20 15:01       ` Stefan Berger
2024-04-30 11:54 ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.