1
The following changes since commit cfe68ae025f704f336d7dd3d1903ce37b445831d:
1
The following changes since commit d9a4282c4b690e45d25c2b933f318bb41eeb271d:
2
2
3
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging (2020-03-26 20:55:54 +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 f3b364f4f77fcb24cec468f518bf5e093dc27cb7:
9
for you to fetch changes up to ac2ff9b840ce82cc7d5fd9ce4fd3019a434d7dc9:
10
10
11
hw/net/allwinner-sun8i-emac.c: Fix REG_ADDR_HIGH/LOW reads (2020-03-27 18:59:47 +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
Andrew Melnychenko (1):
27
Akihiko Odaki (3):
17
Fixed integer overflow in e1000e
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
Peter Maydell (2):
32
Eugenio Pérez (2):
20
hw/net/i82596.c: Avoid reading off end of buffer in i82596_receive()
33
net: parameterize the removing client from nc list
21
hw/net/allwinner-sun8i-emac.c: Fix REG_ADDR_HIGH/LOW reads
34
net: move backend cleanup to NIC cleanup
22
35
23
Philippe Mathieu-Daudé (7):
36
hw/net/net_tx_pkt.c | 4 ----
24
hw/net/i82596: Correct command bitmask (CID 1419392)
37
include/qemu/iov.h | 5 +++--
25
hw/net/e1000e_core: Let e1000e_can_receive() return a boolean
38
net/net.c | 44 ++++++++++++++++++++++++++++++++++----------
26
hw/net/smc91c111: Let smc91c111_can_receive() return a boolean
39
net/tap-linux.c | 17 ++++++++++++++---
27
hw/net/rtl8139: Simplify if/else statement
40
net/vhost-vdpa.c | 8 --------
28
hw/net/rtl8139: Update coding style to make checkpatch.pl happy
41
util/iov.c | 5 -----
29
hw/net: Make NetCanReceive() return a boolean
42
6 files changed, 51 insertions(+), 32 deletions(-)
30
hw/net/can: Make CanBusClientInfo::can_receive() return a boolean
31
32
Prasad J Pandit (1):
33
net: tulip: check frame size and r/w data length
34
35
Zhang Chen (2):
36
net/colo-compare.c: Expose "compare_timeout" to users
37
net/colo-compare.c: Expose "expired_scan_cycle" to users
38
39
hw/net/allwinner-sun8i-emac.c | 12 ++----
40
hw/net/allwinner_emac.c | 2 +-
41
hw/net/cadence_gem.c | 8 ++--
42
hw/net/can/can_sja1000.c | 8 ++--
43
hw/net/can/can_sja1000.h | 2 +-
44
hw/net/dp8393x.c | 8 ++--
45
hw/net/e1000.c | 2 +-
46
hw/net/e1000e.c | 4 +-
47
hw/net/e1000e_core.c | 2 +-
48
hw/net/e1000e_core.h | 2 +-
49
hw/net/ftgmac100.c | 6 +--
50
hw/net/i82596.c | 66 ++++++++++++++++++++----------
51
hw/net/i82596.h | 2 +-
52
hw/net/imx_fec.c | 2 +-
53
hw/net/opencores_eth.c | 5 +--
54
hw/net/rtl8139.c | 22 +++++-----
55
hw/net/smc91c111.c | 10 ++---
56
hw/net/spapr_llan.c | 4 +-
57
hw/net/sungem.c | 6 +--
58
hw/net/sunhme.c | 4 +-
59
hw/net/tulip.c | 36 ++++++++++++----
60
hw/net/virtio-net.c | 10 ++---
61
hw/net/xilinx_ethlite.c | 2 +-
62
include/net/can_emu.h | 2 +-
63
include/net/net.h | 2 +-
64
net/can/can_socketcan.c | 4 +-
65
net/colo-compare.c | 95 ++++++++++++++++++++++++++++++++++++++++---
66
net/filter-buffer.c | 2 +-
67
net/hub.c | 6 +--
68
qemu-options.hx | 10 +++--
69
30 files changed, 235 insertions(+), 111 deletions(-)
70
43
71
44
72
45
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The command is 32-bit, but we are loading the 16 upper bits with
4
the 'get_uint16(s->scb + 2)' call.
5
6
Once shifted by 16, the command bits match the status bits:
7
8
- Command
9
Bit 31 ACK-CX Acknowledges that the CU completed an Action Command.
10
Bit 30 ACK-FR Acknowledges that the RU received a frame.
11
Bit 29 ACK-CNA Acknowledges that the Command Unit became not active.
12
Bit 28 ACK-RNR Acknowledges that the Receive Unit became not ready.
13
14
- Status
15
Bit 15 CX The CU finished executing a command with its I(interrupt) bit set.
16
Bit 14 FR The RU finished receiving a frame.
17
Bit 13 CNA The Command Unit left the Active state.
18
Bit 12 RNR The Receive Unit left the Ready state.
19
20
Add the SCB_COMMAND_ACK_MASK definition to simplify the code.
21
22
This fixes Coverity 1419392 (CONSTANT_EXPRESSION_RESULT):
23
24
/hw/net/i82596.c: 352 in examine_scb()
25
346 cuc = (command >> 8) & 0x7;
26
347 ruc = (command >> 4) & 0x7;
27
348 DBG(printf("MAIN COMMAND %04x cuc %02x ruc %02x\n", command, cuc, ruc));
28
349 /* and clear the scb command word */
29
350 set_uint16(s->scb + 2, 0);
30
351
31
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
32
>>> "command & (2147483648UL /* 1UL << 31 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
33
352 if (command & BIT(31)) /* ACK-CX */
34
353 s->scb_status &= ~SCB_STATUS_CX;
35
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
36
>>> "command & (1073741824UL /* 1UL << 30 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
37
354 if (command & BIT(30)) /*ACK-FR */
38
355 s->scb_status &= ~SCB_STATUS_FR;
39
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
40
>>> "command & (536870912UL /* 1UL << 29 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
41
356 if (command & BIT(29)) /*ACK-CNA */
42
357 s->scb_status &= ~SCB_STATUS_CNA;
43
>>> CID 1419392: (CONSTANT_EXPRESSION_RESULT)
44
>>> "command & (268435456UL /* 1UL << 28 */)" is always 0 regardless of the values of its operands. This occurs as the logical operand of "if".
45
358 if (command & BIT(28)) /*ACK-RNR */
46
359 s->scb_status &= ~SCB_STATUS_RNR;
47
48
Fixes: Covertiy CID 1419392 (commit 376b851909)
49
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
50
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
51
Signed-off-by: Jason Wang <jasowang@redhat.com>
52
---
53
hw/net/i82596.c | 12 ++++--------
54
1 file changed, 4 insertions(+), 8 deletions(-)
55
56
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/net/i82596.c
59
+++ b/hw/net/i82596.c
60
@@ -XXX,XX +XXX,XX @@
61
#define SCB_STATUS_CNA 0x2000 /* CU left active state */
62
#define SCB_STATUS_RNR 0x1000 /* RU left active state */
63
64
+#define SCB_COMMAND_ACK_MASK \
65
+ (SCB_STATUS_CX | SCB_STATUS_FR | SCB_STATUS_CNA | SCB_STATUS_RNR)
66
+
67
#define CU_IDLE 0
68
#define CU_SUSPENDED 1
69
#define CU_ACTIVE 2
70
@@ -XXX,XX +XXX,XX @@ static void examine_scb(I82596State *s)
71
/* and clear the scb command word */
72
set_uint16(s->scb + 2, 0);
73
74
- if (command & BIT(31)) /* ACK-CX */
75
- s->scb_status &= ~SCB_STATUS_CX;
76
- if (command & BIT(30)) /*ACK-FR */
77
- s->scb_status &= ~SCB_STATUS_FR;
78
- if (command & BIT(29)) /*ACK-CNA */
79
- s->scb_status &= ~SCB_STATUS_CNA;
80
- if (command & BIT(28)) /*ACK-RNR */
81
- s->scb_status &= ~SCB_STATUS_RNR;
82
+ s->scb_status &= ~(command & SCB_COMMAND_ACK_MASK);
83
84
switch (cuc) {
85
case 0: /* no change */
86
--
87
2.5.0
88
89
diff view generated by jsdifflib
Deleted patch
1
From: Peter Maydell <peter.maydell@linaro.org>
2
1
3
The i82596_receive() function attempts to pass the guest a buffer
4
which is effectively the concatenation of the data it is passed and a
5
4 byte CRC value. However, rather than implementing this as "write
6
the data; then write the CRC" it instead bumps the length value of
7
the data by 4, and writes 4 extra bytes from beyond the end of the
8
buffer, which it then overwrites with the CRC. It also assumed that
9
we could always fit all four bytes of the CRC into the final receive
10
buffer, which might not be true if the CRC needs to be split over two
11
receive buffers.
12
13
Calculate separately how many bytes we need to transfer into the
14
guest's receive buffer from the source buffer, and how many we need
15
to transfer from the CRC work.
16
17
We add a count 'bufsz' of the number of bytes left in the source
18
buffer, which we use purely to assert() that we don't overrun.
19
20
Spotted by Coverity (CID 1419396) for the specific case when we end
21
up using a local array as the source buffer.
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Jason Wang <jasowang@redhat.com>
25
---
26
hw/net/i82596.c | 44 +++++++++++++++++++++++++++++++++++---------
27
1 file changed, 35 insertions(+), 9 deletions(-)
28
29
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/net/i82596.c
32
+++ b/hw/net/i82596.c
33
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
34
uint32_t rfd_p;
35
uint32_t rbd;
36
uint16_t is_broadcast = 0;
37
- size_t len = sz;
38
+ size_t len = sz; /* length of data for guest (including CRC) */
39
+ size_t bufsz = sz; /* length of data in buf */
40
uint32_t crc;
41
uint8_t *crc_ptr;
42
uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];
43
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
44
if (len < MIN_BUF_SIZE) {
45
len = MIN_BUF_SIZE;
46
}
47
+ bufsz = len;
48
}
49
50
/* Calculate the ethernet checksum (4 bytes) */
51
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
52
while (len) {
53
uint16_t buffer_size, num;
54
uint32_t rba;
55
+ size_t bufcount, crccount;
56
57
/* printf("Receive: rbd is %08x\n", rbd); */
58
buffer_size = get_uint16(rbd + 12);
59
@@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
60
}
61
rba = get_uint32(rbd + 8);
62
/* printf("rba is 0x%x\n", rba); */
63
- address_space_write(&address_space_memory, rba,
64
- MEMTXATTRS_UNSPECIFIED, buf, num);
65
- rba += num;
66
- buf += num;
67
- len -= num;
68
- if (len == 0) { /* copy crc */
69
- address_space_write(&address_space_memory, rba - 4,
70
- MEMTXATTRS_UNSPECIFIED, crc_ptr, 4);
71
+ /*
72
+ * Calculate how many bytes we want from buf[] and how many
73
+ * from the CRC.
74
+ */
75
+ if ((len - num) >= 4) {
76
+ /* The whole guest buffer, we haven't hit the CRC yet */
77
+ bufcount = num;
78
+ } else {
79
+ /* All that's left of buf[] */
80
+ bufcount = len - 4;
81
+ }
82
+ crccount = num - bufcount;
83
+
84
+ if (bufcount > 0) {
85
+ /* Still some of the actual data buffer to transfer */
86
+ bufsz -= bufcount;
87
+ assert(bufsz >= 0);
88
+ address_space_write(&address_space_memory, rba,
89
+ MEMTXATTRS_UNSPECIFIED, buf, bufcount);
90
+ rba += bufcount;
91
+ buf += bufcount;
92
+ len -= bufcount;
93
+ }
94
+
95
+ /* Write as much of the CRC as fits */
96
+ if (crccount > 0) {
97
+ address_space_write(&address_space_memory, rba,
98
+ MEMTXATTRS_UNSPECIFIED, crc_ptr, crccount);
99
+ rba += crccount;
100
+ crc_ptr += crccount;
101
+ len -= crccount;
102
}
103
104
num |= 0x4000; /* set F BIT */
105
--
106
2.5.0
107
108
diff view generated by jsdifflib
Deleted patch
1
From: Andrew Melnychenko <andrew@daynix.com>
2
1
3
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1737400
4
Fixed setting max_queue_num if there are no peers in
5
NICConf. qemu_new_nic() creates NICState with 1 NetClientState(index
6
0) without peers, set max_queue_num to 0 - It prevents undefined
7
behavior and possible crashes, especially during pcie hotplug.
8
9
Fixes: 6f3fbe4ed06 ("net: Introduce e1000e device emulation")
10
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Dmitry Fleytman <dmitry.fleytman@gmail.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
hw/net/e1000e.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/net/e1000e.c
21
+++ b/hw/net/e1000e.c
22
@@ -XXX,XX +XXX,XX @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr)
23
s->nic = qemu_new_nic(&net_e1000e_info, &s->conf,
24
object_get_typename(OBJECT(s)), dev->id, s);
25
26
- s->core.max_queue_num = s->conf.peers.queues - 1;
27
+ s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0;
28
29
trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
30
memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
31
--
32
2.5.0
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
The e1000e_can_receive() function simply returns a boolean value.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000e_core.c | 2 +-
11
hw/net/e1000e_core.h | 2 +-
12
2 files changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/e1000e_core.c
17
+++ b/hw/net/e1000e_core.c
18
@@ -XXX,XX +XXX,XX @@ e1000e_start_recv(E1000ECore *core)
19
}
20
}
21
22
-int
23
+bool
24
e1000e_can_receive(E1000ECore *core)
25
{
26
int i;
27
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/e1000e_core.h
30
+++ b/hw/net/e1000e_core.h
31
@@ -XXX,XX +XXX,XX @@ e1000e_core_set_link_status(E1000ECore *core);
32
void
33
e1000e_core_pci_uninit(E1000ECore *core);
34
35
-int
36
+bool
37
e1000e_can_receive(E1000ECore *core);
38
39
ssize_t
40
--
41
2.5.0
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
The smc91c111_can_receive() function simply returns a boolean value.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/smc91c111.c | 8 ++++----
11
1 file changed, 4 insertions(+), 4 deletions(-)
12
13
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/smc91c111.c
16
+++ b/hw/net/smc91c111.c
17
@@ -XXX,XX +XXX,XX @@ static void smc91c111_update(smc91c111_state *s)
18
qemu_set_irq(s->irq, level);
19
}
20
21
-static int smc91c111_can_receive(smc91c111_state *s)
22
+static bool smc91c111_can_receive(smc91c111_state *s)
23
{
24
if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST)) {
25
- return 1;
26
+ return true;
27
}
28
if (s->allocated == (1 << NUM_PACKETS) - 1 ||
29
s->rx_fifo_len == NUM_PACKETS) {
30
- return 0;
31
+ return false;
32
}
33
- return 1;
34
+ return true;
35
}
36
37
static inline void smc91c111_flush_queued_packets(smc91c111_state *s)
38
--
39
2.5.0
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Rewrite:
4
5
if (E) {
6
return A;
7
} else {
8
return B;
9
}
10
/* EOF */
11
}
12
13
as:
14
15
if (E) {
16
return A;
17
}
18
return B;
19
}
20
21
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Cédric Le Goater <clg@kaod.org>
24
Signed-off-by: Jason Wang <jasowang@redhat.com>
25
---
26
hw/net/rtl8139.c | 8 ++++----
27
1 file changed, 4 insertions(+), 4 deletions(-)
28
29
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/net/rtl8139.c
32
+++ b/hw/net/rtl8139.c
33
@@ -XXX,XX +XXX,XX @@ static int rtl8139_can_receive(NetClientState *nc)
34
/* ??? Flow control not implemented in c+ mode.
35
This is a hack to work around slirp deficiencies anyway. */
36
return 1;
37
- } else {
38
- avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
39
- s->RxBufferSize);
40
- return (avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow));
41
}
42
+
43
+ avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
44
+ s->RxBufferSize);
45
+ return avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow);
46
}
47
48
static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)
49
--
50
2.5.0
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
We will modify this code in the next commit. Clean it up
4
first to avoid checkpatch.pl errors.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
hw/net/rtl8139.c | 10 ++++++----
12
1 file changed, 6 insertions(+), 4 deletions(-)
13
14
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/rtl8139.c
17
+++ b/hw/net/rtl8139.c
18
@@ -XXX,XX +XXX,XX @@ static int rtl8139_can_receive(NetClientState *nc)
19
int avail;
20
21
/* Receive (drop) packets if card is disabled. */
22
- if (!s->clock_enabled)
23
- return 1;
24
- if (!rtl8139_receiver_enabled(s))
25
- return 1;
26
+ if (!s->clock_enabled) {
27
+ return 1;
28
+ }
29
+ if (!rtl8139_receiver_enabled(s)) {
30
+ return 1;
31
+ }
32
33
if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) {
34
/* ??? Flow control not implemented in c+ mode.
35
--
36
2.5.0
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
The NetCanReceive handler return whether the device can or
4
can not receive new packets. Make it obvious by returning
5
a boolean type.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Acked-by: David Gibson <david@gibson.dropbear.id.au>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
hw/net/allwinner_emac.c | 2 +-
14
hw/net/cadence_gem.c | 8 ++++----
15
hw/net/dp8393x.c | 8 +++-----
16
hw/net/e1000.c | 2 +-
17
hw/net/e1000e.c | 2 +-
18
hw/net/ftgmac100.c | 6 +++---
19
hw/net/i82596.c | 10 +++++-----
20
hw/net/i82596.h | 2 +-
21
hw/net/imx_fec.c | 2 +-
22
hw/net/opencores_eth.c | 5 ++---
23
hw/net/rtl8139.c | 8 ++++----
24
hw/net/smc91c111.c | 2 +-
25
hw/net/spapr_llan.c | 4 ++--
26
hw/net/sungem.c | 6 +++---
27
hw/net/sunhme.c | 4 ++--
28
hw/net/virtio-net.c | 10 +++++-----
29
hw/net/xilinx_ethlite.c | 2 +-
30
include/net/net.h | 2 +-
31
net/filter-buffer.c | 2 +-
32
net/hub.c | 6 +++---
33
20 files changed, 45 insertions(+), 48 deletions(-)
34
35
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/allwinner_emac.c
38
+++ b/hw/net/allwinner_emac.c
39
@@ -XXX,XX +XXX,XX @@ static uint32_t fifo8_pop_word(Fifo8 *fifo)
40
return ret;
41
}
42
43
-static int aw_emac_can_receive(NetClientState *nc)
44
+static bool aw_emac_can_receive(NetClientState *nc)
45
{
46
AwEmacState *s = qemu_get_nic_opaque(nc);
47
48
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/net/cadence_gem.c
51
+++ b/hw/net/cadence_gem.c
52
@@ -XXX,XX +XXX,XX @@ static void phy_update_link(CadenceGEMState *s)
53
}
54
}
55
56
-static int gem_can_receive(NetClientState *nc)
57
+static bool gem_can_receive(NetClientState *nc)
58
{
59
CadenceGEMState *s;
60
int i;
61
@@ -XXX,XX +XXX,XX @@ static int gem_can_receive(NetClientState *nc)
62
s->can_rx_state = 1;
63
DB_PRINT("can't receive - no enable\n");
64
}
65
- return 0;
66
+ return false;
67
}
68
69
for (i = 0; i < s->num_priority_queues; i++) {
70
@@ -XXX,XX +XXX,XX @@ static int gem_can_receive(NetClientState *nc)
71
s->can_rx_state = 2;
72
DB_PRINT("can't receive - all the buffer descriptors are busy\n");
73
}
74
- return 0;
75
+ return false;
76
}
77
78
if (s->can_rx_state != 0) {
79
s->can_rx_state = 0;
80
DB_PRINT("can receive\n");
81
}
82
- return 1;
83
+ return true;
84
}
85
86
/*
87
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/net/dp8393x.c
90
+++ b/hw/net/dp8393x.c
91
@@ -XXX,XX +XXX,XX @@ static void dp8393x_do_stop_timer(dp8393xState *s)
92
dp8393x_update_wt_regs(s);
93
}
94
95
-static int dp8393x_can_receive(NetClientState *nc);
96
+static bool dp8393x_can_receive(NetClientState *nc);
97
98
static void dp8393x_do_receiver_enable(dp8393xState *s)
99
{
100
@@ -XXX,XX +XXX,XX @@ static void dp8393x_watchdog(void *opaque)
101
dp8393x_update_irq(s);
102
}
103
104
-static int dp8393x_can_receive(NetClientState *nc)
105
+static bool dp8393x_can_receive(NetClientState *nc)
106
{
107
dp8393xState *s = qemu_get_nic_opaque(nc);
108
109
- if (!(s->regs[SONIC_CR] & SONIC_CR_RXEN))
110
- return 0;
111
- return 1;
112
+ return !!(s->regs[SONIC_CR] & SONIC_CR_RXEN);
113
}
114
115
static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf,
116
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/net/e1000.c
119
+++ b/hw/net/e1000.c
120
@@ -XXX,XX +XXX,XX @@ static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
121
return total_size <= bufs * s->rxbuf_size;
122
}
123
124
-static int
125
+static bool
126
e1000_can_receive(NetClientState *nc)
127
{
128
E1000State *s = qemu_get_nic_opaque(nc);
129
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/net/e1000e.c
132
+++ b/hw/net/e1000e.c
133
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps io_ops = {
134
},
135
};
136
137
-static int
138
+static bool
139
e1000e_nc_can_receive(NetClientState *nc)
140
{
141
E1000EState *s = qemu_get_nic_opaque(nc);
142
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/net/ftgmac100.c
145
+++ b/hw/net/ftgmac100.c
146
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
147
ftgmac100_update_irq(s);
148
}
149
150
-static int ftgmac100_can_receive(NetClientState *nc)
151
+static bool ftgmac100_can_receive(NetClientState *nc)
152
{
153
FTGMAC100State *s = FTGMAC100(qemu_get_nic_opaque(nc));
154
FTGMAC100Desc bd;
155
156
if ((s->maccr & (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN))
157
!= (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) {
158
- return 0;
159
+ return false;
160
}
161
162
if (ftgmac100_read_bd(&bd, s->rx_descriptor)) {
163
- return 0;
164
+ return false;
165
}
166
return !(bd.des0 & FTGMAC100_RXDES0_RXPKT_RDY);
167
}
168
diff --git a/hw/net/i82596.c b/hw/net/i82596.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/net/i82596.c
171
+++ b/hw/net/i82596.c
172
@@ -XXX,XX +XXX,XX @@ void i82596_h_reset(void *opaque)
173
i82596_s_reset(s);
174
}
175
176
-int i82596_can_receive(NetClientState *nc)
177
+bool i82596_can_receive(NetClientState *nc)
178
{
179
I82596State *s = qemu_get_nic_opaque(nc);
180
181
if (s->rx_status == RX_SUSPENDED) {
182
- return 0;
183
+ return false;
184
}
185
186
if (!s->lnkst) {
187
- return 0;
188
+ return false;
189
}
190
191
if (USE_TIMER && !timer_pending(s->flush_queue_timer)) {
192
- return 1;
193
+ return true;
194
}
195
196
- return 1;
197
+ return true;
198
}
199
200
#define MIN_BUF_SIZE 60
201
diff --git a/hw/net/i82596.h b/hw/net/i82596.h
202
index XXXXXXX..XXXXXXX 100644
203
--- a/hw/net/i82596.h
204
+++ b/hw/net/i82596.h
205
@@ -XXX,XX +XXX,XX @@ void i82596_ioport_writel(void *opaque, uint32_t addr, uint32_t val);
206
uint32_t i82596_ioport_readl(void *opaque, uint32_t addr);
207
uint32_t i82596_bcr_readw(I82596State *s, uint32_t rap);
208
ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
209
-int i82596_can_receive(NetClientState *nc);
210
+bool i82596_can_receive(NetClientState *nc);
211
void i82596_set_link_status(NetClientState *nc);
212
void i82596_common_init(DeviceState *dev, I82596State *s, NetClientInfo *info);
213
extern const VMStateDescription vmstate_i82596;
214
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/net/imx_fec.c
217
+++ b/hw/net/imx_fec.c
218
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
219
imx_eth_update(s);
220
}
221
222
-static int imx_eth_can_receive(NetClientState *nc)
223
+static bool imx_eth_can_receive(NetClientState *nc)
224
{
225
IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
226
227
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/net/opencores_eth.c
230
+++ b/hw/net/opencores_eth.c
231
@@ -XXX,XX +XXX,XX @@ static void open_eth_reset(void *opaque)
232
open_eth_set_link_status(qemu_get_queue(s->nic));
233
}
234
235
-static int open_eth_can_receive(NetClientState *nc)
236
+static bool open_eth_can_receive(NetClientState *nc)
237
{
238
OpenEthState *s = qemu_get_nic_opaque(nc);
239
240
- return GET_REGBIT(s, MODER, RXEN) &&
241
- (s->regs[TX_BD_NUM] < 0x80);
242
+ return GET_REGBIT(s, MODER, RXEN) && (s->regs[TX_BD_NUM] < 0x80);
243
}
244
245
static ssize_t open_eth_receive(NetClientState *nc,
246
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/hw/net/rtl8139.c
249
+++ b/hw/net/rtl8139.c
250
@@ -XXX,XX +XXX,XX @@ static bool rtl8139_cp_rx_valid(RTL8139State *s)
251
return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0);
252
}
253
254
-static int rtl8139_can_receive(NetClientState *nc)
255
+static bool rtl8139_can_receive(NetClientState *nc)
256
{
257
RTL8139State *s = qemu_get_nic_opaque(nc);
258
int avail;
259
260
/* Receive (drop) packets if card is disabled. */
261
if (!s->clock_enabled) {
262
- return 1;
263
+ return true;
264
}
265
if (!rtl8139_receiver_enabled(s)) {
266
- return 1;
267
+ return true;
268
}
269
270
if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) {
271
/* ??? Flow control not implemented in c+ mode.
272
This is a hack to work around slirp deficiencies anyway. */
273
- return 1;
274
+ return true;
275
}
276
277
avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
278
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
279
index XXXXXXX..XXXXXXX 100644
280
--- a/hw/net/smc91c111.c
281
+++ b/hw/net/smc91c111.c
282
@@ -XXX,XX +XXX,XX @@ static void smc91c111_writefn(void *opaque, hwaddr addr,
283
}
284
}
285
286
-static int smc91c111_can_receive_nc(NetClientState *nc)
287
+static bool smc91c111_can_receive_nc(NetClientState *nc)
288
{
289
smc91c111_state *s = qemu_get_nic_opaque(nc);
290
291
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
292
index XXXXXXX..XXXXXXX 100644
293
--- a/hw/net/spapr_llan.c
294
+++ b/hw/net/spapr_llan.c
295
@@ -XXX,XX +XXX,XX @@ typedef struct SpaprVioVlan {
296
RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */
297
} SpaprVioVlan;
298
299
-static int spapr_vlan_can_receive(NetClientState *nc)
300
+static bool spapr_vlan_can_receive(NetClientState *nc)
301
{
302
SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
303
304
- return (dev->isopen && dev->rx_bufs > 0);
305
+ return dev->isopen && dev->rx_bufs > 0;
306
}
307
308
/**
309
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
310
index XXXXXXX..XXXXXXX 100644
311
--- a/hw/net/sungem.c
312
+++ b/hw/net/sungem.c
313
@@ -XXX,XX +XXX,XX @@ static bool sungem_rx_full(SunGEMState *s, uint32_t kick, uint32_t done)
314
return kick == ((done + 1) & s->rx_mask);
315
}
316
317
-static int sungem_can_receive(NetClientState *nc)
318
+static bool sungem_can_receive(NetClientState *nc)
319
{
320
SunGEMState *s = qemu_get_nic_opaque(nc);
321
uint32_t kick, done, rxdma_cfg, rxmac_cfg;
322
@@ -XXX,XX +XXX,XX @@ static int sungem_can_receive(NetClientState *nc)
323
/* If MAC disabled, can't receive */
324
if ((rxmac_cfg & MAC_RXCFG_ENAB) == 0) {
325
trace_sungem_rx_mac_disabled();
326
- return 0;
327
+ return false;
328
}
329
if ((rxdma_cfg & RXDMA_CFG_ENABLE) == 0) {
330
trace_sungem_rx_txdma_disabled();
331
- return 0;
332
+ return false;
333
}
334
335
/* Check RX availability */
336
diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
337
index XXXXXXX..XXXXXXX 100644
338
--- a/hw/net/sunhme.c
339
+++ b/hw/net/sunhme.c
340
@@ -XXX,XX +XXX,XX @@ static void sunhme_transmit(SunHMEState *s)
341
sunhme_update_irq(s);
342
}
343
344
-static int sunhme_can_receive(NetClientState *nc)
345
+static bool sunhme_can_receive(NetClientState *nc)
346
{
347
SunHMEState *s = qemu_get_nic_opaque(nc);
348
349
- return s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE;
350
+ return !!(s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE);
351
}
352
353
static void sunhme_link_status_changed(NetClientState *nc)
354
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
355
index XXXXXXX..XXXXXXX 100644
356
--- a/hw/net/virtio-net.c
357
+++ b/hw/net/virtio-net.c
358
@@ -XXX,XX +XXX,XX @@ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
359
qemu_flush_queued_packets(qemu_get_subqueue(n->nic, queue_index));
360
}
361
362
-static int virtio_net_can_receive(NetClientState *nc)
363
+static bool virtio_net_can_receive(NetClientState *nc)
364
{
365
VirtIONet *n = qemu_get_nic_opaque(nc);
366
VirtIODevice *vdev = VIRTIO_DEVICE(n);
367
VirtIONetQueue *q = virtio_net_get_subqueue(nc);
368
369
if (!vdev->vm_running) {
370
- return 0;
371
+ return false;
372
}
373
374
if (nc->queue_index >= n->curr_queues) {
375
- return 0;
376
+ return false;
377
}
378
379
if (!virtio_queue_ready(q->rx_vq) ||
380
!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
381
- return 0;
382
+ return false;
383
}
384
385
- return 1;
386
+ return true;
387
}
388
389
static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize)
390
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
391
index XXXXXXX..XXXXXXX 100644
392
--- a/hw/net/xilinx_ethlite.c
393
+++ b/hw/net/xilinx_ethlite.c
394
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps eth_ops = {
395
}
396
};
397
398
-static int eth_can_rx(NetClientState *nc)
399
+static bool eth_can_rx(NetClientState *nc)
400
{
401
struct xlx_ethlite *s = qemu_get_nic_opaque(nc);
402
unsigned int rxbase = s->rxbuf * (0x800 / 4);
403
diff --git a/include/net/net.h b/include/net/net.h
404
index XXXXXXX..XXXXXXX 100644
405
--- a/include/net/net.h
406
+++ b/include/net/net.h
407
@@ -XXX,XX +XXX,XX @@ typedef struct NICConf {
408
/* Net clients */
409
410
typedef void (NetPoll)(NetClientState *, bool enable);
411
-typedef int (NetCanReceive)(NetClientState *);
412
+typedef bool (NetCanReceive)(NetClientState *);
413
typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t);
414
typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int);
415
typedef void (NetCleanup) (NetClientState *);
416
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
417
index XXXXXXX..XXXXXXX 100644
418
--- a/net/filter-buffer.c
419
+++ b/net/filter-buffer.c
420
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_buffer_receive_iov(NetFilterState *nf,
421
* the filter can still accept packets until its internal queue is full.
422
* For example:
423
* For some reason, receiver could not receive more packets
424
- * (.can_receive() returns zero). Without a filter, at most one packet
425
+ * (.can_receive() returns false). Without a filter, at most one packet
426
* will be queued in incoming queue and sender's poll will be disabled
427
* unit its sent_cb() was called. With a filter, it will keep receiving
428
* the packets without caring about the receiver. This is suboptimal.
429
diff --git a/net/hub.c b/net/hub.c
430
index XXXXXXX..XXXXXXX 100644
431
--- a/net/hub.c
432
+++ b/net/hub.c
433
@@ -XXX,XX +XXX,XX @@ static NetHub *net_hub_new(int id)
434
return hub;
435
}
436
437
-static int net_hub_port_can_receive(NetClientState *nc)
438
+static bool net_hub_port_can_receive(NetClientState *nc)
439
{
440
NetHubPort *port;
441
NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
442
@@ -XXX,XX +XXX,XX @@ static int net_hub_port_can_receive(NetClientState *nc)
443
}
444
445
if (qemu_can_send_packet(&port->nc)) {
446
- return 1;
447
+ return true;
448
}
449
}
450
451
- return 0;
452
+ return false;
453
}
454
455
static ssize_t net_hub_port_receive(NetClientState *nc,
456
--
457
2.5.0
458
459
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
Tulip network driver while copying tx/rx buffers does not check
3
This change is used in later commits so we can avoid the removal of the
4
frame size against r/w data length. This may lead to OOB buffer
4
netclient if it is delayed.
5
access. Add check to avoid it.
6
5
7
Limit iterations over descriptors to avoid potential infinite
6
No functional change intended.
8
loop issue in tulip_xmit_list_update.
9
7
10
Reported-by: Li Qiang <pangpei.lq@antfin.com>
8
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
11
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
9
Acked-by: Jason Wang <jasowang@redhat.com>
12
Reported-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
13
Tested-by: Li Qiang <liq3ea@gmail.com>
14
Reviewed-by: Li Qiang <liq3ea@gmail.com>
15
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
12
---
18
hw/net/tulip.c | 36 +++++++++++++++++++++++++++---------
13
net/net.c | 13 ++++++++-----
19
1 file changed, 27 insertions(+), 9 deletions(-)
14
1 file changed, 8 insertions(+), 5 deletions(-)
20
15
21
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
16
diff --git a/net/net.c b/net/net.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/net/tulip.c
18
--- a/net/net.c
24
+++ b/hw/net/tulip.c
19
+++ b/net/net.c
25
@@ -XXX,XX +XXX,XX @@ static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
20
@@ -XXX,XX +XXX,XX @@ NetClientState *qemu_get_peer(NetClientState *nc, int queue_index)
26
} else {
21
return ncs->peer;
27
len = s->rx_frame_len;
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)
27
{
28
- QTAILQ_REMOVE(&net_clients, nc, next);
29
+ if (remove_from_net_clients) {
30
+ QTAILQ_REMOVE(&net_clients, nc, next);
31
+ }
32
33
if (nc->info->cleanup) {
34
nc->info->cleanup(nc);
35
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
28
}
36
}
29
+
37
30
+ if (s->rx_frame_len + len > sizeof(s->rx_frame)) {
38
for (i = 0; i < queues; i++) {
31
+ return;
39
- qemu_cleanup_net_client(ncs[i]);
32
+ }
40
+ qemu_cleanup_net_client(ncs[i], true);
33
pci_dma_write(&s->dev, desc->buf_addr1, s->rx_frame +
34
(s->rx_frame_size - s->rx_frame_len), len);
35
s->rx_frame_len -= len;
36
@@ -XXX,XX +XXX,XX @@ static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
37
} else {
38
len = s->rx_frame_len;
39
}
41
}
40
+
42
41
+ if (s->rx_frame_len + len > sizeof(s->rx_frame)) {
43
return;
42
+ return;
43
+ }
44
pci_dma_write(&s->dev, desc->buf_addr2, s->rx_frame +
45
(s->rx_frame_size - s->rx_frame_len), len);
46
s->rx_frame_len -= len;
47
@@ -XXX,XX +XXX,XX @@ static ssize_t tulip_receive(TULIPState *s, const uint8_t *buf, size_t size)
48
49
trace_tulip_receive(buf, size);
50
51
- if (size < 14 || size > 2048 || s->rx_frame_len || tulip_rx_stopped(s)) {
52
+ if (size < 14 || size > sizeof(s->rx_frame) - 4
53
+ || s->rx_frame_len || tulip_rx_stopped(s)) {
54
return 0;
55
}
44
}
56
45
57
@@ -XXX,XX +XXX,XX @@ static ssize_t tulip_receive_nc(NetClientState *nc,
46
for (i = 0; i < queues; i++) {
58
return tulip_receive(qemu_get_nic_opaque(nc), buf, size);
47
- qemu_cleanup_net_client(ncs[i]);
59
}
48
+ qemu_cleanup_net_client(ncs[i], true);
60
49
qemu_free_net_client(ncs[i]);
61
-
62
static NetClientInfo net_tulip_info = {
63
.type = NET_CLIENT_DRIVER_NIC,
64
.size = sizeof(NICState),
65
@@ -XXX,XX +XXX,XX @@ static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
66
if ((s->csr[6] >> CSR6_OM_SHIFT) & CSR6_OM_MASK) {
67
/* Internal or external Loopback */
68
tulip_receive(s, s->tx_frame, s->tx_frame_len);
69
- } else {
70
+ } else if (s->tx_frame_len <= sizeof(s->tx_frame)) {
71
qemu_send_packet(qemu_get_queue(s->nic),
72
s->tx_frame, s->tx_frame_len);
73
}
74
@@ -XXX,XX +XXX,XX @@ static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
75
}
50
}
76
}
51
}
77
52
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
78
-static void tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
53
for (i = queues - 1; i >= 0; i--) {
79
+static int tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
54
NetClientState *nc = qemu_get_subqueue(nic, i);
80
{
55
81
int len1 = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK;
56
- qemu_cleanup_net_client(nc);
82
int len2 = (desc->control >> TDES1_BUF2_SIZE_SHIFT) & TDES1_BUF2_SIZE_MASK;
57
+ qemu_cleanup_net_client(nc, true);
83
58
qemu_free_net_client(nc);
84
+ if (s->tx_frame_len + len1 > sizeof(s->tx_frame)) {
85
+ return -1;
86
+ }
87
if (len1) {
88
pci_dma_read(&s->dev, desc->buf_addr1,
89
s->tx_frame + s->tx_frame_len, len1);
90
s->tx_frame_len += len1;
91
}
59
}
92
60
93
+ if (s->tx_frame_len + len2 > sizeof(s->tx_frame)) {
94
+ return -1;
95
+ }
96
if (len2) {
97
pci_dma_read(&s->dev, desc->buf_addr2,
98
s->tx_frame + s->tx_frame_len, len2);
99
s->tx_frame_len += len2;
100
}
101
desc->status = (len1 + len2) ? 0 : 0x7fffffff;
102
+
103
+ return 0;
104
}
105
106
static void tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n)
107
@@ -XXX,XX +XXX,XX @@ static uint32_t tulip_ts(TULIPState *s)
108
109
static void tulip_xmit_list_update(TULIPState *s)
110
{
111
+#define TULIP_DESC_MAX 128
112
+ uint8_t i = 0;
113
struct tulip_descriptor desc;
114
115
if (tulip_ts(s) != CSR5_TS_SUSPENDED) {
116
return;
117
}
118
119
- for (;;) {
120
+ for (i = 0; i < TULIP_DESC_MAX; i++) {
121
tulip_desc_read(s, s->current_tx_desc, &desc);
122
tulip_dump_tx_descriptor(s, &desc);
123
124
@@ -XXX,XX +XXX,XX @@ static void tulip_xmit_list_update(TULIPState *s)
125
s->tx_frame_len = 0;
126
}
127
128
- tulip_copy_tx_buffers(s, &desc);
129
-
130
- if (desc.control & TDES1_LS) {
131
- tulip_tx(s, &desc);
132
+ if (!tulip_copy_tx_buffers(s, &desc)) {
133
+ if (desc.control & TDES1_LS) {
134
+ tulip_tx(s, &desc);
135
+ }
136
}
137
}
138
tulip_desc_write(s, s->current_tx_desc, &desc);
139
--
61
--
140
2.5.0
62
2.42.0
141
63
142
64
diff view generated by jsdifflib
1
From: Zhang Chen <chen.zhang@intel.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
The "compare_timeout" determines the maximum time to hold the primary net packet.
3
Commit a0d7215e33 ("vhost-vdpa: do not cleanup the vdpa/vhost-net
4
This patch expose the "compare_timeout", make user have ability to
4
structures if peer nic is present") effectively delayed the backend
5
adjest the value according to application scenarios.
5
cleanup, allowing the frontend or the guest to access it resources as
6
long as the frontend is still visible to the guest.
6
7
7
QMP command demo:
8
However it does not clean up the resources until the qemu process is
8
{ "execute": "qom-get",
9
over. This causes an effective leak if the device is deleted with
9
"arguments": { "path": "/objects/comp0",
10
device_del, as there is no way to close the vdpa device. This makes
10
"property": "compare_timeout" } }
11
impossible to re-add that device to this or other QEMU instances until
12
the first instance of QEMU is finished.
11
13
12
{ "execute": "qom-set",
14
Move the cleanup from qemu_cleanup to the NIC deletion and to
13
"arguments": { "path": "/objects/comp0",
15
net_cleanup.
14
"property": "compare_timeout",
15
"value": 5000} }
16
16
17
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
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>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
---
22
---
20
net/colo-compare.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
23
net/net.c | 33 +++++++++++++++++++++++++++------
21
qemu-options.hx | 8 +++++---
24
net/vhost-vdpa.c | 8 --------
22
2 files changed, 50 insertions(+), 5 deletions(-)
25
2 files changed, 27 insertions(+), 14 deletions(-)
23
26
24
diff --git a/net/colo-compare.c b/net/colo-compare.c
27
diff --git a/net/net.c b/net/net.c
25
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
26
--- a/net/colo-compare.c
29
--- a/net/net.c
27
+++ b/net/colo-compare.c
30
+++ b/net/net.c
28
@@ -XXX,XX +XXX,XX @@ static NotifierList colo_compare_notifiers =
31
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
29
32
object_unparent(OBJECT(nf));
30
/* TODO: Should be configurable */
33
}
31
#define REGULAR_PACKET_CHECK_MS 3000
34
32
+#define DEFAULT_TIME_OUT_MS 3000
35
- /* If there is a peer NIC, delete and cleanup client, but do not free. */
33
36
+ /*
34
static QemuMutex event_mtx;
37
+ * If there is a peer NIC, transfer ownership to it. Delete the client
35
static QemuCond event_complete_cond;
38
+ * from net_client list but do not cleanup nor free. This way NIC can
36
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
39
+ * still access to members of the backend.
37
SocketReadState sec_rs;
40
+ *
38
SocketReadState notify_rs;
41
+ * The cleanup and free will be done when the NIC is free.
39
bool vnet_hdr;
42
+ */
40
+ uint32_t compare_timeout;
43
if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
41
44
NICState *nic = qemu_get_nic(nc->peer);
42
/*
45
if (nic->peer_deleted) {
43
* Record the connection that through the NIC
46
@@ -XXX,XX +XXX,XX @@ void qemu_del_net_client(NetClientState *nc)
44
@@ -XXX,XX +XXX,XX @@ static int colo_old_packet_check_one_conn(Connection *conn,
47
45
CompareState *s)
48
for (i = 0; i < queues; i++) {
46
{
49
ncs[i]->peer->link_down = true;
47
GList *result = NULL;
50
+ QTAILQ_REMOVE(&net_clients, ncs[i], next);
48
- int64_t check_time = REGULAR_PACKET_CHECK_MS;
51
}
49
52
50
result = g_queue_find_custom(&conn->primary_list,
53
if (nc->peer->info->link_status_changed) {
51
- &check_time,
54
nc->peer->info->link_status_changed(nc->peer);
52
+ &s->compare_timeout,
55
}
53
(GCompareFunc)colo_old_packet_check_one);
56
54
57
- for (i = 0; i < queues; i++) {
55
if (result) {
58
- qemu_cleanup_net_client(ncs[i], true);
56
@@ -XXX,XX +XXX,XX @@ static void compare_set_notify_dev(Object *obj, const char *value, Error **errp)
59
- }
57
s->notify_dev = g_strdup(value);
60
-
58
}
59
60
+static void compare_get_timeout(Object *obj, Visitor *v,
61
+ const char *name, void *opaque,
62
+ Error **errp)
63
+{
64
+ CompareState *s = COLO_COMPARE(obj);
65
+ uint32_t value = s->compare_timeout;
66
+
67
+ visit_type_uint32(v, name, &value, errp);
68
+}
69
+
70
+static void compare_set_timeout(Object *obj, Visitor *v,
71
+ const char *name, void *opaque,
72
+ Error **errp)
73
+{
74
+ CompareState *s = COLO_COMPARE(obj);
75
+ Error *local_err = NULL;
76
+ uint32_t value;
77
+
78
+ visit_type_uint32(v, name, &value, &local_err);
79
+ if (local_err) {
80
+ goto out;
81
+ }
82
+ if (!value) {
83
+ error_setg(&local_err, "Property '%s.%s' requires a positive value",
84
+ object_get_typename(obj), name);
85
+ goto out;
86
+ }
87
+ s->compare_timeout = value;
88
+
89
+out:
90
+ error_propagate(errp, local_err);
91
+}
92
+
93
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
94
{
95
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
96
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
97
return;
61
return;
98
}
62
}
99
63
100
+ if (!s->compare_timeout) {
64
@@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic)
101
+ /* Set default value to 3000 MS */
65
102
+ s->compare_timeout = DEFAULT_TIME_OUT_MS;
66
for (i = 0; i < queues; i++) {
103
+ }
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);
104
+
93
+
105
if (find_and_check_chardev(&chr, s->pri_indev, errp) ||
94
+ if (nic->peer_deleted) {
106
!qemu_chr_fe_init(&s->chr_pri_in, chr, errp)) {
95
+ int queues = MAX(nic->conf->peers.queues, 1);
107
return;
108
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
109
compare_get_notify_dev, compare_set_notify_dev,
110
NULL);
111
112
+ object_property_add(obj, "compare_timeout", "uint32",
113
+ compare_get_timeout,
114
+ compare_set_timeout, NULL, NULL, NULL);
115
+
96
+
116
s->vnet_hdr = false;
97
+ for (int i = 0; i < queues; i++) {
117
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
98
+ nc = qemu_get_subqueue(nic, i);
118
compare_set_vnet_hdr, NULL);
99
+ qemu_cleanup_net_client(nc->peer, false);
119
diff --git a/qemu-options.hx b/qemu-options.hx
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
120
index XXXXXXX..XXXXXXX 100644
107
index XXXXXXX..XXXXXXX 100644
121
--- a/qemu-options.hx
108
--- a/net/vhost-vdpa.c
122
+++ b/qemu-options.hx
109
+++ b/net/vhost-vdpa.c
123
@@ -XXX,XX +XXX,XX @@ SRST
110
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_cleanup(NetClientState *nc)
124
stored. The file format is libpcap, so it can be analyzed with
111
{
125
tools such as tcpdump or Wireshark.
112
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
126
113
127
- ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id]``
114
- /*
128
+ ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}]``
115
- * If a peer NIC is attached, do not cleanup anything.
129
Colo-compare gets packet from primary\_inchardevid and
116
- * Cleanup will happen as a part of qemu_cleanup() -> net_cleanup()
130
secondary\_inchardevid, than compare primary packet with
117
- * when the guest is shutting down.
131
secondary packet. If the packets are same, we will output
118
- */
132
@@ -XXX,XX +XXX,XX @@ SRST
119
- if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) {
133
outdevchardevid. In order to improve efficiency, we need to put
120
- return;
134
the task of comparison in another thread. If it has the
121
- }
135
vnet\_hdr\_support flag, colo compare will send/recv packet with
122
munmap(s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_page_len());
136
- vnet\_hdr\_len. If you want to use Xen COLO, will need the
123
munmap(s->status, vhost_vdpa_net_cvq_cmd_page_len());
137
- notify\_dev to notify Xen colo-frame to do checkpoint.
124
if (s->vhost_net) {
138
+ vnet\_hdr\_len. Then compare\_timeout=@var{ms} determines the
139
+ maximum delay colo-compare wait for the packet.
140
+ If you want to use Xen COLO, will need the notify\_dev to
141
+ notify Xen colo-frame to do checkpoint.
142
143
we must use it with the help of filter-mirror and
144
filter-redirector.
145
--
125
--
146
2.5.0
126
2.42.0
147
127
148
128
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The CanBusClientInfo::can_receive handler return whether the
3
iov_from_buf(), iov_to_buf(), iov_memset(), and iov_copy() asserts
4
device can or can not receive new frames. Make it obvious by
4
that the given offset fits in the iov while tolerating the specified
5
returning a boolean type.
5
number of bytes to operate with to be greater than the size of iov.
6
This is inconsistent so remove the assertions.
6
7
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Asserting the offset fits in the iov makes sense if it is expected that
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
there are other operations that process the content before the offset
9
Reviewed-by: Cédric Le Goater <clg@kaod.org>
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()").
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>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
25
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
26
---
12
hw/net/can/can_sja1000.c | 8 ++++----
27
include/qemu/iov.h | 5 +++--
13
hw/net/can/can_sja1000.h | 2 +-
28
util/iov.c | 5 -----
14
include/net/can_emu.h | 2 +-
29
2 files changed, 3 insertions(+), 7 deletions(-)
15
net/can/can_socketcan.c | 4 ++--
16
4 files changed, 8 insertions(+), 8 deletions(-)
17
30
18
diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.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/hw/net/can/can_sja1000.c
33
--- a/include/qemu/iov.h
21
+++ b/hw/net/can/can_sja1000.c
34
+++ b/include/qemu/iov.h
22
@@ -XXX,XX +XXX,XX @@ uint64_t can_sja_mem_read(CanSJA1000State *s, hwaddr addr, unsigned size)
35
@@ -XXX,XX +XXX,XX @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
23
return temp;
36
* only part of data will be copied, up to the end of the iovec.
24
}
37
* Number of bytes actually copied will be returned, which is
25
38
* min(bytes, iov_size(iov)-offset)
26
-int can_sja_can_receive(CanBusClientState *client)
39
- * `Offset' must point to the inside of iovec.
27
+bool can_sja_can_receive(CanBusClientState *client)
40
+ * Returns 0 when `offset' points to the outside of iovec.
28
{
41
*/
29
CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
42
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
30
43
size_t offset, const void *buf, size_t bytes);
31
if (s->clock & 0x80) { /* PeliCAN Mode */
44
@@ -XXX,XX +XXX,XX @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
32
if (s->mode & 0x01) { /* reset mode. */
45
/**
33
- return 0;
46
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
34
+ return false;
47
* starting at byte offset `start', to value `fillc', repeating it
35
}
48
- * `bytes' number of times. `Offset' must point to the inside of iovec.
36
} else { /* BasicCAN mode */
49
+ * `bytes' number of times.
37
if (s->control & 0x01) {
50
* If `bytes' is large enough, only last bytes portion of iovec,
38
- return 0;
51
* up to the end of it, will be filled with the specified value.
39
+ return false;
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;
40
}
64
}
41
}
65
}
42
66
- assert(offset == 0);
43
- return 1; /* always return 1, when operation mode */
67
return done;
44
+ return true; /* always return true, when operation mode */
45
}
68
}
46
69
47
ssize_t can_sja_receive(CanBusClientState *client, const qemu_can_frame *frames,
70
@@ -XXX,XX +XXX,XX @@ size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
48
diff --git a/hw/net/can/can_sja1000.h b/hw/net/can/can_sja1000.h
71
offset -= iov[i].iov_len;
49
index XXXXXXX..XXXXXXX 100644
72
}
50
--- a/hw/net/can/can_sja1000.h
51
+++ b/hw/net/can/can_sja1000.h
52
@@ -XXX,XX +XXX,XX @@ void can_sja_disconnect(CanSJA1000State *s);
53
54
int can_sja_init(CanSJA1000State *s, qemu_irq irq);
55
56
-int can_sja_can_receive(CanBusClientState *client);
57
+bool can_sja_can_receive(CanBusClientState *client);
58
59
ssize_t can_sja_receive(CanBusClientState *client,
60
const qemu_can_frame *frames, size_t frames_cnt);
61
diff --git a/include/net/can_emu.h b/include/net/can_emu.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/include/net/can_emu.h
64
+++ b/include/net/can_emu.h
65
@@ -XXX,XX +XXX,XX @@ typedef struct CanBusClientState CanBusClientState;
66
typedef struct CanBusState CanBusState;
67
68
typedef struct CanBusClientInfo {
69
- int (*can_receive)(CanBusClientState *);
70
+ bool (*can_receive)(CanBusClientState *);
71
ssize_t (*receive)(CanBusClientState *,
72
const struct qemu_can_frame *frames, size_t frames_cnt);
73
} CanBusClientInfo;
74
diff --git a/net/can/can_socketcan.c b/net/can/can_socketcan.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/net/can/can_socketcan.c
77
+++ b/net/can/can_socketcan.c
78
@@ -XXX,XX +XXX,XX @@ static void can_host_socketcan_read(void *opaque)
79
}
73
}
74
- assert(offset == 0);
75
return done;
80
}
76
}
81
77
82
-static int can_host_socketcan_can_receive(CanBusClientState *client)
78
@@ -XXX,XX +XXX,XX @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
83
+static bool can_host_socketcan_can_receive(CanBusClientState *client)
79
offset -= iov[i].iov_len;
84
{
80
}
85
- return 1;
81
}
86
+ return true;
82
- assert(offset == 0);
83
return done;
87
}
84
}
88
85
89
static ssize_t can_host_socketcan_receive(CanBusClientState *client,
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;
101
}
90
--
102
--
91
2.5.0
103
2.42.0
92
93
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Coverity points out (CID 1421926) that the read code for
3
This reverts commit 83ddb3dbba2ee0f1767442ae6ee665058aeb1093.
4
REG_ADDR_HIGH reads off the end of the buffer, because it does a
5
32-bit read from byte 4 of a 6-byte buffer.
6
4
7
The code also has an endianness issue for both REG_ADDR_HIGH and
5
The added check is no longer necessary due to a change of
8
REG_ADDR_LOW, because it will do the wrong thing on a big-endian
6
iov_from_buf().
9
host.
10
7
11
Rewrite the read code to use ldl_le_p() and lduw_le_p() to fix this;
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
the write code is not incorrect, but for consistency we make it use
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
stl_le_p() and stw_le_p().
14
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
20
---
11
---
21
hw/net/allwinner-sun8i-emac.c | 12 ++++--------
12
hw/net/net_tx_pkt.c | 4 ----
22
1 file changed, 4 insertions(+), 8 deletions(-)
13
1 file changed, 4 deletions(-)
23
14
24
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
15
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/net/allwinner-sun8i-emac.c
17
--- a/hw/net/net_tx_pkt.c
27
+++ b/hw/net/allwinner-sun8i-emac.c
18
+++ b/hw/net/net_tx_pkt.c
28
@@ -XXX,XX +XXX,XX @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
19
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt)
29
value = s->mii_data;
20
uint32_t csum = 0;
30
break;
21
struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG;
31
case REG_ADDR_HIGH: /* MAC Address High */
22
32
- value = *(((uint32_t *) (s->conf.macaddr.a)) + 1);
23
- if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) {
33
+ value = lduw_le_p(s->conf.macaddr.a + 4);
24
- return false;
34
break;
25
- }
35
case REG_ADDR_LOW: /* MAC Address Low */
26
-
36
- value = *(uint32_t *) (s->conf.macaddr.a);
27
if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) {
37
+ value = ldl_le_p(s->conf.macaddr.a);
28
return false;
38
break;
29
}
39
case REG_TX_DMA_STA: /* Transmit DMA Status */
40
break;
41
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_write(void *opaque, hwaddr offset,
42
s->mii_data = value;
43
break;
44
case REG_ADDR_HIGH: /* MAC Address High */
45
- s->conf.macaddr.a[4] = (value & 0xff);
46
- s->conf.macaddr.a[5] = (value & 0xff00) >> 8;
47
+ stw_le_p(s->conf.macaddr.a + 4, value);
48
break;
49
case REG_ADDR_LOW: /* MAC Address Low */
50
- s->conf.macaddr.a[0] = (value & 0xff);
51
- s->conf.macaddr.a[1] = (value & 0xff00) >> 8;
52
- s->conf.macaddr.a[2] = (value & 0xff0000) >> 16;
53
- s->conf.macaddr.a[3] = (value & 0xff000000) >> 24;
54
+ stl_le_p(s->conf.macaddr.a, value);
55
break;
56
case REG_TX_DMA_STA: /* Transmit DMA Status */
57
case REG_TX_CUR_DESC: /* Transmit Current Descriptor */
58
--
30
--
59
2.5.0
31
2.42.0
60
32
61
33
diff view generated by jsdifflib
1
From: Zhang Chen <chen.zhang@intel.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The "expired_scan_cycle" determines period of scanning expired
3
ipvtap and macvtap create a file for each interface unlike tuntap, which
4
primary node net packets.
4
creates one file shared by all interfaces. Try to open a file dedicated
5
to the interface first for ipvtap and macvtap.
5
6
6
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
---
9
net/colo-compare.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
10
net/tap-linux.c | 17 ++++++++++++++---
10
qemu-options.hx | 4 +++-
11
1 file changed, 14 insertions(+), 3 deletions(-)
11
2 files changed, 48 insertions(+), 4 deletions(-)
12
12
13
diff --git a/net/colo-compare.c b/net/colo-compare.c
13
diff --git a/net/tap-linux.c b/net/tap-linux.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/net/colo-compare.c
15
--- a/net/tap-linux.c
16
+++ b/net/colo-compare.c
16
+++ b/net/tap-linux.c
17
@@ -XXX,XX +XXX,XX @@ static NotifierList colo_compare_notifiers =
17
@@ -XXX,XX +XXX,XX @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
18
#define COLO_COMPARE_FREE_PRIMARY 0x01
18
int len = sizeof(struct virtio_net_hdr);
19
#define COLO_COMPARE_FREE_SECONDARY 0x02
19
unsigned int features;
20
20
21
-/* TODO: Should be configurable */
21
- fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
22
#define REGULAR_PACKET_CHECK_MS 3000
23
#define DEFAULT_TIME_OUT_MS 3000
24
25
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
26
SocketReadState notify_rs;
27
bool vnet_hdr;
28
uint32_t compare_timeout;
29
+ uint32_t expired_scan_cycle;
30
31
/*
32
* Record the connection that through the NIC
33
@@ -XXX,XX +XXX,XX @@ static void check_old_packet_regular(void *opaque)
34
/* if have old packet we will notify checkpoint */
35
colo_old_packet_check(s);
36
timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
37
- REGULAR_PACKET_CHECK_MS);
38
+ s->expired_scan_cycle);
39
}
40
41
/* Public API, Used for COLO frame to notify compare event */
42
@@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s)
43
SCALE_MS, check_old_packet_regular,
44
s);
45
timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
46
- REGULAR_PACKET_CHECK_MS);
47
+ s->expired_scan_cycle);
48
}
49
50
static void colo_compare_timer_del(CompareState *s)
51
@@ -XXX,XX +XXX,XX @@ out:
52
error_propagate(errp, local_err);
53
}
54
55
+static void compare_get_expired_scan_cycle(Object *obj, Visitor *v,
56
+ const char *name, void *opaque,
57
+ Error **errp)
58
+{
59
+ CompareState *s = COLO_COMPARE(obj);
60
+ uint32_t value = s->expired_scan_cycle;
61
+
22
+
62
+ visit_type_uint32(v, name, &value, errp);
23
+ ret = if_nametoindex(ifname);
63
+}
24
+ if (ret) {
64
+
25
+ g_autofree char *file = g_strdup_printf("/dev/tap%d", ret);
65
+static void compare_set_expired_scan_cycle(Object *obj, Visitor *v,
26
+ fd = open(file, O_RDWR);
66
+ const char *name, void *opaque,
27
+ } else {
67
+ Error **errp)
28
+ fd = -1;
68
+{
69
+ CompareState *s = COLO_COMPARE(obj);
70
+ Error *local_err = NULL;
71
+ uint32_t value;
72
+
73
+ visit_type_uint32(v, name, &value, &local_err);
74
+ if (local_err) {
75
+ goto out;
76
+ }
77
+ if (!value) {
78
+ error_setg(&local_err, "Property '%s.%s' requires a positive value",
79
+ object_get_typename(obj), name);
80
+ goto out;
81
+ }
82
+ s->expired_scan_cycle = value;
83
+
84
+out:
85
+ error_propagate(errp, local_err);
86
+}
87
+
88
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
89
{
90
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
91
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
92
s->compare_timeout = DEFAULT_TIME_OUT_MS;
93
}
94
95
+ if (!s->expired_scan_cycle) {
96
+ /* Set default value to 3000 MS */
97
+ s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
98
+ }
29
+ }
99
+
30
+
100
if (find_and_check_chardev(&chr, s->pri_indev, errp) ||
31
if (fd < 0) {
101
!qemu_chr_fe_init(&s->chr_pri_in, chr, errp)) {
32
- error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
102
return;
33
- return -1;
103
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
34
+ fd = RETRY_ON_EINTR(open(PATH_NET_TUN, O_RDWR));
104
compare_get_timeout,
35
+ if (fd < 0) {
105
compare_set_timeout, NULL, NULL, NULL);
36
+ error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
106
37
+ return -1;
107
+ object_property_add(obj, "expired_scan_cycle", "uint32",
38
+ }
108
+ compare_get_expired_scan_cycle,
39
}
109
+ compare_set_expired_scan_cycle, NULL, NULL, NULL);
40
memset(&ifr, 0, sizeof(ifr));
110
+
41
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
111
s->vnet_hdr = false;
112
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
113
compare_set_vnet_hdr, NULL);
114
diff --git a/qemu-options.hx b/qemu-options.hx
115
index XXXXXXX..XXXXXXX 100644
116
--- a/qemu-options.hx
117
+++ b/qemu-options.hx
118
@@ -XXX,XX +XXX,XX @@ SRST
119
stored. The file format is libpcap, so it can be analyzed with
120
tools such as tcpdump or Wireshark.
121
122
- ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}]``
123
+ ``-object colo-compare,id=id,primary_in=chardevid,secondary_in=chardevid,outdev=chardevid,iothread=id[,vnet_hdr_support][,notify_dev=id][,compare_timeout=@var{ms}][,expired_scan_cycle=@var{ms}``
124
Colo-compare gets packet from primary\_inchardevid and
125
secondary\_inchardevid, than compare primary packet with
126
secondary packet. If the packets are same, we will output
127
@@ -XXX,XX +XXX,XX @@ SRST
128
vnet\_hdr\_support flag, colo compare will send/recv packet with
129
vnet\_hdr\_len. Then compare\_timeout=@var{ms} determines the
130
maximum delay colo-compare wait for the packet.
131
+ The expired\_scan\_cycle=@var{ms} to set the period of scanning
132
+ expired primary node network packets.
133
If you want to use Xen COLO, will need the notify\_dev to
134
notify Xen colo-frame to do checkpoint.
135
136
--
42
--
137
2.5.0
43
2.42.0
138
139
diff view generated by jsdifflib