* [PATCH net] net: sgi: ioc3-eth: fix split TX DMA mapping lengths
@ 2026-06-29 8:06 raoxu
2026-06-29 17:16 ` Thomas Bogendoerfer
0 siblings, 1 reply; 2+ messages in thread
From: raoxu @ 2026-06-29 8:06 UTC (permalink / raw)
To: tsbogend
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-mips, netdev,
linux-kernel, raoxu, stable
From: Xu Rao <raoxu@uniontech.com>
When a linear skb crosses a 16 KiB boundary, ioc3_start_xmit()
splits it into two buffers of lengths s1 and s2. The descriptor
advertises those lengths through B1CNT and B2CNT.
The first buffer is mapped with s1, but the second buffer is also
mapped with s1 even though the device is told to fetch s2 bytes from
it. When the lengths differ, the DMA mapping does not cover the same
region as the second descriptor buffer, which can result in incorrect
cache maintenance or a DMA fault on implementations that enforce the
mapped range.
There is a separate mismatch in the error path. If mapping the second
buffer fails, only d1 needs to be unmapped. d1 was mapped for s1 bytes,
but the driver unmaps it using the full packet length. Streaming DMA
mappings must be unmapped with the same size used for the corresponding
map operation.
Map the second buffer with s2 and unmap the first buffer with s1 when
the second mapping fails.
Fixes: ed870f6a7aa2 ("net: sgi: ioc3-eth: use dma-direct for dma allocations")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/net/ethernet/sgi/ioc3-eth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
index 3973106..261f2d3 100644
--- a/drivers/net/ethernet/sgi/ioc3-eth.c
+++ b/drivers/net/ethernet/sgi/ioc3-eth.c
@@ -1061,9 +1061,9 @@ static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
d1 = dma_map_single(ip->dma_dev, skb->data, s1, DMA_TO_DEVICE);
if (dma_mapping_error(ip->dma_dev, d1))
goto drop_packet;
- d2 = dma_map_single(ip->dma_dev, (void *)b2, s1, DMA_TO_DEVICE);
+ d2 = dma_map_single(ip->dma_dev, (void *)b2, s2, DMA_TO_DEVICE);
if (dma_mapping_error(ip->dma_dev, d2)) {
- dma_unmap_single(ip->dma_dev, d1, len, DMA_TO_DEVICE);
+ dma_unmap_single(ip->dma_dev, d1, s1, DMA_TO_DEVICE);
goto drop_packet;
}
desc->p1 = cpu_to_be64(ioc3_map(d1, PCI64_ATTR_PREF));
--
2.47.3
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH net] net: sgi: ioc3-eth: fix split TX DMA mapping lengths
2026-06-29 8:06 [PATCH net] net: sgi: ioc3-eth: fix split TX DMA mapping lengths raoxu
@ 2026-06-29 17:16 ` Thomas Bogendoerfer
0 siblings, 0 replies; 2+ messages in thread
From: Thomas Bogendoerfer @ 2026-06-29 17:16 UTC (permalink / raw)
To: raoxu
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-mips, netdev,
linux-kernel, stable
On Mon, Jun 29, 2026 at 04:06:23PM +0800, raoxu wrote:
> From: Xu Rao <raoxu@uniontech.com>
>
> When a linear skb crosses a 16 KiB boundary, ioc3_start_xmit()
> splits it into two buffers of lengths s1 and s2. The descriptor
> advertises those lengths through B1CNT and B2CNT.
>
> The first buffer is mapped with s1, but the second buffer is also
> mapped with s1 even though the device is told to fetch s2 bytes from
> it. When the lengths differ, the DMA mapping does not cover the same
> region as the second descriptor buffer, which can result in incorrect
> cache maintenance or a DMA fault on implementations that enforce the
> mapped range.
>
> There is a separate mismatch in the error path. If mapping the second
> buffer fails, only d1 needs to be unmapped. d1 was mapped for s1 bytes,
> but the driver unmaps it using the full packet length. Streaming DMA
> mappings must be unmapped with the same size used for the corresponding
> map operation.
>
> Map the second buffer with s2 and unmap the first buffer with s1 when
> the second mapping fails.
>
> Fixes: ed870f6a7aa2 ("net: sgi: ioc3-eth: use dma-direct for dma allocations")
> Cc: stable@vger.kernel.org
> Signed-off-by: Xu Rao <raoxu@uniontech.com>
> ---
> drivers/net/ethernet/sgi/ioc3-eth.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
> index 3973106..261f2d3 100644
> --- a/drivers/net/ethernet/sgi/ioc3-eth.c
> +++ b/drivers/net/ethernet/sgi/ioc3-eth.c
> @@ -1061,9 +1061,9 @@ static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
> d1 = dma_map_single(ip->dma_dev, skb->data, s1, DMA_TO_DEVICE);
> if (dma_mapping_error(ip->dma_dev, d1))
> goto drop_packet;
> - d2 = dma_map_single(ip->dma_dev, (void *)b2, s1, DMA_TO_DEVICE);
> + d2 = dma_map_single(ip->dma_dev, (void *)b2, s2, DMA_TO_DEVICE);
> if (dma_mapping_error(ip->dma_dev, d2)) {
> - dma_unmap_single(ip->dma_dev, d1, len, DMA_TO_DEVICE);
> + dma_unmap_single(ip->dma_dev, d1, s1, DMA_TO_DEVICE);
> goto drop_packet;
> }
> desc->p1 = cpu_to_be64(ioc3_map(d1, PCI64_ATTR_PREF));
> --
> 2.47.3
Reviewed-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-06-29 17:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-29 8:06 [PATCH net] net: sgi: ioc3-eth: fix split TX DMA mapping lengths raoxu
2026-06-29 17:16 ` Thomas Bogendoerfer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox