* [PULL 00/15] Net patches
@ 2022-03-08 13:34 Jason Wang
2022-03-09 20:00 ` Peter Maydell
0 siblings, 1 reply; 22+ messages in thread
From: Jason Wang @ 2022-03-08 13:34 UTC (permalink / raw)
To: qemu-devel, peter.maydell; +Cc: Jason Wang
The following changes since commit f45cc81911adc7726e8a2801986b6998b91b816e:
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20220307' into staging (2022-03-08 09:06:57 +0000)
are available in the git repository at:
https://github.com/jasowang/qemu.git tags/net-pull-request
for you to fetch changes up to a10dd1e279fc56cebc7e738925e0db85d0cea089:
vdpa: Expose VHOST_F_LOG_ALL on SVQ (2022-03-08 21:18:41 +0800)
----------------------------------------------------------------
----------------------------------------------------------------
Eugenio Pérez (14):
vhost: Add VhostShadowVirtqueue
vhost: Add Shadow VirtQueue kick forwarding capabilities
vhost: Add Shadow VirtQueue call forwarding capabilities
vhost: Add vhost_svq_valid_features to shadow vq
virtio: Add vhost_svq_get_vring_addr
vdpa: adapt vhost_ops callbacks to svq
vhost: Shadow virtqueue buffers forwarding
util: Add iova_tree_alloc_map
util: add iova_tree_find_iova
vhost: Add VhostIOVATree
vdpa: Add custom IOTLB translations to SVQ
vdpa: Adapt vhost_vdpa_get_vring_base to SVQ
vdpa: Never set log_base addr if SVQ is enabled
vdpa: Expose VHOST_F_LOG_ALL on SVQ
Jason Wang (1):
virtio-net: fix map leaking on error during receive
hw/net/virtio-net.c | 1 +
hw/virtio/meson.build | 2 +-
hw/virtio/vhost-iova-tree.c | 110 +++++++
hw/virtio/vhost-iova-tree.h | 27 ++
hw/virtio/vhost-shadow-virtqueue.c | 637 +++++++++++++++++++++++++++++++++++++
hw/virtio/vhost-shadow-virtqueue.h | 87 +++++
hw/virtio/vhost-vdpa.c | 525 +++++++++++++++++++++++++++++-
include/hw/virtio/vhost-vdpa.h | 8 +
include/qemu/iova-tree.h | 38 ++-
util/iova-tree.c | 169 ++++++++++
10 files changed, 1587 insertions(+), 17 deletions(-)
create mode 100644 hw/virtio/vhost-iova-tree.c
create mode 100644 hw/virtio/vhost-iova-tree.h
create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PULL 00/15] Net patches
2022-03-08 13:34 Jason Wang
@ 2022-03-09 20:00 ` Peter Maydell
2022-03-10 2:39 ` Jason Wang
0 siblings, 1 reply; 22+ messages in thread
From: Peter Maydell @ 2022-03-09 20:00 UTC (permalink / raw)
To: Jason Wang; +Cc: qemu-devel
On Tue, 8 Mar 2022 at 13:35, Jason Wang <jasowang@redhat.com> wrote:
>
> The following changes since commit f45cc81911adc7726e8a2801986b6998b91b816e:
>
> Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20220307' into staging (2022-03-08 09:06:57 +0000)
>
> are available in the git repository at:
>
> https://github.com/jasowang/qemu.git tags/net-pull-request
>
> for you to fetch changes up to a10dd1e279fc56cebc7e738925e0db85d0cea089:
>
> vdpa: Expose VHOST_F_LOG_ALL on SVQ (2022-03-08 21:18:41 +0800)
>
> ----------------------------------------------------------------
>
> ----------------------------------------------------------------
Fails to build:
../../hw/virtio/vhost-shadow-virtqueue.c: In function 'vhost_svq_start':
../../hw/virtio/vhost-shadow-virtqueue.c:537:23: error: implicit
declaration of function 'qemu_memalign'
[-Werror=implicit-function-declaration]
537 | svq->vring.desc = qemu_memalign(qemu_real_host_page_size,
driver_size);
| ^~~~~~~~~~~~~
../../hw/virtio/vhost-shadow-virtqueue.c:537:23: error: nested extern
declaration of 'qemu_memalign' [-Werror=nested-externs]
../../hw/virtio/vhost-shadow-virtqueue.c:537:21: error: assignment to
'vring_desc_t *' {aka 'struct vring_desc *'} from 'int' makes pointer
from i
nteger without a cast [-Werror=int-conversion]
537 | svq->vring.desc = qemu_memalign(qemu_real_host_page_size,
driver_size);
| ^
../../hw/virtio/vhost-shadow-virtqueue.c:541:21: error: assignment to
'vring_used_t *' {aka 'struct vring_used *'} from 'int' makes pointer
from i
nteger without a cast [-Werror=int-conversion]
541 | svq->vring.used = qemu_memalign(qemu_real_host_page_size,
device_size);
| ^
../../hw/virtio/vhost-shadow-virtqueue.c: In function 'vhost_svq_stop':
../../hw/virtio/vhost-shadow-virtqueue.c:579:5: error: implicit
declaration of function 'qemu_vfree'
[-Werror=implicit-function-declaration]
579 | qemu_vfree(svq->vring.desc);
| ^~~~~~~~~~
../../hw/virtio/vhost-shadow-virtqueue.c:579:5: error: nested extern
declaration of 'qemu_vfree' [-Werror=nested-externs]
qemu_memalign/qemu_vfree have just moved to their own header file;
you need to rebase and add #include <qemu/memalign.h> in the
appropriate files.
thanks
-- PMM
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PULL 00/15] Net patches
2022-03-09 20:00 ` Peter Maydell
@ 2022-03-10 2:39 ` Jason Wang
0 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2022-03-10 2:39 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2568 bytes --]
On Thu, Mar 10, 2022 at 4:01 AM Peter Maydell <peter.maydell@linaro.org>
wrote:
> On Tue, 8 Mar 2022 at 13:35, Jason Wang <jasowang@redhat.com> wrote:
> >
> > The following changes since commit
> f45cc81911adc7726e8a2801986b6998b91b816e:
> >
> > Merge remote-tracking branch
> 'remotes/cschoenebeck/tags/pull-9p-20220307' into staging (2022-03-08
> 09:06:57 +0000)
> >
> > are available in the git repository at:
> >
> > https://github.com/jasowang/qemu.git tags/net-pull-request
> >
> > for you to fetch changes up to a10dd1e279fc56cebc7e738925e0db85d0cea089:
> >
> > vdpa: Expose VHOST_F_LOG_ALL on SVQ (2022-03-08 21:18:41 +0800)
> >
> > ----------------------------------------------------------------
> >
> > ----------------------------------------------------------------
>
> Fails to build:
>
> ../../hw/virtio/vhost-shadow-virtqueue.c: In function 'vhost_svq_start':
> ../../hw/virtio/vhost-shadow-virtqueue.c:537:23: error: implicit
> declaration of function 'qemu_memalign'
> [-Werror=implicit-function-declaration]
> 537 | svq->vring.desc = qemu_memalign(qemu_real_host_page_size,
> driver_size);
> | ^~~~~~~~~~~~~
> ../../hw/virtio/vhost-shadow-virtqueue.c:537:23: error: nested extern
> declaration of 'qemu_memalign' [-Werror=nested-externs]
> ../../hw/virtio/vhost-shadow-virtqueue.c:537:21: error: assignment to
> 'vring_desc_t *' {aka 'struct vring_desc *'} from 'int' makes pointer
> from i
> nteger without a cast [-Werror=int-conversion]
> 537 | svq->vring.desc = qemu_memalign(qemu_real_host_page_size,
> driver_size);
> | ^
> ../../hw/virtio/vhost-shadow-virtqueue.c:541:21: error: assignment to
> 'vring_used_t *' {aka 'struct vring_used *'} from 'int' makes pointer
> from i
> nteger without a cast [-Werror=int-conversion]
> 541 | svq->vring.used = qemu_memalign(qemu_real_host_page_size,
> device_size);
> | ^
> ../../hw/virtio/vhost-shadow-virtqueue.c: In function 'vhost_svq_stop':
> ../../hw/virtio/vhost-shadow-virtqueue.c:579:5: error: implicit
> declaration of function 'qemu_vfree'
> [-Werror=implicit-function-declaration]
> 579 | qemu_vfree(svq->vring.desc);
> | ^~~~~~~~~~
> ../../hw/virtio/vhost-shadow-virtqueue.c:579:5: error: nested extern
> declaration of 'qemu_vfree' [-Werror=nested-externs]
>
>
> qemu_memalign/qemu_vfree have just moved to their own header file;
> you need to rebase and add #include <qemu/memalign.h> in the
> appropriate files.
>
Yes, V2 is sent.
Thanks
>
> thanks
> -- PMM
>
>
[-- Attachment #2: Type: text/html, Size: 3636 bytes --]
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PULL 00/15] Net patches
@ 2023-07-07 9:06 Jason Wang
2023-07-07 19:20 ` Richard Henderson
0 siblings, 1 reply; 22+ messages in thread
From: Jason Wang @ 2023-07-07 9:06 UTC (permalink / raw)
To: qemu-devel, richard.henderson, peter.maydell; +Cc: Jason Wang
The following changes since commit 97c81ef4b8e203d9620fd46e7eb77004563e3675:
Merge tag 'pull-9p-20230706' of https://github.com/cschoenebeck/qemu into staging (2023-07-06 18:19:42 +0100)
are available in the git repository at:
https://github.com/jasowang/qemu.git tags/net-pull-request
for you to fetch changes up to da9f7f7769e8e65f6423095e978f9a375e33515c:
igb: Remove obsolete workaround for Windows (2023-07-07 16:35:12 +0800)
----------------------------------------------------------------
----------------------------------------------------------------
Akihiko Odaki (2):
e1000e: Add ICR clearing by corresponding IMS bit
igb: Remove obsolete workaround for Windows
Bin Meng (9):
hw/net: e1000: Remove the logic of padding short frames in the receive path
hw/net: vmxnet3: Remove the logic of padding short frames in the receive path
hw/net: i82596: Remove the logic of padding short frames in the receive path
hw/net: ne2000: Remove the logic of padding short frames in the receive path
hw/net: pcnet: Remove the logic of padding short frames in the receive path
hw/net: rtl8139: Remove the logic of padding short frames in the receive path
hw/net: sungem: Remove the logic of padding short frames in the receive path
hw/net: sunhme: Remove the logic of padding short frames in the receive path
hw/net: ftgmac100: Drop the small packet check in the receive path
Laurent Vivier (4):
virtio-net: correctly report maximum tx_queue_size value
net: socket: prepare to cleanup net_init_socket()
net: socket: move fd type checking to its own function
net: socket: remove net_init_socket()
hw/net/e1000.c | 11 +----------
hw/net/e1000e_core.c | 38 +++++++++++++++++++++++++++++++------
hw/net/ftgmac100.c | 8 --------
hw/net/i82596.c | 18 ------------------
hw/net/igb_core.c | 7 +------
hw/net/ne2000.c | 12 ------------
hw/net/pcnet.c | 9 ---------
hw/net/rtl8139.c | 12 ------------
hw/net/sungem.c | 14 --------------
hw/net/sunhme.c | 11 -----------
hw/net/trace-events | 1 +
hw/net/virtio-net.c | 4 ++--
hw/net/vmxnet3.c | 10 ----------
net/socket.c | 53 +++++++++++++++++++++++++++-------------------------
14 files changed, 65 insertions(+), 143 deletions(-)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PULL 00/15] Net patches
2023-07-07 9:06 Jason Wang
@ 2023-07-07 19:20 ` Richard Henderson
0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2023-07-07 19:20 UTC (permalink / raw)
To: Jason Wang, qemu-devel, peter.maydell
On 7/7/23 10:06, Jason Wang wrote:
> The following changes since commit 97c81ef4b8e203d9620fd46e7eb77004563e3675:
>
> Merge tag 'pull-9p-20230706' ofhttps://github.com/cschoenebeck/qemu into staging (2023-07-06 18:19:42 +0100)
>
> are available in the git repository at:
>
> https://github.com/jasowang/qemu.git tags/net-pull-request
>
> for you to fetch changes up to da9f7f7769e8e65f6423095e978f9a375e33515c:
>
> igb: Remove obsolete workaround for Windows (2023-07-07 16:35:12 +0800)
>
> ----------------------------------------------------------------
>
> ----------------------------------------------------------------
> Akihiko Odaki (2):
> e1000e: Add ICR clearing by corresponding IMS bit
> igb: Remove obsolete workaround for Windows
>
> Bin Meng (9):
> hw/net: e1000: Remove the logic of padding short frames in the receive path
> hw/net: vmxnet3: Remove the logic of padding short frames in the receive path
> hw/net: i82596: Remove the logic of padding short frames in the receive path
> hw/net: ne2000: Remove the logic of padding short frames in the receive path
> hw/net: pcnet: Remove the logic of padding short frames in the receive path
> hw/net: rtl8139: Remove the logic of padding short frames in the receive path
> hw/net: sungem: Remove the logic of padding short frames in the receive path
> hw/net: sunhme: Remove the logic of padding short frames in the receive path
> hw/net: ftgmac100: Drop the small packet check in the receive path
>
> Laurent Vivier (4):
> virtio-net: correctly report maximum tx_queue_size value
> net: socket: prepare to cleanup net_init_socket()
> net: socket: move fd type checking to its own function
> net: socket: remove net_init_socket()
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/8.1 as appropriate.
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PULL 00/15] Net patches
@ 2026-05-29 4:57 Jason Wang
2026-05-29 4:57 ` [PULL 01/15] net/af-xdp: fix type overflow Jason Wang
` (15 more replies)
0 siblings, 16 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Jason Wang
The following changes since commit cbf877d67a812be17a9ce404a589e1bdf722c1f6:
Merge tag 'pbouvier/pr/docs-20260522' of https://gitlab.com/p-b-o/qemu into staging (2026-05-24 07:45:19 -0400)
are available in the Git repository at:
https://github.com/jasowang/qemu.git tags/net-pull-request
for you to fetch changes up to 71d027cfee8553e2ec28efa1ddd7fd0ecbadcc86:
hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match() (2026-05-29 11:54:06 +0800)
----------------------------------------------------------------
-----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEIV1G9IJGaJ7HfzVi7wSWWzmNYhEFAmoZHBQACgkQ7wSWWzmN
YhH7ywf/WZdieTiWCoi1XI2rZ6XCjdJRqTSmp+WENDDQt4tBnXXJ6PxyitFqZh7g
oZnN1+WXgIAO0SZRPbzjspe9mFsXrFkE/7y9XijOF4F/bhbWPA/AL8SICxnjoyaC
nOs1QU2hE7yhOqgnUHweUjNbgpUO8mIgLdSIbKYDgZq1vRFsXy2kkKbeiJkbPCfe
0ILqltFjS5MeCl2fV0WwUquWr7VXEXb0vGPQKAzRbygmbDC+qYRF100cTrSCxnOe
LSW8c1nf2AHZkQJmj2HWc2DUwxynAr8N8jSRPgp4JSC6B2caSQygKHGtKe19Y/Be
u4hm+k5+HB25xkA4czheMcNvefnzoQ==
=JjfR
-----END PGP SIGNATURE-----
----------------------------------------------------------------
Peter Maydell (2):
hw/net/rocker_of_dpa: Check group ID pointers are not NULL
hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match()
Vladimir Sementsov-Ogievskiy (13):
net/af-xdp: fix type overflow
net/tap: net_init_tap_one(): add return value
net/tap: net_init_tap(): drop extra vhostfdname variable
net/tap: net_init_tap(): refactor parameter checking
net/tap: net_init_tap(): common fail label
net/tap: net_init_tap_one() refactor to get vhostfd param
net/tap: net_init_tap_one(): drop model parameter
net: introduce net_parse_fds()
net/tap: move fds parameters handling to separate functions
net/tap: fix vhostfds/vhostfd parameters API
net/tap: net_init_tap(): merge fd=, fds= and helper= cases into one
net/tap: net_init_tap(): relax QEMU hubs check
net/tap: check that user tries to define zero queues
hw/net/rocker/rocker_of_dpa.c | 16 ++-
net/af-xdp.c | 44 ++----
net/tap.c | 324 +++++++++++++++++-------------------------
net/util.c | 55 +++++++
net/util.h | 14 ++
5 files changed, 221 insertions(+), 232 deletions(-)
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PULL 01/15] net/af-xdp: fix type overflow
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 02/15] net/tap: net_init_tap_one(): add return value Jason Wang
` (14 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
In for-loop in net_init_af_xdp, we do nc->queue_index = i,
where is is int64_t for 0 to queues-1, and nc->queue_index is
unsigned int.
Also in parse_socket_fds, g_strv_length() returns guint which
is equivalent to unsigned int.
Let's simply use int type for queues, and update the check
appropriately. It could be unsigned int, but in future commits
we'll share with net/tap.c the common function which will return
number of queues or negative error. So, let's simply use int for
queues-related variables, that simplifies things.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/af-xdp.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/net/af-xdp.c b/net/af-xdp.c
index 14f302ea21..ff1cb30a98 100644
--- a/net/af-xdp.c
+++ b/net/af-xdp.c
@@ -442,14 +442,14 @@ static NetClientInfo net_af_xdp_info = {
};
static int *parse_socket_fds(const char *sock_fds_str,
- int64_t n_expected, Error **errp)
+ int n_expected, Error **errp)
{
gchar **substrings = g_strsplit(sock_fds_str, ":", -1);
- int64_t i, n_sock_fds = g_strv_length(substrings);
+ int i, n_sock_fds = g_strv_length(substrings);
int *sock_fds = NULL;
if (n_sock_fds != n_expected) {
- error_setg(errp, "expected %"PRIi64" socket fds, got %"PRIi64,
+ error_setg(errp, "expected %d socket fds, got %d",
n_expected, n_sock_fds);
goto exit;
}
@@ -484,7 +484,7 @@ int net_init_af_xdp(const Netdev *netdev,
unsigned int ifindex;
uint32_t prog_id = 0;
g_autofree int *sock_fds = NULL;
- int64_t i, queues;
+ int i, queues;
Error *err = NULL;
AFXDPState *s;
bool inhibit;
@@ -496,13 +496,14 @@ int net_init_af_xdp(const Netdev *netdev,
return -1;
}
- queues = opts->has_queues ? opts->queues : 1;
- if (queues < 1) {
+ if (opts->has_queues && (opts->queues < 1 || opts->queues > INT_MAX)) {
error_setg(errp, "invalid number of queues (%" PRIi64 ") for '%s'",
- queues, opts->ifname);
+ opts->queues, opts->ifname);
return -1;
}
+ queues = opts->has_queues ? opts->queues : 1;
+
inhibit = opts->has_inhibit && opts->inhibit;
if (inhibit && !opts->sock_fds && !opts->map_path) {
error_setg(errp, "'inhibit=on' requires 'sock-fds' or 'map-path'");
@@ -537,7 +538,7 @@ int net_init_af_xdp(const Netdev *netdev,
for (i = 0; i < queues; i++) {
nc = qemu_new_net_client(&net_af_xdp_info, peer, "af-xdp", name);
- qemu_set_info_str(nc, "af-xdp%"PRIi64" to %s", i, opts->ifname);
+ qemu_set_info_str(nc, "af-xdp%d to %s", i, opts->ifname);
nc->queue_index = i;
if (!nc0) {
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 02/15] net/tap: net_init_tap_one(): add return value
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
2026-05-29 4:57 ` [PULL 01/15] net/af-xdp: fix type overflow Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 03/15] net/tap: net_init_tap(): drop extra vhostfdname variable Jason Wang
` (13 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Follow common recommendations in include/qapi/error.h of having
a return value together with errp. This allows to avoid error propagation.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 42 +++++++++++++++++-------------------------
1 file changed, 17 insertions(+), 25 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 8d7ab6ba6f..a389aec218 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -703,7 +703,7 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
#define MAX_TAP_QUEUES 1024
-static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
+static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
const char *model, const char *name,
const char *ifname, const char *script,
const char *downscript, const char *vhostfdname,
@@ -783,10 +783,11 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
}
}
- return;
+ return true;
failed:
qemu_del_net_client(&s->nc);
+ return false;
}
static int get_fds(char *str, char *fds[], int max)
@@ -821,7 +822,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
const NetdevTapOptions *tap;
int fd, vnet_hdr = 0, i = 0, queues;
/* for the no-fd, no-helper case */
- Error *err = NULL;
const char *vhostfdname;
char ifname[128];
int ret = 0;
@@ -869,11 +869,9 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
- net_init_tap_one(tap, peer, "tap", name, NULL,
- NULL, NULL,
- vhostfdname, vnet_hdr, fd, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!net_init_tap_one(tap, peer, "tap", name, NULL,
+ NULL, NULL,
+ vhostfdname, vnet_hdr, fd, errp)) {
close(fd);
return -1;
}
@@ -930,12 +928,10 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto free_fail;
}
- net_init_tap_one(tap, peer, "tap", name, ifname,
- NULL, NULL,
- tap->vhostfds ? vhost_fds[i] : NULL,
- vnet_hdr, fd, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!net_init_tap_one(tap, peer, "tap", name, ifname,
+ NULL, NULL,
+ tap->vhostfds ? vhost_fds[i] : NULL,
+ vnet_hdr, fd, errp)) {
ret = -1;
goto free_fail;
}
@@ -975,11 +971,9 @@ free_fail:
return -1;
}
- net_init_tap_one(tap, peer, "bridge", name, ifname,
- NULL, NULL, vhostfdname,
- vnet_hdr, fd, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!net_init_tap_one(tap, peer, "bridge", name, ifname,
+ NULL, NULL, vhostfdname,
+ vnet_hdr, fd, errp)) {
close(fd);
return -1;
}
@@ -1015,12 +1009,10 @@ free_fail:
}
}
- net_init_tap_one(tap, peer, "tap", name, ifname,
- i >= 1 ? NULL : script,
- i >= 1 ? NULL : downscript,
- vhostfdname, vnet_hdr, fd, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!net_init_tap_one(tap, peer, "tap", name, ifname,
+ i >= 1 ? NULL : script,
+ i >= 1 ? NULL : downscript,
+ vhostfdname, vnet_hdr, fd, errp)) {
close(fd);
return -1;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 03/15] net/tap: net_init_tap(): drop extra vhostfdname variable
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
2026-05-29 4:57 ` [PULL 01/15] net/af-xdp: fix type overflow Jason Wang
2026-05-29 4:57 ` [PULL 02/15] net/tap: net_init_tap_one(): add return value Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 04/15] net/tap: net_init_tap(): refactor parameter checking Jason Wang
` (12 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index a389aec218..55b8b33ea8 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -822,14 +822,12 @@ int net_init_tap(const Netdev *netdev, const char *name,
const NetdevTapOptions *tap;
int fd, vnet_hdr = 0, i = 0, queues;
/* for the no-fd, no-helper case */
- const char *vhostfdname;
char ifname[128];
int ret = 0;
assert(netdev->type == NET_CLIENT_DRIVER_TAP);
tap = &netdev->u.tap;
queues = tap->has_queues ? tap->queues : 1;
- vhostfdname = tap->vhostfd;
/* QEMU hubs do not support multiqueue tap, in this case peer is set.
* For -netdev, peer is always NULL. */
@@ -871,7 +869,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, "tap", name, NULL,
NULL, NULL,
- vhostfdname, vnet_hdr, fd, errp)) {
+ tap->vhostfd, vnet_hdr, fd, errp)) {
close(fd);
return -1;
}
@@ -972,7 +970,7 @@ free_fail:
}
if (!net_init_tap_one(tap, peer, "bridge", name, ifname,
- NULL, NULL, vhostfdname,
+ NULL, NULL, tap->vhostfd,
vnet_hdr, fd, errp)) {
close(fd);
return -1;
@@ -1012,7 +1010,7 @@ free_fail:
if (!net_init_tap_one(tap, peer, "tap", name, ifname,
i >= 1 ? NULL : script,
i >= 1 ? NULL : downscript,
- vhostfdname, vnet_hdr, fd, errp)) {
+ tap->vhostfd, vnet_hdr, fd, errp)) {
close(fd);
return -1;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 04/15] net/tap: net_init_tap(): refactor parameter checking
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (2 preceding siblings ...)
2026-05-29 4:57 ` [PULL 03/15] net/tap: net_init_tap(): drop extra vhostfdname variable Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 05/15] net/tap: net_init_tap(): common fail label Jason Wang
` (11 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Move checks to the top of the function to simplify further
refactoring. Merge duplicated checks.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 53 +++++++++++++++++++++++------------------------------
1 file changed, 23 insertions(+), 30 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 55b8b33ea8..331a779585 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -841,16 +841,30 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
- if (tap->fd) {
- if (tap->ifname || tap->script || tap->downscript ||
- tap->has_vnet_hdr || tap->helper || tap->has_queues ||
- tap->fds || tap->vhostfds) {
- error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
- "helper=, queues=, fds=, and vhostfds= "
- "are invalid with fd=");
- return -1;
- }
+ if (tap->has_queues + !!tap->helper + !!tap->fds + !!tap->fd > 1) {
+ error_setg(errp, "queues=, helper=, fds= and fd= are mutual exclusive");
+ return -1;
+ }
+ if ((tap->fd || tap->fds || tap->helper) &&
+ (tap->ifname || tap->script || tap->downscript ||
+ tap->has_vnet_hdr)) {
+ error_setg(errp, "ifname=, script=, downscript=, vnet_hdr= "
+ "are invalid with fd=/fds=/helper=");
+ return -1;
+ }
+
+ if (tap->vhostfds && !tap->fds) {
+ error_setg(errp, "vhostfds= is invalid if fds= wasn't specified");
+ return -1;
+ }
+
+ if (tap->vhostfd && tap->fds) {
+ error_setg(errp, "vhostfd= is invalid with fds=");
+ return -1;
+ }
+
+ if (tap->fd) {
fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
if (fd == -1) {
return -1;
@@ -878,15 +892,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
char **vhost_fds;
int nfds = 0, nvhosts = 0;
- if (tap->ifname || tap->script || tap->downscript ||
- tap->has_vnet_hdr || tap->helper || tap->has_queues ||
- tap->vhostfd) {
- error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
- "helper=, queues=, and vhostfd= "
- "are invalid with fds=");
- return -1;
- }
-
fds = g_new0(char *, MAX_TAP_QUEUES);
vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
@@ -946,13 +951,6 @@ free_fail:
g_free(vhost_fds);
return ret;
} else if (tap->helper) {
- if (tap->ifname || tap->script || tap->downscript ||
- tap->has_vnet_hdr || tap->has_queues || tap->vhostfds) {
- error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
- "queues=, and vhostfds= are invalid with helper=");
- return -1;
- }
-
fd = net_bridge_run_helper(tap->helper,
tap->br ?: DEFAULT_BRIDGE_INTERFACE,
errp);
@@ -981,11 +979,6 @@ free_fail:
g_autofree char *downscript =
tap_parse_script(tap->downscript, DEFAULT_NETWORK_DOWN_SCRIPT);
- if (tap->vhostfds) {
- error_setg(errp, "vhostfds= is invalid if fds= wasn't specified");
- return -1;
- }
-
if (tap->ifname) {
pstrcpy(ifname, sizeof ifname, tap->ifname);
} else {
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 05/15] net/tap: net_init_tap(): common fail label
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (3 preceding siblings ...)
2026-05-29 4:57 ` [PULL 04/15] net/tap: net_init_tap(): refactor parameter checking Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 06/15] net/tap: net_init_tap_one() refactor to get vhostfd param Jason Wang
` (10 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Add common failure label. This:
- simplifies failure paths in the function
- get rid of unusual free_fail: in the middle of the function
- simplify further refactoring
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 84 ++++++++++++++++++++++++-------------------------------
1 file changed, 37 insertions(+), 47 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 331a779585..2eb8a2caeb 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -820,10 +820,12 @@ int net_init_tap(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
const NetdevTapOptions *tap;
- int fd, vnet_hdr = 0, i = 0, queues;
+ int fd = -1, vnet_hdr = 0, i = 0, queues;
/* for the no-fd, no-helper case */
char ifname[128];
- int ret = 0;
+ char **fds = NULL, **vhost_fds = NULL;
+ int nfds = 0, nvhosts = 0;
+
assert(netdev->type == NET_CLIENT_DRIVER_TAP);
tap = &netdev->u.tap;
@@ -867,31 +869,24 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (tap->fd) {
fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
if (fd == -1) {
- return -1;
+ goto fail;
}
if (!qemu_set_blocking(fd, false, errp)) {
- close(fd);
- return -1;
+ goto fail;
}
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
if (vnet_hdr < 0) {
- close(fd);
- return -1;
+ goto fail;
}
if (!net_init_tap_one(tap, peer, "tap", name, NULL,
NULL, NULL,
tap->vhostfd, vnet_hdr, fd, errp)) {
- close(fd);
- return -1;
+ goto fail;
}
} else if (tap->fds) {
- char **fds;
- char **vhost_fds;
- int nfds = 0, nvhosts = 0;
-
fds = g_new0(char *, MAX_TAP_QUEUES);
vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
@@ -901,77 +896,58 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (nfds != nvhosts) {
error_setg(errp, "The number of fds passed does not match "
"the number of vhostfds passed");
- ret = -1;
- goto free_fail;
+ goto fail;
}
}
for (i = 0; i < nfds; i++) {
fd = monitor_fd_param(monitor_cur(), fds[i], errp);
if (fd == -1) {
- ret = -1;
- goto free_fail;
+ goto fail;
}
if (!qemu_set_blocking(fd, false, errp)) {
- ret = -1;
- goto free_fail;
+ goto fail;
}
if (i == 0) {
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
if (vnet_hdr < 0) {
- ret = -1;
- goto free_fail;
+ goto fail;
}
} else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
error_setg(errp,
"vnet_hdr not consistent across given tap fds");
- ret = -1;
- goto free_fail;
+ goto fail;
}
if (!net_init_tap_one(tap, peer, "tap", name, ifname,
NULL, NULL,
tap->vhostfds ? vhost_fds[i] : NULL,
vnet_hdr, fd, errp)) {
- ret = -1;
- goto free_fail;
+ goto fail;
}
}
-
-free_fail:
- for (i = 0; i < nvhosts; i++) {
- g_free(vhost_fds[i]);
- }
- for (i = 0; i < nfds; i++) {
- g_free(fds[i]);
- }
- g_free(fds);
- g_free(vhost_fds);
- return ret;
} else if (tap->helper) {
fd = net_bridge_run_helper(tap->helper,
tap->br ?: DEFAULT_BRIDGE_INTERFACE,
errp);
if (fd == -1) {
- return -1;
+ goto fail;
}
if (!qemu_set_blocking(fd, false, errp)) {
- return -1;
+ goto fail;
}
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
if (vnet_hdr < 0) {
- close(fd);
- return -1;
+ goto fail;
}
if (!net_init_tap_one(tap, peer, "bridge", name, ifname,
NULL, NULL, tap->vhostfd,
vnet_hdr, fd, errp)) {
- close(fd);
- return -1;
+ goto fail;
}
} else {
g_autofree char *script =
@@ -989,14 +965,13 @@ free_fail:
fd = net_tap_init(tap, &vnet_hdr, i >= 1 ? NULL : script,
ifname, sizeof ifname, queues > 1, errp);
if (fd == -1) {
- return -1;
+ goto fail;
}
if (queues > 1 && i == 0 && !tap->ifname) {
if (tap_fd_get_ifname(fd, ifname)) {
error_setg(errp, "Fail to get ifname");
- close(fd);
- return -1;
+ goto fail;
}
}
@@ -1004,13 +979,28 @@ free_fail:
i >= 1 ? NULL : script,
i >= 1 ? NULL : downscript,
tap->vhostfd, vnet_hdr, fd, errp)) {
- close(fd);
- return -1;
+ goto fail;
}
}
}
return 0;
+
+fail:
+ close(fd);
+ if (vhost_fds) {
+ for (i = 0; i < nvhosts; i++) {
+ g_free(vhost_fds[i]);
+ }
+ g_free(vhost_fds);
+ }
+ if (fds) {
+ for (i = 0; i < nfds; i++) {
+ g_free(fds[i]);
+ }
+ g_free(fds);
+ }
+ return -1;
}
int tap_enable(NetClientState *nc)
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 06/15] net/tap: net_init_tap_one() refactor to get vhostfd param
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (4 preceding siblings ...)
2026-05-29 4:57 ` [PULL 05/15] net/tap: net_init_tap(): common fail label Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 07/15] net/tap: net_init_tap_one(): drop model parameter Jason Wang
` (9 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Get vhostfd instead of vhostfdname:
- more symmetry with fd param
- prepare to further changes
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 48 +++++++++++++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 2eb8a2caeb..2c5f8e73fe 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -706,11 +706,10 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
const char *model, const char *name,
const char *ifname, const char *script,
- const char *downscript, const char *vhostfdname,
+ const char *downscript, int vhostfd,
int vnet_hdr, int fd, Error **errp)
{
TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
- int vhostfd;
bool sndbuf_required = tap->has_sndbuf;
int sndbuf =
(tap->has_sndbuf && tap->sndbuf) ? MIN(tap->sndbuf, INT_MAX) : INT_MAX;
@@ -738,7 +737,7 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
}
if (tap->has_vhost ? tap->vhost :
- vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
+ (vhostfd != -1) || (tap->has_vhostforce && tap->vhostforce)) {
VhostNetOptions options;
options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
@@ -749,15 +748,7 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
options.busyloop_timeout = 0;
}
- if (vhostfdname) {
- vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, errp);
- if (vhostfd == -1) {
- goto failed;
- }
- if (!qemu_set_blocking(vhostfd, false, errp)) {
- goto failed;
- }
- } else {
+ if (vhostfd == -1) {
vhostfd = open("/dev/vhost-net", O_RDWR);
if (vhostfd < 0) {
error_setg_file_open(errp, errno, "/dev/vhost-net");
@@ -820,7 +811,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
const NetdevTapOptions *tap;
- int fd = -1, vnet_hdr = 0, i = 0, queues;
+ int fd = -1, vhostfd = -1, vnet_hdr = 0, i = 0, queues;
/* for the no-fd, no-helper case */
char ifname[128];
char **fds = NULL, **vhost_fds = NULL;
@@ -866,6 +857,17 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
+ if (tap->vhostfd) {
+ vhostfd = monitor_fd_param(monitor_cur(), tap->vhostfd, errp);
+ if (vhostfd == -1) {
+ return -1;
+ }
+
+ if (!qemu_set_blocking(vhostfd, false, errp)) {
+ goto fail;
+ }
+ }
+
if (tap->fd) {
fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
if (fd == -1) {
@@ -883,7 +885,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, "tap", name, NULL,
NULL, NULL,
- tap->vhostfd, vnet_hdr, fd, errp)) {
+ vhostfd, vnet_hdr, fd, errp)) {
goto fail;
}
} else if (tap->fds) {
@@ -910,6 +912,17 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
+ if (tap->vhostfds) {
+ vhostfd = monitor_fd_param(monitor_cur(), vhost_fds[i], errp);
+ if (vhostfd == -1) {
+ goto fail;
+ }
+
+ if (!qemu_set_blocking(vhostfd, false, errp)) {
+ goto fail;
+ }
+ }
+
if (i == 0) {
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
if (vnet_hdr < 0) {
@@ -923,7 +936,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, "tap", name, ifname,
NULL, NULL,
- tap->vhostfds ? vhost_fds[i] : NULL,
+ vhostfd,
vnet_hdr, fd, errp)) {
goto fail;
}
@@ -945,7 +958,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
}
if (!net_init_tap_one(tap, peer, "bridge", name, ifname,
- NULL, NULL, tap->vhostfd,
+ NULL, NULL, vhostfd,
vnet_hdr, fd, errp)) {
goto fail;
}
@@ -978,7 +991,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, "tap", name, ifname,
i >= 1 ? NULL : script,
i >= 1 ? NULL : downscript,
- tap->vhostfd, vnet_hdr, fd, errp)) {
+ vhostfd, vnet_hdr, fd, errp)) {
goto fail;
}
}
@@ -988,6 +1001,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
fail:
close(fd);
+ close(vhostfd);
if (vhost_fds) {
for (i = 0; i < nvhosts; i++) {
g_free(vhost_fds[i]);
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 07/15] net/tap: net_init_tap_one(): drop model parameter
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (5 preceding siblings ...)
2026-05-29 4:57 ` [PULL 06/15] net/tap: net_init_tap_one() refactor to get vhostfd param Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 08/15] net: introduce net_parse_fds() Jason Wang
` (8 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
It could be simply derived from tap parameter. And this change
simplifies further refactoring.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 2c5f8e73fe..db3fe380a4 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -704,12 +704,13 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
#define MAX_TAP_QUEUES 1024
static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
- const char *model, const char *name,
+ const char *name,
const char *ifname, const char *script,
const char *downscript, int vhostfd,
int vnet_hdr, int fd, Error **errp)
{
- TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
+ TAPState *s = net_tap_fd_init(peer, tap->helper ? "bridge" : "tap",
+ name, fd, vnet_hdr);
bool sndbuf_required = tap->has_sndbuf;
int sndbuf =
(tap->has_sndbuf && tap->sndbuf) ? MIN(tap->sndbuf, INT_MAX) : INT_MAX;
@@ -883,7 +884,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
- if (!net_init_tap_one(tap, peer, "tap", name, NULL,
+ if (!net_init_tap_one(tap, peer, name, NULL,
NULL, NULL,
vhostfd, vnet_hdr, fd, errp)) {
goto fail;
@@ -934,7 +935,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
- if (!net_init_tap_one(tap, peer, "tap", name, ifname,
+ if (!net_init_tap_one(tap, peer, name, ifname,
NULL, NULL,
vhostfd,
vnet_hdr, fd, errp)) {
@@ -957,7 +958,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
- if (!net_init_tap_one(tap, peer, "bridge", name, ifname,
+ if (!net_init_tap_one(tap, peer, name, ifname,
NULL, NULL, vhostfd,
vnet_hdr, fd, errp)) {
goto fail;
@@ -988,7 +989,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
}
}
- if (!net_init_tap_one(tap, peer, "tap", name, ifname,
+ if (!net_init_tap_one(tap, peer, name, ifname,
i >= 1 ? NULL : script,
i >= 1 ? NULL : downscript,
vhostfd, vnet_hdr, fd, errp)) {
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 08/15] net: introduce net_parse_fds()
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (6 preceding siblings ...)
2026-05-29 4:57 ` [PULL 07/15] net/tap: net_init_tap_one(): drop model parameter Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 09/15] net/tap: move fds parameters handling to separate functions Jason Wang
` (7 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Add common net_parse_fds() and net_free_fds() helpers and use them
in tap.c and af-xdp.c.
Choose returning queues instead of fds, because we'll have derived
helper in net/tap, which will be able to return fds=NULL and non-zero
queues on success. That's also why we move to INT_MAX for queues, to
support negative return value for net_parse_fds() (for failure paths).
Note that redundant restriction of MAX_TAP_QUEUES is dropped for tap.c
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/af-xdp.c | 33 ++-----------------
net/tap.c | 92 +++++++++++-----------------------------------------
net/util.c | 50 ++++++++++++++++++++++++++++
net/util.h | 14 ++++++++
4 files changed, 85 insertions(+), 104 deletions(-)
diff --git a/net/af-xdp.c b/net/af-xdp.c
index ff1cb30a98..1ffd6363a8 100644
--- a/net/af-xdp.c
+++ b/net/af-xdp.c
@@ -21,6 +21,7 @@
#include "clients.h"
#include "monitor/monitor.h"
#include "net/net.h"
+#include "net/util.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
@@ -441,35 +442,6 @@ static NetClientInfo net_af_xdp_info = {
.cleanup = af_xdp_cleanup,
};
-static int *parse_socket_fds(const char *sock_fds_str,
- int n_expected, Error **errp)
-{
- gchar **substrings = g_strsplit(sock_fds_str, ":", -1);
- int i, n_sock_fds = g_strv_length(substrings);
- int *sock_fds = NULL;
-
- if (n_sock_fds != n_expected) {
- error_setg(errp, "expected %d socket fds, got %d",
- n_expected, n_sock_fds);
- goto exit;
- }
-
- sock_fds = g_new(int, n_sock_fds);
-
- for (i = 0; i < n_sock_fds; i++) {
- sock_fds[i] = monitor_fd_param(monitor_cur(), substrings[i], errp);
- if (sock_fds[i] < 0) {
- g_free(sock_fds);
- sock_fds = NULL;
- goto exit;
- }
- }
-
-exit:
- g_strfreev(substrings);
- return sock_fds;
-}
-
/*
* The exported init function.
*
@@ -530,8 +502,7 @@ int net_init_af_xdp(const Netdev *netdev,
}
if (opts->sock_fds) {
- sock_fds = parse_socket_fds(opts->sock_fds, queues, errp);
- if (!sock_fds) {
+ if (net_parse_fds(opts->sock_fds, &sock_fds, queues, errp) < 0) {
return -1;
}
}
diff --git a/net/tap.c b/net/tap.c
index db3fe380a4..2d4630c350 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -45,6 +45,7 @@
#include "hw/virtio/vhost.h"
#include "net/tap.h"
+#include "net/util.h"
#include "net/vhost_net.h"
@@ -701,8 +702,6 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
return fd;
}
-#define MAX_TAP_QUEUES 1024
-
static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
const char *name,
const char *ifname, const char *script,
@@ -782,32 +781,6 @@ failed:
return false;
}
-static int get_fds(char *str, char *fds[], int max)
-{
- char *ptr = str, *this;
- size_t len = strlen(str);
- int i = 0;
-
- while (i < max && ptr < str + len) {
- this = strchr(ptr, ':');
-
- if (this == NULL) {
- fds[i] = g_strdup(ptr);
- } else {
- fds[i] = g_strndup(ptr, this - ptr);
- }
-
- i++;
- if (this == NULL) {
- break;
- } else {
- ptr = this + 1;
- }
- }
-
- return i;
-}
-
int net_init_tap(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
@@ -815,9 +788,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
int fd = -1, vhostfd = -1, vnet_hdr = 0, i = 0, queues;
/* for the no-fd, no-helper case */
char ifname[128];
- char **fds = NULL, **vhost_fds = NULL;
- int nfds = 0, nvhosts = 0;
-
+ int *fds = NULL, *vhost_fds = NULL;
assert(netdev->type == NET_CLIENT_DRIVER_TAP);
tap = &netdev->u.tap;
@@ -890,46 +861,31 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
} else if (tap->fds) {
- fds = g_new0(char *, MAX_TAP_QUEUES);
- vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
-
- nfds = get_fds(tap->fds, fds, MAX_TAP_QUEUES);
- if (tap->vhostfds) {
- nvhosts = get_fds(tap->vhostfds, vhost_fds, MAX_TAP_QUEUES);
- if (nfds != nvhosts) {
- error_setg(errp, "The number of fds passed does not match "
- "the number of vhostfds passed");
- goto fail;
- }
+ queues = net_parse_fds(tap->fds, &fds, 0, errp);
+ if (queues < 0) {
+ goto fail;
}
- for (i = 0; i < nfds; i++) {
- fd = monitor_fd_param(monitor_cur(), fds[i], errp);
- if (fd == -1) {
- goto fail;
- }
+ if (tap->vhostfds && net_parse_fds(tap->vhostfds, &vhost_fds,
+ queues, errp) < 0) {
+ goto fail;
+ }
- if (!qemu_set_blocking(fd, false, errp)) {
+ for (i = 0; i < queues; i++) {
+ if (!qemu_set_blocking(fds[i], false, errp)) {
goto fail;
}
- if (tap->vhostfds) {
- vhostfd = monitor_fd_param(monitor_cur(), vhost_fds[i], errp);
- if (vhostfd == -1) {
- goto fail;
- }
-
- if (!qemu_set_blocking(vhostfd, false, errp)) {
- goto fail;
- }
+ if (vhost_fds && !qemu_set_blocking(vhost_fds[i], false, errp)) {
+ goto fail;
}
if (i == 0) {
- vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ vnet_hdr = tap_probe_vnet_hdr(fds[i], errp);
if (vnet_hdr < 0) {
goto fail;
}
- } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
+ } else if (vnet_hdr != tap_probe_vnet_hdr(fds[i], NULL)) {
error_setg(errp,
"vnet_hdr not consistent across given tap fds");
goto fail;
@@ -937,8 +893,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, name, ifname,
NULL, NULL,
- vhostfd,
- vnet_hdr, fd, errp)) {
+ vhost_fds ? vhost_fds[i] : -1,
+ vnet_hdr, fds[i], errp)) {
goto fail;
}
}
@@ -1003,18 +959,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
fail:
close(fd);
close(vhostfd);
- if (vhost_fds) {
- for (i = 0; i < nvhosts; i++) {
- g_free(vhost_fds[i]);
- }
- g_free(vhost_fds);
- }
- if (fds) {
- for (i = 0; i < nfds; i++) {
- g_free(fds[i]);
- }
- g_free(fds);
- }
+ net_free_fds(fds, queues);
+ net_free_fds(vhost_fds, queues);
return -1;
}
diff --git a/net/util.c b/net/util.c
index 0b3dbfe5d3..1998a6554e 100644
--- a/net/util.c
+++ b/net/util.c
@@ -23,6 +23,8 @@
*/
#include "qemu/osdep.h"
+#include "monitor/monitor.h"
+#include "qapi/error.h"
#include "util.h"
int net_parse_macaddr(uint8_t *macaddr, const char *p)
@@ -57,3 +59,51 @@ int net_parse_macaddr(uint8_t *macaddr, const char *p)
return 0;
}
+
+void net_free_fds(int *fds, int nfds)
+{
+ int i;
+
+ if (!fds || nfds <= 0) {
+ return;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ if (fds[i] != -1) {
+ close(fds[i]);
+ }
+ }
+
+ g_free(fds);
+}
+
+int net_parse_fds(const char *fds_param, int **fds, int expected_nfds,
+ Error **errp)
+{
+ g_auto(GStrv) fdnames = g_strsplit(fds_param, ":", -1);
+ unsigned nfds = g_strv_length(fdnames);
+ int i;
+
+ if (nfds > INT_MAX) {
+ error_setg(errp, "fds parameter exceeds maximum of %d", INT_MAX);
+ return -1;
+ }
+
+ if (expected_nfds && nfds != expected_nfds) {
+ error_setg(errp, "expected %u socket fds, got %u", expected_nfds, nfds);
+ return -1;
+ }
+
+ *fds = g_new(int, nfds);
+
+ for (i = 0; i < nfds; i++) {
+ (*fds)[i] = monitor_fd_param(monitor_cur(), fdnames[i], errp);
+ if ((*fds)[i] == -1) {
+ net_free_fds(*fds, i);
+ *fds = NULL;
+ return -1;
+ }
+ }
+
+ return nfds;
+}
diff --git a/net/util.h b/net/util.h
index 288312979f..4dbc5d416d 100644
--- a/net/util.h
+++ b/net/util.h
@@ -83,4 +83,18 @@ static inline bool in6_equal_net(const struct in6_addr *a,
int net_parse_macaddr(uint8_t *macaddr, const char *p);
+/*
+ * Close all @fds and free @fds itself
+ */
+void net_free_fds(int *fds, int nfds);
+
+/*
+ * Parse @fds_param, where monitor fds are separated by a colon.
+ * @nfds must be non-NULL. If *@nfds is zero - set it accordingly.
+ * If *@nfds is non-zero - check that we have exactly *@nfds fds
+ * and fail otherwise.
+ */
+int net_parse_fds(const char *fds_param, int **fds, int expected_nfds,
+ Error **errp);
+
#endif /* QEMU_NET_UTIL_H */
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 09/15] net/tap: move fds parameters handling to separate functions
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (7 preceding siblings ...)
2026-05-29 4:57 ` [PULL 08/15] net: introduce net_parse_fds() Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 10/15] net/tap: fix vhostfds/vhostfd parameters API Jason Wang
` (6 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
This significantly simplify the code in net_init_tap().
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 99 ++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 65 insertions(+), 34 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index 2d4630c350..b794f80e34 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -781,6 +781,61 @@ failed:
return false;
}
+static bool unblock_fds(int *fds, int nfds, Error **errp)
+{
+ for (int i = 0; i < nfds; i++) {
+ if (!qemu_set_blocking(fds[i], false, errp)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static int tap_parse_fds_and_queues(const NetdevTapOptions *tap, int **fds,
+ Error **errp)
+{
+ int queues = 1;
+
+ if (tap->has_queues + !!tap->helper + !!tap->fds + !!tap->fd > 1) {
+ error_setg(errp, "queues=, helper=, fds= and fd= are mutual exclusive");
+ return -1;
+ }
+
+ if (tap->has_queues) {
+ if (tap->queues > INT_MAX) {
+ error_setg(errp, "queues exceeds maximum %d", INT_MAX);
+ return -1;
+ }
+ queues = tap->queues;
+ *fds = NULL;
+ } else if (tap->fd || tap->fds) {
+ queues = net_parse_fds(tap->fd ?: tap->fds, fds,
+ tap->fd ? 1 : 0, errp);
+ if (!*fds) {
+ return -1;
+ }
+ } else if (tap->helper) {
+ int fd = net_bridge_run_helper(tap->helper,
+ tap->br ?: DEFAULT_BRIDGE_INTERFACE,
+ errp);
+ if (fd < 0) {
+ return -1;
+ }
+
+ queues = 1;
+ *fds = g_new(int, 1);
+ **fds = fd;
+ }
+
+ if (*fds && !unblock_fds(*fds, queues, errp)) {
+ net_free_fds(*fds, queues);
+ return -1;
+ }
+
+ return queues;
+}
+
int net_init_tap(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
@@ -792,7 +847,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
assert(netdev->type == NET_CLIENT_DRIVER_TAP);
tap = &netdev->u.tap;
- queues = tap->has_queues ? tap->queues : 1;
/* QEMU hubs do not support multiqueue tap, in this case peer is set.
* For -netdev, peer is always NULL. */
@@ -829,10 +883,15 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
+ queues = tap_parse_fds_and_queues(tap, &fds, errp);
+ if (queues < 0) {
+ return -1;
+ }
+
if (tap->vhostfd) {
vhostfd = monitor_fd_param(monitor_cur(), tap->vhostfd, errp);
if (vhostfd == -1) {
- return -1;
+ goto fail;
}
if (!qemu_set_blocking(vhostfd, false, errp)) {
@@ -841,41 +900,23 @@ int net_init_tap(const Netdev *netdev, const char *name,
}
if (tap->fd) {
- fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
- if (fd == -1) {
- goto fail;
- }
-
- if (!qemu_set_blocking(fd, false, errp)) {
- goto fail;
- }
-
- vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ vnet_hdr = tap_probe_vnet_hdr(fds[0], errp);
if (vnet_hdr < 0) {
goto fail;
}
if (!net_init_tap_one(tap, peer, name, NULL,
NULL, NULL,
- vhostfd, vnet_hdr, fd, errp)) {
+ vhostfd, vnet_hdr, fds[0], errp)) {
goto fail;
}
} else if (tap->fds) {
- queues = net_parse_fds(tap->fds, &fds, 0, errp);
- if (queues < 0) {
- goto fail;
- }
-
if (tap->vhostfds && net_parse_fds(tap->vhostfds, &vhost_fds,
queues, errp) < 0) {
goto fail;
}
for (i = 0; i < queues; i++) {
- if (!qemu_set_blocking(fds[i], false, errp)) {
- goto fail;
- }
-
if (vhost_fds && !qemu_set_blocking(vhost_fds[i], false, errp)) {
goto fail;
}
@@ -899,24 +940,14 @@ int net_init_tap(const Netdev *netdev, const char *name,
}
}
} else if (tap->helper) {
- fd = net_bridge_run_helper(tap->helper,
- tap->br ?: DEFAULT_BRIDGE_INTERFACE,
- errp);
- if (fd == -1) {
- goto fail;
- }
-
- if (!qemu_set_blocking(fd, false, errp)) {
- goto fail;
- }
- vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+ vnet_hdr = tap_probe_vnet_hdr(fds[0], errp);
if (vnet_hdr < 0) {
goto fail;
}
if (!net_init_tap_one(tap, peer, name, ifname,
NULL, NULL, vhostfd,
- vnet_hdr, fd, errp)) {
+ vnet_hdr, fds[0], errp)) {
goto fail;
}
} else {
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 10/15] net/tap: fix vhostfds/vhostfd parameters API
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (8 preceding siblings ...)
2026-05-29 4:57 ` [PULL 09/15] net/tap: move fds parameters handling to separate functions Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 11/15] net/tap: net_init_tap(): merge fd=, fds= and helper= cases into one Jason Wang
` (5 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
There is a bug in the interface: we don't allow vhostfds argument
together with queues. But we allow vhostfd, and try use it for all
queues of multiqueue TAP.
Let's relax the restriction. We already check that number of vhost fds
match queues (or number of fds). So, no matter do vhost fds come from
vhostfds or vhostfd argument. Let's use correct vhost fds for multiqueue
TAP.
To achieve this we move vhost fds parsing to separate function and call
it earlier in net_init_tap(). Then we have vhost fds available (and
already checked) for all further cases.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 63 ++++++++++++++++++++++++++-----------------------------
1 file changed, 30 insertions(+), 33 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index b794f80e34..d5a719150b 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -836,11 +836,32 @@ static int tap_parse_fds_and_queues(const NetdevTapOptions *tap, int **fds,
return queues;
}
+static bool tap_parse_vhost_fds(const NetdevTapOptions *tap, int **vhost_fds,
+ int queues, Error **errp)
+{
+ if (!(tap->vhostfd || tap->vhostfds)) {
+ *vhost_fds = NULL;
+ return true;
+ }
+
+ if (net_parse_fds(tap->vhostfd ?: tap->vhostfds,
+ vhost_fds, queues, errp) < 0) {
+ return false;
+ }
+
+ if (!unblock_fds(*vhost_fds, queues, errp)) {
+ net_free_fds(*vhost_fds, queues);
+ return false;
+ }
+
+ return true;
+}
+
int net_init_tap(const Netdev *netdev, const char *name,
NetClientState *peer, Error **errp)
{
const NetdevTapOptions *tap;
- int fd = -1, vhostfd = -1, vnet_hdr = 0, i = 0, queues;
+ int fd = -1, vnet_hdr = 0, i = 0, queues;
/* for the no-fd, no-helper case */
char ifname[128];
int *fds = NULL, *vhost_fds = NULL;
@@ -873,30 +894,13 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
- if (tap->vhostfds && !tap->fds) {
- error_setg(errp, "vhostfds= is invalid if fds= wasn't specified");
- return -1;
- }
-
- if (tap->vhostfd && tap->fds) {
- error_setg(errp, "vhostfd= is invalid with fds=");
- return -1;
- }
-
queues = tap_parse_fds_and_queues(tap, &fds, errp);
if (queues < 0) {
return -1;
}
- if (tap->vhostfd) {
- vhostfd = monitor_fd_param(monitor_cur(), tap->vhostfd, errp);
- if (vhostfd == -1) {
- goto fail;
- }
-
- if (!qemu_set_blocking(vhostfd, false, errp)) {
- goto fail;
- }
+ if (!tap_parse_vhost_fds(tap, &vhost_fds, queues, errp)) {
+ goto fail;
}
if (tap->fd) {
@@ -907,20 +911,12 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, name, NULL,
NULL, NULL,
- vhostfd, vnet_hdr, fds[0], errp)) {
+ vhost_fds ? vhost_fds[0] : -1,
+ vnet_hdr, fds[0], errp)) {
goto fail;
}
} else if (tap->fds) {
- if (tap->vhostfds && net_parse_fds(tap->vhostfds, &vhost_fds,
- queues, errp) < 0) {
- goto fail;
- }
-
for (i = 0; i < queues; i++) {
- if (vhost_fds && !qemu_set_blocking(vhost_fds[i], false, errp)) {
- goto fail;
- }
-
if (i == 0) {
vnet_hdr = tap_probe_vnet_hdr(fds[i], errp);
if (vnet_hdr < 0) {
@@ -946,7 +942,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
}
if (!net_init_tap_one(tap, peer, name, ifname,
- NULL, NULL, vhostfd,
+ NULL, NULL,
+ vhost_fds ? vhost_fds[0] : -1,
vnet_hdr, fds[0], errp)) {
goto fail;
}
@@ -979,7 +976,8 @@ int net_init_tap(const Netdev *netdev, const char *name,
if (!net_init_tap_one(tap, peer, name, ifname,
i >= 1 ? NULL : script,
i >= 1 ? NULL : downscript,
- vhostfd, vnet_hdr, fd, errp)) {
+ vhost_fds ? vhost_fds[i] : -1,
+ vnet_hdr, fd, errp)) {
goto fail;
}
}
@@ -989,7 +987,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
fail:
close(fd);
- close(vhostfd);
net_free_fds(fds, queues);
net_free_fds(vhost_fds, queues);
return -1;
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 11/15] net/tap: net_init_tap(): merge fd=, fds= and helper= cases into one
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (9 preceding siblings ...)
2026-05-29 4:57 ` [PULL 10/15] net/tap: fix vhostfds/vhostfd parameters API Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 12/15] net/tap: net_init_tap(): relax QEMU hubs check Jason Wang
` (4 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Now fd= and helper= cases are just a duplication of fds= case with
queues=1. Let's merge them all.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 26 +-------------------------
1 file changed, 1 insertion(+), 25 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index d5a719150b..c6bf8a7042 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -903,19 +903,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
- if (tap->fd) {
- vnet_hdr = tap_probe_vnet_hdr(fds[0], errp);
- if (vnet_hdr < 0) {
- goto fail;
- }
-
- if (!net_init_tap_one(tap, peer, name, NULL,
- NULL, NULL,
- vhost_fds ? vhost_fds[0] : -1,
- vnet_hdr, fds[0], errp)) {
- goto fail;
- }
- } else if (tap->fds) {
+ if (fds) {
for (i = 0; i < queues; i++) {
if (i == 0) {
vnet_hdr = tap_probe_vnet_hdr(fds[i], errp);
@@ -935,18 +923,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
goto fail;
}
}
- } else if (tap->helper) {
- vnet_hdr = tap_probe_vnet_hdr(fds[0], errp);
- if (vnet_hdr < 0) {
- goto fail;
- }
-
- if (!net_init_tap_one(tap, peer, name, ifname,
- NULL, NULL,
- vhost_fds ? vhost_fds[0] : -1,
- vnet_hdr, fds[0], errp)) {
- goto fail;
- }
} else {
g_autofree char *script =
tap_parse_script(tap->script, DEFAULT_NETWORK_SCRIPT);
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 12/15] net/tap: net_init_tap(): relax QEMU hubs check
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (10 preceding siblings ...)
2026-05-29 4:57 ` [PULL 11/15] net/tap: net_init_tap(): merge fd=, fds= and helper= cases into one Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 13/15] net/tap: check that user tries to define zero queues Jason Wang
` (3 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Ben Chaney, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
queues may be set to 1, as well as fds may contain only one fd.
No reason to block such cases. Let's check exactly number of queues.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Ben Chaney <bchaney@akamai.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index c6bf8a7042..e464f62b47 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -869,13 +869,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
assert(netdev->type == NET_CLIENT_DRIVER_TAP);
tap = &netdev->u.tap;
- /* QEMU hubs do not support multiqueue tap, in this case peer is set.
- * For -netdev, peer is always NULL. */
- if (peer && (tap->has_queues || tap->fds || tap->vhostfds)) {
- error_setg(errp, "Multiqueue tap cannot be used with hubs");
- return -1;
- }
-
if (tap->has_vhost && !tap->vhost && (tap->vhostfds || tap->vhostfd)) {
error_setg(errp, "vhostfd(s)= is not valid without vhost");
return -1;
@@ -899,6 +892,15 @@ int net_init_tap(const Netdev *netdev, const char *name,
return -1;
}
+ /*
+ * QEMU hubs do not support multiqueue tap, in this case peer is set.
+ * For -netdev, peer is always NULL.
+ */
+ if (peer && queues > 1) {
+ error_setg(errp, "Multiqueue tap cannot be used with hubs");
+ goto fail;
+ }
+
if (!tap_parse_vhost_fds(tap, &vhost_fds, queues, errp)) {
goto fail;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 13/15] net/tap: check that user tries to define zero queues
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (11 preceding siblings ...)
2026-05-29 4:57 ` [PULL 12/15] net/tap: net_init_tap(): relax QEMU hubs check Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 14/15] hw/net/rocker_of_dpa: Check group ID pointers are not NULL Jason Wang
` (2 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Vladimir Sementsov-Ogievskiy, Jason Wang
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Add check for queues parameter to be non-zero, and for fd/fds
parameters to be non-empty.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
net/tap.c | 4 ++++
net/util.c | 5 +++++
2 files changed, 9 insertions(+)
diff --git a/net/tap.c b/net/tap.c
index e464f62b47..57ffb09885 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -807,6 +807,10 @@ static int tap_parse_fds_and_queues(const NetdevTapOptions *tap, int **fds,
error_setg(errp, "queues exceeds maximum %d", INT_MAX);
return -1;
}
+ if (tap->queues == 0) {
+ error_setg(errp, "queues must be greater than zero");
+ return -1;
+ }
queues = tap->queues;
*fds = NULL;
} else if (tap->fd || tap->fds) {
diff --git a/net/util.c b/net/util.c
index 1998a6554e..8265f15548 100644
--- a/net/util.c
+++ b/net/util.c
@@ -94,6 +94,11 @@ int net_parse_fds(const char *fds_param, int **fds, int expected_nfds,
return -1;
}
+ if (nfds == 0) {
+ error_setg(errp, "no fds passed");
+ return -1;
+ }
+
*fds = g_new(int, nfds);
for (i = 0; i < nfds; i++) {
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 14/15] hw/net/rocker_of_dpa: Check group ID pointers are not NULL
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (12 preceding siblings ...)
2026-05-29 4:57 ` [PULL 13/15] net/tap: check that user tries to define zero queues Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 4:57 ` [PULL 15/15] hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match() Jason Wang
2026-05-29 19:48 ` [PULL 00/15] Net patches Stefan Hajnoczi
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-stable, Jason Wang
From: Peter Maydell <peter.maydell@linaro.org>
In of_dpa_cmd_add_l2_flood(), we use rocker_tlv_parse_nested()
to fill in a tlvs[] array. If the guest command is valid then
the entries should be pointers to TLV data items with group IDs.
However, if the guest gives us bogus data then rocker_tlv_parse_nested()
indicates this by leaving the tlvs[] entries NULL. In the other
places that use this function, we check for this before using
the value, but here we forgot, and the result is that QEMU can
crash:
#0 __memcpy_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:331
#1 0x00005555574f7137 in __asan_memcpy ()
#2 0x0000555558106792 in ldl_he_p (ptr=0x8) at /home/pm215/qemu/include/qemu/bswap.h:278
#3 0x0000555558106755 in ldl_le_p (ptr=0x8) at /home/pm215/qemu/include/qemu/bswap.h:311
#4 0x00005555580f85ed in rocker_tlv_get_le32 (tlv=0x0) at ../../hw/net/rocker/rocker_tlv.h:114
#5 0x000055555810a8ad in of_dpa_cmd_add_l2_flood (of_dpa=0x506000082e38, group=0x503000b4e440, group_tlvs=0x7fff68702c20)
at ../../hw/net/rocker/rocker_of_dpa.c:2032
#6 0x0000555558108a74 in of_dpa_cmd_group_do (of_dpa=0x506000082e38, group_id=1073741824, group=0x503000b4e440, group_tlvs=0x7fff68702c20)
at ../../hw/net/rocker/rocker_of_dpa.c:2115
#7 0x0000555558108730 in of_dpa_cmd_group_add (of_dpa=0x506000082e38, group_id=1073741824, group_tlvs=0x7fff68702c20)
at ../../hw/net/rocker/rocker_of_dpa.c:2135
#8 0x00005555580f66ec in of_dpa_group_cmd
(of_dpa=0x506000082e38, info=0x514000072e40, buf=0x5070002356c0 "\001", cmd=7, group_tlvs=0x7fff68702c20)
at ../../hw/net/rocker/rocker_of_dpa.c:2194
Check for NULL values and return an error.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/1851
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
hw/net/rocker/rocker_of_dpa.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 3190a0e75c..958f3006c1 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -2029,6 +2029,10 @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
group_tlvs[ROCKER_TLV_OF_DPA_GROUP_IDS]);
for (i = 0; i < group->l2_flood.group_count; i++) {
+ if (!tlvs[i + 1]) {
+ err = -ROCKER_EINVAL;
+ goto err_out;
+ }
group->l2_flood.group_ids[i] = rocker_tlv_get_le32(tlvs[i + 1]);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PULL 15/15] hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match()
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (13 preceding siblings ...)
2026-05-29 4:57 ` [PULL 14/15] hw/net/rocker_of_dpa: Check group ID pointers are not NULL Jason Wang
@ 2026-05-29 4:57 ` Jason Wang
2026-05-29 19:48 ` [PULL 00/15] Net patches Stefan Hajnoczi
15 siblings, 0 replies; 22+ messages in thread
From: Jason Wang @ 2026-05-29 4:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-stable, Jason Wang
From: Peter Maydell <peter.maydell@linaro.org>
_of_dpa_flow_match() tries to do masked comparisons of OfDpaFlowkey
structs by casting pointers to them to uint64_t* and then doing the
memory accesses as 64-bit. This is undefined behaviour because the
pointers might not be 64-bit aligned, and the UB sanitizer spots this:
../../hw/net/rocker/rocker_of_dpa.c:321:20: runtime error: load of misaligned address 0x512000164044 for type 'uint64_t' (aka 'unsigned long'), which requires 8 byte alignment
0x512000164044: note: pointer points here
02 00 00 00 00 00 ff ff 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
We do know that OfDpaFlowKey structs must be at least aligned enough
for uint32_t accesses, because that's the type of the first field.
Switch to using uint32_t accesses in the loop.
Because the "width" field is always set via the FLOW_KEY_WIDTH macro
and not exposed to the guest, we can adjust the macro to store the
number of uint32_t to be checked rather than needing to change the
loop boundary in the match function.
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
hw/net/rocker/rocker_of_dpa.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 958f3006c1..3d6f55b512 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -99,13 +99,13 @@ typedef struct of_dpa_flow_key {
} nd;
} ipv6;
};
- int width; /* how many uint64_t's in key? */
+ int width; /* how many uint32_t's in key? */
} OfDpaFlowKey;
-/* Width of key which includes field 'f' in u64s, rounded up */
+/* Width of key which includes field 'f' in u32s, rounded up */
#define FLOW_KEY_WIDTH(f) \
DIV_ROUND_UP(offsetof(OfDpaFlowKey, f) + sizeof_field(OfDpaFlowKey, f), \
- sizeof(uint64_t))
+ sizeof(uint32_t))
typedef struct of_dpa_flow_action {
uint32_t goto_tbl;
@@ -304,9 +304,9 @@ static void _of_dpa_flow_match(void *key, void *value, void *user_data)
{
OfDpaFlow *flow = value;
OfDpaFlowMatch *match = user_data;
- uint64_t *k = (uint64_t *)&flow->key;
- uint64_t *m = (uint64_t *)&flow->mask;
- uint64_t *v = (uint64_t *)&match->value;
+ uint32_t *k = (uint32_t *)&flow->key;
+ uint32_t *m = (uint32_t *)&flow->mask;
+ uint32_t *v = (uint32_t *)&match->value;
int i;
if (flow->key.tbl_id == match->value.tbl_id) {
--
2.54.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PULL 00/15] Net patches
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
` (14 preceding siblings ...)
2026-05-29 4:57 ` [PULL 15/15] hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match() Jason Wang
@ 2026-05-29 19:48 ` Stefan Hajnoczi
15 siblings, 0 replies; 22+ messages in thread
From: Stefan Hajnoczi @ 2026-05-29 19:48 UTC (permalink / raw)
To: Jason Wang; +Cc: qemu-devel, Jason Wang
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-05-29 19:49 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-29 4:57 [PULL 00/15] Net patches Jason Wang
2026-05-29 4:57 ` [PULL 01/15] net/af-xdp: fix type overflow Jason Wang
2026-05-29 4:57 ` [PULL 02/15] net/tap: net_init_tap_one(): add return value Jason Wang
2026-05-29 4:57 ` [PULL 03/15] net/tap: net_init_tap(): drop extra vhostfdname variable Jason Wang
2026-05-29 4:57 ` [PULL 04/15] net/tap: net_init_tap(): refactor parameter checking Jason Wang
2026-05-29 4:57 ` [PULL 05/15] net/tap: net_init_tap(): common fail label Jason Wang
2026-05-29 4:57 ` [PULL 06/15] net/tap: net_init_tap_one() refactor to get vhostfd param Jason Wang
2026-05-29 4:57 ` [PULL 07/15] net/tap: net_init_tap_one(): drop model parameter Jason Wang
2026-05-29 4:57 ` [PULL 08/15] net: introduce net_parse_fds() Jason Wang
2026-05-29 4:57 ` [PULL 09/15] net/tap: move fds parameters handling to separate functions Jason Wang
2026-05-29 4:57 ` [PULL 10/15] net/tap: fix vhostfds/vhostfd parameters API Jason Wang
2026-05-29 4:57 ` [PULL 11/15] net/tap: net_init_tap(): merge fd=, fds= and helper= cases into one Jason Wang
2026-05-29 4:57 ` [PULL 12/15] net/tap: net_init_tap(): relax QEMU hubs check Jason Wang
2026-05-29 4:57 ` [PULL 13/15] net/tap: check that user tries to define zero queues Jason Wang
2026-05-29 4:57 ` [PULL 14/15] hw/net/rocker_of_dpa: Check group ID pointers are not NULL Jason Wang
2026-05-29 4:57 ` [PULL 15/15] hw/net/rocker_of_dpa: Avoid unaligned accesses in _of_dpa_flow_match() Jason Wang
2026-05-29 19:48 ` [PULL 00/15] Net patches Stefan Hajnoczi
-- strict thread matches above, loose matches on Subject: below --
2023-07-07 9:06 Jason Wang
2023-07-07 19:20 ` Richard Henderson
2022-03-08 13:34 Jason Wang
2022-03-09 20:00 ` Peter Maydell
2022-03-10 2:39 ` Jason Wang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.