>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 dera...@arm64.openbsd.org:/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 dera...@arm64.openbsd.org:/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