This fixes two bugs in plic(4). When a particular CPU is not found,
typically when running GENERIC or RAMDISK on a multiprocessor machine,
plic_get_cpuid() returns -1. In that case plic_attach() should just
ignore the entry and move on. The `cpu' variable should also be signed,
otherwise the condition (cpu < 0) cannot be true.

Strangely enough, RAMDISK has been functional despite the type bug.
The -Oz optimized code has generated memory addresses that have not
caused immediate damage but also not triggered any protection errors.
GENERIC on the other hand crashes because sc_contexts[] is updated
with index -1, corrupting plic_softc fields sc_ioh and sc_isrcs.

OK?

Index: arch/riscv64/dev/plic.c
===================================================================
RCS file: src/sys/arch/riscv64/dev/plic.c,v
retrieving revision 1.8
diff -u -p -r1.8 plic.c
--- arch/riscv64/dev/plic.c     3 Jan 2022 03:06:50 -0000       1.8
+++ arch/riscv64/dev/plic.c     17 Jan 2022 14:19:53 -0000
@@ -162,7 +162,7 @@ plic_attach(struct device *parent, struc
        struct fdt_attach_args *faa;
        uint32_t *cells;
        uint32_t irq;
-       uint32_t cpu;
+       int cpu;
        int node;
        int len;
        int ncell;
@@ -251,11 +251,8 @@ plic_attach(struct device *parent, struc
 
                /* Get the corresponding cpuid. */
                cpu = plic_get_cpuid(OF_getnodebyphandle(cells[i]));
-               if (cpu < 0) {
-                       printf(": invalid hart!\n");
-                       free(cells, M_TEMP, len);
-                       return;
-               }
+               if (cpu < 0)
+                       continue;
 
                /*
                 * Set the enable and context register offsets for the CPU.

Reply via email to