>Synopsis: bse: null dereference in genet_rxintr()
>Category: arm64
>Environment:
System : OpenBSD 7.1
Details : OpenBSD 7.1-beta (GENERIC.MP) #1594: Mon Mar 21 06:55:12
MDT 2022
[email protected]:/usr/src/sys/arch/arm64/compile/GENERIC.MP
Architecture: OpenBSD.arm64
Machine : arm64
>Description:
Booting my rpi4 often but not always causes a panic while rc(8) tries to start
the bse network interface:
panic: attempt to access user address 0x38 from EL1
Stopped at panic+0x160: cmp w21, #0x0
TID PID UID PRFLAGS PFLAGS CPU COMMAND
* 0 0 0 0x10000 0x200 0K swapper
db_enter() at panic+0x15c
panic() at do_el1h_sync+0x1f8
do_el1h_sync() at handle_el1h_sync+0x6c
handle_el1h_sync() at genet_rxintr+0x120
genet_rxintr() at genet_intr+0x74
genet_intr() at ampintc_irq_handler+0x14c
ampintc_irq_handler() at arm_cpu_irq+0x30
arm_cpu_irq() at handle_el1h_irq+0x6c
handle_el1h_irq() at ampintc_splx+0x80
ampintc_splx() at genet_ioctl+0x158
genet_ioctl() at ifioctl+0x308
ifioctl() at nfs_boot_init+0xc0
nfs_boot_init() at nfs_mountroot+0x3c
nfs_mountroot() at main+0x464
main() at virtdone+0x70
>Fix:
The mbuf associated with the current index is NULL. I noticed that the NetBSD
driver allocates mbufs for each ring entry in genet_setup_dma(). But even with
that in place the same panic still occurs. Enabling GENET_DEBUG shows that the
total is quite high:
RX pidx=0000ca07 total=51463
Since it's greater than GENET_DMA_DESC_COUNT (=256) the null dereference will
still happen after doing more than 256 iterations in genet_rxintr() since we
will start accessing mbufs cleared by the previous iteration.
Here's a diff with what I've tried so far. The KASSERT() is just capturing the
problem at an earlier stage. Any pointers would be much appreciated.
diff --git sys/dev/ic/bcmgenet.c sys/dev/ic/bcmgenet.c
index 923df40bdfc..c91db84375b 100644
--- sys/dev/ic/bcmgenet.c
+++ sys/dev/ic/bcmgenet.c
@@ -695,7 +695,10 @@ genet_rxintr(struct genet_softc *sc, int qid)
status = RD4(sc, GENET_RX_DESC_STATUS(index));
len = __SHIFTOUT(status, GENET_RX_DESC_STATUS_BUFLEN);
- /* XXX check for errors */
+ if (status & GENET_RX_DESC_STATUS_ALL_ERRS) {
+ ifp->if_ierrors++;
+ goto next;
+ }
bus_dmamap_sync(sc->sc_rx.buf_tag, sc->sc_rx.buf_map[index].map,
0, sc->sc_rx.buf_map[index].map->dm_mapsize,
@@ -706,6 +709,7 @@ genet_rxintr(struct genet_softc *sc, int qid)
n, index, status, len, len - ETHER_ALIGN);
m = sc->sc_rx.buf_map[index].mbuf;
+ KASSERT(m != NULL);
sc->sc_rx.buf_map[index].mbuf = NULL;
if (len > ETHER_ALIGN) {
@@ -722,6 +726,7 @@ genet_rxintr(struct genet_softc *sc, int qid)
if_rxr_put(&sc->sc_rx_ring, 1);
+next:
index = RX_NEXT(index);
}
@@ -919,6 +924,8 @@ genet_setup_dma(struct genet_softc *sc, int qid)
/* Setup RX ring */
sc->sc_rx.buf_tag = sc->sc_dmat;
for (i = 0; i < RX_DESC_COUNT; i++) {
+ struct mbuf *m;
+
error = bus_dmamap_create(sc->sc_rx.buf_tag, MCLBYTES,
1, MCLBYTES, 0, BUS_DMA_WAITOK,
&sc->sc_rx.buf_map[i].map);
@@ -927,6 +934,18 @@ genet_setup_dma(struct genet_softc *sc, int qid)
sc->sc_dev.dv_xname);
return error;
}
+ if ((m = genet_alloc_mbufcl(sc)) == NULL) {
+ printf("%s: cannot allocate RX mbuf\n",
+ sc->sc_dev.dv_xname);
+ return ENOMEM;
+ }
+ error = genet_setup_rxbuf(sc, i, m);
+ if (error != 0) {
+ printf("%s: cannot create RX buffer\n",
+ sc->sc_dev.dv_xname);
+ m_freem(m);
+ return error;
+ }
}
return 0;
diff --git sys/dev/ic/bcmgenetreg.h sys/dev/ic/bcmgenetreg.h
index 2cf24bb6ac0..b4b2d541425 100644
--- sys/dev/ic/bcmgenetreg.h
+++ sys/dev/ic/bcmgenetreg.h
@@ -146,6 +146,7 @@
#define GENET_RX_DESC_STATUS_OWN __BIT(15)
#define GENET_RX_DESC_STATUS_EOP __BIT(14)
#define GENET_RX_DESC_STATUS_SOP __BIT(13)
+#define GENET_RX_DESC_STATUS_ALL_ERRS __BITS(4,0)
#define GENET_RX_DESC_STATUS_RX_ERROR __BIT(2)
#define GENET_RX_DESC_ADDRESS_LO(idx) (GENET_RX_BASE +
GENET_DMA_DESC_SIZE * (idx) + 0x04)
#define GENET_RX_DESC_ADDRESS_HI(idx) (GENET_RX_BASE +
GENET_DMA_DESC_SIZE * (idx) + 0x08)
dmesg:
OpenBSD 7.1-beta (GENERIC.MP) #1594: Mon Mar 21 06:55:12 MDT 2022
[email protected]:/usr/src/sys/arch/arm64/compile/GENERIC.MP
real mem = 4124876800 (3933MB)
avail mem = 3965554688 (3781MB)
random: good seed from bootblocks
mainbus0 at root: Raspberry Pi 4 Model B Rev 1.5
cpu0 at mainbus0 mpidr 0: ARM Cortex-A72 r0p3
cpu0: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache
cpu0: 1024KB 64b/line 16-way L2 cache
cpu0: CRC32,ASID16
cpu1 at mainbus0 mpidr 1: ARM Cortex-A72 r0p3
cpu1: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache
cpu1: 1024KB 64b/line 16-way L2 cache
cpu1: CRC32,ASID16
cpu2 at mainbus0 mpidr 2: ARM Cortex-A72 r0p3
cpu2: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache
cpu2: 1024KB 64b/line 16-way L2 cache
cpu2: CRC32,ASID16
cpu3 at mainbus0 mpidr 3: ARM Cortex-A72 r0p3
cpu3: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache
cpu3: 1024KB 64b/line 16-way L2 cache
cpu3: CRC32,ASID16
efi0 at mainbus0: UEFI 2.8
efi0: Das U-Boot rev 0x20211000
apm0 at mainbus0
"system" at mainbus0 not configured
"axi" at mainbus0 not configured
simplebus0 at mainbus0: "soc"
bcmclock0 at simplebus0
bcmmbox0 at simplebus0
bcmgpio0 at simplebus0
bcmaux0 at simplebus0
ampintc0 at simplebus0 nirq 256, ncpu 4 ipi: 0, 1: "interrupt-controller"
bcmtmon0 at simplebus0
bcmdmac0 at simplebus0: DMA0 DMA2 DMA4 DMA5 DMA6 DMA7 DMA8 DMA9
"timer" at simplebus0 not configured
pluart0 at simplebus0: console
"local_intc" at simplebus0 not configured
bcmdog0 at simplebus0
bcmirng0 at simplebus0
"firmware" at simplebus0 not configured
"power" at simplebus0 not configured
"mailbox" at simplebus0 not configured
sdhc0 at simplebus0
sdhc0: SDHC 3.0, 250 MHz base clock
sdmmc0 at sdhc0: 4-bit, sd high-speed, mmc high-speed
"gpiomem" at simplebus0 not configured
"fb" at simplebus0 not configured
"vcsm" at simplebus0 not configured
"clocks" at mainbus0 not configured
"phy" at mainbus0 not configured
"clk-27M" at mainbus0 not configured
"clk-108M" at mainbus0 not configured
simplebus1 at mainbus0: "emmc2bus"
sdhc1 at simplebus1
sdhc1: SDHC 3.0, 100 MHz base clock
sdmmc1 at sdhc1: 8-bit, sd high-speed, mmc high-speed, ddr52, dma
"arm-pmu" at mainbus0 not configured
agtimer0 at mainbus0: 54000 kHz
simplebus2 at mainbus0: "scb"
bcmpcie0 at simplebus2
pci0 at bcmpcie0
ppb0 at pci0 dev 0 function 0 "Broadcom BCM2711" rev 0x20
pci1 at ppb0 bus 1
xhci0 at pci1 dev 0 function 0 "VIA VL805 xHCI" rev 0x01: intx, xHCI 1.0
usb0 at xhci0: USB revision 3.0
uhub0 at usb0 configuration 1 interface 0 "VIA xHCI root hub" rev 3.00/1.00
addr 1
bse0 at simplebus2: address e4:5f:01:9a:c1:f2
brgphy0 at bse0 phy 1: BCM54210E 10/100/1000baseT PHY, rev. 2
"dma" at simplebus2 not configured
"hevc-decoder" at simplebus2 not configured
"rpivid-local-intc" at simplebus2 not configured
"h264-decoder" at simplebus2 not configured
"vp9-decoder" at simplebus2 not configured
gpioleds0 at mainbus0: "led0", "led1"
"sd_io_1v8_reg" at mainbus0 not configured
"sd_vcc_reg" at mainbus0 not configured
"fixedregulator_3v3" at mainbus0 not configured
"fixedregulator_5v0" at mainbus0 not configured
simplebus3 at mainbus0: "v3dbus"
"bootloader" at mainbus0 not configured
scsibus0 at sdmmc1: 2 targets, initiator 0
sd0 at scsibus0 targ 1 lun 0: <SD/MMC, SC32G, 0080> removable
sd0: 30436MB, 512 bytes/sector, 62333952 sectors
uhub1 at uhub0 port 1 configuration 1 interface 0 "VIA Labs USB2.0 Hub" rev
2.10/4.21 addr 2
bwfm0 at sdmmc0 function 1
manufacturer 0x02d0, product 0xa9a6 at sdmmc0 function 2 not configured
manufacturer 0x02d0, product 0xa9a6 at sdmmc0 function 3 not configured
umass0 at uhub0 port 2 configuration 1 interface 0 "SanDisk Ultra USB 3.0" rev
3.00/1.00 addr 3
umass0: using SCSI over Bulk-Only
scsibus1 at umass0: 2 targets, initiator 0
sd1 at scsibus1 targ 1 lun 0: <SanDisk, Ultra USB 3.0, 1.00> removable
serial.07815591230730102471
sd1: 14663MB, 512 bytes/sector, 30031250 sectors
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
root on sd0a (08ac810e78f1e13f.a) swap on sd0b dump on sd0b
WARNING: CHECK AND RESET THE DATE!
gpio0 at bcmgpio0: 58 pins
bwfm0: address e4:5f:01:9a:c1:f3