1 Star 0 Fork 126

ganqx/src-qemu

forked from src-openEuler/qemu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
virtio-net-drop-too-short-packets-early.patch 3.03 KB
一键复制 编辑 原始数据 按行查看 历史
Jiabo Feng 提交于 2024-11-07 09:21 . QEMU update to version 8.2.0-21:
From 5651eb5cfd3a49506be4be97f8def3fed713c641 Mon Sep 17 00:00:00 2001
From: Alexey Dobriyan <adobriyan@yandex-team.ru>
Date: Tue, 30 Apr 2024 13:53:33 +0300
Subject: [PATCH] virtio-net: drop too short packets early
Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
creates small packet (1 segment, len = 10 == n->guest_hdr_len),
then destroys queue.
"if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
zero length/zero segment packet as there is nothing after guest header.
qemu_sendv_packet_async() tries to send it.
slirp discards it because it is smaller than Ethernet header,
but returns 0 because tx hooks are supposed to return total length of data.
0 is propagated upwards and is interpreted as "packet has been sent"
which is terrible because queue is being destroyed, nobody is waiting for TX
to complete and assert it triggered.
Fix is discard such empty packets instead of sending them.
Length 1 packets will go via different codepath:
virtqueue_push(q->tx_vq, elem, 0);
virtio_notify(vdev, q->tx_vq);
g_free(elem);
and aren't problematic.
Signed-off-by: Alexey Dobriyan <adobriyan@yandex-team.ru>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 2c3e4e2de699cd4d9f6c71f30a22d8f125cd6164)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/net/virtio-net.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 432c433540..b17137a686 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2732,18 +2732,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
out_sg = elem->out_sg;
if (out_num < 1) {
virtio_error(vdev, "virtio-net header not in first element");
- virtqueue_detach_element(q->tx_vq, elem, 0);
- g_free(elem);
- return -EINVAL;
+ goto detach;
}
if (n->has_vnet_hdr) {
if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) <
n->guest_hdr_len) {
virtio_error(vdev, "virtio-net header incorrect");
- virtqueue_detach_element(q->tx_vq, elem, 0);
- g_free(elem);
- return -EINVAL;
+ goto detach;
}
if (n->needs_vnet_hdr_swap) {
virtio_net_hdr_swap(vdev, (void *) &vhdr);
@@ -2774,6 +2770,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
n->guest_hdr_len, -1);
out_num = sg_num;
out_sg = sg;
+
+ if (out_num < 1) {
+ virtio_error(vdev, "virtio-net nothing to send");
+ goto detach;
+ }
}
ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
@@ -2794,6 +2795,11 @@ drop:
}
}
return num_packets;
+
+detach:
+ virtqueue_detach_element(q->tx_vq, elem, 0);
+ g_free(elem);
+ return -EINVAL;
}
static void virtio_net_tx_timer(void *opaque);
--
2.41.0.windows.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ganqx/src-qemu.git
git@gitee.com:ganqx/src-qemu.git
ganqx
src-qemu
src-qemu
master

搜索帮助