@samitouri / QOSamiQemu / commits / fe00b8eba8

hw/sparc/sun4m: Use qdev GPIOs rather than qemu_allocate_irqs()

In the sun4m machine creation code, we currently use qemu_allocate_irqs() to set up the IRQ lines that act as the inbound IRQ lines to the CPUs. This results in a memory leak: Direct leak of 128 byte(s) in 1 object(s) allocated from: #0 0x5a23c1281ec3 in malloc (/home/pm215/qemu/build/sparc-san/qemu-system-sparc+0xdf1ec3) (BuildId: e6aa10be01feb5524656dd083997bc82b85e3e93) #1 0x79e8f78f0ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3) #2 0x5a23c1a94e54 in qemu_extend_irqs /home/pm215/qemu/build/sparc-san/../../hw/core/irq.c:77:51 #3 0x5a23c1a39e03 in cpu_devinit /home/pm215/qemu/build/sparc-san/../../hw/sparc/sun4m.c:802:17 #4 0x5a23c1a39e03 in sun4m_hw_init /home/pm215/qemu/build/sparc-san/../../hw/sparc/sun4m.c:838:9 The leak is unimportant as it is a "once at startup" leak, but fixing it helps in getting a clean leak-sanitizer test run. Switch the sun4m code to handle CPU interrupt lines in the same way as the leon3 machine does: the machine init code uses qdev_init_gpio_in to create GPIO lines on the CPU objects. This is a little bit odd as ideally the CPU would do that itself, but for these 32-bit SPARC machines the machine and the CPU are very closely coupled already (the functions handling the IRQ lines modify data fields inside the CPU). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-ID: <20260307112931.3322532-3-peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Peter Maydell committed Mar 7, 2026 at 11:29 UTC fe00b8eba852e02189626d5cafc489d06ab6a482
1 file changed +14 -9
hw/sparc/sun4m.c
+14 -9
@@ -341,7 +341,7 @@ static void *sparc32_dma_init(hwaddr dma_base,
341 static DeviceState *slavio_intctl_init(hwaddr addr,
342 hwaddr addrg,
343 unsigned int smp_cpus,
344 - qemu_irq **parent_irq)
344 + DeviceState **cpus)
345 {
346 DeviceState *dev;
347 SysBusDevice *s;
@@ -354,7 +354,8 @@ static DeviceState *slavio_intctl_init(hwaddr addr,
354
355 for (i = 0; i < smp_cpus; i++) {
356 for (j = 0; j < MAX_PILS; j++) {
357 - sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
357 + sysbus_connect_irq(s, i * MAX_PILS + j,
358 + qdev_get_gpio_in_named(cpus[i], "pil", j));
359 }
360 }
361 sysbus_mmio_map(s, 0, addrg);
@@ -785,22 +786,25 @@ static const TypeInfo ram_info = {
786 .class_init = ram_class_init,
787 };
788
788 -static void cpu_devinit(const char *cpu_type, unsigned int id,
789 - uint64_t prom_addr, qemu_irq **cpu_irqs)
789 +static DeviceState *cpu_devinit(const char *cpu_type, unsigned int id,
790 + uint64_t prom_addr)
791 {
792 SPARCCPU *cpu;
793 CPUSPARCState *env;
794 + DeviceState *cpudev;
795
796 cpu = SPARC_CPU(object_new(cpu_type));
797 env = &cpu->env;
798 + cpudev = DEVICE(cpu);
799
800 qemu_register_reset(sun4m_cpu_reset, cpu);
801 object_property_set_bool(OBJECT(cpu), "start-powered-off", id != 0,
802 &error_abort);
800 - qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
803 + qdev_init_gpio_in_named(cpudev, cpu_set_irq, "pil", MAX_PILS);
804 + qdev_realize_and_unref(cpudev, NULL, &error_fatal);
805 cpu_sparc_set_id(env, id);
802 - *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS);
806 env->prom_addr = prom_addr;
807 + return cpudev;
808 }
809
810 static void dummy_fdc_tc(void *opaque, int irq, int level)
@@ -813,13 +817,14 @@ static void sun4m_hw_init(MachineState *machine)
817 DeviceState *slavio_intctl;
818 unsigned int i;
819 Nvram *nvram;
816 - qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
820 + qemu_irq slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
821 qemu_irq fdc_tc;
822 unsigned long kernel_size;
823 uint32_t initrd_size;
824 DriveInfo *fd[MAX_FD];
825 FWCfgState *fw_cfg;
826 DeviceState *dev, *ms_kb_orgate, *serial_orgate;
827 + DeviceState *cpus[MAX_CPUS];
828 SysBusDevice *s;
829 unsigned int smp_cpus = machine->smp.cpus;
830 unsigned int max_cpus = machine->smp.max_cpus;
@@ -835,7 +840,7 @@ static void sun4m_hw_init(MachineState *machine)
840
841 /* init CPUs */
842 for(i = 0; i < smp_cpus; i++) {
838 - cpu_devinit(machine->cpu_type, i, hwdef->slavio_base, &cpu_irqs[i]);
843 + cpus[i] = cpu_devinit(machine->cpu_type, i, hwdef->slavio_base);
844 }
845
846 /* Create and map RAM frontend */
@@ -855,7 +860,7 @@ static void sun4m_hw_init(MachineState *machine)
860 slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
861 hwdef->intctl_base + 0x10000ULL,
862 smp_cpus,
858 - cpu_irqs);
863 + cpus);
864
865 for (i = 0; i < 32; i++) {
866 slavio_irq[i] = qdev_get_gpio_in(slavio_intctl, i);