Plic_init_controller second loop controlling expression could cause crash

The second loop in plic_init_controller (kernel/include/drivers/irq/riscv_plic0.h) intends to set an initial priority for each PLIC IRQ, but with the controlling expression i <= PLIC_MAX_IRQ + 1, it sets priority for 1 extra IRQ just beyond the max IRQ. This could crash the system on the platform I use, as the address beyond the max IRQ’s PLIC_PRIO cannot be written.

Is it a bug, or is there a valid reason why it is written this way?

For reference, plic_init_controller (kernel/include/drivers/irq/riscv_plic0.h):

static inline void plic_init_controller(void)
{

    for (int i = 1; i <= PLIC_NUM_INTERRUPTS; i++) {
        /* Clear all pending bits */
        if (plic_pending_interrupt(i)) {
            readl(PLIC_PPTR_BASE + plic_claim_offset(PLIC_HART_ID, PLIC_SVC_CONTEXT));
            writel(i, PLIC_PPTR_BASE + plic_claim_offset(PLIC_HART_ID, PLIC_SVC_CONTEXT));
        }
    }

    /* Set the priorities of all interrupts to 1 */
    for (int i = 1; i <= PLIC_MAX_IRQ + 1; i++) {
        writel(2, PLIC_PPTR_BASE + PLIC_PRIO + PLIC_PRIO_PER_ID * i);
    }

}

Seems like it’s a bug, because the address when i=0 is reserved in the PLIC register map, it was probably interpreted that the first interrupt line starts from i = 1 and goes to PLIC_MAX_IRQ + 1. Instead, interrupt ID 0 is defined as reserved and so the hardware reserves a register corresponding to its priority. So the loop should be from i = 1, i <= PLIC_NUM_INTERRUPTS.

1 Like