memory_region_init_ram_device_ptr() requires the target page
size to be finalized, which has not happened during
instance_init. Calling it from tpm_tis_sysbus_initfn() causes
an assertion failure when the device is introspected without
being realized, for example:

  $ qemu-system-aarch64 -device tpm-tis-device,help
  qemu-system-aarch64: ../system/physmem.c:2524:
  qemu_ram_alloc_internal:
  Assertion 'target_page.decided' failed.
  Aborted (core dumped)

Property introspection only calls instance_init, never
realizefn, so moving the memory region setup to realizefn
avoids the crash while keeping the device fully functional
when actually used in a VM.

Move the PPI buffer allocation, memory_region_init_ram_device_ptr()
and the corresponding sysbus_init_mmio() from
tpm_tis_sysbus_initfn() to tpm_tis_sysbus_realizefn(), placing
them just before the existing vmstate_register_ram() call.

Signed-off-by: Mohammadfaiz Bawa <[email protected]>
---
 hw/tpm/tpm_tis_sysbus.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c
index 6bec30c36f..33fe9e332c 100644
--- a/hw/tpm/tpm_tis_sysbus.c
+++ b/hw/tpm/tpm_tis_sysbus.c
@@ -100,7 +100,6 @@ static void tpm_tis_sysbus_initfn(Object *obj)
 {
     TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(obj);
     TPMState *s = &sbdev->state;
-    size_t host_page_size = qemu_real_host_page_size();
 
     memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
                           s, "tpm-tis-mmio",
@@ -108,18 +107,13 @@ static void tpm_tis_sysbus_initfn(Object *obj)
 
     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
-
-    s->ppi.buf = qemu_memalign(host_page_size,
-                                ROUND_UP(TPM_PPI_ADDR_SIZE, host_page_size));
-    memory_region_init_ram_device_ptr(&s->ppi.ram, obj, "tpm-ppi",
-                                      TPM_PPI_ADDR_SIZE, s->ppi.buf);
-    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->ppi.ram);
 }
 
 static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
 {
     TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
     TPMState *s = &sbdev->state;
+    size_t host_page_size = qemu_real_host_page_size();
 
     if (!tpm_find()) {
         error_setg(errp, "at most one TPM device is permitted");
@@ -131,6 +125,11 @@ static void tpm_tis_sysbus_realizefn(DeviceState *dev, 
Error **errp)
         return;
     }
 
+    s->ppi.buf = qemu_memalign(host_page_size,
+                                ROUND_UP(TPM_PPI_ADDR_SIZE, host_page_size));
+    memory_region_init_ram_device_ptr(&s->ppi.ram, OBJECT(dev), "tpm-ppi",
+                                      TPM_PPI_ADDR_SIZE, s->ppi.buf);
+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->ppi.ram);
     vmstate_register_ram(&s->ppi.ram, dev);
 }
 
-- 
2.53.0


Reply via email to