In the sun4m machine init, we set up the cpu_irqs[] array
with the real inbound IRQs for each CPU, followed by some
dummy IRQs for the remaining slots from smp_cpus up to
MAX_CPUS. These dummy IRQs do nothing when set/cleared
because the dummy_cpu_set_irq() function does nothing.
Instead of creating these "do nothing" qemu_irqs, instead
pass the number of CPUs to slavio_intctl_init() so that it
can only wire up the interrupt controller's interrupts
for the CPUs that actually exist. Calling qemu_set_irq()
on an irq that isn't connected does nothing, so this is
a simpler way to achieve the same result.
This cleanup fixes an unimportant memory leak reported by
the address sanitizer that happens because we allocate these
dummy IRQs with qemu_allocate_irqs():
Direct leak of 1920 byte(s) in 15 object(s) allocated from:
#0 0x5cb7b120cf63 in malloc (/home/pm215/qemu/build/san/qemu-system-sparc+0xe0bf63) (BuildId: d27f9230a7cc82ebfaf0cf9e439dc215ddd7ac68)
#1 0x743cd6dc5ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
#2 0x5cb7b1a42fb4 in qemu_extend_irqs /home/pm215/qemu/build/san/../../hw/core/irq.c:77:51
#3 0x5cb7b19e7e72 in sun4m_hw_init /home/pm215/qemu/build/san/../../hw/sparc/sun4m.c:845:23
#4 0x5cb7b141d3dd in machine_run_board_init /home/pm215/qemu/build/san/../../hw/core/machine.c:1709:5
#5 0x5cb7b1542895 in qemu_init_board /home/pm215/qemu/build/san/../../system/vl.c:2717:5
#6 0x5cb7b1542895 in qmp_x_exit_preconfig /home/pm215/qemu/build/san/../../system/vl.c:2811:5
#7 0x5cb7b15493ac in qemu_init /home/pm215/qemu/build/san/../../system/vl.c:3849:9
#8 0x5cb7b1f3f201 in main /home/pm215/qemu/build/san/../../system/main.c:71:5
#9 0x743cd4a2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#10 0x743cd4a2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
#11 0x5cb7b1172114 in _start (/home/pm215/qemu/build/san/qemu-system-sparc+0xd71114) (BuildId: d27f9230a7cc82ebfaf0cf9e439dc215ddd7ac68)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/sparc/sun4m.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index a17bdb3692..29bc26ebcb 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -196,10 +196,6 @@ static void cpu_set_irq(void *opaque, int irq, int level)
}
}
-static void dummy_cpu_set_irq(void *opaque, int irq, int level)
-{
-}
-
static void sun4m_cpu_reset(void *opaque)
{
SPARCCPU *cpu = opaque;
@@ -344,6 +340,7 @@ static void *sparc32_dma_init(hwaddr dma_base,
static DeviceState *slavio_intctl_init(hwaddr addr,
hwaddr addrg,
+ unsigned int smp_cpus,
qemu_irq **parent_irq)
{
DeviceState *dev;
@@ -355,7 +352,7 @@ static DeviceState *slavio_intctl_init(hwaddr addr,
s = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(s, &error_fatal);
- for (i = 0; i < MAX_CPUS; i++) {
+ for (i = 0; i < smp_cpus; i++) {
for (j = 0; j < MAX_PILS; j++) {
sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
}
@@ -841,9 +838,6 @@ static void sun4m_hw_init(MachineState *machine)
cpu_devinit(machine->cpu_type, i, hwdef->slavio_base, &cpu_irqs[i]);
}
- for (i = smp_cpus; i < MAX_CPUS; i++)
- cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
-
/* Create and map RAM frontend */
dev = qdev_new("memory");
object_property_set_link(OBJECT(dev), "memdev", OBJECT(ram_memdev), &error_fatal);
@@ -860,6 +854,7 @@ static void sun4m_hw_init(MachineState *machine)
slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
hwdef->intctl_base + 0x10000ULL,
+ smp_cpus,
cpu_irqs);
for (i = 0; i < 32; i++) {
--
2.43.0
On 07/03/2026 11:29, Peter Maydell wrote:
> In the sun4m machine init, we set up the cpu_irqs[] array
> with the real inbound IRQs for each CPU, followed by some
> dummy IRQs for the remaining slots from smp_cpus up to
> MAX_CPUS. These dummy IRQs do nothing when set/cleared
> because the dummy_cpu_set_irq() function does nothing.
>
> Instead of creating these "do nothing" qemu_irqs, instead
> pass the number of CPUs to slavio_intctl_init() so that it
> can only wire up the interrupt controller's interrupts
> for the CPUs that actually exist. Calling qemu_set_irq()
> on an irq that isn't connected does nothing, so this is
> a simpler way to achieve the same result.
>
> This cleanup fixes an unimportant memory leak reported by
> the address sanitizer that happens because we allocate these
> dummy IRQs with qemu_allocate_irqs():
>
> Direct leak of 1920 byte(s) in 15 object(s) allocated from:
> #0 0x5cb7b120cf63 in malloc (/home/pm215/qemu/build/san/qemu-system-sparc+0xe0bf63) (BuildId: d27f9230a7cc82ebfaf0cf9e439dc215ddd7ac68)
> #1 0x743cd6dc5ac9 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62ac9) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
> #2 0x5cb7b1a42fb4 in qemu_extend_irqs /home/pm215/qemu/build/san/../../hw/core/irq.c:77:51
> #3 0x5cb7b19e7e72 in sun4m_hw_init /home/pm215/qemu/build/san/../../hw/sparc/sun4m.c:845:23
> #4 0x5cb7b141d3dd in machine_run_board_init /home/pm215/qemu/build/san/../../hw/core/machine.c:1709:5
> #5 0x5cb7b1542895 in qemu_init_board /home/pm215/qemu/build/san/../../system/vl.c:2717:5
> #6 0x5cb7b1542895 in qmp_x_exit_preconfig /home/pm215/qemu/build/san/../../system/vl.c:2811:5
> #7 0x5cb7b15493ac in qemu_init /home/pm215/qemu/build/san/../../system/vl.c:3849:9
> #8 0x5cb7b1f3f201 in main /home/pm215/qemu/build/san/../../system/main.c:71:5
> #9 0x743cd4a2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
> #10 0x743cd4a2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
> #11 0x5cb7b1172114 in _start (/home/pm215/qemu/build/san/qemu-system-sparc+0xd71114) (BuildId: d27f9230a7cc82ebfaf0cf9e439dc215ddd7ac68)
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> hw/sparc/sun4m.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
> index a17bdb3692..29bc26ebcb 100644
> --- a/hw/sparc/sun4m.c
> +++ b/hw/sparc/sun4m.c
> @@ -196,10 +196,6 @@ static void cpu_set_irq(void *opaque, int irq, int level)
> }
> }
>
> -static void dummy_cpu_set_irq(void *opaque, int irq, int level)
> -{
> -}
> -
> static void sun4m_cpu_reset(void *opaque)
> {
> SPARCCPU *cpu = opaque;
> @@ -344,6 +340,7 @@ static void *sparc32_dma_init(hwaddr dma_base,
>
> static DeviceState *slavio_intctl_init(hwaddr addr,
> hwaddr addrg,
> + unsigned int smp_cpus,
> qemu_irq **parent_irq)
> {
> DeviceState *dev;
> @@ -355,7 +352,7 @@ static DeviceState *slavio_intctl_init(hwaddr addr,
> s = SYS_BUS_DEVICE(dev);
> sysbus_realize_and_unref(s, &error_fatal);
>
> - for (i = 0; i < MAX_CPUS; i++) {
> + for (i = 0; i < smp_cpus; i++) {
> for (j = 0; j < MAX_PILS; j++) {
> sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
> }
> @@ -841,9 +838,6 @@ static void sun4m_hw_init(MachineState *machine)
> cpu_devinit(machine->cpu_type, i, hwdef->slavio_base, &cpu_irqs[i]);
> }
>
> - for (i = smp_cpus; i < MAX_CPUS; i++)
> - cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
> -
> /* Create and map RAM frontend */
> dev = qdev_new("memory");
> object_property_set_link(OBJECT(dev), "memdev", OBJECT(ram_memdev), &error_fatal);
> @@ -860,6 +854,7 @@ static void sun4m_hw_init(MachineState *machine)
>
> slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
> hwdef->intctl_base + 0x10000ULL,
> + smp_cpus,
> cpu_irqs);
>
> for (i = 0; i < 32; i++) {
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
ATB,
Mark.
© 2016 - 2026 Red Hat, Inc.