1
The following changes since commit e3debd5e7d0ce031356024878a0a18b9d109354a:
1
The following changes since commit f8d75e10d3e0033a0a29a7a7e4777a4fbc17a016:
2
2
3
Merge tag 'pull-request-2023-03-24' of https://gitlab.com/thuth/qemu into staging (2023-03-24 16:08:46 +0000)
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220112' into staging (2022-01-13 11:18:24 +0000)
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 fba7c3b788dfcb99a3f9253f7d99cc0d217d6d3c:
9
for you to fetch changes up to 818692f0a01587d02220916b31d5bb8e7dced611:
10
10
11
igb: respect VMVIR and VMOLR for VLAN (2023-03-28 13:10:55 +0800)
11
net/vmnet: update MAINTAINERS list (2022-01-14 12:58:19 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
Changes since V2:
16
17
- Try to make vmnet work on some old mac version
18
15
----------------------------------------------------------------
19
----------------------------------------------------------------
16
Akihiko Odaki (4):
20
Peter Foley (2):
17
igb: Save more Tx states
21
net/tap: Set return code on failure
18
igb: Fix DMA requester specification for Tx packet
22
net: Fix uninitialized data usage
19
hw/net/net_tx_pkt: Ignore ECN bit
20
hw/net/net_tx_pkt: Align l3_hdr
21
23
22
Sriram Yagnaraman (8):
24
Philippe Mathieu-Daudé (1):
23
MAINTAINERS: Add Sriram Yagnaraman as a igb reviewer
25
hw/net/vmxnet3: Log guest-triggerable errors using LOG_GUEST_ERROR
24
igb: handle PF/VF reset properly
25
igb: add ICR_RXDW
26
igb: implement VFRE and VFTE registers
27
igb: check oversized packets for VMDq
28
igb: respect E1000_VMOLR_RSSE
29
igb: implement VF Tx and Rx stats
30
igb: respect VMVIR and VMOLR for VLAN
31
26
32
MAINTAINERS | 1 +
27
Rao Lei (1):
33
hw/net/e1000e_core.c | 6 +-
28
net/filter: Optimize filter_send to coroutine
34
hw/net/e1000x_regs.h | 4 +
29
35
hw/net/igb.c | 26 ++++--
30
Vladislav Yaroshchuk (7):
36
hw/net/igb_core.c | 256 ++++++++++++++++++++++++++++++++++++++-------------
31
net/vmnet: add vmnet dependency and customizable option
37
hw/net/igb_core.h | 9 +-
32
net/vmnet: add vmnet backends to qapi/net
38
hw/net/igb_regs.h | 6 ++
33
net/vmnet: implement shared mode (vmnet-shared)
39
hw/net/net_tx_pkt.c | 30 +++---
34
net/vmnet: implement host mode (vmnet-host)
40
hw/net/net_tx_pkt.h | 3 +-
35
net/vmnet: implement bridged mode (vmnet-bridged)
41
hw/net/trace-events | 2 +
36
net/vmnet: update qemu-options.hx
42
hw/net/vmxnet3.c | 4 +-
37
net/vmnet: update MAINTAINERS list
43
11 files changed, 254 insertions(+), 93 deletions(-)
38
39
Zhang Chen (2):
40
net/colo-compare.c: Optimize compare order for performance
41
net/colo-compare.c: Update the default value comments
42
43
MAINTAINERS | 5 +
44
hw/net/vmxnet3.c | 4 +-
45
meson.build | 16 +-
46
meson_options.txt | 2 +
47
net/clients.h | 11 ++
48
net/colo-compare.c | 28 ++--
49
net/filter-mirror.c | 66 +++++++--
50
net/meson.build | 7 +
51
net/net.c | 10 ++
52
net/tap-linux.c | 1 +
53
net/tap.c | 1 +
54
net/vmnet-bridged.m | 120 +++++++++++++++
55
net/vmnet-common.m | 333 ++++++++++++++++++++++++++++++++++++++++++
56
net/vmnet-host.c | 122 ++++++++++++++++
57
net/vmnet-shared.c | 100 +++++++++++++
58
net/vmnet_int.h | 48 ++++++
59
qapi/net.json | 133 ++++++++++++++++-
60
qemu-options.hx | 25 ++++
61
scripts/meson-buildoptions.sh | 3 +
62
19 files changed, 1004 insertions(+), 31 deletions(-)
63
create mode 100644 net/vmnet-bridged.m
64
create mode 100644 net/vmnet-common.m
65
create mode 100644 net/vmnet-host.c
66
create mode 100644 net/vmnet-shared.c
67
create mode 100644 net/vmnet_int.h
68
69
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
igb used to specify the PF as DMA requester when reading Tx packets.
3
The "Interrupt Cause" register (VMXNET3_REG_ICR) is read-only.
4
This made Tx requests from VFs to be performed on the address space of
4
Write accesses are ignored. Log them with as LOG_GUEST_ERROR
5
the PF, defeating the purpose of SR-IOV. Add some logic to change the
5
instead of aborting:
6
requester depending on the queue, which can be assigned to a VF.
7
6
8
Fixes: 3a977deebe ("Intrdocue igb device emulation")
7
[R +0.239743] writeq 0xe0002031 0x46291a5a55460800
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
ERROR:hw/net/vmxnet3.c:1819:vmxnet3_io_bar1_write: code should not be reached
9
Thread 1 "qemu-system-i38" received signal SIGABRT, Aborted.
10
(gdb) bt
11
#3 0x74c397d3 in __GI_abort () at abort.c:79
12
#4 0x76d3cd4c in g_assertion_message (domain=<optimized out>, file=<optimized out>, line=<optimized out>, func=<optimized out>, message=<optimized out>) at ../glib/gtestutils.c:3223
13
#5 0x76d9d45f in g_assertion_message_expr
14
(domain=0x0, file=0x59fc2e53 "hw/net/vmxnet3.c", line=1819, func=0x59fc11e0 <__func__.vmxnet3_io_bar1_write> "vmxnet3_io_bar1_write", expr=<optimized out>)
15
at ../glib/gtestutils.c:3249
16
#6 0x57e80a3a in vmxnet3_io_bar1_write (opaque=0x62814100, addr=56, val=70, size=4) at hw/net/vmxnet3.c:1819
17
#7 0x58c2d894 in memory_region_write_accessor (mr=0x62816b90, addr=56, value=0x7fff9450, size=4, shift=0, mask=4294967295, attrs=...) at softmmu/memory.c:492
18
#8 0x58c2d1d2 in access_with_adjusted_size (addr=56, value=0x7fff9450, size=1, access_size_min=4, access_size_max=4, access_fn=
19
0x58c2d290 <memory_region_write_accessor>, mr=0x62816b90, attrs=...) at softmmu/memory.c:554
20
#9 0x58c2bae7 in memory_region_dispatch_write (mr=0x62816b90, addr=56, data=70, op=MO_8, attrs=...) at softmmu/memory.c:1504
21
#10 0x58bfd034 in flatview_write_continue (fv=0x606000181700, addr=0xe0002038, attrs=..., ptr=0x7fffb9e0, len=1, addr1=56, l=1, mr=0x62816b90)
22
at softmmu/physmem.c:2782
23
#11 0x58beba00 in flatview_write (fv=0x606000181700, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2822
24
#12 0x58beb589 in address_space_write (as=0x608000015f20, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2914
25
26
Reported-by: Dike <dike199774@qq.com>
27
Reported-by: Duhao <504224090@qq.com>
28
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=2032932
29
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
30
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
31
---
12
hw/net/e1000e_core.c | 6 +++---
32
hw/net/vmxnet3.c | 4 +++-
13
hw/net/igb_core.c | 13 ++++++++-----
33
1 file changed, 3 insertions(+), 1 deletion(-)
14
hw/net/net_tx_pkt.c | 3 ++-
15
hw/net/net_tx_pkt.h | 3 ++-
16
hw/net/vmxnet3.c | 4 ++--
17
5 files changed, 17 insertions(+), 12 deletions(-)
18
34
19
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/e1000e_core.c
22
+++ b/hw/net/e1000e_core.c
23
@@ -XXX,XX +XXX,XX @@ e1000e_process_tx_desc(E1000ECore *core,
24
}
25
26
tx->skip_cp = false;
27
- net_tx_pkt_reset(tx->tx_pkt);
28
+ net_tx_pkt_reset(tx->tx_pkt, core->owner);
29
30
tx->sum_needed = 0;
31
tx->cptse = 0;
32
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_uninit(E1000ECore *core)
33
qemu_del_vm_change_state_handler(core->vmstate);
34
35
for (i = 0; i < E1000E_NUM_QUEUES; i++) {
36
- net_tx_pkt_reset(core->tx[i].tx_pkt);
37
+ net_tx_pkt_reset(core->tx[i].tx_pkt, core->owner);
38
net_tx_pkt_uninit(core->tx[i].tx_pkt);
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static void e1000e_reset(E1000ECore *core, bool sw)
42
e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
43
44
for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
45
- net_tx_pkt_reset(core->tx[i].tx_pkt);
46
+ net_tx_pkt_reset(core->tx[i].tx_pkt, core->owner);
47
memset(&core->tx[i].props, 0, sizeof(core->tx[i].props));
48
core->tx[i].skip_cp = false;
49
}
50
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/net/igb_core.c
53
+++ b/hw/net/igb_core.c
54
@@ -XXX,XX +XXX,XX @@ igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt)
55
56
static void
57
igb_process_tx_desc(IGBCore *core,
58
+ PCIDevice *dev,
59
struct igb_tx *tx,
60
union e1000_adv_tx_desc *tx_desc,
61
int queue_index)
62
@@ -XXX,XX +XXX,XX @@ igb_process_tx_desc(IGBCore *core,
63
64
tx->first = true;
65
tx->skip_cp = false;
66
- net_tx_pkt_reset(tx->tx_pkt);
67
+ net_tx_pkt_reset(tx->tx_pkt, dev);
68
}
69
}
70
71
@@ -XXX,XX +XXX,XX @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
72
d = core->owner;
73
}
74
75
+ net_tx_pkt_reset(txr->tx->tx_pkt, d);
76
+
77
while (!igb_ring_empty(core, txi)) {
78
base = igb_ring_head_descr(core, txi);
79
80
@@ -XXX,XX +XXX,XX @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
81
trace_e1000e_tx_descr((void *)(intptr_t)desc.read.buffer_addr,
82
desc.read.cmd_type_len, desc.wb.status);
83
84
- igb_process_tx_desc(core, txr->tx, &desc, txi->idx);
85
+ igb_process_tx_desc(core, d, txr->tx, &desc, txi->idx);
86
igb_ring_advance(core, txi, 1);
87
eic |= igb_txdesc_writeback(core, base, &desc, txi);
88
}
89
@@ -XXX,XX +XXX,XX @@ igb_core_pci_realize(IGBCore *core,
90
core->vmstate = qemu_add_vm_change_state_handler(igb_vm_state_change, core);
91
92
for (i = 0; i < IGB_NUM_QUEUES; i++) {
93
- net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FRAGS);
94
+ net_tx_pkt_init(&core->tx[i].tx_pkt, NULL, E1000E_MAX_TX_FRAGS);
95
}
96
97
net_rx_pkt_init(&core->rx_pkt);
98
@@ -XXX,XX +XXX,XX @@ igb_core_pci_uninit(IGBCore *core)
99
qemu_del_vm_change_state_handler(core->vmstate);
100
101
for (i = 0; i < IGB_NUM_QUEUES; i++) {
102
- net_tx_pkt_reset(core->tx[i].tx_pkt);
103
+ net_tx_pkt_reset(core->tx[i].tx_pkt, NULL);
104
net_tx_pkt_uninit(core->tx[i].tx_pkt);
105
}
106
107
@@ -XXX,XX +XXX,XX @@ static void igb_reset(IGBCore *core, bool sw)
108
109
for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
110
tx = &core->tx[i];
111
- net_tx_pkt_reset(tx->tx_pkt);
112
+ net_tx_pkt_reset(tx->tx_pkt, NULL);
113
memset(tx->ctx, 0, sizeof(tx->ctx));
114
tx->first = true;
115
tx->skip_cp = false;
116
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/net/net_tx_pkt.c
119
+++ b/hw/net/net_tx_pkt.c
120
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_dump(struct NetTxPkt *pkt)
121
#endif
122
}
123
124
-void net_tx_pkt_reset(struct NetTxPkt *pkt)
125
+void net_tx_pkt_reset(struct NetTxPkt *pkt, PCIDevice *pci_dev)
126
{
127
int i;
128
129
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_reset(struct NetTxPkt *pkt)
130
pkt->raw[i].iov_len, DMA_DIRECTION_TO_DEVICE, 0);
131
}
132
}
133
+ pkt->pci_dev = pci_dev;
134
pkt->raw_frags = 0;
135
136
pkt->hdr_len = 0;
137
diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h
138
index XXXXXXX..XXXXXXX 100644
139
--- a/hw/net/net_tx_pkt.h
140
+++ b/hw/net/net_tx_pkt.h
141
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_dump(struct NetTxPkt *pkt);
142
* reset tx packet private context (needed to be called between packets)
143
*
144
* @pkt: packet
145
+ * @dev: PCI device processing the next packet
146
*
147
*/
148
-void net_tx_pkt_reset(struct NetTxPkt *pkt);
149
+void net_tx_pkt_reset(struct NetTxPkt *pkt, PCIDevice *dev);
150
151
/**
152
* Send packet to qemu. handles sw offloads if vhdr is not supported.
153
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
35
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
154
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/net/vmxnet3.c
37
--- a/hw/net/vmxnet3.c
156
+++ b/hw/net/vmxnet3.c
38
+++ b/hw/net/vmxnet3.c
157
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
39
@@ -XXX,XX +XXX,XX @@ vmxnet3_io_bar1_write(void *opaque,
158
vmxnet3_complete_packet(s, qidx, txd_idx);
40
case VMXNET3_REG_ICR:
159
s->tx_sop = true;
41
VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d",
160
s->skip_current_tx_pkt = false;
42
val, size);
161
- net_tx_pkt_reset(s->tx_pkt);
43
- g_assert_not_reached();
162
+ net_tx_pkt_reset(s->tx_pkt, PCI_DEVICE(s));
44
+ qemu_log_mask(LOG_GUEST_ERROR,
163
}
45
+ "%s: write to read-only register VMXNET3_REG_ICR\n",
164
}
46
+ TYPE_VMXNET3);
165
}
47
break;
166
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_deactivate_device(VMXNET3State *s)
48
167
{
49
/* Event Cause Register */
168
if (s->device_active) {
169
VMW_CBPRN("Deactivating vmxnet3...");
170
- net_tx_pkt_reset(s->tx_pkt);
171
+ net_tx_pkt_reset(s->tx_pkt, PCI_DEVICE(s));
172
net_tx_pkt_uninit(s->tx_pkt);
173
net_rx_pkt_uninit(s->rx_pkt);
174
s->device_active = false;
175
--
50
--
176
2.7.4
51
2.7.4
52
53
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Peter Foley <pefoley@google.com>
2
2
3
Also introduce:
3
Match the other error handling in this function.
4
- Checks for RXDCTL/TXDCTL queue enable bits
5
- IGB_NUM_VM_POOLS enum (Sec 1.5: Table 1-7)
6
4
7
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
5
Fixes: e7b347d0bf6 ("net: detect errors from probing vnet hdr flag for TAP devices")
6
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Peter Foley <pefoley@google.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
11
---
10
hw/net/igb_core.c | 38 +++++++++++++++++++++++++++++++-------
12
net/tap.c | 1 +
11
hw/net/igb_core.h | 1 +
13
1 file changed, 1 insertion(+)
12
hw/net/igb_regs.h | 3 +++
13
3 files changed, 35 insertions(+), 7 deletions(-)
14
14
15
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
15
diff --git a/net/tap.c b/net/tap.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/igb_core.c
17
--- a/net/tap.c
18
+++ b/hw/net/igb_core.c
18
+++ b/net/tap.c
19
@@ -XXX,XX +XXX,XX @@ igb_txdesc_writeback(IGBCore *core, dma_addr_t base,
19
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
20
return igb_tx_wb_eic(core, txi->idx);
20
if (i == 0) {
21
}
21
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
22
22
if (vnet_hdr < 0) {
23
+static inline bool
23
+ ret = -1;
24
+igb_tx_enabled(IGBCore *core, const E1000E_RingInfo *txi)
24
goto free_fail;
25
+{
26
+ bool vmdq = core->mac[MRQC] & 1;
27
+ uint16_t qn = txi->idx;
28
+ uint16_t pool = qn % IGB_NUM_VM_POOLS;
29
+
30
+ return (core->mac[TCTL] & E1000_TCTL_EN) &&
31
+ (!vmdq || core->mac[VFTE] & BIT(pool)) &&
32
+ (core->mac[TXDCTL0 + (qn * 16)] & E1000_TXDCTL_QUEUE_ENABLE);
33
+}
34
+
35
static void
36
igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
37
{
38
@@ -XXX,XX +XXX,XX @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
39
const E1000E_RingInfo *txi = txr->i;
40
uint32_t eic = 0;
41
42
- /* TODO: check if the queue itself is enabled too. */
43
- if (!(core->mac[TCTL] & E1000_TCTL_EN)) {
44
+ if (!igb_tx_enabled(core, txi)) {
45
trace_e1000e_tx_disabled();
46
return;
47
}
48
@@ -XXX,XX +XXX,XX @@ igb_can_receive(IGBCore *core)
49
50
for (i = 0; i < IGB_NUM_QUEUES; i++) {
51
E1000E_RxRing rxr;
52
+ if (!(core->mac[RXDCTL0 + (i * 16)] & E1000_RXDCTL_QUEUE_ENABLE)) {
53
+ continue;
54
+ }
55
56
igb_rx_ring_init(core, &rxr, i);
57
if (igb_ring_enabled(core, rxr.i) && igb_has_rxbufs(core, rxr.i, 1)) {
58
@@ -XXX,XX +XXX,XX @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
59
60
if (core->mac[MRQC] & 1) {
61
if (is_broadcast_ether_addr(ehdr->h_dest)) {
62
- for (i = 0; i < 8; i++) {
63
+ for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
64
if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) {
65
queues |= BIT(i);
66
}
25
}
67
@@ -XXX,XX +XXX,XX @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
26
} else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
68
f = ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
69
f = (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & 0xfff;
70
if (macp[f >> 5] & (1 << (f & 0x1f))) {
71
- for (i = 0; i < 8; i++) {
72
+ for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
73
if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) {
74
queues |= BIT(i);
75
}
76
@@ -XXX,XX +XXX,XX @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
77
}
78
}
79
} else {
80
- for (i = 0; i < 8; i++) {
81
+ for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
82
if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) {
83
mask |= BIT(i);
84
}
85
@@ -XXX,XX +XXX,XX @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
86
queues = BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT);
87
}
88
89
+ queues &= core->mac[VFRE];
90
igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, rss_info);
91
if (rss_info->queue & 1) {
92
queues <<= 8;
93
@@ -XXX,XX +XXX,XX @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
94
e1000x_fcs_len(core->mac);
95
96
for (i = 0; i < IGB_NUM_QUEUES; i++) {
97
- if (!(queues & BIT(i))) {
98
+ if (!(queues & BIT(i)) ||
99
+ !(core->mac[RXDCTL0 + (i * 16)] & E1000_RXDCTL_QUEUE_ENABLE)) {
100
continue;
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val)
104
105
static void igb_vf_reset(IGBCore *core, uint16_t vfn)
106
{
107
+ uint16_t qn0 = vfn;
108
+ uint16_t qn1 = vfn + IGB_NUM_VM_POOLS;
109
+
110
/* disable Rx and Tx for the VF*/
111
- core->mac[VFTE] &= ~BIT(vfn);
112
+ core->mac[RXDCTL0 + (qn0 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE;
113
+ core->mac[RXDCTL0 + (qn1 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE;
114
+ core->mac[TXDCTL0 + (qn0 * 16)] &= ~E1000_TXDCTL_QUEUE_ENABLE;
115
+ core->mac[TXDCTL0 + (qn1 * 16)] &= ~E1000_TXDCTL_QUEUE_ENABLE;
116
core->mac[VFRE] &= ~BIT(vfn);
117
+ core->mac[VFTE] &= ~BIT(vfn);
118
/* indicate VF reset to PF */
119
core->mac[VFLRE] |= BIT(vfn);
120
/* VFLRE and mailbox use the same interrupt cause */
121
@@ -XXX,XX +XXX,XX @@ igb_phy_reg_init[] = {
122
static const uint32_t igb_mac_reg_init[] = {
123
[LEDCTL] = 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24),
124
[EEMNGCTL] = BIT(31),
125
+ [TXDCTL0] = E1000_TXDCTL_QUEUE_ENABLE,
126
[RXDCTL0] = E1000_RXDCTL_QUEUE_ENABLE | (1 << 16),
127
[RXDCTL1] = 1 << 16,
128
[RXDCTL2] = 1 << 16,
129
diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/net/igb_core.h
132
+++ b/hw/net/igb_core.h
133
@@ -XXX,XX +XXX,XX @@
134
#define IGB_MSIX_VEC_NUM (10)
135
#define IGBVF_MSIX_VEC_NUM (3)
136
#define IGB_NUM_QUEUES (16)
137
+#define IGB_NUM_VM_POOLS (8)
138
139
typedef struct IGBCore IGBCore;
140
141
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/net/igb_regs.h
144
+++ b/hw/net/igb_regs.h
145
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
146
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
147
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
148
149
+/* Additional Transmit Descriptor Control definitions */
150
+#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
151
+
152
/* Additional Receive Descriptor Control definitions */
153
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
154
155
--
27
--
156
2.7.4
28
2.7.4
29
30
diff view generated by jsdifflib
New patch
1
From: Peter Foley <pefoley@google.com>
1
2
3
e.g.
4
1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0 inside [0x7ffc516af9b8, 4)
5
1109 15:16:20.151659 ==588974==WARNING: MemorySanitizer: use-of-uninitialized-value
6
1109 15:16:20.312923 #0 0x5639b88acb21 in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c:183:9
7
1109 15:16:20.312952 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9
8
1109 15:16:20.312954 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19
9
1109 15:16:20.312956 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13
10
1109 15:16:20.312957 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9
11
1109 15:16:20.312958 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15
12
1109 15:16:20.312960 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11
13
1109 15:16:20.312961 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14
14
1109 15:16:20.312962 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9
15
1109 15:16:20.312964 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
16
1109 15:16:20.312965 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5
17
1109 15:16:20.312967 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5
18
1109 15:16:20.312968 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2)
19
1109 15:16:20.312969 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
20
1109 15:16:20.312970
21
1109 15:16:20.312975 Uninitialized value was stored to memory at
22
1109 15:16:20.313393 #0 0x5639b88acbee in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c
23
1109 15:16:20.313396 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9
24
1109 15:16:20.313398 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19
25
1109 15:16:20.313399 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13
26
1109 15:16:20.313400 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9
27
1109 15:16:20.313401 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15
28
1109 15:16:20.313403 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11
29
1109 15:16:20.313404 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14
30
1109 15:16:20.313405 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9
31
1109 15:16:20.313407 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
32
1109 15:16:20.313408 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5
33
1109 15:16:20.313409 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5
34
1109 15:16:20.313410 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2)
35
1109 15:16:20.313412 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
36
1109 15:16:20.313413
37
1109 15:16:20.313417 Uninitialized value was stored to memory at
38
1109 15:16:20.313791 #0 0x5639b88affbd in net_tap_fd_init third_party/qemu/net/tap.c:400:26
39
1109 15:16:20.313826 #1 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19
40
1109 15:16:20.313829 #2 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13
41
1109 15:16:20.313831 #3 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9
42
1109 15:16:20.313836 #4 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15
43
1109 15:16:20.313838 #5 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11
44
1109 15:16:20.313839 #6 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14
45
1109 15:16:20.313841 #7 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9
46
1109 15:16:20.313843 #8 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5
47
1109 15:16:20.313844 #9 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5
48
1109 15:16:20.313845 #10 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5
49
1109 15:16:20.313846 #11 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2)
50
1109 15:16:20.313847 #12 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120
51
1109 15:16:20.313849
52
1109 15:16:20.313851 Uninitialized value was created by an allocation of 'ifr' in the stack frame of function 'tap_probe_vnet_hdr'
53
1109 15:16:20.313855 #0 0x5639b88ac680 in tap_probe_vnet_hdr third_party/qemu/net/tap-linux.c:151
54
1109 15:16:20.313856
55
1109 15:16:20.313878 SUMMARY: MemorySanitizer: use-of-uninitialized-value third_party/qemu/net/tap-linux.c:183:9 in tap_probe_vnet_hdr_len
56
57
Fixes: dc69004c7d8 ("net: move tap_probe_vnet_hdr() to tap-linux.c")
58
Reviewed-by: Hao Wu <wuhaotsh@google.com>
59
Reviewed-by: Patrick Venture <venture@google.com>
60
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
61
Signed-off-by: Peter Foley <pefoley@google.com>
62
Signed-off-by: Jason Wang <jasowang@redhat.com>
63
---
64
net/tap-linux.c | 1 +
65
1 file changed, 1 insertion(+)
66
67
diff --git a/net/tap-linux.c b/net/tap-linux.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/net/tap-linux.c
70
+++ b/net/tap-linux.c
71
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
72
int tap_probe_vnet_hdr(int fd, Error **errp)
73
{
74
struct ifreq ifr;
75
+ memset(&ifr, 0, sizeof(ifr));
76
77
if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
78
/* TUNGETIFF is available since kernel v2.6.27 */
79
--
80
2.7.4
81
82
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
Please note that loopback counters for VM to VM traffic is not
3
COLO-compare use the glib function g_queue_find_custom to dump
4
implemented yet: VFGOTLBC, VFGPTLBC, VFGORLBC and VFGPRLBC.
4
another VM's networking packet to compare. But this function always
5
start find from the queue->head(here is the newest packet), It will
6
reduce the success rate of comparison. So this patch reversed
7
the order of the queues for performance.
5
8
6
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
9
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
10
Reported-by: leirao <lei.rao@intel.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
12
---
9
hw/net/igb_core.c | 26 ++++++++++++++++++++++----
13
net/colo-compare.c | 26 +++++++++++++-------------
10
1 file changed, 22 insertions(+), 4 deletions(-)
14
1 file changed, 13 insertions(+), 13 deletions(-)
11
15
12
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/igb_core.c
18
--- a/net/colo-compare.c
15
+++ b/hw/net/igb_core.c
19
+++ b/net/colo-compare.c
16
@@ -XXX,XX +XXX,XX @@ igb_tx_pkt_send(IGBCore *core, struct igb_tx *tx, int queue_index)
20
@@ -XXX,XX +XXX,XX @@ static void colo_compare_inconsistency_notify(CompareState *s)
21
/* Use restricted to colo_insert_packet() */
22
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
23
{
24
- return a->tcp_seq - b->tcp_seq;
25
+ return b->tcp_seq - a->tcp_seq;
17
}
26
}
18
27
19
static void
28
static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
20
-igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt)
29
@@ -XXX,XX +XXX,XX @@ pri:
21
+igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt, int qn)
30
if (g_queue_is_empty(&conn->primary_list)) {
22
{
31
return;
23
static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511,
32
}
24
PTC1023, PTC1522 };
33
- ppkt = g_queue_pop_head(&conn->primary_list);
25
@@ -XXX,XX +XXX,XX @@ igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt)
34
+ ppkt = g_queue_pop_tail(&conn->primary_list);
26
core->mac[GPTC] = core->mac[TPT];
35
sec:
27
core->mac[GOTCL] = core->mac[TOTL];
36
if (g_queue_is_empty(&conn->secondary_list)) {
28
core->mac[GOTCH] = core->mac[TOTH];
37
- g_queue_push_head(&conn->primary_list, ppkt);
29
+
38
+ g_queue_push_tail(&conn->primary_list, ppkt);
30
+ if (core->mac[MRQC] & 1) {
39
return;
31
+ uint16_t pool = qn % IGB_NUM_VM_POOLS;
40
}
32
+
41
- spkt = g_queue_pop_head(&conn->secondary_list);
33
+ core->mac[PVFGOTC0 + (pool * 64)] += tot_len;
42
+ spkt = g_queue_pop_tail(&conn->secondary_list);
34
+ core->mac[PVFGPTC0 + (pool * 64)]++;
43
35
+ }
44
if (ppkt->tcp_seq == ppkt->seq_end) {
36
}
45
colo_release_primary_pkt(s, ppkt);
37
46
@@ -XXX,XX +XXX,XX @@ sec:
38
static void
39
@@ -XXX,XX +XXX,XX @@ igb_process_tx_desc(IGBCore *core,
40
net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, vlan, vet);
41
}
42
if (igb_tx_pkt_send(core, tx, queue_index)) {
43
- igb_on_tx_done_update_stats(core, tx->tx_pkt);
44
+ igb_on_tx_done_update_stats(core, tx->tx_pkt, queue_index);
45
}
47
}
46
}
48
}
47
49
if (!ppkt) {
48
@@ -XXX,XX +XXX,XX @@ igb_write_to_rx_buffers(IGBCore *core,
50
- g_queue_push_head(&conn->secondary_list, spkt);
51
+ g_queue_push_tail(&conn->secondary_list, spkt);
52
goto pri;
53
}
54
}
55
@@ -XXX,XX +XXX,XX @@ sec:
56
if (mark == COLO_COMPARE_FREE_PRIMARY) {
57
conn->compare_seq = ppkt->seq_end;
58
colo_release_primary_pkt(s, ppkt);
59
- g_queue_push_head(&conn->secondary_list, spkt);
60
+ g_queue_push_tail(&conn->secondary_list, spkt);
61
goto pri;
62
} else if (mark == COLO_COMPARE_FREE_SECONDARY) {
63
conn->compare_seq = spkt->seq_end;
64
@@ -XXX,XX +XXX,XX @@ sec:
65
goto pri;
66
}
67
} else {
68
- g_queue_push_head(&conn->primary_list, ppkt);
69
- g_queue_push_head(&conn->secondary_list, spkt);
70
+ g_queue_push_tail(&conn->primary_list, ppkt);
71
+ g_queue_push_tail(&conn->secondary_list, spkt);
72
73
#ifdef DEBUG_COLO_PACKETS
74
qemu_hexdump(stderr, "colo-compare ppkt", ppkt->data, ppkt->size);
75
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
76
77
while (!g_queue_is_empty(&conn->primary_list) &&
78
!g_queue_is_empty(&conn->secondary_list)) {
79
- pkt = g_queue_pop_head(&conn->primary_list);
80
+ pkt = g_queue_pop_tail(&conn->primary_list);
81
result = g_queue_find_custom(&conn->secondary_list,
82
pkt, (GCompareFunc)HandlePacket);
83
84
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
85
* timeout, it will trigger a checkpoint request.
86
*/
87
trace_colo_compare_main("packet different");
88
- g_queue_push_head(&conn->primary_list, pkt);
89
+ g_queue_push_tail(&conn->primary_list, pkt);
90
91
colo_compare_inconsistency_notify(s);
92
break;
93
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
94
entry->buf = g_malloc(size);
95
memcpy(entry->buf, buf, size);
96
}
97
- g_queue_push_head(&sendco->send_list, entry);
98
+ g_queue_push_tail(&sendco->send_list, entry);
99
100
if (sendco->done) {
101
sendco->co = qemu_coroutine_create(_compare_chr_send, sendco);
102
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
103
Packet *pkt = NULL;
104
105
while (!g_queue_is_empty(&conn->primary_list)) {
106
- pkt = g_queue_pop_head(&conn->primary_list);
107
+ pkt = g_queue_pop_tail(&conn->primary_list);
108
compare_chr_send(s,
109
pkt->data,
110
pkt->size,
111
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
112
packet_destroy_partial(pkt, NULL);
113
}
114
while (!g_queue_is_empty(&conn->secondary_list)) {
115
- pkt = g_queue_pop_head(&conn->secondary_list);
116
+ pkt = g_queue_pop_tail(&conn->secondary_list);
117
packet_destroy(pkt, NULL);
118
}
49
}
119
}
50
51
static void
52
-igb_update_rx_stats(IGBCore *core, size_t data_size, size_t data_fcs_size)
53
+igb_update_rx_stats(IGBCore *core, const E1000E_RingInfo *rxi,
54
+ size_t data_size, size_t data_fcs_size)
55
{
56
e1000x_update_rx_total_stats(core->mac, data_size, data_fcs_size);
57
58
@@ -XXX,XX +XXX,XX @@ igb_update_rx_stats(IGBCore *core, size_t data_size, size_t data_fcs_size)
59
default:
60
break;
61
}
62
+
63
+ if (core->mac[MRQC] & 1) {
64
+ uint16_t pool = rxi->idx % IGB_NUM_VM_POOLS;
65
+
66
+ core->mac[PVFGORC0 + (pool * 64)] += data_size + 4;
67
+ core->mac[PVFGPRC0 + (pool * 64)]++;
68
+ if (net_rx_pkt_get_packet_type(core->rx_pkt) == ETH_PKT_MCAST) {
69
+ core->mac[PVFMPRC0 + (pool * 64)]++;
70
+ }
71
+ }
72
}
73
74
static inline bool
75
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
76
77
} while (desc_offset < total_size);
78
79
- igb_update_rx_stats(core, size, total_size);
80
+ igb_update_rx_stats(core, rxi, size, total_size);
81
}
82
83
static inline void
84
--
120
--
85
2.7.4
121
2.7.4
122
123
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
The current implementation of igb uses only part of a advanced Tx
3
Make the comments consistent with the REGULAR_PACKET_CHECK_MS.
4
context descriptor and first data descriptor because it misses some
5
features and sniffs the trait of the packet instead of respecting the
6
packet type specified in the descriptor. However, we will certainly
7
need the entire Tx context descriptor when we update igb to respect
8
these ignored fields. Save the entire context descriptor and first
9
data descriptor except the buffer address to prepare for such a change.
10
4
11
This also introduces the distinction of contexts with different
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
12
indexes, which was not present in e1000e but in igb.
13
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
Reviewed-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
7
---
18
hw/net/igb.c | 26 +++++++++++++++++++-------
8
net/colo-compare.c | 2 +-
19
hw/net/igb_core.c | 39 +++++++++++++++++++--------------------
9
1 file changed, 1 insertion(+), 1 deletion(-)
20
hw/net/igb_core.h | 8 +++-----
21
3 files changed, 41 insertions(+), 32 deletions(-)
22
10
23
diff --git a/hw/net/igb.c b/hw/net/igb.c
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
24
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/net/igb.c
13
--- a/net/colo-compare.c
26
+++ b/hw/net/igb.c
14
+++ b/net/colo-compare.c
27
@@ -XXX,XX +XXX,XX @@ static int igb_post_load(void *opaque, int version_id)
15
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
28
return igb_core_post_load(&s->core);
29
}
30
31
-static const VMStateDescription igb_vmstate_tx = {
32
- .name = "igb-tx",
33
+static const VMStateDescription igb_vmstate_tx_ctx = {
34
+ .name = "igb-tx-ctx",
35
.version_id = 1,
36
.minimum_version_id = 1,
37
.fields = (VMStateField[]) {
38
- VMSTATE_UINT16(vlan, struct igb_tx),
39
- VMSTATE_UINT16(mss, struct igb_tx),
40
- VMSTATE_BOOL(tse, struct igb_tx),
41
- VMSTATE_BOOL(ixsm, struct igb_tx),
42
- VMSTATE_BOOL(txsm, struct igb_tx),
43
+ VMSTATE_UINT32(vlan_macip_lens, struct e1000_adv_tx_context_desc),
44
+ VMSTATE_UINT32(seqnum_seed, struct e1000_adv_tx_context_desc),
45
+ VMSTATE_UINT32(type_tucmd_mlhl, struct e1000_adv_tx_context_desc),
46
+ VMSTATE_UINT32(mss_l4len_idx, struct e1000_adv_tx_context_desc),
47
+ VMSTATE_END_OF_LIST()
48
+ }
49
+};
50
+
51
+static const VMStateDescription igb_vmstate_tx = {
52
+ .name = "igb-tx",
53
+ .version_id = 2,
54
+ .minimum_version_id = 2,
55
+ .fields = (VMStateField[]) {
56
+ VMSTATE_STRUCT_ARRAY(ctx, struct igb_tx, 2, 0, igb_vmstate_tx_ctx,
57
+ struct e1000_adv_tx_context_desc),
58
+ VMSTATE_UINT32(first_cmd_type_len, struct igb_tx),
59
+ VMSTATE_UINT32(first_olinfo_status, struct igb_tx),
60
VMSTATE_BOOL(first, struct igb_tx),
61
VMSTATE_BOOL(skip_cp, struct igb_tx),
62
VMSTATE_END_OF_LIST()
63
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/net/igb_core.c
66
+++ b/hw/net/igb_core.c
67
@@ -XXX,XX +XXX,XX @@ igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, bool tx,
68
static bool
69
igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx)
70
{
71
- if (tx->tse) {
72
- if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->mss)) {
73
+ if (tx->first_cmd_type_len & E1000_ADVTXD_DCMD_TSE) {
74
+ uint32_t idx = (tx->first_olinfo_status >> 4) & 1;
75
+ uint32_t mss = tx->ctx[idx].mss_l4len_idx >> 16;
76
+ if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, mss)) {
77
return false;
78
}
79
80
@@ -XXX,XX +XXX,XX @@ igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx)
81
return true;
82
}
16
}
83
17
84
- if (tx->txsm) {
18
if (!s->expired_scan_cycle) {
85
+ if (tx->first_olinfo_status & E1000_ADVTXD_POTS_TXSM) {
19
- /* Set default value to 3000 MS */
86
if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) {
20
+ /* Set default value to 1000 MS */
87
return false;
21
s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
88
}
89
}
22
}
90
23
91
- if (tx->ixsm) {
92
+ if (tx->first_olinfo_status & E1000_ADVTXD_POTS_IXSM) {
93
net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt);
94
}
95
96
@@ -XXX,XX +XXX,XX @@ igb_process_tx_desc(IGBCore *core,
97
{
98
struct e1000_adv_tx_context_desc *tx_ctx_desc;
99
uint32_t cmd_type_len;
100
- uint32_t olinfo_status;
101
+ uint32_t idx;
102
uint64_t buffer_addr;
103
uint16_t length;
104
105
@@ -XXX,XX +XXX,XX @@ igb_process_tx_desc(IGBCore *core,
106
E1000_ADVTXD_DTYP_DATA) {
107
/* advanced transmit data descriptor */
108
if (tx->first) {
109
- olinfo_status = le32_to_cpu(tx_desc->read.olinfo_status);
110
-
111
- tx->tse = !!(cmd_type_len & E1000_ADVTXD_DCMD_TSE);
112
- tx->ixsm = !!(olinfo_status & E1000_ADVTXD_POTS_IXSM);
113
- tx->txsm = !!(olinfo_status & E1000_ADVTXD_POTS_TXSM);
114
-
115
+ tx->first_cmd_type_len = cmd_type_len;
116
+ tx->first_olinfo_status = le32_to_cpu(tx_desc->read.olinfo_status);
117
tx->first = false;
118
}
119
} else if ((cmd_type_len & E1000_ADVTXD_DTYP_CTXT) ==
120
E1000_ADVTXD_DTYP_CTXT) {
121
/* advanced transmit context descriptor */
122
tx_ctx_desc = (struct e1000_adv_tx_context_desc *)tx_desc;
123
- tx->vlan = le32_to_cpu(tx_ctx_desc->vlan_macip_lens) >> 16;
124
- tx->mss = le32_to_cpu(tx_ctx_desc->mss_l4len_idx) >> 16;
125
+ idx = (le32_to_cpu(tx_ctx_desc->mss_l4len_idx) >> 4) & 1;
126
+ tx->ctx[idx].vlan_macip_lens = le32_to_cpu(tx_ctx_desc->vlan_macip_lens);
127
+ tx->ctx[idx].seqnum_seed = le32_to_cpu(tx_ctx_desc->seqnum_seed);
128
+ tx->ctx[idx].type_tucmd_mlhl = le32_to_cpu(tx_ctx_desc->type_tucmd_mlhl);
129
+ tx->ctx[idx].mss_l4len_idx = le32_to_cpu(tx_ctx_desc->mss_l4len_idx);
130
return;
131
} else {
132
/* unknown descriptor type */
133
@@ -XXX,XX +XXX,XX @@ igb_process_tx_desc(IGBCore *core,
134
if (cmd_type_len & E1000_TXD_CMD_EOP) {
135
if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) {
136
if (cmd_type_len & E1000_TXD_CMD_VLE) {
137
- net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, tx->vlan,
138
- core->mac[VET] & 0xffff);
139
+ idx = (tx->first_olinfo_status >> 4) & 1;
140
+ uint16_t vlan = tx->ctx[idx].vlan_macip_lens >> 16;
141
+ uint16_t vet = core->mac[VET] & 0xffff;
142
+ net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, vlan, vet);
143
}
144
if (igb_tx_pkt_send(core, tx, queue_index)) {
145
igb_on_tx_done_update_stats(core, tx->tx_pkt);
146
@@ -XXX,XX +XXX,XX @@ static void igb_reset(IGBCore *core, bool sw)
147
for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
148
tx = &core->tx[i];
149
net_tx_pkt_reset(tx->tx_pkt);
150
- tx->vlan = 0;
151
- tx->mss = 0;
152
- tx->tse = false;
153
- tx->ixsm = false;
154
- tx->txsm = false;
155
+ memset(tx->ctx, 0, sizeof(tx->ctx));
156
tx->first = true;
157
tx->skip_cp = false;
158
}
159
diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/net/igb_core.h
162
+++ b/hw/net/igb_core.h
163
@@ -XXX,XX +XXX,XX @@ struct IGBCore {
164
QEMUTimer *autoneg_timer;
165
166
struct igb_tx {
167
- uint16_t vlan; /* VLAN Tag */
168
- uint16_t mss; /* Maximum Segment Size */
169
- bool tse; /* TCP/UDP Segmentation Enable */
170
- bool ixsm; /* Insert IP Checksum */
171
- bool txsm; /* Insert TCP/UDP Checksum */
172
+ struct e1000_adv_tx_context_desc ctx[2];
173
+ uint32_t first_cmd_type_len;
174
+ uint32_t first_olinfo_status;
175
176
bool first;
177
bool skip_cp;
178
--
24
--
179
2.7.4
25
2.7.4
26
27
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Rao Lei <lei.rao@intel.com>
2
2
3
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
3
This patch is to improve the logic of QEMU main thread sleep code in
4
qemu_chr_write_buffer() where it can be blocked and can't run other
5
coroutines during COLO IO stress test.
6
7
Our approach is to put filter_send() in a coroutine. In this way,
8
filter_send() will call qemu_coroutine_yield() in qemu_co_sleep_ns(),
9
so that it can be scheduled out and QEMU main thread has opportunity to
10
run other tasks.
11
12
Signed-off-by: Lei Rao <lei.rao@intel.com>
13
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
14
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
15
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
17
---
6
hw/net/igb_core.c | 41 ++++++++++++++++++++++++++++++++++++-----
18
net/filter-mirror.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
7
1 file changed, 36 insertions(+), 5 deletions(-)
19
1 file changed, 53 insertions(+), 13 deletions(-)
8
20
9
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
21
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
10
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/net/igb_core.c
23
--- a/net/filter-mirror.c
12
+++ b/hw/net/igb_core.c
24
+++ b/net/filter-mirror.c
13
@@ -XXX,XX +XXX,XX @@ igb_rx_l4_cso_enabled(IGBCore *core)
25
@@ -XXX,XX +XXX,XX @@
14
return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD);
26
#include "chardev/char-fe.h"
27
#include "qemu/iov.h"
28
#include "qemu/sockets.h"
29
+#include "block/aio-wait.h"
30
31
#define TYPE_FILTER_MIRROR "filter-mirror"
32
typedef struct MirrorState MirrorState;
33
@@ -XXX,XX +XXX,XX @@ struct MirrorState {
34
bool vnet_hdr;
35
};
36
37
-static int filter_send(MirrorState *s,
38
- const struct iovec *iov,
39
- int iovcnt)
40
+typedef struct FilterSendCo {
41
+ MirrorState *s;
42
+ char *buf;
43
+ ssize_t size;
44
+ bool done;
45
+ int ret;
46
+} FilterSendCo;
47
+
48
+static int _filter_send(MirrorState *s,
49
+ char *buf,
50
+ ssize_t size)
51
{
52
NetFilterState *nf = NETFILTER(s);
53
int ret = 0;
54
- ssize_t size = 0;
55
uint32_t len = 0;
56
- char *buf;
57
-
58
- size = iov_size(iov, iovcnt);
59
- if (!size) {
60
- return 0;
61
- }
62
63
len = htonl(size);
64
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
65
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
66
}
67
}
68
69
- buf = g_malloc(size);
70
- iov_to_buf(iov, iovcnt, 0, buf, size);
71
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
72
- g_free(buf);
73
if (ret != size) {
74
goto err;
75
}
76
@@ -XXX,XX +XXX,XX @@ err:
77
return ret < 0 ? ret : -EIO;
15
}
78
}
16
79
17
+static bool
80
+static void coroutine_fn filter_send_co(void *opaque)
18
+igb_rx_is_oversized(IGBCore *core, uint16_t qn, size_t size)
19
+{
81
+{
20
+ uint16_t pool = qn % IGB_NUM_VM_POOLS;
82
+ FilterSendCo *data = opaque;
21
+ bool lpe = !!(core->mac[VMOLR0 + pool] & E1000_VMOLR_LPE);
22
+ int max_ethernet_lpe_size =
23
+ core->mac[VMOLR0 + pool] & E1000_VMOLR_RLPML_MASK;
24
+ int max_ethernet_vlan_size = 1522;
25
+
83
+
26
+ return size > (lpe ? max_ethernet_lpe_size : max_ethernet_vlan_size);
84
+ data->ret = _filter_send(data->s, data->buf, data->size);
85
+ data->done = true;
86
+ g_free(data->buf);
87
+ aio_wait_kick();
27
+}
88
+}
28
+
89
+
29
static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
90
+static int filter_send(MirrorState *s,
30
- E1000E_RSSInfo *rss_info, bool *external_tx)
91
+ const struct iovec *iov,
31
+ size_t size, E1000E_RSSInfo *rss_info,
92
+ int iovcnt)
32
+ bool *external_tx)
93
+{
33
{
94
+ ssize_t size = iov_size(iov, iovcnt);
34
static const int ta_shift[] = { 4, 3, 2, 0 };
95
+ char *buf = NULL;
35
uint32_t f, ra[2], *macp, rctl = core->mac[RCTL];
36
uint16_t queues = 0;
37
+ uint16_t oversized = 0;
38
uint16_t vid = lduw_be_p(&PKT_GET_VLAN_HDR(ehdr)->h_tci) & VLAN_VID_MASK;
39
bool accepted = false;
40
int i;
41
@@ -XXX,XX +XXX,XX @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
42
}
43
44
queues &= core->mac[VFRE];
45
- igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, rss_info);
46
- if (rss_info->queue & 1) {
47
- queues <<= 8;
48
+ if (queues) {
49
+ for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
50
+ if ((queues & BIT(i)) && igb_rx_is_oversized(core, i, size)) {
51
+ oversized |= BIT(i);
52
+ }
53
+ }
54
+ /* 8.19.37 increment ROC if packet is oversized for all queues */
55
+ if (oversized == queues) {
56
+ trace_e1000x_rx_oversized(size);
57
+ e1000x_inc_reg_if_not_full(core->mac, ROC);
58
+ }
59
+ queues &= ~oversized;
60
+ }
61
+
96
+
62
+ if (queues) {
97
+ if (!size) {
63
+ igb_rss_parse_packet(core, core->rx_pkt,
98
+ return 0;
64
+ external_tx != NULL, rss_info);
99
+ }
65
+ if (rss_info->queue & 1) {
100
+
66
+ queues <<= 8;
101
+ buf = g_malloc(size);
67
+ }
102
+ iov_to_buf(iov, iovcnt, 0, buf, size);
68
}
103
+
69
} else {
104
+ FilterSendCo data = {
70
switch (net_rx_pkt_get_packet_type(core->rx_pkt)) {
105
+ .s = s,
71
@@ -XXX,XX +XXX,XX @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
106
+ .size = size,
72
e1000x_vlan_enabled(core->mac),
107
+ .buf = buf,
73
core->mac[VET] & 0xffff);
108
+ .ret = 0,
74
109
+ };
75
- queues = igb_receive_assign(core, ehdr, &rss_info, external_tx);
110
+
76
+ queues = igb_receive_assign(core, ehdr, size, &rss_info, external_tx);
111
+ Coroutine *co = qemu_coroutine_create(filter_send_co, &data);
77
if (!queues) {
112
+ qemu_coroutine_enter(co);
78
trace_e1000e_rx_flt_dropped();
113
+
79
return orig_size;
114
+ while (!data.done) {
115
+ aio_poll(qemu_get_aio_context(), true);
116
+ }
117
+
118
+ return data.ret;
119
+}
120
+
121
static void redirector_to_filter(NetFilterState *nf,
122
const uint8_t *buf,
123
int len)
80
--
124
--
81
2.7.4
125
2.7.4
126
127
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
RSS for VFs is only enabled if VMOLR[n].RSSE is set.
3
vmnet.framework dependency is added with 'vmnet' option
4
to enable or disable it. Default value is 'auto'.
4
5
5
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
6
vmnet features to be used are available since macOS 11.0,
7
corresponding probe is created into meson.build.
8
9
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
11
---
8
hw/net/igb_core.c | 9 ++++++++-
12
meson.build | 16 +++++++++++++++-
9
1 file changed, 8 insertions(+), 1 deletion(-)
13
meson_options.txt | 2 ++
14
scripts/meson-buildoptions.sh | 3 +++
15
3 files changed, 20 insertions(+), 1 deletion(-)
10
16
11
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
17
diff --git a/meson.build b/meson.build
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/net/igb_core.c
19
--- a/meson.build
14
+++ b/hw/net/igb_core.c
20
+++ b/meson.build
15
@@ -XXX,XX +XXX,XX @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
21
@@ -XXX,XX +XXX,XX @@ if cocoa.found() and get_option('gtk').enabled()
16
if (queues) {
22
error('Cocoa and GTK+ cannot be enabled at the same time')
17
igb_rss_parse_packet(core, core->rx_pkt,
23
endif
18
external_tx != NULL, rss_info);
24
19
+ /* Sec 8.26.1: PQn = VFn + VQn*8 */
25
+vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
20
if (rss_info->queue & 1) {
26
+if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
21
- queues <<= 8;
27
+ 'VMNET_BRIDGED_MODE',
22
+ for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
28
+ dependencies: vmnet)
23
+ if ((queues & BIT(i)) &&
29
+ vmnet = not_found
24
+ (core->mac[VMOLR0 + i] & E1000_VMOLR_RSSE)) {
30
+ if get_option('vmnet').enabled()
25
+ queues |= BIT(i + IGB_NUM_VM_POOLS);
31
+ error('vmnet.framework API is outdated')
26
+ queues &= ~BIT(i);
32
+ else
27
+ }
33
+ warning('vmnet.framework API is outdated, disabling')
28
+ }
34
+ endif
29
}
35
+endif
30
}
36
+
31
} else {
37
seccomp = not_found
38
if not get_option('seccomp').auto() or have_system or have_tools
39
seccomp = dependency('libseccomp', version: '>=2.3.0',
40
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_SECCOMP', seccomp.found())
41
config_host_data.set('CONFIG_SNAPPY', snappy.found())
42
config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
43
config_host_data.set('CONFIG_VDE', vde.found())
44
+config_host_data.set('CONFIG_VMNET', vmnet.found())
45
config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
46
config_host_data.set('CONFIG_VNC', vnc.found())
47
config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
48
@@ -XXX,XX +XXX,XX @@ summary(summary_info, bool_yn: true, section: 'Crypto')
49
# Libraries
50
summary_info = {}
51
if targetos == 'darwin'
52
- summary_info += {'Cocoa support': cocoa}
53
+ summary_info += {'Cocoa support': cocoa}
54
+ summary_info += {'vmnet.framework support': vmnet}
55
endif
56
summary_info += {'SDL support': sdl}
57
summary_info += {'SDL image support': sdl_image}
58
diff --git a/meson_options.txt b/meson_options.txt
59
index XXXXXXX..XXXXXXX 100644
60
--- a/meson_options.txt
61
+++ b/meson_options.txt
62
@@ -XXX,XX +XXX,XX @@ option('netmap', type : 'feature', value : 'auto',
63
description: 'netmap network backend support')
64
option('vde', type : 'feature', value : 'auto',
65
description: 'vde network backend support')
66
+option('vmnet', type : 'feature', value : 'auto',
67
+ description: 'vmnet.framework network backend support')
68
option('virglrenderer', type : 'feature', value : 'auto',
69
description: 'virgl rendering support')
70
option('vnc', type : 'feature', value : 'auto',
71
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
72
index XXXXXXX..XXXXXXX 100644
73
--- a/scripts/meson-buildoptions.sh
74
+++ b/scripts/meson-buildoptions.sh
75
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
76
printf "%s\n" ' u2f U2F emulation support'
77
printf "%s\n" ' usb-redir libusbredir support'
78
printf "%s\n" ' vde vde network backend support'
79
+ printf "%s\n" ' vmnet vmnet.framework network backend support'
80
printf "%s\n" ' vhost-user-blk-server'
81
printf "%s\n" ' build vhost-user-blk server'
82
printf "%s\n" ' virglrenderer virgl rendering support'
83
@@ -XXX,XX +XXX,XX @@ _meson_option_parse() {
84
--disable-usb-redir) printf "%s" -Dusb_redir=disabled ;;
85
--enable-vde) printf "%s" -Dvde=enabled ;;
86
--disable-vde) printf "%s" -Dvde=disabled ;;
87
+ --enable-vmnet) printf "%s" -Dvmnet=enabled ;;
88
+ --disable-vmnet) printf "%s" -Dvmnet=disabled ;;
89
--enable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=enabled ;;
90
--disable-vhost-user-blk-server) printf "%s" -Dvhost_user_blk_server=disabled ;;
91
--enable-virglrenderer) printf "%s" -Dvirglrenderer=enabled ;;
32
--
92
--
33
2.7.4
93
2.7.4
94
95
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
IGB uses RXDW ICR bit to indicate that rx descriptor has been written
3
Create separate netdevs for each vmnet operating mode:
4
back. This is the same as RXT0 bit in older HW.
4
- vmnet-host
5
- vmnet-shared
6
- vmnet-bridged
5
7
6
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
8
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
hw/net/e1000x_regs.h | 4 ++++
11
net/clients.h | 11 +++++
10
hw/net/igb_core.c | 2 +-
12
net/meson.build | 7 +++
11
2 files changed, 5 insertions(+), 1 deletion(-)
13
net/net.c | 10 ++++
14
net/vmnet-bridged.m | 25 ++++++++++
15
net/vmnet-common.m | 19 ++++++++
16
net/vmnet-host.c | 24 ++++++++++
17
net/vmnet-shared.c | 25 ++++++++++
18
net/vmnet_int.h | 25 ++++++++++
19
qapi/net.json | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++-
20
9 files changed, 277 insertions(+), 2 deletions(-)
21
create mode 100644 net/vmnet-bridged.m
22
create mode 100644 net/vmnet-common.m
23
create mode 100644 net/vmnet-host.c
24
create mode 100644 net/vmnet-shared.c
25
create mode 100644 net/vmnet_int.h
12
26
13
diff --git a/hw/net/e1000x_regs.h b/hw/net/e1000x_regs.h
27
diff --git a/net/clients.h b/net/clients.h
14
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/e1000x_regs.h
29
--- a/net/clients.h
16
+++ b/hw/net/e1000x_regs.h
30
+++ b/net/clients.h
17
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
18
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
32
19
#define E1000_ICR_RXO 0x00000040 /* rx overrun */
33
int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
20
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
34
NetClientState *peer, Error **errp);
21
+#define E1000_ICR_RXDW 0x00000080 /* rx desc written back */
35
+#ifdef CONFIG_VMNET
22
#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
36
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
23
#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
37
+ NetClientState *peer, Error **errp);
24
#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
38
+
25
@@ -XXX,XX +XXX,XX @@
39
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
26
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
40
+ NetClientState *peer, Error **errp);
27
#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
41
+
28
#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
42
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
29
+#define E1000_ICS_RXDW E1000_ICR_RXDW /* rx desc written back */
43
+ NetClientState *peer, Error **errp);
30
#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
44
+#endif /* CONFIG_VMNET */
31
#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
45
+
32
#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
46
#endif /* QEMU_NET_CLIENTS_H */
33
@@ -XXX,XX +XXX,XX @@
47
diff --git a/net/meson.build b/net/meson.build
34
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
35
#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
36
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
37
+#define E1000_IMS_RXDW E1000_ICR_RXDW /* rx desc written back */
38
#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
39
#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
40
#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
41
@@ -XXX,XX +XXX,XX @@
42
#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
43
#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
44
#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
45
+#define E1000_IMC_RXDW E1000_ICR_RXDW /* rx desc written back */
46
#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
47
#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
48
#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
49
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
50
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/net/igb_core.c
49
--- a/net/meson.build
52
+++ b/hw/net/igb_core.c
50
+++ b/net/meson.build
53
@@ -XXX,XX +XXX,XX @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
51
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files(tap_posix))
54
continue;
52
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('tap-win32.c'))
55
}
53
softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
56
54
57
- n |= E1000_ICR_RXT0;
55
+vmnet_files = files(
58
+ n |= E1000_ICR_RXDW;
56
+ 'vmnet-common.m',
59
57
+ 'vmnet-bridged.m',
60
igb_rx_fix_l4_csum(core, core->rx_pkt);
58
+ 'vmnet-host.c',
61
igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info);
59
+ 'vmnet-shared.c'
60
+)
61
+softmmu_ss.add(when: vmnet, if_true: vmnet_files)
62
subdir('can')
63
diff --git a/net/net.c b/net/net.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/net/net.c
66
+++ b/net/net.c
67
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
68
#ifdef CONFIG_L2TPV3
69
[NET_CLIENT_DRIVER_L2TPV3] = net_init_l2tpv3,
70
#endif
71
+#ifdef CONFIG_VMNET
72
+ [NET_CLIENT_DRIVER_VMNET_HOST] = net_init_vmnet_host,
73
+ [NET_CLIENT_DRIVER_VMNET_SHARED] = net_init_vmnet_shared,
74
+ [NET_CLIENT_DRIVER_VMNET_BRIDGED] = net_init_vmnet_bridged,
75
+#endif /* CONFIG_VMNET */
76
};
77
78
79
@@ -XXX,XX +XXX,XX @@ void show_netdevs(void)
80
#ifdef CONFIG_VHOST_VDPA
81
"vhost-vdpa",
82
#endif
83
+#ifdef CONFIG_VMNET
84
+ "vmnet-host",
85
+ "vmnet-shared",
86
+ "vmnet-bridged",
87
+#endif
88
};
89
90
qemu_printf("Available netdev backend types:\n");
91
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
92
new file mode 100644
93
index XXXXXXX..XXXXXXX
94
--- /dev/null
95
+++ b/net/vmnet-bridged.m
96
@@ -XXX,XX +XXX,XX @@
97
+/*
98
+ * vmnet-bridged.m
99
+ *
100
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
101
+ *
102
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
103
+ * See the COPYING file in the top-level directory.
104
+ *
105
+ */
106
+
107
+#include "qemu/osdep.h"
108
+#include "qapi/qapi-types-net.h"
109
+#include "vmnet_int.h"
110
+#include "clients.h"
111
+#include "qemu/error-report.h"
112
+#include "qapi/error.h"
113
+
114
+#include <vmnet/vmnet.h>
115
+
116
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
117
+ NetClientState *peer, Error **errp)
118
+{
119
+ error_setg(errp, "vmnet-bridged is not implemented yet");
120
+ return -1;
121
+}
122
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
123
new file mode 100644
124
index XXXXXXX..XXXXXXX
125
--- /dev/null
126
+++ b/net/vmnet-common.m
127
@@ -XXX,XX +XXX,XX @@
128
+/*
129
+ * vmnet-common.m - network client wrapper for Apple vmnet.framework
130
+ *
131
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
132
+ * Copyright(c) 2021 Phillip Tennen <phillip@axleos.com>
133
+ *
134
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
135
+ * See the COPYING file in the top-level directory.
136
+ *
137
+ */
138
+
139
+#include "qemu/osdep.h"
140
+#include "qapi/qapi-types-net.h"
141
+#include "vmnet_int.h"
142
+#include "clients.h"
143
+#include "qemu/error-report.h"
144
+#include "qapi/error.h"
145
+
146
+#include <vmnet/vmnet.h>
147
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
148
new file mode 100644
149
index XXXXXXX..XXXXXXX
150
--- /dev/null
151
+++ b/net/vmnet-host.c
152
@@ -XXX,XX +XXX,XX @@
153
+/*
154
+ * vmnet-host.c
155
+ *
156
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
157
+ *
158
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
159
+ * See the COPYING file in the top-level directory.
160
+ *
161
+ */
162
+
163
+#include "qemu/osdep.h"
164
+#include "qapi/qapi-types-net.h"
165
+#include "vmnet_int.h"
166
+#include "clients.h"
167
+#include "qemu/error-report.h"
168
+#include "qapi/error.h"
169
+
170
+#include <vmnet/vmnet.h>
171
+
172
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
173
+ NetClientState *peer, Error **errp) {
174
+ error_setg(errp, "vmnet-host is not implemented yet");
175
+ return -1;
176
+}
177
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
178
new file mode 100644
179
index XXXXXXX..XXXXXXX
180
--- /dev/null
181
+++ b/net/vmnet-shared.c
182
@@ -XXX,XX +XXX,XX @@
183
+/*
184
+ * vmnet-shared.c
185
+ *
186
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
187
+ *
188
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
189
+ * See the COPYING file in the top-level directory.
190
+ *
191
+ */
192
+
193
+#include "qemu/osdep.h"
194
+#include "qapi/qapi-types-net.h"
195
+#include "vmnet_int.h"
196
+#include "clients.h"
197
+#include "qemu/error-report.h"
198
+#include "qapi/error.h"
199
+
200
+#include <vmnet/vmnet.h>
201
+
202
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
203
+ NetClientState *peer, Error **errp)
204
+{
205
+ error_setg(errp, "vmnet-shared is not implemented yet");
206
+ return -1;
207
+}
208
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
209
new file mode 100644
210
index XXXXXXX..XXXXXXX
211
--- /dev/null
212
+++ b/net/vmnet_int.h
213
@@ -XXX,XX +XXX,XX @@
214
+/*
215
+ * vmnet_int.h
216
+ *
217
+ * Copyright(c) 2021 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
218
+ *
219
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
220
+ * See the COPYING file in the top-level directory.
221
+ *
222
+ */
223
+#ifndef VMNET_INT_H
224
+#define VMNET_INT_H
225
+
226
+#include "qemu/osdep.h"
227
+#include "vmnet_int.h"
228
+#include "clients.h"
229
+
230
+#include <vmnet/vmnet.h>
231
+
232
+typedef struct VmnetCommonState {
233
+ NetClientState nc;
234
+
235
+} VmnetCommonState;
236
+
237
+
238
+#endif /* VMNET_INT_H */
239
diff --git a/qapi/net.json b/qapi/net.json
240
index XXXXXXX..XXXXXXX 100644
241
--- a/qapi/net.json
242
+++ b/qapi/net.json
243
@@ -XXX,XX +XXX,XX @@
244
'*queues': 'int' } }
245
246
##
247
+# @NetdevVmnetHostOptions:
248
+#
249
+# vmnet (host mode) network backend.
250
+#
251
+# Allows the vmnet interface to communicate with other vmnet
252
+# interfaces that are in host mode and also with the host.
253
+#
254
+# @start-address: The starting IPv4 address to use for the interface.
255
+# Must be in the private IP range (RFC 1918). Must be
256
+# specified along with @end-address and @subnet-mask.
257
+# This address is used as the gateway address. The
258
+# subsequent address up to and including end-address are
259
+# placed in the DHCP pool.
260
+#
261
+# @end-address: The DHCP IPv4 range end address to use for the
262
+# interface. Must be in the private IP range (RFC 1918).
263
+# Must be specified along with @start-address and
264
+# @subnet-mask.
265
+#
266
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
267
+# be specified along with @start-address and @subnet-mask.
268
+#
269
+# @isolated: Enable isolation for this interface. Interface isolation
270
+# ensures that vmnet interface is not able to communicate
271
+# with any other vmnet interfaces. Only communication with
272
+# host is allowed. Available since macOS Big Sur 11.0.
273
+#
274
+# @net-uuid: The identifier (UUID) to uniquely identify the isolated
275
+# network vmnet interface should be added to. If
276
+# set, no DHCP service is provided for this interface and
277
+# network communication is allowed only with other interfaces
278
+# added to this network identified by the UUID. Available
279
+# since macOS Big Sur 11.0.
280
+#
281
+# Since: 7.0
282
+##
283
+{ 'struct': 'NetdevVmnetHostOptions',
284
+ 'data': {
285
+ '*start-address': 'str',
286
+ '*end-address': 'str',
287
+ '*subnet-mask': 'str',
288
+ '*isolated': 'bool',
289
+ '*net-uuid': 'str' },
290
+ 'if': 'CONFIG_VMNET' }
291
+
292
+##
293
+# @NetdevVmnetSharedOptions:
294
+#
295
+# vmnet (shared mode) network backend.
296
+#
297
+# Allows traffic originating from the vmnet interface to reach the
298
+# Internet through a network address translator (NAT).
299
+# The vmnet interface can communicate with the host and with
300
+# other shared mode interfaces on the same subnet. If no DHCP
301
+# settings, subnet mask and IPv6 prefix specified, the interface can
302
+# communicate with any of other interfaces in shared mode.
303
+#
304
+# @start-address: The starting IPv4 address to use for the interface.
305
+# Must be in the private IP range (RFC 1918). Must be
306
+# specified along with @end-address and @subnet-mask.
307
+# This address is used as the gateway address. The
308
+# subsequent address up to and including end-address are
309
+# placed in the DHCP pool.
310
+#
311
+# @end-address: The DHCP IPv4 range end address to use for the
312
+# interface. Must be in the private IP range (RFC 1918).
313
+# Must be specified along with @start-address and @subnet-mask.
314
+#
315
+# @subnet-mask: The IPv4 subnet mask to use on the interface. Must
316
+# be specified along with @start-address and @subnet-mask.
317
+#
318
+# @isolated: Enable isolation for this interface. Interface isolation
319
+# ensures that vmnet interface is not able to communicate
320
+# with any other vmnet interfaces. Only communication with
321
+# host is allowed. Available since macOS Big Sur 11.0.
322
+#
323
+# @nat66-prefix: The IPv6 prefix to use into guest network. Must be a
324
+# unique local address i.e. start with fd00::/8 and have
325
+# length of 64.
326
+#
327
+# Since: 7.0
328
+##
329
+{ 'struct': 'NetdevVmnetSharedOptions',
330
+ 'data': {
331
+ '*start-address': 'str',
332
+ '*end-address': 'str',
333
+ '*subnet-mask': 'str',
334
+ '*isolated': 'bool',
335
+ '*nat66-prefix': 'str' },
336
+ 'if': 'CONFIG_VMNET' }
337
+
338
+##
339
+# @NetdevVmnetBridgedOptions:
340
+#
341
+# vmnet (bridged mode) network backend.
342
+#
343
+# Bridges the vmnet interface with a physical network interface.
344
+#
345
+# @ifname: The name of the physical interface to be bridged.
346
+#
347
+# @isolated: Enable isolation for this interface. Interface isolation
348
+# ensures that vmnet interface is not able to communicate
349
+# with any other vmnet interfaces. Only communication with
350
+# host is allowed. Available since macOS Big Sur 11.0.
351
+#
352
+# Since: 7.0
353
+##
354
+{ 'struct': 'NetdevVmnetBridgedOptions',
355
+ 'data': {
356
+ 'ifname': 'str',
357
+ '*isolated': 'bool' },
358
+ 'if': 'CONFIG_VMNET' }
359
+
360
+##
361
# @NetClientDriver:
362
#
363
# Available netdev drivers.
364
@@ -XXX,XX +XXX,XX @@
365
# Since: 2.7
366
#
367
# @vhost-vdpa since 5.1
368
+# @vmnet-host since 7.0
369
+# @vmnet-shared since 7.0
370
+# @vmnet-bridged since 7.0
371
##
372
{ 'enum': 'NetClientDriver',
373
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
374
- 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa' ] }
375
+ 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa',
376
+ { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' },
377
+ { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' },
378
+ { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] }
379
380
##
381
# @Netdev:
382
@@ -XXX,XX +XXX,XX @@
383
# Since: 1.2
384
#
385
# 'l2tpv3' - since 2.1
386
+# 'vmnet-host' - since 7.0
387
+# 'vmnet-shared' - since 7.0
388
+# 'vmnet-bridged' - since 7.0
389
##
390
{ 'union': 'Netdev',
391
'base': { 'id': 'str', 'type': 'NetClientDriver' },
392
@@ -XXX,XX +XXX,XX @@
393
'hubport': 'NetdevHubPortOptions',
394
'netmap': 'NetdevNetmapOptions',
395
'vhost-user': 'NetdevVhostUserOptions',
396
- 'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
397
+ 'vhost-vdpa': 'NetdevVhostVDPAOptions',
398
+ 'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
399
+ 'if': 'CONFIG_VMNET' },
400
+ 'vmnet-shared': { 'type': 'NetdevVmnetSharedOptions',
401
+ 'if': 'CONFIG_VMNET' },
402
+ 'vmnet-bridged': { 'type': 'NetdevVmnetBridgedOptions',
403
+ 'if': 'CONFIG_VMNET' } } }
404
405
##
406
# @RxState:
62
--
407
--
63
2.7.4
408
2.7.4
409
410
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
No segmentation should be performed if gso type is
3
Interaction with vmnet.framework in different modes
4
VIRTIO_NET_HDR_GSO_NONE even if ECN bit is set.
4
differs only on configuration stage, so we can create
5
5
common `send`, `receive`, etc. procedures and reuse them.
6
Fixes: e263cd49c7 ("Packet abstraction for VMWARE network devices")
6
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1544
7
vmnet.framework supports iov, but writing more than
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
one iov into vmnet interface fails with
9
'VMNET_INVALID_ARGUMENT'. Collecting provided iovs into
10
one and passing it to vmnet works fine. That's the
11
reason why receive_iov() left unimplemented. But it still
12
works with good enough performance having .receive()
13
implemented only.
14
15
Also, there is no way to unsubscribe from vmnet packages
16
receiving except registering and unregistering event
17
callback or simply drop packages just ignoring and
18
not processing them when related flag is set. Here we do
19
using the second way.
20
21
Signed-off-by: Phillip Tennen <phillip@axleos.com>
22
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
24
---
11
hw/net/net_tx_pkt.c | 6 ++++--
25
net/vmnet-common.m | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++
12
1 file changed, 4 insertions(+), 2 deletions(-)
26
net/vmnet-shared.c | 83 +++++++++++++-
13
27
net/vmnet_int.h | 23 ++++
14
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
28
3 files changed, 416 insertions(+), 4 deletions(-)
29
30
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
15
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/net_tx_pkt.c
32
--- a/net/vmnet-common.m
17
+++ b/hw/net/net_tx_pkt.c
33
+++ b/net/vmnet-common.m
18
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
34
@@ -XXX,XX +XXX,XX @@
35
*/
36
37
#include "qemu/osdep.h"
38
+#include "qemu/main-loop.h"
39
+#include "qemu/log.h"
40
#include "qapi/qapi-types-net.h"
41
#include "vmnet_int.h"
42
#include "clients.h"
43
@@ -XXX,XX +XXX,XX @@
44
#include "qapi/error.h"
45
46
#include <vmnet/vmnet.h>
47
+#include <dispatch/dispatch.h>
48
+
49
+#ifdef DEBUG
50
+#define D(x) x
51
+#define D_LOG(...) qemu_log(__VA_ARGS__)
52
+#else
53
+#define D(x) do { } while (0)
54
+#define D_LOG(...) do { } while (0)
55
+#endif
56
+
57
+typedef struct vmpktdesc vmpktdesc_t;
58
+typedef struct iovec iovec_t;
59
+
60
+static void vmnet_set_send_enabled(VmnetCommonState *s, bool enable)
61
+{
62
+ s->send_enabled = enable;
63
+}
64
+
65
+
66
+static void vmnet_send_completed(NetClientState *nc, ssize_t len)
67
+{
68
+ VmnetCommonState *s = DO_UPCAST(VmnetCommonState, nc, nc);
69
+ vmnet_set_send_enabled(s, true);
70
+}
71
+
72
+
73
+static void vmnet_send(NetClientState *nc,
74
+ interface_event_t event_id,
75
+ xpc_object_t event)
76
+{
77
+ assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
78
+
79
+ VmnetCommonState *s;
80
+ uint64_t packets_available;
81
+
82
+ struct iovec *iov;
83
+ struct vmpktdesc *packets;
84
+ int pkt_cnt;
85
+ int i;
86
+
87
+ vmnet_return_t if_status;
88
+ ssize_t size;
89
+
90
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
91
+
92
+ packets_available = xpc_dictionary_get_uint64(
93
+ event,
94
+ vmnet_estimated_packets_available_key
95
+ );
96
+
97
+ pkt_cnt = (packets_available < VMNET_PACKETS_LIMIT) ?
98
+ packets_available :
99
+ VMNET_PACKETS_LIMIT;
100
+
101
+
102
+ iov = s->iov_buf;
103
+ packets = s->packets_buf;
104
+
105
+ for (i = 0; i < pkt_cnt; ++i) {
106
+ packets[i].vm_pkt_size = s->max_packet_size;
107
+ packets[i].vm_pkt_iovcnt = 1;
108
+ packets[i].vm_flags = 0;
109
+ }
110
+
111
+ if_status = vmnet_read(s->vmnet_if, packets, &pkt_cnt);
112
+ if (if_status != VMNET_SUCCESS) {
113
+ error_printf("vmnet: read failed: %s\n",
114
+ vmnet_status_map_str(if_status));
115
+ }
116
+ qemu_mutex_lock_iothread();
117
+ for (i = 0; i < pkt_cnt; ++i) {
118
+ size = qemu_send_packet_async(nc,
119
+ iov[i].iov_base,
120
+ packets[i].vm_pkt_size,
121
+ vmnet_send_completed);
122
+ if (size == 0) {
123
+ vmnet_set_send_enabled(s, false);
124
+ } else if (size < 0) {
125
+ break;
126
+ }
127
+ }
128
+ qemu_mutex_unlock_iothread();
129
+
130
+}
131
+
132
+
133
+static void vmnet_register_event_callback(VmnetCommonState *s)
134
+{
135
+ dispatch_queue_t avail_pkt_q = dispatch_queue_create(
136
+ "org.qemu.vmnet.if_queue",
137
+ DISPATCH_QUEUE_SERIAL
138
+ );
139
+
140
+ vmnet_interface_set_event_callback(
141
+ s->vmnet_if,
142
+ VMNET_INTERFACE_PACKETS_AVAILABLE,
143
+ avail_pkt_q,
144
+ ^(interface_event_t event_id, xpc_object_t event) {
145
+ if (s->send_enabled) {
146
+ vmnet_send(&s->nc, event_id, event);
147
+ }
148
+ });
149
+}
150
+
151
+
152
+static void vmnet_bufs_init(VmnetCommonState *s)
153
+{
154
+ int i;
155
+ struct vmpktdesc *packets;
156
+ struct iovec *iov;
157
+
158
+ packets = s->packets_buf;
159
+ iov = s->iov_buf;
160
+
161
+ for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
162
+ iov[i].iov_len = s->max_packet_size;
163
+ iov[i].iov_base = g_malloc0(iov[i].iov_len);
164
+ packets[i].vm_pkt_iov = iov + i;
165
+ }
166
+}
167
+
168
+
169
+const char *vmnet_status_map_str(vmnet_return_t status)
170
+{
171
+ switch (status) {
172
+ case VMNET_SUCCESS:
173
+ return "success";
174
+ case VMNET_FAILURE:
175
+ return "general failure";
176
+ case VMNET_MEM_FAILURE:
177
+ return "memory allocation failure";
178
+ case VMNET_INVALID_ARGUMENT:
179
+ return "invalid argument specified";
180
+ case VMNET_SETUP_INCOMPLETE:
181
+ return "interface setup is not complete";
182
+ case VMNET_INVALID_ACCESS:
183
+ return "invalid access, permission denied";
184
+ case VMNET_PACKET_TOO_BIG:
185
+ return "packet size is larger than MTU";
186
+ case VMNET_BUFFER_EXHAUSTED:
187
+ return "buffers exhausted in kernel";
188
+ case VMNET_TOO_MANY_PACKETS:
189
+ return "packet count exceeds limit";
190
+#if defined(MAC_OS_VERSION_11_0) && \
191
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
192
+ case VMNET_SHARING_SERVICE_BUSY:
193
+ return "conflict, sharing service is in use";
194
+#endif
195
+ default:
196
+ return "unknown vmnet error";
197
+ }
198
+}
199
+
200
+
201
+int vmnet_if_create(NetClientState *nc,
202
+ xpc_object_t if_desc,
203
+ Error **errp,
204
+ void (*completion_callback)(xpc_object_t interface_param))
205
+{
206
+ VmnetCommonState *s;
207
+
208
+ dispatch_queue_t if_create_q;
209
+ dispatch_semaphore_t if_created_sem;
210
+
211
+ __block vmnet_return_t if_status;
212
+
213
+ if_create_q = dispatch_queue_create("org.qemu.vmnet.create",
214
+ DISPATCH_QUEUE_SERIAL);
215
+ if_created_sem = dispatch_semaphore_create(0);
216
+
217
+ xpc_dictionary_set_bool(
218
+ if_desc,
219
+ vmnet_allocate_mac_address_key,
220
+ false
221
+ );
222
+
223
+ D(D_LOG("vmnet.start.interface_desc:\n");
224
+ xpc_dictionary_apply(if_desc,
225
+ ^bool(const char *k, xpc_object_t v) {
226
+ char *desc = xpc_copy_description(v);
227
+ D_LOG(" %s=%s\n", k, desc);
228
+ free(desc);
229
+ return true;
230
+ }));
231
+
232
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
233
+ s->vmnet_if = vmnet_start_interface(
234
+ if_desc,
235
+ if_create_q,
236
+ ^(vmnet_return_t status, xpc_object_t interface_param) {
237
+ if_status = status;
238
+ if (status != VMNET_SUCCESS || !interface_param) {
239
+ dispatch_semaphore_signal(if_created_sem);
240
+ return;
241
+ }
242
+
243
+ D(D_LOG("vmnet.start.interface_param:\n");
244
+ xpc_dictionary_apply(interface_param,
245
+ ^bool(const char *k, xpc_object_t v) {
246
+ char *desc = xpc_copy_description(v);
247
+ D_LOG(" %s=%s\n", k, desc);
248
+ free(desc);
249
+ return true;
250
+ }));
251
+
252
+ s->mtu = xpc_dictionary_get_uint64(
253
+ interface_param,
254
+ vmnet_mtu_key);
255
+ s->max_packet_size = xpc_dictionary_get_uint64(
256
+ interface_param,
257
+ vmnet_max_packet_size_key);
258
+
259
+ if (completion_callback) {
260
+ completion_callback(interface_param);
261
+ }
262
+ dispatch_semaphore_signal(if_created_sem);
263
+ });
264
+
265
+ if (s->vmnet_if == NULL) {
266
+ error_setg(errp, "unable to create interface with requested params");
267
+ return -1;
268
+ }
269
+
270
+ dispatch_semaphore_wait(if_created_sem, DISPATCH_TIME_FOREVER);
271
+ dispatch_release(if_create_q);
272
+
273
+ if (if_status != VMNET_SUCCESS) {
274
+ error_setg(errp,
275
+ "cannot create vmnet interface: %s",
276
+ vmnet_status_map_str(if_status));
277
+ return -1;
278
+ }
279
+
280
+ vmnet_register_event_callback(s);
281
+ vmnet_bufs_init(s);
282
+ vmnet_set_send_enabled(s, true);
283
+
284
+ return 0;
285
+}
286
+
287
+
288
+ssize_t vmnet_receive_common(NetClientState *nc,
289
+ const uint8_t *buf,
290
+ size_t size)
291
+{
292
+ VmnetCommonState *s;
293
+ vmpktdesc_t packet;
294
+ iovec_t iov;
295
+ int pkt_cnt;
296
+ vmnet_return_t if_status;
297
+
298
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
299
+
300
+ if (size > s->max_packet_size) {
301
+ warn_report("vmnet: packet is too big, %zu > %llu\n",
302
+ packet.vm_pkt_size,
303
+ s->max_packet_size);
304
+ return -1;
305
+ }
306
+
307
+ iov.iov_base = (char *) buf;
308
+ iov.iov_len = size;
309
+
310
+ packet.vm_pkt_iovcnt = 1;
311
+ packet.vm_flags = 0;
312
+ packet.vm_pkt_size = size;
313
+ packet.vm_pkt_iov = &iov;
314
+
315
+ pkt_cnt = 1;
316
+ if_status = vmnet_write(s->vmnet_if, &packet, &pkt_cnt);
317
+
318
+ if (if_status != VMNET_SUCCESS) {
319
+ error_report("vmnet: write error: %s\n",
320
+ vmnet_status_map_str(if_status));
321
+ }
322
+
323
+ if (if_status == VMNET_SUCCESS && pkt_cnt) {
324
+ return size;
325
+ }
326
+ return 0;
327
+}
328
+
329
+
330
+void vmnet_cleanup_common(NetClientState *nc)
331
+{
332
+ VmnetCommonState *s;
333
+ dispatch_queue_t if_destroy_q;
334
+
335
+ s = DO_UPCAST(VmnetCommonState, nc, nc);
336
+
337
+ qemu_purge_queued_packets(nc);
338
+ vmnet_set_send_enabled(s, false);
339
+
340
+ if (s->vmnet_if == NULL) {
341
+ return;
342
+ }
343
+
344
+ if_destroy_q = dispatch_queue_create(
345
+ "org.qemu.vmnet.destroy",
346
+ DISPATCH_QUEUE_SERIAL
347
+ );
348
+
349
+ vmnet_stop_interface(
350
+ s->vmnet_if,
351
+ if_destroy_q,
352
+ ^(vmnet_return_t status) {
353
+ });
354
+
355
+ for (int i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
356
+ g_free(s->iov_buf[i].iov_base);
357
+ }
358
+}
359
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c
360
index XXXXXXX..XXXXXXX 100644
361
--- a/net/vmnet-shared.c
362
+++ b/net/vmnet-shared.c
363
@@ -XXX,XX +XXX,XX @@
364
365
#include "qemu/osdep.h"
366
#include "qapi/qapi-types-net.h"
367
+#include "qapi/error.h"
368
#include "vmnet_int.h"
369
#include "clients.h"
370
-#include "qemu/error-report.h"
371
-#include "qapi/error.h"
372
373
#include <vmnet/vmnet.h>
374
375
+typedef struct VmnetSharedState {
376
+ VmnetCommonState cs;
377
+} VmnetSharedState;
378
+
379
+
380
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
381
+{
382
+ const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
383
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
384
+
385
+ xpc_dictionary_set_uint64(
386
+ if_desc,
387
+ vmnet_operation_mode_key,
388
+ VMNET_SHARED_MODE
389
+ );
390
+
391
+#if defined(MAC_OS_VERSION_11_0) && \
392
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
393
+ xpc_dictionary_set_bool(
394
+ if_desc,
395
+ vmnet_enable_isolation_key,
396
+ options->isolated
397
+ );
398
+#else
399
+ if (options->has_isolated) {
400
+ error_setg(errp,
401
+ "vmnet-shared.isolated feature is "
402
+ "unavailable: outdated vmnet.framework API");
403
+ }
404
+#endif
405
+
406
+ if (options->has_nat66_prefix) {
407
+ xpc_dictionary_set_string(if_desc,
408
+ vmnet_nat66_prefix_key,
409
+ options->nat66_prefix);
410
+ }
411
+
412
+ if (options->has_start_address ||
413
+ options->has_end_address ||
414
+ options->has_subnet_mask) {
415
+
416
+ if (options->has_start_address &&
417
+ options->has_end_address &&
418
+ options->has_subnet_mask) {
419
+
420
+ xpc_dictionary_set_string(if_desc,
421
+ vmnet_start_address_key,
422
+ options->start_address);
423
+ xpc_dictionary_set_string(if_desc,
424
+ vmnet_end_address_key,
425
+ options->end_address);
426
+ xpc_dictionary_set_string(if_desc,
427
+ vmnet_subnet_mask_key,
428
+ options->subnet_mask);
429
+ } else {
430
+ error_setg(
431
+ errp,
432
+ "'start-address', 'end-address', 'subnet-mask' "
433
+ "should be provided together"
434
+ );
435
+ }
436
+ }
437
+
438
+ return if_desc;
439
+}
440
+
441
+static NetClientInfo net_vmnet_shared_info = {
442
+ .type = NET_CLIENT_DRIVER_VMNET_SHARED,
443
+ .size = sizeof(VmnetSharedState),
444
+ .receive = vmnet_receive_common,
445
+ .cleanup = vmnet_cleanup_common,
446
+};
447
+
448
int net_init_vmnet_shared(const Netdev *netdev, const char *name,
449
NetClientState *peer, Error **errp)
19
{
450
{
20
assert(pkt);
451
- error_setg(errp, "vmnet-shared is not implemented yet");
21
452
- return -1;
22
+ uint8_t gso_type = pkt->virt_hdr.gso_type & ~VIRTIO_NET_HDR_GSO_ECN;
453
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
23
+
454
+ peer, "vmnet-shared", name);
24
/*
455
+ xpc_object_t if_desc = create_if_desc(netdev, errp);
25
* Since underlying infrastructure does not support IP datagrams longer
456
+
26
* than 64K we should drop such packets and don't even try to send
457
+ return vmnet_if_create(nc, if_desc, errp, NULL);
27
*/
458
}
28
- if (VIRTIO_NET_HDR_GSO_NONE != pkt->virt_hdr.gso_type) {
459
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
29
+ if (VIRTIO_NET_HDR_GSO_NONE != gso_type) {
460
index XXXXXXX..XXXXXXX 100644
30
if (pkt->payload_len >
461
--- a/net/vmnet_int.h
31
ETH_MAX_IP_DGRAM_LEN -
462
+++ b/net/vmnet_int.h
32
pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len) {
463
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
464
34
}
465
#include <vmnet/vmnet.h>
35
}
466
36
467
+#define VMNET_PACKETS_LIMIT 50
37
- if (offload || pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
468
+
38
+ if (offload || gso_type == VIRTIO_NET_HDR_GSO_NONE) {
469
typedef struct VmnetCommonState {
39
if (!offload && pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
470
NetClientState nc;
40
net_tx_pkt_do_sw_csum(pkt, &pkt->vec[NET_TX_PKT_L2HDR_FRAG],
471
+ interface_ref vmnet_if;
41
pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1,
472
+
473
+ bool send_enabled;
474
+
475
+ uint64_t mtu;
476
+ uint64_t max_packet_size;
477
+
478
+ struct vmpktdesc packets_buf[VMNET_PACKETS_LIMIT];
479
+ struct iovec iov_buf[VMNET_PACKETS_LIMIT];
480
481
} VmnetCommonState;
482
483
+const char *vmnet_status_map_str(vmnet_return_t status);
484
+
485
+int vmnet_if_create(NetClientState *nc,
486
+ xpc_object_t if_desc,
487
+ Error **errp,
488
+ void (*completion_callback)(xpc_object_t interface_param));
489
+
490
+ssize_t vmnet_receive_common(NetClientState *nc,
491
+ const uint8_t *buf,
492
+ size_t size);
493
+
494
+void vmnet_cleanup_common(NetClientState *nc);
495
496
#endif /* VMNET_INT_H */
42
--
497
--
43
2.7.4
498
2.7.4
499
500
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
Add support for stripping/inserting VLAN for VFs.
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
5
Had to move CSUM calculation back into the for loop, since packet data
6
is pulled inside the loop based on strip VLAN decision for every VF.
7
8
net_rx_pkt_fix_l4_csum should be extended to accept a buffer instead for
9
igb. Work for a future patch.
10
11
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
5
---
14
hw/net/igb_core.c | 62 +++++++++++++++++++++++++++++++++++++++++++------------
6
net/vmnet-host.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
15
1 file changed, 49 insertions(+), 13 deletions(-)
7
1 file changed, 104 insertions(+), 6 deletions(-)
16
8
17
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
9
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
18
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/igb_core.c
11
--- a/net/vmnet-host.c
20
+++ b/hw/net/igb_core.c
12
+++ b/net/vmnet-host.c
21
@@ -XXX,XX +XXX,XX @@ igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, bool tx,
13
@@ -XXX,XX +XXX,XX @@
22
info->queue = E1000_RSS_QUEUE(&core->mac[RETA], info->hash);
14
*/
23
}
15
24
16
#include "qemu/osdep.h"
25
+static void
17
+#include "qemu/uuid.h"
26
+igb_tx_insert_vlan(IGBCore *core, uint16_t qn, struct igb_tx *tx,
18
#include "qapi/qapi-types-net.h"
27
+ uint16_t vlan, bool insert_vlan)
19
-#include "vmnet_int.h"
20
-#include "clients.h"
21
-#include "qemu/error-report.h"
22
#include "qapi/error.h"
23
+#include "clients.h"
24
+#include "vmnet_int.h"
25
26
#include <vmnet/vmnet.h>
27
28
+typedef struct VmnetHostState {
29
+ VmnetCommonState cs;
30
+ QemuUUID network_uuid;
31
+} VmnetHostState;
32
+
33
+static xpc_object_t create_if_desc(const Netdev *netdev,
34
+ NetClientState *nc,
35
+ Error **errp)
28
+{
36
+{
29
+ if (core->mac[MRQC] & 1) {
37
+ const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
30
+ uint16_t pool = qn % IGB_NUM_VM_POOLS;
31
+
38
+
32
+ if (core->mac[VMVIR0 + pool] & E1000_VMVIR_VLANA_DEFAULT) {
39
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
33
+ /* always insert default VLAN */
40
+
34
+ insert_vlan = true;
41
+ xpc_dictionary_set_uint64(
35
+ vlan = core->mac[VMVIR0 + pool] & 0xffff;
42
+ if_desc,
36
+ } else if (core->mac[VMVIR0 + pool] & E1000_VMVIR_VLANA_NEVER) {
43
+ vmnet_operation_mode_key,
37
+ insert_vlan = false;
44
+ VMNET_HOST_MODE
45
+ );
46
+
47
+#if defined(MAC_OS_VERSION_11_0) && \
48
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
49
+
50
+ VmnetCommonState *cs = DO_UPCAST(VmnetCommonState, nc, nc);
51
+ VmnetHostState *hs = DO_UPCAST(VmnetHostState, cs, cs);
52
+
53
+ xpc_dictionary_set_bool(
54
+ if_desc,
55
+ vmnet_enable_isolation_key,
56
+ options->isolated
57
+ );
58
+
59
+ if (options->has_net_uuid) {
60
+ if (qemu_uuid_parse(options->net_uuid, &hs->network_uuid) < 0) {
61
+ error_setg(errp, "Invalid UUID provided in 'net-uuid'");
62
+ }
63
+
64
+ xpc_dictionary_set_uuid(
65
+ if_desc,
66
+ vmnet_network_identifier_key,
67
+ hs->network_uuid.data
68
+ );
69
+ }
70
+#else
71
+ if (options->has_isolated) {
72
+ error_setg(errp,
73
+ "vmnet-host.isolated feature is "
74
+ "unavailable: outdated vmnet.framework API");
75
+ }
76
+
77
+ if (options->has_net_uuid) {
78
+ error_setg(errp,
79
+ "vmnet-host.net-uuid feature is "
80
+ "unavailable: outdated vmnet.framework API");
81
+ }
82
+#endif
83
+
84
+ if (options->has_start_address ||
85
+ options->has_end_address ||
86
+ options->has_subnet_mask) {
87
+
88
+ if (options->has_start_address &&
89
+ options->has_end_address &&
90
+ options->has_subnet_mask) {
91
+
92
+ xpc_dictionary_set_string(if_desc,
93
+ vmnet_start_address_key,
94
+ options->start_address);
95
+ xpc_dictionary_set_string(if_desc,
96
+ vmnet_end_address_key,
97
+ options->end_address);
98
+ xpc_dictionary_set_string(if_desc,
99
+ vmnet_subnet_mask_key,
100
+ options->subnet_mask);
101
+ } else {
102
+ error_setg(
103
+ errp,
104
+ "'start-address', 'end-address', 'subnet-mask' "
105
+ "should be provided together"
106
+ );
38
+ }
107
+ }
39
+ }
108
+ }
40
+
109
+
41
+ if (insert_vlan && e1000x_vlan_enabled(core->mac)) {
110
+ return if_desc;
42
+ net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, vlan,
43
+ core->mac[VET] & 0xffff);
44
+ }
45
+}
111
+}
46
+
112
+
47
static bool
113
+static NetClientInfo net_vmnet_host_info = {
48
igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx)
114
+ .type = NET_CLIENT_DRIVER_VMNET_HOST,
49
{
115
+ .size = sizeof(VmnetHostState),
50
@@ -XXX,XX +XXX,XX @@ igb_process_tx_desc(IGBCore *core,
116
+ .receive = vmnet_receive_common,
51
117
+ .cleanup = vmnet_cleanup_common,
52
if (cmd_type_len & E1000_TXD_CMD_EOP) {
118
+};
53
if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) {
54
- if (cmd_type_len & E1000_TXD_CMD_VLE) {
55
- idx = (tx->first_olinfo_status >> 4) & 1;
56
- uint16_t vlan = tx->ctx[idx].vlan_macip_lens >> 16;
57
- uint16_t vet = core->mac[VET] & 0xffff;
58
- net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, vlan, vet);
59
- }
60
+ idx = (tx->first_olinfo_status >> 4) & 1;
61
+ igb_tx_insert_vlan(core, queue_index, tx,
62
+ tx->ctx[idx].vlan_macip_lens >> 16,
63
+ !!(cmd_type_len & E1000_TXD_CMD_VLE));
64
+
119
+
65
if (igb_tx_pkt_send(core, tx, queue_index)) {
120
int net_init_vmnet_host(const Netdev *netdev, const char *name,
66
igb_on_tx_done_update_stats(core, tx->tx_pkt, queue_index);
121
- NetClientState *peer, Error **errp) {
67
}
122
- error_setg(errp, "vmnet-host is not implemented yet");
68
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
123
- return -1;
69
igb_update_rx_stats(core, rxi, size, total_size);
124
+ NetClientState *peer, Error **errp)
125
+{
126
+ NetClientState *nc;
127
+ xpc_object_t if_desc;
128
+
129
+ nc = qemu_new_net_client(&net_vmnet_host_info,
130
+ peer, "vmnet-host", name);
131
+ if_desc = create_if_desc(netdev, nc, errp);
132
+ return vmnet_if_create(nc, if_desc, errp, NULL);
70
}
133
}
71
72
+static bool
73
+igb_rx_strip_vlan(IGBCore *core, const E1000E_RingInfo *rxi)
74
+{
75
+ if (core->mac[MRQC] & 1) {
76
+ uint16_t pool = rxi->idx % IGB_NUM_VM_POOLS;
77
+ /* Sec 7.10.3.8: CTRL.VME is ignored, only VMOLR/RPLOLR is used */
78
+ return (net_rx_pkt_get_packet_type(core->rx_pkt) == ETH_PKT_MCAST) ?
79
+ core->mac[RPLOLR] & E1000_RPLOLR_STRVLAN :
80
+ core->mac[VMOLR0 + pool] & E1000_VMOLR_STRVLAN;
81
+ }
82
+
83
+ return e1000x_vlan_enabled(core->mac);
84
+}
85
+
86
static inline void
87
igb_rx_fix_l4_csum(IGBCore *core, struct NetRxPkt *pkt)
88
{
89
@@ -XXX,XX +XXX,XX @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
90
91
ehdr = PKT_GET_ETH_HDR(filter_buf);
92
net_rx_pkt_set_packet_type(core->rx_pkt, get_eth_packet_type(ehdr));
93
-
94
- net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs,
95
- e1000x_vlan_enabled(core->mac),
96
- core->mac[VET] & 0xffff);
97
+ net_rx_pkt_set_protocols(core->rx_pkt, filter_buf, size);
98
99
queues = igb_receive_assign(core, ehdr, size, &rss_info, external_tx);
100
if (!queues) {
101
@@ -XXX,XX +XXX,XX @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
102
return orig_size;
103
}
104
105
- total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
106
- e1000x_fcs_len(core->mac);
107
-
108
for (i = 0; i < IGB_NUM_QUEUES; i++) {
109
if (!(queues & BIT(i)) ||
110
!(core->mac[RXDCTL0 + (i * 16)] & E1000_RXDCTL_QUEUE_ENABLE)) {
111
@@ -XXX,XX +XXX,XX @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
112
113
igb_rx_ring_init(core, &rxr, i);
114
115
+ net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs,
116
+ igb_rx_strip_vlan(core, rxr.i),
117
+ core->mac[VET] & 0xffff);
118
+
119
+ total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
120
+ e1000x_fcs_len(core->mac);
121
+
122
if (!igb_has_rxbufs(core, rxr.i, total_size)) {
123
n |= E1000_ICS_RXO;
124
trace_e1000e_rx_not_written_to_guest(rxr.i->idx);
125
--
134
--
126
2.7.4
135
2.7.4
136
137
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
Use PFRSTD to reset RSTI bit for VFs, and raise VFLRE interrupt when VF
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
is reset.
5
6
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
5
---
9
hw/net/igb_core.c | 38 ++++++++++++++++++++++++++------------
6
net/vmnet-bridged.m | 105 +++++++++++++++++++++++++++++++++++++++++++++++++---
10
hw/net/igb_regs.h | 3 +++
7
1 file changed, 100 insertions(+), 5 deletions(-)
11
hw/net/trace-events | 2 ++
12
3 files changed, 31 insertions(+), 12 deletions(-)
13
8
14
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
9
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
15
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/igb_core.c
11
--- a/net/vmnet-bridged.m
17
+++ b/hw/net/igb_core.c
12
+++ b/net/vmnet-bridged.m
18
@@ -XXX,XX +XXX,XX @@ static void igb_set_eims(IGBCore *core, int index, uint32_t val)
13
@@ -XXX,XX +XXX,XX @@
19
igb_update_interrupt_state(core);
14
20
}
15
#include "qemu/osdep.h"
21
16
#include "qapi/qapi-types-net.h"
22
-static void igb_vf_reset(IGBCore *core, uint16_t vfn)
17
-#include "vmnet_int.h"
23
-{
18
-#include "clients.h"
24
- /* TODO: Reset of the queue enable and the interrupt registers of the VF. */
19
-#include "qemu/error-report.h"
25
-
20
#include "qapi/error.h"
26
- core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_RSTI;
21
+#include "clients.h"
27
- core->mac[V2PMAILBOX0 + vfn] = E1000_V2PMAILBOX_RSTD;
22
+#include "vmnet_int.h"
28
-}
23
29
-
24
#include <vmnet/vmnet.h>
30
static void mailbox_interrupt_to_vf(IGBCore *core, uint16_t vfn)
25
31
{
26
+typedef struct VmnetBridgedState {
32
uint32_t ent = core->mac[VTIVAR_MISC + vfn];
27
+ VmnetCommonState cs;
33
@@ -XXX,XX +XXX,XX @@ static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val)
28
+} VmnetBridgedState;
34
}
29
+
35
}
30
+static bool validate_ifname(const char *ifname)
36
37
+static void igb_vf_reset(IGBCore *core, uint16_t vfn)
38
+{
31
+{
39
+ /* disable Rx and Tx for the VF*/
32
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
40
+ core->mac[VFTE] &= ~BIT(vfn);
33
+ __block bool match = false;
41
+ core->mac[VFRE] &= ~BIT(vfn);
34
+
42
+ /* indicate VF reset to PF */
35
+ xpc_array_apply(
43
+ core->mac[VFLRE] |= BIT(vfn);
36
+ shared_if_list,
44
+ /* VFLRE and mailbox use the same interrupt cause */
37
+ ^bool(size_t index, xpc_object_t value) {
45
+ mailbox_interrupt_to_pf(core);
38
+ if (strcmp(xpc_string_get_string_ptr(value), ifname) == 0) {
39
+ match = true;
40
+ return false;
41
+ }
42
+ return true;
43
+ });
44
+
45
+ return match;
46
+}
46
+}
47
+
47
+
48
static void igb_w1c(IGBCore *core, int index, uint32_t val)
48
+static const char *get_valid_ifnames(void)
49
+{
50
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
51
+ __block char *if_list = NULL;
52
+
53
+ xpc_array_apply(
54
+ shared_if_list,
55
+ ^bool(size_t index, xpc_object_t value) {
56
+ if_list = g_strconcat(xpc_string_get_string_ptr(value),
57
+ " ",
58
+ if_list,
59
+ NULL);
60
+ return true;
61
+ });
62
+
63
+ if (if_list) {
64
+ return if_list;
65
+ }
66
+ return "[no interfaces]";
67
+}
68
+
69
+static xpc_object_t create_if_desc(const Netdev *netdev, Error **errp)
70
+{
71
+ const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
72
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
73
+
74
+ xpc_dictionary_set_uint64(
75
+ if_desc,
76
+ vmnet_operation_mode_key,
77
+ VMNET_BRIDGED_MODE
78
+ );
79
+
80
+#if defined(MAC_OS_VERSION_11_0) && \
81
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
82
+ xpc_dictionary_set_bool(
83
+ if_desc,
84
+ vmnet_enable_isolation_key,
85
+ options->isolated
86
+ );
87
+#else
88
+ if (options->has_isolated) {
89
+ error_setg(errp,
90
+ "vmnet-bridged.isolated feature is "
91
+ "unavailable: outdated vmnet.framework API");
92
+ }
93
+#endif
94
+
95
+ if (validate_ifname(options->ifname)) {
96
+ xpc_dictionary_set_string(if_desc,
97
+ vmnet_shared_interface_name_key,
98
+ options->ifname);
99
+ } else {
100
+ return NULL;
101
+ }
102
+ return if_desc;
103
+}
104
+
105
+static NetClientInfo net_vmnet_bridged_info = {
106
+ .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
107
+ .size = sizeof(VmnetBridgedState),
108
+ .receive = vmnet_receive_common,
109
+ .cleanup = vmnet_cleanup_common,
110
+};
111
+
112
int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
113
NetClientState *peer, Error **errp)
49
{
114
{
50
core->mac[index] &= ~val;
115
- error_setg(errp, "vmnet-bridged is not implemented yet");
51
@@ -XXX,XX +XXX,XX @@ igb_set_status(IGBCore *core, int index, uint32_t val)
116
- return -1;
52
static void
117
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
53
igb_set_ctrlext(IGBCore *core, int index, uint32_t val)
118
+ peer, "vmnet-bridged", name);
54
{
119
+ xpc_object_t if_desc = create_if_desc(netdev, errp);;
55
- trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK),
56
- !!(val & E1000_CTRL_EXT_SPD_BYPS));
57
-
58
- /* TODO: PFRSTD */
59
+ trace_igb_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK),
60
+ !!(val & E1000_CTRL_EXT_SPD_BYPS),
61
+ !!(val & E1000_CTRL_EXT_PFRSTD));
62
63
/* Zero self-clearing bits */
64
val &= ~(E1000_CTRL_EXT_ASDCHK | E1000_CTRL_EXT_EE_RST);
65
core->mac[CTRL_EXT] = val;
66
+
120
+
67
+ if (core->mac[CTRL_EXT] & E1000_CTRL_EXT_PFRSTD) {
121
+ if (!if_desc) {
68
+ for (int vfn = 0; vfn < IGB_MAX_VF_FUNCTIONS; vfn++) {
122
+ error_setg(errp,
69
+ core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_RSTI;
123
+ "unsupported ifname, should be one of: %s",
70
+ core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_RSTD;
124
+ get_valid_ifnames());
71
+ }
125
+ return -1;
72
+ }
73
}
74
75
static void
76
@@ -XXX,XX +XXX,XX @@ static void igb_reset(IGBCore *core, bool sw)
77
78
e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
79
80
+ for (int vfn = 0; vfn < IGB_MAX_VF_FUNCTIONS; vfn++) {
81
+ /* Set RSTI, so VF can identify a PF reset is in progress */
82
+ core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_RSTI;
83
+ }
126
+ }
84
+
127
+
85
for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
128
+ return vmnet_if_create(nc, if_desc, errp, NULL);
86
tx = &core->tx[i];
129
}
87
net_tx_pkt_reset(tx->tx_pkt, NULL);
88
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/net/igb_regs.h
91
+++ b/hw/net/igb_regs.h
92
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
93
94
/* from igb/e1000_defines.h */
95
96
+/* Physical Func Reset Done Indication */
97
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
98
+
99
#define E1000_IVAR_VALID 0x80
100
#define E1000_GPIE_NSICR 0x00000001
101
#define E1000_GPIE_MSIX_MODE 0x00000010
102
diff --git a/hw/net/trace-events b/hw/net/trace-events
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/net/trace-events
105
+++ b/hw/net/trace-events
106
@@ -XXX,XX +XXX,XX @@ igb_core_mdic_read_unhandled(uint32_t addr) "MDIC READ: PHY[%u] UNHANDLED"
107
igb_core_mdic_write(uint32_t addr, uint32_t data) "MDIC WRITE: PHY[%u] = 0x%x"
108
igb_core_mdic_write_unhandled(uint32_t addr) "MDIC WRITE: PHY[%u] UNHANDLED"
109
110
+igb_link_set_ext_params(bool asd_check, bool speed_select_bypass, bool pfrstd) "Set extended link params: ASD check: %d, Speed select bypass: %d, PF reset done: %d"
111
+
112
igb_rx_desc_buff_size(uint32_t b) "buffer size: %u"
113
igb_rx_desc_buff_write(uint64_t addr, uint16_t offset, const void* source, uint32_t len) "addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"
114
115
--
130
--
116
2.7.4
131
2.7.4
132
133
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
Align the l3_hdr member of NetTxPkt by defining it as a union of
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
ip_header, ip6_header, and an array of octets.
5
6
Fixes: e263cd49c7 ("Packet abstraction for VMWARE network devices")
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1544
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
5
---
11
hw/net/net_tx_pkt.c | 21 +++++++++++----------
6
qemu-options.hx | 25 +++++++++++++++++++++++++
12
1 file changed, 11 insertions(+), 10 deletions(-)
7
1 file changed, 25 insertions(+)
13
8
14
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
9
diff --git a/qemu-options.hx b/qemu-options.hx
15
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/net_tx_pkt.c
11
--- a/qemu-options.hx
17
+++ b/hw/net/net_tx_pkt.c
12
+++ b/qemu-options.hx
18
@@ -XXX,XX +XXX,XX @@ struct NetTxPkt {
13
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
19
struct iovec *vec;
14
"-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
20
15
" configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
21
uint8_t l2_hdr[ETH_MAX_L2_HDR_LEN];
16
#endif
22
- uint8_t l3_hdr[ETH_MAX_IP_DGRAM_LEN];
17
+#ifdef CONFIG_VMNET
23
+ union {
18
+ "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n"
24
+ struct ip_header ip;
19
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
25
+ struct ip6_header ip6;
20
+ " configure a vmnet network backend in host mode with ID 'str',\n"
26
+ uint8_t octets[ETH_MAX_IP_DGRAM_LEN];
21
+ " isolate this interface from others with 'isolated',\n"
27
+ } l3_hdr;
22
+ " configure the address range and choose a subnet mask,\n"
28
23
+ " specify network UUID 'uuid' to disable DHCP and interact with\n"
29
uint32_t payload_len;
24
+ " vmnet-host interfaces within this isolated network\n"
30
25
+ "-netdev vmnet-shared,id=str[,isolated=on|off][,nat66-prefix=addr]\n"
31
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_update_ip_hdr_checksum(struct NetTxPkt *pkt)
26
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
32
{
27
+ " configure a vmnet network backend in shared mode with ID 'str',\n"
33
uint16_t csum;
28
+ " configure the address range and choose a subnet mask,\n"
34
assert(pkt);
29
+ " set IPv6 ULA prefix (of length 64) to use for internal network,\n"
35
- struct ip_header *ip_hdr;
30
+ " isolate this interface from others with 'isolated'\n"
36
- ip_hdr = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
31
+ "-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]\n"
37
32
+ " configure a vmnet network backend in bridged mode with ID 'str',\n"
38
- ip_hdr->ip_len = cpu_to_be16(pkt->payload_len +
33
+ " use 'ifname=name' to select a physical network interface to be bridged,\n"
39
+ pkt->l3_hdr.ip.ip_len = cpu_to_be16(pkt->payload_len +
34
+ " isolate this interface from others with 'isolated'\n"
40
pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len);
35
+#endif
41
36
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
42
- ip_hdr->ip_sum = 0;
37
" configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
43
- csum = net_raw_checksum((uint8_t *)ip_hdr,
38
DEF("nic", HAS_ARG, QEMU_OPTION_nic,
44
+ pkt->l3_hdr.ip.ip_sum = 0;
39
@@ -XXX,XX +XXX,XX @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
45
+ csum = net_raw_checksum(pkt->l3_hdr.octets,
40
#ifdef CONFIG_POSIX
46
pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len);
41
"vhost-user|"
47
- ip_hdr->ip_sum = cpu_to_be16(csum);
42
#endif
48
+ pkt->l3_hdr.ip.ip_sum = cpu_to_be16(csum);
43
+#ifdef CONFIG_VMNET
49
}
44
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
50
45
+#endif
51
void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt)
46
"socket][,option][,...][mac=macaddr]\n"
52
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_fix_ip6_payload_len(struct NetTxPkt *pkt)
47
" initialize an on-board / default host NIC (using MAC address\n"
53
{
48
" macaddr) and connect it to the given host network backend\n"
54
struct iovec *l2 = &pkt->vec[NET_TX_PKT_L2HDR_FRAG];
49
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
55
if (eth_get_l3_proto(l2, 1, l2->iov_len) == ETH_P_IPV6) {
50
#ifdef CONFIG_NETMAP
56
- struct ip6_header *ip6 = (struct ip6_header *) pkt->l3_hdr;
51
"netmap|"
57
/*
52
#endif
58
* TODO: if qemu would support >64K packets - add jumbo option check
53
+#ifdef CONFIG_VMNET
59
* something like that:
54
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
60
* 'if (ip6->ip6_plen == 0 && !has_jumbo_option(ip6)) {'
55
+#endif
61
*/
56
"socket][,option][,option][,...]\n"
62
- if (ip6->ip6_plen == 0) {
57
" old way to initialize a host network interface\n"
63
+ if (pkt->l3_hdr.ip6.ip6_plen == 0) {
58
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
64
if (pkt->payload_len <= ETH_MAX_IP_DGRAM_LEN) {
65
- ip6->ip6_plen = htons(pkt->payload_len);
66
+ pkt->l3_hdr.ip6.ip6_plen = htons(pkt->payload_len);
67
}
68
/*
69
* TODO: if qemu would support >64K packets
70
--
59
--
71
2.7.4
60
2.7.4
61
62
diff view generated by jsdifflib
1
From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
I would like to review and be informed on changes to igb device
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
5
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
5
---
8
MAINTAINERS | 1 +
6
MAINTAINERS | 5 +++++
9
1 file changed, 1 insertion(+)
7
1 file changed, 5 insertions(+)
10
8
11
diff --git a/MAINTAINERS b/MAINTAINERS
9
diff --git a/MAINTAINERS b/MAINTAINERS
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/MAINTAINERS
11
--- a/MAINTAINERS
14
+++ b/MAINTAINERS
12
+++ b/MAINTAINERS
15
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/libqos/e1000e.*
13
@@ -XXX,XX +XXX,XX @@ W: http://info.iet.unipi.it/~luigi/netmap/
16
17
igb
18
M: Akihiko Odaki <akihiko.odaki@daynix.com>
19
+R: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
20
S: Maintained
14
S: Maintained
21
F: docs/system/devices/igb.rst
15
F: net/netmap.c
22
F: hw/net/igb*
16
17
+Apple vmnet network backends
18
+M: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
19
+S: Maintained
20
+F: net/vmnet*
21
+
22
Host Memory Backends
23
M: David Hildenbrand <david@redhat.com>
24
M: Igor Mammedov <imammedo@redhat.com>
23
--
25
--
24
2.7.4
26
2.7.4
27
28
diff view generated by jsdifflib