⬢ DragonFlyBSD Kernel Audit
DF-4708 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/amr/amr_pci.c
+++ b/sys/dev/raid/amr/amr_pci.c
@@ -544,6 +544,7 @@ amr_sglist_map(struct amr_softc *sc)
     size_t	segsize;
     void	*p;
     int		error;
+    int		retries = 0;
 
     debug_called(1);
 
@@ -592,14 +593,23 @@ amr_sglist_map(struct amr_softc *sc)
     retry:
     error = bus_dmamem_alloc(sc->amr_sg_dmat, &p, BUS_DMA_NOWAIT,
 			     &sc->amr_sg_dmamap);
     if (error) {
 	device_printf(sc->amr_dev, "can't allocate s/g table\n");
 	return(ENOMEM);
     }
-    bus_dmamap_load(sc->amr_sg_dmat, sc->amr_sg_dmamap, p, segsize, amr_sglist_helper, &sc->amr_sgbusaddr, 0);
+    error = bus_dmamap_load(sc->amr_sg_dmat, sc->amr_sg_dmamap, p, segsize, amr_sglist_helper, &sc->amr_sgbusaddr, 0);
+    if (error) {
+	device_printf(sc->amr_dev, "can't load s/g table\n");
+	bus_dmamem_free(sc->amr_sg_dmat, p, sc->amr_sg_dmamap);
+	return(ENOMEM);
+    }
     if (sc->amr_sgbusaddr < 0x2000) {
 	debug(1, "s/g table too low (0x%x), reallocating\n", sc->amr_sgbusaddr);
+	bus_dmamap_unload(sc->amr_sg_dmat, sc->amr_sg_dmamap);
+	bus_dmamem_free(sc->amr_sg_dmat, p, sc->amr_sg_dmamap);
+	if (++retries > 8) {
+	    device_printf(sc->amr_dev, "s/g table stuck too low, giving up\n");
+	    return(ENOMEM);
+	}
 	goto retry;
     }
@@ -651,8 +660,13 @@ amr_setup_mbox(struct amr_softc *sc)
     error = bus_dmamem_alloc(sc->amr_mailbox_dmat, &p, BUS_DMA_NOWAIT,
 			     &sc->amr_mailbox_dmamap);
     if (error) {
         device_printf(sc->amr_dev, "can't allocate mailbox memory\n");
         return(ENOMEM);
     }
-    bus_dmamap_load(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap, p,
-		    sizeof(struct amr_mailbox64), amr_sglist_helper, &baddr, 0);
+    error = bus_dmamap_load(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap, p,
+		    sizeof(struct amr_mailbox64), amr_sglist_helper, &baddr, 0);
+    if (error) {
+        device_printf(sc->amr_dev, "can't load mailbox\n");
+        return(ENOMEM);
+    }
@@ -695,7 +709,11 @@ amr_ccb_map(struct amr_softc *sc)
     if (error) {
         device_printf(sc->amr_dev, "can't allocate ccb memory\n");
         return (ENOMEM);
     }
-    bus_dmamap_load(sc->amr_ccb_dmat, sc->amr_ccb_dmamap, sc->amr_ccb,
-		    ccbsize, amr_sglist_helper, &sc->amr_ccb_busaddr, 0);
+    error = bus_dmamap_load(sc->amr_ccb_dmat, sc->amr_ccb_dmamap, sc->amr_ccb,
+		    ccbsize, amr_sglist_helper, &sc->amr_ccb_busaddr, 0);
+    if (error) {
+        device_printf(sc->amr_dev, "can't load ccb block\n");
+        return (ENOMEM);
+    }