From: bluhm Date: Thu, 22 Aug 2024 11:36:24 +0000 (+0000) Subject: Fix merge of bounce buffer segments in amd64 bus dma. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e8c1c6d5997843e8953c48dbf25930ba36957107;p=openbsd Fix merge of bounce buffer segments in amd64 bus dma. If the physical pages are contiguous, _bus_dmamap_load_buffer() tries to merge the segments. In case of mbuf chains, it can happen that the physical bounce buffers are contiguous, but the virtual addresses of mbuf m_data are not. Then during transmit _bus_dmamap_sync() tries to copy segments where it cannot access the virtual source address which is mapped in a different mbuf. So if bounce buffers are used, physical and virtual buffer must be contigous, to merge a segment. While there, split check and decrement of variable i in a for loop to make the code readable. with and OK hshoexer@ --- diff --git a/sys/arch/amd64/amd64/bus_dma.c b/sys/arch/amd64/amd64/bus_dma.c index c29501ad735..070c3429b05 100644 --- a/sys/arch/amd64/amd64/bus_dma.c +++ b/sys/arch/amd64/amd64/bus_dma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bus_dma.c,v 1.56 2024/08/20 15:30:29 bluhm Exp $ */ +/* $OpenBSD: bus_dma.c,v 1.57 2024/08/22 11:36:24 bluhm Exp $ */ /* $NetBSD: bus_dma.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */ /*- @@ -499,7 +499,7 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t addr, if (!use_bounce_buffer) return; - for (i = map->_dm_segcnt, sg = map->dm_segs; size && i--; sg++) { + for (i = map->_dm_segcnt, sg = map->dm_segs; size && i; i--, sg++) { if (off >= sg->ds_len) { off -= sg->ds_len; continue; @@ -767,9 +767,11 @@ _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, map->_dm_maxsegsz && (map->_dm_boundary == 0 || (map->dm_segs[seg].ds_addr & bmask) == - (curaddr & bmask))) + (curaddr & bmask)) && + (!use_bounce_buffer || (map->dm_segs[seg]._ds_va + + map->dm_segs[seg].ds_len) == vaddr)) { map->dm_segs[seg].ds_len += sgsize; - else { + } else { if (++seg >= map->_dm_segcnt) break; map->dm_segs[seg].ds_addr = curaddr;