@samitouri / QOSamiQemu / commits / 7134dbcc63

hw/m68k/mcf_intc: Use qdev input gpios for input IRQs

The m68k mcf_intc interrupt controller currently implements its inbound IRQ lines by calling qemu_allocate_irqs() in mcf_intc_init(). This results in leaks like this: Direct leak of 2944 byte(s) in 46 object(s) allocated from: #0 0x5cf95ec15323 in malloc (/home/pm215/qemu/build/san/qemu-system-m68k+0xf9e323) (BuildId: 18d55ef8ea9856e68ee30802078af5050b8b06c5) #1 0x7637c65c5ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3) #2 0x5cf95f6b2f27 in object_new_with_type /home/pm215/qemu/build/san/../../qom/object.c:767:15 #3 0x5cf95f6aa62e in qemu_allocate_irq /home/pm215/qemu/build/san/../../hw/core/irq.c:91:25 #4 0x5cf95f6aa62e in qemu_extend_irqs /home/pm215/qemu/build/san/../../hw/core/irq.c:79:16 #5 0x5cf95f5f6d99 in mcf5208evb_init /home/pm215/qemu/build/san/../../hw/m68k/mcf5208.c:310:11 This isn't an important leak, as it is memory we allocate once at QEMU startup and that has to stay live for the lifetime of the system. However it does point at a code improvement. Modernise this to have the device itself create inbound GPIOs with qdev_init_gpio_in() that the board can then refer to and wire up individually. As the device is used in only a single board, we can update device and board in a single patch rather than having to try to figure out some way to change the API more piecemeal. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Thomas Huth <th.huth+qemu@posteo.eu> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260306190425.3047580-1-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Peter Maydell committed Mar 6, 2026 at 19:04 UTC 7134dbcc63c670a1f5eb6b43a73b9d0f33e54981
3 files changed +16 -21
hw/m68k/mcf5208.c
+11 -13
@@ -227,7 +227,7 @@ static const MemoryRegionOps m5208_rcm_ops = {
227 .endianness = DEVICE_BIG_ENDIAN,
228 };
229
230 -static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic,
230 +static void mcf5208_sys_init(MemoryRegion *address_space, DeviceState *intc,
231 M68kCPU *cpu)
232 {
233 MemoryRegion *iomem = g_new(MemoryRegion, 1);
@@ -250,11 +250,11 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic,
250 "m5208-timer", 0x00004000);
251 memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
252 &s->iomem);
253 - s->irq = pic[4 + i];
253 + s->irq = qdev_get_gpio_in(intc, 4 + i);
254 }
255 }
256
257 -static void mcf_fec_init(MemoryRegion *sysmem, hwaddr base, qemu_irq *irqs)
257 +static void mcf_fec_init(MemoryRegion *sysmem, hwaddr base, DeviceState *intc)
258 {
259 DeviceState *dev;
260 SysBusDevice *s;
@@ -268,7 +268,7 @@ static void mcf_fec_init(MemoryRegion *sysmem, hwaddr base, qemu_irq *irqs)
268 s = SYS_BUS_DEVICE(dev);
269 sysbus_realize_and_unref(s, &error_fatal);
270 for (i = 0; i < FEC_NUM_IRQ; i++) {
271 - sysbus_connect_irq(s, i, irqs[i]);
271 + sysbus_connect_irq(s, i, qdev_get_gpio_in(intc, i + 36));
272 }
273
274 memory_region_add_subregion(sysmem, base, sysbus_mmio_get_region(s, 0));
@@ -283,10 +283,10 @@ static void mcf5208evb_init(MachineState *machine)
283 int kernel_size;
284 uint64_t elf_entry;
285 hwaddr entry;
286 - qemu_irq *pic;
286 MemoryRegion *address_space_mem = get_system_memory();
287 MemoryRegion *rom = g_new(MemoryRegion, 1);
288 MemoryRegion *sram = g_new(MemoryRegion, 1);
289 + DeviceState *intc;
290
291 cpu = M68K_CPU(cpu_create(machine->cpu_type));
292 env = &cpu->env;
@@ -307,17 +307,15 @@ static void mcf5208evb_init(MachineState *machine)
307 memory_region_add_subregion(address_space_mem, 0x80000000, sram);
308
309 /* Internal peripherals. */
310 - pic = mcf_intc_init(address_space_mem, 0xfc048000, cpu);
310 + intc = mcf_intc_init(address_space_mem, 0xfc048000, cpu);
311
312 - mcf_uart_create_mmap(0xfc060000, pic[26], serial_hd(0));
313 - mcf_uart_create_mmap(0xfc064000, pic[27], serial_hd(1));
314 - mcf_uart_create_mmap(0xfc068000, pic[28], serial_hd(2));
312 + mcf_uart_create_mmap(0xfc060000, qdev_get_gpio_in(intc, 26), serial_hd(0));
313 + mcf_uart_create_mmap(0xfc064000, qdev_get_gpio_in(intc, 27), serial_hd(1));
314 + mcf_uart_create_mmap(0xfc068000, qdev_get_gpio_in(intc, 28), serial_hd(2));
315
316 - mcf5208_sys_init(address_space_mem, pic, cpu);
316 + mcf5208_sys_init(address_space_mem, intc, cpu);
317
318 - mcf_fec_init(address_space_mem, 0xfc030000, pic + 36);
319 -
320 - g_free(pic);
318 + mcf_fec_init(address_space_mem, 0xfc030000, intc);
319
320 /* 0xfc000000 SCM. */
321 /* 0xfc004000 XBS. */
hw/m68k/mcf_intc.c
+3 -5
@@ -175,6 +175,7 @@ static void mcf_intc_instance_init(Object *obj)
175
176 memory_region_init_io(&s->iomem, obj, &mcf_intc_ops, s, "mcf", 0x100);
177 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
178 + qdev_init_gpio_in(DEVICE(s), mcf_intc_set_irq, 64);
179 }
180
181 static const Property mcf_intc_properties[] = {
@@ -206,9 +207,7 @@ static void mcf_intc_register_types(void)
207
208 type_init(mcf_intc_register_types)
209
209 -qemu_irq *mcf_intc_init(MemoryRegion *sysmem,
210 - hwaddr base,
211 - M68kCPU *cpu)
210 +DeviceState *mcf_intc_init(MemoryRegion *sysmem, hwaddr base, M68kCPU *cpu)
211 {
212 DeviceState *dev;
213
@@ -218,6 +217,5 @@ qemu_irq *mcf_intc_init(MemoryRegion *sysmem,
217 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
218 memory_region_add_subregion(sysmem, base,
219 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
221 -
222 - return qemu_allocate_irqs(mcf_intc_set_irq, dev, 64);
220 + return dev;
221 }
include/hw/m68k/mcf.h
+2 -3
@@ -14,9 +14,8 @@ DeviceState *mcf_uart_create(qemu_irq irq, Chardev *chr);
14 DeviceState *mcf_uart_create_mmap(hwaddr base, qemu_irq irq, Chardev *chr);
15
16 /* mcf_intc.c */
17 -qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem,
18 - hwaddr base,
19 - M68kCPU *cpu);
17 +DeviceState *mcf_intc_init(struct MemoryRegion *sysmem,
18 + hwaddr base, M68kCPU *cpu);
19
20 /* mcf5206.c */
21 #define TYPE_MCF5206_MBAR "mcf5206-mbar"