> Date: Sat, 2 Apr 2016 21:30:55 +0200
> From: Alexander Bluhm <[email protected]>
> 
> Should we clear the scratch page to prevent that the dc(4) hardware
> may see sensitive information?

Good point; new diff below.

Index: dev/ic/dc.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/dc.c,v
retrieving revision 1.149
diff -u -p -r1.149 dc.c
--- dev/ic/dc.c 28 Nov 2015 22:57:43 -0000      1.149
+++ dev/ic/dc.c 2 Apr 2016 20:45:59 -0000
@@ -2584,13 +2584,13 @@ dc_start(struct ifnet *ifp)
 
                map = sc->sc_tx_sparemap;
                switch (bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
-                   BUS_DMA_NOWAIT)) {
+                   BUS_DMA_NOWAIT | BUS_DMA_OVERRUN)) {
                case 0:
                        break;
                case EFBIG:
                        if (m_defrag(m, M_DONTWAIT) == 0 &&
                            bus_dmamap_load_mbuf(sc->sc_dmat, map, m,
-                            BUS_DMA_NOWAIT) == 0)
+                            BUS_DMA_NOWAIT | BUS_DMA_OVERRUN) == 0)
                                break;
 
                        /* FALLTHROUGH */
Index: arch/sparc64/dev/iommu.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/dev/iommu.c,v
retrieving revision 1.72
diff -u -p -r1.72 iommu.c
--- arch/sparc64/dev/iommu.c    9 Jan 2015 14:23:25 -0000       1.72
+++ arch/sparc64/dev/iommu.c    2 Apr 2016 20:46:01 -0000
@@ -195,6 +195,13 @@ iommu_init(char *name, struct iommu_stat
        pmap_update(pmap_kernel());
        memset(is->is_tsb, 0, size);
 
+       TAILQ_INIT(&mlist);
+       if (uvm_pglistalloc(PAGE_SIZE, 0, -1, PAGE_SIZE, 0, &mlist, 1,
+           UVM_PLA_NOWAIT | UVM_PLA_ZERO) != 0)
+               panic("%s: no memory", __func__);
+       m = TAILQ_FIRST(&mlist);
+       is->is_scratch = VM_PAGE_TO_PHYS(m);
+
 #ifdef DEBUG
        if (iommudebug & IDB_INFO) {
                /* Probe the iommu */
@@ -734,6 +741,13 @@ iommu_dvmamap_load(bus_dma_tag_t t, bus_
                        }
                }
        }
+       if (flags & BUS_DMA_OVERRUN) {
+               err = iommu_iomap_insert_page(ims, is->is_scratch);
+               if (err) {
+                       iommu_iomap_clear_pages(ims);
+                       return (EFBIG);
+               }
+       }
        sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE;
 
        mtx_enter(&is->is_mtx);
@@ -939,6 +953,13 @@ iommu_dvmamap_load_raw(bus_dma_tag_t t, 
                        }
 
                        left -= seg_len;
+               }
+       }
+       if (flags & BUS_DMA_OVERRUN) {
+               err = iommu_iomap_insert_page(ims, is->is_scratch);
+               if (err) {
+                       iommu_iomap_clear_pages(ims);
+                       return (EFBIG);
                }
        }
        sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE;
Index: arch/sparc64/dev/iommuvar.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/dev/iommuvar.h,v
retrieving revision 1.16
diff -u -p -r1.16 iommuvar.h
--- arch/sparc64/dev/iommuvar.h 22 Jan 2014 10:52:35 -0000      1.16
+++ arch/sparc64/dev/iommuvar.h 2 Apr 2016 20:46:01 -0000
@@ -117,6 +117,8 @@ struct iommu_state {
 
        struct strbuf_ctl       *is_sb[2];      /* Streaming buffers if any */
 
+       paddr_t                 is_scratch;     /* Scratch page */
+
        /* copies of our parents state, to allow us to be self contained */
        bus_space_tag_t         is_bustag;      /* our bus tag */
        bus_space_handle_t      is_iommu;       /* IOMMU registers */
Index: arch/sparc64/dev/viommu.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/dev/viommu.c,v
retrieving revision 1.16
diff -u -p -r1.16 viommu.c
--- arch/sparc64/dev/viommu.c   9 Jan 2015 14:23:25 -0000       1.16
+++ arch/sparc64/dev/viommu.c   2 Apr 2016 20:46:01 -0000
@@ -106,6 +106,9 @@ void
 viommu_init(char *name, struct iommu_state *is, int tsbsize,
     u_int32_t iovabase)
 {
+       struct vm_page *m;
+       struct pglist mlist;
+
        /*
         * Setup the iommu.
         *
@@ -121,6 +124,13 @@ viommu_init(char *name, struct iommu_sta
                is->is_dvmaend = iovabase + IOTSB_VSIZE(tsbsize) - 1;
        }
 
+       TAILQ_INIT(&mlist);
+       if (uvm_pglistalloc(PAGE_SIZE, 0, -1, PAGE_SIZE, 0, &mlist, 1,
+           UVM_PLA_NOWAIT | UVM_PLA_ZERO) != 0)
+               panic("%s: no memory", __func__);
+       m = TAILQ_FIRST(&mlist);
+       is->is_scratch = VM_PAGE_TO_PHYS(m);
+
        /*
         * Allocate a dvma map.
         */
@@ -341,6 +351,13 @@ viommu_dvmamap_load(bus_dma_tag_t t, bus
                        }
                }
        }
