1
The following changes since commit 7fe7fae8b48e3f9c647fd685e5155ebc8e6fb84d:
1
The following changes since commit f8d75e10d3e0033a0a29a7a7e4777a4fbc17a016:
2
2
3
Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-migration-20210609a' into staging (2021-06-09 16:40:21 +0100)
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 5a2d9929ac1f01a1e8ef2a3f56f69e6069863dad:
9
for you to fetch changes up to 818692f0a01587d02220916b31d5bb8e7dced611:
10
10
11
Fixed calculation error of pkt->header_size in fill_pkt_tcp_info() (2021-06-11 10:30:13 +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
Jason Wang (4):
20
Peter Foley (2):
17
vhost-vdpa: skip ram device from the IOTLB mapping
21
net/tap: Set return code on failure
18
vhost-vdpa: map virtqueue notification area if possible
22
net: Fix uninitialized data usage
19
vhost-vdpa: don't initialize backend_features
20
vhost-vdpa: remove the unused vhost_vdpa_get_acked_features()
21
23
22
Paolo Bonzini (1):
24
Philippe Mathieu-Daudé (1):
23
netdev: add more commands to preconfig mode
25
hw/net/vmxnet3: Log guest-triggerable errors using LOG_GUEST_ERROR
24
26
25
Rao, Lei (7):
27
Rao Lei (1):
26
Remove some duplicate trace code.
28
net/filter: Optimize filter_send to coroutine
27
Fix the qemu crash when guest shutdown during checkpoint
28
Optimize the function of filter_send
29
Remove migrate_set_block_enabled in checkpoint
30
Add a function named packet_new_nocopy for COLO.
31
Add the function of colo_compare_cleanup
32
Fixed calculation error of pkt->header_size in fill_pkt_tcp_info()
33
29
34
hmp-commands.hx | 2 +
30
Vladislav Yaroshchuk (7):
35
hw/virtio/vhost-vdpa.c | 100 +++++++++++++++++++++++++++++++++++------
31
net/vmnet: add vmnet dependency and customizable option
36
include/hw/virtio/vhost-vdpa.h | 6 +++
32
net/vmnet: add vmnet backends to qapi/net
37
include/net/vhost-vdpa.h | 1 -
33
net/vmnet: implement shared mode (vmnet-shared)
38
migration/colo.c | 6 ---
34
net/vmnet: implement host mode (vmnet-host)
39
migration/migration.c | 4 ++
35
net/vmnet: implement bridged mode (vmnet-bridged)
40
net/colo-compare.c | 25 +++++------
36
net/vmnet: update qemu-options.hx
41
net/colo-compare.h | 1 +
37
net/vmnet: update MAINTAINERS list
42
net/colo.c | 25 +++++++----
38
43
net/colo.h | 1 +
39
Zhang Chen (2):
44
net/filter-mirror.c | 8 ++--
40
net/colo-compare.c: Optimize compare order for performance
45
net/filter-rewriter.c | 3 +-
41
net/colo-compare.c: Update the default value comments
46
net/net.c | 4 ++
42
47
net/vhost-vdpa.c | 9 ----
43
MAINTAINERS | 5 +
48
qapi/net.json | 6 ++-
44
hw/net/vmxnet3.c | 4 +-
49
softmmu/runstate.c | 1 +
45
meson.build | 16 +-
50
16 files changed, 143 insertions(+), 59 deletions(-)
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
51
68
52
69
53
54
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
There is the same trace code in the colo_compare_packet_payload.
3
The "Interrupt Cause" register (VMXNET3_REG_ICR) is read-only.
4
Write accesses are ignored. Log them with as LOG_GUEST_ERROR
5
instead of aborting:
4
6
5
Signed-off-by: Lei Rao <lei.rao@intel.com>
7
[R +0.239743] writeq 0xe0002031 0x46291a5a55460800
6
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
8
ERROR:hw/net/vmxnet3.c:1819:vmxnet3_io_bar1_write: code should not be reached
7
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
9
Thread 1 "qemu-system-i38" received signal SIGABRT, Aborted.
8
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
10
(gdb) bt
9
Tested-by: Lukas Straub <lukasstraub2@web.de>
11
#3 0x74c397d3 in __GI_abort () at abort.c:79
10
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
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>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
30
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
31
---
13
net/colo-compare.c | 13 -------------
32
hw/net/vmxnet3.c | 4 +++-
14
1 file changed, 13 deletions(-)
33
1 file changed, 3 insertions(+), 1 deletion(-)
15
34
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
35
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
17
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
18
--- a/net/colo-compare.c
37
--- a/hw/net/vmxnet3.c
19
+++ b/net/colo-compare.c
38
+++ b/hw/net/vmxnet3.c
20
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
39
@@ -XXX,XX +XXX,XX @@ vmxnet3_io_bar1_write(void *opaque,
21
uint16_t offset = ppkt->vnet_hdr_len;
40
case VMXNET3_REG_ICR:
22
41
VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d",
23
trace_colo_compare_main("compare other");
42
val, size);
24
- if (trace_event_get_state_backends(TRACE_COLO_COMPARE_IP_INFO)) {
43
- g_assert_not_reached();
25
- char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
44
+ qemu_log_mask(LOG_GUEST_ERROR,
26
-
45
+ "%s: write to read-only register VMXNET3_REG_ICR\n",
27
- strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src));
46
+ TYPE_VMXNET3);
28
- strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst));
47
break;
29
- strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src));
48
30
- strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst));
49
/* Event Cause Register */
31
-
32
- trace_colo_compare_ip_info(ppkt->size, pri_ip_src,
33
- pri_ip_dst, spkt->size,
34
- sec_ip_src, sec_ip_dst);
35
- }
36
-
37
if (ppkt->size != spkt->size) {
38
trace_colo_compare_main("Other: payload size of packets are different");
39
return -1;
40
--
50
--
41
2.7.4
51
2.7.4
42
52
43
53
diff view generated by jsdifflib
New patch
1
From: Peter Foley <pefoley@google.com>
1
2
3
Match the other error handling in this function.
4
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>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
net/tap.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/net/tap.c b/net/tap.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/net/tap.c
18
+++ b/net/tap.c
19
@@ -XXX,XX +XXX,XX @@ int net_init_tap(const Netdev *netdev, const char *name,
20
if (i == 0) {
21
vnet_hdr = tap_probe_vnet_hdr(fd, errp);
22
if (vnet_hdr < 0) {
23
+ ret = -1;
24
goto free_fail;
25
}
26
} else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
27
--
28
2.7.4
29
30
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Peter Foley <pefoley@google.com>
2
2
3
This patch fixes the following:
3
e.g.
4
qemu-system-x86_64: invalid runstate transition: 'colo' ->'shutdown'
4
1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0 inside [0x7ffc516af9b8, 4)
5
Aborted (core dumped)
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
6
56
7
Signed-off-by: Lei Rao <lei.rao@intel.com>
57
Fixes: dc69004c7d8 ("net: move tap_probe_vnet_hdr() to tap-linux.c")
8
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
58
Reviewed-by: Hao Wu <wuhaotsh@google.com>
9
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
59
Reviewed-by: Patrick Venture <venture@google.com>
10
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
60
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Tested-by: Lukas Straub <lukasstraub2@web.de>
61
Signed-off-by: Peter Foley <pefoley@google.com>
12
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
62
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
63
---
15
softmmu/runstate.c | 1 +
64
net/tap-linux.c | 1 +
16
1 file changed, 1 insertion(+)
65
1 file changed, 1 insertion(+)
17
66
18
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
67
diff --git a/net/tap-linux.c b/net/tap-linux.c
19
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
20
--- a/softmmu/runstate.c
69
--- a/net/tap-linux.c
21
+++ b/softmmu/runstate.c
70
+++ b/net/tap-linux.c
22
@@ -XXX,XX +XXX,XX @@ static const RunStateTransition runstate_transitions_def[] = {
71
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
23
{ RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
72
int tap_probe_vnet_hdr(int fd, Error **errp)
24
73
{
25
{ RUN_STATE_COLO, RUN_STATE_RUNNING },
74
struct ifreq ifr;
26
+ { RUN_STATE_COLO, RUN_STATE_SHUTDOWN},
75
+ memset(&ifr, 0, sizeof(ifr));
27
76
28
{ RUN_STATE_RUNNING, RUN_STATE_DEBUG },
77
if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
29
{ RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
78
/* TUNGETIFF is available since kernel v2.6.27 */
30
--
79
--
31
2.7.4
80
2.7.4
32
81
33
82
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
This patch fixes the following:
3
COLO-compare use the glib function g_queue_find_custom to dump
4
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
4
another VM's networking packet to compare. But this function always
5
#1 0x00007f6ae4559859 in __GI_abort () at abort.c:79
5
start find from the queue->head(here is the newest packet), It will
6
#2 0x0000559aaa386720 in error_exit (err=16, msg=0x559aaa5973d0 <__func__.16227> "qemu_mutex_destroy") at util/qemu-thread-posix.c:36
6
reduce the success rate of comparison. So this patch reversed
7
#3 0x0000559aaa3868c5 in qemu_mutex_destroy (mutex=0x559aabffe828) at util/qemu-thread-posix.c:69
7
the order of the queues for performance.
8
#4 0x0000559aaa2f93a8 in char_finalize (obj=0x559aabffe800) at chardev/char.c:285
9
#5 0x0000559aaa23318a in object_deinit (obj=0x559aabffe800, type=0x559aabfd7d20) at qom/object.c:606
10
#6 0x0000559aaa2331b8 in object_deinit (obj=0x559aabffe800, type=0x559aabfd9060) at qom/object.c:610
11
#7 0x0000559aaa233200 in object_finalize (data=0x559aabffe800) at qom/object.c:620
12
#8 0x0000559aaa234202 in object_unref (obj=0x559aabffe800) at qom/object.c:1074
13
#9 0x0000559aaa2356b6 in object_finalize_child_property (obj=0x559aac0dac10, name=0x559aac778760 "compare0-0", opaque=0x559aabffe800) at qom/object.c:1584
14
#10 0x0000559aaa232f70 in object_property_del_all (obj=0x559aac0dac10) at qom/object.c:557
15
#11 0x0000559aaa2331ed in object_finalize (data=0x559aac0dac10) at qom/object.c:619
16
#12 0x0000559aaa234202 in object_unref (obj=0x559aac0dac10) at qom/object.c:1074
17
#13 0x0000559aaa2356b6 in object_finalize_child_property (obj=0x559aac0c75c0, name=0x559aac0dadc0 "chardevs", opaque=0x559aac0dac10) at qom/object.c:1584
18
#14 0x0000559aaa233071 in object_property_del_child (obj=0x559aac0c75c0, child=0x559aac0dac10, errp=0x0) at qom/object.c:580
19
#15 0x0000559aaa233155 in object_unparent (obj=0x559aac0dac10) at qom/object.c:599
20
#16 0x0000559aaa2fb721 in qemu_chr_cleanup () at chardev/char.c:1159
21
#17 0x0000559aa9f9b110 in main (argc=54, argv=0x7ffeb62fa998, envp=0x7ffeb62fab50) at vl.c:4539
22
8
23
When chardev is cleaned up, chr_write_lock needs to be destroyed. But
24
the colo-compare module is not cleaned up normally before it when the
25
guest poweroff. It is holding chr_write_lock at this time. This will
26
cause qemu crash.So we add the function of colo_compare_cleanup() before
27
qemu_chr_cleanup() to fix the bug.
28
29
Signed-off-by: Lei Rao <lei.rao@intel.com>
30
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
31
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
32
Tested-by: Lukas Straub <lukasstraub2@web.de>
33
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
9
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
10
Reported-by: leirao <lei.rao@intel.com>
34
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
35
---
12
---
36
net/colo-compare.c | 10 ++++++++++
13
net/colo-compare.c | 26 +++++++++++++-------------
37
net/colo-compare.h | 1 +
14
1 file changed, 13 insertions(+), 13 deletions(-)
38
net/net.c | 4 ++++
39
3 files changed, 15 insertions(+)
40
15
41
diff --git a/net/colo-compare.c b/net/colo-compare.c
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
42
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
43
--- a/net/colo-compare.c
18
--- a/net/colo-compare.c
44
+++ b/net/colo-compare.c
19
+++ b/net/colo-compare.c
45
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void colo_compare_inconsistency_notify(CompareState *s)
46
compare_set_vnet_hdr);
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;
47
}
26
}
48
27
49
+void colo_compare_cleanup(void)
28
static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
50
+{
29
@@ -XXX,XX +XXX,XX @@ pri:
51
+ CompareState *tmp = NULL;
30
if (g_queue_is_empty(&conn->primary_list)) {
52
+ CompareState *n = NULL;
31
return;
53
+
32
}
54
+ QTAILQ_FOREACH_SAFE(tmp, &net_compares, next, n) {
33
- ppkt = g_queue_pop_head(&conn->primary_list);
55
+ object_unparent(OBJECT(tmp));
34
+ ppkt = g_queue_pop_tail(&conn->primary_list);
56
+ }
35
sec:
57
+}
36
if (g_queue_is_empty(&conn->secondary_list)) {
58
+
37
- g_queue_push_head(&conn->primary_list, ppkt);
59
static void colo_compare_finalize(Object *obj)
38
+ g_queue_push_tail(&conn->primary_list, ppkt);
60
{
39
return;
61
CompareState *s = COLO_COMPARE(obj);
40
}
62
diff --git a/net/colo-compare.h b/net/colo-compare.h
41
- spkt = g_queue_pop_head(&conn->secondary_list);
63
index XXXXXXX..XXXXXXX 100644
42
+ spkt = g_queue_pop_tail(&conn->secondary_list);
64
--- a/net/colo-compare.h
43
65
+++ b/net/colo-compare.h
44
if (ppkt->tcp_seq == ppkt->seq_end) {
66
@@ -XXX,XX +XXX,XX @@
45
colo_release_primary_pkt(s, ppkt);
67
void colo_notify_compares_event(void *opaque, int event, Error **errp);
46
@@ -XXX,XX +XXX,XX @@ sec:
68
void colo_compare_register_notifier(Notifier *notify);
47
}
69
void colo_compare_unregister_notifier(Notifier *notify);
48
}
70
+void colo_compare_cleanup(void);
49
if (!ppkt) {
71
50
- g_queue_push_head(&conn->secondary_list, spkt);
72
#endif /* QEMU_COLO_COMPARE_H */
51
+ g_queue_push_tail(&conn->secondary_list, spkt);
73
diff --git a/net/net.c b/net/net.c
52
goto pri;
74
index XXXXXXX..XXXXXXX 100644
53
}
75
--- a/net/net.c
54
}
76
+++ b/net/net.c
55
@@ -XXX,XX +XXX,XX @@ sec:
77
@@ -XXX,XX +XXX,XX @@
56
if (mark == COLO_COMPARE_FREE_PRIMARY) {
78
#include "qapi/error.h"
57
conn->compare_seq = ppkt->seq_end;
79
#include "qapi/opts-visitor.h"
58
colo_release_primary_pkt(s, ppkt);
80
#include "sysemu/runstate.h"
59
- g_queue_push_head(&conn->secondary_list, spkt);
81
+#include "net/colo-compare.h"
60
+ g_queue_push_tail(&conn->secondary_list, spkt);
82
#include "net/filter.h"
61
goto pri;
83
#include "qapi/string-output-visitor.h"
62
} else if (mark == COLO_COMPARE_FREE_SECONDARY) {
84
63
conn->compare_seq = spkt->seq_end;
85
@@ -XXX,XX +XXX,XX @@ void net_cleanup(void)
64
@@ -XXX,XX +XXX,XX @@ sec:
86
{
65
goto pri;
87
NetClientState *nc;
66
}
88
67
} else {
89
+ /*cleanup colo compare module for COLO*/
68
- g_queue_push_head(&conn->primary_list, ppkt);
90
+ colo_compare_cleanup();
69
- g_queue_push_head(&conn->secondary_list, spkt);
91
+
70
+ g_queue_push_tail(&conn->primary_list, ppkt);
92
/* We may del multiple entries during qemu_del_net_client(),
71
+ g_queue_push_tail(&conn->secondary_list, spkt);
93
* so QTAILQ_FOREACH_SAFE() is also not safe here.
72
94
*/
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
}
119
}
95
--
120
--
96
2.7.4
121
2.7.4
97
122
98
123
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Zhang Chen <chen.zhang@intel.com>
2
2
3
The data pointer has skipped vnet_hdr_len in the function of
3
Make the comments consistent with the REGULAR_PACKET_CHECK_MS.
4
parse_packet_early().So, we can not subtract vnet_hdr_len again
5
when calculating pkt->header_size in fill_pkt_tcp_info(). Otherwise,
6
it will cause network packet comparsion errors and greatly increase
7
the frequency of checkpoints.
8
4
9
Signed-off-by: Lei Rao <lei.rao@intel.com>
10
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
11
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
12
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
13
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
14
Tested-by: Lukas Straub <lukasstraub2@web.de>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
---
7
---
17
net/colo-compare.c | 2 +-
8
net/colo-compare.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 1 insertion(+), 1 deletion(-)
19
10
20
diff --git a/net/colo-compare.c b/net/colo-compare.c
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/net/colo-compare.c
13
--- a/net/colo-compare.c
23
+++ b/net/colo-compare.c
14
+++ b/net/colo-compare.c
24
@@ -XXX,XX +XXX,XX @@ static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
15
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
25
pkt->tcp_ack = ntohl(tcphd->th_ack);
16
}
26
*max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
17
27
pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
18
if (!s->expired_scan_cycle) {
28
- + (tcphd->th_off << 2) - pkt->vnet_hdr_len;
19
- /* Set default value to 3000 MS */
29
+ + (tcphd->th_off << 2);
20
+ /* Set default value to 1000 MS */
30
pkt->payload_size = pkt->size - pkt->header_size;
21
s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
31
pkt->seq_end = pkt->tcp_seq + pkt->payload_size;
22
}
32
pkt->flags = tcphd->th_flags;
23
33
--
24
--
34
2.7.4
25
2.7.4
35
26
36
27
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Rao Lei <lei.rao@intel.com>
2
2
3
The iov_size has been calculated in filter_send(). we can directly
3
This patch is to improve the logic of QEMU main thread sleep code in
4
return the size.In this way, this is no need to repeat calculations
4
qemu_chr_write_buffer() where it can be blocked and can't run other
5
in filter_redirector_receive_iov();
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.
6
11
7
Signed-off-by: Lei Rao <lei.rao@intel.com>
12
Signed-off-by: Lei Rao <lei.rao@intel.com>
13
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
8
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
14
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
9
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
15
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
10
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
11
Tested-by: Lukas Straub <lukasstraub2@web.de>
12
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
17
---
15
net/filter-mirror.c | 8 ++++----
18
net/filter-mirror.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----------
16
1 file changed, 4 insertions(+), 4 deletions(-)
19
1 file changed, 53 insertions(+), 13 deletions(-)
17
20
18
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
21
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/net/filter-mirror.c
23
--- a/net/filter-mirror.c
21
+++ b/net/filter-mirror.c
24
+++ b/net/filter-mirror.c
25
@@ -XXX,XX +XXX,XX @@
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));
22
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
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) {
23
goto err;
74
goto err;
24
}
75
}
25
76
@@ -XXX,XX +XXX,XX @@ err:
26
- return 0;
27
+ return size;
28
29
err:
30
return ret < 0 ? ret : -EIO;
77
return ret < 0 ? ret : -EIO;
31
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
78
}
32
int ret;
79
33
80
+static void coroutine_fn filter_send_co(void *opaque)
34
ret = filter_send(s, iov, iovcnt);
81
+{
35
- if (ret) {
82
+ FilterSendCo *data = opaque;
36
+ if (ret < 0) {
83
+
37
error_report("filter mirror send failed(%s)", strerror(-ret));
84
+ data->ret = _filter_send(data->s, data->buf, data->size);
38
}
85
+ data->done = true;
39
86
+ g_free(data->buf);
40
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
87
+ aio_wait_kick();
41
88
+}
42
if (qemu_chr_fe_backend_connected(&s->chr_out)) {
89
+
43
ret = filter_send(s, iov, iovcnt);
90
+static int filter_send(MirrorState *s,
44
- if (ret) {
91
+ const struct iovec *iov,
45
+ if (ret < 0) {
92
+ int iovcnt)
46
error_report("filter redirector send failed(%s)", strerror(-ret));
93
+{
47
}
94
+ ssize_t size = iov_size(iov, iovcnt);
48
- return iov_size(iov, iovcnt);
95
+ char *buf = NULL;
49
+ return ret;
96
+
50
} else {
97
+ if (!size) {
51
return 0;
98
+ return 0;
52
}
99
+ }
100
+
101
+ buf = g_malloc(size);
102
+ iov_to_buf(iov, iovcnt, 0, buf, size);
103
+
104
+ FilterSendCo data = {
105
+ .s = s,
106
+ .size = size,
107
+ .buf = buf,
108
+ .ret = 0,
109
+ };
110
+
111
+ Coroutine *co = qemu_coroutine_create(filter_send_co, &data);
112
+ qemu_coroutine_enter(co);
113
+
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)
53
--
124
--
54
2.7.4
125
2.7.4
55
126
56
127
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
We can detect disk migration in migrate_prepare, if disk migration
3
vmnet.framework dependency is added with 'vmnet' option
4
is enabled in COLO mode, we can directly report an error.and there
4
to enable or disable it. Default value is 'auto'.
5
is no need to disable block migration at every checkpoint.
6
5
7
Signed-off-by: Lei Rao <lei.rao@intel.com>
6
vmnet features to be used are available since macOS 11.0,
8
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
7
corresponding probe is created into meson.build.
9
Reviewed-by: Li Zhijian <lizhijian@fujitsu.com>
8
10
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
9
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
11
Reviewed-by: Lukas Straub <lukasstraub2@web.de>
12
Tested-by: Lukas Straub <lukasstraub2@web.de>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
11
---
15
migration/colo.c | 6 ------
12
meson.build | 16 +++++++++++++++-
16
migration/migration.c | 4 ++++
13
meson_options.txt | 2 ++
17
2 files changed, 4 insertions(+), 6 deletions(-)
14
scripts/meson-buildoptions.sh | 3 +++
15
3 files changed, 20 insertions(+), 1 deletion(-)
18
16
19
diff --git a/migration/colo.c b/migration/colo.c
17
diff --git a/meson.build b/meson.build
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/migration/colo.c
19
--- a/meson.build
22
+++ b/migration/colo.c
20
+++ b/meson.build
23
@@ -XXX,XX +XXX,XX @@ static int colo_do_checkpoint_transaction(MigrationState *s,
21
@@ -XXX,XX +XXX,XX @@ if cocoa.found() and get_option('gtk').enabled()
24
if (failover_get_state() != FAILOVER_STATUS_NONE) {
22
error('Cocoa and GTK+ cannot be enabled at the same time')
25
goto out;
23
endif
26
}
24
27
-
25
+vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
28
- /* Disable block migration */
26
+if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
29
- migrate_set_block_enabled(false, &local_err);
27
+ 'VMNET_BRIDGED_MODE',
30
- if (local_err) {
28
+ dependencies: vmnet)
31
- goto out;
29
+ vmnet = not_found
32
- }
30
+ if get_option('vmnet').enabled()
33
qemu_mutex_lock_iothread();
31
+ error('vmnet.framework API is outdated')
34
32
+ else
35
#ifdef CONFIG_REPLICATION
33
+ warning('vmnet.framework API is outdated, disabling')
36
diff --git a/migration/migration.c b/migration/migration.c
34
+ endif
35
+endif
36
+
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
37
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
38
--- a/migration/migration.c
60
--- a/meson_options.txt
39
+++ b/migration/migration.c
61
+++ b/meson_options.txt
40
@@ -XXX,XX +XXX,XX @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
62
@@ -XXX,XX +XXX,XX @@ option('netmap', type : 'feature', value : 'auto',
41
}
63
description: 'netmap network backend support')
42
64
option('vde', type : 'feature', value : 'auto',
43
if (blk || blk_inc) {
65
description: 'vde network backend support')
44
+ if (migrate_colo_enabled()) {
66
+option('vmnet', type : 'feature', value : 'auto',
45
+ error_setg(errp, "No disk migration is required in COLO mode");
67
+ description: 'vmnet.framework network backend support')
46
+ return false;
68
option('virglrenderer', type : 'feature', value : 'auto',
47
+ }
69
description: 'virgl rendering support')
48
if (migrate_use_block() || migrate_use_block_incremental()) {
70
option('vnc', type : 'feature', value : 'auto',
49
error_setg(errp, "Command options are incompatible with "
71
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
50
"current migration capabilities");
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 ;;
51
--
92
--
52
2.7.4
93
2.7.4
53
94
54
95
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
Creating and destroying network backend does not require a fully
3
Create separate netdevs for each vmnet operating mode:
4
constructed machine. Allow the related monitor commands to run before
4
- vmnet-host
5
machine initialization has concluded.
5
- vmnet-shared
6
- vmnet-bridged
6
7
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
8
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
10
---
11
hmp-commands.hx | 2 ++
11
net/clients.h | 11 +++++
12
qapi/net.json | 6 ++++--
12
net/meson.build | 7 +++
13
2 files changed, 6 insertions(+), 2 deletions(-)
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
14
26
15
diff --git a/hmp-commands.hx b/hmp-commands.hx
27
diff --git a/net/clients.h b/net/clients.h
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/hmp-commands.hx
29
--- a/net/clients.h
18
+++ b/hmp-commands.hx
30
+++ b/net/clients.h
19
@@ -XXX,XX +XXX,XX @@ ERST
31
@@ -XXX,XX +XXX,XX @@ int net_init_vhost_user(const Netdev *netdev, const char *name,
20
.help = "add host network device",
32
21
.cmd = hmp_netdev_add,
33
int net_init_vhost_vdpa(const Netdev *netdev, const char *name,
22
.command_completion = netdev_add_completion,
34
NetClientState *peer, Error **errp);
23
+ .flags = "p",
35
+#ifdef CONFIG_VMNET
24
},
36
+int net_init_vmnet_host(const Netdev *netdev, const char *name,
25
37
+ NetClientState *peer, Error **errp);
26
SRST
38
+
27
@@ -XXX,XX +XXX,XX @@ ERST
39
+int net_init_vmnet_shared(const Netdev *netdev, const char *name,
28
.help = "remove host network device",
40
+ NetClientState *peer, Error **errp);
29
.cmd = hmp_netdev_del,
41
+
30
.command_completion = netdev_del_completion,
42
+int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
31
+ .flags = "p",
43
+ NetClientState *peer, Error **errp);
32
},
44
+#endif /* CONFIG_VMNET */
33
45
+
34
SRST
46
#endif /* QEMU_NET_CLIENTS_H */
47
diff --git a/net/meson.build b/net/meson.build
48
index XXXXXXX..XXXXXXX 100644
49
--- a/net/meson.build
50
+++ b/net/meson.build
51
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files(tap_posix))
52
softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('tap-win32.c'))
53
softmmu_ss.add(when: 'CONFIG_VHOST_NET_VDPA', if_true: files('vhost-vdpa.c'))
54
55
+vmnet_files = files(
56
+ 'vmnet-common.m',
57
+ 'vmnet-bridged.m',
58
+ 'vmnet-host.c',
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 */
35
diff --git a/qapi/net.json b/qapi/net.json
239
diff --git a/qapi/net.json b/qapi/net.json
36
index XXXXXXX..XXXXXXX 100644
240
index XXXXXXX..XXXXXXX 100644
37
--- a/qapi/net.json
241
--- a/qapi/net.json
38
+++ b/qapi/net.json
242
+++ b/qapi/net.json
39
@@ -XXX,XX +XXX,XX @@
243
@@ -XXX,XX +XXX,XX @@
40
# <- { "return": {} }
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:
41
#
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
42
##
371
##
43
-{ 'command': 'netdev_add', 'data': 'Netdev', 'boxed': true }
372
{ 'enum': 'NetClientDriver',
44
+{ 'command': 'netdev_add', 'data': 'Netdev', 'boxed': true,
373
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde',
45
+ 'allow-preconfig': true }
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' }] }
46
379
47
##
380
##
48
# @netdev_del:
381
# @Netdev:
49
@@ -XXX,XX +XXX,XX @@
382
@@ -XXX,XX +XXX,XX @@
50
# <- { "return": {} }
383
# Since: 1.2
51
#
384
#
385
# 'l2tpv3' - since 2.1
386
+# 'vmnet-host' - since 7.0
387
+# 'vmnet-shared' - since 7.0
388
+# 'vmnet-bridged' - since 7.0
52
##
389
##
53
-{ 'command': 'netdev_del', 'data': {'id': 'str'} }
390
{ 'union': 'Netdev',
54
+{ 'command': 'netdev_del', 'data': {'id': 'str'},
391
'base': { 'id': 'str', 'type': 'NetClientDriver' },
55
+ 'allow-preconfig': true }
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' } } }
56
404
57
##
405
##
58
# @NetLegacyNicOptions:
406
# @RxState:
59
--
407
--
60
2.7.4
408
2.7.4
61
409
62
410
diff view generated by jsdifflib
1
No user for this helper, let's remove it.
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
Interaction with vmnet.framework in different modes
4
differs only on configuration stage, so we can create
5
common `send`, `receive`, etc. procedures and reuse them.
6
7
vmnet.framework supports iov, but writing more than
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>
3
Signed-off-by: Jason Wang <jasowang@redhat.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
---
24
---
5
include/net/vhost-vdpa.h | 1 -
25
net/vmnet-common.m | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++
6
net/vhost-vdpa.c | 9 ---------
26
net/vmnet-shared.c | 83 +++++++++++++-
7
2 files changed, 10 deletions(-)
27
net/vmnet_int.h | 23 ++++
8
28
3 files changed, 416 insertions(+), 4 deletions(-)
9
diff --git a/include/net/vhost-vdpa.h b/include/net/vhost-vdpa.h
29
30
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
10
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
11
--- a/include/net/vhost-vdpa.h
32
--- a/net/vmnet-common.m
12
+++ b/include/net/vhost-vdpa.h
33
+++ b/net/vmnet-common.m
13
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
14
#define TYPE_VHOST_VDPA "vhost-vdpa"
35
*/
15
36
16
struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc);
37
#include "qemu/osdep.h"
17
-uint64_t vhost_vdpa_get_acked_features(NetClientState *nc);
38
+#include "qemu/main-loop.h"
18
39
+#include "qemu/log.h"
19
extern const int vdpa_feature_bits[];
40
#include "qapi/qapi-types-net.h"
20
41
#include "vmnet_int.h"
21
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
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
22
index XXXXXXX..XXXXXXX 100644
360
index XXXXXXX..XXXXXXX 100644
23
--- a/net/vhost-vdpa.c
361
--- a/net/vmnet-shared.c
24
+++ b/net/vhost-vdpa.c
362
+++ b/net/vmnet-shared.c
25
@@ -XXX,XX +XXX,XX @@ VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
363
@@ -XXX,XX +XXX,XX @@
26
return s->vhost_net;
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)
450
{
451
- error_setg(errp, "vmnet-shared is not implemented yet");
452
- return -1;
453
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
454
+ peer, "vmnet-shared", name);
455
+ xpc_object_t if_desc = create_if_desc(netdev, errp);
456
+
457
+ return vmnet_if_create(nc, if_desc, errp, NULL);
27
}
458
}
28
459
diff --git a/net/vmnet_int.h b/net/vmnet_int.h
29
-uint64_t vhost_vdpa_get_acked_features(NetClientState *nc)
460
index XXXXXXX..XXXXXXX 100644
30
-{
461
--- a/net/vmnet_int.h
31
- VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
462
+++ b/net/vmnet_int.h
32
- assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
463
@@ -XXX,XX +XXX,XX @@
33
- s->acked_features = vhost_net_get_acked_features(s->vhost_net);
464
34
-
465
#include <vmnet/vmnet.h>
35
- return s->acked_features;
466
36
-}
467
+#define VMNET_PACKETS_LIMIT 50
37
-
468
+
38
static int vhost_vdpa_net_check_device_id(struct vhost_net *net)
469
typedef struct VmnetCommonState {
39
{
470
NetClientState nc;
40
uint32_t device_id;
471
+ interface_ref vmnet_if;
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 */
41
--
497
--
42
2.7.4
498
2.7.4
43
499
44
500
diff view generated by jsdifflib
1
This patch implements the vq notification mapping support for
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
vhost-vDPA. This is simply done by using mmap()/munmap() for the
3
vhost-vDPA fd during device start/stop. For the device without
4
notification mapping support, we fall back to eventfd based
5
notification gracefully.
6
2
7
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
5
---
10
hw/virtio/vhost-vdpa.c | 85 ++++++++++++++++++++++++++++++++++++++++++
6
net/vmnet-host.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
11
include/hw/virtio/vhost-vdpa.h | 6 +++
7
1 file changed, 104 insertions(+), 6 deletions(-)
12
2 files changed, 91 insertions(+)
13
8
14
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
9
diff --git a/net/vmnet-host.c b/net/vmnet-host.c
15
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/virtio/vhost-vdpa.c
11
--- a/net/vmnet-host.c
17
+++ b/hw/virtio/vhost-vdpa.c
12
+++ b/net/vmnet-host.c
18
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
13
@@ -XXX,XX +XXX,XX @@
19
return 0;
14
*/
20
}
15
21
16
#include "qemu/osdep.h"
22
+static void vhost_vdpa_host_notifier_uninit(struct vhost_dev *dev,
17
+#include "qemu/uuid.h"
23
+ int queue_index)
18
#include "qapi/qapi-types-net.h"
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)
24
+{
36
+{
25
+ size_t page_size = qemu_real_host_page_size;
37
+ const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
26
+ struct vhost_vdpa *v = dev->opaque;
27
+ VirtIODevice *vdev = dev->vdev;
28
+ VhostVDPAHostNotifier *n;
29
+
38
+
30
+ n = &v->notifier[queue_index];
39
+ xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
31
+
40
+
32
+ if (n->addr) {
41
+ xpc_dictionary_set_uint64(
33
+ virtio_queue_set_host_notifier_mr(vdev, queue_index, &n->mr, false);
42
+ if_desc,
34
+ object_unparent(OBJECT(&n->mr));
43
+ vmnet_operation_mode_key,
35
+ munmap(n->addr, page_size);
44
+ VMNET_HOST_MODE
36
+ n->addr = NULL;
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
+ );
37
+ }
69
+ }
38
+}
70
+#else
39
+
71
+ if (options->has_isolated) {
40
+static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n)
72
+ error_setg(errp,
41
+{
73
+ "vmnet-host.isolated feature is "
42
+ int i;
74
+ "unavailable: outdated vmnet.framework API");
43
+
44
+ for (i = 0; i < n; i++) {
45
+ vhost_vdpa_host_notifier_uninit(dev, i);
46
+ }
47
+}
48
+
49
+static int vhost_vdpa_host_notifier_init(struct vhost_dev *dev, int queue_index)
50
+{
51
+ size_t page_size = qemu_real_host_page_size;
52
+ struct vhost_vdpa *v = dev->opaque;
53
+ VirtIODevice *vdev = dev->vdev;
54
+ VhostVDPAHostNotifier *n;
55
+ int fd = v->device_fd;
56
+ void *addr;
57
+ char *name;
58
+
59
+ vhost_vdpa_host_notifier_uninit(dev, queue_index);
60
+
61
+ n = &v->notifier[queue_index];
62
+
63
+ addr = mmap(NULL, page_size, PROT_WRITE, MAP_SHARED, fd,
64
+ queue_index * page_size);
65
+ if (addr == MAP_FAILED) {
66
+ goto err;
67
+ }
75
+ }
68
+
76
+
69
+ name = g_strdup_printf("vhost-vdpa/host-notifier@%p mmaps[%d]",
77
+ if (options->has_net_uuid) {
70
+ v, queue_index);
78
+ error_setg(errp,
71
+ memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name,
79
+ "vmnet-host.net-uuid feature is "
72
+ page_size, addr);
80
+ "unavailable: outdated vmnet.framework API");
73
+ g_free(name);
81
+ }
82
+#endif
74
+
83
+
75
+ if (virtio_queue_set_host_notifier_mr(vdev, queue_index, &n->mr, true)) {
84
+ if (options->has_start_address ||
76
+ munmap(addr, page_size);
85
+ options->has_end_address ||
77
+ goto err;
86
+ options->has_subnet_mask) {
78
+ }
79
+ n->addr = addr;
80
+
87
+
81
+ return 0;
88
+ if (options->has_start_address &&
89
+ options->has_end_address &&
90
+ options->has_subnet_mask) {
82
+
91
+
83
+err:
92
+ xpc_dictionary_set_string(if_desc,
84
+ return -1;
93
+ vmnet_start_address_key,
85
+}
94
+ options->start_address);
86
+
95
+ xpc_dictionary_set_string(if_desc,
87
+static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)
96
+ vmnet_end_address_key,
88
+{
97
+ options->end_address);
89
+ int i;
98
+ xpc_dictionary_set_string(if_desc,
90
+
99
+ vmnet_subnet_mask_key,
91
+ for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) {
100
+ options->subnet_mask);
92
+ if (vhost_vdpa_host_notifier_init(dev, i)) {
101
+ } else {
93
+ goto err;
102
+ error_setg(
103
+ errp,
104
+ "'start-address', 'end-address', 'subnet-mask' "
105
+ "should be provided together"
106
+ );
94
+ }
107
+ }
95
+ }
108
+ }
96
+
109
+
97
+ return;
110
+ return if_desc;
98
+
99
+err:
100
+ vhost_vdpa_host_notifiers_uninit(dev, i);
101
+ return;
102
+}
111
+}
103
+
112
+
104
static int vhost_vdpa_cleanup(struct vhost_dev *dev)
113
+static NetClientInfo net_vmnet_host_info = {
105
{
114
+ .type = NET_CLIENT_DRIVER_VMNET_HOST,
106
struct vhost_vdpa *v;
115
+ .size = sizeof(VmnetHostState),
107
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
116
+ .receive = vmnet_receive_common,
108
v = dev->opaque;
117
+ .cleanup = vmnet_cleanup_common,
109
trace_vhost_vdpa_cleanup(dev, v);
118
+};
110
+ vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
111
memory_listener_unregister(&v->listener);
112
113
dev->opaque = NULL;
114
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
115
if (started) {
116
uint8_t status = 0;
117
memory_listener_register(&v->listener, &address_space_memory);
118
+ vhost_vdpa_host_notifiers_init(dev);
119
vhost_vdpa_set_vring_ready(dev);
120
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
121
vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
122
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
123
vhost_vdpa_reset_device(dev);
124
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
125
VIRTIO_CONFIG_S_DRIVER);
126
+ vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
127
memory_listener_unregister(&v->listener);
128
129
return 0;
130
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
131
index XXXXXXX..XXXXXXX 100644
132
--- a/include/hw/virtio/vhost-vdpa.h
133
+++ b/include/hw/virtio/vhost-vdpa.h
134
@@ -XXX,XX +XXX,XX @@
135
136
#include "hw/virtio/virtio.h"
137
138
+typedef struct VhostVDPAHostNotifier {
139
+ MemoryRegion mr;
140
+ void *addr;
141
+} VhostVDPAHostNotifier;
142
+
119
+
143
typedef struct vhost_vdpa {
120
int net_init_vmnet_host(const Netdev *netdev, const char *name,
144
int device_fd;
121
- NetClientState *peer, Error **errp) {
145
uint32_t msg_type;
122
- error_setg(errp, "vmnet-host is not implemented yet");
146
MemoryListener listener;
123
- return -1;
147
struct vhost_dev *dev;
124
+ NetClientState *peer, Error **errp)
148
+ VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
125
+{
149
} VhostVDPA;
126
+ NetClientState *nc;
150
127
+ xpc_object_t if_desc;
151
#endif
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);
133
}
152
--
134
--
153
2.7.4
135
2.7.4
154
136
155
137
diff view generated by jsdifflib
1
From: "Rao, Lei" <lei.rao@intel.com>
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
2
3
Use the packet_new_nocopy instead of packet_new in the
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
4
filter-rewriter module. There will be one less memory
5
copy in the processing of each network packet.
6
7
Signed-off-by: Lei Rao <lei.rao@intel.com>
8
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
9
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
5
---
12
net/colo.c | 25 +++++++++++++++++--------
6
net/vmnet-bridged.m | 105 +++++++++++++++++++++++++++++++++++++++++++++++++---
13
net/colo.h | 1 +
7
1 file changed, 100 insertions(+), 5 deletions(-)
14
net/filter-rewriter.c | 3 +--
15
3 files changed, 19 insertions(+), 10 deletions(-)
16
8
17
diff --git a/net/colo.c b/net/colo.c
9
diff --git a/net/vmnet-bridged.m b/net/vmnet-bridged.m
18
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
19
--- a/net/colo.c
11
--- a/net/vmnet-bridged.m
20
+++ b/net/colo.c
12
+++ b/net/vmnet-bridged.m
21
@@ -XXX,XX +XXX,XX @@ void connection_destroy(void *opaque)
13
@@ -XXX,XX +XXX,XX @@
22
14
23
Packet *packet_new(const void *data, int size, int vnet_hdr_len)
15
#include "qemu/osdep.h"
24
{
16
#include "qapi/qapi-types-net.h"
25
- Packet *pkt = g_slice_new(Packet);
17
-#include "vmnet_int.h"
26
+ Packet *pkt = g_slice_new0(Packet);
18
-#include "clients.h"
27
19
-#include "qemu/error-report.h"
28
pkt->data = g_memdup(data, size);
20
#include "qapi/error.h"
29
pkt->size = size;
21
+#include "clients.h"
30
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
22
+#include "vmnet_int.h"
31
pkt->vnet_hdr_len = vnet_hdr_len;
23
32
- pkt->tcp_seq = 0;
24
#include <vmnet/vmnet.h>
33
- pkt->tcp_ack = 0;
25
34
- pkt->seq_end = 0;
26
+typedef struct VmnetBridgedState {
35
- pkt->header_size = 0;
27
+ VmnetCommonState cs;
36
- pkt->payload_size = 0;
28
+} VmnetBridgedState;
37
- pkt->offset = 0;
38
- pkt->flags = 0;
39
+
29
+
40
+ return pkt;
30
+static bool validate_ifname(const char *ifname)
31
+{
32
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
33
+ __block bool match = false;
34
+
35
+ xpc_array_apply(
36
+ shared_if_list,
37
+ ^bool(size_t index, xpc_object_t value) {
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;
41
+}
46
+}
42
+
47
+
43
+/*
48
+static const char *get_valid_ifnames(void)
44
+ * packet_new_nocopy will not copy data, so the caller can't release
45
+ * the data. And it will be released in packet_destroy.
46
+ */
47
+Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len)
48
+{
49
+{
49
+ Packet *pkt = g_slice_new0(Packet);
50
+ xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
51
+ __block char *if_list = NULL;
50
+
52
+
51
+ pkt->data = data;
53
+ xpc_array_apply(
52
+ pkt->size = size;
54
+ shared_if_list,
53
+ pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
55
+ ^bool(size_t index, xpc_object_t value) {
54
+ pkt->vnet_hdr_len = vnet_hdr_len;
56
+ if_list = g_strconcat(xpc_string_get_string_ptr(value),
55
57
+ " ",
56
return pkt;
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)
114
{
115
- error_setg(errp, "vmnet-bridged is not implemented yet");
116
- return -1;
117
+ NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
118
+ peer, "vmnet-bridged", name);
119
+ xpc_object_t if_desc = create_if_desc(netdev, errp);;
120
+
121
+ if (!if_desc) {
122
+ error_setg(errp,
123
+ "unsupported ifname, should be one of: %s",
124
+ get_valid_ifnames());
125
+ return -1;
126
+ }
127
+
128
+ return vmnet_if_create(nc, if_desc, errp, NULL);
57
}
129
}
58
diff --git a/net/colo.h b/net/colo.h
59
index XXXXXXX..XXXXXXX 100644
60
--- a/net/colo.h
61
+++ b/net/colo.h
62
@@ -XXX,XX +XXX,XX @@ bool connection_has_tracked(GHashTable *connection_track_table,
63
ConnectionKey *key);
64
void connection_hashtable_reset(GHashTable *connection_track_table);
65
Packet *packet_new(const void *data, int size, int vnet_hdr_len);
66
+Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len);
67
void packet_destroy(void *opaque, void *user_data);
68
void packet_destroy_partial(void *opaque, void *user_data);
69
70
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/net/filter-rewriter.c
73
+++ b/net/filter-rewriter.c
74
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
75
vnet_hdr_len = nf->netdev->vnet_hdr_len;
76
}
77
78
- pkt = packet_new(buf, size, vnet_hdr_len);
79
- g_free(buf);
80
+ pkt = packet_new_nocopy(buf, size, vnet_hdr_len);
81
82
/*
83
* if we get tcp packet
84
--
130
--
85
2.7.4
131
2.7.4
86
132
87
133
diff view generated by jsdifflib
1
We used to initialize backend_features during vhost_vdpa_init()
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
regardless whether or not it was supported by vhost. This will lead
3
the unsupported features like VIRTIO_F_IN_ORDER to be included and set
4
to the vhost-vdpa during vhost_dev_start. Because the
5
VIRTIO_F_IN_ORDER is not supported by vhost-vdpa so it won't be
6
advertised to guest which will break the datapath.
7
2
8
Fix this by not initializing the backend_features, so the
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
9
acked_features could be built only from guest features via
10
vhost_net_ack_features().
11
12
Fixes: 108a64818e69b ("vhost-vdpa: introduce vhost-vdpa backend")
13
Cc: qemu-stable@nongnu.org
14
Cc: Gautam Dawar <gdawar@xilinx.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
---
5
---
17
hw/virtio/vhost-vdpa.c | 3 ---
6
qemu-options.hx | 25 +++++++++++++++++++++++++
18
1 file changed, 3 deletions(-)
7
1 file changed, 25 insertions(+)
19
8
20
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
9
diff --git a/qemu-options.hx b/qemu-options.hx
21
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/virtio/vhost-vdpa.c
11
--- a/qemu-options.hx
23
+++ b/hw/virtio/vhost-vdpa.c
12
+++ b/qemu-options.hx
24
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
13
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
25
static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
14
"-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n"
26
{
15
" configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n"
27
struct vhost_vdpa *v;
16
#endif
28
- uint64_t features;
17
+#ifdef CONFIG_VMNET
29
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
18
+ "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n"
30
trace_vhost_vdpa_init(dev, opaque);
19
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
31
20
+ " configure a vmnet network backend in host mode with ID 'str',\n"
32
v = opaque;
21
+ " isolate this interface from others with 'isolated',\n"
33
v->dev = dev;
22
+ " configure the address range and choose a subnet mask,\n"
34
dev->opaque = opaque ;
23
+ " specify network UUID 'uuid' to disable DHCP and interact with\n"
35
- vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
24
+ " vmnet-host interfaces within this isolated network\n"
36
- dev->backend_features = features;
25
+ "-netdev vmnet-shared,id=str[,isolated=on|off][,nat66-prefix=addr]\n"
37
v->listener = vhost_vdpa_memory_listener;
26
+ " [,start-address=addr,end-address=addr,subnet-mask=mask]\n"
38
v->msg_type = VHOST_IOTLB_MSG_V2;
27
+ " configure a vmnet network backend in shared mode with ID 'str',\n"
39
28
+ " configure the address range and choose a subnet mask,\n"
29
+ " set IPv6 ULA prefix (of length 64) to use for internal network,\n"
30
+ " isolate this interface from others with 'isolated'\n"
31
+ "-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]\n"
32
+ " configure a vmnet network backend in bridged mode with ID 'str',\n"
33
+ " use 'ifname=name' to select a physical network interface to be bridged,\n"
34
+ " isolate this interface from others with 'isolated'\n"
35
+#endif
36
"-netdev hubport,id=str,hubid=n[,netdev=nd]\n"
37
" configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL)
38
DEF("nic", HAS_ARG, QEMU_OPTION_nic,
39
@@ -XXX,XX +XXX,XX @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
40
#ifdef CONFIG_POSIX
41
"vhost-user|"
42
#endif
43
+#ifdef CONFIG_VMNET
44
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
45
+#endif
46
"socket][,option][,...][mac=macaddr]\n"
47
" initialize an on-board / default host NIC (using MAC address\n"
48
" macaddr) and connect it to the given host network backend\n"
49
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
50
#ifdef CONFIG_NETMAP
51
"netmap|"
52
#endif
53
+#ifdef CONFIG_VMNET
54
+ "vmnet-host|vmnet-shared|vmnet-bridged|"
55
+#endif
56
"socket][,option][,option][,...]\n"
57
" old way to initialize a host network interface\n"
58
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
40
--
59
--
41
2.7.4
60
2.7.4
42
61
43
62
diff view generated by jsdifflib
1
vDPA is not tie to any specific hardware, for safety and simplicity,
1
From: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
2
vhost-vDPA doesn't allow MMIO area to be mapped via IOTLB. Only the
3
doorbell could be mapped via mmap(). So this patch exclude skip the
4
ram device from the IOTLB mapping.
5
2
6
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
3
Signed-off-by: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
5
---
9
hw/virtio/vhost-vdpa.c | 12 ++----------
6
MAINTAINERS | 5 +++++
10
1 file changed, 2 insertions(+), 10 deletions(-)
7
1 file changed, 5 insertions(+)
11
8
12
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
9
diff --git a/MAINTAINERS b/MAINTAINERS
13
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/virtio/vhost-vdpa.c
11
--- a/MAINTAINERS
15
+++ b/hw/virtio/vhost-vdpa.c
12
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
13
@@ -XXX,XX +XXX,XX @@ W: http://info.iet.unipi.it/~luigi/netmap/
17
{
14
S: Maintained
18
return (!memory_region_is_ram(section->mr) &&
15
F: net/netmap.c
19
!memory_region_is_iommu(section->mr)) ||
16
20
+ /* vhost-vDPA doesn't allow MMIO to be mapped */
17
+Apple vmnet network backends
21
+ memory_region_is_ram_device(section->mr) ||
18
+M: Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
22
/*
19
+S: Maintained
23
* Sizing an enabled 64-bit BAR can cause spurious mappings to
20
+F: net/vmnet*
24
* addresses in the upper part of the 64-bit address space. These
21
+
25
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
22
Host Memory Backends
26
vaddr, section->readonly);
23
M: David Hildenbrand <david@redhat.com>
27
if (ret) {
24
M: Igor Mammedov <imammedo@redhat.com>
28
error_report("vhost vdpa map fail!");
29
- if (memory_region_is_ram_device(section->mr)) {
30
- /* Allow unexpected mappings not to be fatal for RAM devices */
31
- error_report("map ram fail!");
32
- return ;
33
- }
34
goto fail;
35
}
36
37
return;
38
39
fail:
40
- if (memory_region_is_ram_device(section->mr)) {
41
- error_report("failed to vdpa_dma_map. pci p2p may not work");
42
- return;
43
-
44
- }
45
/*
46
* On the initfn path, store the first error in the container so we
47
* can gracefully fail. Runtime, there's not much we can do other
48
--
25
--
49
2.7.4
26
2.7.4
50
27
51
28
diff view generated by jsdifflib