1 | The following changes since commit 23895cbd82be95428e90168b12e925d0d3ca2f06: | 1 | The following changes since commit 97c81ef4b8e203d9620fd46e7eb77004563e3675: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20201123.0' into staging (2020-11-23 18:51:13 +0000) | 3 | Merge tag 'pull-9p-20230706' of https://github.com/cschoenebeck/qemu into staging (2023-07-06 18:19:42 +0100) |
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 9925990d01a92564af55f6f69d0f5f59b47609b1: | 9 | for you to fetch changes up to da9f7f7769e8e65f6423095e978f9a375e33515c: |
10 | 10 | ||
11 | net: Use correct default-path macro for downscript (2020-11-24 10:40:17 +0800) | 11 | igb: Remove obsolete workaround for Windows (2023-07-07 16:35:12 +0800) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | 14 | ||
15 | ---------------------------------------------------------------- | 15 | ---------------------------------------------------------------- |
16 | Keqian Zhu (1): | 16 | Akihiko Odaki (2): |
17 | net: Use correct default-path macro for downscript | 17 | e1000e: Add ICR clearing by corresponding IMS bit |
18 | igb: Remove obsolete workaround for Windows | ||
18 | 19 | ||
19 | Paolo Bonzini (1): | 20 | Bin Meng (9): |
20 | net: do not exit on "netdev_add help" monitor command | 21 | hw/net: e1000: Remove the logic of padding short frames in the receive path |
22 | hw/net: vmxnet3: Remove the logic of padding short frames in the receive path | ||
23 | hw/net: i82596: Remove the logic of padding short frames in the receive path | ||
24 | hw/net: ne2000: Remove the logic of padding short frames in the receive path | ||
25 | hw/net: pcnet: Remove the logic of padding short frames in the receive path | ||
26 | hw/net: rtl8139: Remove the logic of padding short frames in the receive path | ||
27 | hw/net: sungem: Remove the logic of padding short frames in the receive path | ||
28 | hw/net: sunhme: Remove the logic of padding short frames in the receive path | ||
29 | hw/net: ftgmac100: Drop the small packet check in the receive path | ||
21 | 30 | ||
22 | Prasad J Pandit (1): | 31 | Laurent Vivier (4): |
23 | hw/net/e1000e: advance desc_offset in case of null descriptor | 32 | virtio-net: correctly report maximum tx_queue_size value |
33 | net: socket: prepare to cleanup net_init_socket() | ||
34 | net: socket: move fd type checking to its own function | ||
35 | net: socket: remove net_init_socket() | ||
24 | 36 | ||
25 | Yuri Benditovich (1): | 37 | hw/net/e1000.c | 11 +---------- |
26 | net: purge queued rx packets on queue deletion | 38 | hw/net/e1000e_core.c | 38 +++++++++++++++++++++++++++++++------ |
27 | 39 | hw/net/ftgmac100.c | 8 -------- | |
28 | yuanjungong (1): | 40 | hw/net/i82596.c | 18 ------------------ |
29 | tap: fix a memory leak | 41 | hw/net/igb_core.c | 7 +------ |
30 | 42 | hw/net/ne2000.c | 12 ------------ | |
31 | hw/net/e1000e_core.c | 8 +++--- | 43 | hw/net/pcnet.c | 9 --------- |
32 | include/net/net.h | 1 + | 44 | hw/net/rtl8139.c | 12 ------------ |
33 | monitor/hmp-cmds.c | 6 ++++ | 45 | hw/net/sungem.c | 14 -------------- |
34 | net/net.c | 80 +++++++++++++++++++++++++++------------------------- | 46 | hw/net/sunhme.c | 11 ----------- |
35 | net/tap.c | 5 +++- | 47 | hw/net/trace-events | 1 + |
36 | 5 files changed, 57 insertions(+), 43 deletions(-) | 48 | hw/net/virtio-net.c | 4 ++-- |
37 | 49 | hw/net/vmxnet3.c | 10 ---------- | |
38 | 50 | net/socket.c | 53 +++++++++++++++++++++++++++------------------------- | |
51 | 14 files changed, 65 insertions(+), 143 deletions(-) | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
1 | 2 | ||
3 | Maximum value for tx_queue_size depends on the backend type. | ||
4 | 1024 for vDPA/vhost-user, 256 for all the others. | ||
5 | |||
6 | The value is returned by virtio_net_max_tx_queue_size() to set the | ||
7 | parameter: | ||
8 | |||
9 | n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n), | ||
10 | n->net_conf.tx_queue_size); | ||
11 | |||
12 | But the parameter checking uses VIRTQUEUE_MAX_SIZE (1024). | ||
13 | |||
14 | So the parameter is silently ignored and ethtool reports a different | ||
15 | value than the one provided by the user. | ||
16 | |||
17 | ... -netdev tap,... -device virtio-net,tx_queue_size=1024 | ||
18 | |||
19 | # ethtool -g enp0s2 | ||
20 | Ring parameters for enp0s2: | ||
21 | Pre-set maximums: | ||
22 | RX: 256 | ||
23 | RX Mini: n/a | ||
24 | RX Jumbo: n/a | ||
25 | TX: 256 | ||
26 | Current hardware settings: | ||
27 | RX: 256 | ||
28 | RX Mini: n/a | ||
29 | RX Jumbo: n/a | ||
30 | TX: 256 | ||
31 | |||
32 | ... -netdev vhost-user,... -device virtio-net,tx_queue_size=2048 | ||
33 | |||
34 | Invalid tx_queue_size (= 2048), must be a power of 2 between 256 and 1024 | ||
35 | |||
36 | With this patch the correct maximum value is checked and displayed. | ||
37 | |||
38 | For vDPA/vhost-user: | ||
39 | |||
40 | Invalid tx_queue_size (= 2048), must be a power of 2 between 256 and 1024 | ||
41 | |||
42 | For all the others: | ||
43 | |||
44 | Invalid tx_queue_size (= 512), must be a power of 2 between 256 and 256 | ||
45 | |||
46 | Fixes: 2eef278b9e63 ("virtio-net: fix tx queue size for !vhost-user") | ||
47 | Cc: mst@redhat.com | ||
48 | Cc: qemu-stable@nongnu.org | ||
49 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
50 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
51 | --- | ||
52 | hw/net/virtio-net.c | 4 ++-- | ||
53 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
54 | |||
55 | diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/hw/net/virtio-net.c | ||
58 | +++ b/hw/net/virtio-net.c | ||
59 | @@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) | ||
60 | } | ||
61 | |||
62 | if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE || | ||
63 | - n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE || | ||
64 | + n->net_conf.tx_queue_size > virtio_net_max_tx_queue_size(n) || | ||
65 | !is_power_of_2(n->net_conf.tx_queue_size)) { | ||
66 | error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), " | ||
67 | "must be a power of 2 between %d and %d", | ||
68 | n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE, | ||
69 | - VIRTQUEUE_MAX_SIZE); | ||
70 | + virtio_net_max_tx_queue_size(n)); | ||
71 | virtio_cleanup(vdev); | ||
72 | return; | ||
73 | } | ||
74 | -- | ||
75 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
1 | 2 | ||
3 | Now that we have implemented unified short frames padding in the | ||
4 | QEMU networking codes, remove the same logic in the NIC codes. | ||
5 | |||
6 | This actually reverts commit 78aeb23eded2d0b765bf9145c71f80025b568acd. | ||
7 | |||
8 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
9 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
10 | --- | ||
11 | hw/net/e1000.c | 11 +---------- | ||
12 | 1 file changed, 1 insertion(+), 10 deletions(-) | ||
13 | |||
14 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/hw/net/e1000.c | ||
17 | +++ b/hw/net/e1000.c | ||
18 | @@ -XXX,XX +XXX,XX @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) | ||
19 | uint16_t vlan_special = 0; | ||
20 | uint8_t vlan_status = 0; | ||
21 | uint8_t min_buf[ETH_ZLEN]; | ||
22 | - struct iovec min_iov; | ||
23 | uint8_t *filter_buf = iov->iov_base; | ||
24 | size_t size = iov_size(iov, iovcnt); | ||
25 | size_t iov_ofs = 0; | ||
26 | @@ -XXX,XX +XXX,XX @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | - /* Pad to minimum Ethernet frame length */ | ||
31 | - if (size < sizeof(min_buf)) { | ||
32 | - iov_to_buf(iov, iovcnt, 0, min_buf, size); | ||
33 | - memset(&min_buf[size], 0, sizeof(min_buf) - size); | ||
34 | - min_iov.iov_base = filter_buf = min_buf; | ||
35 | - min_iov.iov_len = size = sizeof(min_buf); | ||
36 | - iovcnt = 1; | ||
37 | - iov = &min_iov; | ||
38 | - } else if (iov->iov_len < MAXIMUM_ETHERNET_HDR_LEN) { | ||
39 | + if (iov->iov_len < MAXIMUM_ETHERNET_HDR_LEN) { | ||
40 | /* This is very unlikely, but may happen. */ | ||
41 | iov_to_buf(iov, iovcnt, 0, min_buf, MAXIMUM_ETHERNET_HDR_LEN); | ||
42 | filter_buf = min_buf; | ||
43 | -- | ||
44 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
1 | 2 | ||
3 | Now that we have implemented unified short frames padding in the | ||
4 | QEMU networking codes, remove the same logic in the NIC codes. | ||
5 | |||
6 | This actually reverts commit 40a87c6c9b11ef9c14e0301f76abf0eb2582f08e. | ||
7 | |||
8 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
9 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
10 | --- | ||
11 | hw/net/vmxnet3.c | 10 ---------- | ||
12 | 1 file changed, 10 deletions(-) | ||
13 | |||
14 | diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/hw/net/vmxnet3.c | ||
17 | +++ b/hw/net/vmxnet3.c | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | |||
20 | #define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1 | ||
21 | #define VMXNET3_MSIX_BAR_SIZE 0x2000 | ||
22 | -#define MIN_BUF_SIZE 60 | ||
23 | |||
24 | /* Compatibility flags for migration */ | ||
25 | #define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0 | ||
26 | @@ -XXX,XX +XXX,XX @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size) | ||
27 | { | ||
28 | VMXNET3State *s = qemu_get_nic_opaque(nc); | ||
29 | size_t bytes_indicated; | ||
30 | - uint8_t min_buf[MIN_BUF_SIZE]; | ||
31 | |||
32 | if (!vmxnet3_can_receive(nc)) { | ||
33 | VMW_PKPRN("Cannot receive now"); | ||
34 | @@ -XXX,XX +XXX,XX @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size) | ||
35 | size -= sizeof(struct virtio_net_hdr); | ||
36 | } | ||
37 | |||
38 | - /* Pad to minimum Ethernet frame length */ | ||
39 | - if (size < sizeof(min_buf)) { | ||
40 | - memcpy(min_buf, buf, size); | ||
41 | - memset(&min_buf[size], 0, sizeof(min_buf) - size); | ||
42 | - buf = min_buf; | ||
43 | - size = sizeof(min_buf); | ||
44 | - } | ||
45 | - | ||
46 | net_rx_pkt_set_packet_type(s->rx_pkt, | ||
47 | get_eth_packet_type(PKT_GET_ETH_HDR(buf))); | ||
48 | |||
49 | -- | ||
50 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
1 | 2 | ||
3 | Now that we have implemented unified short frames padding in the | ||
4 | QEMU networking codes, remove the same logic in the NIC codes. | ||
5 | |||
6 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | hw/net/i82596.c | 18 ------------------ | ||
10 | 1 file changed, 18 deletions(-) | ||
11 | |||
12 | diff --git a/hw/net/i82596.c b/hw/net/i82596.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/net/i82596.c | ||
15 | +++ b/hw/net/i82596.c | ||
16 | @@ -XXX,XX +XXX,XX @@ enum commands { | ||
17 | #define I596_EOF 0x8000 | ||
18 | #define SIZE_MASK 0x3fff | ||
19 | |||
20 | -#define ETHER_TYPE_LEN 2 | ||
21 | -#define VLAN_TCI_LEN 2 | ||
22 | -#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN) | ||
23 | - | ||
24 | /* various flags in the chip config registers */ | ||
25 | #define I596_PREFETCH (s->config[0] & 0x80) | ||
26 | #define I596_PROMISC (s->config[8] & 0x01) | ||
27 | @@ -XXX,XX +XXX,XX @@ bool i82596_can_receive(NetClientState *nc) | ||
28 | return true; | ||
29 | } | ||
30 | |||
31 | -#define MIN_BUF_SIZE 60 | ||
32 | - | ||
33 | ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz) | ||
34 | { | ||
35 | I82596State *s = qemu_get_nic_opaque(nc); | ||
36 | @@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz) | ||
37 | size_t bufsz = sz; /* length of data in buf */ | ||
38 | uint32_t crc; | ||
39 | uint8_t *crc_ptr; | ||
40 | - uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN]; | ||
41 | static const uint8_t broadcast_macaddr[6] = { | ||
42 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
43 | |||
44 | @@ -XXX,XX +XXX,XX @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | - /* if too small buffer, then expand it */ | ||
49 | - if (len < MIN_BUF_SIZE + VLAN_HLEN) { | ||
50 | - memcpy(buf1, buf, len); | ||
51 | - memset(buf1 + len, 0, MIN_BUF_SIZE + VLAN_HLEN - len); | ||
52 | - buf = buf1; | ||
53 | - if (len < MIN_BUF_SIZE) { | ||
54 | - len = MIN_BUF_SIZE; | ||
55 | - } | ||
56 | - bufsz = len; | ||
57 | - } | ||
58 | - | ||
59 | /* Calculate the ethernet checksum (4 bytes) */ | ||
60 | len += 4; | ||
61 | crc = cpu_to_be32(crc32(~0, buf, sz)); | ||
62 | -- | ||
63 | 2.7.4 | diff view generated by jsdifflib |
1 | From: Paolo Bonzini <pbonzini@redhat.com> | 1 | From: Bin Meng <bmeng@tinylab.org> |
---|---|---|---|
2 | 2 | ||
3 | "netdev_add help" is causing QEMU to exit because the code that | 3 | Now that we have implemented unified short frames padding in the |
4 | invokes show_netdevs is shared between CLI and HMP processing. | 4 | QEMU networking codes, remove the same logic in the NIC codes. |
5 | Move the check to the callers so that exit(0) remains only | ||
6 | in the CLI flow. | ||
7 | 5 | ||
8 | "netdev_add help" is not fixed by this patch; that is left for | 6 | Signed-off-by: Bin Meng <bmeng@tinylab.org> |
9 | later work. | ||
10 | |||
11 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | ||
12 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 7 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
13 | --- | 8 | --- |
14 | include/net/net.h | 1 + | 9 | hw/net/ne2000.c | 12 ------------ |
15 | monitor/hmp-cmds.c | 6 +++++ | 10 | 1 file changed, 12 deletions(-) |
16 | net/net.c | 68 +++++++++++++++++++++++++++--------------------------- | ||
17 | 3 files changed, 41 insertions(+), 34 deletions(-) | ||
18 | 11 | ||
19 | diff --git a/include/net/net.h b/include/net/net.h | 12 | diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c |
20 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/include/net/net.h | 14 | --- a/hw/net/ne2000.c |
22 | +++ b/include/net/net.h | 15 | +++ b/hw/net/ne2000.c |
23 | @@ -XXX,XX +XXX,XX @@ extern const char *host_net_devices[]; | 16 | @@ -XXX,XX +XXX,XX @@ static int ne2000_buffer_full(NE2000State *s) |
24 | |||
25 | /* from net.c */ | ||
26 | int net_client_parse(QemuOptsList *opts_list, const char *str); | ||
27 | +void show_netdevs(void); | ||
28 | int net_init_clients(Error **errp); | ||
29 | void net_check_clients(void); | ||
30 | void net_cleanup(void); | ||
31 | diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/monitor/hmp-cmds.c | ||
34 | +++ b/monitor/hmp-cmds.c | ||
35 | @@ -XXX,XX +XXX,XX @@ | ||
36 | #include "qemu/option.h" | ||
37 | #include "qemu/timer.h" | ||
38 | #include "qemu/sockets.h" | ||
39 | +#include "qemu/help_option.h" | ||
40 | #include "monitor/monitor-internal.h" | ||
41 | #include "qapi/error.h" | ||
42 | #include "qapi/clone-visitor.h" | ||
43 | @@ -XXX,XX +XXX,XX @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict) | ||
44 | { | ||
45 | Error *err = NULL; | ||
46 | QemuOpts *opts; | ||
47 | + const char *type = qdict_get_try_str(qdict, "type"); | ||
48 | |||
49 | + if (type && is_help_option(type)) { | ||
50 | + show_netdevs(); | ||
51 | + return; | ||
52 | + } | ||
53 | opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err); | ||
54 | if (err) { | ||
55 | goto out; | ||
56 | diff --git a/net/net.c b/net/net.c | ||
57 | index XXXXXXX..XXXXXXX 100644 | ||
58 | --- a/net/net.c | ||
59 | +++ b/net/net.c | ||
60 | @@ -XXX,XX +XXX,XX @@ | ||
61 | #include "qemu/config-file.h" | ||
62 | #include "qemu/ctype.h" | ||
63 | #include "qemu/iov.h" | ||
64 | +#include "qemu/qemu-print.h" | ||
65 | #include "qemu/main-loop.h" | ||
66 | #include "qemu/option.h" | ||
67 | #include "qapi/error.h" | ||
68 | @@ -XXX,XX +XXX,XX @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp) | ||
69 | return 0; | 17 | return 0; |
70 | } | 18 | } |
71 | 19 | ||
72 | -static void show_netdevs(void) | 20 | -#define MIN_BUF_SIZE 60 |
73 | +void show_netdevs(void) | 21 | - |
22 | ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_) | ||
74 | { | 23 | { |
75 | int idx; | 24 | NE2000State *s = qemu_get_nic_opaque(nc); |
76 | const char *available_netdevs[] = { | 25 | size_t size = size_; |
77 | @@ -XXX,XX +XXX,XX @@ static void show_netdevs(void) | 26 | uint8_t *p; |
78 | #endif | 27 | unsigned int total_len, next, avail, len, index, mcast_idx; |
79 | }; | 28 | - uint8_t buf1[60]; |
80 | 29 | static const uint8_t broadcast_macaddr[6] = | |
81 | - printf("Available netdev backend types:\n"); | 30 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
82 | + qemu_printf("Available netdev backend types:\n"); | 31 | |
83 | for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) { | 32 | @@ -XXX,XX +XXX,XX @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_) |
84 | - puts(available_netdevs[idx]); | 33 | } |
85 | + qemu_printf("%s\n", available_netdevs[idx]); | ||
86 | } | 34 | } |
87 | } | 35 | |
88 | |||
89 | @@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) | ||
90 | int ret = -1; | ||
91 | Visitor *v = opts_visitor_new(opts); | ||
92 | |||
93 | - const char *type = qemu_opt_get(opts, "type"); | ||
94 | - | 36 | - |
95 | - if (is_netdev && type && is_help_option(type)) { | 37 | - /* if too small buffer, then expand it */ |
96 | - show_netdevs(); | 38 | - if (size < MIN_BUF_SIZE) { |
97 | - exit(0); | 39 | - memcpy(buf1, buf, size); |
98 | - } else { | 40 | - memset(buf1 + size, 0, MIN_BUF_SIZE - size); |
99 | - /* Parse convenience option format ip6-net=fec0::0[/64] */ | 41 | - buf = buf1; |
100 | - const char *ip6_net = qemu_opt_get(opts, "ipv6-net"); | 42 | - size = MIN_BUF_SIZE; |
101 | + /* Parse convenience option format ip6-net=fec0::0[/64] */ | 43 | - } |
102 | + const char *ip6_net = qemu_opt_get(opts, "ipv6-net"); | ||
103 | |||
104 | - if (ip6_net) { | ||
105 | - char *prefix_addr; | ||
106 | - unsigned long prefix_len = 64; /* Default 64bit prefix length. */ | ||
107 | + if (ip6_net) { | ||
108 | + char *prefix_addr; | ||
109 | + unsigned long prefix_len = 64; /* Default 64bit prefix length. */ | ||
110 | |||
111 | - substrings = g_strsplit(ip6_net, "/", 2); | ||
112 | - if (!substrings || !substrings[0]) { | ||
113 | - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net", | ||
114 | - "a valid IPv6 prefix"); | ||
115 | - goto out; | ||
116 | - } | ||
117 | + substrings = g_strsplit(ip6_net, "/", 2); | ||
118 | + if (!substrings || !substrings[0]) { | ||
119 | + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net", | ||
120 | + "a valid IPv6 prefix"); | ||
121 | + goto out; | ||
122 | + } | ||
123 | |||
124 | - prefix_addr = substrings[0]; | ||
125 | + prefix_addr = substrings[0]; | ||
126 | |||
127 | - /* Handle user-specified prefix length. */ | ||
128 | - if (substrings[1] && | ||
129 | - qemu_strtoul(substrings[1], NULL, 10, &prefix_len)) | ||
130 | - { | ||
131 | - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, | ||
132 | - "ipv6-prefixlen", "a number"); | ||
133 | - goto out; | ||
134 | - } | ||
135 | - | 44 | - |
136 | - qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort); | 45 | index = s->curpag << 8; |
137 | - qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len, | 46 | if (index >= NE2000_PMEM_END) { |
138 | - &error_abort); | 47 | index = s->start; |
139 | - qemu_opt_unset(opts, "ipv6-net"); | ||
140 | + /* Handle user-specified prefix length. */ | ||
141 | + if (substrings[1] && | ||
142 | + qemu_strtoul(substrings[1], NULL, 10, &prefix_len)) | ||
143 | + { | ||
144 | + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, | ||
145 | + "ipv6-prefixlen", "a number"); | ||
146 | + goto out; | ||
147 | } | ||
148 | + | ||
149 | + qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort); | ||
150 | + qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len, | ||
151 | + &error_abort); | ||
152 | + qemu_opt_unset(opts, "ipv6-net"); | ||
153 | } | ||
154 | |||
155 | /* Create an ID for -net if the user did not specify one */ | ||
156 | @@ -XXX,XX +XXX,XX @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp) | ||
157 | |||
158 | static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp) | ||
159 | { | ||
160 | + const char *type = qemu_opt_get(opts, "type"); | ||
161 | + | ||
162 | + if (type && is_help_option(type)) { | ||
163 | + show_netdevs(); | ||
164 | + exit(0); | ||
165 | + } | ||
166 | return net_client_init(opts, true, errp); | ||
167 | } | ||
168 | |||
169 | -- | 48 | -- |
170 | 2.7.4 | 49 | 2.7.4 |
171 | |||
172 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
1 | 2 | ||
3 | Now that we have implemented unified short frames padding in the | ||
4 | QEMU networking codes, remove the same logic in the NIC codes. | ||
5 | |||
6 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | hw/net/pcnet.c | 9 --------- | ||
10 | 1 file changed, 9 deletions(-) | ||
11 | |||
12 | diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/net/pcnet.c | ||
15 | +++ b/hw/net/pcnet.c | ||
16 | @@ -XXX,XX +XXX,XX @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_) | ||
17 | { | ||
18 | PCNetState *s = qemu_get_nic_opaque(nc); | ||
19 | int is_padr = 0, is_bcast = 0, is_ladr = 0; | ||
20 | - uint8_t buf1[60]; | ||
21 | int remaining; | ||
22 | int crc_err = 0; | ||
23 | size_t size = size_; | ||
24 | @@ -XXX,XX +XXX,XX @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_) | ||
25 | printf("pcnet_receive size=%zu\n", size); | ||
26 | #endif | ||
27 | |||
28 | - /* if too small buffer, then expand it */ | ||
29 | - if (size < MIN_BUF_SIZE) { | ||
30 | - memcpy(buf1, buf, size); | ||
31 | - memset(buf1 + size, 0, MIN_BUF_SIZE - size); | ||
32 | - buf = buf1; | ||
33 | - size = MIN_BUF_SIZE; | ||
34 | - } | ||
35 | - | ||
36 | if (CSR_PROM(s) | ||
37 | || (is_padr=padr_match(s, buf, size)) | ||
38 | || (is_bcast=padr_bcast(s, buf, size)) | ||
39 | -- | ||
40 | 2.7.4 | diff view generated by jsdifflib |
1 | From: Yuri Benditovich <yuri.benditovich@daynix.com> | 1 | From: Bin Meng <bmeng@tinylab.org> |
---|---|---|---|
2 | 2 | ||
3 | https://bugzilla.redhat.com/show_bug.cgi?id=1829272 | 3 | Now that we have implemented unified short frames padding in the |
4 | When deleting queue pair, purge pending RX packets if any. | 4 | QEMU networking codes, remove the same logic in the NIC codes. |
5 | Example of problematic flow: | ||
6 | 1. Bring up q35 VM with tap (vhost off) and virtio-net or e1000e | ||
7 | 2. Run ping flood to the VM NIC ( 1 ms interval) | ||
8 | 3. Hot unplug the NIC device (device_del) | ||
9 | During unplug process one or more packets come, the NIC | ||
10 | can't receive, tap disables read_poll | ||
11 | 4. Hot plug the device (device_add) with the same netdev | ||
12 | The tap stays with read_poll disabled and does not receive | ||
13 | any packets anymore (tap_send never triggered) | ||
14 | 5 | ||
15 | Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com> | 6 | Signed-off-by: Bin Meng <bmeng@tinylab.org> |
16 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 7 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
17 | --- | 8 | --- |
18 | net/net.c | 12 ++++++++---- | 9 | hw/net/rtl8139.c | 12 ------------ |
19 | 1 file changed, 8 insertions(+), 4 deletions(-) | 10 | 1 file changed, 12 deletions(-) |
20 | 11 | ||
21 | diff --git a/net/net.c b/net/net.c | 12 | diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c |
22 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/net/net.c | 14 | --- a/hw/net/rtl8139.c |
24 | +++ b/net/net.c | 15 | +++ b/hw/net/rtl8139.c |
25 | @@ -XXX,XX +XXX,XX @@ void qemu_del_nic(NICState *nic) | 16 | @@ -XXX,XX +XXX,XX @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t |
26 | 17 | ||
27 | qemu_macaddr_set_free(&nic->conf->macaddr); | 18 | uint32_t packet_header = 0; |
28 | 19 | ||
29 | - /* If this is a peer NIC and peer has already been deleted, free it now. */ | 20 | - uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN]; |
30 | - if (nic->peer_deleted) { | 21 | static const uint8_t broadcast_macaddr[6] = |
31 | - for (i = 0; i < queues; i++) { | 22 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
32 | - qemu_free_net_client(qemu_get_subqueue(nic, i)->peer); | 23 | |
33 | + for (i = 0; i < queues; i++) { | 24 | @@ -XXX,XX +XXX,XX @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t |
34 | + NetClientState *nc = qemu_get_subqueue(nic, i); | ||
35 | + /* If this is a peer NIC and peer has already been deleted, free it now. */ | ||
36 | + if (nic->peer_deleted) { | ||
37 | + qemu_free_net_client(nc->peer); | ||
38 | + } else if (nc->peer) { | ||
39 | + /* if there are RX packets pending, complete them */ | ||
40 | + qemu_purge_queued_packets(nc->peer); | ||
41 | } | 25 | } |
42 | } | 26 | } |
43 | 27 | ||
28 | - /* if too small buffer, then expand it | ||
29 | - * Include some tailroom in case a vlan tag is later removed. */ | ||
30 | - if (size < MIN_BUF_SIZE + VLAN_HLEN) { | ||
31 | - memcpy(buf1, buf, size); | ||
32 | - memset(buf1 + size, 0, MIN_BUF_SIZE + VLAN_HLEN - size); | ||
33 | - buf = buf1; | ||
34 | - if (size < MIN_BUF_SIZE) { | ||
35 | - size = MIN_BUF_SIZE; | ||
36 | - } | ||
37 | - } | ||
38 | - | ||
39 | if (rtl8139_cp_receiver_enabled(s)) | ||
40 | { | ||
41 | if (!rtl8139_cp_rx_valid(s)) { | ||
44 | -- | 42 | -- |
45 | 2.7.4 | 43 | 2.7.4 |
46 | |||
47 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
1 | 2 | ||
3 | Now that we have implemented unified short frames padding in the | ||
4 | QEMU networking codes, remove the same logic in the NIC codes. | ||
5 | |||
6 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | hw/net/sungem.c | 14 -------------- | ||
10 | 1 file changed, 14 deletions(-) | ||
11 | |||
12 | diff --git a/hw/net/sungem.c b/hw/net/sungem.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/net/sungem.c | ||
15 | +++ b/hw/net/sungem.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static ssize_t sungem_receive(NetClientState *nc, const uint8_t *buf, | ||
17 | PCIDevice *d = PCI_DEVICE(s); | ||
18 | uint32_t mac_crc, done, kick, max_fsize; | ||
19 | uint32_t fcs_size, ints, rxdma_cfg, rxmac_cfg, csum, coff; | ||
20 | - uint8_t smallbuf[60]; | ||
21 | struct gem_rxd desc; | ||
22 | uint64_t dbase, baddr; | ||
23 | unsigned int rx_cond; | ||
24 | @@ -XXX,XX +XXX,XX @@ static ssize_t sungem_receive(NetClientState *nc, const uint8_t *buf, | ||
25 | return size; | ||
26 | } | ||
27 | |||
28 | - /* We don't drop too small frames since we get them in qemu, we pad | ||
29 | - * them instead. We should probably use the min frame size register | ||
30 | - * but I don't want to use a variable size staging buffer and I | ||
31 | - * know both MacOS and Linux use the default 64 anyway. We use 60 | ||
32 | - * here to account for the non-existent FCS. | ||
33 | - */ | ||
34 | - if (size < 60) { | ||
35 | - memcpy(smallbuf, buf, size); | ||
36 | - memset(&smallbuf[size], 0, 60 - size); | ||
37 | - buf = smallbuf; | ||
38 | - size = 60; | ||
39 | - } | ||
40 | - | ||
41 | /* Get MAC crc */ | ||
42 | mac_crc = net_crc32_le(buf, ETH_ALEN); | ||
43 | |||
44 | -- | ||
45 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
1 | 2 | ||
3 | Now that we have implemented unified short frames padding in the | ||
4 | QEMU networking codes, remove the same logic in the NIC codes. | ||
5 | |||
6 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | hw/net/sunhme.c | 11 ----------- | ||
10 | 1 file changed, 11 deletions(-) | ||
11 | |||
12 | diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/net/sunhme.c | ||
15 | +++ b/hw/net/sunhme.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static inline void sunhme_set_rx_ring_nr(SunHMEState *s, int i) | ||
17 | s->erxregs[HME_ERXI_RING >> 2] = ring; | ||
18 | } | ||
19 | |||
20 | -#define MIN_BUF_SIZE 60 | ||
21 | - | ||
22 | static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf, | ||
23 | size_t size) | ||
24 | { | ||
25 | @@ -XXX,XX +XXX,XX @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf, | ||
26 | dma_addr_t rb, addr; | ||
27 | uint32_t intstatus, status, buffer, buffersize, sum; | ||
28 | uint16_t csum; | ||
29 | - uint8_t buf1[60]; | ||
30 | int nr, cr, len, rxoffset, csum_offset; | ||
31 | |||
32 | trace_sunhme_rx_incoming(size); | ||
33 | @@ -XXX,XX +XXX,XX @@ static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf, | ||
34 | |||
35 | trace_sunhme_rx_filter_accept(); | ||
36 | |||
37 | - /* If too small buffer, then expand it */ | ||
38 | - if (size < MIN_BUF_SIZE) { | ||
39 | - memcpy(buf1, buf, size); | ||
40 | - memset(buf1 + size, 0, MIN_BUF_SIZE - size); | ||
41 | - buf = buf1; | ||
42 | - size = MIN_BUF_SIZE; | ||
43 | - } | ||
44 | - | ||
45 | rb = s->erxregs[HME_ERXI_RING >> 2] & HME_ERXI_RING_ADDR; | ||
46 | nr = sunhme_get_rx_ring_count(s); | ||
47 | cr = sunhme_get_rx_ring_nr(s); | ||
48 | -- | ||
49 | 2.7.4 | diff view generated by jsdifflib |
1 | From: Keqian Zhu <zhukeqian1@huawei.com> | 1 | From: Bin Meng <bmeng@tinylab.org> |
---|---|---|---|
2 | 2 | ||
3 | Fixes: 63c4db4c2e6d (net: relocate paths to helpers and scripts) | 3 | Now that we have implemented unified short frames padding in the |
4 | Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com> | 4 | QEMU networking codes, the small packet check logic in the receive |
5 | path is no longer needed. | ||
6 | |||
7 | Suggested-by: Cédric Le Goater <clg@kaod.org> | ||
8 | Reviewed-by: Cédric Le Goater <clg@kaod.org> | ||
9 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
5 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 10 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
6 | --- | 11 | --- |
7 | net/tap.c | 3 ++- | 12 | hw/net/ftgmac100.c | 8 -------- |
8 | 1 file changed, 2 insertions(+), 1 deletion(-) | 13 | 1 file changed, 8 deletions(-) |
9 | 14 | ||
10 | diff --git a/net/tap.c b/net/tap.c | 15 | diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c |
11 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/net/tap.c | 17 | --- a/hw/net/ftgmac100.c |
13 | +++ b/net/tap.c | 18 | +++ b/hw/net/ftgmac100.c |
14 | @@ -XXX,XX +XXX,XX @@ free_fail: | 19 | @@ -XXX,XX +XXX,XX @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, |
15 | script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT); | 20 | return -1; |
16 | } | 21 | } |
17 | if (!downscript) { | 22 | |
18 | - downscript = default_downscript = get_relocated_path(DEFAULT_NETWORK_SCRIPT); | 23 | - /* TODO : Pad to minimum Ethernet frame length */ |
19 | + downscript = default_downscript = | 24 | - /* handle small packets. */ |
20 | + get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT); | 25 | - if (size < 10) { |
21 | } | 26 | - qemu_log_mask(LOG_GUEST_ERROR, "%s: dropped frame of %zd bytes\n", |
22 | 27 | - __func__, size); | |
23 | if (tap->has_ifname) { | 28 | - return size; |
29 | - } | ||
30 | - | ||
31 | if (!ftgmac100_filter(s, buf, size)) { | ||
32 | return size; | ||
33 | } | ||
24 | -- | 34 | -- |
25 | 2.7.4 | 35 | 2.7.4 |
26 | 36 | ||
27 | 37 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
1 | 2 | ||
3 | Use directly net_socket_fd_init_stream() and net_socket_fd_init_dgram() | ||
4 | when the socket type is already known. | ||
5 | |||
6 | Reviewed-by: David Gibson <david@gibson.dropbear.id.au> | ||
7 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
8 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
9 | --- | ||
10 | net/socket.c | 6 +++--- | ||
11 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
12 | |||
13 | diff --git a/net/socket.c b/net/socket.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/net/socket.c | ||
16 | +++ b/net/socket.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer, | ||
18 | break; | ||
19 | } | ||
20 | } | ||
21 | - s = net_socket_fd_init(peer, model, name, fd, connected, NULL, errp); | ||
22 | + s = net_socket_fd_init_stream(peer, model, name, fd, connected); | ||
23 | if (!s) { | ||
24 | return -1; | ||
25 | } | ||
26 | @@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer, | ||
27 | return -1; | ||
28 | } | ||
29 | |||
30 | - s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp); | ||
31 | + s = net_socket_fd_init_dgram(peer, model, name, fd, 0, NULL, errp); | ||
32 | if (!s) { | ||
33 | return -1; | ||
34 | } | ||
35 | @@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer, | ||
36 | } | ||
37 | qemu_socket_set_nonblock(fd); | ||
38 | |||
39 | - s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp); | ||
40 | + s = net_socket_fd_init_dgram(peer, model, name, fd, 0, NULL, errp); | ||
41 | if (!s) { | ||
42 | return -1; | ||
43 | } | ||
44 | -- | ||
45 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Laurent Vivier <lvivier@redhat.com> | ||
1 | 2 | ||
3 | Reviewed-by: David Gibson <david@gibson.dropbear.id.au> | ||
4 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | ||
5 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
6 | --- | ||
7 | net/socket.c | 28 ++++++++++++++++++++-------- | ||
8 | 1 file changed, 20 insertions(+), 8 deletions(-) | ||
9 | |||
10 | diff --git a/net/socket.c b/net/socket.c | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/net/socket.c | ||
13 | +++ b/net/socket.c | ||
14 | @@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer, | ||
15 | return s; | ||
16 | } | ||
17 | |||
18 | +static int net_socket_fd_check(int fd, Error **errp) | ||
19 | +{ | ||
20 | + int so_type, optlen = sizeof(so_type); | ||
21 | + | ||
22 | + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, | ||
23 | + (socklen_t *)&optlen) < 0) { | ||
24 | + error_setg(errp, "can't get socket option SO_TYPE"); | ||
25 | + return -1; | ||
26 | + } | ||
27 | + if (so_type != SOCK_DGRAM && so_type != SOCK_STREAM) { | ||
28 | + error_setg(errp, "socket type=%d for fd=%d must be either" | ||
29 | + " SOCK_DGRAM or SOCK_STREAM", so_type, fd); | ||
30 | + return -1; | ||
31 | + } | ||
32 | + return so_type; | ||
33 | +} | ||
34 | + | ||
35 | static NetSocketState *net_socket_fd_init(NetClientState *peer, | ||
36 | const char *model, const char *name, | ||
37 | int fd, int is_connected, | ||
38 | const char *mc, Error **errp) | ||
39 | { | ||
40 | - int so_type = -1, optlen=sizeof(so_type); | ||
41 | + int so_type; | ||
42 | |||
43 | - if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, | ||
44 | - (socklen_t *)&optlen)< 0) { | ||
45 | - error_setg(errp, "can't get socket option SO_TYPE"); | ||
46 | + so_type = net_socket_fd_check(fd, errp); | ||
47 | + if (so_type < 0) { | ||
48 | close(fd); | ||
49 | return NULL; | ||
50 | } | ||
51 | @@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init(NetClientState *peer, | ||
52 | mc, errp); | ||
53 | case SOCK_STREAM: | ||
54 | return net_socket_fd_init_stream(peer, model, name, fd, is_connected); | ||
55 | - default: | ||
56 | - error_setg(errp, "socket type=%d for fd=%d must be either" | ||
57 | - " SOCK_DGRAM or SOCK_STREAM", so_type, fd); | ||
58 | - close(fd); | ||
59 | } | ||
60 | return NULL; | ||
61 | } | ||
62 | -- | ||
63 | 2.7.4 | diff view generated by jsdifflib |
1 | From: yuanjungong <ruc_gongyuanjun@163.com> | 1 | From: Laurent Vivier <lvivier@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Close fd before returning. | 3 | Move the file descriptor type checking before doing anything with it. |
4 | If it's not usable, don't close it as it could be in use by another | ||
5 | part of QEMU, only fail and report an error. | ||
4 | 6 | ||
5 | Buglink: https://bugs.launchpad.net/qemu/+bug/1904486 | 7 | Reviewed-by: David Gibson <david@gibson.dropbear.id.au> |
6 | 8 | Signed-off-by: Laurent Vivier <lvivier@redhat.com> | |
7 | Signed-off-by: yuanjungong <ruc_gongyuanjun@163.com> | ||
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
9 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 9 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
10 | --- | 10 | --- |
11 | net/tap.c | 2 ++ | 11 | net/socket.c | 43 +++++++++++++++++-------------------------- |
12 | 1 file changed, 2 insertions(+) | 12 | 1 file changed, 17 insertions(+), 26 deletions(-) |
13 | 13 | ||
14 | diff --git a/net/tap.c b/net/tap.c | 14 | diff --git a/net/socket.c b/net/socket.c |
15 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/net/tap.c | 16 | --- a/net/socket.c |
17 | +++ b/net/tap.c | 17 | +++ b/net/socket.c |
18 | @@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name, | 18 | @@ -XXX,XX +XXX,XX @@ static int net_socket_fd_check(int fd, Error **errp) |
19 | return so_type; | ||
20 | } | ||
21 | |||
22 | -static NetSocketState *net_socket_fd_init(NetClientState *peer, | ||
23 | - const char *model, const char *name, | ||
24 | - int fd, int is_connected, | ||
25 | - const char *mc, Error **errp) | ||
26 | -{ | ||
27 | - int so_type; | ||
28 | - | ||
29 | - so_type = net_socket_fd_check(fd, errp); | ||
30 | - if (so_type < 0) { | ||
31 | - close(fd); | ||
32 | - return NULL; | ||
33 | - } | ||
34 | - switch(so_type) { | ||
35 | - case SOCK_DGRAM: | ||
36 | - return net_socket_fd_init_dgram(peer, model, name, fd, is_connected, | ||
37 | - mc, errp); | ||
38 | - case SOCK_STREAM: | ||
39 | - return net_socket_fd_init_stream(peer, model, name, fd, is_connected); | ||
40 | - } | ||
41 | - return NULL; | ||
42 | -} | ||
43 | - | ||
44 | static void net_socket_accept(void *opaque) | ||
45 | { | ||
46 | NetSocketState *s = opaque; | ||
47 | @@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name, | ||
48 | } | ||
49 | |||
50 | if (sock->fd) { | ||
51 | - int fd, ret; | ||
52 | + int fd, ret, so_type; | ||
53 | |||
54 | fd = monitor_fd_param(monitor_cur(), sock->fd, errp); | ||
55 | if (fd == -1) { | ||
56 | return -1; | ||
57 | } | ||
58 | + so_type = net_socket_fd_check(fd, errp); | ||
59 | + if (so_type < 0) { | ||
60 | + return -1; | ||
61 | + } | ||
62 | ret = qemu_socket_try_set_nonblock(fd); | ||
19 | if (ret < 0) { | 63 | if (ret < 0) { |
20 | error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", | 64 | error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", |
21 | name, fd); | 65 | name, fd); |
22 | + close(fd); | ||
23 | return -1; | 66 | return -1; |
24 | } | 67 | } |
25 | 68 | - if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast, | |
26 | @@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name, | 69 | - errp)) { |
27 | vhostfdname, vnet_hdr, fd, &err); | 70 | - return -1; |
28 | if (err) { | 71 | + switch (so_type) { |
29 | error_propagate(errp, err); | 72 | + case SOCK_DGRAM: |
30 | + close(fd); | 73 | + if (!net_socket_fd_init_dgram(peer, "socket", name, fd, 1, |
31 | return -1; | 74 | + sock->mcast, errp)) { |
75 | + return -1; | ||
76 | + } | ||
77 | + break; | ||
78 | + case SOCK_STREAM: | ||
79 | + if (!net_socket_fd_init_stream(peer, "socket", name, fd, 1)) { | ||
80 | + return -1; | ||
81 | + } | ||
82 | + break; | ||
32 | } | 83 | } |
33 | } else if (tap->has_fds) { | 84 | return 0; |
85 | } | ||
34 | -- | 86 | -- |
35 | 2.7.4 | 87 | 2.7.4 |
36 | |||
37 | diff view generated by jsdifflib |
1 | From: Prasad J Pandit <pjp@fedoraproject.org> | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> |
---|---|---|---|
2 | 2 | ||
3 | While receiving packets via e1000e_write_packet_to_guest() routine, | 3 | The datasheet does not say what happens when interrupt was asserted |
4 | 'desc_offset' is advanced only when RX descriptor is processed. And | 4 | (ICR.INT_ASSERT=1) and auto mask is *not* active. |
5 | RX descriptor is not processed if it has NULL buffer address. | 5 | However, section of 13.3.27 the PCIe* GbE Controllers Open Source |
6 | This may lead to an infinite loop condition. Increament 'desc_offset' | 6 | Software Developer’s Manual, which were written for older devices, |
7 | to process next descriptor in the ring to avoid infinite loop. | 7 | namely 631xESB/632xESB, 82563EB/82564EB, 82571EB/82572EI & |
8 | 82573E/82573V/82573L, does say: | ||
9 | > If IMS = 0b, then the ICR register is always clear-on-read. If IMS is | ||
10 | > not 0b, but some ICR bit is set where the corresponding IMS bit is not | ||
11 | > set, then a read does not clear the ICR register. For example, if | ||
12 | > IMS = 10101010b and ICR = 01010101b, then a read to the ICR register | ||
13 | > does not clear it. If IMS = 10101010b and ICR = 0101011b, then a read | ||
14 | > to the ICR register clears it entirely (ICR.INT_ASSERTED = 1b). | ||
8 | 15 | ||
9 | Reported-by: Cheol-woo Myung <330cjfdn@gmail.com> | 16 | Linux does no longer activate auto mask since commit |
10 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | 17 | 0a8047ac68e50e4ccbadcfc6b6b070805b976885 and the real hardware clears |
18 | ICR even in such a case so we also should do so. | ||
19 | |||
20 | Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1707441 | ||
21 | Signed-off-by: Andrew Melnychenko <andrew@daynix.com> | ||
22 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
11 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 23 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
12 | --- | 24 | --- |
13 | hw/net/e1000e_core.c | 8 ++++---- | 25 | hw/net/e1000e_core.c | 38 ++++++++++++++++++++++++++++++++------ |
14 | 1 file changed, 4 insertions(+), 4 deletions(-) | 26 | hw/net/trace-events | 1 + |
27 | 2 files changed, 33 insertions(+), 6 deletions(-) | ||
15 | 28 | ||
16 | diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c | 29 | diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c |
17 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/hw/net/e1000e_core.c | 31 | --- a/hw/net/e1000e_core.c |
19 | +++ b/hw/net/e1000e_core.c | 32 | +++ b/hw/net/e1000e_core.c |
20 | @@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, | 33 | @@ -XXX,XX +XXX,XX @@ e1000e_mac_icr_read(E1000ECore *core, int index) |
21 | (const char *) &fcs_pad, e1000x_fcs_len(core->mac)); | 34 | e1000e_lower_interrupts(core, ICR, 0xffffffff); |
22 | } | 35 | } |
23 | } | 36 | |
24 | - desc_offset += desc_size; | 37 | - if ((core->mac[ICR] & E1000_ICR_ASSERTED) && |
25 | - if (desc_offset >= total_size) { | 38 | - (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { |
26 | - is_last = true; | 39 | - trace_e1000e_irq_icr_clear_iame(); |
27 | - } | 40 | - e1000e_lower_interrupts(core, ICR, 0xffffffff); |
28 | } else { /* as per intel docs; skip descriptors with null buf addr */ | 41 | - trace_e1000e_irq_icr_process_iame(); |
29 | trace_e1000e_rx_null_descriptor(); | 42 | - e1000e_lower_interrupts(core, IMS, core->mac[IAM]); |
30 | } | 43 | + if (core->mac[ICR] & E1000_ICR_ASSERTED) { |
31 | + desc_offset += desc_size; | 44 | + if (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME) { |
32 | + if (desc_offset >= total_size) { | 45 | + trace_e1000e_irq_icr_clear_iame(); |
33 | + is_last = true; | 46 | + e1000e_lower_interrupts(core, ICR, 0xffffffff); |
47 | + trace_e1000e_irq_icr_process_iame(); | ||
48 | + e1000e_lower_interrupts(core, IMS, core->mac[IAM]); | ||
34 | + } | 49 | + } |
35 | 50 | + | |
36 | e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL, | 51 | + /* |
37 | rss_info, do_ps ? ps_hdr_len : 0, &bastate.written); | 52 | + * The datasheet does not say what happens when interrupt was asserted |
53 | + * (ICR.INT_ASSERT=1) and auto mask is *not* active. | ||
54 | + * However, section of 13.3.27 the PCIe* GbE Controllers Open Source | ||
55 | + * Software Developer’s Manual, which were written for older devices, | ||
56 | + * namely 631xESB/632xESB, 82563EB/82564EB, 82571EB/82572EI & | ||
57 | + * 82573E/82573V/82573L, does say: | ||
58 | + * > If IMS = 0b, then the ICR register is always clear-on-read. If IMS | ||
59 | + * > is not 0b, but some ICR bit is set where the corresponding IMS bit | ||
60 | + * > is not set, then a read does not clear the ICR register. For | ||
61 | + * > example, if IMS = 10101010b and ICR = 01010101b, then a read to the | ||
62 | + * > ICR register does not clear it. If IMS = 10101010b and | ||
63 | + * > ICR = 0101011b, then a read to the ICR register clears it entirely | ||
64 | + * > (ICR.INT_ASSERTED = 1b). | ||
65 | + * | ||
66 | + * Linux does no longer activate auto mask since commit | ||
67 | + * 0a8047ac68e50e4ccbadcfc6b6b070805b976885 and the real hardware | ||
68 | + * clears ICR even in such a case so we also should do so. | ||
69 | + */ | ||
70 | + if (core->mac[ICR] & core->mac[IMS]) { | ||
71 | + trace_e1000e_irq_icr_clear_icr_bit_ims(core->mac[ICR], | ||
72 | + core->mac[IMS]); | ||
73 | + e1000e_lower_interrupts(core, ICR, 0xffffffff); | ||
74 | + } | ||
75 | } | ||
76 | |||
77 | return ret; | ||
78 | diff --git a/hw/net/trace-events b/hw/net/trace-events | ||
79 | index XXXXXXX..XXXXXXX 100644 | ||
80 | --- a/hw/net/trace-events | ||
81 | +++ b/hw/net/trace-events | ||
82 | @@ -XXX,XX +XXX,XX @@ e1000e_irq_read_ims(uint32_t ims) "Current IMS: 0x%x" | ||
83 | e1000e_irq_icr_clear_nonmsix_icr_read(void) "Clearing ICR on read due to non MSI-X int" | ||
84 | e1000e_irq_icr_clear_zero_ims(void) "Clearing ICR on read due to zero IMS" | ||
85 | e1000e_irq_icr_clear_iame(void) "Clearing ICR on read due to IAME" | ||
86 | +e1000e_irq_icr_clear_icr_bit_ims(uint32_t icr, uint32_t ims) "Clearing ICR on read due corresponding IMS bit: 0x%x & 0x%x" | ||
87 | e1000e_irq_iam_clear_eiame(uint32_t iam, uint32_t cause) "Clearing IMS due to EIAME, IAM: 0x%X, cause: 0x%X" | ||
88 | e1000e_irq_icr_clear_eiac(uint32_t icr, uint32_t eiac) "Clearing ICR bits due to EIAC, ICR: 0x%X, EIAC: 0x%X" | ||
89 | e1000e_irq_ims_clear_set_imc(uint32_t val) "Clearing IMS bits due to IMC write 0x%x" | ||
38 | -- | 90 | -- |
39 | 2.7.4 | 91 | 2.7.4 |
40 | 92 | ||
41 | 93 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | I confirmed it works with Windows even without this workaround. It is | ||
4 | likely to be a mistake so remove it. | ||
5 | |||
6 | Fixes: 3a977deebe ("Intrdocue igb device emulation") | ||
7 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
8 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
9 | --- | ||
10 | hw/net/igb_core.c | 7 +------ | ||
11 | 1 file changed, 1 insertion(+), 6 deletions(-) | ||
12 | |||
13 | diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/hw/net/igb_core.c | ||
16 | +++ b/hw/net/igb_core.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static uint32_t igb_get_status(IGBCore *core, int index) | ||
18 | res |= E1000_STATUS_IOV_MODE; | ||
19 | } | ||
20 | |||
21 | - /* | ||
22 | - * Windows driver 12.18.9.23 resets if E1000_STATUS_GIO_MASTER_ENABLE is | ||
23 | - * left set after E1000_CTRL_LRST is set. | ||
24 | - */ | ||
25 | - if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE) && | ||
26 | - !(core->mac[CTRL] & E1000_CTRL_LRST)) { | ||
27 | + if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE)) { | ||
28 | res |= E1000_STATUS_GIO_MASTER_ENABLE; | ||
29 | } | ||
30 | |||
31 | -- | ||
32 | 2.7.4 | diff view generated by jsdifflib |