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.