diff options
author | jhb <jhb@FreeBSD.org> | 2009-04-17 13:22:18 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-04-17 13:22:18 +0000 |
commit | 360bcf216198a3173ff063265a1df2948aa5e0bf (patch) | |
tree | 578d27762d5eae159d85fdddd6668b6619761570 | |
parent | b12508be46e8501b7f2bcf3116f8a5d097b386ae (diff) | |
download | FreeBSD-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.c | 13 | ||||
-rw-r--r-- | sys/arm/arm/busdma_machdep.c | 13 | ||||
-rw-r--r-- | sys/i386/i386/busdma_machdep.c | 13 | ||||
-rw-r--r-- | sys/ia64/ia64/busdma_machdep.c | 13 |
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); |