From: Mohammadfaiz Bawa <[email protected]> Calling memory_region_init_ram_device_ptr() and memory_region_init_io() from tpm_tis_sysbus_initfn() crashes when the device is introspected without being realized, because the memory subsystem has not been initialized at that point.
So running: $ qemu-system-aarch64 -device tpm-tis-device,help triggers qdev_device_help() which creates the device object to list its properties, calling instance_init, but never realizefn. The memory region calls in instance_init then hit uninitialized subsystems: With CONFIG_DEBUG_TCG: Assertion 'target_page.decided' failed. (physmem.c:2524) Without CONFIG_DEBUG_TCG: Assertion 'mutex->initialized' failed. (qemu-thread-posix.c:107) Since realizefn is only called when the device is actually used in a running VM, moving resource allocation there avoids the crash without breaking introspection. Signed-off-by: Mohammadfaiz Bawa <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Message-ID: <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- hw/tpm/tpm_tis_sysbus.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c index 6bec30c36fc..f9cd1c8b5c6 100644 --- a/hw/tpm/tpm_tis_sysbus.c +++ b/hw/tpm/tpm_tis_sysbus.c @@ -100,19 +100,9 @@ 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", - TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT); 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); } @@ -120,6 +110,7 @@ static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp) { TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev); TPMState *s = &sbdev->state; + const 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 +122,13 @@ 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_io(&s->mmio, OBJECT(dev), &tpm_tis_memory_ops, + s, "tpm-tis-mmio", + TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT); + memory_region_init_ram_device_ptr(&s->ppi.ram, OBJECT(dev), "tpm-ppi", + TPM_PPI_ADDR_SIZE, s->ppi.buf); vmstate_register_ram(&s->ppi.ram, dev); } -- 2.53.0
