Author: jhb
Date: Fri Apr 17 13:22:18 2009
New Revision: 191201
URL: http://svn.freebsd.org/changeset/base/191201

Log:
  Restore bus DMA bounce pages to an offset of 0 when they are released by
  a tag that has BUS_DMA_KEEP_PG_OFFSET set.  Otherwise the page could be
  reused with a non-zero offset by a tag that doesn't have
  BUS_DMA_KEEP_PG_OFFSET leading to data corruption.
  
  Sleuthing by: avg
  Reviewed by:  scottl

Modified:
  head/sys/amd64/amd64/busdma_machdep.c
  head/sys/arm/arm/busdma_machdep.c
  head/sys/i386/i386/busdma_machdep.c
  head/sys/ia64/ia64/busdma_machdep.c

Modified: head/sys/amd64/amd64/busdma_machdep.c
==============================================================================
--- head/sys/amd64/amd64/busdma_machdep.c       Fri Apr 17 11:30:32 2009        
(r191200)
+++ head/sys/amd64/amd64/busdma_machdep.c       Fri Apr 17 13:22:18 2009        
(r191201)
@@ -1137,9 +1137,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
        mtx_unlock(&bounce_lock);
 
        if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
-               /* page offset needs to be preserved */
-               bpage->vaddr &= ~PAGE_MASK;
-               bpage->busaddr &= ~PAGE_MASK;
+               /* Page offset needs to be preserved. */
                bpage->vaddr |= vaddr & PAGE_MASK;
                bpage->busaddr |= vaddr & PAGE_MASK;
        }
@@ -1158,6 +1156,15 @@ free_bounce_page(bus_dma_tag_t dmat, str
        bz = dmat->bounce_zone;
        bpage->datavaddr = 0;
        bpage->datacount = 0;
+       if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+               /*
+                * Reset the bounce page to start at offset 0.  Other uses
+                * of this bounce page may need to store a full page of
+                * data and/or assume it starts on a page boundary.
+                */
+               bpage->vaddr &= ~PAGE_MASK;
+               bpage->busaddr &= ~PAGE_MASK;
+       }
 
        mtx_lock(&bounce_lock);
        STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);

Modified: head/sys/arm/arm/busdma_machdep.c
==============================================================================
--- head/sys/arm/arm/busdma_machdep.c   Fri Apr 17 11:30:32 2009        
(r191200)
+++ head/sys/arm/arm/busdma_machdep.c   Fri Apr 17 13:22:18 2009        
(r191201)
@@ -1427,9 +1427,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
        mtx_unlock(&bounce_lock);
 
        if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
-               /* page offset needs to be preserved */
-               bpage->vaddr &= ~PAGE_MASK;
-               bpage->busaddr &= ~PAGE_MASK;
+               /* Page offset needs to be preserved. */
                bpage->vaddr |= vaddr & PAGE_MASK;
                bpage->busaddr |= vaddr & PAGE_MASK;
        }
@@ -1448,6 +1446,15 @@ free_bounce_page(bus_dma_tag_t dmat, str
        bz = dmat->bounce_zone;
        bpage->datavaddr = 0;
        bpage->datacount = 0;
+       if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+               /*
+                * Reset the bounce page to start at offset 0.  Other uses
+                * of this bounce page may need to store a full page of
+                * data and/or assume it starts on a page boundary.
+                */
+               bpage->vaddr &= ~PAGE_MASK;
+               bpage->busaddr &= ~PAGE_MASK;
+       }
 
        mtx_lock(&bounce_lock);
        STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);

Modified: head/sys/i386/i386/busdma_machdep.c
==============================================================================
--- head/sys/i386/i386/busdma_machdep.c Fri Apr 17 11:30:32 2009        
(r191200)
+++ head/sys/i386/i386/busdma_machdep.c Fri Apr 17 13:22:18 2009        
(r191201)
@@ -1155,9 +1155,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
        mtx_unlock(&bounce_lock);
 
        if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
-               /* page offset needs to be preserved */
-               bpage->vaddr &= ~PAGE_MASK;
-               bpage->busaddr &= ~PAGE_MASK;
+               /* Page offset needs to be preserved. */
                bpage->vaddr |= vaddr & PAGE_MASK;
                bpage->busaddr |= vaddr & PAGE_MASK;
        }
@@ -1176,6 +1174,15 @@ free_bounce_page(bus_dma_tag_t dmat, str
        bz = dmat->bounce_zone;
        bpage->datavaddr = 0;
        bpage->datacount = 0;
+       if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+               /*
+                * Reset the bounce page to start at offset 0.  Other uses
+                * of this bounce page may need to store a full page of
+                * data and/or assume it starts on a page boundary.
+                */
+               bpage->vaddr &= ~PAGE_MASK;
+               bpage->busaddr &= ~PAGE_MASK;
+       }
 
        mtx_lock(&bounce_lock);
        STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);

Modified: head/sys/ia64/ia64/busdma_machdep.c
==============================================================================
--- head/sys/ia64/ia64/busdma_machdep.c Fri Apr 17 11:30:32 2009        
(r191200)
+++ head/sys/ia64/ia64/busdma_machdep.c Fri Apr 17 13:22:18 2009        
(r191201)
@@ -940,9 +940,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
        mtx_unlock(&bounce_lock);
 
        if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
-               /* page offset needs to be preserved */
-               bpage->vaddr &= ~PAGE_MASK;
-               bpage->busaddr &= ~PAGE_MASK;
+               /* Page offset needs to be preserved. */
                bpage->vaddr |= vaddr & PAGE_MASK;
                bpage->busaddr |= vaddr & PAGE_MASK;
        }
@@ -959,6 +957,15 @@ free_bounce_page(bus_dma_tag_t dmat, str
 
        bpage->datavaddr = 0;
        bpage->datacount = 0;
+       if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+               /*
+                * Reset the bounce page to start at offset 0.  Other uses
+                * of this bounce page may need to store a full page of
+                * data and/or assume it starts on a page boundary.
+                */
+               bpage->vaddr &= ~PAGE_MASK;
+               bpage->busaddr &= ~PAGE_MASK;
+       }
 
        mtx_lock(&bounce_lock);
        STAILQ_INSERT_HEAD(&bounce_page_list, bpage, links);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to