summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-02-04 16:30:27 +0000
committerharti <harti@FreeBSD.org>2003-02-04 16:30:27 +0000
commit570156f24c833c50ded55e900b5d6284fc04ccee (patch)
tree456b763a94213088811e390d3dfe4a45d7fa5de6 /sys/alpha
parent865d0cfd1290a3611baf60c7619c4fca51305464 (diff)
downloadFreeBSD-src-570156f24c833c50ded55e900b5d6284fc04ccee.zip
FreeBSD-src-570156f24c833c50ded55e900b5d6284fc04ccee.tar.gz
Fix a problem in bus_dmamap_load_{mbuf,uio} when the first mbuf or the first
uio segment is empty. In this case no dma segment is create by bus_dmamap_load_buffer, but the calling routine clears the first flag. Under certain combinations of addresses of the first and second mbuf/uio buffer this leads to corrupted DMA segment descriptors. This was already fixed by tmm in sparc64/sparc64/iommu.c. PR: kern/47733 Reviewed by: sam Approved by: jake (mentor)
Diffstat (limited to 'sys/alpha')
-rw-r--r--sys/alpha/alpha/busdma_machdep.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/sys/alpha/alpha/busdma_machdep.c b/sys/alpha/alpha/busdma_machdep.c
index 28240ae..8b70104 100644
--- a/sys/alpha/alpha/busdma_machdep.c
+++ b/sys/alpha/alpha/busdma_machdep.c
@@ -674,11 +674,14 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
struct mbuf *m;
for (m = m0; m != NULL && error == 0; m = m->m_next) {
- error = _bus_dmamap_load_buffer(dmat,
- dm_segments,
- m->m_data, m->m_len,
- NULL, flags, &lastaddr, &nsegs, first);
- first = 0;
+ if (m->m_len > 0) {
+ error = _bus_dmamap_load_buffer(dmat,
+ dm_segments,
+ m->m_data, m->m_len,
+ NULL, flags, &lastaddr,
+ &nsegs, first);
+ first = 0;
+ }
}
} else {
error = EINVAL;
@@ -738,13 +741,15 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
resid < iov[i].iov_len ? resid : iov[i].iov_len;
caddr_t addr = (caddr_t) iov[i].iov_base;
- error = _bus_dmamap_load_buffer(dmat,
- dm_segments,
- addr, minlen,
- td, flags, &lastaddr, &nsegs, first);
- first = 0;
+ if (minlen > 0) {
+ error = _bus_dmamap_load_buffer(dmat,
+ dm_segments,
+ addr, minlen,
+ td, flags, &lastaddr, &nsegs, first);
+ first = 0;
- resid -= minlen;
+ resid -= minlen;
+ }
}
if (error) {
OpenPOWER on IntegriCloud