summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-04-17 13:22:18 +0000
committerjhb <jhb@FreeBSD.org>2009-04-17 13:22:18 +0000
commit360bcf216198a3173ff063265a1df2948aa5e0bf (patch)
tree578d27762d5eae159d85fdddd6668b6619761570
parentb12508be46e8501b7f2bcf3116f8a5d097b386ae (diff)
downloadFreeBSD-src-360bcf216198a3173ff063265a1df2948aa5e0bf.zip
FreeBSD-src-360bcf216198a3173ff063265a1df2948aa5e0bf.tar.gz
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
-rw-r--r--sys/amd64/amd64/busdma_machdep.c13
-rw-r--r--sys/arm/arm/busdma_machdep.c13
-rw-r--r--sys/i386/i386/busdma_machdep.c13
-rw-r--r--sys/ia64/ia64/busdma_machdep.c13
4 files changed, 40 insertions, 12 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
index de4717c..d403151 100644
--- a/sys/amd64/amd64/busdma_machdep.c
+++ b/sys/amd64/amd64/busdma_machdep.c
@@ -1137,9 +1137,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
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, struct bounce_page *bpage)
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);
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index 153d83f..fb3afee 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -1427,9 +1427,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
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, struct bounce_page *bpage)
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);
diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c
index cf0ac51..921cb0b 100644
--- a/sys/i386/i386/busdma_machdep.c
+++ b/sys/i386/i386/busdma_machdep.c
@@ -1155,9 +1155,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
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, struct bounce_page *bpage)
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);
diff --git a/sys/ia64/ia64/busdma_machdep.c b/sys/ia64/ia64/busdma_machdep.c
index 609a8a9..7e7366a 100644
--- a/sys/ia64/ia64/busdma_machdep.c
+++ b/sys/ia64/ia64/busdma_machdep.c
@@ -940,9 +940,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
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, struct bounce_page *bpage)
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);
OpenPOWER on IntegriCloud