>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

Reply via email to