1
The following changes since commit 2e02083438962d26ef9dcc7100f3b378104183db:
1
The following changes since commit d9a4282c4b690e45d25c2b933f318bb41eeb271d:
2
2
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2017-11-17 19:08:07 +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 c527e0afcd7d719abc3a5ca5e4c8ac2fe48b999f:
9
for you to fetch changes up to ac2ff9b840ce82cc7d5fd9ce4fd3019a434d7dc9:
10
10
11
hw/net/vmxnet3: Fix code to work on big endian hosts, too (2017-11-20 11:08:00 +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
Ed Swierk (1):
27
Akihiko Odaki (3):
17
net: Transmit zero UDP checksum as 0xFFFF
28
util/iov: Do not assert offset is in iov
29
Revert "hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()"
30
tap-linux: Open ipvtap and macvtap
18
31
19
Jason Wang (1):
32
Eugenio Pérez (2):
20
Revert "Add new PCI ID for i82559a"
33
net: parameterize the removing client from nc list
34
net: move backend cleanup to NIC cleanup
21
35
22
Mao Zhongyi (1):
36
hw/net/net_tx_pkt.c | 4 ----
23
colo-compare: fix the dangerous assignment
37
include/qemu/iov.h | 5 +++--
24
38
net/net.c | 44 ++++++++++++++++++++++++++++++++++----------
25
Stefan Weil (1):
39
net/tap-linux.c | 17 ++++++++++++++---
26
MAINTAINERS: Add missing entry for eepro100 emulation
40
net/vhost-vdpa.c | 8 --------
27
41
util/iov.c | 5 -----
28
Thomas Huth (2):
42
6 files changed, 51 insertions(+), 32 deletions(-)
29
hw/net/eepro100: Fix endianness problem on big endian hosts
30
hw/net/vmxnet3: Fix code to work on big endian hosts, too
31
32
MAINTAINERS | 5 ++
33
hw/net/e1000.c | 2 +-
34
hw/net/eepro100.c | 17 +---
35
hw/net/net_rx_pkt.c | 2 +-
36
hw/net/net_tx_pkt.c | 2 +-
37
hw/net/vmware_utils.h | 6 ++
38
hw/net/vmxnet3.c | 49 ++++++++---
39
hw/net/vmxnet3.h | 230 ++++++++++++++++++++++++++++++-------------------
40
include/hw/compat.h | 4 -
41
include/hw/pci/pci.h | 1 -
42
include/net/checksum.h | 6 ++
43
net/colo-compare.c | 2 +-
44
qemu-options.hx | 2 +-
45
13 files changed, 201 insertions(+), 127 deletions(-)
46
43
47
44
45
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
Since commit ab06ec43577177a442e8 we test the vmxnet3 device in the
3
This change is used in later commits so we can avoid the removal of the
4
pxe-tester, too (when running "make check SPEED=slow"). This now
4
netclient if it is delayed.
5
revealed that the code is not working there if the host is a big
6
endian machine (for example ppc64 or s390x) - "make check SPEED=slow"
7
is now failing on such hosts.
8
5
9
The vmxnet3 code lacks endianness conversions in a couple of places.
6
No functional change intended.
10
Interestingly, the bitfields in the structs in vmxnet3.h already tried to
11
take care of the *bit* endianness of the C compilers - but the code missed
12
to change the *byte* endianness when reading or writing the corresponding
13
structs. So the bitfields are now wrapped into unions which allow to change
14
the byte endianness during runtime with the non-bitfield member of the union.
15
With these changes, "make check SPEED=slow" now properly works on big endian
16
hosts, too.
17
7
18
Reported-by: David Gibson <dgibson@redhat.com>
8
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Acked-by: Jason Wang <jasowang@redhat.com>
20
Reviewed-by: David Gibson <dgibson@redhat.com>
10
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
21
Signed-off-by: Thomas Huth <thuth@redhat.com>
22
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
23
---
12
---
24
hw/net/vmware_utils.h | 6 ++
13
net/net.c | 13 ++++++++-----
25
hw/net/vmxnet3.c | 46 +++++++---
14
1 file changed, 8 insertions(+), 5 deletions(-)
26
hw/net/vmxnet3.h | 230 ++++++++++++++++++++++++++++++--------------------
27
3 files changed, 181 insertions(+), 101 deletions(-)
28
15
29
diff --git a/hw/net/vmware_utils.h b/hw/net/vmware_utils.h
16
diff --git a/net/net.c b/net/net.c
30
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/net/vmware_utils.h
18
--- a/net/net.c
32
+++ b/hw/net/vmware_utils.h
19
+++ b/net/net.c
33
@@ -XXX,XX +XXX,XX @@ vmw_shmem_ld16(PCIDevice *d, hwaddr addr)
20
@@ -XXX,XX +XXX,XX @@ NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
21
return ncs->peer;
22
}
23
24
-static void qemu_cleanup_net_client(NetClientState *nc)
25
+static void qemu_cleanup_net_client(NetClientState *nc,
26
+ bool remove_from_net_clients)
34
{
27
{
35
uint16_t res;
28
- QTAILQ_REMOVE(&net_clients, nc, next);
36
pci_dma_read(d, addr, &res, 2);
29
+ if (remove_from_net_clients) {
37
+ res = le16_to_cpu(res);
30
+ QTAILQ_REMOVE(&net_clients, nc, next);
38
VMW_SHPRN("SHMEM load16: %" PRIx64 " (value 0x%X)", addr, res);
31
+ }
39
return res;
32
40
}
33
if (nc->info->cleanup) {
41
@@ -XXX,XX +XXX,XX @@ static inline void
34
nc->info->cleanup(nc);
42
vmw_shmem_st16(PCIDevice *d, hwaddr addr, uint16_t value)
35
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
43
{
36
}
44
VMW_SHPRN("SHMEM store16: %" PRIx64 " (value 0x%X)", addr, value);
37
45
+ value = cpu_to_le16(value);
38
for (i = 0; i < queues; i++) {
46
pci_dma_write(d, addr, &value, 2);
39
- qemu_cleanup_net_client(ncs[i]);
47
}
40
+ qemu_cleanup_net_client(ncs[i], true);
48
41
}
49
@@ -XXX,XX +XXX,XX @@ vmw_shmem_ld32(PCIDevice *d, hwaddr addr)
42
50
{
43
return;
51
uint32_t res;
44
}
52
pci_dma_read(d, addr, &res, 4);
45
53
+ res = le32_to_cpu(res);
46
for (i = 0; i < queues; i++) {
54
VMW_SHPRN("SHMEM load32: %" PRIx64 " (value 0x%X)", addr, res);
47
- qemu_cleanup_net_client(ncs[i]);
55
return res;
48
+ qemu_cleanup_net_client(ncs[i], true);
56
}
49
qemu_free_net_client(ncs[i]);
57
@@ -XXX,XX +XXX,XX @@ static inline void
58
vmw_shmem_st32(PCIDevice *d, hwaddr addr, uint32_t value)
59
{
60
VMW_SHPRN("SHMEM store32: %" PRIx64 " (value 0x%X)", addr, value);
61
+ value = cpu_to_le32(value);
62
pci_dma_write(d, addr, &value, 4);
63
}
64
65
@@ -XXX,XX +XXX,XX @@ vmw_shmem_ld64(PCIDevice *d, hwaddr addr)
66
{
67
uint64_t res;
68
pci_dma_read(d, addr, &res, 8);
69
+ res = le64_to_cpu(res);
70
VMW_SHPRN("SHMEM load64: %" PRIx64 " (value %" PRIx64 ")", addr, res);
71
return res;
72
}
73
@@ -XXX,XX +XXX,XX @@ static inline void
74
vmw_shmem_st64(PCIDevice *d, hwaddr addr, uint64_t value)
75
{
76
VMW_SHPRN("SHMEM store64: %" PRIx64 " (value %" PRIx64 ")", addr, value);
77
+ value = cpu_to_le64(value);
78
pci_dma_write(d, addr, &value, 8);
79
}
80
81
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/net/vmxnet3.c
84
+++ b/hw/net/vmxnet3.c
85
@@ -XXX,XX +XXX,XX @@ vmxnet3_dump_tx_descr(struct Vmxnet3_TxDesc *descr)
86
"addr %" PRIx64 ", len: %d, gen: %d, rsvd: %d, "
87
"dtype: %d, ext1: %d, msscof: %d, hlen: %d, om: %d, "
88
"eop: %d, cq: %d, ext2: %d, ti: %d, tci: %d",
89
- le64_to_cpu(descr->addr), descr->len, descr->gen, descr->rsvd,
90
+ descr->addr, descr->len, descr->gen, descr->rsvd,
91
descr->dtype, descr->ext1, descr->msscof, descr->hlen, descr->om,
92
descr->eop, descr->cq, descr->ext2, descr->ti, descr->tci);
93
}
94
@@ -XXX,XX +XXX,XX @@ vmxnet3_dump_rx_descr(struct Vmxnet3_RxDesc *descr)
95
{
96
VMW_PKPRN("RX DESCR: addr %" PRIx64 ", len: %d, gen: %d, rsvd: %d, "
97
"dtype: %d, ext1: %d, btype: %d",
98
- le64_to_cpu(descr->addr), descr->len, descr->gen,
99
+ descr->addr, descr->len, descr->gen,
100
descr->rsvd, descr->dtype, descr->ext1, descr->btype);
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_complete_packet(VMXNET3State *s, int qidx, uint32_t tx_ridx)
104
memset(&txcq_descr, 0, sizeof(txcq_descr));
105
txcq_descr.txdIdx = tx_ridx;
106
txcq_descr.gen = vmxnet3_ring_curr_gen(&s->txq_descr[qidx].comp_ring);
107
-
108
+ txcq_descr.val1 = cpu_to_le32(txcq_descr.val1);
109
+ txcq_descr.val2 = cpu_to_le32(txcq_descr.val2);
110
vmxnet3_ring_write_curr_cell(d, &s->txq_descr[qidx].comp_ring, &txcq_descr);
111
112
/* Flush changes in TX descriptor before changing the counter value */
113
@@ -XXX,XX +XXX,XX @@ vmxnet3_on_rx_done_update_stats(VMXNET3State *s,
114
}
50
}
115
}
51
}
116
52
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
117
+static inline void
53
for (i = queues - 1; i >= 0; i--) {
118
+vmxnet3_ring_read_curr_txdesc(PCIDevice *pcidev, Vmxnet3Ring *ring,
54
NetClientState *nc = qemu_get_subqueue(nic, i);
119
+ struct Vmxnet3_TxDesc *txd)
55
120
+{
56
- qemu_cleanup_net_client(nc);
121
+ vmxnet3_ring_read_curr_cell(pcidev, ring, txd);
57
+ qemu_cleanup_net_client(nc, true);
122
+ txd->addr = le64_to_cpu(txd->addr);
58
qemu_free_net_client(nc);
123
+ txd->val1 = le32_to_cpu(txd->val1);
124
+ txd->val2 = le32_to_cpu(txd->val2);
125
+}
126
+
127
static inline bool
128
vmxnet3_pop_next_tx_descr(VMXNET3State *s,
129
int qidx,
130
@@ -XXX,XX +XXX,XX @@ vmxnet3_pop_next_tx_descr(VMXNET3State *s,
131
Vmxnet3Ring *ring = &s->txq_descr[qidx].tx_ring;
132
PCIDevice *d = PCI_DEVICE(s);
133
134
- vmxnet3_ring_read_curr_cell(d, ring, txd);
135
+ vmxnet3_ring_read_curr_txdesc(d, ring, txd);
136
if (txd->gen == vmxnet3_ring_curr_gen(ring)) {
137
/* Only read after generation field verification */
138
smp_rmb();
139
/* Re-read to be sure we got the latest version */
140
- vmxnet3_ring_read_curr_cell(d, ring, txd);
141
+ vmxnet3_ring_read_curr_txdesc(d, ring, txd);
142
VMXNET3_RING_DUMP(VMW_RIPRN, "TX", qidx, ring);
143
*descr_idx = vmxnet3_ring_curr_cell_idx(ring);
144
vmxnet3_inc_tx_consumption_counter(s, qidx);
145
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
146
147
if (!s->skip_current_tx_pkt) {
148
data_len = (txd.len > 0) ? txd.len : VMXNET3_MAX_TX_BUF_SIZE;
149
- data_pa = le64_to_cpu(txd.addr);
150
+ data_pa = txd.addr;
151
152
if (!net_tx_pkt_add_raw_fragment(s->tx_pkt,
153
data_pa,
154
@@ -XXX,XX +XXX,XX @@ vmxnet3_read_next_rx_descr(VMXNET3State *s, int qidx, int ridx,
155
Vmxnet3Ring *ring = &s->rxq_descr[qidx].rx_ring[ridx];
156
*didx = vmxnet3_ring_curr_cell_idx(ring);
157
vmxnet3_ring_read_curr_cell(d, ring, dbuf);
158
+ dbuf->addr = le64_to_cpu(dbuf->addr);
159
+ dbuf->val1 = le32_to_cpu(dbuf->val1);
160
+ dbuf->ext1 = le32_to_cpu(dbuf->ext1);
161
}
162
163
static inline uint8_t
164
@@ -XXX,XX +XXX,XX @@ vmxnet3_pop_rxc_descr(VMXNET3State *s, int qidx, uint32_t *descr_gen)
165
166
pci_dma_read(PCI_DEVICE(s),
167
daddr, &rxcd, sizeof(struct Vmxnet3_RxCompDesc));
168
+ rxcd.val1 = le32_to_cpu(rxcd.val1);
169
+ rxcd.val2 = le32_to_cpu(rxcd.val2);
170
+ rxcd.val3 = le32_to_cpu(rxcd.val3);
171
ring_gen = vmxnet3_ring_curr_gen(&s->rxq_descr[qidx].comp_ring);
172
173
if (rxcd.gen != ring_gen) {
174
@@ -XXX,XX +XXX,XX @@ vmxnet3_pci_dma_writev(PCIDevice *pci_dev,
175
}
59
}
176
}
60
177
178
+static void
179
+vmxnet3_pci_dma_write_rxcd(PCIDevice *pcidev, dma_addr_t pa,
180
+ struct Vmxnet3_RxCompDesc *rxcd)
181
+{
182
+ rxcd->val1 = cpu_to_le32(rxcd->val1);
183
+ rxcd->val2 = cpu_to_le32(rxcd->val2);
184
+ rxcd->val3 = cpu_to_le32(rxcd->val3);
185
+ pci_dma_write(pcidev, pa, rxcd, sizeof(*rxcd));
186
+}
187
+
188
static bool
189
vmxnet3_indicate_packet(VMXNET3State *s)
190
{
191
@@ -XXX,XX +XXX,XX @@ vmxnet3_indicate_packet(VMXNET3State *s)
192
}
193
194
chunk_size = MIN(bytes_left, rxd.len);
195
- vmxnet3_pci_dma_writev(d, data, bytes_copied,
196
- le64_to_cpu(rxd.addr), chunk_size);
197
+ vmxnet3_pci_dma_writev(d, data, bytes_copied, rxd.addr, chunk_size);
198
bytes_copied += chunk_size;
199
bytes_left -= chunk_size;
200
201
vmxnet3_dump_rx_descr(&rxd);
202
203
if (ready_rxcd_pa != 0) {
204
- pci_dma_write(d, ready_rxcd_pa, &rxcd, sizeof(rxcd));
205
+ vmxnet3_pci_dma_write_rxcd(d, ready_rxcd_pa, &rxcd);
206
}
207
208
memset(&rxcd, 0, sizeof(struct Vmxnet3_RxCompDesc));
209
@@ -XXX,XX +XXX,XX @@ vmxnet3_indicate_packet(VMXNET3State *s)
210
rxcd.eop = 1;
211
rxcd.err = (bytes_left != 0);
212
213
- pci_dma_write(d, ready_rxcd_pa, &rxcd, sizeof(rxcd));
214
+ vmxnet3_pci_dma_write_rxcd(d, ready_rxcd_pa, &rxcd);
215
216
/* Flush RX descriptor changes */
217
smp_wmb();
218
diff --git a/hw/net/vmxnet3.h b/hw/net/vmxnet3.h
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/net/vmxnet3.h
221
+++ b/hw/net/vmxnet3.h
222
@@ -XXX,XX +XXX,XX @@ enum {
223
struct Vmxnet3_TxDesc {
224
__le64 addr;
225
226
+ union {
227
+ struct {
228
#ifdef __BIG_ENDIAN_BITFIELD
229
- u32 msscof:14; /* MSS, checksum offset, flags */
230
- u32 ext1:1;
231
- u32 dtype:1; /* descriptor type */
232
- u32 rsvd:1;
233
- u32 gen:1; /* generation bit */
234
- u32 len:14;
235
+ u32 msscof:14; /* MSS, checksum offset, flags */
236
+ u32 ext1:1;
237
+ u32 dtype:1; /* descriptor type */
238
+ u32 rsvd:1;
239
+ u32 gen:1; /* generation bit */
240
+ u32 len:14;
241
#else
242
- u32 len:14;
243
- u32 gen:1; /* generation bit */
244
- u32 rsvd:1;
245
- u32 dtype:1; /* descriptor type */
246
- u32 ext1:1;
247
- u32 msscof:14; /* MSS, checksum offset, flags */
248
+ u32 len:14;
249
+ u32 gen:1; /* generation bit */
250
+ u32 rsvd:1;
251
+ u32 dtype:1; /* descriptor type */
252
+ u32 ext1:1;
253
+ u32 msscof:14; /* MSS, checksum offset, flags */
254
#endif /* __BIG_ENDIAN_BITFIELD */
255
-
256
+ };
257
+ u32 val1;
258
+ };
259
+
260
+ union {
261
+ struct {
262
#ifdef __BIG_ENDIAN_BITFIELD
263
- u32 tci:16; /* Tag to Insert */
264
- u32 ti:1; /* VLAN Tag Insertion */
265
- u32 ext2:1;
266
- u32 cq:1; /* completion request */
267
- u32 eop:1; /* End Of Packet */
268
- u32 om:2; /* offload mode */
269
- u32 hlen:10; /* header len */
270
+ u32 tci:16; /* Tag to Insert */
271
+ u32 ti:1; /* VLAN Tag Insertion */
272
+ u32 ext2:1;
273
+ u32 cq:1; /* completion request */
274
+ u32 eop:1; /* End Of Packet */
275
+ u32 om:2; /* offload mode */
276
+ u32 hlen:10; /* header len */
277
#else
278
- u32 hlen:10; /* header len */
279
- u32 om:2; /* offload mode */
280
- u32 eop:1; /* End Of Packet */
281
- u32 cq:1; /* completion request */
282
- u32 ext2:1;
283
- u32 ti:1; /* VLAN Tag Insertion */
284
- u32 tci:16; /* Tag to Insert */
285
+ u32 hlen:10; /* header len */
286
+ u32 om:2; /* offload mode */
287
+ u32 eop:1; /* End Of Packet */
288
+ u32 cq:1; /* completion request */
289
+ u32 ext2:1;
290
+ u32 ti:1; /* VLAN Tag Insertion */
291
+ u32 tci:16; /* Tag to Insert */
292
#endif /* __BIG_ENDIAN_BITFIELD */
293
+ };
294
+ u32 val2;
295
+ };
296
};
297
298
/* TxDesc.OM values */
299
@@ -XXX,XX +XXX,XX @@ struct Vmxnet3_TxDataDesc {
300
#define VMXNET3_TCD_GEN_DWORD_SHIFT 3
301
302
struct Vmxnet3_TxCompDesc {
303
- u32 txdIdx:12; /* Index of the EOP TxDesc */
304
- u32 ext1:20;
305
-
306
+ union {
307
+ struct {
308
+#ifdef __BIG_ENDIAN_BITFIELD
309
+ u32 ext1:20;
310
+ u32 txdIdx:12; /* Index of the EOP TxDesc */
311
+#else
312
+ u32 txdIdx:12; /* Index of the EOP TxDesc */
313
+ u32 ext1:20;
314
+#endif
315
+ };
316
+ u32 val1;
317
+ };
318
__le32 ext2;
319
__le32 ext3;
320
321
- u32 rsvd:24;
322
- u32 type:7; /* completion type */
323
- u32 gen:1; /* generation bit */
324
+ union {
325
+ struct {
326
+#ifdef __BIG_ENDIAN_BITFIELD
327
+ u32 gen:1; /* generation bit */
328
+ u32 type:7; /* completion type */
329
+ u32 rsvd:24;
330
+#else
331
+ u32 rsvd:24;
332
+ u32 type:7; /* completion type */
333
+ u32 gen:1; /* generation bit */
334
+#endif
335
+ };
336
+ u32 val2;
337
+ };
338
};
339
340
struct Vmxnet3_RxDesc {
341
__le64 addr;
342
-
343
+ union {
344
+ struct {
345
#ifdef __BIG_ENDIAN_BITFIELD
346
- u32 gen:1; /* Generation bit */
347
- u32 rsvd:15;
348
- u32 dtype:1; /* Descriptor type */
349
- u32 btype:1; /* Buffer Type */
350
- u32 len:14;
351
+ u32 gen:1; /* Generation bit */
352
+ u32 rsvd:15;
353
+ u32 dtype:1; /* Descriptor type */
354
+ u32 btype:1; /* Buffer Type */
355
+ u32 len:14;
356
#else
357
- u32 len:14;
358
- u32 btype:1; /* Buffer Type */
359
- u32 dtype:1; /* Descriptor type */
360
- u32 rsvd:15;
361
- u32 gen:1; /* Generation bit */
362
+ u32 len:14;
363
+ u32 btype:1; /* Buffer Type */
364
+ u32 dtype:1; /* Descriptor type */
365
+ u32 rsvd:15;
366
+ u32 gen:1; /* Generation bit */
367
#endif
368
+ };
369
+ u32 val1;
370
+ };
371
u32 ext1;
372
};
373
374
@@ -XXX,XX +XXX,XX @@ struct Vmxnet3_RxDesc {
375
#define VMXNET3_RXD_GEN_SHIFT 31
376
377
struct Vmxnet3_RxCompDesc {
378
+ union {
379
+ struct {
380
#ifdef __BIG_ENDIAN_BITFIELD
381
- u32 ext2:1;
382
- u32 cnc:1; /* Checksum Not Calculated */
383
- u32 rssType:4; /* RSS hash type used */
384
- u32 rqID:10; /* rx queue/ring ID */
385
- u32 sop:1; /* Start of Packet */
386
- u32 eop:1; /* End of Packet */
387
- u32 ext1:2;
388
- u32 rxdIdx:12; /* Index of the RxDesc */
389
+ u32 ext2:1;
390
+ u32 cnc:1; /* Checksum Not Calculated */
391
+ u32 rssType:4; /* RSS hash type used */
392
+ u32 rqID:10; /* rx queue/ring ID */
393
+ u32 sop:1; /* Start of Packet */
394
+ u32 eop:1; /* End of Packet */
395
+ u32 ext1:2;
396
+ u32 rxdIdx:12; /* Index of the RxDesc */
397
#else
398
- u32 rxdIdx:12; /* Index of the RxDesc */
399
- u32 ext1:2;
400
- u32 eop:1; /* End of Packet */
401
- u32 sop:1; /* Start of Packet */
402
- u32 rqID:10; /* rx queue/ring ID */
403
- u32 rssType:4; /* RSS hash type used */
404
- u32 cnc:1; /* Checksum Not Calculated */
405
- u32 ext2:1;
406
+ u32 rxdIdx:12; /* Index of the RxDesc */
407
+ u32 ext1:2;
408
+ u32 eop:1; /* End of Packet */
409
+ u32 sop:1; /* Start of Packet */
410
+ u32 rqID:10; /* rx queue/ring ID */
411
+ u32 rssType:4; /* RSS hash type used */
412
+ u32 cnc:1; /* Checksum Not Calculated */
413
+ u32 ext2:1;
414
#endif /* __BIG_ENDIAN_BITFIELD */
415
+ };
416
+ u32 val1;
417
+ };
418
419
__le32 rssHash; /* RSS hash value */
420
421
+ union {
422
+ struct {
423
#ifdef __BIG_ENDIAN_BITFIELD
424
- u32 tci:16; /* Tag stripped */
425
- u32 ts:1; /* Tag is stripped */
426
- u32 err:1; /* Error */
427
- u32 len:14; /* data length */
428
+ u32 tci:16; /* Tag stripped */
429
+ u32 ts:1; /* Tag is stripped */
430
+ u32 err:1; /* Error */
431
+ u32 len:14; /* data length */
432
#else
433
- u32 len:14; /* data length */
434
- u32 err:1; /* Error */
435
- u32 ts:1; /* Tag is stripped */
436
- u32 tci:16; /* Tag stripped */
437
+ u32 len:14; /* data length */
438
+ u32 err:1; /* Error */
439
+ u32 ts:1; /* Tag is stripped */
440
+ u32 tci:16; /* Tag stripped */
441
#endif /* __BIG_ENDIAN_BITFIELD */
442
+ };
443
+ u32 val2;
444
+ };
445
446
-
447
+ union {
448
+ struct {
449
#ifdef __BIG_ENDIAN_BITFIELD
450
- u32 gen:1; /* generation bit */
451
- u32 type:7; /* completion type */
452
- u32 fcs:1; /* Frame CRC correct */
453
- u32 frg:1; /* IP Fragment */
454
- u32 v4:1; /* IPv4 */
455
- u32 v6:1; /* IPv6 */
456
- u32 ipc:1; /* IP Checksum Correct */
457
- u32 tcp:1; /* TCP packet */
458
- u32 udp:1; /* UDP packet */
459
- u32 tuc:1; /* TCP/UDP Checksum Correct */
460
- u32 csum:16;
461
+ u32 gen:1; /* generation bit */
462
+ u32 type:7; /* completion type */
463
+ u32 fcs:1; /* Frame CRC correct */
464
+ u32 frg:1; /* IP Fragment */
465
+ u32 v4:1; /* IPv4 */
466
+ u32 v6:1; /* IPv6 */
467
+ u32 ipc:1; /* IP Checksum Correct */
468
+ u32 tcp:1; /* TCP packet */
469
+ u32 udp:1; /* UDP packet */
470
+ u32 tuc:1; /* TCP/UDP Checksum Correct */
471
+ u32 csum:16;
472
#else
473
- u32 csum:16;
474
- u32 tuc:1; /* TCP/UDP Checksum Correct */
475
- u32 udp:1; /* UDP packet */
476
- u32 tcp:1; /* TCP packet */
477
- u32 ipc:1; /* IP Checksum Correct */
478
- u32 v6:1; /* IPv6 */
479
- u32 v4:1; /* IPv4 */
480
- u32 frg:1; /* IP Fragment */
481
- u32 fcs:1; /* Frame CRC correct */
482
- u32 type:7; /* completion type */
483
- u32 gen:1; /* generation bit */
484
+ u32 csum:16;
485
+ u32 tuc:1; /* TCP/UDP Checksum Correct */
486
+ u32 udp:1; /* UDP packet */
487
+ u32 tcp:1; /* TCP packet */
488
+ u32 ipc:1; /* IP Checksum Correct */
489
+ u32 v6:1; /* IPv6 */
490
+ u32 v4:1; /* IPv4 */
491
+ u32 frg:1; /* IP Fragment */
492
+ u32 fcs:1; /* Frame CRC correct */
493
+ u32 type:7; /* completion type */
494
+ u32 gen:1; /* generation bit */
495
#endif /* __BIG_ENDIAN_BITFIELD */
496
+ };
497
+ u32 val3;
498
+ };
499
};
500
501
/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
502
--
61
--
503
2.7.4
62
2.42.0
504
63
505
64
diff view generated by jsdifflib
1
From: Stefan Weil <sw@weilnetz.de>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
Signed-off-by: Stefan Weil <sw@weilnetz.de>
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>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
22
---
6
MAINTAINERS | 5 +++++
23
net/net.c | 33 +++++++++++++++++++++++++++------
7
1 file changed, 5 insertions(+)
24
net/vhost-vdpa.c | 8 --------
25
2 files changed, 27 insertions(+), 14 deletions(-)
8
26
9
diff --git a/MAINTAINERS b/MAINTAINERS
27
diff --git a/net/net.c b/net/net.c
10
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
11
--- a/MAINTAINERS
29
--- a/net/net.c
12
+++ b/MAINTAINERS
30
+++ b/net/net.c
13
@@ -XXX,XX +XXX,XX @@ M: Dmitry Fleytman <dmitry@daynix.com>
31
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
14
S: Maintained
32
object_unparent(OBJECT(nf));
15
F: hw/net/e1000e*
33
}
16
34
17
+eepro100
35
- /* If there is a peer NIC, delete and cleanup client, but do not free. */
18
+M: Stefan Weil <sw@weilnetz.de>
36
+ /*
19
+S: Maintained
37
+ * If there is a peer NIC, transfer ownership to it. Delete the client
20
+F: hw/net/eepro100.c
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);
21
+
93
+
22
Generic Loader
94
+ if (nic->peer_deleted) {
23
M: Alistair Francis <alistair.francis@xilinx.com>
95
+ int queues = MAX(nic->conf->peers.queues, 1);
24
S: Maintained
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) {
25
--
125
--
26
2.7.4
126
2.42.0
27
127
28
128
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Cc: Peter Maydell <peter.maydell@linaro.org>
3
iov_from_buf(), iov_to_buf(), iov_memset(), and iov_copy() asserts
4
Cc: Jason Wang <jasowang@redhat.com>
4
that the given offset fits in the iov while tolerating the specified
5
Cc: Zhang Chen <zhangckid@gmail.com>
5
number of bytes to operate with to be greater than the size of iov.
6
Cc: Li Zhijian <lizhijian@cn.fujitsu.com>
6
This is inconsistent so remove the assertions.
7
Cc: Paolo Bonzini <pbonzini@redhat.com>
7
8
Fixes: 8ec14402029d783720f4312ed8a925548e1dad61
8
Asserting the offset fits in the iov makes sense if it is expected that
9
Reported-by: Peter Maydell <peter.maydell@linaro.org>
9
there are other operations that process the content before the offset
10
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
10
and the content is processed in order. Under this expectation, the
11
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
11
offset should point to the end of bytes that are previously processed
12
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
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()").
16
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.
23
24
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
25
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
26
---
15
net/colo-compare.c | 2 +-
27
include/qemu/iov.h | 5 +++--
16
1 file changed, 1 insertion(+), 1 deletion(-)
28
util/iov.c | 5 -----
29
2 files changed, 3 insertions(+), 7 deletions(-)
17
30
18
diff --git a/net/colo-compare.c b/net/colo-compare.c
31
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
19
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
20
--- a/net/colo-compare.c
33
--- a/include/qemu/iov.h
21
+++ b/net/colo-compare.c
34
+++ b/include/qemu/iov.h
22
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
35
@@ -XXX,XX +XXX,XX @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
23
"drop packet");
36
* only part of data will be copied, up to the end of the iovec.
37
* Number of bytes actually copied will be returned, which is
38
* min(bytes, iov_size(iov)-offset)
39
- * `Offset' must point to the inside of iovec.
40
+ * Returns 0 when `offset' points to the outside of iovec.
41
*/
42
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
43
size_t offset, const void *buf, size_t bytes);
44
@@ -XXX,XX +XXX,XX @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
45
/**
46
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
47
* starting at byte offset `start', to value `fillc', repeating it
48
- * `bytes' number of times. `Offset' must point to the inside of iovec.
49
+ * `bytes' number of times.
50
* If `bytes' is large enough, only last bytes portion of iovec,
51
* up to the end of it, will be filled with the specified value.
52
* Function return actual number of bytes processed, which is
53
* min(size, iov_size(iov) - offset).
54
+ * Returns 0 when `offset' points to the outside of iovec.
55
*/
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
59
index XXXXXXX..XXXXXXX 100644
60
--- a/util/iov.c
61
+++ b/util/iov.c
62
@@ -XXX,XX +XXX,XX @@ size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
63
offset -= iov[i].iov_len;
24
}
64
}
25
}
65
}
26
- con = &conn;
66
- assert(offset == 0);
27
+ *con = conn;
67
return done;
28
68
}
29
return 0;
69
70
@@ -XXX,XX +XXX,XX @@ size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
71
offset -= iov[i].iov_len;
72
}
73
}
74
- assert(offset == 0);
75
return done;
76
}
77
78
@@ -XXX,XX +XXX,XX @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
79
offset -= iov[i].iov_len;
80
}
81
}
82
- assert(offset == 0);
83
return done;
84
}
85
86
@@ -XXX,XX +XXX,XX @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
87
bytes -= len;
88
offset = 0;
89
}
90
- assert(offset == 0);
91
return j;
92
}
93
94
@@ -XXX,XX +XXX,XX @@ size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
95
soffset -= src_iov[i].iov_len;
96
}
97
}
98
- assert(soffset == 0); /* offset beyond end of src */
99
100
return done;
30
}
101
}
31
--
102
--
32
2.7.4
103
2.42.0
33
34
diff view generated by jsdifflib
Deleted patch
1
This reverts commit 5e89dc01133f8f5e621f6b66b356c6f37d31dafb since:
2
1
3
- we should use ID in the spec instead the one used by OEM
4
- in the future, we should allow changing id through either property
5
or EEPROM file.
6
7
Cc: Stefan Weil <sw@weilnetz.de>
8
Cc: Michael Nawrocki <michael.nawrocki@gtri.gatech.edu>
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Reviewed-by: Stefan Weil <sw@weilnetz.de>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
hw/net/eepro100.c | 13 -------------
15
include/hw/compat.h | 4 ----
16
include/hw/pci/pci.h | 1 -
17
qemu-options.hx | 2 +-
18
4 files changed, 1 insertion(+), 19 deletions(-)
19
20
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/eepro100.c
23
+++ b/hw/net/eepro100.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct {
25
const char *name;
26
const char *desc;
27
uint16_t device_id;
28
- uint16_t alt_device_id;
29
uint8_t revision;
30
uint16_t subsystem_vendor_id;
31
uint16_t subsystem_id;
32
@@ -XXX,XX +XXX,XX @@ typedef struct {
33
/* Quasi static device properties (no need to save them). */
34
uint16_t stats_size;
35
bool has_extended_tcb_support;
36
- bool use_alt_device_id;
37
} EEPRO100State;
38
39
/* Word indices in EEPROM. */
40
@@ -XXX,XX +XXX,XX @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
41
42
TRACE(OTHER, logout("\n"));
43
44
- /* By default, the i82559a adapter uses the legacy PCI ID (for the
45
- * i82557). This allows the PCI ID to be changed to the alternate
46
- * i82559 ID if needed.
47
- */
48
- if (s->use_alt_device_id && strcmp(info->name, "i82559a") == 0) {
49
- pci_config_set_device_id(s->dev.config, info->alt_device_id);
50
- }
51
-
52
s->device = info->device;
53
54
e100_pci_reset(s, &local_err);
55
@@ -XXX,XX +XXX,XX @@ static E100PCIDeviceInfo e100_devices[] = {
56
.desc = "Intel i82559A Ethernet",
57
.device = i82559A,
58
.device_id = PCI_DEVICE_ID_INTEL_82557,
59
- .alt_device_id = PCI_DEVICE_ID_INTEL_82559,
60
.revision = 0x06,
61
.stats_size = 80,
62
.has_extended_tcb_support = true,
63
@@ -XXX,XX +XXX,XX @@ static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s)
64
65
static Property e100_properties[] = {
66
DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
67
- DEFINE_PROP_BOOL("x-use-alt-device-id", EEPRO100State, use_alt_device_id,
68
- true),
69
DEFINE_PROP_END_OF_LIST(),
70
};
71
72
diff --git a/include/hw/compat.h b/include/hw/compat.h
73
index XXXXXXX..XXXXXXX 100644
74
--- a/include/hw/compat.h
75
+++ b/include/hw/compat.h
76
@@ -XXX,XX +XXX,XX @@
77
.driver = "virtio-tablet-device",\
78
.property = "wheel-axis",\
79
.value = "false",\
80
- },{\
81
- .driver = "i82559a",\
82
- .property = "x-use-alt-device-id",\
83
- .value = "false",\
84
},
85
86
#define HW_COMPAT_2_9 \
87
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
88
index XXXXXXX..XXXXXXX 100644
89
--- a/include/hw/pci/pci.h
90
+++ b/include/hw/pci/pci.h
91
@@ -XXX,XX +XXX,XX @@ extern bool pci_available;
92
/* Intel (0x8086) */
93
#define PCI_DEVICE_ID_INTEL_82551IT 0x1209
94
#define PCI_DEVICE_ID_INTEL_82557 0x1229
95
-#define PCI_DEVICE_ID_INTEL_82559 0x1030
96
#define PCI_DEVICE_ID_INTEL_82801IR 0x2922
97
98
/* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */
99
diff --git a/qemu-options.hx b/qemu-options.hx
100
index XXXXXXX..XXXXXXX 100644
101
--- a/qemu-options.hx
102
+++ b/qemu-options.hx
103
@@ -XXX,XX +XXX,XX @@ that the card should have; this option currently only affects virtio cards; set
104
@var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single
105
NIC is created. QEMU can emulate several different models of network card.
106
Valid values for @var{type} are
107
-@code{virtio}, @code{i82551}, @code{i82557b}, @code{i82559a}, @code{i82559er},
108
+@code{virtio}, @code{i82551}, @code{i82557b}, @code{i82559er},
109
@code{ne2k_pci}, @code{ne2k_isa}, @code{pcnet}, @code{rtl8139},
110
@code{e1000}, @code{smc91c111}, @code{lance} and @code{mcf_fec}.
111
Not all devices are supported on all targets. Use @code{-net nic,model=help}
112
--
113
2.7.4
114
115
diff view generated by jsdifflib
1
From: Ed Swierk <eswierk@skyportsystems.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The checksum algorithm used by IPv4, TCP and UDP allows a zero value
3
This reverts commit 83ddb3dbba2ee0f1767442ae6ee665058aeb1093.
4
to be represented by either 0x0000 and 0xFFFF. But per RFC 768, a zero
5
UDP checksum must be transmitted as 0xFFFF because 0x0000 is a special
6
value meaning no checksum.
7
4
8
Substitute 0xFFFF whenever a checksum is computed as zero when
5
The added check is no longer necessary due to a change of
9
modifying a UDP datagram header. Doing this on IPv4 and TCP checksums
6
iov_from_buf().
10
is unnecessary but legal. Add a wrapper for net_checksum_finish() that
11
makes the substitution.
12
7
13
(We can't just change net_checksum_finish(), as that function is also
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
used by receivers to verify checksums, and in that case the expected
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
value is always 0x0000.)
16
17
Signed-off-by: Ed Swierk <eswierk@skyportsystems.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
---
11
---
20
hw/net/e1000.c | 2 +-
12
hw/net/net_tx_pkt.c | 4 ----
21
hw/net/net_rx_pkt.c | 2 +-
13
1 file changed, 4 deletions(-)
22
hw/net/net_tx_pkt.c | 2 +-
23
hw/net/vmxnet3.c | 3 ++-
24
include/net/checksum.h | 6 ++++++
25
5 files changed, 11 insertions(+), 4 deletions(-)
26
14
27
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/e1000.c
30
+++ b/hw/net/e1000.c
31
@@ -XXX,XX +XXX,XX @@ putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
32
n = cse + 1;
33
if (sloc < n-1) {
34
sum = net_checksum_add(n-css, data+css);
35
- stw_be_p(data + sloc, net_checksum_finish(sum));
36
+ stw_be_p(data + sloc, net_checksum_finish_nozero(sum));
37
}
38
}
39
40
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/net/net_rx_pkt.c
43
+++ b/hw/net/net_rx_pkt.c
44
@@ -XXX,XX +XXX,XX @@ _net_rx_pkt_calc_l4_csum(struct NetRxPkt *pkt)
45
cntr += net_checksum_add_iov(pkt->vec, pkt->vec_len,
46
pkt->l4hdr_off, csl, cso);
47
48
- csum = net_checksum_finish(cntr);
49
+ csum = net_checksum_finish_nozero(cntr);
50
51
trace_net_rx_pkt_l4_csum_calc_csum(pkt->l4hdr_off, csl, cntr, csum);
52
53
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
54
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/net/net_tx_pkt.c
17
--- a/hw/net/net_tx_pkt.c
56
+++ b/hw/net/net_tx_pkt.c
18
+++ b/hw/net/net_tx_pkt.c
57
@@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
19
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt)
58
net_checksum_add_iov(iov, iov_len, pkt->virt_hdr.csum_start, csl, cso);
20
uint32_t csum = 0;
59
21
struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG;
60
/* Put the checksum obtained into the packet */
22
61
- csum = cpu_to_be16(net_checksum_finish(csum_cntr));
23
- if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) {
62
+ csum = cpu_to_be16(net_checksum_finish_nozero(csum_cntr));
24
- return false;
63
iov_from_buf(iov, iov_len, csum_offset, &csum, sizeof csum);
25
- }
64
}
26
-
65
27
if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) {
66
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
28
return false;
67
index XXXXXXX..XXXXXXX 100644
29
}
68
--- a/hw/net/vmxnet3.c
69
+++ b/hw/net/vmxnet3.c
70
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
71
data = (uint8_t *)pkt_data + vhdr->csum_start;
72
len = pkt_len - vhdr->csum_start;
73
/* Put the checksum obtained into the packet */
74
- stw_be_p(data + vhdr->csum_offset, net_raw_checksum(data, len));
75
+ stw_be_p(data + vhdr->csum_offset,
76
+ net_checksum_finish_nozero(net_checksum_add(len, data)));
77
78
vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
79
vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
80
diff --git a/include/net/checksum.h b/include/net/checksum.h
81
index XXXXXXX..XXXXXXX 100644
82
--- a/include/net/checksum.h
83
+++ b/include/net/checksum.h
84
@@ -XXX,XX +XXX,XX @@ net_checksum_add(int len, uint8_t *buf)
85
}
86
87
static inline uint16_t
88
+net_checksum_finish_nozero(uint32_t sum)
89
+{
90
+ return net_checksum_finish(sum) ?: 0xFFFF;
91
+}
92
+
93
+static inline uint16_t
94
net_raw_checksum(uint8_t *data, int length)
95
{
96
return net_checksum_finish(net_checksum_add(length, data));
97
--
30
--
98
2.7.4
31
2.42.0
99
32
100
33
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Since commit 1865e288a823c764cd4344d ("Fix eepro100 simple transmission
3
ipvtap and macvtap create a file for each interface unlike tuntap, which
4
mode"), the test/pxe-test is broken for the eepro100 device on big
4
creates one file shared by all interfaces. Try to open a file dedicated
5
endian hosts. However, it seems like that commit did not introduce the
5
to the interface first for ipvtap and macvtap.
6
problem, but just uncovered it: The EEPRO100State->tx.tbd_array_addr and
7
EEPRO100State->tx.tcb_bytes fields are already in host byte order, since
8
they have already been byte-swapped in the read_cb() function.
9
Thus byte-swapping them in tx_command() again results in the wrong
10
endianness. Removing the byte-swapping here fixes the pxe-test.
11
6
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
9
---
15
hw/net/eepro100.c | 4 ++--
10
net/tap-linux.c | 17 ++++++++++++++---
16
1 file changed, 2 insertions(+), 2 deletions(-)
11
1 file changed, 14 insertions(+), 3 deletions(-)
17
12
18
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
13
diff --git a/net/tap-linux.c b/net/tap-linux.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/net/eepro100.c
15
--- a/net/tap-linux.c
21
+++ b/hw/net/eepro100.c
16
+++ b/net/tap-linux.c
22
@@ -XXX,XX +XXX,XX @@ static void read_cb(EEPRO100State *s)
17
@@ -XXX,XX +XXX,XX @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
23
18
int len = sizeof(struct virtio_net_hdr);
24
static void tx_command(EEPRO100State *s)
19
unsigned int features;
25
{
20
26
- uint32_t tbd_array = le32_to_cpu(s->tx.tbd_array_addr);
21
- fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
27
- uint16_t tcb_bytes = (le16_to_cpu(s->tx.tcb_bytes) & 0x3fff);
22
+
28
+ uint32_t tbd_array = s->tx.tbd_array_addr;
23
+ ret = if_nametoindex(ifname);
29
+ uint16_t tcb_bytes = s->tx.tcb_bytes & 0x3fff;
24
+ if (ret) {
30
/* Sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes. */
25
+ g_autofree char *file = g_strdup_printf("/dev/tap%d", ret);
31
uint8_t buf[2600];
26
+ fd = open(file, O_RDWR);
32
uint16_t size = 0;
27
+ } else {
28
+ fd = -1;
29
+ }
30
+
31
if (fd < 0) {
32
- error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
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;
33
--
42
--
34
2.7.4
43
2.42.0
35
36
diff view generated by jsdifflib