+       if (flags & BUS_DMA_OVERRUN) {
+               err = iommu_iomap_insert_page(ims, is->is_scratch);
+               if (err) {
+                       iommu_iomap_clear_pages(ims);
+                       return (EFBIG);
+               }
+       }
        sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE;
 
        mtx_enter(&is->is_mtx);
@@ -522,6 +539,13 @@ viommu_dvmamap_load_raw(bus_dma_tag_t t,
                        }
 
                        left -= seg_len;
+               }
+       }
+       if (flags & BUS_DMA_OVERRUN) {
+               err = iommu_iomap_insert_page(ims, is->is_scratch);
+               if (err) {
+                       iommu_iomap_clear_pages(ims);
+                       return (EFBIG);
                }
        }
        sgsize = ims->ims_map.ipm_pagecnt * PAGE_SIZE;
Index: arch/sparc64/include/bus.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/bus.h,v
retrieving revision 1.29
diff -u -p -r1.29 bus.h
--- arch/sparc64/include/bus.h  13 May 2013 17:46:42 -0000      1.29
+++ arch/sparc64/include/bus.h  2 Apr 2016 20:46:01 -0000
@@ -356,19 +356,20 @@ bus_space_barrier(t, h, o, s, f)
 /*
  * Flags used in various bus DMA methods.
  */
-#define        BUS_DMA_WAITOK          0x000   /* safe to sleep (pseudo-flag) 
*/
-#define        BUS_DMA_NOWAIT          0x001   /* not safe to sleep */
-#define        BUS_DMA_ALLOCNOW        0x002   /* perform resource allocation 
now */
-#define        BUS_DMA_COHERENT        0x004   /* hint: map memory DMA 
coherent */
-#define        BUS_DMA_NOWRITE         0x008   /* I suppose the following two 
should default on */
-#define        BUS_DMA_BUS1            0x010   /* placeholders for bus 
functions... */
-#define        BUS_DMA_BUS2            0x020
-#define        BUS_DMA_BUS3            0x040
-#define        BUS_DMA_BUS4            0x080
-#define        BUS_DMA_STREAMING       0x100   /* hint: sequential, 
unidirectional */
-#define        BUS_DMA_READ            0x200   /* mapping is device -> memory 
only */
-#define        BUS_DMA_WRITE           0x400   /* mapping is memory -> device 
only */
-#define        BUS_DMA_ZERO            0x800   /* zero memory in dmamem_alloc 
*/
+#define        BUS_DMA_WAITOK          0x0000  /* safe to sleep (pseudo-flag) 
*/
+#define        BUS_DMA_NOWAIT          0x0001  /* not safe to sleep */
+#define        BUS_DMA_ALLOCNOW        0x0002  /* perform resource allocation 
now */
+#define        BUS_DMA_COHERENT        0x0004  /* hint: map memory DMA 
coherent */
+#define        BUS_DMA_NOWRITE         0x0008  /* I suppose the following two 
should default on */
+#define        BUS_DMA_BUS1            0x0010  /* placeholders for bus 
functions... */
+#define        BUS_DMA_BUS2            0x0020
+#define        BUS_DMA_BUS3            0x0040
+#define        BUS_DMA_BUS4            0x0080
+#define        BUS_DMA_STREAMING       0x0100  /* hint: sequential, 
unidirectional */
+#define        BUS_DMA_READ            0x0200  /* mapping is device -> memory 
only */
+#define        BUS_DMA_WRITE           0x0400  /* mapping is memory -> device 
only */
+#define        BUS_DMA_ZERO            0x0800  /* zero memory in dmamem_alloc 
*/
+#define BUS_DMA_OVERRUN                0x1000  /* tolerate DMA overruns */
 
 #define        BUS_DMA_NOCACHE         BUS_DMA_BUS1
 #define        BUS_DMA_DVMA            BUS_DMA_BUS2    /* Don't bother with 
alignment */

Reply via email to