diff options
author | harti <harti@FreeBSD.org> | 2003-02-04 16:30:27 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2003-02-04 16:30:27 +0000 |
commit | 570156f24c833c50ded55e900b5d6284fc04ccee (patch) | |
tree | 456b763a94213088811e390d3dfe4a45d7fa5de6 /sys/ia64 | |
parent | 865d0cfd1290a3611baf60c7619c4fca51305464 (diff) | |
download | FreeBSD-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/ia64')
-rw-r--r-- | sys/ia64/ia64/busdma_machdep.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/sys/ia64/ia64/busdma_machdep.c b/sys/ia64/ia64/busdma_machdep.c index e10f084..d12ea4f 100644 --- a/sys/ia64/ia64/busdma_machdep.c +++ b/sys/ia64/ia64/busdma_machdep.c @@ -644,11 +644,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; @@ -708,13 +711,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) { |