@samitouri / QOSamiQemu / commits / dc6444b9c5

hw/tpm/tpm_tis_sysbus: defer resource allocation to realize

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. This also fixes a memory leak that is reported by the address sanitizer during 'make check', because we currently allocate ppi.buf during instance_init and never free it. "Allocate in realize and never free" is less bad, because we don't currently support "unrealize and destroy a sysbus device". Fixes: 46cd2c1050f ("hw/tpm: add PPI support to tpm-tis-device for ARM64 virt") Signed-off-by: Mohammadfaiz Bawa <mbawa@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260528093123.55403-1-mbawa@redhat.com> Message-ID: <CAFEAcA8fEYODmPhbh1W=oPGvju-P=qWvN_dyWrPqAr-E9FK7UA@mail.gmail.com> [PMD: Amend Peter comment from previous mail in description] Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Mohammadfaiz Bawa committed May 28, 2026 at 15:01 UTC dc6444b9c595dc40d7ead0837b930b83ec966e1f
1 file changed +8 -10
hw/tpm/tpm_tis_sysbus.c
+8 -10
@@ -100,19 +100,9 @@ static void tpm_tis_sysbus_initfn(Object *obj)
100 {
101 TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(obj);
102 TPMState *s = &sbdev->state;
103 - size_t host_page_size = qemu_real_host_page_size();
104 -
105 - memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
106 - s, "tpm-tis-mmio",
107 - TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
103
104 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
105 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
111 -
112 - s->ppi.buf = qemu_memalign(host_page_size,
113 - ROUND_UP(TPM_PPI_ADDR_SIZE, host_page_size));
114 - memory_region_init_ram_device_ptr(&s->ppi.ram, obj, "tpm-ppi",
115 - TPM_PPI_ADDR_SIZE, s->ppi.buf);
106 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->ppi.ram);
107 }
108
@@ -120,6 +110,7 @@ static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
110 {
111 TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
112 TPMState *s = &sbdev->state;
113 + const size_t host_page_size = qemu_real_host_page_size();
114
115 if (!tpm_find()) {
116 error_setg(errp, "at most one TPM device is permitted");
@@ -131,6 +122,13 @@ static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
122 return;
123 }
124
125 + s->ppi.buf = qemu_memalign(host_page_size,
126 + ROUND_UP(TPM_PPI_ADDR_SIZE, host_page_size));
127 + memory_region_init_io(&s->mmio, OBJECT(dev), &tpm_tis_memory_ops,
128 + s, "tpm-tis-mmio",
129 + TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
130 + memory_region_init_ram_device_ptr(&s->ppi.ram, OBJECT(dev), "tpm-ppi",
131 + TPM_PPI_ADDR_SIZE, s->ppi.buf);
132 vmstate_register_ram(&s->ppi.ram, dev);
133 }
134