Commit 8be03286 authored by Wenbo Li's avatar Wenbo Li Committed by Wen Zhiwei
Browse files

virtio_net: Fix mismatched buf address when unmapping for small packets

stable inclusion
from stable-v6.6.54
commit e9e3424d6d4b34d2c15071c71ec249a9f78ff341
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAZ3K2

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e9e3424d6d4b34d2c15071c71ec249a9f78ff341



--------------------------------

[ Upstream commit c11a49d58ad229a1be1ebe08a2b68fedf83db6c8 ]

Currently, the virtio-net driver will perform a pre-dma-mapping for
small or mergeable RX buffer. But for small packets, a mismatched address
without VIRTNET_RX_PAD and xdp_headroom is used for unmapping.

That will result in unsynchronized buffers when SWIOTLB is enabled, for
example, when running as a TDX guest.

This patch unifies the address passed to the virtio core as the address of
the virtnet header and fixes the mismatched buffer address.

Changes from v2: unify the buf that passed to the virtio core in small
and merge mode.
Changes from v1: Use ctx to get xdp_headroom.

Fixes: 295525e2 ("virtio_net: merge dma operations when filling mergeable buffers")
Signed-off-by: default avatarWenbo Li <liwenbo.martin@bytedance.com>
Signed-off-by: default avatarJiahui Cen <cenjiahui@bytedance.com>
Signed-off-by: default avatarYing Fang <fangying.tommy@bytedance.com>
Reviewed-by: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
Link: https://patch.msgid.link/20240919081351.51772-1-liwenbo.martin@bytedance.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarWen Zhiwei <wenzhiwei@kylinos.cn>
parent be4dd44e
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1269,6 +1269,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
	struct page *page = virt_to_head_page(buf);
	struct sk_buff *skb;

	/* We passed the address of virtnet header to virtio-core,
	 * so truncate the padding.
	 */
	buf -= VIRTNET_RX_PAD + xdp_headroom;

	len -= vi->hdr_len;
	u64_stats_add(&stats->bytes, len);

@@ -1859,8 +1864,9 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
	if (unlikely(!buf))
		return -ENOMEM;

	virtnet_rq_init_one_sg(rq, buf + VIRTNET_RX_PAD + xdp_headroom,
			       vi->hdr_len + GOOD_PACKET_LEN);
	buf += VIRTNET_RX_PAD + xdp_headroom;

	virtnet_rq_init_one_sg(rq, buf, vi->hdr_len + GOOD_PACKET_LEN);

	err = virtqueue_add_inbuf_ctx(rq->vq, rq->sg, 1, buf, ctx, gfp);
	if (err < 0) {