On 18. 6. 25. 19:48, Daniel Henrique Barboza wrote:
> [You don't often get email from dbarb...@ventanamicro.com. Learn why 
> this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> CAUTION: This email originated from outside of the organization. Do 
> not click links or open attachments unless you recognize the sender 
> and know the content is safe.
>
>
> On 6/18/25 9:27 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>
>> ---
>>   hw/intc/riscv_aclint.c | 27 +++++++++++++++++++++++++--
>>   hw/intc/riscv_aplic.c  | 10 +++++++---
>>   2 files changed, 32 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
>> index b0139f03f5..ef1fc57610 100644
>> --- a/hw/intc/riscv_aclint.c
>> +++ b/hw/intc/riscv_aclint.c
>> @@ -233,6 +233,9 @@ static void riscv_aclint_mtimer_write(void 
>> *opaque, hwaddr addr,
>>           /* Check if timer interrupt is triggered for each hart. */
>>           for (i = 0; i < mtimer->num_harts; i++) {
>>               CPUState *cpu = cpu_by_arch_id(mtimer->hartid_base + i);
>> +            if (cpu == NULL) {
>> +                continue;
>> +            }
>>               CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
>>               if (!env) {
>>                   continue;
>> @@ -292,7 +295,11 @@ 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 *temp = cpu_by_arch_id(s->hartid_base + i);
>> +        if (temp == NULL) {
>> +            continue;
>> +        }
>> +        RISCVCPU *cpu = RISCV_CPU(temp);
>>           if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) {
>>               error_report("MTIP already claimed");
>>               exit(1);
>> @@ -373,6 +380,9 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr 
>> addr, hwaddr size,
>>
>>       for (i = 0; i < num_harts; i++) {
>>           CPUState *cpu = cpu_by_arch_id(hartid_base + i);
>> +        if (cpu == NULL) {
>> +            continue;
>> +        }
>>           RISCVCPU *rvcpu = RISCV_CPU(cpu);
>>           CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
>>           riscv_aclint_mtimer_callback *cb =
>> @@ -408,6 +418,9 @@ static uint64_t riscv_aclint_swi_read(void 
>> *opaque, hwaddr addr,
>>       if (addr < (swi->num_harts << 2)) {
>>           size_t hartid = swi->hartid_base + (addr >> 2);
>>           CPUState *cpu = cpu_by_arch_id(hartid);
>> +        if (cpu == NULL) {
>> +            return 0;
>> +        }
>
> I don't think we need this change, and the one below in 
> riscv_aclint_swi_write(). The
> existing code is handling the case where cpu == NULL:
>
>         size_t hartid = swi->hartid_base + (addr >> 2);
>         CPUState *cpu = cpu_by_arch_id(hartid);
>         CPURISCVState *env = cpu ? cpu_env(cpu) : NULL; <-------------
>         if (!env) { <-----------------
>             qemu_log_mask(LOG_GUEST_ERROR,
>                           "aclint-swi: invalid hartid: %zu", hartid);
>         } else if {...}
>
>
> In fact what we have is better: we do a qemu_log() informing about the 
> invalid hart-id
> instead of silently returning.
>
Yes. We do not need all of those. But I will add logging for the cases 
we do.

Thanks,
Djordje


>
> Thanks,
>
> Daniel
>
>
>>           CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
>>           if (!env) {
>>               qemu_log_mask(LOG_GUEST_ERROR,
>> @@ -431,6 +444,9 @@ static void riscv_aclint_swi_write(void *opaque, 
>> hwaddr addr, uint64_t value,
>>       if (addr < (swi->num_harts << 2)) {
>>           size_t hartid = swi->hartid_base + (addr >> 2);
>>           CPUState *cpu = cpu_by_arch_id(hartid);
>> +        if (cpu == NULL) {
>> +            return;
>> +        }
>>           CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
>>           if (!env) {
>>               qemu_log_mask(LOG_GUEST_ERROR,
>> @@ -481,7 +497,11 @@ 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 *temp = cpu_by_arch_id(swi->hartid_base + i);
>> +        if (temp == NULL) {
>> +            continue;
>> +        }
>> +        RISCVCPU *cpu = RISCV_CPU(temp);
>>           /* 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 +565,9 @@ 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) {
>> +            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