From f6cebdb4a5396ba94adf521a297fc87ae039481d Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 21:32:37 +0800 Subject: [PATCH 01/30] bugfix: fix some illegal memory access and memory leak Signed-off-by: yuxiating Signed-off-by: jiangdongxu --- ...illegal-memory-access-and-memory-lea.patch | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 bugfix-fix-some-illegal-memory-access-and-memory-lea.patch diff --git a/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch b/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch new file mode 100644 index 0000000..48c7970 --- /dev/null +++ b/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch @@ -0,0 +1,53 @@ +From 0a0a490c805fadc7191489277e77fbf9688b39ab Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 21:32:37 +0800 +Subject: [PATCH] bugfix: fix some illegal memory access and memory leak + +Signed-off-by: yuxiating +Signed-off-by: jiangdongxu +--- + contrib/elf2dmp/main.c | 1 + + hw/display/cirrus_vga.c | 2 +- + util/range.c | 1 + + 3 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c +index 20b477d582..3f0d1eb709 100644 +--- a/contrib/elf2dmp/main.c ++++ b/contrib/elf2dmp/main.c +@@ -125,6 +125,7 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, + + if (va_space_rw(vs, KdDebuggerDataBlock, kdbg, kdbg_hdr.Size, 0)) { + eprintf("Failed to extract entire KDBG\n"); ++ free(kdbg); + return NULL; + } + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index fdca6ca659..c66ed801ef 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -834,7 +834,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) + word alignment, so we keep them for the next line */ + /* XXX: keep alignment to speed up transfer */ + end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; +- copy_count = s->cirrus_srcptr_end - end_ptr; ++ copy_count = MIN(s->cirrus_srcptr_end - end_ptr, CIRRUS_BLTBUFSIZE); + memmove(s->cirrus_bltbuf, end_ptr, copy_count); + s->cirrus_srcptr = s->cirrus_bltbuf + copy_count; + s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; +diff --git a/util/range.c b/util/range.c +index 098d9d2dc0..83d1a6c302 100644 +--- a/util/range.c ++++ b/util/range.c +@@ -65,6 +65,7 @@ GList *range_list_insert(GList *list, Range *data) + range_extend(l->data, l->next->data); + g_free(l->next->data); + new_l = g_list_delete_link(list, l->next); ++ l->next = NULL; + assert(new_l == list); + } + +-- +2.27.0 + -- Gitee From 423164a16617357a9c6e31103586ee5f3a6582e9 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 22:12:50 +0800 Subject: [PATCH 02/30] bugfix: fix possible memory leak Signed-off-by: caojinhua Signed-off-by: jiangdongxu --- bugfix-fix-possible-memory-leak.patch | 97 +++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 bugfix-fix-possible-memory-leak.patch diff --git a/bugfix-fix-possible-memory-leak.patch b/bugfix-fix-possible-memory-leak.patch new file mode 100644 index 0000000..3e6a611 --- /dev/null +++ b/bugfix-fix-possible-memory-leak.patch @@ -0,0 +1,97 @@ +From 03e7e232a323c45205d3c6ecb7d8e52e7209d9eb Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 22:12:50 +0800 +Subject: [PATCH] bugfix: fix possible memory leak + +Signed-off-by: caojinhua +Signed-off-by: jiangdongxu +--- + migration/savevm.c | 2 ++ + qga/main.c | 18 +++++++++++++----- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/migration/savevm.c b/migration/savevm.c +index d59e976d50..803cd9004d 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1427,6 +1427,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, + ret = vmstate_save(f, se, vmdesc); + if (ret) { + qemu_file_set_error(f, ret); ++ json_writer_free(vmdesc); + return ret; + } + trace_savevm_section_end(se->idstr, se->section_id, 0); +@@ -1443,6 +1444,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, + error_report("%s: bdrv_inactivate_all() failed (%d)", + __func__, ret); + qemu_file_set_error(f, ret); ++ json_writer_free(vmdesc); + return ret; + } + } +diff --git a/qga/main.c b/qga/main.c +index 15fd3a4149..6f09a689ac 100644 +--- a/qga/main.c ++++ b/qga/main.c +@@ -1283,7 +1283,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + if (g_mkdir_with_parents(config->state_dir, S_IRWXU) == -1) { + g_critical("unable to create (an ancestor of) the state directory" + " '%s': %s", config->state_dir, strerror(errno)); +- return NULL; ++ goto failed; + } + #endif + +@@ -1308,7 +1308,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + if (!log_file) { + g_critical("unable to open specified log file: %s", + strerror(errno)); +- return NULL; ++ goto failed; + } + s->log_file = log_file; + } +@@ -1319,7 +1319,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + s->pstate_filepath, + ga_is_frozen(s))) { + g_critical("failed to load persistent state"); +- return NULL; ++ goto failed; + } + + config->blacklist = ga_command_blacklist_init(config->blacklist); +@@ -1340,7 +1340,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + #ifndef _WIN32 + if (!register_signal_handlers()) { + g_critical("failed to register signal handlers"); +- return NULL; ++ goto failed; + } + #endif + +@@ -1353,12 +1353,20 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) + s->wakeup_event = CreateEvent(NULL, TRUE, FALSE, TEXT("WakeUp")); + if (s->wakeup_event == NULL) { + g_critical("CreateEvent failed"); +- return NULL; ++ goto failed; + } + #endif + + ga_state = s; + return s; ++failed: ++ g_free(s->pstate_filepath); ++ g_free(s->state_filepath_isfrozen); ++ if (s->log_file) { ++ fclose(s->log_file); ++ } ++ g_free(s); ++ return NULL; + } + + static void cleanup_agent(GAState *s) +-- +2.27.0 + -- Gitee From 991018cf145144703fb5d91cb67dea7bf6eb0547 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 21:50:28 +0800 Subject: [PATCH 03/30] bugfix: fix eventfds may double free when vm_id reused in ivshmem As the ivshmem Server-Client Protol describes, when a client disconnects from the server, server sends disconnect notifications to the other clients. And the other clients will free the eventfds of the disconnected client according to the client ID. If the client ID is reused, the eventfds may be double freed. It will be solved by setting eventfds to NULL after freeing and allocating memory for it when it's used. Signed-off-by: Peng Liang Signed-off-by: jiangdongxu --- ...fds-may-double-free-when-vm_id-reuse.patch | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch diff --git a/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch b/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch new file mode 100644 index 0000000..5802835 --- /dev/null +++ b/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch @@ -0,0 +1,48 @@ +From 02a17066ac3dfb5e53b72b15a80643154990191b Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 21:50:28 +0800 +Subject: [PATCH] bugfix: fix eventfds may double free when vm_id reused in + ivshmem + +As the ivshmem Server-Client Protol describes, when a +client disconnects from the server, server sends disconnect +notifications to the other clients. And the other clients +will free the eventfds of the disconnected client according +to the client ID. If the client ID is reused, the eventfds +may be double freed. + +It will be solved by setting eventfds to NULL after freeing +and allocating memory for it when it's used. + +Signed-off-by: Peng Liang +Signed-off-by: jiangdongxu +--- + hw/misc/ivshmem.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index 1ba4a98377..05f06ed6cf 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -400,6 +400,7 @@ static void close_peer_eventfds(IVShmemState *s, int posn) + } + + g_free(s->peers[posn].eventfds); ++ s->peers[posn].eventfds = NULL; + s->peers[posn].nb_eventfds = 0; + } + +@@ -530,6 +531,10 @@ static void process_msg_connect(IVShmemState *s, uint16_t posn, int fd, + close(fd); + return; + } ++ if (peer->eventfds == NULL) { ++ peer->eventfds = g_new0(EventNotifier, s->vectors); ++ peer->nb_eventfds = 0; ++ } + vector = peer->nb_eventfds++; + + IVSHMEM_DPRINTF("eventfds[%d][%d] = %d\n", posn, vector, fd); +-- +2.27.0 + -- Gitee From fc55fd7a750f51b2c46af18f93233c4718139625 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 21:37:49 +0800 Subject: [PATCH 04/30] block/mirror: fix file-system went to read-only after block-mirror config vm disk with prdm, keep the disk writing data continuously during block-mirror, the file-system will went to read-only after block-mirror, fix it. Signed-off-by: caojinhua Signed-off-by: jiangdongxu --- ...-file-system-went-to-read-only-after.patch | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 block-mirror-fix-file-system-went-to-read-only-after.patch diff --git a/block-mirror-fix-file-system-went-to-read-only-after.patch b/block-mirror-fix-file-system-went-to-read-only-after.patch new file mode 100644 index 0000000..2126e83 --- /dev/null +++ b/block-mirror-fix-file-system-went-to-read-only-after.patch @@ -0,0 +1,32 @@ +From 7448eb87ee59856aa0f0853f2aa5b803c832fccf Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 21:37:49 +0800 +Subject: [PATCH] block/mirror: fix file-system went to read-only after + block-mirror + +config vm disk with prdm, keep the disk writing data continuously +during block-mirror, the file-system will went to read-only after +block-mirror, fix it. + +Signed-off-by: caojinhua +Signed-off-by: jiangdongxu +--- + block/mirror.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/mirror.c b/block/mirror.c +index efec2c7674..b7f0cba9b9 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -1640,7 +1640,7 @@ static BlockJob *mirror_start_job( + * reads on the top, while disabling it in the intermediate nodes, and make + * the backing chain writable. */ + mirror_top_bs = bdrv_new_open_driver(&bdrv_mirror_top, filter_node_name, +- BDRV_O_RDWR, errp); ++ BDRV_O_RDWR | BDRV_O_NOCACHE, errp); + if (mirror_top_bs == NULL) { + return NULL; + } +-- +2.27.0 + -- Gitee From 1d0ccd26c4a418b7406763cbe07ce489336dd734 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 22:42:23 +0800 Subject: [PATCH 05/30] bugfix: fix mmio information leak and ehci vm escape 0-day vulnerability Signed-off-by: Yutao Ai Signed-off-by: jiangdongxu --- ...information-leak-and-ehci-vm-escape-.patch | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch diff --git a/bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch b/bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch new file mode 100644 index 0000000..f463c6b --- /dev/null +++ b/bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch @@ -0,0 +1,67 @@ +From f14ea0bd2596f94ad926009411b8ffda9c2c2cda Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 22:42:23 +0800 +Subject: [PATCH] bugfix: fix mmio information leak and ehci vm escape 0-day + vulnerability + +Signed-off-by: Yutao Ai +Signed-off-by: jiangdongxu +--- + hw/usb/core.c | 20 ++++++++++++++++++-- + hw/usb/hcd-ehci.c | 2 ++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/core.c b/hw/usb/core.c +index 51b36126ca..a62826e051 100644 +--- a/hw/usb/core.c ++++ b/hw/usb/core.c +@@ -206,7 +206,15 @@ static void do_token_in(USBDevice *s, USBPacket *p) + + case SETUP_STATE_DATA: + if (s->setup_buf[0] & USB_DIR_IN) { +- int len = s->setup_len - s->setup_index; ++ int len; ++ if (s->setup_len > sizeof(s->data_buf)) { ++ fprintf(stderr, ++ "usb_generic_handle_packet: ctrl buffer too small do_token_in(%d > %zu)\n", ++ s->setup_len, sizeof(s->data_buf)); ++ p->status = USB_RET_STALL; ++ return; ++ } ++ len = s->setup_len - s->setup_index; + if (len > p->iov.size) { + len = p->iov.size; + } +@@ -244,7 +252,15 @@ static void do_token_out(USBDevice *s, USBPacket *p) + + case SETUP_STATE_DATA: + if (!(s->setup_buf[0] & USB_DIR_IN)) { +- int len = s->setup_len - s->setup_index; ++ int len; ++ if (s->setup_len > sizeof(s->data_buf)) { ++ fprintf(stderr, ++ "usb_generic_handle_packet: ctrl buffer too small do_token_out(%d > %zu)\n", ++ s->setup_len, sizeof(s->data_buf)); ++ p->status = USB_RET_STALL; ++ return; ++ } ++ len = s->setup_len - s->setup_index; + if (len > p->iov.size) { + len = p->iov.size; + } +diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c +index 6caa7ac6c2..1415107315 100644 +--- a/hw/usb/hcd-ehci.c ++++ b/hw/usb/hcd-ehci.c +@@ -612,6 +612,8 @@ static void ehci_free_queue(EHCIQueue *q, const char *warn) + ehci_trace_guest_bug(q->ehci, warn); + } + QTAILQ_REMOVE(head, q, next); ++ memset(q, 0, sizeof(*q)); ++ *(volatile char *)q = *(volatile char *)q; + g_free(q); + } + +-- +2.27.0 + -- Gitee From 48e84b2a53974b968b444e0d4859174418665494 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 21:41:06 +0800 Subject: [PATCH 06/30] target-i386: Fix the RES memory inc which caused by the coroutine created for better performance, change the POOL_BATCH_SIZE from 64 to 128. Signed-off-by: caojinhua Signed-off-by: jiangdongxu --- ...the-RES-memory-inc-which-caused-by-t.patch | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch diff --git a/target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch b/target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch new file mode 100644 index 0000000..ae16318 --- /dev/null +++ b/target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch @@ -0,0 +1,30 @@ +From 6e070be26502e171fd5d43a128dea99f1d34429b Mon Sep 17 00:00:00 2001 +From: jiangdongxu +Date: Thu, 10 Feb 2022 21:41:06 +0800 +Subject: [PATCH] target-i386: Fix the RES memory inc which caused by the + coroutine created + +for better performance, change the POOL_BATCH_SIZE from 64 to 128. + +Signed-off-by: caojinhua +Signed-off-by: jiangdongxu +--- + util/qemu-coroutine.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c +index 38fb6d3084..b9586d6929 100644 +--- a/util/qemu-coroutine.c ++++ b/util/qemu-coroutine.c +@@ -21,7 +21,7 @@ + #include "block/aio.h" + + enum { +- POOL_BATCH_SIZE = 64, ++ POOL_BATCH_SIZE = 128, + }; + + /** Free list to speed up creation */ +-- +2.27.0 + -- Gitee From b4a7edfa1743312a97219328b2e287c7a2756fbf Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 12 Feb 2022 20:58:45 +0800 Subject: [PATCH 07/30] =?UTF-8?q?spec:=20Update=20patch=20and=20changelog?= =?UTF-8?q?=20with=20!248=20=E3=80=906.2.0=E3=80=91=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B3=84=E9=9C=B2=E5=8F=8A=E9=83=A8=E5=88=86IO=E7=9B=B8?= =?UTF-8?q?=E5=85=B3bugfix=E5=9B=9E=E5=90=88=20=20!248?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bugfix: fix some illegal memory access and memory leak bugfix: fix possible memory leak bugfix: fix eventfds may double free when vm_id reused in ivshmem block/mirror: fix file-system went to read-only after block-mirror bugfix: fix mmio information leak and ehci vm escape 0-day vulnerability target-i386: Fix the RES memory inc which caused by the coroutine created Signed-off-by: Chen Qun --- qemu.spec | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/qemu.spec b/qemu.spec index 03fa178..625e54d 100644 --- a/qemu.spec +++ b/qemu.spec @@ -137,6 +137,12 @@ Patch0124: vfio-Add-vfio_prereg_listener_global_log_start-stop-.patch Patch0125: hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch Patch0126: vfio-common-Fix-incorrect-address-alignment-in-vfio_.patch Patch0127: vfio-common-Add-address-alignment-check-in-vfio_list.patch +Patch0128: bugfix-fix-some-illegal-memory-access-and-memory-lea.patch +Patch0129: bugfix-fix-possible-memory-leak.patch +Patch0130: bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch +Patch0131: block-mirror-fix-file-system-went-to-read-only-after.patch +Patch0132: bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch +Patch0133: target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch BuildRequires: flex BuildRequires: gcc @@ -581,6 +587,14 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat Feb 12 2022 Chen Qun +- bugfix: fix some illegal memory access and memory leak +- bugfix: fix possible memory leak +- bugfix: fix eventfds may double free when vm_id reused in ivshmem +- block/mirror: fix file-system went to read-only after block-mirror +- bugfix: fix mmio information leak and ehci vm escape 0-day vulnerability +- target-i386: Fix the RES memory inc which caused by the coroutine created + * Sat Feb 12 2022 Chen Qun - linux-headers: update against 5.10 and manual clear vfio dirty log series - vfio: Maintain DMA mapping range for the container -- Gitee From af8ca98d766b6b40356f5c7114cdded6a6b2d236 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Wed, 9 Feb 2022 19:58:21 +0800 Subject: [PATCH 08/30] virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk with dataplane The vm will trigger a disk sweep operation after plugging a controller who's io type is iothread. If attach a scsi disk immediately, the sg_inqury request in vm will trigger the assert in virtio_scsi_ctx_check(), which is called by virtio_scsi_handle_cmd_req_prepare(). Add judgment in virtio_scsi_handle_cmd_req_prepare() and return IO Error directly if the device has not been initialized. Signed-off-by: Jinhua Cao --- ...ix-fix-qemu-crash-for-hotplug-scsi-d.patch | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch diff --git a/virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch b/virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch new file mode 100644 index 0000000..bca7db0 --- /dev/null +++ b/virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch @@ -0,0 +1,37 @@ +From 98cbb6d13484e79b6f9da064a40a281f2983be1d Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Wed, 9 Feb 2022 19:58:21 +0800 +Subject: [PATCH] virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk + with dataplane + +The vm will trigger a disk sweep operation after plugging +a controller who's io type is iothread. If attach a scsi +disk immediately, the sg_inqury request in vm will trigger +the assert in virtio_scsi_ctx_check(), which is called by +virtio_scsi_handle_cmd_req_prepare(). + +Add judgment in virtio_scsi_handle_cmd_req_prepare() and +return IO Error directly if the device has not been +initialized. + +Signed-off-by: Jinhua Cao +--- + hw/scsi/virtio-scsi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c +index 51fd09522a..781a37fe89 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -638,7 +638,7 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) + req->req.cmd.tag, req->req.cmd.cdb[0]); + + d = virtio_scsi_device_get(s, req->req.cmd.lun); +- if (!d) { ++ if (!d || !d->qdev.realized) { + req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; + virtio_scsi_complete_cmd_req(req); + return -ENOENT; +-- +2.27.0 + -- Gitee From be69250e04aed1de703d3678f56b005abf105272 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Wed, 9 Feb 2022 20:27:41 +0800 Subject: [PATCH 09/30] virtio: net-tap: bugfix: del net client if net_init_tap_one failed In net_init_tap_one(), if the net-tap initializes successful but other actions failed during vhost-net hot-plugging, the net-tap will remain in the net clients.causing next hot-plug fails again. Signed-off-by: Jinhua Cao --- ...ugfix-del-net-client-if-net_init_tap.patch | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch diff --git a/virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch b/virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch new file mode 100644 index 0000000..59b7c25 --- /dev/null +++ b/virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch @@ -0,0 +1,76 @@ +From cee545754b44b6283408ec6a43eb0e317c98ebb1 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Wed, 9 Feb 2022 20:27:41 +0800 +Subject: [PATCH] virtio: net-tap: bugfix: del net client if net_init_tap_one + failed + +In net_init_tap_one(), if the net-tap initializes successful +but other actions failed during vhost-net hot-plugging, the +net-tap will remain in the net clients.causing next hot-plug +fails again. + +Signed-off-by: Jinhua Cao +--- + net/tap.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/net/tap.c b/net/tap.c +index c5cbeaa7a2..3f79cd06c2 100644 +--- a/net/tap.c ++++ b/net/tap.c +@@ -684,7 +684,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, + tap_set_sndbuf(s->fd, tap, &err); + if (err) { + error_propagate(errp, err); +- return; ++ goto fail; + } + + if (tap->has_fd || tap->has_fds) { +@@ -726,13 +726,13 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, + } else { + warn_report_err(err); + } +- return; ++ goto fail; + } + ret = qemu_try_set_nonblock(vhostfd); + if (ret < 0) { + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); +- return; ++ goto fail; + } + } else { + vhostfd = open("/dev/vhost-net", O_RDWR); +@@ -744,7 +744,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, + warn_report("tap: open vhost char device failed: %s", + strerror(errno)); + } +- return; ++ goto fail; + } + qemu_set_nonblock(vhostfd); + } +@@ -758,11 +758,17 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, + } else { + warn_report(VHOST_NET_INIT_FAILED); + } +- return; ++ goto fail; + } + } else if (vhostfdname) { + error_setg(errp, "vhostfd(s)= is not valid without vhost"); ++ goto fail; + } ++ ++ return; ++ ++fail: ++ qemu_del_net_client(&s->nc); + } + + static int get_fds(char *str, char *fds[], int max) +-- +2.27.0 + -- Gitee From 1f2ea8bf1c8876a1a5530a912016053c87c7b159 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 10:17:20 +0800 Subject: [PATCH 10/30] virtio: bugfix: clean up callback when del virtqueue We will access NULL pointer as follow: 1. Start a vm with multiqueue vhost-net 2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to trigger multiqueue disable in this vm which will delete the virtqueue. In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh still exist. 3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh will be called and qemu will be crashed. Signed-off-by: Jinhua Cao --- ...clean-up-callback-when-del-virtqueue.patch | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 virtio-bugfix-clean-up-callback-when-del-virtqueue.patch diff --git a/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch b/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch new file mode 100644 index 0000000..c0e259b --- /dev/null +++ b/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch @@ -0,0 +1,52 @@ +From 95d334a905e8ddaac4a8cec908dcdb03b2e5993f Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 10:17:20 +0800 +Subject: [PATCH] virtio: bugfix: clean up callback when del virtqueue + +We will access NULL pointer as follow: +1. Start a vm with multiqueue vhost-net +2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to + trigger multiqueue disable in this vm which will delete the virtqueue. + In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh + still exist. +3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to + notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh + will be called and qemu will be crashed. + +Signed-off-by: Jinhua Cao +--- + hw/net/virtio-net.c | 5 ++++- + hw/virtio/virtio.c | 1 + + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index f2014d5ea0..b3a5d0b19e 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -2644,7 +2644,10 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq) + return; + } + virtio_queue_set_notification(vq, 0); +- qemu_bh_schedule(q->tx_bh); ++ ++ if (q->tx_bh) { ++ qemu_bh_schedule(q->tx_bh); ++ } + } + + static void virtio_net_tx_timer(void *opaque) +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 9b4ac58a16..ec3e96af3b 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2417,6 +2417,7 @@ void virtio_delete_queue(VirtQueue *vq) + { + vq->vring.num = 0; + vq->vring.num_default = 0; ++ vq->vring.align = 0; + vq->handle_output = NULL; + vq->handle_aio_output = NULL; + g_free(vq->used_elems); +-- +2.27.0 + -- Gitee From 4eb44efb541a540d887c85869f83f806e82e45fe Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 10:31:38 +0800 Subject: [PATCH 11/30] virtio-net: bugfix: do not delete netdev before virtio net For the vhost-user net-card, it is allow to delete its network backend while the virtio-net device still exists. However, when the status of the device changes in guest, QEMU will check whether the network backend exists, otherwise it will crash. So do not allowed to delete the network backend directly without delete virtio-net device. Signed-off-by: Jinhua Cao --- ...x-do-not-delete-netdev-before-virtio.patch | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch diff --git a/virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch b/virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch new file mode 100644 index 0000000..c328f9e --- /dev/null +++ b/virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch @@ -0,0 +1,38 @@ +From 532566ba64b60f2dd2f8ff41d670712ccafe1e98 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 10:31:38 +0800 +Subject: [PATCH] virtio-net: bugfix: do not delete netdev before virtio net + +For the vhost-user net-card, it is allow to delete its +network backend while the virtio-net device still exists. +However, when the status of the device changes in guest, +QEMU will check whether the network backend exists, otherwise +it will crash. +So do not allowed to delete the network backend directly +without delete virtio-net device. + +Signed-off-by: Jinhua Cao +--- + net/net.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/net.c b/net/net.c +index f0d14dbfc1..ed4b1c1740 100644 +--- a/net/net.c ++++ b/net/net.c +@@ -1202,6 +1202,12 @@ void qmp_netdev_del(const char *id, Error **errp) + return; + } + ++ if (nc->info->type == NET_CLIENT_DRIVER_VHOST_USER && nc->peer) { ++ error_setg(errp, "Device '%s' is a netdev for vhostuser," ++ "please delete the peer front-end device (virtio-net) first.", id); ++ return; ++ } ++ + qemu_del_net_client(nc); + + /* +-- +2.27.0 + -- Gitee From 0c1ffff3eb4e169a4deae6db4bf9a25274162bd6 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 10:48:27 +0800 Subject: [PATCH 12/30] virtio-net: fix max vring buf size when set ring num Signed-off-by: Jinhua Cao --- ...max-vring-buf-size-when-set-ring-num.patch | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch diff --git a/virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch b/virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch new file mode 100644 index 0000000..8e2af0c --- /dev/null +++ b/virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch @@ -0,0 +1,50 @@ +From 318f0eda68554af0c779e5374f16bf8cdb895fe7 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 10:48:27 +0800 +Subject: [PATCH] virtio-net: fix max vring buf size when set ring num + +Signed-off-by: Jinhua Cao +--- + hw/virtio/virtio.c | 9 +++++++-- + include/hw/virtio/virtio.h | 1 + + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index ec3e96af3b..03afa36e99 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2241,12 +2241,17 @@ void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc, + + void virtio_queue_set_num(VirtIODevice *vdev, int n, int num) + { ++ int vq_max_size = VIRTQUEUE_MAX_SIZE; ++ ++ if (!strcmp(vdev->name, "virtio-net")) { ++ vq_max_size = VIRTIO_NET_VQ_MAX_SIZE; ++ } ++ + /* Don't allow guest to flip queue between existent and + * nonexistent states, or to set it to an invalid size. + */ + if (!!num != !!vdev->vq[n].vring.num || +- num > VIRTQUEUE_MAX_SIZE || +- num < 0) { ++ num > vq_max_size || num < 0) { + return; + } + vdev->vq[n].vring.num = num; +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index 8bab9cfb75..b3749ce34b 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -49,6 +49,7 @@ size_t virtio_feature_get_config_size(const VirtIOFeature *features, + typedef struct VirtQueue VirtQueue; + + #define VIRTQUEUE_MAX_SIZE 1024 ++#define VIRTIO_NET_VQ_MAX_SIZE (4096) + + typedef struct VirtQueueElement + { +-- +2.27.0 + -- Gitee From c9a501c67ed4fdf8dec577b300e207d32b10ea21 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 11:09:36 +0800 Subject: [PATCH 13/30] virtio: check descriptor numbers Check if the vring num is normal in virtio_save(), and add LOG the vm push the wrong viring num down through writing IO Port. Signed-off-by: Jinhua Cao --- virtio-check-descriptor-numbers.patch | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 virtio-check-descriptor-numbers.patch diff --git a/virtio-check-descriptor-numbers.patch b/virtio-check-descriptor-numbers.patch new file mode 100644 index 0000000..ea38103 --- /dev/null +++ b/virtio-check-descriptor-numbers.patch @@ -0,0 +1,52 @@ +From 9e04e1c6a7a12e3e1d0a8a7cf07f441597a1dbb7 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 11:09:36 +0800 +Subject: [PATCH] virtio: check descriptor numbers + +Check if the vring num is normal in virtio_save(), and add LOG +the vm push the wrong viring num down through writing IO Port. + +Signed-off-by: Jinhua Cao +--- + hw/virtio/virtio.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 03afa36e99..007f4c9e26 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2860,6 +2860,22 @@ static const VMStateDescription vmstate_virtio = { + } + }; + ++static void check_vring_avail_num(VirtIODevice *vdev, int index) ++{ ++ uint16_t nheads; ++ ++ /* Check it isn't doing strange things with descriptor numbers. */ ++ nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; ++ if (nheads > vdev->vq[index].vring.num) { ++ qemu_log("VQ %d size 0x%x Guest index 0x%x " ++ "inconsistent with Host index 0x%x: " ++ "delta 0x%x\n", ++ index, vdev->vq[index].vring.num, ++ vring_avail_idx(&vdev->vq[index]), ++ vdev->vq[index].last_avail_idx, nheads); ++ } ++} ++ + int virtio_save(VirtIODevice *vdev, QEMUFile *f) + { + BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); +@@ -2890,6 +2906,8 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f) + if (vdev->vq[i].vring.num == 0) + break; + ++ check_vring_avail_num(vdev, i); ++ + qemu_put_be32(f, vdev->vq[i].vring.num); + if (k->has_variable_vring_alignment) { + qemu_put_be32(f, vdev->vq[i].vring.align); +-- +2.27.0 + -- Gitee From d0609c346dea49deb258c54a749f8b4257b3f89c Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 11:16:26 +0800 Subject: [PATCH 14/30] virtio: bugfix: add rcu_read_lock when vring_avail_idx is called viring_avail_idx should be called within rcu_read_lock(), or may get NULL caches in vring_get_region_caches() and trigger assert(). Signed-off-by: Jinhua Cao --- ...d-rcu_read_lock-when-vring_avail_idx.patch | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch diff --git a/virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch b/virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch new file mode 100644 index 0000000..39551a7 --- /dev/null +++ b/virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch @@ -0,0 +1,38 @@ +From 41aa66e37d04246d48b5417c57967425ecc466a0 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 11:16:26 +0800 +Subject: [PATCH] virtio: bugfix: add rcu_read_lock when vring_avail_idx is + called + +viring_avail_idx should be called within rcu_read_lock(), +or may get NULL caches in vring_get_region_caches() and +trigger assert(). + +Signed-off-by: Jinhua Cao +--- + hw/virtio/virtio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 007f4c9e26..0af9684881 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2864,6 +2864,7 @@ static void check_vring_avail_num(VirtIODevice *vdev, int index) + { + uint16_t nheads; + ++ rcu_read_lock(); + /* Check it isn't doing strange things with descriptor numbers. */ + nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; + if (nheads > vdev->vq[index].vring.num) { +@@ -2874,6 +2875,7 @@ static void check_vring_avail_num(VirtIODevice *vdev, int index) + vring_avail_idx(&vdev->vq[index]), + vdev->vq[index].last_avail_idx, nheads); + } ++ rcu_read_unlock(); + } + + int virtio_save(VirtIODevice *vdev, QEMUFile *f) +-- +2.27.0 + -- Gitee From 4b35e5096dacb799c900ba0fc34b940043936cba Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 14:16:17 +0800 Subject: [PATCH 15/30] virtio: print the guest virtio_net features that host does not support Signed-off-by: Jinhua Cao --- ...-guest-virtio_net-features-that-host.patch | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 virtio-print-the-guest-virtio_net-features-that-host.patch diff --git a/virtio-print-the-guest-virtio_net-features-that-host.patch b/virtio-print-the-guest-virtio_net-features-that-host.patch new file mode 100644 index 0000000..5db0434 --- /dev/null +++ b/virtio-print-the-guest-virtio_net-features-that-host.patch @@ -0,0 +1,105 @@ +From 8a08b3b41400e152cc1786ae5a8a53507f8e925c Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 14:16:17 +0800 +Subject: [PATCH] virtio: print the guest virtio_net features that host does + not support + +Signed-off-by: Jinhua Cao +--- + hw/net/virtio-net.c | 41 ++++++++++++++++++++++++++++++++++++++ + hw/virtio/virtio.c | 7 +++++++ + include/hw/virtio/virtio.h | 1 + + 3 files changed, 49 insertions(+) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index b3a5d0b19e..6874c88bc0 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -3692,6 +3692,46 @@ static Property virtio_net_properties[] = { + DEFINE_PROP_END_OF_LIST(), + }; + ++static void virtio_net_print_features(uint64_t features) ++{ ++ Property *props = virtio_net_properties; ++ int feature_cnt = 0; ++ ++ if (!features) { ++ return; ++ } ++ printf("virtio_net_feature: "); ++ ++ for (; features && props->name; props++) { ++ /* The bitnr of property may be default(0) besides 'csum' property. */ ++ if (props->bitnr == 0 && strcmp(props->name, "csum")) { ++ continue; ++ } ++ ++ /* Features only support 64bit. */ ++ if (props->bitnr > 63) { ++ continue; ++ } ++ ++ if (virtio_has_feature(features, props->bitnr)) { ++ virtio_clear_feature(&features, props->bitnr); ++ if (feature_cnt != 0) { ++ printf(", "); ++ } ++ printf("%s", props->name); ++ feature_cnt++; ++ } ++ } ++ ++ if (features) { ++ if (feature_cnt != 0) { ++ printf(", "); ++ } ++ printf("unkown bits 0x%." PRIx64, features); ++ } ++ printf("\n"); ++} ++ + static void virtio_net_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); +@@ -3706,6 +3746,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) + vdc->set_config = virtio_net_set_config; + vdc->get_features = virtio_net_get_features; + vdc->set_features = virtio_net_set_features; ++ vdc->print_features = virtio_net_print_features; + vdc->bad_features = virtio_net_bad_features; + vdc->reset = virtio_net_reset; + vdc->set_status = virtio_net_set_status; +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 0af9684881..9a2a83d507 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2967,6 +2967,13 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) + { + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + bool bad = (val & ~(vdev->host_features)) != 0; ++ uint64_t feat = val & ~(vdev->host_features); ++ ++ if (bad && k->print_features) { ++ qemu_log("error: Please check host config, "\ ++ "because host does not support required feature bits 0x%" PRIx64 "\n", feat); ++ k->print_features(feat); ++ } + + val &= vdev->host_features; + if (k->set_features) { +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index b3749ce34b..7472145821 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -127,6 +127,7 @@ struct VirtioDeviceClass { + int (*validate_features)(VirtIODevice *vdev); + void (*get_config)(VirtIODevice *vdev, uint8_t *config); + void (*set_config)(VirtIODevice *vdev, const uint8_t *config); ++ void (*print_features)(uint64_t features); + void (*reset)(VirtIODevice *vdev); + void (*set_status)(VirtIODevice *vdev, uint8_t val); + /* For transitional devices, this is a bitmap of features +-- +2.27.0 + -- Gitee From 93e3194fa45e84e169cbea0942efef7b2c9f6473 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 14:37:52 +0800 Subject: [PATCH 16/30] virtio: bugfix: check the value of caches before accessing it Vring caches may be NULL in check_vring_avail_num() if virtio_reset() is called at the same time, such as when the virtual machine starts. So check it before accessing it in vring_avail_idx(). Signed-off-by: Jinhua Cao --- ...eck-the-value-of-caches-before-acces.patch | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 virtio-bugfix-check-the-value-of-caches-before-acces.patch diff --git a/virtio-bugfix-check-the-value-of-caches-before-acces.patch b/virtio-bugfix-check-the-value-of-caches-before-acces.patch new file mode 100644 index 0000000..8cead34 --- /dev/null +++ b/virtio-bugfix-check-the-value-of-caches-before-acces.patch @@ -0,0 +1,42 @@ +From 74ab61b4317f12b231fb2cbcd54a333a07efd678 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 14:37:52 +0800 +Subject: [PATCH] virtio: bugfix: check the value of caches before accessing it + +Vring caches may be NULL in check_vring_avail_num() if +virtio_reset() is called at the same time, such as when +the virtual machine starts. +So check it before accessing it in vring_avail_idx(). + +Signed-off-by: Jinhua Cao +--- + hw/virtio/virtio.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 9a2a83d507..b08fff9419 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2863,8 +2863,19 @@ static const VMStateDescription vmstate_virtio = { + static void check_vring_avail_num(VirtIODevice *vdev, int index) + { + uint16_t nheads; ++ VRingMemoryRegionCaches *caches; + + rcu_read_lock(); ++ caches = qatomic_rcu_read(&vdev->vq[index].vring.caches); ++ if (caches == NULL) { ++ /* ++ * caches may be NULL if virtio_reset is called at the same time, ++ * such as when the virtual machine starts. ++ */ ++ rcu_read_unlock(); ++ return; ++ } ++ + /* Check it isn't doing strange things with descriptor numbers. */ + nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; + if (nheads > vdev->vq[index].vring.num) { +-- +2.27.0 + -- Gitee From 2670d4cf40a6c8a28b210407429aef58b1ac9904 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 12 Feb 2022 17:22:38 +0800 Subject: [PATCH 17/30] virtio-net: set the max of queue size to 4096 Signed-off-by: Jinhua Cao --- ...et-set-the-max-of-queue-size-to-4096.patch | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 virtio-net-set-the-max-of-queue-size-to-4096.patch diff --git a/virtio-net-set-the-max-of-queue-size-to-4096.patch b/virtio-net-set-the-max-of-queue-size-to-4096.patch new file mode 100644 index 0000000..de0520e --- /dev/null +++ b/virtio-net-set-the-max-of-queue-size-to-4096.patch @@ -0,0 +1,68 @@ +From 7beaecc21a8a573d43c7ad7604ac77cdf5bbf405 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Sat, 12 Feb 2022 17:22:38 +0800 +Subject: [PATCH] virtio-net: set the max of queue size to 4096 + +Signed-off-by: Jinhua Cao +--- + hw/net/virtio-net.c | 10 +++++----- + hw/virtio/virtio.c | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 6874c88bc0..009dc9f3d1 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -637,7 +637,7 @@ static int virtio_net_max_tx_queue_size(VirtIONet *n) + return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; + } + +- return VIRTQUEUE_MAX_SIZE; ++ return VIRTIO_NET_VQ_MAX_SIZE; + } + + static int peer_attach(VirtIONet *n, int index) +@@ -3394,23 +3394,23 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) + * help from us (using virtio 1 and up). + */ + if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE || +- n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE || ++ n->net_conf.rx_queue_size > VIRTIO_NET_VQ_MAX_SIZE || + !is_power_of_2(n->net_conf.rx_queue_size)) { + error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), " + "must be a power of 2 between %d and %d.", + n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE, +- VIRTQUEUE_MAX_SIZE); ++ VIRTIO_NET_VQ_MAX_SIZE); + virtio_cleanup(vdev); + return; + } + + if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE || +- n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE || ++ n->net_conf.tx_queue_size > VIRTIO_NET_VQ_MAX_SIZE || + !is_power_of_2(n->net_conf.tx_queue_size)) { + error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), " + "must be a power of 2 between %d and %d", + n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE, +- VIRTQUEUE_MAX_SIZE); ++ VIRTIO_NET_VQ_MAX_SIZE); + virtio_cleanup(vdev); + return; + } +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index b08fff9419..120672672e 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2401,7 +2401,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, + break; + } + +- if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) { ++ if (i == VIRTIO_QUEUE_MAX) { + qemu_log("unacceptable queue_size (%d) or num (%d)\n", + queue_size, i); + abort(); +-- +2.27.0 + -- Gitee From 3cd93f57445b8e111882640f410a5337f0a03fdf Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 17:28:49 +0800 Subject: [PATCH 18/30] virtio-net: update the default and max of rx/tx_queue_size Set the max of tx_queue_size to 4096 even if the backends are not vhost-user. Set the default of rx/tx_queue_size to 2048 if the backends are vhost-user, otherwise to 4096. Signed-off-by: Jinhua Cao --- ...e-the-default-and-max-of-rx-tx_queue.patch | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 virtio-net-update-the-default-and-max-of-rx-tx_queue.patch diff --git a/virtio-net-update-the-default-and-max-of-rx-tx_queue.patch b/virtio-net-update-the-default-and-max-of-rx-tx_queue.patch new file mode 100644 index 0000000..0d849f9 --- /dev/null +++ b/virtio-net-update-the-default-and-max-of-rx-tx_queue.patch @@ -0,0 +1,104 @@ +From 88dfb4236c735c608f8ca91cfbfb5ac424d654aa Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 17:28:49 +0800 +Subject: [PATCH] virtio-net: update the default and max of rx/tx_queue_size + +Set the max of tx_queue_size to 4096 even if the backends +are not vhost-user. + +Set the default of rx/tx_queue_size to 2048 if the backends +are vhost-user, otherwise to 4096. + +Signed-off-by: Jinhua Cao +--- + hw/net/virtio-net.c | 41 +++++++++++++++++++++++++++++++---------- + 1 file changed, 31 insertions(+), 10 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 009dc9f3d1..e887589a30 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -51,12 +51,11 @@ + #define MAX_VLAN (1 << 12) /* Per 802.1Q definition */ + + /* previously fixed value */ +-#define VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE 256 +-#define VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE 256 ++#define VIRTIO_NET_VHOST_USER_DEFAULT_SIZE 2048 + + /* for now, only allow larger queue_pairs; with virtio-1, guest can downsize */ +-#define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE +-#define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE ++#define VIRTIO_NET_RX_QUEUE_MIN_SIZE 256 ++#define VIRTIO_NET_TX_QUEUE_MIN_SIZE 256 + + #define VIRTIO_NET_IP4_ADDR_SIZE 8 /* ipv4 saddr + daddr */ + +@@ -622,6 +621,28 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs, + } + } + ++static void virtio_net_set_default_queue_size(VirtIONet *n) ++{ ++ NetClientState *peer = n->nic_conf.peers.ncs[0]; ++ ++ /* Default value is 0 if not set */ ++ if (n->net_conf.rx_queue_size == 0) { ++ if (peer && peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { ++ n->net_conf.rx_queue_size = VIRTIO_NET_VHOST_USER_DEFAULT_SIZE; ++ } else { ++ n->net_conf.rx_queue_size = VIRTIO_NET_VQ_MAX_SIZE; ++ } ++ } ++ ++ if (n->net_conf.tx_queue_size == 0) { ++ if (peer && peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { ++ n->net_conf.tx_queue_size = VIRTIO_NET_VHOST_USER_DEFAULT_SIZE; ++ } else { ++ n->net_conf.tx_queue_size = VIRTIO_NET_VQ_MAX_SIZE; ++ } ++ } ++} ++ + static int virtio_net_max_tx_queue_size(VirtIONet *n) + { + NetClientState *peer = n->nic_conf.peers.ncs[0]; +@@ -630,11 +651,11 @@ static int virtio_net_max_tx_queue_size(VirtIONet *n) + * Backends other than vhost-user don't support max queue size. + */ + if (!peer) { +- return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; ++ return VIRTIO_NET_VQ_MAX_SIZE; + } + + if (peer->info->type != NET_CLIENT_DRIVER_VHOST_USER) { +- return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; ++ return VIRTIO_NET_VQ_MAX_SIZE; + } + + return VIRTIO_NET_VQ_MAX_SIZE; +@@ -3388,6 +3409,8 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) + virtio_net_set_config_size(n, n->host_features); + virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); + ++ virtio_net_set_default_queue_size(n); ++ + /* + * We set a lower limit on RX queue size to what it always was. + * Guests that want a smaller ring can always resize it without +@@ -3679,10 +3702,8 @@ static Property virtio_net_properties[] = { + TX_TIMER_INTERVAL), + DEFINE_PROP_INT32("x-txburst", VirtIONet, net_conf.txburst, TX_BURST), + DEFINE_PROP_STRING("tx", VirtIONet, net_conf.tx), +- DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size, +- VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE), +- DEFINE_PROP_UINT16("tx_queue_size", VirtIONet, net_conf.tx_queue_size, +- VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE), ++ DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size, 0), ++ DEFINE_PROP_UINT16("tx_queue_size", VirtIONet, net_conf.tx_queue_size, 0), + DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0), + DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend, + true), +-- +2.27.0 + -- Gitee From b6e129b43b9aa401563a6c1fd67eda30d2949176 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 20:21:33 +0800 Subject: [PATCH 19/30] vhost-user: add unregister_savevm when vhost-user cleanup Signed-off-by: Jinhua Cao --- ...nregister_savevm-when-vhost-user-cle.patch | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 vhost-user-add-unregister_savevm-when-vhost-user-cle.patch diff --git a/vhost-user-add-unregister_savevm-when-vhost-user-cle.patch b/vhost-user-add-unregister_savevm-when-vhost-user-cle.patch new file mode 100644 index 0000000..95488a2 --- /dev/null +++ b/vhost-user-add-unregister_savevm-when-vhost-user-cle.patch @@ -0,0 +1,33 @@ +From a9459c849c5484a022f67a317b72de764c84c845 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 20:21:33 +0800 +Subject: [PATCH] vhost-user: add unregister_savevm when vhost-user cleanup + +Signed-off-by: Jinhua Cao +--- + hw/virtio/vhost-user.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index bf6e50223c..c265e9e92c 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -24,6 +24,7 @@ + #include "sysemu/cryptodev.h" + #include "migration/migration.h" + #include "migration/postcopy-ram.h" ++#include "migration/register.h" + #include "trace.h" + + #include +@@ -2068,6 +2069,7 @@ static int vhost_user_backend_cleanup(struct vhost_dev *dev) + u->region_rb_len = 0; + g_free(u); + dev->opaque = 0; ++ unregister_savevm(NULL, "vhost-user", dev); + + return 0; + } +-- +2.27.0 + -- Gitee From eec1d28be6c65120b3d30860a9affc84dc9efeb5 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 14:25:39 +0800 Subject: [PATCH 20/30] qemu-img: block: dont blk_make_zero if discard_zeroes false Signed-off-by: Jinhua Cao --- ...ont-blk_make_zero-if-discard_zeroes-.patch | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch diff --git a/qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch b/qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch new file mode 100644 index 0000000..c96e5b4 --- /dev/null +++ b/qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch @@ -0,0 +1,26 @@ +From 724134432ef21f1fb2b18bbe55b891d31181ccca Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 14:25:39 +0800 +Subject: [PATCH] qemu-img: block: dont blk_make_zero if discard_zeroes false + +Signed-off-by: Jinhua Cao +--- + block/file-posix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index b283093e5b..aed7529f44 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -804,7 +804,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, + } + #endif + +- bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK; ++ bs->supported_zero_flags = s->discard_zeroes ? (BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) : 0; + if (S_ISREG(st.st_mode)) { + /* When extending regular files, we get zeros from the OS */ + bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE; +-- +2.27.0 + -- Gitee From a884586654e05dd94505bebfef591c88779d74d0 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 18:05:47 +0800 Subject: [PATCH 21/30] vhost-user: Add support reconnect vhost-user socket Add support reconnect vhost-user socket, the reconnect time is set to be 3 seconds. Signed-off-by: Jinhua Cao --- ...-support-reconnect-vhost-user-socket.patch | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 vhost-user-Add-support-reconnect-vhost-user-socket.patch diff --git a/vhost-user-Add-support-reconnect-vhost-user-socket.patch b/vhost-user-Add-support-reconnect-vhost-user-socket.patch new file mode 100644 index 0000000..cbe49c2 --- /dev/null +++ b/vhost-user-Add-support-reconnect-vhost-user-socket.patch @@ -0,0 +1,168 @@ +From 3a223111d71307eb4fdc18f5ee46ce3d6cb57660 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 18:05:47 +0800 +Subject: [PATCH] vhost-user: Add support reconnect vhost-user socket + +Add support reconnect vhost-user socket, the reconnect time +is set to be 3 seconds. + +Signed-off-by: Jinhua Cao +--- + chardev/char-socket.c | 19 ++++++++++++++++++- + hw/net/vhost_net.c | 4 +++- + hw/virtio/vhost-user.c | 6 ++++++ + include/chardev/char.h | 16 ++++++++++++++++ + net/vhost-user.c | 3 +++ + 5 files changed, 46 insertions(+), 2 deletions(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 836cfa0bc2..b1e9f43ec6 100644 +--- a/chardev/char-socket.c ++++ b/chardev/char-socket.c +@@ -393,6 +393,22 @@ static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond) + return qio_channel_create_watch(s->ioc, cond); + } + ++static void tcp_chr_set_reconnect_time(Chardev *chr, ++ int64_t reconnect_time) ++{ ++ SocketChardev *s = SOCKET_CHARDEV(chr); ++ s->reconnect_time = reconnect_time; ++} ++ ++void qemu_chr_set_reconnect_time(Chardev *chr, int64_t reconnect_time) ++{ ++ ChardevClass *cc = CHARDEV_GET_CLASS(chr); ++ ++ if (cc->chr_set_reconnect_time) { ++ cc->chr_set_reconnect_time(chr, reconnect_time); ++ } ++} ++ + static void remove_hup_source(SocketChardev *s) + { + if (s->hup_source != NULL) { +@@ -591,7 +607,7 @@ static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len) + if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) { + qio_channel_set_blocking(s->ioc, false, NULL); + } +- if (size == 0) { ++ if (size == 0 && chr->chr_for_flag != CHR_FOR_VHOST_USER) { + /* connection closed */ + tcp_chr_disconnect(chr); + } +@@ -1585,6 +1601,7 @@ static void char_socket_class_init(ObjectClass *oc, void *data) + cc->set_msgfds = tcp_set_msgfds; + cc->chr_add_client = tcp_chr_add_client; + cc->chr_add_watch = tcp_chr_add_watch; ++ cc->chr_set_reconnect_time = tcp_chr_set_reconnect_time; + cc->chr_update_read_handler = tcp_chr_update_read_handler; + + object_class_property_add(oc, "addr", "SocketAddress", +diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c +index 30379d2ca4..a60f7cef9a 100644 +--- a/hw/net/vhost_net.c ++++ b/hw/net/vhost_net.c +@@ -376,7 +376,9 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, + goto err_start; + } + +- if (peer->vring_enable) { ++ /* ovs needs to restore all states of vring */ ++ if (peer->vring_enable || ++ ncs[i].peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { + /* restore vring enable state */ + r = vhost_set_vring_enable(peer, peer->vring_enable); + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index c265e9e92c..fc2b1b81c9 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -1926,9 +1926,15 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, + uint64_t features, protocol_features, ram_slots; + struct vhost_user *u; + int err; ++ Chardev *chr; + + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); + ++ chr = qemu_chr_fe_get_driver(((VhostUserState *)opaque)->chr); ++ if (chr) { ++ chr->chr_for_flag = CHR_FOR_VHOST_USER; ++ } ++ + u = g_new0(struct vhost_user, 1); + u->user = opaque; + u->dev = dev; +diff --git a/include/chardev/char.h b/include/chardev/char.h +index a319b5fdff..f388d4b109 100644 +--- a/include/chardev/char.h ++++ b/include/chardev/char.h +@@ -14,6 +14,8 @@ + #define IAC_SB 250 + #define IAC 255 + ++#define CHR_FOR_VHOST_USER 0x32a1 ++ + /* character device */ + typedef struct CharBackend CharBackend; + +@@ -70,6 +72,7 @@ struct Chardev { + GSource *gsource; + GMainContext *gcontext; + DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); ++ int chr_for_flag; + }; + + /** +@@ -227,6 +230,16 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all); + #define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true) + int qemu_chr_wait_connected(Chardev *chr, Error **errp); + ++/** ++ * @qemu_chr_set_reconnect_time: ++ * ++ * Set reconnect time for char disconnect. ++ * Currently, only vhost user will call it. ++ * ++ * @reconnect_time the reconnect_time to be set ++ */ ++void qemu_chr_set_reconnect_time(Chardev *chr, int64_t reconnect_time); ++ + #define TYPE_CHARDEV "chardev" + OBJECT_DECLARE_TYPE(Chardev, ChardevClass, CHARDEV) + +@@ -306,6 +319,9 @@ struct ChardevClass { + + /* handle various events */ + void (*chr_be_event)(Chardev *s, QEMUChrEvent event); ++ ++ /* set reconnect time */ ++ void (*chr_set_reconnect_time)(Chardev *chr, int64_t reconnect_time); + }; + + Chardev *qemu_chardev_new(const char *id, const char *typename, +diff --git a/net/vhost-user.c b/net/vhost-user.c +index b1a0247b59..d1aefcb9aa 100644 +--- a/net/vhost-user.c ++++ b/net/vhost-user.c +@@ -21,6 +21,8 @@ + #include "qemu/option.h" + #include "trace.h" + ++#define VHOST_USER_RECONNECT_TIME (3) ++ + typedef struct NetVhostUserState { + NetClientState nc; + CharBackend chr; /* only queue index 0 */ +@@ -287,6 +289,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event) + trace_vhost_user_event(chr->label, event); + switch (event) { + case CHR_EVENT_OPENED: ++ qemu_chr_set_reconnect_time(chr, VHOST_USER_RECONNECT_TIME); + if (vhost_user_start(queues, ncs, s->vhost_user) < 0) { + qemu_chr_fe_disconnect(&s->chr); + return; +-- +2.27.0 + -- Gitee From b864a3041c0cdfb76716a1be19482b9ebb17fab5 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 18:49:21 +0800 Subject: [PATCH 22/30] vhost-user: Set the acked_features to vm's featrue Fix the problem when vm restart, the ovs restart and lead to the net unreachable. The soluation is set the acked_features to vm's featrue just the same as guest virtio-net mod load. Signed-off-by: Jinhua Cao --- ...t-the-acked_features-to-vm-s-featrue.patch | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 vhost-user-Set-the-acked_features-to-vm-s-featrue.patch diff --git a/vhost-user-Set-the-acked_features-to-vm-s-featrue.patch b/vhost-user-Set-the-acked_features-to-vm-s-featrue.patch new file mode 100644 index 0000000..63c0353 --- /dev/null +++ b/vhost-user-Set-the-acked_features-to-vm-s-featrue.patch @@ -0,0 +1,96 @@ +From 12af29806ba8ede96567e4df9223f0c02669727c Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 18:49:21 +0800 +Subject: [PATCH] vhost-user: Set the acked_features to vm's featrue + +Fix the problem when vm restart, the ovs restart and lead to the net +unreachable. The soluation is set the acked_features to vm's featrue +just the same as guest virtio-net mod load. + +Signed-off-by: Jinhua Cao +--- + hw/net/vhost_net.c | 58 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 57 insertions(+), 1 deletion(-) + +diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c +index a60f7cef9a..e8a79db94d 100644 +--- a/hw/net/vhost_net.c ++++ b/hw/net/vhost_net.c +@@ -152,9 +152,26 @@ static int vhost_net_get_fd(NetClientState *backend) + } + } + ++static uint64_t vhost_get_mask_features(const int *feature_bits, uint64_t features) ++{ ++ const int *bit = feature_bits; ++ uint64_t out_features = 0; ++ ++ while (*bit != VHOST_INVALID_FEATURE_BIT) { ++ uint64_t bit_mask = (1ULL << *bit); ++ if (features & bit_mask) { ++ out_features |= bit_mask; ++ } ++ bit++; ++ } ++ return out_features; ++} ++ + struct vhost_net *vhost_net_init(VhostNetOptions *options) + { + int r; ++ VirtIONet *n; ++ VirtIODevice *vdev; + bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL; + struct vhost_net *net = g_new0(struct vhost_net, 1); + uint64_t features = 0; +@@ -180,7 +197,46 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) + net->backend = r; + net->dev.protocol_features = 0; + } else { +- net->dev.backend_features = 0; ++ /* for ovs restart when vm start. ++ * Normal situation: ++ * 1.vm start. ++ * 2.vhost_net_init init ok, then dev.acked_features is 0x40000000. ++ * 3.guest virtio-net mod load. qemu will call virtio_net_set_features set ++ * dev.acked_features to 0x40408000. ++ * 4.feature set to ovs's vhostuser(0x40408000). ++ * 5.ovs restart. ++ * 6.vhost_user_stop will save net->dev.acked_features(0x40408000) to ++ * VhostUserState's acked_features(0x40408000). ++ * 7.restart ok. ++ * 8.vhost_net_init fun call vhost_user_get_acked_features get the save ++ * features, and set to net->dev.acked_features. ++ * Abnormal situation: ++ * 1.vm start. ++ * 2.vhost_net_init init ok, then dev.acked_features is 0x40000000. ++ * 3.ovs restart. ++ * 4.vhost_user_stop will save net->dev.acked_features(0x40000000) to ++ * VhostUserState's acked_features(0x40000000). ++ * 5.guest virtio-net mod load. qemu will call virtio_net_set_features set ++ * dev.acked_features to 0x40408000. ++ * 6.restart ok. ++ * 7.vhost_net_init fun call vhost_user_get_acked_features get the save ++ * features(0x40000000), and set to net->dev.acked_features(0x40000000). ++ * 8.feature set to ovs's vhostuser(0x40000000). ++ * ++ * in abnormal situation, qemu set the wrong features to ovs's vhostuser, ++ * then the vm's network will be down. ++ * in abnormal situation, we found it just lost the guest feartures in ++ * acked_features, so hear we set the acked_features to vm's featrue ++ * just the same as guest virtio-net mod load. ++ */ ++ if (options->net_backend->peer) { ++ n = qemu_get_nic_opaque(options->net_backend->peer); ++ vdev = VIRTIO_DEVICE(n); ++ net->dev.backend_features = vhost_get_mask_features(vhost_net_get_feature_bits(net), ++ vdev->guest_features); ++ } else { ++ net->dev.backend_features = 0; ++ } + net->dev.protocol_features = 0; + net->backend = -1; + +-- +2.27.0 + -- Gitee From 7929b150579995a770e9723cf31b8cdfaef50ada Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 18:59:34 +0800 Subject: [PATCH 23/30] vhost-user: add vhost_set_mem_table when vm load_setup at destination When migrate huge vm, packages lost are 90+. During the load_setup of the destination vm, pass the vm mem structure to ovs, the netcard could be enabled when the migration finish state shifting. Signed-off-by: Jinhua Cao --- ...host_set_mem_table-when-vm-load_setu.patch | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch diff --git a/vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch b/vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch new file mode 100644 index 0000000..fcd6bbf --- /dev/null +++ b/vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch @@ -0,0 +1,61 @@ +From 5c753d539a968f2127ff6e5b916cd4b38a08b40c Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 18:59:34 +0800 +Subject: [PATCH] vhost-user: add vhost_set_mem_table when vm load_setup at + destination + +When migrate huge vm, packages lost are 90+. + +During the load_setup of the destination vm, pass the +vm mem structure to ovs, the netcard could be enabled +when the migration finish state shifting. + +Signed-off-by: Jinhua Cao +--- + hw/virtio/vhost-user.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index fc2b1b81c9..a8feea489b 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -1920,6 +1920,28 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier, + return 0; + } + ++static int vhost_user_load_setup(QEMUFile *f, void *opaque) ++{ ++ struct vhost_dev *hdev = opaque; ++ int r; ++ ++ if (hdev->vhost_ops && hdev->vhost_ops->vhost_set_mem_table) { ++ r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); ++ if (r < 0) { ++ qemu_log("error: vhost_set_mem_table failed: %s(%d)\n", ++ strerror(errno), errno); ++ return r; ++ } else { ++ qemu_log("info: vhost_set_mem_table OK\n"); ++ } ++ } ++ return 0; ++} ++ ++SaveVMHandlers savevm_vhost_user_handlers = { ++ .load_setup = vhost_user_load_setup, ++}; ++ + static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, + Error **errp) + { +@@ -2044,6 +2066,7 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, + + u->postcopy_notifier.notify = vhost_user_postcopy_notifier; + postcopy_add_notifier(&u->postcopy_notifier); ++ register_savevm_live("vhost-user", -1, 1, &savevm_vhost_user_handlers, dev); + + return 0; + } +-- +2.27.0 + -- Gitee From 3c1298a7f1cf9fbdbf38002d03a5c615a17b83fc Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 19:17:59 +0800 Subject: [PATCH 24/30] vhost-user: add separate memslot counter for vhost-user Used_memslots is equal to dev->mem->nregions now, it is true for vhost kernel, but not for vhost user, which uses the memory regions that have file descriptor. In fact, not all of the memory regions have file descriptor. It is usefully in some scenarios, e.g. used_memslots is 8, and only 5 memory slots can be used by vhost user, it is failed to hot plug a new memory RAM because vhost_has_free_slot just returned false, but we can hot plug it safely in fact. Signed-off-by: Jinhua Cao --- ...eparate-memslot-counter-for-vhost-us.patch | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 vhost-user-add-separate-memslot-counter-for-vhost-us.patch diff --git a/vhost-user-add-separate-memslot-counter-for-vhost-us.patch b/vhost-user-add-separate-memslot-counter-for-vhost-us.patch new file mode 100644 index 0000000..d84f830 --- /dev/null +++ b/vhost-user-add-separate-memslot-counter-for-vhost-us.patch @@ -0,0 +1,244 @@ +From 185d7efe768229b43911504f64fccd33ad3650ef Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 19:17:59 +0800 +Subject: [PATCH] vhost-user: add separate memslot counter for vhost-user + +Used_memslots is equal to dev->mem->nregions now, it is true for +vhost kernel, but not for vhost user, which uses the memory regions +that have file descriptor. In fact, not all of the memory regions +have file descriptor. +It is usefully in some scenarios, e.g. used_memslots is 8, and only +5 memory slots can be used by vhost user, it is failed to hot plug +a new memory RAM because vhost_has_free_slot just returned false, +but we can hot plug it safely in fact. + +Signed-off-by: Jinhua Cao +--- + hw/virtio/vhost-backend.c | 14 ++++++++++ + hw/virtio/vhost-user.c | 27 ++++++++++++++++++ + hw/virtio/vhost.c | 46 +++++++++++++++++++++++++------ + include/hw/virtio/vhost-backend.h | 4 +++ + 4 files changed, 82 insertions(+), 9 deletions(-) + +diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c +index b65f8f7e97..2acfb750fd 100644 +--- a/hw/virtio/vhost-backend.c ++++ b/hw/virtio/vhost-backend.c +@@ -20,6 +20,8 @@ + #include + #include + ++static unsigned int vhost_kernel_used_memslots; ++ + static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request, + void *arg) + { +@@ -293,6 +295,16 @@ static void vhost_kernel_set_iotlb_callback(struct vhost_dev *dev, + qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL, NULL); + } + ++static void vhost_kernel_set_used_memslots(struct vhost_dev *dev) ++{ ++ vhost_kernel_used_memslots = dev->mem->nregions; ++} ++ ++static unsigned int vhost_kernel_get_used_memslots(void) ++{ ++ return vhost_kernel_used_memslots; ++} ++ + const VhostOps kernel_ops = { + .backend_type = VHOST_BACKEND_TYPE_KERNEL, + .vhost_backend_init = vhost_kernel_init, +@@ -325,6 +337,8 @@ const VhostOps kernel_ops = { + #endif /* CONFIG_VHOST_VSOCK */ + .vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback, + .vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg, ++ .vhost_set_used_memslots = vhost_kernel_set_used_memslots, ++ .vhost_get_used_memslots = vhost_kernel_get_used_memslots, + }; + #endif + +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index a8feea489b..176cae9244 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -234,6 +234,7 @@ static VhostUserMsg m __attribute__ ((unused)); + + /* The version of the protocol we support */ + #define VHOST_USER_VERSION (0x1) ++static unsigned int vhost_user_used_memslots; + + struct vhost_user { + struct vhost_dev *dev; +@@ -2524,6 +2525,30 @@ void vhost_user_cleanup(VhostUserState *user) + user->chr = NULL; + } + ++static void vhost_user_set_used_memslots(struct vhost_dev *dev) ++{ ++ unsigned int counter = 0; ++ int i; ++ ++ for (i = 0; i < dev->mem->nregions; ++i) { ++ struct vhost_memory_region *reg = dev->mem->regions + i; ++ ram_addr_t offset; ++ MemoryRegion *mr; ++ ++ mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr, ++ &offset); ++ if (mr && memory_region_get_fd(mr) > 0) { ++ counter++; ++ } ++ } ++ vhost_user_used_memslots = counter; ++} ++ ++static unsigned int vhost_user_get_used_memslots(void) ++{ ++ return vhost_user_used_memslots; ++} ++ + const VhostOps user_ops = { + .backend_type = VHOST_BACKEND_TYPE_USER, + .vhost_backend_init = vhost_user_backend_init, +@@ -2557,4 +2582,6 @@ const VhostOps user_ops = { + .vhost_backend_mem_section_filter = vhost_user_mem_section_filter, + .vhost_get_inflight_fd = vhost_user_get_inflight_fd, + .vhost_set_inflight_fd = vhost_user_set_inflight_fd, ++ .vhost_set_used_memslots = vhost_user_set_used_memslots, ++ .vhost_get_used_memslots = vhost_user_get_used_memslots, + }; +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index dafb23c481..e4809777bc 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -45,20 +45,20 @@ + static struct vhost_log *vhost_log; + static struct vhost_log *vhost_log_shm; + +-static unsigned int used_memslots; + static QLIST_HEAD(, vhost_dev) vhost_devices = + QLIST_HEAD_INITIALIZER(vhost_devices); + + bool vhost_has_free_slot(void) + { +- unsigned int slots_limit = ~0U; + struct vhost_dev *hdev; + + QLIST_FOREACH(hdev, &vhost_devices, entry) { +- unsigned int r = hdev->vhost_ops->vhost_backend_memslots_limit(hdev); +- slots_limit = MIN(slots_limit, r); ++ if (hdev->vhost_ops->vhost_get_used_memslots() >= ++ hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { ++ return false; ++ } + } +- return slots_limit > used_memslots; ++ return true; + } + + static void vhost_dev_sync_region(struct vhost_dev *dev, +@@ -521,7 +521,6 @@ static void vhost_commit(MemoryListener *listener) + dev->n_mem_sections * sizeof dev->mem->regions[0]; + dev->mem = g_realloc(dev->mem, regions_size); + dev->mem->nregions = dev->n_mem_sections; +- used_memslots = dev->mem->nregions; + for (i = 0; i < dev->n_mem_sections; i++) { + struct vhost_memory_region *cur_vmr = dev->mem->regions + i; + struct MemoryRegionSection *mrs = dev->mem_sections + i; +@@ -697,6 +696,7 @@ static void vhost_region_add_section(struct vhost_dev *dev, + dev->tmp_sections[dev->n_tmp_sections - 1].fv = NULL; + memory_region_ref(section->mr); + } ++ dev->vhost_ops->vhost_set_used_memslots(dev); + } + + /* Used for both add and nop callbacks */ +@@ -712,6 +712,17 @@ static void vhost_region_addnop(MemoryListener *listener, + vhost_region_add_section(dev, section); + } + ++static void vhost_region_del(MemoryListener *listener, ++ MemoryRegionSection *section) ++{ ++ struct vhost_dev *dev = container_of(listener, struct vhost_dev, ++ memory_listener); ++ if (!vhost_section(dev, section)) { ++ return; ++ } ++ dev->vhost_ops->vhost_set_used_memslots(dev); ++} ++ + static void vhost_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) + { + struct vhost_iommu *iommu = container_of(n, struct vhost_iommu, n); +@@ -1319,6 +1330,18 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq) + event_notifier_cleanup(&vq->masked_notifier); + } + ++static bool vhost_dev_used_memslots_is_exceeded(struct vhost_dev *hdev) ++{ ++ if (hdev->vhost_ops->vhost_get_used_memslots() > ++ hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { ++ error_report("vhost backend memory slots limit is less" ++ " than current number of present memory slots"); ++ return true; ++ } ++ ++ return false; ++} ++ + int vhost_dev_init(struct vhost_dev *hdev, void *opaque, + VhostBackendType backend_type, uint32_t busyloop_timeout, + Error **errp) +@@ -1374,6 +1397,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, + .name = "vhost", + .begin = vhost_begin, + .commit = vhost_commit, ++ .region_del = vhost_region_del, + .region_add = vhost_region_addnop, + .region_nop = vhost_region_addnop, + .log_start = vhost_log_start, +@@ -1420,9 +1444,13 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, + memory_listener_register(&hdev->memory_listener, &address_space_memory); + QLIST_INSERT_HEAD(&vhost_devices, hdev, entry); + +- if (used_memslots > hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { +- error_setg(errp, "vhost backend memory slots limit is less" +- " than current number of present memory slots"); ++ /* ++ * If we started a VM without any vhost device, ++ * vhost_dev_used_memslots_is_exceeded will always return false for the ++ * first time vhost device hot-plug(vhost_get_used_memslots is always 0), ++ * so it needs to double check here ++ */ ++ if (vhost_dev_used_memslots_is_exceeded(hdev)) { + r = -EINVAL; + goto fail_busyloop; + } +diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h +index 81bf3109f8..a64708f456 100644 +--- a/include/hw/virtio/vhost-backend.h ++++ b/include/hw/virtio/vhost-backend.h +@@ -125,6 +125,8 @@ typedef int (*vhost_vq_get_addr_op)(struct vhost_dev *dev, + typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id); + + typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev); ++typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev); ++typedef unsigned int (*vhost_get_used_memslots_op)(void); + + typedef struct VhostOps { + VhostBackendType backend_type; +@@ -171,6 +173,8 @@ typedef struct VhostOps { + vhost_vq_get_addr_op vhost_vq_get_addr; + vhost_get_device_id_op vhost_get_device_id; + vhost_force_iommu_op vhost_force_iommu; ++ vhost_set_used_memslots_op vhost_set_used_memslots; ++ vhost_get_used_memslots_op vhost_get_used_memslots; + } VhostOps; + + int vhost_backend_update_device_iotlb(struct vhost_dev *dev, +-- +2.27.0 + -- Gitee From 2cb32927203fd1fb68f2a60922ada5393bf21dc2 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 19:24:30 +0800 Subject: [PATCH 25/30] vhost-user: quit infinite loop while used memslots is more than the backend limit When used memslots is more than the backend limit, the vhost-user netcard would attach fail and quit infinite loop. Signed-off-by: Jinhua Cao --- ...infinite-loop-while-used-memslots-is.patch | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 vhost-user-quit-infinite-loop-while-used-memslots-is.patch diff --git a/vhost-user-quit-infinite-loop-while-used-memslots-is.patch b/vhost-user-quit-infinite-loop-while-used-memslots-is.patch new file mode 100644 index 0000000..e6990e3 --- /dev/null +++ b/vhost-user-quit-infinite-loop-while-used-memslots-is.patch @@ -0,0 +1,88 @@ +From f46191f24706a6200cfe607a902b3da45f57c9ad Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 19:24:30 +0800 +Subject: [PATCH] vhost-user: quit infinite loop while used memslots is more + than the backend limit + +When used memslots is more than the backend limit, +the vhost-user netcard would attach fail and quit +infinite loop. + +Signed-off-by: Jinhua Cao +--- + hw/virtio/vhost.c | 9 +++++++++ + include/hw/virtio/vhost.h | 1 + + net/vhost-user.c | 6 ++++++ + 3 files changed, 16 insertions(+) + +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index e4809777bc..4c4072951c 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -48,6 +48,8 @@ static struct vhost_log *vhost_log_shm; + static QLIST_HEAD(, vhost_dev) vhost_devices = + QLIST_HEAD_INITIALIZER(vhost_devices); + ++bool used_memslots_exceeded; ++ + bool vhost_has_free_slot(void) + { + struct vhost_dev *hdev; +@@ -1336,9 +1338,11 @@ static bool vhost_dev_used_memslots_is_exceeded(struct vhost_dev *hdev) + hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { + error_report("vhost backend memory slots limit is less" + " than current number of present memory slots"); ++ used_memslots_exceeded = true; + return true; + } + ++ used_memslots_exceeded = false; + return false; + } + +@@ -1895,3 +1899,8 @@ int vhost_net_set_backend(struct vhost_dev *hdev, + + return -1; + } ++ ++bool used_memslots_is_exceeded(void) ++{ ++ return used_memslots_exceeded; ++} +diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h +index 58a73e7b7a..86f36f0106 100644 +--- a/include/hw/virtio/vhost.h ++++ b/include/hw/virtio/vhost.h +@@ -154,4 +154,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev, + struct vhost_inflight *inflight); + int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, + struct vhost_inflight *inflight); ++bool used_memslots_is_exceeded(void); + #endif +diff --git a/net/vhost-user.c b/net/vhost-user.c +index d1aefcb9aa..f910a286e4 100644 +--- a/net/vhost-user.c ++++ b/net/vhost-user.c +@@ -20,6 +20,7 @@ + #include "qemu/error-report.h" + #include "qemu/option.h" + #include "trace.h" ++#include "include/hw/virtio/vhost.h" + + #define VHOST_USER_RECONNECT_TIME (3) + +@@ -369,6 +370,11 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, + qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, + net_vhost_user_event, NULL, nc0->name, NULL, + true); ++ if (used_memslots_is_exceeded()) { ++ error_report("used memslots exceeded the backend limit, quit " ++ "loop"); ++ goto err; ++ } + } while (!s->started); + + assert(s->vhost_net); +-- +2.27.0 + -- Gitee From a8958fb9ddd44ffcd9b3cceefe03317c8c1eda1e Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 12 Feb 2022 15:41:08 +0800 Subject: [PATCH 26/30] qmp: add command to query used memslots of vhost-net and vhost-user Signed-off-by: Jinhua Cao --- ...to-query-used-memslots-of-vhost-net-.patch | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 qmp-add-command-to-query-used-memslots-of-vhost-net-.patch diff --git a/qmp-add-command-to-query-used-memslots-of-vhost-net-.patch b/qmp-add-command-to-query-used-memslots-of-vhost-net-.patch new file mode 100644 index 0000000..10d69dd --- /dev/null +++ b/qmp-add-command-to-query-used-memslots-of-vhost-net-.patch @@ -0,0 +1,131 @@ +From 1545a60a8b78490c7dc8909b7012bca63dba63cd Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Sat, 12 Feb 2022 15:41:08 +0800 +Subject: [PATCH] qmp: add command to query used memslots of vhost-net and + vhost-user + +Signed-off-by: Jinhua Cao +--- + hw/virtio/vhost-backend.c | 2 +- + hw/virtio/vhost-user.c | 2 +- + include/hw/virtio/vhost-backend.h | 2 ++ + monitor/qmp-cmds.c | 12 ++++++++++++ + qapi/net.json | 18 ++++++++++++++++++ + qapi/pragma.json | 4 +++- + 6 files changed, 37 insertions(+), 3 deletions(-) + +diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c +index 2acfb750fd..d8e1710758 100644 +--- a/hw/virtio/vhost-backend.c ++++ b/hw/virtio/vhost-backend.c +@@ -300,7 +300,7 @@ static void vhost_kernel_set_used_memslots(struct vhost_dev *dev) + vhost_kernel_used_memslots = dev->mem->nregions; + } + +-static unsigned int vhost_kernel_get_used_memslots(void) ++unsigned int vhost_kernel_get_used_memslots(void) + { + return vhost_kernel_used_memslots; + } +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index 176cae9244..8f69a3b850 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -2544,7 +2544,7 @@ static void vhost_user_set_used_memslots(struct vhost_dev *dev) + vhost_user_used_memslots = counter; + } + +-static unsigned int vhost_user_get_used_memslots(void) ++unsigned int vhost_user_get_used_memslots(void) + { + return vhost_user_used_memslots; + } +diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h +index a64708f456..7bbc658161 100644 +--- a/include/hw/virtio/vhost-backend.h ++++ b/include/hw/virtio/vhost-backend.h +@@ -190,4 +190,6 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev, + + int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd); + ++unsigned int vhost_kernel_get_used_memslots(void); ++unsigned int vhost_user_get_used_memslots(void); + #endif /* VHOST_BACKEND_H */ +diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c +index 98868cee03..f3e80ec8a7 100644 +--- a/monitor/qmp-cmds.c ++++ b/monitor/qmp-cmds.c +@@ -36,6 +36,7 @@ + #include "qapi/qapi-commands-machine.h" + #include "qapi/qapi-commands-misc.h" + #include "qapi/qapi-commands-ui.h" ++#include "qapi/qapi-commands-net.h" + #include "qapi/type-helpers.h" + #include "qapi/qmp/qerror.h" + #include "exec/ramlist.h" +@@ -43,6 +44,7 @@ + #include "hw/acpi/acpi_dev_interface.h" + #include "hw/intc/intc.h" + #include "hw/rdma/rdma.h" ++#include "hw/virtio/vhost-backend.h" + + NameInfo *qmp_query_name(Error **errp) + { +@@ -471,3 +473,13 @@ int64_t qmp_query_rtc_date_diff(Error **errp) + { + return get_rtc_date_diff(); + } ++ ++uint32_t qmp_query_vhost_kernel_used_memslots(Error **errp) ++{ ++ return vhost_kernel_get_used_memslots(); ++} ++ ++uint32_t qmp_query_vhost_user_used_memslots(Error **errp) ++{ ++ return vhost_user_get_used_memslots(); ++} +diff --git a/qapi/net.json b/qapi/net.json +index 7fab2e7cd8..c9ff849eed 100644 +--- a/qapi/net.json ++++ b/qapi/net.json +@@ -696,3 +696,21 @@ + ## + { 'event': 'FAILOVER_NEGOTIATED', + 'data': {'device-id': 'str'} } ++ ++## ++# @query-vhost-kernel-used-memslots: ++# ++# Get vhost-kernel nic used memslots ++# ++# Since: 4.1 ++## ++{ 'command': 'query-vhost-kernel-used-memslots', 'returns': 'uint32' } ++ ++## ++# @query-vhost-user-used-memslots: ++# ++# Get vhost-user nic used memslots ++# ++# Since: 4.1 ++## ++{ 'command': 'query-vhost-user-used-memslots', 'returns': 'uint32' } +diff --git a/qapi/pragma.json b/qapi/pragma.json +index b37f6de445..d35c897acb 100644 +--- a/qapi/pragma.json ++++ b/qapi/pragma.json +@@ -27,7 +27,9 @@ + 'query-tpm-models', + 'query-tpm-types', + 'ringbuf-read', +- 'query-rtc-date-diff' ], ++ 'query-rtc-date-diff', ++ 'query-vhost-user-used-memslots', ++ 'query-vhost-kernel-used-memslots' ], + # Externally visible types whose member names may use uppercase + 'member-name-exceptions': [ # visible in: + 'ACPISlotType', # query-acpi-ospm-status +-- +2.27.0 + -- Gitee From b424bae94c3cd5ef37210a3d3452a14113b29615 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 20:13:50 +0800 Subject: [PATCH 27/30] vhost-user-scsi: add support for SPDK hot upgrade In the hot upgrade scenario, the reconnection mechanism of qemu and SPDK after upgrade Signed-off-by: Jinhua Cao --- ...csi-add-support-for-SPDK-hot-upgrade.patch | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch diff --git a/vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch b/vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch new file mode 100644 index 0000000..8d54935 --- /dev/null +++ b/vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch @@ -0,0 +1,94 @@ +From 8c52233c08fe66b2e5c79fd514d4f804aa6fe427 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 20:13:50 +0800 +Subject: [PATCH] vhost-user-scsi: add support for SPDK hot upgrade + +In the hot upgrade scenario, the reconnection mechanism of qemu and SPDK after upgrade + +Signed-off-by: Jinhua Cao +--- + hw/scsi/vhost-user-scsi.c | 42 ++++++++++++++++++++++++++++++++++++++- + 1 file changed, 41 insertions(+), 1 deletion(-) + +diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c +index 1b2f7eed98..052740a76e 100644 +--- a/hw/scsi/vhost-user-scsi.c ++++ b/hw/scsi/vhost-user-scsi.c +@@ -29,6 +29,9 @@ + #include "hw/virtio/virtio-access.h" + #include "chardev/char-fe.h" + #include "sysemu/sysemu.h" ++#include "qemu/log.h" ++ ++#define VHOST_USER_SCSI_RECONNECT_TIME 3 + + /* Features supported by the host application */ + static const int user_feature_bits[] = { +@@ -59,7 +62,7 @@ static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) + ret = vhost_scsi_common_start(vsc); + if (ret < 0) { + error_report("unable to start vhost-user-scsi: %s", strerror(-ret)); +- exit(1); ++ return; + } + } else { + vhost_scsi_common_stop(vsc); +@@ -89,11 +92,43 @@ static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) + { + } + ++static void vhost_user_scsi_event(void *opaque, QEMUChrEvent event) ++{ ++ int ret; ++ VHostUserSCSI *s = (VHostUserSCSI *)opaque; ++ VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); ++ VirtIODevice *vdev = VIRTIO_DEVICE(s); ++ ++ qemu_log("event:%d, vdev status:%d\n", event, vdev->status); ++ ++ /* if CHR_EVENT_CLOSED, do nothing */ ++ if (event != CHR_EVENT_OPENED) { ++ return; ++ }; ++ ++ /* if status of vdev is not DRIVER_OK, just waiting. ++ * vsc should start when status change to DRIVER_OK */ ++ if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { ++ return; ++ } ++ ++ /* vsc may not fully start because of vhost app stopping */ ++ if (vsc->dev.started) { ++ vhost_scsi_common_stop(vsc); ++ } ++ ++ ret = vhost_scsi_common_start(vsc); ++ if (ret < 0) { ++ qemu_log("unable to start vhost-user-scsi: %s\n", strerror(-ret)); ++ } ++} ++ + static void vhost_user_scsi_realize(DeviceState *dev, Error **errp) + { + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); + VHostUserSCSI *s = VHOST_USER_SCSI(dev); + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); ++ Chardev *chr; + struct vhost_virtqueue *vqs = NULL; + Error *err = NULL; + int ret; +@@ -132,6 +167,11 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp) + vsc->lun = 0; + vsc->target = vs->conf.boot_tpgt; + ++ chr = qemu_chr_fe_get_driver(&vs->conf.chardev); ++ qemu_chr_set_reconnect_time(chr, VHOST_USER_SCSI_RECONNECT_TIME); ++ qemu_chr_fe_set_handlers(&vs->conf.chardev, NULL, NULL, ++ vhost_user_scsi_event, NULL, s, NULL, true); ++ + return; + + free_vhost: +-- +2.27.0 + -- Gitee From 34a01ee5d03e97990583fc9d42cfa2d5f045d2c9 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Fri, 11 Feb 2022 20:33:47 +0800 Subject: [PATCH 28/30] i6300esb watchdog: bugfix: Add a runstate transition QEMU will abort() for the reasons now: invalid runstate transition: 'prelaunch' -> 'postmigrate' Aborted This happens when: |<- watchdog timeout happened, then sets reset_requested to | SHUTDOWN_CAUSE_GUEST_RESET; |<- hot-migration thread sets vm state to RUN_STATE_FINISH_MIGRATE | before the last time of migration; |<- main thread gets the change of reset_requested and triggers | reset, then sets vm state to RUN_STATE_PRELAUNCH; |<- hot-migration thread sets vm state to RUN_STATE_POSTMIGRATE. Then 'prelaunch' -> 'postmigrate' runstate transition will happen. It is legal so add this transition to runstate_transitions_def. Signed-off-by: Jinhua Cao --- ...dog-bugfix-Add-a-runstate-transition.patch | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch diff --git a/i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch b/i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch new file mode 100644 index 0000000..f207f40 --- /dev/null +++ b/i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch @@ -0,0 +1,42 @@ +From 3c283ea7ca1902b9d221897fd65c5edb1d16e004 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Fri, 11 Feb 2022 20:33:47 +0800 +Subject: [PATCH] i6300esb watchdog: bugfix: Add a runstate transition + +QEMU will abort() for the reasons now: + + invalid runstate transition: 'prelaunch' -> 'postmigrate' + Aborted + +This happens when: + |<- watchdog timeout happened, then sets reset_requested to + | SHUTDOWN_CAUSE_GUEST_RESET; + |<- hot-migration thread sets vm state to RUN_STATE_FINISH_MIGRATE + | before the last time of migration; + |<- main thread gets the change of reset_requested and triggers + | reset, then sets vm state to RUN_STATE_PRELAUNCH; + |<- hot-migration thread sets vm state to RUN_STATE_POSTMIGRATE. + +Then 'prelaunch' -> 'postmigrate' runstate transition will happen. +It is legal so add this transition to runstate_transitions_def. + +Signed-off-by: Jinhua Cao +--- + softmmu/runstate.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/softmmu/runstate.c b/softmmu/runstate.c +index 5736d908db..680994cdf8 100644 +--- a/softmmu/runstate.c ++++ b/softmmu/runstate.c +@@ -115,6 +115,7 @@ static const RunStateTransition runstate_transitions_def[] = { + { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, + { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE }, ++ { RUN_STATE_PRELAUNCH, RUN_STATE_POSTMIGRATE }, + + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING }, + { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED }, +-- +2.27.0 + -- Gitee From c0d01326e7e6009344700c6dccc8b40abf20b35d Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 12 Feb 2022 20:58:50 +0800 Subject: [PATCH 29/30] =?UTF-8?q?spec:=20Update=20patch=20and=20changelog?= =?UTF-8?q?=20with=20!251=20vhost-user/qemu-img/virtio=5Fnet/pci/scsi?= =?UTF-8?q?=E8=A1=A5=E4=B8=81=E5=9B=9E=E5=90=88=20=20!251?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk with dataplane virtio: net-tap: bugfix: del net client if net_init_tap_one failed virtio: bugfix: clean up callback when del virtqueue virtio-net: bugfix: do not delete netdev before virtio net virtio-net: fix max vring buf size when set ring num virtio: check descriptor numbers virtio: bugfix: add rcu_read_lock when vring_avail_idx is called virtio: print the guest virtio_net features that host does not support virtio: bugfix: check the value of caches before accessing it virtio-net: set the max of queue size to 4096 virtio-net: update the default and max of rx/tx_queue_size vhost-user: add unregister_savevm when vhost-user cleanup qemu-img: block: dont blk_make_zero if discard_zeroes false vhost-user: Add support reconnect vhost-user socket vhost-user: Set the acked_features to vm's featrue vhost-user: add vhost_set_mem_table when vm load_setup at destination vhost-user: add separate memslot counter for vhost-user vhost-user: quit infinite loop while used memslots is more than the backend limit qmp: add command to query used memslots of vhost-net and vhost-user vhost-user-scsi: add support for SPDK hot upgrade i6300esb watchdog: bugfix: Add a runstate transition Signed-off-by: Chen Qun --- qemu.spec | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/qemu.spec b/qemu.spec index 625e54d..0f70e10 100644 --- a/qemu.spec +++ b/qemu.spec @@ -143,6 +143,27 @@ Patch0130: bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch Patch0131: block-mirror-fix-file-system-went-to-read-only-after.patch Patch0132: bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch Patch0133: target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch +Patch0134: virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch +Patch0135: virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch +Patch0136: virtio-bugfix-clean-up-callback-when-del-virtqueue.patch +Patch0137: virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch +Patch0138: virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch +Patch0139: virtio-check-descriptor-numbers.patch +Patch0140: virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch +Patch0141: virtio-print-the-guest-virtio_net-features-that-host.patch +Patch0142: virtio-bugfix-check-the-value-of-caches-before-acces.patch +Patch0143: virtio-net-set-the-max-of-queue-size-to-4096.patch +Patch0144: virtio-net-update-the-default-and-max-of-rx-tx_queue.patch +Patch0145: vhost-user-add-unregister_savevm-when-vhost-user-cle.patch +Patch0146: qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch +Patch0147: vhost-user-Add-support-reconnect-vhost-user-socket.patch +Patch0148: vhost-user-Set-the-acked_features-to-vm-s-featrue.patch +Patch0149: vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch +Patch0150: vhost-user-add-separate-memslot-counter-for-vhost-us.patch +Patch0151: vhost-user-quit-infinite-loop-while-used-memslots-is.patch +Patch0152: qmp-add-command-to-query-used-memslots-of-vhost-net-.patch +Patch0153: vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch +Patch0154: i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch BuildRequires: flex BuildRequires: gcc @@ -587,6 +608,29 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat Feb 12 2022 Chen Qun +- virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk with dataplane +- virtio: net-tap: bugfix: del net client if net_init_tap_one failed +- virtio: bugfix: clean up callback when del virtqueue +- virtio-net: bugfix: do not delete netdev before virtio net +- virtio-net: fix max vring buf size when set ring num +- virtio: check descriptor numbers +- virtio: bugfix: add rcu_read_lock when vring_avail_idx is called +- virtio: print the guest virtio_net features that host does not support +- virtio: bugfix: check the value of caches before accessing it +- virtio-net: set the max of queue size to 4096 +- virtio-net: update the default and max of rx/tx_queue_size +- vhost-user: add unregister_savevm when vhost-user cleanup +- qemu-img: block: dont blk_make_zero if discard_zeroes false +- vhost-user: Add support reconnect vhost-user socket +- vhost-user: Set the acked_features to vm's featrue +- vhost-user: add vhost_set_mem_table when vm load_setup at destination +- vhost-user: add separate memslot counter for vhost-user +- vhost-user: quit infinite loop while used memslots is more than the backend limit +- qmp: add command to query used memslots of vhost-net and vhost-user +- vhost-user-scsi: add support for SPDK hot upgrade +- i6300esb watchdog: bugfix: Add a runstate transition + * Sat Feb 12 2022 Chen Qun - bugfix: fix some illegal memory access and memory leak - bugfix: fix possible memory leak -- Gitee From d21bb2a10f99bce223e2ab4b84e854d27f62de8e Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 12 Feb 2022 20:58:53 +0800 Subject: [PATCH 30/30] spec: Update release version with !248 !251 increase release verison by one Signed-off-by: Chen Qun --- qemu.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu.spec b/qemu.spec index 0f70e10..849d106 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 6.2.0 -Release: 12 +Release: 13 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 -- Gitee