1
The following changes since commit f4abdf32714d1845b7c01ec136dd2b04c2f7db47:
1
The following changes since commit d9a4282c4b690e45d25c2b933f318bb41eeb271d:
2
2
3
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2' into staging (2021-03-11 16:20:58 +0000)
3
Merge tag 'pull-tcg-20250308' of https://gitlab.com/rth7680/qemu into staging (2025-03-09 11:45:00 +0800)
4
4
5
are available in the git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to 9bdb56367679e68e5e71a1c29a1087bda6414b25:
9
for you to fetch changes up to ac2ff9b840ce82cc7d5fd9ce4fd3019a434d7dc9:
10
10
11
pvrdma: wean code off pvrdma_ring.h kernel header (2021-03-12 14:08:31 +0800)
11
tap-linux: Open ipvtap and macvtap (2025-03-10 17:07:16 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
-----BEGIN PGP SIGNATURE-----
15
16
iQEzBAABCAAdFiEEIV1G9IJGaJ7HfzVi7wSWWzmNYhEFAmfO1zkACgkQ7wSWWzmN
17
YhET+wf+PkaGeFTNUrOtWpl35fSMKlmOVbb1fkPfuhVBmeY2Vh1EIN3OjqnzdV0F
18
wxpuk+wwmFiuV1n6RNuMHQ0nz1mhgsSlZh93N5rArC/PUr3iViaT0cb82RjwxhaI
19
RODBhhy7V9WxEhT9hR8sCP2ky2mrKgcYbjiIEw+IvFZOVQa58rMr2h/cbAb/iH4l
20
7T9Wba03JBqOS6qgzSFZOMxvqnYdVjhqXN8M6W9ngRJOjPEAkTB6Evwep6anRjcM
21
mCUOgkf2sgQwKve8pYAeTMkzXFctvTc/qCU4ZbN8XcoKVVxe2jllGQqdOpMskPEf
22
slOuINeW5M0K5gyjsb/huqcOTfDI2A==
23
=/Y0+
24
-----END PGP SIGNATURE-----
14
25
15
----------------------------------------------------------------
26
----------------------------------------------------------------
16
Alexander Bulekov (4):
27
Akihiko Odaki (3):
17
rtl8139: switch to use qemu_receive_packet() for loopback
28
util/iov: Do not assert offset is in iov
18
pcnet: switch to use qemu_receive_packet() for loopback
29
Revert "hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()"
19
cadence_gem: switch to use qemu_receive_packet() for loopback
30
tap-linux: Open ipvtap and macvtap
20
lan9118: switch to use qemu_receive_packet() for loopback
21
31
22
Bin Meng (1):
32
Eugenio Pérez (2):
23
net: Fix build error when DEBUG_NET is on
33
net: parameterize the removing client from nc list
34
net: move backend cleanup to NIC cleanup
24
35
25
Cornelia Huck (1):
36
hw/net/net_tx_pkt.c | 4 ----
26
pvrdma: wean code off pvrdma_ring.h kernel header
37
include/qemu/iov.h | 5 +++--
27
38
net/net.c | 44 ++++++++++++++++++++++++++++++++++----------
28
Jason Wang (9):
39
net/tap-linux.c | 17 ++++++++++++++---
29
virtio-net: calculating proper msix vectors on init
40
net/vhost-vdpa.c | 8 --------
30
net: unbreak well-form id check for "-nic"
41
util/iov.c | 5 -----
31
e1000: fail early for evil descriptor
42
6 files changed, 51 insertions(+), 32 deletions(-)
32
net: introduce qemu_receive_packet()
33
e1000: switch to use qemu_receive_packet() for loopback
34
dp8393x: switch to use qemu_receive_packet() for loopback packet
35
msf2-mac: switch to use qemu_receive_packet() for loopback
36
sungem: switch to use qemu_receive_packet() for loopback
37
tx_pkt: switch to use qemu_receive_packet_iov() for loopback
38
39
Paolo Bonzini (1):
40
net: validate that ids are well formed
41
42
hw/core/machine.c | 1 +
43
hw/net/cadence_gem.c | 4 +-
44
hw/net/dp8393x.c | 2 +-
45
hw/net/e1000.c | 6 +-
46
hw/net/lan9118.c | 2 +-
47
hw/net/msf2-emac.c | 2 +-
48
hw/net/net_tx_pkt.c | 2 +-
49
hw/net/pcnet.c | 2 +-
50
hw/net/rtl8139.c | 2 +-
51
hw/net/sungem.c | 2 +-
52
hw/rdma/vmw/pvrdma.h | 5 +-
53
hw/rdma/vmw/pvrdma_cmd.c | 6 +-
54
hw/rdma/vmw/pvrdma_dev_ring.c | 41 ++++----
55
hw/rdma/vmw/pvrdma_dev_ring.h | 9 +-
56
hw/rdma/vmw/pvrdma_main.c | 4 +-
57
hw/virtio/virtio-net-pci.c | 10 +-
58
include/net/net.h | 5 +
59
include/net/queue.h | 8 ++
60
.../drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h | 114 ---------------------
61
net/net.c | 53 ++++++++--
62
net/queue.c | 22 ++++
63
scripts/update-linux-headers.sh | 3 +-
64
22 files changed, 142 insertions(+), 163 deletions(-)
65
delete mode 100644 include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
66
43
67
44
45
diff view generated by jsdifflib
Deleted patch
1
Currently, the default msix vectors for virtio-net-pci is 3 which is
2
obvious not suitable for multiqueue guest, so we depends on the user
3
or management tools to pass a correct vectors parameter. In fact, we
4
can simplifying this by calculating the number of vectors on realize.
5
1
6
Consider we have N queues, the number of vectors needed is 2*N + 2
7
(#queue pairs + plus one config interrupt and control vq). We didn't
8
check whether or not host support control vq because it was added
9
unconditionally by qemu to avoid breaking legacy guests such as Minix.
10
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
12
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
hw/core/machine.c | 1 +
17
hw/virtio/virtio-net-pci.c | 10 +++++++++-
18
2 files changed, 10 insertions(+), 1 deletion(-)
19
20
diff --git a/hw/core/machine.c b/hw/core/machine.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/core/machine.c
23
+++ b/hw/core/machine.c
24
@@ -XXX,XX +XXX,XX @@
25
GlobalProperty hw_compat_5_2[] = {
26
{ "ICH9-LPC", "smm-compat", "on"},
27
{ "PIIX4_PM", "smm-compat", "on"},
28
+ { "virtio-net-pci", "vectors", "3"},
29
};
30
const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2);
31
32
diff --git a/hw/virtio/virtio-net-pci.c b/hw/virtio/virtio-net-pci.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/virtio/virtio-net-pci.c
35
+++ b/hw/virtio/virtio-net-pci.c
36
@@ -XXX,XX +XXX,XX @@ struct VirtIONetPCI {
37
static Property virtio_net_properties[] = {
38
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
39
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
40
- DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
41
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
42
+ DEV_NVECTORS_UNSPECIFIED),
43
DEFINE_PROP_END_OF_LIST(),
44
};
45
46
@@ -XXX,XX +XXX,XX @@ static void virtio_net_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
47
DeviceState *qdev = DEVICE(vpci_dev);
48
VirtIONetPCI *dev = VIRTIO_NET_PCI(vpci_dev);
49
DeviceState *vdev = DEVICE(&dev->vdev);
50
+ VirtIONet *net = VIRTIO_NET(vdev);
51
+
52
+ if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
53
+ vpci_dev->nvectors = 2 * MAX(net->nic_conf.peers.queues, 1)
54
+ + 1 /* Config interrupt */
55
+ + 1 /* Control vq */;
56
+ }
57
58
virtio_net_set_netclient_name(&dev->vdev, qdev->id,
59
object_get_typename(OBJECT(qdev)));
60
--
61
2.7.4
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Bin Meng <bin.meng@windriver.com>
2
1
3
"qemu-common.h" should be included to provide the forward declaration
4
of qemu_hexdump() when DEBUG_NET is on.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
net/net.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/net/net.c b/net/net.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/net/net.c
16
+++ b/net/net.c
17
@@ -XXX,XX +XXX,XX @@
18
*/
19
20
#include "qemu/osdep.h"
21
+#include "qemu-common.h"
22
23
#include "net/net.h"
24
#include "clients.h"
25
--
26
2.7.4
27
28
diff view generated by jsdifflib
1
Some NIC supports loopback mode and this is done by calling
1
From: Eugenio Pérez <eperezma@redhat.com>
2
nc->info->receive() directly which in fact suppresses the effort of
3
reentrancy check that is done in qemu_net_queue_send().
4
2
5
Unfortunately we can't use qemu_net_queue_send() here since for
3
This change is used in later commits so we can avoid the removal of the
6
loopback there's no sender as peer, so this patch introduce a
4
netclient if it is delayed.
7
qemu_receive_packet() which is used for implementing loopback mode
8
for a NIC with this check.
9
5
10
NIC that supports loopback mode will be converted to this helper.
6
No functional change intended.
11
7
12
This is intended to address CVE-2021-3416.
8
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
13
9
Acked-by: Jason Wang <jasowang@redhat.com>
14
Cc: Prasad J Pandit <ppandit@redhat.com>
10
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Cc: qemu-stable@nongnu.org
17
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
18
---
12
---
19
include/net/net.h | 5 +++++
13
net/net.c | 13 ++++++++-----
20
include/net/queue.h | 8 ++++++++
14
1 file changed, 8 insertions(+), 5 deletions(-)
21
net/net.c | 38 +++++++++++++++++++++++++++++++-------
22
net/queue.c | 22 ++++++++++++++++++++++
23
4 files changed, 66 insertions(+), 7 deletions(-)
24
15
25
diff --git a/include/net/net.h b/include/net/net.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/net/net.h
28
+++ b/include/net/net.h
29
@@ -XXX,XX +XXX,XX @@ void *qemu_get_nic_opaque(NetClientState *nc);
30
void qemu_del_net_client(NetClientState *nc);
31
typedef void (*qemu_nic_foreach)(NICState *nic, void *opaque);
32
void qemu_foreach_nic(qemu_nic_foreach func, void *opaque);
33
+int qemu_can_receive_packet(NetClientState *nc);
34
int qemu_can_send_packet(NetClientState *nc);
35
ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
36
int iovcnt);
37
ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
38
int iovcnt, NetPacketSent *sent_cb);
39
ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
40
+ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size);
41
+ssize_t qemu_receive_packet_iov(NetClientState *nc,
42
+ const struct iovec *iov,
43
+ int iovcnt);
44
ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
45
ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
46
int size, NetPacketSent *sent_cb);
47
diff --git a/include/net/queue.h b/include/net/queue.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/net/queue.h
50
+++ b/include/net/queue.h
51
@@ -XXX,XX +XXX,XX @@ void qemu_net_queue_append_iov(NetQueue *queue,
52
53
void qemu_del_net_queue(NetQueue *queue);
54
55
+ssize_t qemu_net_queue_receive(NetQueue *queue,
56
+ const uint8_t *data,
57
+ size_t size);
58
+
59
+ssize_t qemu_net_queue_receive_iov(NetQueue *queue,
60
+ const struct iovec *iov,
61
+ int iovcnt);
62
+
63
ssize_t qemu_net_queue_send(NetQueue *queue,
64
NetClientState *sender,
65
unsigned flags,
66
diff --git a/net/net.c b/net/net.c
16
diff --git a/net/net.c b/net/net.c
67
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
68
--- a/net/net.c
18
--- a/net/net.c
69
+++ b/net/net.c
19
+++ b/net/net.c
70
@@ -XXX,XX +XXX,XX @@ int qemu_set_vnet_be(NetClientState *nc, bool is_be)
20
@@ -XXX,XX +XXX,XX @@ NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
71
#endif
21
return ncs->peer;
72
}
22
}
73
23
74
+int qemu_can_receive_packet(NetClientState *nc)
24
-static void qemu_cleanup_net_client(NetClientState *nc)
75
+{
25
+static void qemu_cleanup_net_client(NetClientState *nc,
76
+ if (nc->receive_disabled) {
26
+ bool remove_from_net_clients)
77
+ return 0;
27
{
78
+ } else if (nc->info->can_receive &&
28
- QTAILQ_REMOVE(&net_clients, nc, next);
79
+ !nc->info->can_receive(nc)) {
29
+ if (remove_from_net_clients) {
80
+ return 0;
30
+ QTAILQ_REMOVE(&net_clients, nc, next);
81
+ }
31
+ }
82
+ return 1;
32
83
+}
33
if (nc->info->cleanup) {
84
+
34
nc->info->cleanup(nc);
85
int qemu_can_send_packet(NetClientState *sender)
35
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
86
{
36
}
87
int vm_running = runstate_is_running();
37
88
@@ -XXX,XX +XXX,XX @@ int qemu_can_send_packet(NetClientState *sender)
38
for (i = 0; i < queues; i++) {
89
return 1;
39
- qemu_cleanup_net_client(ncs[i]);
40
+ qemu_cleanup_net_client(ncs[i], true);
41
}
42
43
return;
90
}
44
}
91
45
92
- if (sender->peer->receive_disabled) {
46
for (i = 0; i < queues; i++) {
93
- return 0;
47
- qemu_cleanup_net_client(ncs[i]);
94
- } else if (sender->peer->info->can_receive &&
48
+ qemu_cleanup_net_client(ncs[i], true);
95
- !sender->peer->info->can_receive(sender->peer)) {
49
qemu_free_net_client(ncs[i]);
96
- return 0;
50
}
97
- }
98
- return 1;
99
+ return qemu_can_receive_packet(sender->peer);
100
}
51
}
101
52
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
102
static ssize_t filter_receive_iov(NetClientState *nc,
53
for (i = queues - 1; i >= 0; i--) {
103
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
54
NetClientState *nc = qemu_get_subqueue(nic, i);
104
return qemu_send_packet_async(nc, buf, size, NULL);
55
105
}
56
- qemu_cleanup_net_client(nc);
106
57
+ qemu_cleanup_net_client(nc, true);
107
+ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size)
58
qemu_free_net_client(nc);
108
+{
59
}
109
+ if (!qemu_can_receive_packet(nc)) {
60
110
+ return 0;
111
+ }
112
+
113
+ return qemu_net_queue_receive(nc->incoming_queue, buf, size);
114
+}
115
+
116
+ssize_t qemu_receive_packet_iov(NetClientState *nc, const struct iovec *iov,
117
+ int iovcnt)
118
+{
119
+ if (!qemu_can_receive_packet(nc)) {
120
+ return 0;
121
+ }
122
+
123
+ return qemu_net_queue_receive_iov(nc->incoming_queue, iov, iovcnt);
124
+}
125
+
126
ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
127
{
128
return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW,
129
diff --git a/net/queue.c b/net/queue.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/net/queue.c
132
+++ b/net/queue.c
133
@@ -XXX,XX +XXX,XX @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
134
return ret;
135
}
136
137
+ssize_t qemu_net_queue_receive(NetQueue *queue,
138
+ const uint8_t *data,
139
+ size_t size)
140
+{
141
+ if (queue->delivering) {
142
+ return 0;
143
+ }
144
+
145
+ return qemu_net_queue_deliver(queue, NULL, 0, data, size);
146
+}
147
+
148
+ssize_t qemu_net_queue_receive_iov(NetQueue *queue,
149
+ const struct iovec *iov,
150
+ int iovcnt)
151
+{
152
+ if (queue->delivering) {
153
+ return 0;
154
+ }
155
+
156
+ return qemu_net_queue_deliver_iov(queue, NULL, 0, iov, iovcnt);
157
+}
158
+
159
ssize_t qemu_net_queue_send(NetQueue *queue,
160
NetClientState *sender,
161
unsigned flags,
162
--
61
--
163
2.7.4
62
2.42.0
164
63
165
64
diff view generated by jsdifflib
1
The auto genreated id for "-nic" has "_" prefix which can't satisfy
1
From: Eugenio Pérez <eperezma@redhat.com>
2
the well-formed id check that is introduced by
3
871579b9834aca517dc2d4941691a1d2082db6f2 ("net: validate that ids are
4
well formed"). Fix this by simply removing the "__" prefix.
5
2
3
Commit a0d7215e33 ("vhost-vdpa: do not cleanup the vdpa/vhost-net
4
structures if peer nic is present") effectively delayed the backend
5
cleanup, allowing the frontend or the guest to access it resources as
6
long as the frontend is still visible to the guest.
7
8
However it does not clean up the resources until the qemu process is
9
over. This causes an effective leak if the device is deleted with
10
device_del, as there is no way to close the vdpa device. This makes
11
impossible to re-add that device to this or other QEMU instances until
12
the first instance of QEMU is finished.
13
14
Move the cleanup from qemu_cleanup to the NIC deletion and to
15
net_cleanup.
16
17
Fixes: a0d7215e33 ("vhost-vdpa: do not cleanup the vdpa/vhost-net structures if peer nic is present")
18
Reported-by: Lei Yang <leiyang@redhat.com>
19
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
20
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
22
---
8
net/net.c | 2 +-
23
net/net.c | 33 +++++++++++++++++++++++++++------
9
1 file changed, 1 insertion(+), 1 deletion(-)
24
net/vhost-vdpa.c | 8 --------
25
2 files changed, 27 insertions(+), 14 deletions(-)
10
26
11
diff --git a/net/net.c b/net/net.c
27
diff --git a/net/net.c b/net/net.c
12
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
13
--- a/net/net.c
29
--- a/net/net.c
14
+++ b/net/net.c
30
+++ b/net/net.c
15
@@ -XXX,XX +XXX,XX @@ static int net_param_nic(void *dummy, QemuOpts *opts, Error **errp)
31
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
16
/* Create an ID if the user did not specify one */
32
object_unparent(OBJECT(nf));
17
nd_id = g_strdup(qemu_opts_id(opts));
18
if (!nd_id) {
19
- nd_id = g_strdup_printf("__org.qemu.nic%i", idx);
20
+ nd_id = g_strdup_printf("org.qemu.nic%i", idx);
21
qemu_opts_set_id(opts, nd_id);
22
}
33
}
23
34
35
- /* If there is a peer NIC, delete and cleanup client, but do not free. */
36
+ /*
37
+ * If there is a peer NIC, transfer ownership to it. Delete the client
38
+ * from net_client list but do not cleanup nor free. This way NIC can
39
+ * still access to members of the backend.
40
+ *
41
+ * The cleanup and free will be done when the NIC is free.
42
+ */
43
if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
44
NICState *nic = qemu_get_nic(nc->peer);
45
if (nic->peer_deleted) {
46
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
47
48
for (i = 0; i < queues; i++) {
49
ncs[i]->peer->link_down = true;
50
+ QTAILQ_REMOVE(&net_clients, ncs[i], next);
51
}
52
53
if (nc->peer->info->link_status_changed) {
54
nc->peer->info->link_status_changed(nc->peer);
55
}
56
57
- for (i = 0; i < queues; i++) {
58
- qemu_cleanup_net_client(ncs[i], true);
59
- }
60
-
61
return;
62
}
63
64
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
65
66
for (i = 0; i < queues; i++) {
67
NetClientState *nc = qemu_get_subqueue(nic, i);
68
- /* If this is a peer NIC and peer has already been deleted, free it now. */
69
+ /*
70
+ * If this is a peer NIC and peer has already been deleted, clean it up
71
+ * and free it now.
72
+ */
73
if (nic->peer_deleted) {
74
+ qemu_cleanup_net_client(nc->peer, false);
75
qemu_free_net_client(nc->peer);
76
} else if (nc->peer) {
77
/* if there are RX packets pending, complete them */
78
@@ -XXX,XX +XXX,XX @@ void net_cleanup(void)
79
* of the latest NET_CLIENT_DRIVER_NIC, and operate on *p as we walk
80
* the list.
81
*
82
+ * However, the NIC may have peers that trust to be clean beyond this
83
+ * point. For example, if they have been removed with device_del.
84
+ *
85
* The 'nc' variable isn't part of the list traversal; it's purely
86
* for convenience as too much '(*p)->' has a tendency to make the
87
* readers' eyes bleed.
88
@@ -XXX,XX +XXX,XX @@ void net_cleanup(void)
89
while (*p) {
90
nc = *p;
91
if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
92
+ NICState *nic = qemu_get_nic(nc);
93
+
94
+ if (nic->peer_deleted) {
95
+ int queues = MAX(nic->conf->peers.queues, 1);
96
+
97
+ for (int i = 0; i < queues; i++) {
98
+ nc = qemu_get_subqueue(nic, i);
99
+ qemu_cleanup_net_client(nc->peer, false);
100
+ }
101
+ }
102
+
103
/* Skip NET_CLIENT_DRIVER_NIC entries */
104
p = &QTAILQ_NEXT(nc, next);
105
} else {
106
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/net/vhost-vdpa.c
109
+++ b/net/vhost-vdpa.c
110
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_cleanup(NetClientState *nc)
111
{
112
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
113
114
- /*
115
- * If a peer NIC is attached, do not cleanup anything.
116
- * Cleanup will happen as a part of qemu_cleanup() -> net_cleanup()
117
- * when the guest is shutting down.
118
- */
119
- if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
120
- return;
121
- }
122
munmap(s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_page_len());
123
munmap(s->status, vhost_vdpa_net_cvq_cmd_page_len());
124
if (s->vhost_net) {
24
--
125
--
25
2.7.4
126
2.42.0
26
127
27
128
diff view generated by jsdifflib
1
From: Cornelia Huck <cohuck@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The pvrdma code relies on the pvrdma_ring.h kernel header for some
3
iov_from_buf(), iov_to_buf(), iov_memset(), and iov_copy() asserts
4
basic ring buffer handling. The content of that header isn't very
4
that the given offset fits in the iov while tolerating the specified
5
exciting, but contains some (q)atomic_*() invocations that (a)
5
number of bytes to operate with to be greater than the size of iov.
6
cause manual massaging when doing a headers update, and (b) are
6
This is inconsistent so remove the assertions.
7
an indication that we probably should not be importing that header
8
at all.
9
7
10
Let's reimplement the ring buffer handling directly in the pvrdma
8
Asserting the offset fits in the iov makes sense if it is expected that
11
code instead. This arguably also improves readability of the code.
9
there are other operations that process the content before the offset
10
and the content is processed in order. Under this expectation, the
11
offset should point to the end of bytes that are previously processed
12
and fit in the iov. However, this expectation depends on the details of
13
the caller, and did not hold true at least one case and required code to
14
check iov_size(), which is added with commit 83ddb3dbba2e
15
("hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()").
12
16
13
Importing the header can now be dropped.
17
Adding such a check is inefficient and error-prone. These functions
18
already tolerate the specified number of bytes to operate with to be
19
greater than the size of iov to avoid such checks so remove the
20
assertions to tolerate invalid offset as well. They return the number of
21
bytes they operated with so their callers can still check the returned
22
value to ensure there are sufficient space at the given offset.
14
23
15
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
24
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
16
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
17
Reviewed-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
18
Tested-by: Yuval Shaia <yuval.shaia.ml@gmail.com>
19
Signed-off-by: Jason Wang <jasowang@redhat.com>
25
Signed-off-by: Jason Wang <jasowang@redhat.com>
20
---
26
---
21
hw/rdma/vmw/pvrdma.h | 5 +-
27
include/qemu/iov.h | 5 +++--
22
hw/rdma/vmw/pvrdma_cmd.c | 6 +-
28
util/iov.c | 5 -----
23
hw/rdma/vmw/pvrdma_dev_ring.c | 41 ++++----
29
2 files changed, 3 insertions(+), 7 deletions(-)
24
hw/rdma/vmw/pvrdma_dev_ring.h | 9 +-
25
hw/rdma/vmw/pvrdma_main.c | 4 +-
26
.../drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h | 114 ---------------------
27
scripts/update-linux-headers.sh | 3 +-
28
7 files changed, 38 insertions(+), 144 deletions(-)
29
delete mode 100644 include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
30
30
31
diff --git a/hw/rdma/vmw/pvrdma.h b/hw/rdma/vmw/pvrdma.h
31
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
32
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/rdma/vmw/pvrdma.h
33
--- a/include/qemu/iov.h
34
+++ b/hw/rdma/vmw/pvrdma.h
34
+++ b/include/qemu/iov.h
35
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
36
#include "../rdma_backend_defs.h"
36
* only part of data will be copied, up to the end of the iovec.
37
#include "../rdma_rm_defs.h"
37
* Number of bytes actually copied will be returned, which is
38
38
* min(bytes, iov_size(iov)-offset)
39
-#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
39
- * `Offset' must point to the inside of iovec.
40
#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h"
40
+ * Returns 0 when `offset' points to the outside of iovec.
41
#include "pvrdma_dev_ring.h"
41
*/
42
#include "qom/object.h"
42
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
43
@@ -XXX,XX +XXX,XX @@ typedef struct DSRInfo {
43
size_t offset, const void *buf, size_t bytes);
44
union pvrdma_cmd_req *req;
44
@@ -XXX,XX +XXX,XX @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
45
union pvrdma_cmd_resp *rsp;
45
/**
46
46
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
47
- struct pvrdma_ring *async_ring_state;
47
* starting at byte offset `start', to value `fillc', repeating it
48
+ PvrdmaRingState *async_ring_state;
48
- * `bytes' number of times. `Offset' must point to the inside of iovec.
49
PvrdmaRing async;
49
+ * `bytes' number of times.
50
50
* If `bytes' is large enough, only last bytes portion of iovec,
51
- struct pvrdma_ring *cq_ring_state;
51
* up to the end of it, will be filled with the specified value.
52
+ PvrdmaRingState *cq_ring_state;
52
* Function return actual number of bytes processed, which is
53
PvrdmaRing cq;
53
* min(size, iov_size(iov) - offset).
54
} DSRInfo;
54
+ * Returns 0 when `offset' points to the outside of iovec.
55
55
*/
56
diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
56
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
57
size_t offset, int fillc, size_t bytes);
58
diff --git a/util/iov.c b/util/iov.c
57
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/rdma/vmw/pvrdma_cmd.c
60
--- a/util/iov.c
59
+++ b/hw/rdma/vmw/pvrdma_cmd.c
61
+++ b/util/iov.c
60
@@ -XXX,XX +XXX,XX @@ static int create_cq_ring(PCIDevice *pci_dev , PvrdmaRing **ring,
62
@@ -XXX,XX +XXX,XX @@ size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
61
r = g_malloc(sizeof(*r));
63
offset -= iov[i].iov_len;
62
*ring = r;
64
}
63
64
- r->ring_state = (struct pvrdma_ring *)
65
+ r->ring_state = (PvrdmaRingState *)
66
rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
67
68
if (!r->ring_state) {
69
@@ -XXX,XX +XXX,XX @@ static int create_qp_rings(PCIDevice *pci_dev, uint64_t pdir_dma,
70
*rings = sr;
71
72
/* Create send ring */
73
- sr->ring_state = (struct pvrdma_ring *)
74
+ sr->ring_state = (PvrdmaRingState *)
75
rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
76
if (!sr->ring_state) {
77
rdma_error_report("Failed to map to QP ring state");
78
@@ -XXX,XX +XXX,XX @@ static int create_srq_ring(PCIDevice *pci_dev, PvrdmaRing **ring,
79
r = g_malloc(sizeof(*r));
80
*ring = r;
81
82
- r->ring_state = (struct pvrdma_ring *)
83
+ r->ring_state = (PvrdmaRingState *)
84
rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
85
if (!r->ring_state) {
86
rdma_error_report("Failed to map tp SRQ ring state");
87
diff --git a/hw/rdma/vmw/pvrdma_dev_ring.c b/hw/rdma/vmw/pvrdma_dev_ring.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/rdma/vmw/pvrdma_dev_ring.c
90
+++ b/hw/rdma/vmw/pvrdma_dev_ring.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "trace.h"
93
94
#include "../rdma_utils.h"
95
-#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
96
#include "pvrdma_dev_ring.h"
97
98
int pvrdma_ring_init(PvrdmaRing *ring, const char *name, PCIDevice *dev,
99
- struct pvrdma_ring *ring_state, uint32_t max_elems,
100
+ PvrdmaRingState *ring_state, uint32_t max_elems,
101
size_t elem_sz, dma_addr_t *tbl, uint32_t npages)
102
{
103
int i;
104
@@ -XXX,XX +XXX,XX @@ out:
105
106
void *pvrdma_ring_next_elem_read(PvrdmaRing *ring)
107
{
108
- int e;
109
- unsigned int idx = 0, offset;
110
+ unsigned int idx, offset;
111
+ const uint32_t tail = qatomic_read(&ring->ring_state->prod_tail);
112
+ const uint32_t head = qatomic_read(&ring->ring_state->cons_head);
113
114
- e = pvrdma_idx_ring_has_data(ring->ring_state, ring->max_elems, &idx);
115
- if (e <= 0) {
116
+ if (tail & ~((ring->max_elems << 1) - 1) ||
117
+ head & ~((ring->max_elems << 1) - 1) ||
118
+ tail == head) {
119
trace_pvrdma_ring_next_elem_read_no_data(ring->name);
120
return NULL;
121
}
65
}
122
66
- assert(offset == 0);
123
+ idx = head & (ring->max_elems - 1);
67
return done;
124
offset = idx * ring->elem_sz;
125
return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
126
}
68
}
127
69
128
void pvrdma_ring_read_inc(PvrdmaRing *ring)
70
@@ -XXX,XX +XXX,XX @@ size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
129
{
71
offset -= iov[i].iov_len;
130
- pvrdma_idx_ring_inc(&ring->ring_state->cons_head, ring->max_elems);
72
}
131
+ uint32_t idx = qatomic_read(&ring->ring_state->cons_head);
73
}
132
+
74
- assert(offset == 0);
133
+ idx = (idx + 1) & ((ring->max_elems << 1) - 1);
75
return done;
134
+ qatomic_set(&ring->ring_state->cons_head, idx);
135
}
76
}
136
77
137
void *pvrdma_ring_next_elem_write(PvrdmaRing *ring)
78
@@ -XXX,XX +XXX,XX @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
138
{
79
offset -= iov[i].iov_len;
139
- int idx;
80
}
140
- unsigned int offset, tail;
141
+ unsigned int idx, offset;
142
+ const uint32_t tail = qatomic_read(&ring->ring_state->prod_tail);
143
+ const uint32_t head = qatomic_read(&ring->ring_state->cons_head);
144
145
- idx = pvrdma_idx_ring_has_space(ring->ring_state, ring->max_elems, &tail);
146
- if (idx <= 0) {
147
+ if (tail & ~((ring->max_elems << 1) - 1) ||
148
+ head & ~((ring->max_elems << 1) - 1) ||
149
+ tail == (head ^ ring->max_elems)) {
150
rdma_error_report("CQ is full");
151
return NULL;
152
}
81
}
153
82
- assert(offset == 0);
154
- idx = pvrdma_idx(&ring->ring_state->prod_tail, ring->max_elems);
83
return done;
155
- if (idx < 0 || tail != idx) {
156
- rdma_error_report("Invalid idx %d", idx);
157
- return NULL;
158
- }
159
-
160
+ idx = tail & (ring->max_elems - 1);
161
offset = idx * ring->elem_sz;
162
return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
163
}
84
}
164
85
165
void pvrdma_ring_write_inc(PvrdmaRing *ring)
86
@@ -XXX,XX +XXX,XX @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
166
{
87
bytes -= len;
167
- pvrdma_idx_ring_inc(&ring->ring_state->prod_tail, ring->max_elems);
88
offset = 0;
168
+ uint32_t idx = qatomic_read(&ring->ring_state->prod_tail);
89
}
169
+
90
- assert(offset == 0);
170
+ idx = (idx + 1) & ((ring->max_elems << 1) - 1);
91
return j;
171
+ qatomic_set(&ring->ring_state->prod_tail, idx);
172
}
92
}
173
93
174
void pvrdma_ring_free(PvrdmaRing *ring)
94
@@ -XXX,XX +XXX,XX @@ size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
175
diff --git a/hw/rdma/vmw/pvrdma_dev_ring.h b/hw/rdma/vmw/pvrdma_dev_ring.h
95
soffset -= src_iov[i].iov_len;
176
index XXXXXXX..XXXXXXX 100644
96
}
177
--- a/hw/rdma/vmw/pvrdma_dev_ring.h
97
}
178
+++ b/hw/rdma/vmw/pvrdma_dev_ring.h
98
- assert(soffset == 0); /* offset beyond end of src */
179
@@ -XXX,XX +XXX,XX @@
99
180
100
return done;
181
#define MAX_RING_NAME_SZ 32
182
183
+typedef struct PvrdmaRingState {
184
+ int prod_tail; /* producer tail */
185
+ int cons_head; /* consumer head */
186
+} PvrdmaRingState;
187
+
188
typedef struct PvrdmaRing {
189
char name[MAX_RING_NAME_SZ];
190
PCIDevice *dev;
191
uint32_t max_elems;
192
size_t elem_sz;
193
- struct pvrdma_ring *ring_state; /* used only for unmap */
194
+ PvrdmaRingState *ring_state; /* used only for unmap */
195
int npages;
196
void **pages;
197
} PvrdmaRing;
198
199
int pvrdma_ring_init(PvrdmaRing *ring, const char *name, PCIDevice *dev,
200
- struct pvrdma_ring *ring_state, uint32_t max_elems,
201
+ PvrdmaRingState *ring_state, uint32_t max_elems,
202
size_t elem_sz, dma_addr_t *tbl, uint32_t npages);
203
void *pvrdma_ring_next_elem_read(PvrdmaRing *ring);
204
void pvrdma_ring_read_inc(PvrdmaRing *ring);
205
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/hw/rdma/vmw/pvrdma_main.c
208
+++ b/hw/rdma/vmw/pvrdma_main.c
209
@@ -XXX,XX +XXX,XX @@ static void free_dev_ring(PCIDevice *pci_dev, PvrdmaRing *ring,
210
rdma_pci_dma_unmap(pci_dev, ring_state, TARGET_PAGE_SIZE);
211
}
101
}
212
213
-static int init_dev_ring(PvrdmaRing *ring, struct pvrdma_ring **ring_state,
214
+static int init_dev_ring(PvrdmaRing *ring, PvrdmaRingState **ring_state,
215
const char *name, PCIDevice *pci_dev,
216
dma_addr_t dir_addr, uint32_t num_pages)
217
{
218
@@ -XXX,XX +XXX,XX @@ static int init_dev_ring(PvrdmaRing *ring, struct pvrdma_ring **ring_state,
219
/* RX ring is the second */
220
(*ring_state)++;
221
rc = pvrdma_ring_init(ring, name, pci_dev,
222
- (struct pvrdma_ring *)*ring_state,
223
+ (PvrdmaRingState *)*ring_state,
224
(num_pages - 1) * TARGET_PAGE_SIZE /
225
sizeof(struct pvrdma_cqne),
226
sizeof(struct pvrdma_cqne),
227
diff --git a/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h b/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
228
deleted file mode 100644
229
index XXXXXXX..XXXXXXX
230
--- a/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h
231
+++ /dev/null
232
@@ -XXX,XX +XXX,XX @@
233
-/*
234
- * Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
235
- *
236
- * This program is free software; you can redistribute it and/or
237
- * modify it under the terms of EITHER the GNU General Public License
238
- * version 2 as published by the Free Software Foundation or the BSD
239
- * 2-Clause License. This program is distributed in the hope that it
240
- * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
241
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
242
- * See the GNU General Public License version 2 for more details at
243
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
244
- *
245
- * You should have received a copy of the GNU General Public License
246
- * along with this program available in the file COPYING in the main
247
- * directory of this source tree.
248
- *
249
- * The BSD 2-Clause License
250
- *
251
- * Redistribution and use in source and binary forms, with or
252
- * without modification, are permitted provided that the following
253
- * conditions are met:
254
- *
255
- * - Redistributions of source code must retain the above
256
- * copyright notice, this list of conditions and the following
257
- * disclaimer.
258
- *
259
- * - Redistributions in binary form must reproduce the above
260
- * copyright notice, this list of conditions and the following
261
- * disclaimer in the documentation and/or other materials
262
- * provided with the distribution.
263
- *
264
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
265
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
266
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
267
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
268
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
269
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
270
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
271
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
272
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
273
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
274
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
275
- * OF THE POSSIBILITY OF SUCH DAMAGE.
276
- */
277
-
278
-#ifndef __PVRDMA_RING_H__
279
-#define __PVRDMA_RING_H__
280
-
281
-#include "standard-headers/linux/types.h"
282
-
283
-#define PVRDMA_INVALID_IDX    -1    /* Invalid index. */
284
-
285
-struct pvrdma_ring {
286
-    int prod_tail;    /* Producer tail. */
287
-    int cons_head;    /* Consumer head. */
288
-};
289
-
290
-struct pvrdma_ring_state {
291
-    struct pvrdma_ring tx;    /* Tx ring. */
292
-    struct pvrdma_ring rx;    /* Rx ring. */
293
-};
294
-
295
-static inline int pvrdma_idx_valid(uint32_t idx, uint32_t max_elems)
296
-{
297
-    /* Generates fewer instructions than a less-than. */
298
-    return (idx & ~((max_elems << 1) - 1)) == 0;
299
-}
300
-
301
-static inline int32_t pvrdma_idx(int *var, uint32_t max_elems)
302
-{
303
-    const unsigned int idx = qatomic_read(var);
304
-
305
-    if (pvrdma_idx_valid(idx, max_elems))
306
-        return idx & (max_elems - 1);
307
-    return PVRDMA_INVALID_IDX;
308
-}
309
-
310
-static inline void pvrdma_idx_ring_inc(int *var, uint32_t max_elems)
311
-{
312
-    uint32_t idx = qatomic_read(var) + 1;    /* Increment. */
313
-
314
-    idx &= (max_elems << 1) - 1;        /* Modulo size, flip gen. */
315
-    qatomic_set(var, idx);
316
-}
317
-
318
-static inline int32_t pvrdma_idx_ring_has_space(const struct pvrdma_ring *r,
319
-                     uint32_t max_elems, uint32_t *out_tail)
320
-{
321
-    const uint32_t tail = qatomic_read(&r->prod_tail);
322
-    const uint32_t head = qatomic_read(&r->cons_head);
323
-
324
-    if (pvrdma_idx_valid(tail, max_elems) &&
325
-     pvrdma_idx_valid(head, max_elems)) {
326
-        *out_tail = tail & (max_elems - 1);
327
-        return tail != (head ^ max_elems);
328
-    }
329
-    return PVRDMA_INVALID_IDX;
330
-}
331
-
332
-static inline int32_t pvrdma_idx_ring_has_data(const struct pvrdma_ring *r,
333
-                     uint32_t max_elems, uint32_t *out_head)
334
-{
335
-    const uint32_t tail = qatomic_read(&r->prod_tail);
336
-    const uint32_t head = qatomic_read(&r->cons_head);
337
-
338
-    if (pvrdma_idx_valid(tail, max_elems) &&
339
-     pvrdma_idx_valid(head, max_elems)) {
340
-        *out_head = head & (max_elems - 1);
341
-        return tail != head;
342
-    }
343
-    return PVRDMA_INVALID_IDX;
344
-}
345
-
346
-#endif /* __PVRDMA_RING_H__ */
347
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
348
index XXXXXXX..XXXXXXX 100755
349
--- a/scripts/update-linux-headers.sh
350
+++ b/scripts/update-linux-headers.sh
351
@@ -XXX,XX +XXX,XX @@ sed -e '1h;2,$H;$!d;g' -e 's/[^};]*pvrdma[^(| ]*([^)]*);//g' \
352
"$linux/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h" > \
353
"$tmp_pvrdma_verbs";
354
355
-for i in "$linux/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h" \
356
- "$linux/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h" \
357
+for i in "$linux/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h" \
358
"$tmp_pvrdma_verbs"; do \
359
cp_portable "$i" \
360
"$output/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma/"
361
--
102
--
362
2.7.4
103
2.42.0
363
364
diff view generated by jsdifflib
1
This patch switches to use qemu_receive_receive_iov() which can detect
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
reentrancy and return early.
3
2
4
This is intended to address CVE-2021-3416.
3
This reverts commit 83ddb3dbba2ee0f1767442ae6ee665058aeb1093.
5
4
6
Cc: Prasad J Pandit <ppandit@redhat.com>
5
The added check is no longer necessary due to a change of
7
Cc: qemu-stable@nongnu.org
6
iov_from_buf().
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
---
11
hw/net/net_tx_pkt.c | 2 +-
12
hw/net/net_tx_pkt.c | 4 ----
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 4 deletions(-)
13
14
14
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
15
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/net_tx_pkt.c
17
--- a/hw/net/net_tx_pkt.c
17
+++ b/hw/net/net_tx_pkt.c
18
+++ b/hw/net/net_tx_pkt.c
18
@@ -XXX,XX +XXX,XX @@ static inline void net_tx_pkt_sendv(struct NetTxPkt *pkt,
19
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt)
19
NetClientState *nc, const struct iovec *iov, int iov_cnt)
20
uint32_t csum = 0;
20
{
21
struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG;
21
if (pkt->is_loopback) {
22
22
- nc->info->receive_iov(nc, iov, iov_cnt);
23
- if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) {
23
+ qemu_receive_packet_iov(nc, iov, iov_cnt);
24
- return false;
24
} else {
25
- }
25
qemu_sendv_packet(nc, iov, iov_cnt);
26
-
27
if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) {
28
return false;
26
}
29
}
27
--
30
--
28
2.7.4
31
2.42.0
29
32
30
33
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
When a network or network device is created from the command line or HMP,
3
ipvtap and macvtap create a file for each interface unlike tuntap, which
4
QemuOpts ensures that the id passes the id_wellformed check. However,
4
creates one file shared by all interfaces. Try to open a file dedicated
5
QMP skips this:
5
to the interface first for ipvtap and macvtap.
6
6
7
$ qemu-system-x86_64 -qmp stdio -S -nic user,id=123/456
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
qemu-system-x86_64: -nic user,id=123/456: Parameter id expects an identifier
9
Identifiers consist of letters, digits, -, ., _, starting with a letter.
10
11
$ qemu-system-x86_64 -qmp stdio -S
12
{"execute":"qmp_capabilities"}
13
{"return": {}}
14
{"execute":"netdev_add", "arguments": {"type": "user", "id": "123/456"}}
15
{"return": {}}
16
17
After:
18
19
$ qemu-system-x86_64 -qmp stdio -S
20
{"execute":"qmp_capabilities"}
21
{"return": {}}
22
{"execute":"netdev_add", "arguments": {"type": "user", "id": "123/456"}}
23
{"error": {"class": "GenericError", "desc": "Parameter "id" expects an identifier"}}
24
25
Validity checks should be performed always at the bottom of the call chain,
26
because QMP skips all the steps above. Do this for the network subsystem.
27
28
Cc: Jason Wang <jasowang@redhat.com>
29
Reviewed-by: Eric Blake <eblake@redhat.com>
30
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
31
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
32
---
9
---
33
net/net.c | 12 ++++++++++++
10
net/tap-linux.c | 17 ++++++++++++++---
34
1 file changed, 12 insertions(+)
11
1 file changed, 14 insertions(+), 3 deletions(-)
35
12
36
diff --git a/net/net.c b/net/net.c
13
diff --git a/net/tap-linux.c b/net/tap-linux.c
37
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
38
--- a/net/net.c
15
--- a/net/tap-linux.c
39
+++ b/net/net.c
16
+++ b/net/tap-linux.c
40
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
41
#include "qemu/cutils.h"
18
int len = sizeof(struct virtio_net_hdr);
42
#include "qemu/config-file.h"
19
unsigned int features;
43
#include "qemu/ctype.h"
20
44
+#include "qemu/id.h"
21
- fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
45
#include "qemu/iov.h"
22
+
46
#include "qemu/qemu-print.h"
23
+ ret = if_nametoindex(ifname);
47
#include "qemu/main-loop.h"
24
+ if (ret) {
48
@@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
25
+ g_autofree char *file = g_strdup_printf("/dev/tap%d", ret);
49
}
26
+ fd = open(file, O_RDWR);
50
}
27
+ } else {
51
28
+ fd = -1;
52
+ /*
53
+ * The id for -net has already been checked by QemuOpts and
54
+ * could be automatically generated, in which case it is not
55
+ * well-formed by design. HMP and QMP only call us with
56
+ * is_netdev == true.
57
+ */
58
+ if (is_netdev && !id_wellformed(netdev->id)) {
59
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
60
+ return -1;
61
+ }
29
+ }
62
+
30
+
63
nc = qemu_find_netdev(netdev->id);
31
if (fd < 0) {
64
if (nc) {
32
- error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
65
error_setg(errp, "Duplicate ID '%s'", netdev->id);
33
- return -1;
34
+ fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
35
+ if (fd < 0) {
36
+ error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
37
+ return -1;
38
+ }
39
}
40
memset(&ifr, 0, sizeof(ifr));
41
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
66
--
42
--
67
2.7.4
43
2.42.0
68
69
diff view generated by jsdifflib
Deleted patch
1
During procss_tx_desc(), driver can try to chain data descriptor with
2
legacy descriptor, when will lead underflow for the following
3
calculation in process_tx_desc() for bytes:
4
1
5
if (tp->size + bytes > msh)
6
bytes = msh - tp->size;
7
8
This will lead a infinite loop. So check and fail early if tp->size if
9
greater or equal to msh.
10
11
Reported-by: Alexander Bulekov <alxndr@bu.edu>
12
Reported-by: Cheolwoo Myung <cwmyung@snu.ac.kr>
13
Reported-by: Ruhr-University Bochum <bugs-syssec@rub.de>
14
Cc: Prasad J Pandit <ppandit@redhat.com>
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
18
hw/net/e1000.c | 4 ++++
19
1 file changed, 4 insertions(+)
20
21
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/net/e1000.c
24
+++ b/hw/net/e1000.c
25
@@ -XXX,XX +XXX,XX @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
26
msh = tp->tso_props.hdr_len + tp->tso_props.mss;
27
do {
28
bytes = split_size;
29
+ if (tp->size >= msh) {
30
+ goto eop;
31
+ }
32
if (tp->size + bytes > msh)
33
bytes = msh - tp->size;
34
35
@@ -XXX,XX +XXX,XX @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
36
tp->size += split_size;
37
}
38
39
+eop:
40
if (!(txd_lower & E1000_TXD_CMD_EOP))
41
return;
42
if (!(tp->cptse && tp->size < tp->tso_props.hdr_len)) {
43
--
44
2.7.4
45
46
diff view generated by jsdifflib
Deleted patch
1
This patch switches to use qemu_receive_packet() which can detect
2
reentrancy and return early.
3
1
4
This is intended to address CVE-2021-3416.
5
6
Cc: Prasad J Pandit <ppandit@redhat.com>
7
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
hw/net/e1000.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/e1000.c
17
+++ b/hw/net/e1000.c
18
@@ -XXX,XX +XXX,XX @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
19
20
NetClientState *nc = qemu_get_queue(s->nic);
21
if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) {
22
- nc->info->receive(nc, buf, size);
23
+ qemu_receive_packet(nc, buf, size);
24
} else {
25
qemu_send_packet(nc, buf, size);
26
}
27
--
28
2.7.4
29
30
diff view generated by jsdifflib
Deleted patch
1
This patch switches to use qemu_receive_packet() which can detect
2
reentrancy and return early.
3
1
4
This is intended to address CVE-2021-3416.
5
6
Cc: Prasad J Pandit <ppandit@redhat.com>
7
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
hw/net/dp8393x.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/dp8393x.c
17
+++ b/hw/net/dp8393x.c
18
@@ -XXX,XX +XXX,XX @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
19
s->regs[SONIC_TCR] |= SONIC_TCR_CRSL;
20
if (nc->info->can_receive(nc)) {
21
s->loopback_packet = 1;
22
- nc->info->receive(nc, s->tx_buffer, tx_len);
23
+ qemu_receive_packet(nc, s->tx_buffer, tx_len);
24
}
25
} else {
26
/* Transmit packet */
27
--
28
2.7.4
29
30
diff view generated by jsdifflib
Deleted patch
1
This patch switches to use qemu_receive_packet() which can detect
2
reentrancy and return early.
3
1
4
This is intended to address CVE-2021-3416.
5
6
Cc: Prasad J Pandit <ppandit@redhat.com>
7
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
hw/net/msf2-emac.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/msf2-emac.c
17
+++ b/hw/net/msf2-emac.c
18
@@ -XXX,XX +XXX,XX @@ static void msf2_dma_tx(MSF2EmacState *s)
19
* R_CFG1 bit 0 is set.
20
*/
21
if (s->regs[R_CFG1] & R_CFG1_LB_EN_MASK) {
22
- nc->info->receive(nc, buf, size);
23
+ qemu_receive_packet(nc, buf, size);
24
} else {
25
qemu_send_packet(nc, buf, size);
26
}
27
--
28
2.7.4
29
30
diff view generated by jsdifflib
Deleted patch
1
This patch switches to use qemu_receive_packet() which can detect
2
reentrancy and return early.
3
1
4
This is intended to address CVE-2021-3416.
5
6
Cc: Prasad J Pandit <ppandit@redhat.com>
7
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
hw/net/sungem.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/sungem.c
19
+++ b/hw/net/sungem.c
20
@@ -XXX,XX +XXX,XX @@ static void sungem_send_packet(SunGEMState *s, const uint8_t *buf,
21
NetClientState *nc = qemu_get_queue(s->nic);
22
23
if (s->macregs[MAC_XIFCFG >> 2] & MAC_XIFCFG_LBCK) {
24
- nc->info->receive(nc, buf, size);
25
+ qemu_receive_packet(nc, buf, size);
26
} else {
27
qemu_send_packet(nc, buf, size);
28
}
29
--
30
2.7.4
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Bulekov <alxndr@bu.edu>
2
1
3
This patch switches to use qemu_receive_packet() which can detect
4
reentrancy and return early.
5
6
This is intended to address CVE-2021-3416.
7
8
Cc: Prasad J Pandit <ppandit@redhat.com>
9
Cc: qemu-stable@nongnu.org
10
Buglink: https://bugs.launchpad.net/qemu/+bug/1910826
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
12
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
hw/net/rtl8139.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/net/rtl8139.c
21
+++ b/hw/net/rtl8139.c
22
@@ -XXX,XX +XXX,XX @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
23
}
24
25
DPRINTF("+++ transmit loopback mode\n");
26
- rtl8139_do_receive(qemu_get_queue(s->nic), buf, size, do_interrupt);
27
+ qemu_receive_packet(qemu_get_queue(s->nic), buf, size);
28
29
if (iov) {
30
g_free(buf2);
31
--
32
2.7.4
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Bulekov <alxndr@bu.edu>
2
1
3
This patch switches to use qemu_receive_packet() which can detect
4
reentrancy and return early.
5
6
This is intended to address CVE-2021-3416.
7
8
Cc: Prasad J Pandit <ppandit@redhat.com>
9
Cc: qemu-stable@nongnu.org
10
Buglink: https://bugs.launchpad.net/qemu/+bug/1917085
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
12
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
hw/net/pcnet.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/net/pcnet.c
21
+++ b/hw/net/pcnet.c
22
@@ -XXX,XX +XXX,XX @@ txagain:
23
if (BCR_SWSTYLE(s) == 1)
24
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
25
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
26
- pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
27
+ qemu_receive_packet(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
28
s->looptest = 0;
29
} else {
30
if (s->nic) {
31
--
32
2.7.4
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Bulekov <alxndr@bu.edu>
2
1
3
This patch switches to use qemu_receive_packet() which can detect
4
reentrancy and return early.
5
6
This is intended to address CVE-2021-3416.
7
8
Cc: Prasad J Pandit <ppandit@redhat.com>
9
Cc: qemu-stable@nongnu.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
hw/net/cadence_gem.c | 4 ++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/cadence_gem.c
20
+++ b/hw/net/cadence_gem.c
21
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
22
/* Send the packet somewhere */
23
if (s->phy_loop || (s->regs[GEM_NWCTRL] &
24
GEM_NWCTRL_LOCALLOOP)) {
25
- gem_receive(qemu_get_queue(s->nic), s->tx_packet,
26
- total_bytes);
27
+ qemu_receive_packet(qemu_get_queue(s->nic), s->tx_packet,
28
+ total_bytes);
29
} else {
30
qemu_send_packet(qemu_get_queue(s->nic), s->tx_packet,
31
total_bytes);
32
--
33
2.7.4
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Bulekov <alxndr@bu.edu>
2
1
3
This patch switches to use qemu_receive_packet() which can detect
4
reentrancy and return early.
5
6
This is intended to address CVE-2021-3416.
7
8
Cc: Prasad J Pandit <ppandit@redhat.com>
9
Cc: qemu-stable@nongnu.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
11
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
hw/net/lan9118.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/lan9118.c
20
+++ b/hw/net/lan9118.c
21
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
22
/* FIXME: Honor TX disable, and allow queueing of packets. */
23
if (s->phy_control & 0x4000) {
24
/* This assumes the receive routine doesn't touch the VLANClient. */
25
- lan9118_receive(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
26
+ qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
27
} else {
28
qemu_send_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
29
}
30
--
31
2.7.4
32
33
diff view generated by jsdifflib