Re: [PATCH net] net: sgi: ioc3-eth: fix split TX DMA mapping lengths

From: Thomas Bogendoerfer

Date: Mon Jun 29 2026 - 13:40:35 EST


On Mon, Jun 29, 2026 at 04:06:23PM +0800, raoxu wrote:
> From: Xu Rao <raoxu@xxxxxxxxxxxxx>
>
> 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@xxxxxxxxxxxxxxx
> Signed-off-by: Xu Rao <raoxu@xxxxxxxxxxxxx>
> ---
> 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@xxxxxxxxxxxxxxxx>

--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]