On 6/25/25 11:18 AM, Djordje Todorovic wrote:
This is needed for riscv based CPUs by MIPS since those may have
sparse hart-ID layouts. ACLINT and APLIC still assume a dense
range, and if a hart is missing, this causes NULL derefs.

Signed-off-by: Chao-ying Fu <c...@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todoro...@htecgroup.com>
---

Reviewed-by: Daniel Henrique Barboza <dbarb...@ventanamicro.com>

  hw/intc/riscv_aclint.c | 21 +++++++++++++++++++--
  hw/intc/riscv_aplic.c  | 10 +++++++---
  2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index b0139f03f5..22ac4133d5 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -292,7 +292,13 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, 
Error **errp)
      s->timecmp = g_new0(uint64_t, s->num_harts);
      /* Claim timer interrupt bits */
      for (i = 0; i < s->num_harts; i++) {
-        RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
+        CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i);
+        if (cpu_by_hartid == NULL) {
+            qemu_log_mask(LOG_GUEST_ERROR, "aclint-mtimer: invalid hartid: %u",
+                          s->hartid_base + i);
+            continue;
+        }
+        RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid);
          if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) {
              error_report("MTIP already claimed");
              exit(1);
@@ -481,7 +487,13 @@ static void riscv_aclint_swi_realize(DeviceState *dev, 
Error **errp)
/* Claim software interrupt bits */
      for (i = 0; i < swi->num_harts; i++) {
-        RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i));
+        CPUState *cpu_by_hartid = cpu_by_arch_id(swi->hartid_base + i);
+        if (cpu_by_hartid == NULL) {
+            qemu_log_mask(LOG_GUEST_ERROR, "aclint-swi: invalid hartid: %u",
+                          swi->hartid_base + i);
+            continue;
+        }
+        RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid);
          /* We don't claim mip.SSIP because it is writable by software */
          if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) {
              error_report("MSIP already claimed");
@@ -545,6 +557,11 @@ DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t 
hartid_base,
for (i = 0; i < num_harts; i++) {
          CPUState *cpu = cpu_by_arch_id(hartid_base + i);
+        if (cpu == NULL) {
+            qemu_log_mask(LOG_GUEST_ERROR, "aclint-swi: invalid hartid: %u",
+                          hartid_base + i);
+            continue;
+        }
          RISCVCPU *rvcpu = RISCV_CPU(cpu);
qdev_connect_gpio_out(dev, i,
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 8bcd9f4697..360a3dc117 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -899,9 +899,11 @@ static void riscv_aplic_realize(DeviceState *dev, Error 
**errp)
          if (!aplic->msimode) {
              /* Claim the CPU interrupt to be triggered by this APLIC */
              for (i = 0; i < aplic->num_harts; i++) {
-                RISCVCPU *cpu;
-
-                cpu = RISCV_CPU(cpu_by_arch_id(aplic->hartid_base + i));
+                CPUState *temp = cpu_by_arch_id(aplic->hartid_base + i);
+                if (temp == NULL) {
+                    continue;
+                }
+                RISCVCPU *cpu = RISCV_CPU(temp);
                  if (riscv_cpu_claim_interrupts(cpu,
                      (aplic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) {
                      error_report("%s already claimed",
@@ -1076,6 +1078,8 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
          if (!msimode) {
              for (i = 0; i < num_harts; i++) {
                  CPUState *cpu = cpu_by_arch_id(hartid_base + i);
+                if (cpu == NULL)
+                    continue;
qdev_connect_gpio_out_named(dev, NULL, i,
                                              qdev_get_gpio_in(DEVICE(cpu),


Reply via email to