From d6091072562a2fba30670ad2528530a3a1120523 Mon Sep 17 00:00:00 2001 From: imxcc Date: Wed, 28 Jul 2021 15:16:24 +0800 Subject: [PATCH] some bugfix sync from 20.09 Signed-off-by: imxcc --- Fixed-integer-overflow-in-e1000e.patch | 40 +++ ...it-APIC-ID-for-migration-instance-ID.patch | 50 ++++ audio-fix-integer-overflow.patch | 37 +++ ...-memleak-on-qcow2-image-info-failure.patch | 35 +++ ...rv_set_backing_bs-fix-use-after-free.patch | 116 +++++++++ ...oot_attach_child-forget-to-unref-chi.patch | 33 +++ ...rror-fix-use-after-free-of-local_err.patch | 34 +++ ...-nbd-extract-the-common-cleanup-code.patch | 67 +++++ ...2-do-free-crypto_opts-in-qcow2_close.patch | 54 ++++ ...k-qcow2-threads-fix-qcow2_decompress.patch | 75 ++++++ ...fter-free-with-dup-chardev-reconnect.patch | 126 ++++++++++ ...-Fix-error-message-double-free-error.patch | 43 ++++ ...re-Fix-memory-leak-in-packet_enqueue.patch | 90 +++++++ ...-do-not-leak-struct-cris_disasm_data.patch | 139 ++++++++++ display-bochs-display-fix-memory-leak.patch | 35 +++ ...eaked-fd-in-raw_open_common-error-pa.patch | 31 +++ fix-vhost_user_blk_watch-crash.patch | 81 ++++++ hmp-vnc-Fix-info-vnc-list-leak.patch | 48 ++++ hppa-fix-leak-from-g_strdup_printf.patch | 54 ++++ ...me-fix-pci-doorbell-size-calculation.patch | 62 +++++ ...vme-fix-pin-based-interrupt-behavior.patch | 87 +++++++ ...e-Correct-pci_bridge_io-memory-regio.patch | 67 +++++ ide-fix-leak-from-qemu_allocate_irqs.patch | 28 +++ ...c-fix-integer-underflow-in-target_mr.patch | 34 +++ ...ak-memory-on-object_new-object_unref.patch | 77 ++++++ ...-use-after-free-in-test-opts-visitor.patch | 102 ++++++++ ...208-fix-leak-from-qemu_allocate_irqs.patch | 29 +++ ...oblaze-fix-leak-of-fdevice-tree-blob.patch | 32 +++ ...-SaveStateEntry.instance_id-into-uin.patch | 158 ++++++++++++ ...ount-new_dirty-instead-of-real_dirty.patch | 74 ++++++ ...ation-Define-VMSTATE_INSTANCE_ID_ANY.patch | 237 +++++++++++++++++ ...colo-fix-use-after-free-of-local_err.patch | 33 +++ migration-fix-cleanup_bh-leak-on-resume.patch | 64 +++++ ...ifd-clean-pages-after-filling-packet.patch | 51 ++++ ...tifd-not-use-multifd-during-postcopy.patch | 41 +++ ...-ram-fix-use-after-free-of-local_err.patch | 33 +++ ...leanup-rdma-context-before-g_free-to.patch | 58 +++++ ...-release-gslist-after-dump_vmstate_j.patch | 63 +++++ object-return-self-in-object_ref.patch | 58 +++++ ...-net-fix-a-possible-memory-leak-in-g.patch | 34 +++ qemu-img-free-memory-before-re-assign.patch | 33 +++ qemu.spec | 126 +++++++++- ...y-memory-leak-in-guest-set-memory-bl.patch | 40 +++ ...osix-fix-use-after-free-of-local_err.patch | 49 ++++ ...-assert-regression-on-guest-shutdown.patch | 47 ++++ ...callbacks-that-return-both-value-and.patch | 47 ++++ ...date-the-ID-registers-of-Kunpeng-920.patch | 57 +++++ ...-EL2-and-EL3-only-when-kvm-is-not-en.patch | 42 ++++ ...set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch | 31 +++ usbredir-fix-buffer-overflow-on-vmload.patch | 54 ++++ ...k-convert-to-new-virtio_delete_queue.patch | 99 ++++++++ ...-blk-delay-vhost_user_blk_disconnect.patch | 90 +++++++ ...elete-virtioqueues-in-unrealize-to-f.patch | 69 +++++ ...ility-to-delete-vq-through-a-pointer.patch | 61 +++++ ...ete-vqs-on-the-error-path-in-realize.patch | 45 ++++ ...-delete-ctrl_vq-in-virtio_crypto_dev.patch | 55 ++++ ...cefully-handle-invalid-region-caches.patch | 238 ++++++++++++++++++ ...o-input-fix-memory-leak-on-unrealize.patch | 45 ++++ virtio-pci-fix-queue_enable-write.patch | 58 +++++ ...elete-rq_vq-in-virtio_pmem_unrealize.patch | 39 +++ ...s-Plug-memory-leak-on-realize-error-.patch | 65 +++++ ...ax_access_size-to-access-address-reg.patch | 62 +++++ 62 files changed, 4061 insertions(+), 1 deletion(-) create mode 100644 Fixed-integer-overflow-in-e1000e.patch create mode 100644 apic-Use-32bit-APIC-ID-for-migration-instance-ID.patch create mode 100644 audio-fix-integer-overflow.patch create mode 100644 block-Avoid-memleak-on-qcow2-image-info-failure.patch create mode 100644 block-bdrv_set_backing_bs-fix-use-after-free.patch create mode 100644 block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch create mode 100644 block-mirror-fix-use-after-free-of-local_err.patch create mode 100644 block-nbd-extract-the-common-cleanup-code.patch create mode 100644 block-qcow2-do-free-crypto_opts-in-qcow2_close.patch create mode 100644 block-qcow2-threads-fix-qcow2_decompress.patch create mode 100644 char-fix-use-after-free-with-dup-chardev-reconnect.patch create mode 100644 chardev-tcp-Fix-error-message-double-free-error.patch create mode 100644 colo-compare-Fix-memory-leak-in-packet_enqueue.patch create mode 100644 cris-do-not-leak-struct-cris_disasm_data.patch create mode 100644 display-bochs-display-fix-memory-leak.patch create mode 100644 file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch create mode 100644 fix-vhost_user_blk_watch-crash.patch create mode 100644 hmp-vnc-Fix-info-vnc-list-leak.patch create mode 100644 hppa-fix-leak-from-g_strdup_printf.patch create mode 100644 hw-block-nvme-fix-pci-doorbell-size-calculation.patch create mode 100644 hw-block-nvme-fix-pin-based-interrupt-behavior.patch create mode 100644 hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch create mode 100644 ide-fix-leak-from-qemu_allocate_irqs.patch create mode 100644 linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch create mode 100644 lm32-do-not-leak-memory-on-object_new-object_unref.patch create mode 100644 make-check-unit-use-after-free-in-test-opts-visitor.patch create mode 100644 mcf5208-fix-leak-from-qemu_allocate_irqs.patch create mode 100644 microblaze-fix-leak-of-fdevice-tree-blob.patch create mode 100644 migration-Change-SaveStateEntry.instance_id-into-uin.patch create mode 100644 migration-Count-new_dirty-instead-of-real_dirty.patch create mode 100644 migration-Define-VMSTATE_INSTANCE_ID_ANY.patch create mode 100644 migration-colo-fix-use-after-free-of-local_err.patch create mode 100644 migration-fix-cleanup_bh-leak-on-resume.patch create mode 100644 migration-multifd-clean-pages-after-filling-packet.patch create mode 100644 migration-multifd-not-use-multifd-during-postcopy.patch create mode 100644 migration-ram-fix-use-after-free-of-local_err.patch create mode 100644 migration-rdma-cleanup-rdma-context-before-g_free-to.patch create mode 100644 migration-savevm-release-gslist-after-dump_vmstate_j.patch create mode 100644 object-return-self-in-object_ref.patch create mode 100644 pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch create mode 100644 qemu-img-free-memory-before-re-assign.patch create mode 100644 qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch create mode 100644 qga-commands-posix-fix-use-after-free-of-local_err.patch create mode 100644 qga-fix-assert-regression-on-guest-shutdown.patch create mode 100644 qmp-fix-leak-on-callbacks-that-return-both-value-and.patch create mode 100644 target-arm-Update-the-ID-registers-of-Kunpeng-920.patch create mode 100644 target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch create mode 100644 target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch create mode 100644 usbredir-fix-buffer-overflow-on-vmload.patch create mode 100644 vhost-user-blk-convert-to-new-virtio_delete_queue.patch create mode 100644 vhost-user-blk-delay-vhost_user_blk_disconnect.patch create mode 100644 vhost-user-blk-delete-virtioqueues-in-unrealize-to-f.patch create mode 100644 virtio-add-ability-to-delete-vq-through-a-pointer.patch create mode 100644 virtio-blk-delete-vqs-on-the-error-path-in-realize.patch create mode 100644 virtio-crypto-do-delete-ctrl_vq-in-virtio_crypto_dev.patch create mode 100644 virtio-gracefully-handle-invalid-region-caches.patch create mode 100644 virtio-input-fix-memory-leak-on-unrealize.patch create mode 100644 virtio-pci-fix-queue_enable-write.patch create mode 100644 virtio-pmem-do-delete-rq_vq-in-virtio_pmem_unrealize.patch create mode 100644 virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch create mode 100644 xhci-fix-valid.max_access_size-to-access-address-reg.patch diff --git a/Fixed-integer-overflow-in-e1000e.patch b/Fixed-integer-overflow-in-e1000e.patch new file mode 100644 index 00000000..004390fc --- /dev/null +++ b/Fixed-integer-overflow-in-e1000e.patch @@ -0,0 +1,40 @@ +From 41077af2c4283c15c0a822017ea51612d15b68f8 Mon Sep 17 00:00:00 2001 +From: Andrew Melnychenko +Date: Wed, 4 Mar 2020 16:20:58 +0200 +Subject: [PATCH 1/5] Fixed integer overflow in e1000e +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1737400 +Fixed setting max_queue_num if there are no peers in +NICConf. qemu_new_nic() creates NICState with 1 NetClientState(index +0) without peers, set max_queue_num to 0 - It prevents undefined +behavior and possible crashes, especially during pcie hotplug. + +Fixes: 6f3fbe4ed06 ("net: Introduce e1000e device emulation") +Signed-off-by: Andrew Melnychenko +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Dmitry Fleytman +Signed-off-by: Jason Wang +Signed-off-by: Zhenyu Ye +--- + hw/net/e1000e.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c +index 581f7d03..1e827c4f 100644 +--- a/hw/net/e1000e.c ++++ b/hw/net/e1000e.c +@@ -325,7 +325,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) + s->nic = qemu_new_nic(&net_e1000e_info, &s->conf, + object_get_typename(OBJECT(s)), dev->id, s); + +- s->core.max_queue_num = s->conf.peers.queues - 1; ++ s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; + + trace_e1000e_mac_set_permanent(MAC_ARG(macaddr)); + memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac)); +-- +2.22.0.windows.1 + diff --git a/apic-Use-32bit-APIC-ID-for-migration-instance-ID.patch b/apic-Use-32bit-APIC-ID-for-migration-instance-ID.patch new file mode 100644 index 00000000..4a96fc5c --- /dev/null +++ b/apic-Use-32bit-APIC-ID-for-migration-instance-ID.patch @@ -0,0 +1,50 @@ +From 3bdd21c4b7d80cacc6b5f1b26ab52ef3a0aceb06 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 16 Oct 2019 10:29:32 +0800 +Subject: [PATCH 7/8] apic: Use 32bit APIC ID for migration instance ID + +Migration is silently broken now with x2apic config like this: + + -smp 200,maxcpus=288,sockets=2,cores=72,threads=2 \ + -device intel-iommu,intremap=on,eim=on + +After migration, the guest kernel could hang at anything, due to +x2apic bit not migrated correctly in IA32_APIC_BASE on some vcpus, so +any operations related to x2apic could be broken then (e.g., RDMSR on +x2apic MSRs could fail because KVM would think that the vcpu hasn't +enabled x2apic at all). + +The issue is that the x2apic bit was never applied correctly for vcpus +whose ID > 255 when migrate completes, and that's because when we +migrate APIC we use the APICCommonState.id as instance ID of the +migration stream, while that's too short for x2apic. + +Let's use the newly introduced initial_apic_id for that. + +Signed-off-by: Peter Xu +Reviewed-by: Juan Quintela +Reviewed-by: Eduardo Habkost +Signed-off-by: Juan Quintela +--- + hw/intc/apic_common.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c +index 07adba0..2c0cb1e 100644 +--- a/hw/intc/apic_common.c ++++ b/hw/intc/apic_common.c +@@ -313,7 +313,10 @@ static void apic_common_realize(DeviceState *dev, Error **errp) + APICCommonState *s = APIC_COMMON(dev); + APICCommonClass *info; + static DeviceState *vapic; +- uint32_t instance_id = s->id; ++ uint32_t instance_id = s->initial_apic_id; ++ ++ /* Normally initial APIC ID should be no more than hundreds */ ++ assert(instance_id != VMSTATE_INSTANCE_ID_ANY); + + info = APIC_COMMON_GET_CLASS(s); + info->realize(dev, errp); +-- +1.8.3.1 + diff --git a/audio-fix-integer-overflow.patch b/audio-fix-integer-overflow.patch new file mode 100644 index 00000000..91f5280f --- /dev/null +++ b/audio-fix-integer-overflow.patch @@ -0,0 +1,37 @@ +From d0c4e8cc25dc3bfed1659c35fb59b2f0418ba1d5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Volker=20R=C3=BCmelin?= +Date: Thu, 19 Dec 2019 21:34:05 +0100 +Subject: [PATCH 2/8] audio: fix integer overflow +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Tell the compiler to do a 32bit * 32bit -> 64bit multiplication +because period_ticks is a 64bit variable. The overflow occurs +for audio timer periods larger than 4294967us. + +Fixes: be1092afa0 "audio: fix audio timer rate conversion bug" + +Signed-off-by: Volker Rümelin +Message-id: 8893a235-66a8-8fbe-7d95-862e29da90b1@t-online.de +Signed-off-by: Gerd Hoffmann +--- + audio/audio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/audio/audio.c b/audio/audio.c +index 05adf7f..efcb5d4 100644 +--- a/audio/audio.c ++++ b/audio/audio.c +@@ -1473,7 +1473,7 @@ static int audio_init(Audiodev *dev) + if (dev->timer_period <= 0) { + s->period_ticks = 1; + } else { +- s->period_ticks = dev->timer_period * SCALE_US; ++ s->period_ticks = dev->timer_period * (int64_t)SCALE_US; + } + + e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s); +-- +1.8.3.1 + diff --git a/block-Avoid-memleak-on-qcow2-image-info-failure.patch b/block-Avoid-memleak-on-qcow2-image-info-failure.patch new file mode 100644 index 00000000..13917f5b --- /dev/null +++ b/block-Avoid-memleak-on-qcow2-image-info-failure.patch @@ -0,0 +1,35 @@ +From 6a39af8880c18fb3bcbfb715aef909c64286524e Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 20 Mar 2020 13:36:20 -0500 +Subject: [PATCH 04/14] block: Avoid memleak on qcow2 image info failure + +If we fail to get bitmap info, we must not leak the encryption info. + +Fixes: b8968c875f403 +Fixes: Coverity CID 1421894 +Signed-off-by: Eric Blake +Message-Id: <20200320183620.1112123-1-eblake@redhat.com> +Reviewed-by: Vladimir Sementsov-Ogievskiy +Reviewed-by: Andrey Shinkevich +Tested-by: Andrey Shinkevich +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/qcow2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block/qcow2.c b/block/qcow2.c +index 27c54b9905aa..0f4b0940d457 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -4588,6 +4588,7 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs, + if (local_err) { + error_propagate(errp, local_err); + qapi_free_ImageInfoSpecific(spec_info); ++ qapi_free_QCryptoBlockInfo(encrypt_info); + return NULL; + } + *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){ +-- +2.26.2 + diff --git a/block-bdrv_set_backing_bs-fix-use-after-free.patch b/block-bdrv_set_backing_bs-fix-use-after-free.patch new file mode 100644 index 00000000..93ac7216 --- /dev/null +++ b/block-bdrv_set_backing_bs-fix-use-after-free.patch @@ -0,0 +1,116 @@ +From 3754525eb383f91869634766ccd041cfe40bbf17 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Mon, 16 Mar 2020 09:06:30 +0300 +Subject: [PATCH 05/14] block: bdrv_set_backing_bs: fix use-after-free +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is a use-after-free possible: bdrv_unref_child() leaves +bs->backing freed but not NULL. bdrv_attach_child may produce nested +polling loop due to drain, than access of freed pointer is possible. + +I've produced the following crash on 30 iotest with modified code. It +does not reproduce on master, but still seems possible: + + #0 __strcmp_avx2 () at /lib64/libc.so.6 + #1 bdrv_backing_overridden (bs=0x55c9d3cc2060) at block.c:6350 + #2 bdrv_refresh_filename (bs=0x55c9d3cc2060) at block.c:6404 + #3 bdrv_backing_attach (c=0x55c9d48e5520) at block.c:1063 + #4 bdrv_replace_child_noperm + (child=child@entry=0x55c9d48e5520, + new_bs=new_bs@entry=0x55c9d3cc2060) at block.c:2290 + #5 bdrv_replace_child + (child=child@entry=0x55c9d48e5520, + new_bs=new_bs@entry=0x55c9d3cc2060) at block.c:2320 + #6 bdrv_root_attach_child + (child_bs=child_bs@entry=0x55c9d3cc2060, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + ctx=, perm=, shared_perm=21, + opaque=0x55c9d3c5a3d0, errp=0x7ffd117108e0) at block.c:2424 + #7 bdrv_attach_child + (parent_bs=parent_bs@entry=0x55c9d3c5a3d0, + child_bs=child_bs@entry=0x55c9d3cc2060, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + errp=errp@entry=0x7ffd117108e0) at block.c:5876 + #8 in bdrv_set_backing_hd + (bs=bs@entry=0x55c9d3c5a3d0, + backing_hd=backing_hd@entry=0x55c9d3cc2060, + errp=errp@entry=0x7ffd117108e0) + at block.c:2576 + #9 stream_prepare (job=0x55c9d49d84a0) at block/stream.c:150 + #10 job_prepare (job=0x55c9d49d84a0) at job.c:761 + #11 job_txn_apply (txn=, fn=) at + job.c:145 + #12 job_do_finalize (job=0x55c9d49d84a0) at job.c:778 + #13 job_completed_txn_success (job=0x55c9d49d84a0) at job.c:832 + #14 job_completed (job=0x55c9d49d84a0) at job.c:845 + #15 job_completed (job=0x55c9d49d84a0) at job.c:836 + #16 job_exit (opaque=0x55c9d49d84a0) at job.c:864 + #17 aio_bh_call (bh=0x55c9d471a160) at util/async.c:117 + #18 aio_bh_poll (ctx=ctx@entry=0x55c9d3c46720) at util/async.c:117 + #19 aio_poll (ctx=ctx@entry=0x55c9d3c46720, + blocking=blocking@entry=true) + at util/aio-posix.c:728 + #20 bdrv_parent_drained_begin_single (poll=true, c=0x55c9d3d558f0) + at block/io.c:121 + #21 bdrv_parent_drained_begin_single (c=c@entry=0x55c9d3d558f0, + poll=poll@entry=true) + at block/io.c:114 + #22 bdrv_replace_child_noperm + (child=child@entry=0x55c9d3d558f0, + new_bs=new_bs@entry=0x55c9d3d27300) at block.c:2258 + #23 bdrv_replace_child + (child=child@entry=0x55c9d3d558f0, + new_bs=new_bs@entry=0x55c9d3d27300) at block.c:2320 + #24 bdrv_root_attach_child + (child_bs=child_bs@entry=0x55c9d3d27300, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + ctx=, perm=, shared_perm=21, + opaque=0x55c9d3cc2060, errp=0x7ffd11710c60) at block.c:2424 + #25 bdrv_attach_child + (parent_bs=parent_bs@entry=0x55c9d3cc2060, + child_bs=child_bs@entry=0x55c9d3d27300, + child_name=child_name@entry=0x55c9d241d478 "backing", + child_role=child_role@entry=0x55c9d26ecee0 , + errp=errp@entry=0x7ffd11710c60) at block.c:5876 + #26 bdrv_set_backing_hd + (bs=bs@entry=0x55c9d3cc2060, + backing_hd=backing_hd@entry=0x55c9d3d27300, + errp=errp@entry=0x7ffd11710c60) + at block.c:2576 + #27 stream_prepare (job=0x55c9d495ead0) at block/stream.c:150 + ... + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200316060631.30052-2-vsementsov@virtuozzo.com> +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: John Snow +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block.c b/block.c +index 29e504b86aff..e834102c87f7 100644 +--- a/block.c ++++ b/block.c +@@ -2549,10 +2549,10 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, + + if (bs->backing) { + bdrv_unref_child(bs, bs->backing); ++ bs->backing = NULL; + } + + if (!backing_hd) { +- bs->backing = NULL; + goto out; + } + +-- +2.26.2 + diff --git a/block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch b/block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch new file mode 100644 index 00000000..d901f106 --- /dev/null +++ b/block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch @@ -0,0 +1,33 @@ +From 5060ef71fa4621061101a30fa9e0d1690696c5c1 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:59:21 +0300 +Subject: [PATCH 10/14] block: fix bdrv_root_attach_child forget to unref + child_bs + +bdrv_root_attach_child promises to drop child_bs reference on failure. +It does it on first handled failure path, but not on the second. Fix +that. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324155921.23822-1-vsementsov@virtuozzo.com> +Signed-off-by: Kevin Wolf +Signed-off-by: Peng Liang +--- + block.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block.c b/block.c +index e834102c87f7..38880eabf801 100644 +--- a/block.c ++++ b/block.c +@@ -2399,6 +2399,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, + error_propagate(errp, local_err); + g_free(child); + bdrv_abort_perm_update(child_bs); ++ bdrv_unref(child_bs); + return NULL; + } + } +-- +2.26.2 + diff --git a/block-mirror-fix-use-after-free-of-local_err.patch b/block-mirror-fix-use-after-free-of-local_err.patch new file mode 100644 index 00000000..ea2f7394 --- /dev/null +++ b/block-mirror-fix-use-after-free-of-local_err.patch @@ -0,0 +1,34 @@ +From 682d23829adf0a872d5a3ca6eb4b31c424f558fc Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:26 +0300 +Subject: [PATCH 09/14] block/mirror: fix use after free of local_err + +local_err is used again in mirror_exit_common() after +bdrv_set_backing_hd(), so we must zero it. Otherwise try to set +non-NULL local_err will crash. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-3-vsementsov@virtuozzo.com> +Reviewed-by: Eric Blake +Reviewed-by: John Snow +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/mirror.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block/mirror.c b/block/mirror.c +index 681b305de650..ef6c958ff9b3 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -674,6 +674,7 @@ static int mirror_exit_common(Job *job) + bdrv_set_backing_hd(target_bs, backing, &local_err); + if (local_err) { + error_report_err(local_err); ++ local_err = NULL; + ret = -EPERM; + } + } +-- +2.26.2 + diff --git a/block-nbd-extract-the-common-cleanup-code.patch b/block-nbd-extract-the-common-cleanup-code.patch new file mode 100644 index 00000000..4cc24818 --- /dev/null +++ b/block-nbd-extract-the-common-cleanup-code.patch @@ -0,0 +1,67 @@ +From 1196a2079a558cbb673e06142fa67a401c5e6c30 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Thu, 5 Dec 2019 11:45:27 +0800 +Subject: [PATCH 6/9] block/nbd: extract the common cleanup code + +The BDRVNBDState cleanup code is common in two places, add +nbd_clear_bdrvstate() function to do these cleanups. + +Suggested-by: Stefano Garzarella +Signed-off-by: Pan Nengyuan +Reviewed-by: Vladimir Sementsov-Ogievskiy +Message-Id: <1575517528-44312-2-git-send-email-pannengyuan@huawei.com> +Reviewed-by: Eric Blake +[eblake: fix compilation error and commit message] +Signed-off-by: Eric Blake +Signed-off-by: AlexChen +--- + block/nbd.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/block/nbd.c b/block/nbd.c +index 57c1a20..3977b1e 100644 +--- a/block/nbd.c ++++ b/block/nbd.c +@@ -73,6 +73,16 @@ typedef struct BDRVNBDState { + char *export, *tlscredsid; + } BDRVNBDState; + ++static void nbd_clear_bdrvstate(BDRVNBDState *s) ++{ ++ qapi_free_SocketAddress(s->saddr); ++ s->saddr = NULL; ++ g_free(s->export); ++ s->export = NULL; ++ g_free(s->tlscredsid); ++ s->tlscredsid = NULL; ++} ++ + static void nbd_recv_coroutines_wake_all(BDRVNBDState *s) + { + int i; +@@ -1640,9 +1650,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, + object_unref(OBJECT(tlscreds)); + } + if (ret < 0) { +- qapi_free_SocketAddress(s->saddr); +- g_free(s->export); +- g_free(s->tlscredsid); ++ nbd_clear_bdrvstate(s); + } + qemu_opts_del(opts); + return ret; +@@ -1692,10 +1700,7 @@ static void nbd_close(BlockDriverState *bs) + BDRVNBDState *s = bs->opaque; + + nbd_client_close(bs); +- +- qapi_free_SocketAddress(s->saddr); +- g_free(s->export); +- g_free(s->tlscredsid); ++ nbd_clear_bdrvstate(s); + } + + static int64_t nbd_getlength(BlockDriverState *bs) +-- +1.8.3.1 + diff --git a/block-qcow2-do-free-crypto_opts-in-qcow2_close.patch b/block-qcow2-do-free-crypto_opts-in-qcow2_close.patch new file mode 100644 index 00000000..44b0ea19 --- /dev/null +++ b/block-qcow2-do-free-crypto_opts-in-qcow2_close.patch @@ -0,0 +1,54 @@ +From 88ef4e1862987227f8b87228cff94be3af66d054 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Thu, 27 Feb 2020 09:29:49 +0800 +Subject: [PATCH 01/14] block/qcow2: do free crypto_opts in qcow2_close() + +'crypto_opts' forgot to free in qcow2_close(), this patch fix the bellow leak stack: + +Direct leak of 24 byte(s) in 1 object(s) allocated from: + #0 0x7f0edd81f970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970) + #1 0x7f0edc6d149d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d) + #2 0x55d7eaede63d in qobject_input_start_struct /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qobject-input-visitor.c:295 + #3 0x55d7eaed78b8 in visit_start_struct /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qapi-visit-core.c:49 + #4 0x55d7eaf5140b in visit_type_QCryptoBlockOpenOptions qapi/qapi-visit-crypto.c:290 + #5 0x55d7eae43af3 in block_crypto_open_opts_init /mnt/sdb/qemu-new/qemu_test/qemu/block/crypto.c:163 + #6 0x55d7eacd2924 in qcow2_update_options_prepare /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1148 + #7 0x55d7eacd33f7 in qcow2_update_options /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1232 + #8 0x55d7eacd9680 in qcow2_do_open /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1512 + #9 0x55d7eacdc55e in qcow2_open_entry /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1792 + #10 0x55d7eacdc8fe in qcow2_open /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:1819 + #11 0x55d7eac3742d in bdrv_open_driver /mnt/sdb/qemu-new/qemu_test/qemu/block.c:1317 + #12 0x55d7eac3e990 in bdrv_open_common /mnt/sdb/qemu-new/qemu_test/qemu/block.c:1575 + #13 0x55d7eac4442c in bdrv_open_inherit /mnt/sdb/qemu-new/qemu_test/qemu/block.c:3126 + #14 0x55d7eac45c3f in bdrv_open /mnt/sdb/qemu-new/qemu_test/qemu/block.c:3219 + #15 0x55d7ead8e8a4 in blk_new_open /mnt/sdb/qemu-new/qemu_test/qemu/block/block-backend.c:397 + #16 0x55d7eacde74c in qcow2_co_create /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:3534 + #17 0x55d7eacdfa6d in qcow2_co_create_opts /mnt/sdb/qemu-new/qemu_test/qemu/block/qcow2.c:3668 + #18 0x55d7eac1c678 in bdrv_create_co_entry /mnt/sdb/qemu-new/qemu_test/qemu/block.c:485 + #19 0x55d7eb0024d2 in coroutine_trampoline /mnt/sdb/qemu-new/qemu_test/qemu/util/coroutine-ucontext.c:115 + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Max Reitz +Message-Id: <20200227012950.12256-2-pannengyuan@huawei.com> +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/qcow2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block/qcow2.c b/block/qcow2.c +index 1909df6e1d24..27c54b9905aa 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -2408,6 +2408,7 @@ static void qcow2_close(BlockDriverState *bs) + + qcrypto_block_free(s->crypto); + s->crypto = NULL; ++ qapi_free_QCryptoBlockOpenOptions(s->crypto_opts); + + g_free(s->unknown_header_fields); + cleanup_unknown_header_ext(bs); +-- +2.26.2 + diff --git a/block-qcow2-threads-fix-qcow2_decompress.patch b/block-qcow2-threads-fix-qcow2_decompress.patch new file mode 100644 index 00000000..d2fd9ee7 --- /dev/null +++ b/block-qcow2-threads-fix-qcow2_decompress.patch @@ -0,0 +1,75 @@ +From a583b6b616b086d3fdce93e255d24ab2c865efd3 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Mon, 2 Mar 2020 18:09:30 +0300 +Subject: [PATCH 03/14] block/qcow2-threads: fix qcow2_decompress +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On success path we return what inflate() returns instead of 0. And it +most probably works for Z_STREAM_END as it is positive, but is +definitely broken for Z_BUF_ERROR. + +While being here, switch to errno return code, to be closer to +qcow2_compress API (and usual expectations). + +Revert condition in if to be more positive. Drop dead initialization of +ret. + +Cc: qemu-stable@nongnu.org # v4.0 +Fixes: 341926ab83e2b +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200302150930.16218-1-vsementsov@virtuozzo.com> +Reviewed-by: Alberto Garcia +Reviewed-by: Ján Tomko +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + block/qcow2-threads.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c +index 3b1e63fe414d..449cd3c0a1f4 100644 +--- a/block/qcow2-threads.c ++++ b/block/qcow2-threads.c +@@ -128,12 +128,12 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size, + * @src - source buffer, @src_size bytes + * + * Returns: 0 on success +- * -1 on fail ++ * -EIO on fail + */ + static ssize_t qcow2_decompress(void *dest, size_t dest_size, + const void *src, size_t src_size) + { +- int ret = 0; ++ int ret; + z_stream strm; + + memset(&strm, 0, sizeof(strm)); +@@ -144,17 +144,19 @@ static ssize_t qcow2_decompress(void *dest, size_t dest_size, + + ret = inflateInit2(&strm, -12); + if (ret != Z_OK) { +- return -1; ++ return -EIO; + } + + ret = inflate(&strm, Z_FINISH); +- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) { ++ if ((ret == Z_STREAM_END || ret == Z_BUF_ERROR) && strm.avail_out == 0) { + /* + * We approve Z_BUF_ERROR because we need @dest buffer to be filled, but + * @src buffer may be processed partly (because in qcow2 we know size of + * compressed data with precision of one sector) + */ +- ret = -1; ++ ret = 0; ++ } else { ++ ret = -EIO; + } + + inflateEnd(&strm); +-- +2.26.2 + diff --git a/char-fix-use-after-free-with-dup-chardev-reconnect.patch b/char-fix-use-after-free-with-dup-chardev-reconnect.patch new file mode 100644 index 00000000..fd81015a --- /dev/null +++ b/char-fix-use-after-free-with-dup-chardev-reconnect.patch @@ -0,0 +1,126 @@ +From 902a8192600ff81681a162509e23bf95619d1f04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 20 Apr 2020 13:20:12 +0200 +Subject: [PATCH] char: fix use-after-free with dup chardev & reconnect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With a reconnect socket, qemu_char_open() will start a background +thread. It should keep a reference on the chardev. + +Fixes invalid read: +READ of size 8 at 0x6040000ac858 thread T7 + #0 0x5555598d37b8 in unix_connect_saddr /home/elmarco/src/qq/util/qemu-sockets.c:954 + #1 0x5555598d4751 in socket_connect /home/elmarco/src/qq/util/qemu-sockets.c:1109 + #2 0x555559707c34 in qio_channel_socket_connect_sync /home/elmarco/src/qq/io/channel-socket.c:145 + #3 0x5555596adebb in tcp_chr_connect_client_task /home/elmarco/src/qq/chardev/char-socket.c:1104 + #4 0x555559723d55 in qio_task_thread_worker /home/elmarco/src/qq/io/task.c:123 + #5 0x5555598a6731 in qemu_thread_start /home/elmarco/src/qq/util/qemu-thread-posix.c:519 + #6 0x7ffff40d4431 in start_thread (/lib64/libpthread.so.0+0x9431) + #7 0x7ffff40029d2 in __clone (/lib64/libc.so.6+0x1019d2) + +Signed-off-by: Marc-André Lureau +Reviewed-by: Daniel P. Berrangé +Message-Id: <20200420112012.567284-1-marcandre.lureau@redhat.com> +Signed-off-by: Zhenyu Ye +--- + chardev/char-socket.c | 3 ++- + tests/test-char.c | 53 ++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 54 insertions(+), 2 deletions(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 7ca5d97a..701b62f9 100644 +--- a/chardev/char-socket.c ++++ b/chardev/char-socket.c +@@ -1118,7 +1118,8 @@ static void tcp_chr_connect_client_async(Chardev *chr) + */ + s->connect_task = qio_task_new(OBJECT(sioc), + qemu_chr_socket_connected, +- chr, NULL); ++ object_ref(OBJECT(chr)), ++ (GDestroyNotify)object_unref); + qio_task_run_in_thread(s->connect_task, + tcp_chr_connect_client_task, + s->addr, +diff --git a/tests/test-char.c b/tests/test-char.c +index f9440cdc..0e4069fb 100644 +--- a/tests/test-char.c ++++ b/tests/test-char.c +@@ -871,6 +871,53 @@ typedef struct { + } CharSocketClientTestConfig; + + ++static void char_socket_client_dupid_test(gconstpointer opaque) ++{ ++ const CharSocketClientTestConfig *config = opaque; ++ QIOChannelSocket *ioc; ++ char *optstr; ++ Chardev *chr1, *chr2; ++ SocketAddress *addr; ++ QemuOpts *opts; ++ Error *local_err = NULL; ++ ++ /* ++ * Setup a listener socket and determine get its address ++ * so we know the TCP port for the client later ++ */ ++ ioc = qio_channel_socket_new(); ++ g_assert_nonnull(ioc); ++ qio_channel_socket_listen_sync(ioc, config->addr, &error_abort); ++ addr = qio_channel_socket_get_local_address(ioc, &error_abort); ++ g_assert_nonnull(addr); ++ ++ /* ++ * Populate the chardev address based on what the server ++ * is actually listening on ++ */ ++ optstr = char_socket_addr_to_opt_str(addr, ++ config->fd_pass, ++ config->reconnect, ++ false); ++ ++ opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), ++ optstr, true); ++ g_assert_nonnull(opts); ++ chr1 = qemu_chr_new_from_opts(opts, NULL, &error_abort); ++ g_assert_nonnull(chr1); ++ ++ chr2 = qemu_chr_new_from_opts(opts, NULL, &local_err); ++ g_assert_null(chr2); ++ error_free_or_abort(&local_err); ++ ++ object_unref(OBJECT(ioc)); ++ qemu_opts_del(opts); ++ object_unparent(OBJECT(chr1)); ++ qapi_free_SocketAddress(addr); ++ g_free(optstr); ++} ++ ++ + static void char_socket_client_test(gconstpointer opaque) + { + const CharSocketClientTestConfig *config = opaque; +@@ -1425,6 +1472,8 @@ int main(int argc, char **argv) + { addr, NULL, false, true }; \ + CharSocketClientTestConfig client6 ## name = \ + { addr, NULL, true, true }; \ ++ CharSocketClientTestConfig client7 ## name = \ ++ { addr, ",reconnect=1", false, false }; \ + g_test_add_data_func("/char/socket/client/mainloop/" # name, \ + &client1 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn/" # name, \ +@@ -1436,7 +1485,9 @@ int main(int argc, char **argv) + g_test_add_data_func("/char/socket/client/mainloop-fdpass/" # name, \ + &client5 ##name, char_socket_client_test); \ + g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \ +- &client6 ##name, char_socket_client_test) ++ &client6 ##name, char_socket_client_test); \ ++ g_test_add_data_func("/char/socket/client/dupid-reconnect/" # name, \ ++ &client7 ##name, char_socket_client_dupid_test) + + SOCKET_SERVER_TEST(tcp, &tcpaddr); + SOCKET_CLIENT_TEST(tcp, &tcpaddr); +-- +2.22.0.windows.1 + diff --git a/chardev-tcp-Fix-error-message-double-free-error.patch b/chardev-tcp-Fix-error-message-double-free-error.patch new file mode 100644 index 00000000..175ddfe2 --- /dev/null +++ b/chardev-tcp-Fix-error-message-double-free-error.patch @@ -0,0 +1,43 @@ +From 4488ab4700d344b049ddef808a64eda4b5867902 Mon Sep 17 00:00:00 2001 +From: lichun +Date: Mon, 22 Jun 2020 05:30:17 +0800 +Subject: [PATCH 06/11] chardev/tcp: Fix error message double free error + +Errors are already freed by error_report_err, so we only need to call +error_free when that function is not called. + +Cc: qemu-stable@nongnu.org +Signed-off-by: lichun +Message-Id: <20200621213017.17978-1-lichun@ruijie.com.cn> +Reviewed-by: Markus Armbruster +[Commit message improved, cc: qemu-stable] +Signed-off-by: Markus Armbruster +Signed-off-by: BiaoXiang Ye +--- + chardev/char-socket.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 701b62f9..9b06c8aa 100644 +--- a/chardev/char-socket.c ++++ b/chardev/char-socket.c +@@ -141,6 +141,8 @@ static void check_report_connect_error(Chardev *chr, + error_report("Unable to connect character device %s: %s", + chr->label, error_get_pretty(err)); + s->connect_err_reported = true; ++ } else { ++ error_free(err); + } + qemu_chr_socket_restart_timer(chr); + } +@@ -1074,7 +1076,6 @@ static void qemu_chr_socket_connected(QIOTask *task, void *opaque) + if (qio_task_propagate_error(task, &err)) { + tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); + check_report_connect_error(chr, err); +- error_free(err); + goto cleanup; + } + +-- +2.27.0.dirty + diff --git a/colo-compare-Fix-memory-leak-in-packet_enqueue.patch b/colo-compare-Fix-memory-leak-in-packet_enqueue.patch new file mode 100644 index 00000000..ca5e43c4 --- /dev/null +++ b/colo-compare-Fix-memory-leak-in-packet_enqueue.patch @@ -0,0 +1,90 @@ +From 19afb1431bd730a1e4e09e3c0835c35572517268 Mon Sep 17 00:00:00 2001 +From: Derek Su +Date: Fri, 22 May 2020 15:53:57 +0800 +Subject: [PATCH 07/11] colo-compare: Fix memory leak in packet_enqueue() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The patch is to fix the "pkt" memory leak in packet_enqueue(). +The allocated "pkt" needs to be freed if the colo compare +primary or secondary queue is too big. + +Replace the error_report of full queue with a trace event. + +Signed-off-by: Derek Su +Reviewed-by: Zhang Chen +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Zhang Chen +Signed-off-by: Jason Wang +Signed-off-by: BiaoXiang Ye +--- + net/colo-compare.c | 23 +++++++++++++++-------- + net/trace-events | 1 + + 2 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/net/colo-compare.c b/net/colo-compare.c +index 7ee17f2c..3168407e 100644 +--- a/net/colo-compare.c ++++ b/net/colo-compare.c +@@ -120,6 +120,10 @@ enum { + SECONDARY_IN, + }; + ++static const char *colo_mode[] = { ++ [PRIMARY_IN] = "primary", ++ [SECONDARY_IN] = "secondary", ++}; + + static int compare_chr_send(CompareState *s, + const uint8_t *buf, +@@ -215,6 +219,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) + ConnectionKey key; + Packet *pkt = NULL; + Connection *conn; ++ int ret; + + if (mode == PRIMARY_IN) { + pkt = packet_new(s->pri_rs.buf, +@@ -243,16 +248,18 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con) + } + + if (mode == PRIMARY_IN) { +- if (!colo_insert_packet(&conn->primary_list, pkt, &conn->pack)) { +- error_report("colo compare primary queue size too big," +- "drop packet"); +- } ++ ret = colo_insert_packet(&conn->primary_list, pkt, &conn->pack); + } else { +- if (!colo_insert_packet(&conn->secondary_list, pkt, &conn->sack)) { +- error_report("colo compare secondary queue size too big," +- "drop packet"); +- } ++ ret = colo_insert_packet(&conn->secondary_list, pkt, &conn->sack); + } ++ ++ if (!ret) { ++ trace_colo_compare_drop_packet(colo_mode[mode], ++ "queue size too big, drop packet"); ++ packet_destroy(pkt, NULL); ++ pkt = NULL; ++ } ++ + *con = conn; + + return 0; +diff --git a/net/trace-events b/net/trace-events +index ac570564..a9995387 100644 +--- a/net/trace-events ++++ b/net/trace-events +@@ -12,6 +12,7 @@ colo_proxy_main(const char *chr) ": %s" + + # colo-compare.c + colo_compare_main(const char *chr) ": %s" ++colo_compare_drop_packet(const char *queue, const char *chr) ": %s: %s" + colo_compare_udp_miscompare(const char *sta, int size) ": %s = %d" + colo_compare_icmp_miscompare(const char *sta, int size) ": %s = %d" + colo_compare_ip_info(int psize, const char *sta, const char *stb, int ssize, const char *stc, const char *std) "ppkt size = %d, ip_src = %s, ip_dst = %s, spkt size = %d, ip_src = %s, ip_dst = %s" +-- +2.27.0.dirty + diff --git a/cris-do-not-leak-struct-cris_disasm_data.patch b/cris-do-not-leak-struct-cris_disasm_data.patch new file mode 100644 index 00000000..fa7623fe --- /dev/null +++ b/cris-do-not-leak-struct-cris_disasm_data.patch @@ -0,0 +1,139 @@ +From d0586065e67b5df2611f4cf61eb791d48b78ff77 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:42:59 +0800 +Subject: [PATCH] cris: do not leak struct cris_disasm_data + +Use a stack-allocated struct to avoid a memory leak. + +Signed-off-by: Paolo Bonzini +--- + disas/cris.c | 65 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 35 insertions(+), 30 deletions(-) + +diff --git a/disas/cris.c b/disas/cris.c +index 2f43c9b2..f3ff44ba 100644 +--- a/disas/cris.c ++++ b/disas/cris.c +@@ -1294,24 +1294,17 @@ static int cris_constraint + /* Parse disassembler options and store state in info. FIXME: For the + time being, we abuse static variables. */ + +-static bfd_boolean +-cris_parse_disassembler_options (disassemble_info *info, ++static void ++cris_parse_disassembler_options (struct cris_disasm_data *disdata, ++ char *disassembler_options, + enum cris_disass_family distype) + { +- struct cris_disasm_data *disdata; +- +- info->private_data = calloc (1, sizeof (struct cris_disasm_data)); +- disdata = (struct cris_disasm_data *) info->private_data; +- if (disdata == NULL) +- return false; +- + /* Default true. */ + disdata->trace_case +- = (info->disassembler_options == NULL +- || (strcmp (info->disassembler_options, "nocase") != 0)); ++ = (disassembler_options == NULL ++ || (strcmp (disassembler_options, "nocase") != 0)); + + disdata->distype = distype; +- return true; + } + + static const struct cris_spec_reg * +@@ -2736,9 +2729,11 @@ static int + print_insn_cris_with_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v0_v10)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v0_v10); ++ + return print_insn_cris_generic (vma, info, true); + } + /* Disassemble, prefixing register names with `$'. CRIS v32. */ +@@ -2747,9 +2742,11 @@ static int + print_insn_crisv32_with_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v32); ++ + return print_insn_cris_generic (vma, info, true); + } + +@@ -2761,9 +2758,11 @@ static int + print_insn_crisv10_v32_with_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_common_v10_v32); ++ + return print_insn_cris_generic (vma, info, true); + } + +@@ -2773,9 +2772,11 @@ static int + print_insn_cris_without_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v0_v10)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v0_v10); ++ + return print_insn_cris_generic (vma, info, false); + } + +@@ -2785,9 +2786,11 @@ static int + print_insn_crisv32_without_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_v32); ++ + return print_insn_cris_generic (vma, info, false); + } + +@@ -2798,9 +2801,11 @@ static int + print_insn_crisv10_v32_without_register_prefix (bfd_vma vma, + disassemble_info *info) + { +- if (info->private_data == NULL +- && !cris_parse_disassembler_options (info, cris_dis_common_v10_v32)) +- return -1; ++ struct cris_disasm_data disdata; ++ info->private_data = &disdata; ++ cris_parse_disassembler_options (&disdata, info->disassembler_options, ++ cris_dis_common_v10_v32); ++ + return print_insn_cris_generic (vma, info, false); + } + #endif +-- +2.19.1 + diff --git a/display-bochs-display-fix-memory-leak.patch b/display-bochs-display-fix-memory-leak.patch new file mode 100644 index 00000000..4dd3aa61 --- /dev/null +++ b/display-bochs-display-fix-memory-leak.patch @@ -0,0 +1,35 @@ +From 7edca67dc630e31043644e87ede2e05e504f845b Mon Sep 17 00:00:00 2001 +From: Cameron Esfahani +Date: Tue, 10 Dec 2019 13:27:54 -0800 +Subject: [PATCH 1/8] display/bochs-display: fix memory leak +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix memory leak in bochs_display_update(). Leaks 304 bytes per frame. + +Fixes: 33ebad54056 +Signed-off-by: Cameron Esfahani +Message-Id: +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Gerd Hoffmann +--- + hw/display/bochs-display.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c +index 8e83b51..b601b2f 100644 +--- a/hw/display/bochs-display.c ++++ b/hw/display/bochs-display.c +@@ -251,6 +251,8 @@ static void bochs_display_update(void *opaque) + dpy_gfx_update(s->con, 0, ys, + mode.width, y - ys); + } ++ ++ g_free(snap); + } + } + +-- +1.8.3.1 + diff --git a/file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch b/file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch new file mode 100644 index 00000000..28c1e3bc --- /dev/null +++ b/file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch @@ -0,0 +1,31 @@ +From 94be73a20d42482cdf30115e672c36af2fe9068d Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 17 Jul 2020 12:54:26 +0200 +Subject: [PATCH 5/5] file-posix: Fix leaked fd in raw_open_common() error path + +Signed-off-by: Kevin Wolf +Message-Id: <20200717105426.51134-4-kwolf@redhat.com> +Reviewed-by: Max Reitz +Signed-off-by: Kevin Wolf +Signed-off-by: Zhenyu Ye +--- + block/file-posix.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/block/file-posix.c b/block/file-posix.c +index 2184aa98..1259bf58 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -671,6 +671,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, + bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK; + ret = 0; + fail: ++ if (ret < 0 && s->fd != -1) { ++ qemu_close(s->fd); ++ } + if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { + unlink(filename); + } +-- +2.22.0.windows.1 + diff --git a/fix-vhost_user_blk_watch-crash.patch b/fix-vhost_user_blk_watch-crash.patch new file mode 100644 index 00000000..905cbe3c --- /dev/null +++ b/fix-vhost_user_blk_watch-crash.patch @@ -0,0 +1,81 @@ +From 0b77995819a596f96c621697643e83624126e668 Mon Sep 17 00:00:00 2001 +From: Li Feng +Date: Mon, 23 Mar 2020 13:29:24 +0800 +Subject: [PATCH 13/14] fix vhost_user_blk_watch crash + +the G_IO_HUP is watched in tcp_chr_connect, and the callback +vhost_user_blk_watch is not needed, because tcp_chr_hup is registered as +callback. And it will close the tcp link. + +Signed-off-by: Li Feng +Message-Id: <20200323052924.29286-1-fengli@smartx.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Peng Liang +--- + hw/block/vhost-user-blk.c | 19 ------------------- + include/hw/virtio/vhost-user-blk.h | 1 - + 2 files changed, 20 deletions(-) + +diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c +index 85bc4017e7e9..dc66f8a5febd 100644 +--- a/hw/block/vhost-user-blk.c ++++ b/hw/block/vhost-user-blk.c +@@ -346,18 +346,6 @@ static void vhost_user_blk_disconnect(DeviceState *dev) + vhost_dev_cleanup(&s->dev); + } + +-static gboolean vhost_user_blk_watch(GIOChannel *chan, GIOCondition cond, +- void *opaque) +-{ +- DeviceState *dev = opaque; +- VirtIODevice *vdev = VIRTIO_DEVICE(dev); +- VHostUserBlk *s = VHOST_USER_BLK(vdev); +- +- qemu_chr_fe_disconnect(&s->chardev); +- +- return true; +-} +- + static void vhost_user_blk_event(void *opaque, int event) + { + DeviceState *dev = opaque; +@@ -370,15 +358,9 @@ static void vhost_user_blk_event(void *opaque, int event) + qemu_chr_fe_disconnect(&s->chardev); + return; + } +- s->watch = qemu_chr_fe_add_watch(&s->chardev, G_IO_HUP, +- vhost_user_blk_watch, dev); + break; + case CHR_EVENT_CLOSED: + vhost_user_blk_disconnect(dev); +- if (s->watch) { +- g_source_remove(s->watch); +- s->watch = 0; +- } + break; + } + } +@@ -419,7 +401,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) + + s->inflight = g_new0(struct vhost_inflight, 1); + s->vqs = g_new(struct vhost_virtqueue, s->num_queues); +- s->watch = 0; + s->connected = false; + + qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event, +diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h +index 8dbf11c6f071..ad9b742a644c 100644 +--- a/include/hw/virtio/vhost-user-blk.h ++++ b/include/hw/virtio/vhost-user-blk.h +@@ -38,7 +38,6 @@ typedef struct VHostUserBlk { + struct vhost_inflight *inflight; + VhostUserState vhost_user; + struct vhost_virtqueue *vqs; +- guint watch; + bool connected; + } VHostUserBlk; + +-- +2.26.2 + diff --git a/hmp-vnc-Fix-info-vnc-list-leak.patch b/hmp-vnc-Fix-info-vnc-list-leak.patch new file mode 100644 index 00000000..ccc4e1db --- /dev/null +++ b/hmp-vnc-Fix-info-vnc-list-leak.patch @@ -0,0 +1,48 @@ +From 6cb599f75b7844aefd7823ad97fc3bae70eff11f Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Mon, 23 Mar 2020 12:08:22 +0000 +Subject: [PATCH 06/14] hmp/vnc: Fix info vnc list leak + +We're iterating the list, and then freeing the iteration pointer rather +than the list head. + +Fixes: 0a9667ecdb6d ("hmp: Update info vnc") +Reported-by: Coverity (CID 1421932) +Signed-off-by: Dr. David Alan Gilbert +Message-Id: <20200323120822.51266-1-dgilbert@redhat.com> +Reviewed-by: Peter Maydell +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Peng Liang +--- + monitor/hmp-cmds.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 5ca3ebe94272..fc5d6b92c4b6 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -745,10 +745,11 @@ static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server) + + void hmp_info_vnc(Monitor *mon, const QDict *qdict) + { +- VncInfo2List *info2l; ++ VncInfo2List *info2l, *info2l_head; + Error *err = NULL; + + info2l = qmp_query_vnc_servers(&err); ++ info2l_head = info2l; + if (err) { + hmp_handle_error(mon, &err); + return; +@@ -777,7 +778,7 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict) + info2l = info2l->next; + } + +- qapi_free_VncInfo2List(info2l); ++ qapi_free_VncInfo2List(info2l_head); + + } + #endif +-- +2.26.2 + diff --git a/hppa-fix-leak-from-g_strdup_printf.patch b/hppa-fix-leak-from-g_strdup_printf.patch new file mode 100644 index 00000000..b04193e3 --- /dev/null +++ b/hppa-fix-leak-from-g_strdup_printf.patch @@ -0,0 +1,54 @@ +From b7ef7e6fb5a2b08268f4b19c07c07abd4fbb2064 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:48:49 +0800 +Subject: [PATCH] hppa: fix leak from g_strdup_printf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +memory_region_init_* takes care of copying the name into memory it owns. +Free it in the caller. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Philippe Mathieu-Daudé +--- + hw/hppa/dino.c | 1 + + hw/hppa/machine.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c +index e94614ab..ef923b49 100644 +--- a/hw/hppa/dino.c ++++ b/hw/hppa/dino.c +@@ -485,6 +485,7 @@ PCIBus *dino_init(MemoryRegion *addr_space, + memory_region_init_alias(&s->pci_mem_alias[i], OBJECT(s), + name, &s->pci_mem, addr, + DINO_MEM_CHUNK_SIZE); ++ g_free(name); + } + + /* Set up PCI view of memory: Bus master address space. */ +diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c +index 662838d8..9e25660e 100644 +--- a/hw/hppa/machine.c ++++ b/hw/hppa/machine.c +@@ -78,13 +78,15 @@ static void machine_hppa_init(MachineState *machine) + + /* Create CPUs. */ + for (i = 0; i < smp_cpus; i++) { ++ char *name = g_strdup_printf("cpu%ld-io-eir", i); + cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); + + cpu_region = g_new(MemoryRegion, 1); + memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops, +- cpu[i], g_strdup_printf("cpu%ld-io-eir", i), 4); ++ cpu[i], name, 4); + memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000, + cpu_region); ++ g_free(name); + } + + /* Limit main memory. */ +-- +2.19.1 + diff --git a/hw-block-nvme-fix-pci-doorbell-size-calculation.patch b/hw-block-nvme-fix-pci-doorbell-size-calculation.patch new file mode 100644 index 00000000..f0aa0967 --- /dev/null +++ b/hw-block-nvme-fix-pci-doorbell-size-calculation.patch @@ -0,0 +1,62 @@ +From 1aa42c9269c762ad1b7efa41e92f734b093dce1c Mon Sep 17 00:00:00 2001 +From: Klaus Jensen +Date: Tue, 9 Jun 2020 21:03:12 +0200 +Subject: [PATCH 10/11] hw/block/nvme: fix pci doorbell size calculation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The size of the BAR is 0x1000 (main registers) + 8 bytes for each +queue. Currently, the size of the BAR is calculated like so: + + n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4); + +Since the 'num_queues' parameter already accounts for the admin queue, +this should in any case not need to be incremented by one. Also, the +size should be initialized to (0x1000). + + n->reg_size = pow2ceil(0x1000 + 2 * n->num_queues * 4); + +This, with the default value of num_queues (64), we will set aside room +for 1 admin queue and 63 I/O queues (4 bytes per doorbell, 2 doorbells +per queue). + +Signed-off-by: Klaus Jensen +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Maxim Levitsky +Reviewed-by: Keith Busch +Message-Id: <20200609190333.59390-2-its@irrelevant.dk> +Signed-off-by: Kevin Wolf +Signed-off-by: BiaoXiang Ye +--- + hw/block/nvme.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/hw/block/nvme.c b/hw/block/nvme.c +index 417068d8..edac2f1d 100644 +--- a/hw/block/nvme.c ++++ b/hw/block/nvme.c +@@ -42,6 +42,9 @@ + #include "trace.h" + #include "nvme.h" + ++#define NVME_REG_SIZE 0x1000 ++#define NVME_DB_SIZE 4 ++ + #define NVME_GUEST_ERR(trace, fmt, ...) \ + do { \ + (trace_##trace)(__VA_ARGS__); \ +@@ -1348,7 +1351,9 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp) + pcie_endpoint_cap_init(pci_dev, 0x80); + + n->num_namespaces = 1; +- n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4); ++ ++ /* num_queues is really number of pairs, so each has two doorbells */ ++ n->reg_size = pow2ceil(NVME_REG_SIZE + 2 * n->num_queues * NVME_DB_SIZE); + n->ns_size = bs_size / (uint64_t)n->num_namespaces; + + n->namespaces = g_new0(NvmeNamespace, n->num_namespaces); +-- +2.27.0.dirty + diff --git a/hw-block-nvme-fix-pin-based-interrupt-behavior.patch b/hw-block-nvme-fix-pin-based-interrupt-behavior.patch new file mode 100644 index 00000000..1fe1213d --- /dev/null +++ b/hw-block-nvme-fix-pin-based-interrupt-behavior.patch @@ -0,0 +1,87 @@ +From 74ef18c90684f0ae18aef071b9e11a5e8796177b Mon Sep 17 00:00:00 2001 +From: alexchen +Date: Tue, 8 Sep 2020 11:17:20 +0000 +Subject: [PATCH] hw/block/nvme: fix pin-based interrupt behavior + +First, since the device only supports MSI-X or pin-based interrupt, if +MSI-X is not enabled, it should not accept interrupt vectors different +from 0 when creating completion queues. + +Secondly, the irq_status NvmeCtrl member is meant to be compared to the +INTMS register, so it should only be 32 bits wide. And it is really only +useful when used with multi-message MSI. + +Third, since we do not force a 1-to-1 correspondence between cqid and +interrupt vector, the irq_status register should not have bits set +according to cqid, but according to the associated interrupt vector. + +Fix these issues, but keep irq_status available so we can easily support +multi-message MSI down the line. + +Fixes: 5e9aa92eb1a5 ("hw/block: Fix pin-based interrupt behaviour of NVMe") +Cc: "Michael S. Tsirkin" +Cc: Marcel Apfelbaum +Signed-off-by: Klaus Jensen +Reviewed-by: Keith Busch +Message-Id: <20200609190333.59390-8-its@irrelevant.dk> +Signed-off-by: Kevin Wolf +Signed-off-by: BiaoXiang Ye +Signed-off-by: Zhenyu Ye +--- + hw/block/nvme.c | 12 ++++++++---- + hw/block/nvme.h | 2 +- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/hw/block/nvme.c b/hw/block/nvme.c +index 36d6a8bb..e35c2e10 100644 +--- a/hw/block/nvme.c ++++ b/hw/block/nvme.c +@@ -115,8 +115,8 @@ static void nvme_irq_assert(NvmeCtrl *n, NvmeCQueue *cq) + msix_notify(&(n->parent_obj), cq->vector); + } else { + trace_nvme_irq_pin(); +- assert(cq->cqid < 64); +- n->irq_status |= 1 << cq->cqid; ++ assert(cq->vector < 32); ++ n->irq_status |= 1 << cq->vector; + nvme_irq_check(n); + } + } else { +@@ -130,8 +130,8 @@ static void nvme_irq_deassert(NvmeCtrl *n, NvmeCQueue *cq) + if (msix_enabled(&(n->parent_obj))) { + return; + } else { +- assert(cq->cqid < 64); +- n->irq_status &= ~(1 << cq->cqid); ++ assert(cq->vector < 32); ++ n->irq_status &= ~(1 << cq->vector); + nvme_irq_check(n); + } + } +@@ -630,6 +630,10 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd) + trace_nvme_err_invalid_create_cq_addr(prp1); + return NVME_INVALID_FIELD | NVME_DNR; + } ++ if (unlikely(!msix_enabled(&n->parent_obj) && vector)) { ++ trace_nvme_err_invalid_create_cq_vector(vector); ++ return NVME_INVALID_IRQ_VECTOR | NVME_DNR; ++ } + if (unlikely(vector > n->num_queues)) { + trace_nvme_err_invalid_create_cq_vector(vector); + return NVME_INVALID_IRQ_VECTOR | NVME_DNR; +diff --git a/hw/block/nvme.h b/hw/block/nvme.h +index 557194ee..f4c1ff91 100644 +--- a/hw/block/nvme.h ++++ b/hw/block/nvme.h +@@ -78,7 +78,7 @@ typedef struct NvmeCtrl { + uint32_t cmbsz; + uint32_t cmbloc; + uint8_t *cmbuf; +- uint64_t irq_status; ++ uint32_t irq_status; + uint64_t host_timestamp; /* Timestamp sent by the host */ + uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */ + +-- +2.23.0 + diff --git a/hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch b/hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch new file mode 100644 index 00000000..76497d9e --- /dev/null +++ b/hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch @@ -0,0 +1,67 @@ +From 595a0d0a0f21cd73863ea3b78ecccb6e0ea8b7a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Mon, 1 Jun 2020 16:29:25 +0200 +Subject: [PATCH 2/5] hw/pci/pci_bridge: Correct pci_bridge_io memory region + size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +memory_region_set_size() handle the 16 Exabytes limit by +special-casing the UINT64_MAX value. This is not a problem +for the 32-bit maximum, 4 GiB. +By using the UINT32_MAX value, the pci_bridge_io MemoryRegion +ends up missing 1 byte: + + (qemu) info mtree + memory-region: pci_bridge_io + 0000000000000000-00000000fffffffe (prio 0, i/o): pci_bridge_io + 0000000000000060-0000000000000060 (prio 0, i/o): i8042-data + 0000000000000064-0000000000000064 (prio 0, i/o): i8042-cmd + 00000000000001ce-00000000000001d1 (prio 0, i/o): vbe + 0000000000000378-000000000000037f (prio 0, i/o): parallel + 00000000000003b4-00000000000003b5 (prio 0, i/o): vga + ... + +Fix by using the correct value. We now have: + + memory-region: pci_bridge_io + 0000000000000000-00000000ffffffff (prio 0, i/o): pci_bridge_io + 0000000000000060-0000000000000060 (prio 0, i/o): i8042-data + 0000000000000064-0000000000000064 (prio 0, i/o): i8042-cmd + ... + +Reviewed-by: Peter Maydell +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20200601142930.29408-4-f4bug@amsat.org> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Richard Henderson +--- + hw/pci/pci_bridge.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c +index 715b9a4f..d67c691d 100644 +--- a/hw/pci/pci_bridge.c ++++ b/hw/pci/pci_bridge.c +@@ -30,6 +30,7 @@ + */ + + #include "qemu/osdep.h" ++#include "qemu/units.h" + #include "hw/pci/pci_bridge.h" + #include "hw/pci/pci_bus.h" + #include "qemu/module.h" +@@ -381,7 +382,7 @@ void pci_bridge_initfn(PCIDevice *dev, const char *typename) + memory_region_init(&br->address_space_mem, OBJECT(br), "pci_bridge_pci", UINT64_MAX); + sec_bus->address_space_io = &br->address_space_io; + memory_region_init(&br->address_space_io, OBJECT(br), "pci_bridge_io", +- UINT32_MAX); ++ 4 * GiB); + br->windows = pci_bridge_region_init(br); + QLIST_INIT(&sec_bus->child); + QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); +-- +2.23.0 + diff --git a/ide-fix-leak-from-qemu_allocate_irqs.patch b/ide-fix-leak-from-qemu_allocate_irqs.patch new file mode 100644 index 00000000..dce6e906 --- /dev/null +++ b/ide-fix-leak-from-qemu_allocate_irqs.patch @@ -0,0 +1,28 @@ +From df35f8fe2687df32cb65f6a03b8dd80314cc4c53 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 15:00:08 +0800 +Subject: [PATCH] ide: fix leak from qemu_allocate_irqs + +The array returned by qemu_allocate_irqs is malloced, free it. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Thomas Huth +--- + hw/ide/cmd646.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c +index ed23aabf..a149cd6c 100644 +--- a/hw/ide/cmd646.c ++++ b/hw/ide/cmd646.c +@@ -299,6 +299,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) + d->bmdma[i].bus = &d->bus[i]; + ide_register_restart_cb(&d->bus[i]); + } ++ g_free(irq); + + vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); + qemu_register_reset(cmd646_reset, d); +-- +2.19.1 + diff --git a/linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch b/linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch new file mode 100644 index 00000000..2d0c6abf --- /dev/null +++ b/linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch @@ -0,0 +1,34 @@ +From 7b4aded3f772ef43e2b600594f755eadd5da5958 Mon Sep 17 00:00:00 2001 +From: Jonathan Marler +Date: Sat, 2 May 2020 10:12:25 -0600 +Subject: [PATCH 3/5] linux-user/mmap.c: fix integer underflow in target_mremap + +Fixes: https://bugs.launchpad.net/bugs/1876373 + +This code path in mmap occurs when a page size is decreased with mremap. When a section of pages is shrunk, qemu calls mmap_reserve on the pages that were released. However, it has the diff operation reversed, subtracting the larger old_size from the smaller new_size. Instead, it should be subtracting the smaller new_size from the larger old_size. You can also see in the previous line of the change that this mmap_reserve call only occurs when old_size > new_size. + +Bug: https://bugs.launchpad.net/qemu/+bug/1876373 +Signed-off-by: Jonathan Marler +Reviewded-by: Laurent Vivier +Message-Id: <20200502161225.14346-1-johnnymarler@gmail.com> +Signed-off-by: Laurent Vivier +--- + linux-user/mmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/linux-user/mmap.c b/linux-user/mmap.c +index 46a6e3a7..2a9ca0c3 100644 +--- a/linux-user/mmap.c ++++ b/linux-user/mmap.c +@@ -740,7 +740,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, + if (prot == 0) { + host_addr = mremap(g2h(old_addr), old_size, new_size, flags); + if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) { +- mmap_reserve(old_addr + old_size, new_size - old_size); ++ mmap_reserve(old_addr + old_size, old_size - new_size); + } + } else { + errno = ENOMEM; +-- +2.23.0 + diff --git a/lm32-do-not-leak-memory-on-object_new-object_unref.patch b/lm32-do-not-leak-memory-on-object_new-object_unref.patch new file mode 100644 index 00000000..7ccc5368 --- /dev/null +++ b/lm32-do-not-leak-memory-on-object_new-object_unref.patch @@ -0,0 +1,77 @@ +From d50be5295c49be1b6024f5902948b52e683b4c23 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:18:35 +0800 +Subject: [PATCH] lm32: do not leak memory on object_new/object_unref +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bottom halves and ptimers are malloced, but nothing in these +files is freeing memory allocated by instance_init. Since +these are sysctl devices that are never unrealized, just moving +the allocations to realize is enough to avoid the leak in +practice (and also to avoid upsetting asan when running +device-introspect-test). + +Signed-off-by: Paolo Bonzini +Reviewed-by: Philippe Mathieu-Daudé +--- + hw/timer/lm32_timer.c | 6 +++--- + hw/timer/milkymist-sysctl.c | 10 +++++----- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/hw/timer/lm32_timer.c b/hw/timer/lm32_timer.c +index 6ce876c6..13f15825 100644 +--- a/hw/timer/lm32_timer.c ++++ b/hw/timer/lm32_timer.c +@@ -184,9 +184,6 @@ static void lm32_timer_init(Object *obj) + + sysbus_init_irq(dev, &s->irq); + +- s->bh = qemu_bh_new(timer_hit, s); +- s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT); +- + memory_region_init_io(&s->iomem, obj, &timer_ops, s, + "timer", R_MAX * 4); + sysbus_init_mmio(dev, &s->iomem); +@@ -196,6 +193,9 @@ static void lm32_timer_realize(DeviceState *dev, Error **errp) + { + LM32TimerState *s = LM32_TIMER(dev); + ++ s->bh = qemu_bh_new(timer_hit, s); ++ s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT); ++ + ptimer_set_freq(s->ptimer, s->freq_hz); + } + +diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c +index a9d25087..2f1ecc6d 100644 +--- a/hw/timer/milkymist-sysctl.c ++++ b/hw/timer/milkymist-sysctl.c +@@ -280,11 +280,6 @@ static void milkymist_sysctl_init(Object *obj) + sysbus_init_irq(dev, &s->timer0_irq); + sysbus_init_irq(dev, &s->timer1_irq); + +- s->bh0 = qemu_bh_new(timer0_hit, s); +- s->bh1 = qemu_bh_new(timer1_hit, s); +- s->ptimer0 = ptimer_init(s->bh0, PTIMER_POLICY_DEFAULT); +- s->ptimer1 = ptimer_init(s->bh1, PTIMER_POLICY_DEFAULT); +- + memory_region_init_io(&s->regs_region, obj, &sysctl_mmio_ops, s, + "milkymist-sysctl", R_MAX * 4); + sysbus_init_mmio(dev, &s->regs_region); +@@ -294,6 +289,11 @@ static void milkymist_sysctl_realize(DeviceState *dev, Error **errp) + { + MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev); + ++ s->bh0 = qemu_bh_new(timer0_hit, s); ++ s->bh1 = qemu_bh_new(timer1_hit, s); ++ s->ptimer0 = ptimer_init(s->bh0, PTIMER_POLICY_DEFAULT); ++ s->ptimer1 = ptimer_init(s->bh1, PTIMER_POLICY_DEFAULT); ++ + ptimer_set_freq(s->ptimer0, s->freq_hz); + ptimer_set_freq(s->ptimer1, s->freq_hz); + } +-- +2.19.1 + diff --git a/make-check-unit-use-after-free-in-test-opts-visitor.patch b/make-check-unit-use-after-free-in-test-opts-visitor.patch new file mode 100644 index 00000000..59097000 --- /dev/null +++ b/make-check-unit-use-after-free-in-test-opts-visitor.patch @@ -0,0 +1,102 @@ +From e3dfb5d2848975e9e947cb894afac87ce386a2bc Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 15:18:52 +0800 +Subject: [PATCH] make check-unit: use after free in test-opts-visitor + +In the struct OptsVisitor, the 'repeated_opts' member points to a list +in the 'unprocessed_opts' hash table after the list has been destroyed. +A subsequent call to visit_type_int() references the deleted list. +It results in use-after-free issue reproduced by running the test case +under the Valgrind: valgrind tests/test-opts-visitor. +A new mode ListMode::LM_TRAVERSED is declared to mark the list +traversal completed. + +Suggested-by: Markus Armbruster +Signed-off-by: Andrey Shinkevich +Message-Id: <1565024586-387112-1-git-send-email-andrey.shinkevich@virtuozzo.com> +--- + qapi/opts-visitor.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c +index 324b1974..42d87df6 100644 +--- a/qapi/opts-visitor.c ++++ b/qapi/opts-visitor.c +@@ -24,7 +24,8 @@ enum ListMode + { + LM_NONE, /* not traversing a list of repeated options */ + +- LM_IN_PROGRESS, /* opts_next_list() ready to be called. ++ LM_IN_PROGRESS, /* ++ * opts_next_list() ready to be called. + * + * Generating the next list link will consume the most + * recently parsed QemuOpt instance of the repeated +@@ -36,7 +37,8 @@ enum ListMode + * LM_UNSIGNED_INTERVAL. + */ + +- LM_SIGNED_INTERVAL, /* opts_next_list() has been called. ++ LM_SIGNED_INTERVAL, /* ++ * opts_next_list() has been called. + * + * Generating the next list link will consume the most + * recently stored element from the signed interval, +@@ -48,7 +50,14 @@ enum ListMode + * next element of the signed interval. + */ + +- LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */ ++ LM_UNSIGNED_INTERVAL, /* Same as above, only for an unsigned interval. */ ++ ++ LM_TRAVERSED /* ++ * opts_next_list() has been called. ++ * ++ * No more QemuOpt instance in the list. ++ * The traversal has been completed. ++ */ + }; + + typedef enum ListMode ListMode; +@@ -238,6 +247,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size) + OptsVisitor *ov = to_ov(v); + + switch (ov->list_mode) { ++ case LM_TRAVERSED: ++ return NULL; + case LM_SIGNED_INTERVAL: + case LM_UNSIGNED_INTERVAL: + if (ov->list_mode == LM_SIGNED_INTERVAL) { +@@ -258,6 +269,8 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size) + opt = g_queue_pop_head(ov->repeated_opts); + if (g_queue_is_empty(ov->repeated_opts)) { + g_hash_table_remove(ov->unprocessed_opts, opt->name); ++ ov->repeated_opts = NULL; ++ ov->list_mode = LM_TRAVERSED; + return NULL; + } + break; +@@ -289,7 +302,8 @@ opts_end_list(Visitor *v, void **obj) + + assert(ov->list_mode == LM_IN_PROGRESS || + ov->list_mode == LM_SIGNED_INTERVAL || +- ov->list_mode == LM_UNSIGNED_INTERVAL); ++ ov->list_mode == LM_UNSIGNED_INTERVAL || ++ ov->list_mode == LM_TRAVERSED); + ov->repeated_opts = NULL; + ov->list_mode = LM_NONE; + } +@@ -306,6 +320,10 @@ lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp) + list = lookup_distinct(ov, name, errp); + return list ? g_queue_peek_tail(list) : NULL; + } ++ if (ov->list_mode == LM_TRAVERSED) { ++ error_setg(errp, "Fewer list elements than expected"); ++ return NULL; ++ } + assert(ov->list_mode == LM_IN_PROGRESS); + return g_queue_peek_head(ov->repeated_opts); + } +-- +2.19.1 + diff --git a/mcf5208-fix-leak-from-qemu_allocate_irqs.patch b/mcf5208-fix-leak-from-qemu_allocate_irqs.patch new file mode 100644 index 00000000..7e254f57 --- /dev/null +++ b/mcf5208-fix-leak-from-qemu_allocate_irqs.patch @@ -0,0 +1,29 @@ +From 07b7cdb648124748c34be299fbfdfe3b6e38a521 Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:53:00 +0800 +Subject: [PATCH] mcf5208: fix leak from qemu_allocate_irqs + +The array returned by qemu_allocate_irqs is malloced, free it. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Thomas Huth +--- + hw/m68k/mcf5208.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c +index 6f6efae9..cc765eac 100644 +--- a/hw/m68k/mcf5208.c ++++ b/hw/m68k/mcf5208.c +@@ -270,6 +270,8 @@ static void mcf5208evb_init(MachineState *machine) + 0xfc030000, pic + 36); + } + ++ g_free(pic); ++ + /* 0xfc000000 SCM. */ + /* 0xfc004000 XBS. */ + /* 0xfc008000 FlexBus CS. */ +-- +2.19.1 + diff --git a/microblaze-fix-leak-of-fdevice-tree-blob.patch b/microblaze-fix-leak-of-fdevice-tree-blob.patch new file mode 100644 index 00000000..dd845e80 --- /dev/null +++ b/microblaze-fix-leak-of-fdevice-tree-blob.patch @@ -0,0 +1,32 @@ +From 2ff9c28e2b72cd359a0c4e931412e355baee8e1e Mon Sep 17 00:00:00 2001 +From: lizhengui +Date: Wed, 9 Sep 2020 14:55:11 +0800 +Subject: [PATCH] microblaze: fix leak of fdevice tree blob +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The device tree blob returned by load_device_tree is malloced. +Free it before returning. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Philippe Mathieu-Daudé +--- + hw/microblaze/boot.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c +index a7af4c07..0fcc4e9d 100644 +--- a/hw/microblaze/boot.c ++++ b/hw/microblaze/boot.c +@@ -99,6 +99,7 @@ static int microblaze_load_dtb(hwaddr addr, + } + + cpu_physical_memory_write(addr, fdt, fdt_size); ++ g_free(fdt); + return fdt_size; + } + +-- +2.19.1 + diff --git a/migration-Change-SaveStateEntry.instance_id-into-uin.patch b/migration-Change-SaveStateEntry.instance_id-into-uin.patch new file mode 100644 index 00000000..3eb83b39 --- /dev/null +++ b/migration-Change-SaveStateEntry.instance_id-into-uin.patch @@ -0,0 +1,158 @@ +From 2eadc5c611ca8cc916f74c0f393f1fd942903ef7 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 16 Oct 2019 10:29:31 +0800 +Subject: [PATCH 6/8] migration: Change SaveStateEntry.instance_id into + uint32_t + +It was always used as 32bit, so define it as used to be clear. +Instead of using -1 as the auto-gen magic value, we switch to +UINT32_MAX. We also make sure that we don't auto-gen this value to +avoid overflowed instance IDs without being noticed. + +Suggested-by: Juan Quintela +Signed-off-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +--- + hw/intc/apic_common.c | 2 +- + include/migration/register.h | 2 +- + include/migration/vmstate.h | 2 +- + migration/savevm.c | 18 ++++++++++-------- + stubs/vmstate.c | 2 +- + 5 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c +index faea1af..07adba0 100644 +--- a/hw/intc/apic_common.c ++++ b/hw/intc/apic_common.c +@@ -313,7 +313,7 @@ static void apic_common_realize(DeviceState *dev, Error **errp) + APICCommonState *s = APIC_COMMON(dev); + APICCommonClass *info; + static DeviceState *vapic; +- int instance_id = s->id; ++ uint32_t instance_id = s->id; + + info = APIC_COMMON_GET_CLASS(s); + info->realize(dev, errp); +diff --git a/include/migration/register.h b/include/migration/register.h +index 3d0b983..8b2bc5b 100644 +--- a/include/migration/register.h ++++ b/include/migration/register.h +@@ -70,7 +70,7 @@ typedef struct SaveVMHandlers { + + int register_savevm_live(DeviceState *dev, + const char *idstr, +- int instance_id, ++ uint32_t instance_id, + int version_id, + const SaveVMHandlers *ops, + void *opaque); +diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h +index 92f531a..8abd2e3 100644 +--- a/include/migration/vmstate.h ++++ b/include/migration/vmstate.h +@@ -1117,7 +1117,7 @@ bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque); + #define VMSTATE_INSTANCE_ID_ANY -1 + + /* Returns: 0 on success, -1 on failure */ +-int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, ++int vmstate_register_with_alias_id(DeviceState *dev, uint32_t instance_id, + const VMStateDescription *vmsd, + void *base, int alias_id, + int required_for_version, +diff --git a/migration/savevm.c b/migration/savevm.c +index 62552ab..7d89c57 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -229,7 +229,7 @@ typedef struct CompatEntry { + typedef struct SaveStateEntry { + QTAILQ_ENTRY(SaveStateEntry) entry; + char idstr[256]; +- int instance_id; ++ uint32_t instance_id; + int alias_id; + int version_id; + /* version id read from the stream */ +@@ -616,10 +616,10 @@ void dump_vmstate_json_to_file(FILE *out_file) + fclose(out_file); + } + +-static int calculate_new_instance_id(const char *idstr) ++static uint32_t calculate_new_instance_id(const char *idstr) + { + SaveStateEntry *se; +- int instance_id = 0; ++ uint32_t instance_id = 0; + + QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { + if (strcmp(idstr, se->idstr) == 0 +@@ -627,6 +627,8 @@ static int calculate_new_instance_id(const char *idstr) + instance_id = se->instance_id + 1; + } + } ++ /* Make sure we never loop over without being noticed */ ++ assert(instance_id != VMSTATE_INSTANCE_ID_ANY); + return instance_id; + } + +@@ -682,7 +684,7 @@ static void savevm_state_handler_insert(SaveStateEntry *nse) + distinguishing id for all instances of your device class. */ + int register_savevm_live(DeviceState *dev, + const char *idstr, +- int instance_id, ++ uint32_t instance_id, + int version_id, + const SaveVMHandlers *ops, + void *opaque) +@@ -756,7 +758,7 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque) + } + } + +-int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, ++int vmstate_register_with_alias_id(DeviceState *dev, uint32_t instance_id, + const VMStateDescription *vmsd, + void *opaque, int alias_id, + int required_for_version, +@@ -1507,7 +1509,7 @@ int qemu_save_device_state(QEMUFile *f) + return qemu_file_get_error(f); + } + +-static SaveStateEntry *find_se(const char *idstr, int instance_id) ++static SaveStateEntry *find_se(const char *idstr, uint32_t instance_id) + { + SaveStateEntry *se; + +@@ -2187,7 +2189,7 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis) + /* Find savevm section */ + se = find_se(idstr, instance_id); + if (se == NULL) { +- error_report("Unknown savevm section or instance '%s' %d. " ++ error_report("Unknown savevm section or instance '%s' %"PRIu32". " + "Make sure that your current VM setup matches your " + "saved VM setup, including any hotplugged devices", + idstr, instance_id); +@@ -2211,7 +2213,7 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis) + + ret = vmstate_load(f, se); + if (ret < 0) { +- error_report("error while loading state for instance 0x%x of" ++ error_report("error while loading state for instance 0x%"PRIx32" of" + " device '%s'", instance_id, idstr); + return ret; + } +diff --git a/stubs/vmstate.c b/stubs/vmstate.c +index e1e89b8..4ed5cc6 100644 +--- a/stubs/vmstate.c ++++ b/stubs/vmstate.c +@@ -4,7 +4,7 @@ + const VMStateDescription vmstate_dummy = {}; + + int vmstate_register_with_alias_id(DeviceState *dev, +- int instance_id, ++ uint32_t instance_id, + const VMStateDescription *vmsd, + void *base, int alias_id, + int required_for_version, +-- +1.8.3.1 + diff --git a/migration-Count-new_dirty-instead-of-real_dirty.patch b/migration-Count-new_dirty-instead-of-real_dirty.patch new file mode 100644 index 00000000..a9ff297f --- /dev/null +++ b/migration-Count-new_dirty-instead-of-real_dirty.patch @@ -0,0 +1,74 @@ +From 63320ae36834e4ff2f0d139f205c464caa3887b4 Mon Sep 17 00:00:00 2001 +From: Keqian Zhu +Date: Mon, 22 Jun 2020 11:20:37 +0800 +Subject: [PATCH 04/11] migration: Count new_dirty instead of real_dirty + +real_dirty_pages becomes equal to total ram size after dirty log sync +in ram_init_bitmaps, the reason is that the bitmap of ramblock is +initialized to be all set, so old path counts them as "real dirty" at +beginning. + +This causes wrong dirty rate and false positive throttling. + +Signed-off-by: Keqian Zhu +Message-Id: <20200622032037.31112-1-zhukeqian1@huawei.com> +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: BiaoXiang Ye +--- + include/exec/ram_addr.h | 5 +---- + migration/ram.c | 8 +++++--- + 2 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h +index b7b2e60f..52344066 100644 +--- a/include/exec/ram_addr.h ++++ b/include/exec/ram_addr.h +@@ -485,8 +485,7 @@ static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, + static inline + uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + ram_addr_t start, +- ram_addr_t length, +- uint64_t *real_dirty_pages) ++ ram_addr_t length) + { + ram_addr_t addr; + unsigned long word = BIT_WORD((start + rb->offset) >> TARGET_PAGE_BITS); +@@ -512,7 +511,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + if (src[idx][offset]) { + unsigned long bits = atomic_xchg(&src[idx][offset], 0); + unsigned long new_dirty; +- *real_dirty_pages += ctpopl(bits); + new_dirty = ~dest[k]; + dest[k] |= bits; + new_dirty &= bits; +@@ -545,7 +543,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + start + addr + offset, + TARGET_PAGE_SIZE, + DIRTY_MEMORY_MIGRATION)) { +- *real_dirty_pages += 1; + long k = (start + addr) >> TARGET_PAGE_BITS; + if (!test_and_set_bit(k, dest)) { + num_dirty++; +diff --git a/migration/ram.c b/migration/ram.c +index 840e3548..83cabec6 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1765,9 +1765,11 @@ static inline bool migration_bitmap_clear_dirty(RAMState *rs, + static void migration_bitmap_sync_range(RAMState *rs, RAMBlock *rb, + ram_addr_t length) + { +- rs->migration_dirty_pages += +- cpu_physical_memory_sync_dirty_bitmap(rb, 0, length, +- &rs->num_dirty_pages_period); ++ uint64_t new_dirty_pages = ++ cpu_physical_memory_sync_dirty_bitmap(rb, 0, rb->used_length); ++ ++ rs->migration_dirty_pages += new_dirty_pages; ++ rs->num_dirty_pages_period += new_dirty_pages; + } + + /** +-- +2.27.0.dirty + diff --git a/migration-Define-VMSTATE_INSTANCE_ID_ANY.patch b/migration-Define-VMSTATE_INSTANCE_ID_ANY.patch new file mode 100644 index 00000000..cd32b049 --- /dev/null +++ b/migration-Define-VMSTATE_INSTANCE_ID_ANY.patch @@ -0,0 +1,237 @@ +From 21e049e2941b108df45c9089cbf7539caae538e6 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 16 Oct 2019 10:29:30 +0800 +Subject: [PATCH 5/8] migration: Define VMSTATE_INSTANCE_ID_ANY + +Define the new macro VMSTATE_INSTANCE_ID_ANY for callers who wants to +auto-generate the vmstate instance ID. Previously it was hard coded +as -1 instead of this macro. It helps to change this default value in +the follow up patches. No functional change. + +Signed-off-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +--- + hw/arm/stellaris.c | 2 +- + hw/core/qdev.c | 4 +++- + hw/display/ads7846.c | 2 +- + hw/i2c/core.c | 2 +- + hw/input/stellaris_input.c | 3 ++- + hw/intc/apic_common.c | 2 +- + hw/misc/max111x.c | 3 ++- + hw/net/eepro100.c | 3 ++- + hw/pci/pci.c | 2 +- + hw/ppc/spapr.c | 2 +- + hw/timer/arm_timer.c | 2 +- + hw/tpm/tpm_emulator.c | 3 ++- + include/migration/vmstate.h | 2 ++ + migration/savevm.c | 8 ++++---- + 14 files changed, 24 insertions(+), 16 deletions(-) + +diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c +index 499035f..3432033 100644 +--- a/hw/arm/stellaris.c ++++ b/hw/arm/stellaris.c +@@ -705,7 +705,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq, + memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000); + memory_region_add_subregion(get_system_memory(), base, &s->iomem); + ssys_reset(s); +- vmstate_register(NULL, -1, &vmstate_stellaris_sys, s); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_stellaris_sys, s); + return 0; + } + +diff --git a/hw/core/qdev.c b/hw/core/qdev.c +index 94ebc0a..4b32f2f 100644 +--- a/hw/core/qdev.c ++++ b/hw/core/qdev.c +@@ -848,7 +848,9 @@ static void device_set_realized(Object *obj, bool value, Error **errp) + dev->canonical_path = object_get_canonical_path(OBJECT(dev)); + + if (qdev_get_vmsd(dev)) { +- if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev, ++ if (vmstate_register_with_alias_id(dev, ++ VMSTATE_INSTANCE_ID_ANY, ++ qdev_get_vmsd(dev), dev, + dev->instance_id_alias, + dev->alias_required_for_version, + &local_err) < 0) { +diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c +index 1a97e97..be1802e 100644 +--- a/hw/display/ads7846.c ++++ b/hw/display/ads7846.c +@@ -152,7 +152,7 @@ static void ads7846_realize(SSISlave *d, Error **errp) + + ads7846_int_update(s); + +- vmstate_register(NULL, -1, &vmstate_ads7846, s); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_ads7846, s); + } + + static void ads7846_class_init(ObjectClass *klass, void *data) +diff --git a/hw/i2c/core.c b/hw/i2c/core.c +index 20f36f1..186702b 100644 +--- a/hw/i2c/core.c ++++ b/hw/i2c/core.c +@@ -59,7 +59,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name) + + bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name)); + QLIST_INIT(&bus->current_devs); +- vmstate_register(NULL, -1, &vmstate_i2c_bus, bus); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus); + return bus; + } + +diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c +index 3a666d6..6c5b6d8 100644 +--- a/hw/input/stellaris_input.c ++++ b/hw/input/stellaris_input.c +@@ -86,5 +86,6 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) + } + s->num_buttons = n; + qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s); +- vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, ++ &vmstate_stellaris_gamepad, s); + } +diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c +index e764a2b..faea1af 100644 +--- a/hw/intc/apic_common.c ++++ b/hw/intc/apic_common.c +@@ -329,7 +329,7 @@ static void apic_common_realize(DeviceState *dev, Error **errp) + } + + if (s->legacy_instance_id) { +- instance_id = -1; ++ instance_id = VMSTATE_INSTANCE_ID_ANY; + } + vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common, + s, -1, 0, NULL); +diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c +index d373ece..364cb01 100644 +--- a/hw/misc/max111x.c ++++ b/hw/misc/max111x.c +@@ -144,7 +144,8 @@ static int max111x_init(SSISlave *d, int inputs) + s->input[7] = 0x80; + s->com = 0; + +- vmstate_register(dev, -1, &vmstate_max111x, s); ++ vmstate_register(dev, VMSTATE_INSTANCE_ID_ANY, ++ &vmstate_max111x, s); + return 0; + } + +diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c +index 6607c91..03edd25 100644 +--- a/hw/net/eepro100.c ++++ b/hw/net/eepro100.c +@@ -1872,7 +1872,8 @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) + + s->vmstate = g_memdup(&vmstate_eepro100, sizeof(vmstate_eepro100)); + s->vmstate->name = qemu_get_queue(s->nic)->model; +- vmstate_register(&pci_dev->qdev, -1, s->vmstate, s); ++ vmstate_register(&pci_dev->qdev, VMSTATE_INSTANCE_ID_ANY, ++ s->vmstate, s); + } + + static void eepro100_instance_init(Object *obj) +diff --git a/hw/pci/pci.c b/hw/pci/pci.c +index 8076a80..e74143c 100644 +--- a/hw/pci/pci.c ++++ b/hw/pci/pci.c +@@ -118,7 +118,7 @@ static void pci_bus_realize(BusState *qbus, Error **errp) + bus->machine_done.notify = pcibus_machine_done; + qemu_add_machine_init_done_notifier(&bus->machine_done); + +- vmstate_register(NULL, -1, &vmstate_pcibus, bus); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_pcibus, bus); + } + + static void pcie_bus_realize(BusState *qbus, Error **errp) +diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c +index 12ed4b0..b0f37c3 100644 +--- a/hw/ppc/spapr.c ++++ b/hw/ppc/spapr.c +@@ -3069,7 +3069,7 @@ static void spapr_machine_init(MachineState *machine) + * interface, this is a legacy from the sPAPREnvironment structure + * which predated MachineState but had a similar function */ + vmstate_register(NULL, 0, &vmstate_spapr, spapr); +- register_savevm_live(NULL, "spapr/htab", -1, 1, ++ register_savevm_live(NULL, "spapr/htab", VMSTATE_INSTANCE_ID_ANY, 1, + &savevm_htab_handlers, spapr); + + qbus_set_hotplug_handler(sysbus_get_default(), OBJECT(machine), +diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c +index f0a7534..1ce4e01 100644 +--- a/hw/timer/arm_timer.c ++++ b/hw/timer/arm_timer.c +@@ -172,7 +172,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq) + + bh = qemu_bh_new(arm_timer_tick, s); + s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT); +- vmstate_register(NULL, -1, &vmstate_arm_timer, s); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_arm_timer, s); + return s; + } + +diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c +index 38bf5fd..836c489 100644 +--- a/hw/tpm/tpm_emulator.c ++++ b/hw/tpm/tpm_emulator.c +@@ -914,7 +914,8 @@ static void tpm_emulator_inst_init(Object *obj) + tpm_emu->cur_locty_number = ~0; + qemu_mutex_init(&tpm_emu->mutex); + +- vmstate_register(NULL, -1, &vmstate_tpm_emulator, obj); ++ vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, ++ &vmstate_tpm_emulator, obj); + } + + /* +diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h +index c2bfa7a..92f531a 100644 +--- a/include/migration/vmstate.h ++++ b/include/migration/vmstate.h +@@ -1114,6 +1114,8 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, + + bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque); + ++#define VMSTATE_INSTANCE_ID_ANY -1 ++ + /* Returns: 0 on success, -1 on failure */ + int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, + const VMStateDescription *vmsd, +diff --git a/migration/savevm.c b/migration/savevm.c +index 480c511..62552ab 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -722,7 +722,7 @@ int register_savevm_live(DeviceState *dev, + } + pstrcat(se->idstr, sizeof(se->idstr), idstr); + +- if (instance_id == -1) { ++ if (instance_id == VMSTATE_INSTANCE_ID_ANY) { + se->instance_id = calculate_new_instance_id(se->idstr); + } else { + se->instance_id = instance_id; +@@ -789,14 +789,14 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, + + se->compat = g_new0(CompatEntry, 1); + pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name); +- se->compat->instance_id = instance_id == -1 ? ++ se->compat->instance_id = instance_id == VMSTATE_INSTANCE_ID_ANY ? + calculate_compat_instance_id(vmsd->name) : instance_id; +- instance_id = -1; ++ instance_id = VMSTATE_INSTANCE_ID_ANY; + } + } + pstrcat(se->idstr, sizeof(se->idstr), vmsd->name); + +- if (instance_id == -1) { ++ if (instance_id == VMSTATE_INSTANCE_ID_ANY) { + se->instance_id = calculate_new_instance_id(se->idstr); + } else { + se->instance_id = instance_id; +-- +1.8.3.1 + diff --git a/migration-colo-fix-use-after-free-of-local_err.patch b/migration-colo-fix-use-after-free-of-local_err.patch new file mode 100644 index 00000000..c03ceb51 --- /dev/null +++ b/migration-colo-fix-use-after-free-of-local_err.patch @@ -0,0 +1,33 @@ +From 663e9b5f25d22834260a0686f77a27c957cd7b2f Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:28 +0300 +Subject: [PATCH 07/14] migration/colo: fix use after free of local_err + +local_err is used again in secondary_vm_do_failover() after +replication_stop_all(), so we must zero it. Otherwise try to set +non-NULL local_err will crash. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-5-vsementsov@virtuozzo.com> +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Peng Liang +--- + migration/colo.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/migration/colo.c b/migration/colo.c +index 9f84b1fa3c0f..761b3544d472 100644 +--- a/migration/colo.c ++++ b/migration/colo.c +@@ -89,6 +89,7 @@ static void secondary_vm_do_failover(void) + replication_stop_all(true, &local_err); + if (local_err) { + error_report_err(local_err); ++ local_err = NULL; + } + + /* Notify all filters of all NIC to do checkpoint */ +-- +2.26.2 + diff --git a/migration-fix-cleanup_bh-leak-on-resume.patch b/migration-fix-cleanup_bh-leak-on-resume.patch new file mode 100644 index 00000000..6b75ed01 --- /dev/null +++ b/migration-fix-cleanup_bh-leak-on-resume.patch @@ -0,0 +1,64 @@ +From 1d7c227bbb24665cea03f96a984ad6be223ac40c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 25 Mar 2020 19:47:21 +0100 +Subject: [PATCH 2/5] migration: fix cleanup_bh leak on resume +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since commit 8c6b0356b53977bcfdea5299db07884915425b0c ("util/async: +make bh_aio_poll() O(1)"), migration-test reveals a leak: + +QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64 +tests/qtest/migration-test -p /x86_64/migration/postcopy/recovery +tests/qtest/libqtest.c:140: kill_qemu() tried to terminate QEMU +process but encountered exit status 1 (expected 0) + +================================================================= +==2082571==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 40 byte(s) in 1 object(s) allocated from: + #0 0x7f25971dfc58 in __interceptor_malloc (/lib64/libasan.so.5+0x10dc58) + #1 0x7f2596d08358 in g_malloc (/lib64/libglib-2.0.so.0+0x57358) + #2 0x560970d006f8 in qemu_bh_new /home/elmarco/src/qemu/util/main-loop.c:532 + #3 0x5609704afa02 in migrate_fd_connect +/home/elmarco/src/qemu/migration/migration.c:3407 + #4 0x5609704b6b6f in migration_channel_connect +/home/elmarco/src/qemu/migration/channel.c:92 + #5 0x5609704b2bfb in socket_outgoing_migration +/home/elmarco/src/qemu/migration/socket.c:108 + #6 0x560970b9bd6c in qio_task_complete /home/elmarco/src/qemu/io/task.c:196 + #7 0x560970b9aa97 in qio_task_thread_result +/home/elmarco/src/qemu/io/task.c:111 + #8 0x7f2596cfee3a (/lib64/libglib-2.0.so.0+0x4de3a) + +Signed-off-by: Marc-André Lureau +Message-Id: <20200325184723.2029630-2-marcandre.lureau@redhat.com> +Reviewed-by: Juan Quintela +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhenyu Ye +--- + migration/migration.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 8f2fc2b4..7949f2a4 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -3313,7 +3313,12 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) + bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED; + + s->expected_downtime = s->parameters.downtime_limit; +- s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s); ++ if (resume) { ++ assert(s->cleanup_bh); ++ } else { ++ assert(!s->cleanup_bh); ++ s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s); ++ } + if (error_in) { + migrate_fd_error(s, error_in); + migrate_fd_cleanup(s); +-- +2.22.0.windows.1 + diff --git a/migration-multifd-clean-pages-after-filling-packet.patch b/migration-multifd-clean-pages-after-filling-packet.patch new file mode 100644 index 00000000..596c5244 --- /dev/null +++ b/migration-multifd-clean-pages-after-filling-packet.patch @@ -0,0 +1,51 @@ +From 0f7e704a4faa661583ea6d82659f206e561f23d4 Mon Sep 17 00:00:00 2001 +From: Wei Yang +Date: Sat, 26 Oct 2019 07:19:59 +0800 +Subject: [PATCH 3/8] migration/multifd: clean pages after filling packet + +This is a preparation for the next patch: + + not use multifd during postcopy. + +Without enabling postcopy, everything looks good. While after enabling +postcopy, migration may fail even not use multifd during postcopy. The +reason is the pages is not properly cleared and *old* target page will +continue to be transferred. + +After clean pages, migration succeeds. + +Signed-off-by: Wei Yang +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +--- + migration/ram.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/migration/ram.c b/migration/ram.c +index 840e354..c2eb1ed 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -947,10 +947,10 @@ static int multifd_send_pages(RAMState *rs) + } + qemu_mutex_unlock(&p->mutex); + } +- p->pages->used = 0; ++ assert(!p->pages->used); ++ assert(!p->pages->block); + + p->packet_num = multifd_send_state->packet_num++; +- p->pages->block = NULL; + multifd_send_state->pages = p->pages; + p->pages = pages; + transferred = ((uint64_t) pages->used) * TARGET_PAGE_SIZE + p->packet_len; +@@ -1137,6 +1137,7 @@ static void *multifd_send_thread(void *opaque) + p->num_packets++; + p->num_pages += used; + p->pages->used = 0; ++ p->pages->block = NULL; + qemu_mutex_unlock(&p->mutex); + + trace_multifd_send(p->id, packet_num, used, flags, +-- +1.8.3.1 + diff --git a/migration-multifd-not-use-multifd-during-postcopy.patch b/migration-multifd-not-use-multifd-during-postcopy.patch new file mode 100644 index 00000000..6df61bfd --- /dev/null +++ b/migration-multifd-not-use-multifd-during-postcopy.patch @@ -0,0 +1,41 @@ +From 7331554bd6ab230404b20d612aed20a95c20eba6 Mon Sep 17 00:00:00 2001 +From: Wei Yang +Date: Sat, 26 Oct 2019 07:20:00 +0800 +Subject: [PATCH 4/8] migration/multifd: not use multifd during postcopy + +We don't support multifd during postcopy, but user still could enable +both multifd and postcopy. This leads to migration failure. + +Skip multifd during postcopy. + +Signed-off-by: Wei Yang +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +--- + migration/ram.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/migration/ram.c b/migration/ram.c +index c2eb1ed..aace3a5 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2571,10 +2571,13 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, + } + + /* +- * do not use multifd for compression as the first page in the new +- * block should be posted out before sending the compressed page ++ * Do not use multifd for: ++ * 1. Compression as the first page in the new block should be posted out ++ * before sending the compressed page ++ * 2. In postcopy as one whole host page should be placed + */ +- if (!save_page_use_compression(rs) && migrate_use_multifd()) { ++ if (!save_page_use_compression(rs) && migrate_use_multifd() ++ && !migration_in_postcopy()) { + return ram_save_multifd_page(rs, block, offset); + } + +-- +1.8.3.1 + diff --git a/migration-ram-fix-use-after-free-of-local_err.patch b/migration-ram-fix-use-after-free-of-local_err.patch new file mode 100644 index 00000000..f74e3b18 --- /dev/null +++ b/migration-ram-fix-use-after-free-of-local_err.patch @@ -0,0 +1,33 @@ +From 019526f7f7b42a7d1b8a74e1db6a8050adf9e1fb Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:29 +0300 +Subject: [PATCH 08/14] migration/ram: fix use after free of local_err + +local_err is used again in migration_bitmap_sync_precopy() after +precopy_notify(), so we must zero it. Otherwise try to set +non-NULL local_err will crash. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-6-vsementsov@virtuozzo.com> +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Peng Liang +--- + migration/ram.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/migration/ram.c b/migration/ram.c +index 840e35480b04..5d1ae7570018 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1912,6 +1912,7 @@ static void migration_bitmap_sync_precopy(RAMState *rs) + */ + if (precopy_notify(PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC, &local_err)) { + error_report_err(local_err); ++ local_err = NULL; + } + + migration_bitmap_sync(rs); +-- +2.26.2 + diff --git a/migration-rdma-cleanup-rdma-context-before-g_free-to.patch b/migration-rdma-cleanup-rdma-context-before-g_free-to.patch new file mode 100644 index 00000000..a39894ad --- /dev/null +++ b/migration-rdma-cleanup-rdma-context-before-g_free-to.patch @@ -0,0 +1,58 @@ +From 9867dc6fc3f131324b73664b9617376270d8d013 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Fri, 8 May 2020 06:07:55 -0400 +Subject: [PATCH 4/5] migration/rdma: cleanup rdma context before g_free to + avoid memleaks + +When error happen in initializing 'rdma_return_path', we should cleanup rdma context +before g_free(rdma) to avoid some memleaks. This patch fix that. + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Message-Id: <20200508100755.7875-3-pannengyuan@huawei.com> +Reviewed-by: Juan Quintela +Signed-off-by: Dr. David Alan Gilbert +--- + migration/rdma.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/migration/rdma.c b/migration/rdma.c +index 3036221e..bb24dac5 100644 +--- a/migration/rdma.c ++++ b/migration/rdma.c +@@ -4103,20 +4103,20 @@ void rdma_start_outgoing_migration(void *opaque, + rdma_return_path = qemu_rdma_data_init(host_port, errp); + + if (rdma_return_path == NULL) { +- goto err; ++ goto return_path_err; + } + + ret = qemu_rdma_source_init(rdma_return_path, + s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL], errp); + + if (ret) { +- goto err; ++ goto return_path_err; + } + + ret = qemu_rdma_connect(rdma_return_path, errp); + + if (ret) { +- goto err; ++ goto return_path_err; + } + + rdma->return_path = rdma_return_path; +@@ -4129,6 +4129,8 @@ void rdma_start_outgoing_migration(void *opaque, + s->to_dst_file = qemu_fopen_rdma(rdma, "wb"); + migrate_fd_connect(s, NULL); + return; ++return_path_err: ++ qemu_rdma_cleanup(rdma); + err: + g_free(rdma); + g_free(rdma_return_path); +-- +2.23.0 + diff --git a/migration-savevm-release-gslist-after-dump_vmstate_j.patch b/migration-savevm-release-gslist-after-dump_vmstate_j.patch new file mode 100644 index 00000000..d5ec9b88 --- /dev/null +++ b/migration-savevm-release-gslist-after-dump_vmstate_j.patch @@ -0,0 +1,63 @@ +From 0d8c145e986d4f500f065d2d8645e95175324e62 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Wed, 19 Feb 2020 17:47:05 +0800 +Subject: [PATCH 8/9] migration/savevm: release gslist after dump_vmstate_json + +'list' forgot to free at the end of dump_vmstate_json_to_file(), although it's called only once, but seems like a clean code. + +Fix the leak as follow: +Direct leak of 16 byte(s) in 1 object(s) allocated from: + #0 0x7fb946abd768 in __interceptor_malloc (/lib64/libasan.so.5+0xef768) + #1 0x7fb945eca445 in g_malloc (/lib64/libglib-2.0.so.0+0x52445) + #2 0x7fb945ee2066 in g_slice_alloc (/lib64/libglib-2.0.so.0+0x6a066) + #3 0x7fb945ee3139 in g_slist_prepend (/lib64/libglib-2.0.so.0+0x6b139) + #4 0x5585db591581 in object_class_get_list_tramp /mnt/sdb/qemu-new/qemu/qom/object.c:1084 + #5 0x5585db590f66 in object_class_foreach_tramp /mnt/sdb/qemu-new/qemu/qom/object.c:1028 + #6 0x7fb945eb35f7 in g_hash_table_foreach (/lib64/libglib-2.0.so.0+0x3b5f7) + #7 0x5585db59110c in object_class_foreach /mnt/sdb/qemu-new/qemu/qom/object.c:1038 + #8 0x5585db5916b6 in object_class_get_list /mnt/sdb/qemu-new/qemu/qom/object.c:1092 + #9 0x5585db335ca0 in dump_vmstate_json_to_file /mnt/sdb/qemu-new/qemu/migration/savevm.c:638 + #10 0x5585daa5bcbf in main /mnt/sdb/qemu-new/qemu/vl.c:4420 + #11 0x7fb941204812 in __libc_start_main ../csu/libc-start.c:308 + #12 0x5585da29420d in _start (/mnt/sdb/qemu-new/qemu/build/x86_64-softmmu/qemu-system-x86_64+0x27f020d) + +Indirect leak of 7472 byte(s) in 467 object(s) allocated from: + #0 0x7fb946abd768 in __interceptor_malloc (/lib64/libasan.so.5+0xef768) + #1 0x7fb945eca445 in g_malloc (/lib64/libglib-2.0.so.0+0x52445) + #2 0x7fb945ee2066 in g_slice_alloc (/lib64/libglib-2.0.so.0+0x6a066) + #3 0x7fb945ee3139 in g_slist_prepend (/lib64/libglib-2.0.so.0+0x6b139) + #4 0x5585db591581 in object_class_get_list_tramp /mnt/sdb/qemu-new/qemu/qom/object.c:1084 + #5 0x5585db590f66 in object_class_foreach_tramp /mnt/sdb/qemu-new/qemu/qom/object.c:1028 + #6 0x7fb945eb35f7 in g_hash_table_foreach (/lib64/libglib-2.0.so.0+0x3b5f7) + #7 0x5585db59110c in object_class_foreach /mnt/sdb/qemu-new/qemu/qom/object.c:1038 + #8 0x5585db5916b6 in object_class_get_list /mnt/sdb/qemu-new/qemu/qom/object.c:1092 + #9 0x5585db335ca0 in dump_vmstate_json_to_file /mnt/sdb/qemu-new/qemu/migration/savevm.c:638 + #10 0x5585daa5bcbf in main /mnt/sdb/qemu-new/qemu/vl.c:4420 + #11 0x7fb941204812 in __libc_start_main ../csu/libc-start.c:308 + #12 0x5585da29420d in _start (/mnt/sdb/qemu-new/qemu/build/x86_64-softmmu/qemu-system-x86_64+0x27f020d) + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Juan Quintela +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Juan Quintela +Signed-off-by: AlexChen +--- + migration/savevm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/migration/savevm.c b/migration/savevm.c +index 7d89c57..8163de7 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -614,6 +614,7 @@ void dump_vmstate_json_to_file(FILE *out_file) + } + fprintf(out_file, "\n}\n"); + fclose(out_file); ++ g_slist_free(list); + } + + static uint32_t calculate_new_instance_id(const char *idstr) +-- +1.8.3.1 + diff --git a/object-return-self-in-object_ref.patch b/object-return-self-in-object_ref.patch new file mode 100644 index 00000000..e851fb30 --- /dev/null +++ b/object-return-self-in-object_ref.patch @@ -0,0 +1,58 @@ +From b77ade9bb37b2e9813a42008cb21d0c743aa50a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 10 Jan 2020 19:30:31 +0400 +Subject: [PATCH] object: return self in object_ref() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allow for simpler assignment with ref: foo = object_ref(bar) + +Signed-off-by: Marc-André Lureau +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20200110153039.1379601-19-marcandre.lureau@redhat.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhenyu Ye +--- + include/qom/object.h | 3 ++- + qom/object.c | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/include/qom/object.h b/include/qom/object.h +index 5e2f60d4b0..18660fde1c 100644 +--- a/include/qom/object.h ++++ b/include/qom/object.h +@@ -1005,8 +1005,9 @@ GSList *object_class_get_list_sorted(const char *implements_type, + * + * Increase the reference count of a object. A object cannot be freed as long + * as its reference count is greater than zero. ++ * Returns: @obj + */ +-void object_ref(Object *obj); ++Object *object_ref(Object *obj); + + /** + * object_unref: +diff --git a/qom/object.c b/qom/object.c +index 66c4a5f1cb..555c8b9d07 100644 +--- a/qom/object.c ++++ b/qom/object.c +@@ -1107,12 +1107,13 @@ GSList *object_class_get_list_sorted(const char *implements_type, + object_class_cmp); + } + +-void object_ref(Object *obj) ++Object *object_ref(Object *obj) + { + if (!obj) { +- return; ++ return NULL; + } + atomic_inc(&obj->ref); ++ return obj; + } + + void object_unref(Object *obj) +-- +2.22.0.windows.1 + diff --git a/pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch b/pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch new file mode 100644 index 00000000..6e29f08d --- /dev/null +++ b/pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch @@ -0,0 +1,34 @@ +From d2bb5b4c4ed3b1dbc0096deb195b6df33f813f23 Mon Sep 17 00:00:00 2001 +From: Yifan Luo +Date: Wed, 14 Aug 2019 14:14:26 +0800 +Subject: [PATCH 5/5] pc-bios/s390-ccw/net: fix a possible memory leak in + get_uuid() + +There is a possible memory leak in get_uuid(). Should free allocated mem +before +return NULL. + +Signed-off-by: Yifan Luo +Message-Id: <02cf01d55267$86cf2850$946d78f0$@cmss.chinamobile.com> +Reviewed-by: Thomas Huth +Reviewed-by: Cornelia Huck +Signed-off-by: Thomas Huth +--- + pc-bios/s390-ccw/netmain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index f3542cb2..f2dcc01e 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -269,6 +269,7 @@ static const char *get_uuid(void) + : "d" (r0), "d" (r1), [addr] "a" (buf) + : "cc", "memory"); + if (cc) { ++ free(mem); + return NULL; + } + +-- +2.23.0 + diff --git a/qemu-img-free-memory-before-re-assign.patch b/qemu-img-free-memory-before-re-assign.patch new file mode 100644 index 00000000..2d46d64b --- /dev/null +++ b/qemu-img-free-memory-before-re-assign.patch @@ -0,0 +1,33 @@ +From d22af5cb41c16829dbf3ed3c611ef56ceeb840ff Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Thu, 27 Feb 2020 09:29:50 +0800 +Subject: [PATCH 02/14] qemu-img: free memory before re-assign + +collect_image_check() is called twice in img_check(), the filename/format will be alloced without free the original memory. +It is not a big deal since the process will exit anyway, but seems like a clean code and it will remove the warning spotted by asan. + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Message-Id: <20200227012950.12256-3-pannengyuan@huawei.com> +Signed-off-by: Max Reitz +Signed-off-by: Peng Liang +--- + qemu-img.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/qemu-img.c b/qemu-img.c +index 79983772de39..2e9cc5db7c4c 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -808,6 +808,8 @@ static int img_check(int argc, char **argv) + check->corruptions_fixed); + } + ++ qapi_free_ImageCheck(check); ++ check = g_new0(ImageCheck, 1); + ret = collect_image_check(bs, check, filename, fmt, 0); + + check->leaks_fixed = leaks_fixed; +-- +2.26.2 + diff --git a/qemu.spec b/qemu.spec index d128ac25..c6089ff7 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 71 +Release: 72 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 @@ -415,6 +415,67 @@ Patch0402: seqlock-fix-seqlock_write_unlock_impl-function.patch Patch0403: target-i386-kvm-initialize-microcode-revision-from-K.patch Patch0404: target-i386-check-for-availability-of-MSR_IA32_UCODE.patch Patch0405: hw-arm-virt-Init-PMU-for-hotplugged-vCPU.patch +Patch0406: Fixed-integer-overflow-in-e1000e.patch +Patch0407: migration-fix-cleanup_bh-leak-on-resume.patch +Patch0408: qmp-fix-leak-on-callbacks-that-return-both-value-and.patch +Patch0409: qga-commands-posix-fix-use-after-free-of-local_err.patch +Patch0410: file-posix-Fix-leaked-fd-in-raw_open_common-error-pa.patch +Patch0411: object-return-self-in-object_ref.patch +Patch0412: lm32-do-not-leak-memory-on-object_new-object_unref.patch +Patch0413: cris-do-not-leak-struct-cris_disasm_data.patch +Patch0414: hppa-fix-leak-from-g_strdup_printf.patch +Patch0415: mcf5208-fix-leak-from-qemu_allocate_irqs.patch +Patch0416: microblaze-fix-leak-of-fdevice-tree-blob.patch +Patch0417: ide-fix-leak-from-qemu_allocate_irqs.patch +Patch0418: make-check-unit-use-after-free-in-test-opts-visitor.patch +Patch0419: xhci-fix-valid.max_access_size-to-access-address-reg.patch +Patch0420: qga-fix-assert-regression-on-guest-shutdown.patch +Patch0421: char-fix-use-after-free-with-dup-chardev-reconnect.patch +Patch0422: migration-Count-new_dirty-instead-of-real_dirty.patch +Patch0423: qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch +Patch0424: chardev-tcp-Fix-error-message-double-free-error.patch +Patch0425: colo-compare-Fix-memory-leak-in-packet_enqueue.patch +Patch0426: hw-block-nvme-fix-pin-based-interrupt-behavior.patch +Patch0427: hw-block-nvme-fix-pci-doorbell-size-calculation.patch +Patch0428: virtio-pci-fix-queue_enable-write.patch +Patch0429: hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch +Patch0430: linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch +Patch0431: migration-rdma-cleanup-rdma-context-before-g_free-to.patch +Patch0432: pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch +Patch0433: block-qcow2-do-free-crypto_opts-in-qcow2_close.patch +Patch0434: qemu-img-free-memory-before-re-assign.patch +Patch0435: block-qcow2-threads-fix-qcow2_decompress.patch +Patch0436: block-Avoid-memleak-on-qcow2-image-info-failure.patch +Patch0437: block-bdrv_set_backing_bs-fix-use-after-free.patch +Patch0438: hmp-vnc-Fix-info-vnc-list-leak.patch +Patch0439: migration-colo-fix-use-after-free-of-local_err.patch +Patch0440: migration-ram-fix-use-after-free-of-local_err.patch +Patch0441: block-mirror-fix-use-after-free-of-local_err.patch +Patch0442: block-fix-bdrv_root_attach_child-forget-to-unref-chi.patch +Patch0443: virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch +Patch0444: virtio-blk-delete-vqs-on-the-error-path-in-realize.patch +Patch0445: fix-vhost_user_blk_watch-crash.patch +Patch0446: vhost-user-blk-delay-vhost_user_blk_disconnect.patch +Patch0447: usbredir-fix-buffer-overflow-on-vmload.patch +Patch0448: display-bochs-display-fix-memory-leak.patch +Patch0449: audio-fix-integer-overflow.patch +Patch0450: migration-multifd-clean-pages-after-filling-packet.patch +Patch0451: migration-multifd-not-use-multifd-during-postcopy.patch +Patch0452: migration-Define-VMSTATE_INSTANCE_ID_ANY.patch +Patch0453: migration-Change-SaveStateEntry.instance_id-into-uin.patch +Patch0454: apic-Use-32bit-APIC-ID-for-migration-instance-ID.patch +Patch0455: virtio-add-ability-to-delete-vq-through-a-pointer.patch +Patch0456: virtio-pmem-do-delete-rq_vq-in-virtio_pmem_unrealize.patch +Patch0457: virtio-crypto-do-delete-ctrl_vq-in-virtio_crypto_dev.patch +Patch0458: vhost-user-blk-delete-virtioqueues-in-unrealize-to-f.patch +Patch0459: vhost-user-blk-convert-to-new-virtio_delete_queue.patch +Patch0460: block-nbd-extract-the-common-cleanup-code.patch +Patch0461: virtio-gracefully-handle-invalid-region-caches.patch +Patch0462: migration-savevm-release-gslist-after-dump_vmstate_j.patch +Patch0463: virtio-input-fix-memory-leak-on-unrealize.patch +Patch0464: target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch +Patch0465: target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch +Patch0466: target-arm-Update-the-ID-registers-of-Kunpeng-920.patch BuildRequires: flex BuildRequires: gcc @@ -809,6 +870,69 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Wed Jul 28 2021 imxcc +- object: return self in object_ref() +- file-posix: Fix leaked fd in raw_open_common() error path +- qga/commands-posix: fix use after free of local_err +- qmp: fix leak on callbacks that return both value and error +- migration: fix cleanup_bh leak on resume +- Fixed integer overflow in e1000e +- lm32-do-not-leak-memory-on-object_new-object_unref.patch +- cris-do-not-leak-struct-cris_disasm_data.patch +- hppa-fix-leak-from-g_strdup_printf.patch +- mcf5208-fix-leak-from-qemu_allocate_irqs.patch +- microblaze-fix-leak-of-fdevice-tree-blob.patch +- ide-fix-leak-from-qemu_allocate_irqs.patch +- make-check-unit-use-after-free-in-test-opts-visitor.patch +- virtio-pci: fix queue_enable write +- hw/block/nvme: fix pci doorbell size calculation +- hw/block/nvme: fix pin-based interrupt behavior +- colo-compare: Fix memory leak in packet_enqueue() +- chardev/tcp: Fix error message double free error +- qga: Plug unlikely memory leak in guest-set-memory-blocks +- migration: Count new_dirty instead of real_dirty +- char: fix use-after-free with dup chardev & reconnect +- qga: fix assert regression on guest-shutdown +- xhci: fix valid.max_access_size to access address registers +- block/qcow2: do free crypto_opts in qcow2_close() +- qemu-img: free memory before re-assign +- block/qcow2-threads: fix qcow2_decompress +- block: Avoid memleak on qcow2 image info failure +- block: bdrv_set_backing_bs: fix use-after-free +- hmp/vnc: Fix info vnc list leak +- migration/colo: fix use after free of local_err +- migration/ram: fix use after free of local_err +- block/mirror: fix use after free of local_err +- block: fix bdrv_root_attach_child forget to unref child_bs +- virtio-serial-bus: Plug memory leak on realize() error paths +- virtio-blk: delete vqs on the error path in realize() +- fix vhost_user_blk_watch crash +- vhost-user-blk: delay vhost_user_blk_disconnect +- hw-pci-pci_bridge-Correct-pci_bridge_io-memory-regio.patch +- linux-user-mmap.c-fix-integer-underflow-in-target_mr.patch +- migration-rdma-cleanup-rdma-context-before-g_free-to.patch +- pc-bios-s390-ccw-net-fix-a-possible-memory-leak-in-g.patch +- usbredir-fix-buffer-overflow-on-vmload.patch +- apic: Use 32bit APIC ID for migration instance-ID +- audio: fix integer overflow +- display/bochs-display: fix memory leak +- migration: Change SaveStateEntry.instance_id into uint32_t +- migration: Define VMSTATE_INSTANCE_ID_ANY +- migration/multifd: clean pages after filling packet +- migration/multifd: not use multifd during postcopy +- virtio: add ability to delete vq through a pointer +- virtio-pmem: do delete rq_vq in virtio_pmem_unrealize +- virtio-crypto: do delete ctrl_vq in virtio_crypto_device_unrealize +- vhost-user-blk: delete virtioqueues in unrealize to fix memleaks +- vhost-user-blk: convert to new virtio_delete_queue +- block/nbd: extract the common cleanup code +- virtio: gracefully handle invalid region caches +- migration/savevm: release gslist after dump_vmstate_json +- virtio-input: fix memory leak on unrealize +- target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest +- target/arm: clear EL2 and EL3 only when kvm is not enabled +- target/arm: Update the ID registers of Kunpeng-920 + * Fri Jul 23 2021 imxcc - hw/arm/virt: Init PMU for hotplugged vCPU diff --git a/qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch b/qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch new file mode 100644 index 00000000..a901a500 --- /dev/null +++ b/qga-Plug-unlikely-memory-leak-in-guest-set-memory-bl.patch @@ -0,0 +1,40 @@ +From 1580682eafb489eaf417456778267662629cf696 Mon Sep 17 00:00:00 2001 +From: Markus Armbruster +Date: Tue, 30 Jun 2020 11:03:33 +0200 +Subject: [PATCH 05/11] qga: Plug unlikely memory leak in + guest-set-memory-blocks + +transfer_memory_block() leaks an Error object when reading file +/sys/devices/system/memory/memory/state fails with errno other +than ENOENT, and @sys2memblk is false, i.e. when the state file exists +but cannot be read (seems quite unlikely), and this is +guest-set-memory-blocks, not guest-get-memory-blocks. + +Plug the leak. + +Fixes: bd240fca42d5f072fb758a71720d9de9990ac553 +Cc: Michael Roth +Cc: Hailiang Zhang +Signed-off-by: Markus Armbruster +Reviewed-by: zhanghailiang +Message-Id: <20200630090351.1247703-9-armbru@redhat.com> +Signed-off-by: BiaoXiang Ye +--- + qga/commands-posix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index dfc05f5b..c318cee7 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -2420,6 +2420,7 @@ static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk, + if (sys2memblk) { + error_propagate(errp, local_err); + } else { ++ error_free(local_err); + result->response = + GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED; + } +-- +2.27.0.dirty + diff --git a/qga-commands-posix-fix-use-after-free-of-local_err.patch b/qga-commands-posix-fix-use-after-free-of-local_err.patch new file mode 100644 index 00000000..9628d0c5 --- /dev/null +++ b/qga-commands-posix-fix-use-after-free-of-local_err.patch @@ -0,0 +1,49 @@ +From 15847279f29b0bd67b95daefff395cab8fad80d3 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Tue, 24 Mar 2020 18:36:30 +0300 +Subject: [PATCH 4/5] qga/commands-posix: fix use after free of local_err + +local_err is used several times in guest_suspend(). Setting non-NULL +local_err will crash, so let's zero it after freeing. Also fix possible +leak of local_err in final if(). + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20200324153630.11882-7-vsementsov@virtuozzo.com> +Reviewed-by: Richard Henderson +Signed-off-by: Markus Armbruster +Signed-off-by: Zhenyu Ye +--- + qga/commands-posix.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index dfc05f5b..66164e6c 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -1760,6 +1760,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) + } + + error_free(local_err); ++ local_err = NULL; + + if (pmutils_supports_mode(mode, &local_err)) { + mode_supported = true; +@@ -1771,6 +1772,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) + } + + error_free(local_err); ++ local_err = NULL; + + if (linux_sys_state_supports_mode(mode, &local_err)) { + mode_supported = true; +@@ -1778,6 +1780,7 @@ static void guest_suspend(SuspendMode mode, Error **errp) + } + + if (!mode_supported) { ++ error_free(local_err); + error_setg(errp, + "the requested suspend mode is not supported by the guest"); + } else { +-- +2.22.0.windows.1 + diff --git a/qga-fix-assert-regression-on-guest-shutdown.patch b/qga-fix-assert-regression-on-guest-shutdown.patch new file mode 100644 index 00000000..c5f1e106 --- /dev/null +++ b/qga-fix-assert-regression-on-guest-shutdown.patch @@ -0,0 +1,47 @@ +From aeccff89333c565c7a894f99c17c0044d7d43be2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 4 Jun 2020 11:44:25 +0200 +Subject: [PATCH 02/11] qga: fix assert regression on guest-shutdown +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since commit 781f2b3d1e ("qga: process_event() simplification"), +send_response() is called unconditionally, but will assert when "rsp" is +NULL. This may happen with QCO_NO_SUCCESS_RESP commands, such as +"guest-shutdown". + +Fixes: 781f2b3d1e5ef389b44016a897fd55e7a780bf35 +Cc: Michael Roth +Reported-by: Christian Ehrhardt +Signed-off-by: Marc-André Lureau +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Christian Ehrhardt +Tested-by: Christian Ehrhardt +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael Roth +Signed-off-by: BiaoXiang Ye +--- + qga/main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/qga/main.c b/qga/main.c +index c35c2a21..12fa463f 100644 +--- a/qga/main.c ++++ b/qga/main.c +@@ -529,7 +529,11 @@ static int send_response(GAState *s, const QDict *rsp) + QString *payload_qstr, *response_qstr; + GIOStatus status; + +- g_assert(rsp && s->channel); ++ g_assert(s->channel); ++ ++ if (!rsp) { ++ return 0; ++ } + + payload_qstr = qobject_to_json(QOBJECT(rsp)); + if (!payload_qstr) { +-- +2.27.0.dirty + diff --git a/qmp-fix-leak-on-callbacks-that-return-both-value-and.patch b/qmp-fix-leak-on-callbacks-that-return-both-value-and.patch new file mode 100644 index 00000000..1ceb1e70 --- /dev/null +++ b/qmp-fix-leak-on-callbacks-that-return-both-value-and.patch @@ -0,0 +1,47 @@ +From 1f1949368d4ac7a18973aa83a074daf01daf97ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 25 Mar 2020 19:47:22 +0100 +Subject: [PATCH 3/5] qmp: fix leak on callbacks that return both value and + error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Direct leak of 4120 byte(s) in 1 object(s) allocated from: + #0 0x7fa114931887 in __interceptor_calloc (/lib64/libasan.so.6+0xb0887) + #1 0x7fa1144ad8f0 in g_malloc0 (/lib64/libglib-2.0.so.0+0x588f0) + #2 0x561e3c9c8897 in qmp_object_add /home/elmarco/src/qemu/qom/qom-qmp-cmds.c:291 + #3 0x561e3cf48736 in qmp_dispatch /home/elmarco/src/qemu/qapi/qmp-dispatch.c:155 + #4 0x561e3c8efb36 in monitor_qmp_dispatch /home/elmarco/src/qemu/monitor/qmp.c:145 + #5 0x561e3c8f09ed in monitor_qmp_bh_dispatcher /home/elmarco/src/qemu/monitor/qmp.c:234 + #6 0x561e3d08c993 in aio_bh_call /home/elmarco/src/qemu/util/async.c:136 + #7 0x561e3d08d0a5 in aio_bh_poll /home/elmarco/src/qemu/util/async.c:164 + #8 0x561e3d0a535a in aio_dispatch /home/elmarco/src/qemu/util/aio-posix.c:380 + #9 0x561e3d08e3ca in aio_ctx_dispatch /home/elmarco/src/qemu/util/async.c:298 + #10 0x7fa1144a776e in g_main_context_dispatch (/lib64/libglib-2.0.so.0+0x5276e) + +Signed-off-by: Marc-André Lureau +Message-Id: <20200325184723.2029630-3-marcandre.lureau@redhat.com> +Reviewed-by: Markus Armbruster +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhenyu Ye +--- + qapi/qmp-dispatch.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c +index 6dfdad57..a635abb9 100644 +--- a/qapi/qmp-dispatch.c ++++ b/qapi/qmp-dispatch.c +@@ -189,6 +189,8 @@ QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request, + + ret = do_qmp_dispatch(cmds, request, allow_oob, &err); + if (err) { ++ /* or assert(!ret) after reviewing all handlers: */ ++ qobject_unref(ret); + rsp = qmp_error_response(err); + } else if (ret) { + rsp = qdict_new(); +-- +2.22.0.windows.1 + diff --git a/target-arm-Update-the-ID-registers-of-Kunpeng-920.patch b/target-arm-Update-the-ID-registers-of-Kunpeng-920.patch new file mode 100644 index 00000000..586dcbb1 --- /dev/null +++ b/target-arm-Update-the-ID-registers-of-Kunpeng-920.patch @@ -0,0 +1,57 @@ +From b54ca94f19a9b22537712638ae05d2095258eb80 Mon Sep 17 00:00:00 2001 +From: Peng Liang +Date: Sat, 19 Sep 2020 09:04:45 +0800 +Subject: [PATCH] target/arm: Update the ID registers of Kunpeng-920 + +The values of some ID registers in Kunpeng-920 are not exactly correct. +Let's update them. The values are read from Kunpeng-920 by calling +read_sysreg_s. + +Signed-off-by: Peng Liang +--- + target/arm/cpu64.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c +index 726d123d8e..a1649f8844 100644 +--- a/target/arm/cpu64.c ++++ b/target/arm/cpu64.c +@@ -275,10 +275,33 @@ static void aarch64_kunpeng_920_initfn(Object *obj) + + cpu->midr = 0x480fd010; + cpu->ctr = 0x84448004; +- cpu->isar.regs[ID_AA64PFR0] = 0x11001111; ++ cpu->isar.regs[ID_ISAR0] = 0; ++ cpu->isar.regs[ID_ISAR1] = 0; ++ cpu->isar.regs[ID_ISAR2] = 0; ++ cpu->isar.regs[ID_ISAR3] = 0; ++ cpu->isar.regs[ID_ISAR4] = 0; ++ cpu->isar.regs[ID_ISAR5] = 0; ++ cpu->isar.regs[ID_MMFR0] = 0; ++ cpu->isar.regs[ID_MMFR1] = 0; ++ cpu->isar.regs[ID_MMFR2] = 0; ++ cpu->isar.regs[ID_MMFR3] = 0; ++ cpu->isar.regs[ID_MMFR4] = 0; ++ cpu->isar.regs[MVFR0] = 0; ++ cpu->isar.regs[MVFR1] = 0; ++ cpu->isar.regs[MVFR2] = 0; ++ cpu->isar.regs[ID_DFR0] = 0; ++ cpu->isar.regs[MVFR2] = 0; ++ cpu->isar.regs[MVFR2] = 0; ++ cpu->isar.regs[MVFR2] = 0; ++ cpu->id_pfr0 = 0; ++ cpu->id_pfr1 = 0; ++ cpu->isar.regs[ID_AA64PFR0] = 0x0000010011111111; + cpu->isar.regs[ID_AA64DFR0] = 0x110305408; +- cpu->isar.regs[ID_AA64ISAR0] = 0x10211120; ++ cpu->isar.regs[ID_AA64ISAR0] = 0x0001100010211120; ++ cpu->isar.regs[ID_AA64ISAR1] = 0x00011001; + cpu->isar.regs[ID_AA64MMFR0] = 0x101125; ++ cpu->isar.regs[ID_AA64MMFR1] = 0x10211122; ++ cpu->isar.regs[ID_AA64MMFR2] = 0x00001011; + } + + static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name, +-- +2.23.0 + diff --git a/target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch b/target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch new file mode 100644 index 00000000..455dc843 --- /dev/null +++ b/target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch @@ -0,0 +1,42 @@ +From ad6ce039cab07b6a99ccaa36fbb0043ae85a74c9 Mon Sep 17 00:00:00 2001 +From: Peng Liang +Date: Mon, 21 Sep 2020 22:14:20 +0800 +Subject: [PATCH] target/arm: clear EL2 and EL3 only when kvm is not enabled + +When has_el2 and has_el3 are disabled, which is the default value for +virt machine, QEMU will clear the corresponding field in ID_PFR1_EL1 and +ID_AA64PFR0_EL1 to not expose EL3 and EL2 to guest. Because KVM doesn't +support to emulate ID registers in AArch64 before, it will not take +effect. Hence, clear EL2 and EL3 only when kvm is not enabled for +backwards compatibility. + +Signed-off-by: Peng Liang +--- + target/arm/cpu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/arm/cpu.c b/target/arm/cpu.c +index 7ae2d3da56..3f62336acf 100644 +--- a/target/arm/cpu.c ++++ b/target/arm/cpu.c +@@ -1996,7 +1996,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) + } + } + +- if (!cpu->has_el3) { ++ if (!cpu->has_el3 && !kvm_enabled()) { + /* If the has_el3 CPU property is disabled then we need to disable the + * feature. + */ +@@ -2037,7 +2037,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) + cpu->pmceid1 = 0; + } + +- if (!arm_feature(env, ARM_FEATURE_EL2)) { ++ if (!arm_feature(env, ARM_FEATURE_EL2) && !kvm_enabled()) { + /* Disable the hypervisor feature bits in the processor feature + * registers if we don't have EL2. These are id_pfr1[15:12] and + * id_aa64pfr0_el1[11:8]. +-- +2.23.0 + diff --git a/target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch b/target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch new file mode 100644 index 00000000..91702dbe --- /dev/null +++ b/target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch @@ -0,0 +1,31 @@ +From 88e3146118230de8b99280db219a6a6c47bebce1 Mon Sep 17 00:00:00 2001 +From: Peng Liang +Date: Wed, 16 Sep 2020 19:40:28 +0800 +Subject: [PATCH] target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest + +Some AArch64 CPU doesn't support AArch32 mode, and the values of AArch32 +registers are all 0. Hence, We'd better not to modify AArch32 registers +in AArch64 mode. + +Signed-off-by: zhanghailiang +Signed-off-by: Peng Liang +--- + target/arm/helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/arm/helper.c b/target/arm/helper.c +index 97b6b86197..b262f5d6c5 100644 +--- a/target/arm/helper.c ++++ b/target/arm/helper.c +@@ -5672,7 +5672,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) + ARMCPU *cpu = env_archcpu(env); + uint64_t pfr1 = cpu->id_pfr1; + +- if (env->gicv3state) { ++ if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && env->gicv3state) { + pfr1 |= 1 << 28; + } + return pfr1; +-- +2.23.0 + diff --git a/usbredir-fix-buffer-overflow-on-vmload.patch b/usbredir-fix-buffer-overflow-on-vmload.patch new file mode 100644 index 00000000..4a43c35c --- /dev/null +++ b/usbredir-fix-buffer-overflow-on-vmload.patch @@ -0,0 +1,54 @@ +From 66fce891aecec3969d1ba979cf0a9a6df70afecd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 7 Aug 2019 12:40:48 +0400 +Subject: [PATCH] usbredir: fix buffer-overflow on vmload +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If interface_count is NO_INTERFACE_INFO, let's not access the arrays +out-of-bounds. + +==994==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x625000243930 at pc 0x5642068086a8 bp 0x7f0b6f9ffa50 sp 0x7f0b6f9ffa40 +READ of size 1 at 0x625000243930 thread T0 + #0 0x5642068086a7 in usbredir_check_bulk_receiving /home/elmarco/src/qemu/hw/usb/redirect.c:1503 + #1 0x56420681301c in usbredir_post_load /home/elmarco/src/qemu/hw/usb/redirect.c:2154 + #2 0x5642068a56c2 in vmstate_load_state /home/elmarco/src/qemu/migration/vmstate.c:168 + #3 0x56420688e2ac in vmstate_load /home/elmarco/src/qemu/migration/savevm.c:829 + #4 0x5642068980cb in qemu_loadvm_section_start_full /home/elmarco/src/qemu/migration/savevm.c:2211 + #5 0x564206899645 in qemu_loadvm_state_main /home/elmarco/src/qemu/migration/savevm.c:2395 + #6 0x5642068998cf in qemu_loadvm_state /home/elmarco/src/qemu/migration/savevm.c:2467 + #7 0x56420685f3e9 in process_incoming_migration_co /home/elmarco/src/qemu/migration/migration.c:449 + #8 0x564207106c47 in coroutine_trampoline /home/elmarco/src/qemu/util/coroutine-ucontext.c:115 + #9 0x7f0c0604e37f (/lib64/libc.so.6+0x4d37f) + +Signed-off-by: Marc-André Lureau +Reviewed-by: Liam Merwick +Reviewed-by: Li Qiang +Reviewed-by: Philippe Mathieu-Daudé +Message-id: 20190807084048.4258-1-marcandre.lureau@redhat.com +Signed-off-by: Gerd Hoffmann +Signed-off-by: Zhenyu Ye +--- + hw/usb/redirect.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 998fc6e4..9764a579 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -1495,6 +1495,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev) + for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) { + dev->endpoint[i].bulk_receiving_enabled = 0; + } ++ ++ if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { ++ return; ++ } ++ + for (i = 0; i < dev->interface_info.interface_count; i++) { + quirks = usb_get_quirks(dev->device_info.vendor_id, + dev->device_info.product_id, +-- +2.22.0.windows.1 + diff --git a/vhost-user-blk-convert-to-new-virtio_delete_queue.patch b/vhost-user-blk-convert-to-new-virtio_delete_queue.patch new file mode 100644 index 00000000..3f419966 --- /dev/null +++ b/vhost-user-blk-convert-to-new-virtio_delete_queue.patch @@ -0,0 +1,99 @@ +From 30d20e1258722431198cd2a8298c85b7af2a0c1b Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Mon, 24 Feb 2020 12:13:36 +0800 +Subject: [PATCH 5/9] vhost-user-blk: convert to new virtio_delete_queue + +use the new virtio_delete_queue function to cleanup. + +Signed-off-by: Pan Nengyuan +Message-Id: <20200224041336.30790-3-pannengyuan@huawei.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: AlexChen +--- + hw/block/vhost-user-blk.c | 20 ++++++++++++-------- + include/hw/virtio/vhost-user-blk.h | 4 +++- + 2 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c +index dbc0a2e..146b927 100644 +--- a/hw/block/vhost-user-blk.c ++++ b/hw/block/vhost-user-blk.c +@@ -303,7 +303,7 @@ static int vhost_user_blk_connect(DeviceState *dev) + s->connected = true; + + s->dev.nvqs = s->num_queues; +- s->dev.vqs = s->vqs; ++ s->dev.vqs = s->vhost_vqs; + s->dev.vq_index = 0; + s->dev.backend_features = 0; + +@@ -430,13 +430,15 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) + virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, + sizeof(struct virtio_blk_config)); + ++ s->virtqs = g_new(VirtQueue *, s->num_queues); + for (i = 0; i < s->num_queues; i++) { +- virtio_add_queue(vdev, s->queue_size, +- vhost_user_blk_handle_output); ++ s->virtqs[i] = virtio_add_queue(vdev, s->queue_size, ++ vhost_user_blk_handle_output); + } + + s->inflight = g_new0(struct vhost_inflight, 1); +- s->vqs = g_new(struct vhost_virtqueue, s->num_queues); ++ s->vhost_vqs = g_new0(struct vhost_virtqueue, s->num_queues); ++ s->watch = 0; + s->connected = false; + + qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event, +@@ -467,11 +469,12 @@ reconnect: + return; + + virtio_err: +- g_free(s->vqs); ++ g_free(s->vhost_vqs); + g_free(s->inflight); + for (i = 0; i < s->num_queues; i++) { +- virtio_del_queue(vdev, i); ++ virtio_delete_queue(s->virtqs[i]); + } ++ g_free(s->virtqs); + virtio_cleanup(vdev); + vhost_user_cleanup(&s->vhost_user); + } +@@ -487,12 +490,13 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp) + NULL, NULL, NULL, false); + vhost_dev_cleanup(&s->dev); + vhost_dev_free_inflight(s->inflight); +- g_free(s->vqs); ++ g_free(s->vhost_vqs); + g_free(s->inflight); + + for (i = 0; i < s->num_queues; i++) { +- virtio_del_queue(vdev, i); ++ virtio_delete_queue(s->virtqs[i]); + } ++ g_free(s->virtqs); + virtio_cleanup(vdev); + vhost_user_cleanup(&s->vhost_user); + } +diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h +index ad9b742..29375dd 100644 +--- a/include/hw/virtio/vhost-user-blk.h ++++ b/include/hw/virtio/vhost-user-blk.h +@@ -37,7 +37,9 @@ typedef struct VHostUserBlk { + struct vhost_dev dev; + struct vhost_inflight *inflight; + VhostUserState vhost_user; +- struct vhost_virtqueue *vqs; ++ struct vhost_virtqueue *vhost_vqs; ++ VirtQueue **virtqs; ++ guint watch; + bool connected; + } VHostUserBlk; + +-- +1.8.3.1 + diff --git a/vhost-user-blk-delay-vhost_user_blk_disconnect.patch b/vhost-user-blk-delay-vhost_user_blk_disconnect.patch new file mode 100644 index 00000000..422e2a17 --- /dev/null +++ b/vhost-user-blk-delay-vhost_user_blk_disconnect.patch @@ -0,0 +1,90 @@ +From 632a841b6ba547906b475250f5c2cb46774ab4af Mon Sep 17 00:00:00 2001 +From: Dima Stepanov +Date: Thu, 28 May 2020 12:11:19 +0300 +Subject: [PATCH 14/14] vhost-user-blk: delay vhost_user_blk_disconnect + +A socket write during vhost-user communication may trigger a disconnect +event, calling vhost_user_blk_disconnect() and clearing all the +vhost_dev structures holding data that vhost-user functions expect to +remain valid to roll back initialization correctly. Delay the cleanup to +keep vhost_dev structure valid. +There are two possible states to handle: +1. RUN_STATE_PRELAUNCH: skip bh oneshot call and perform disconnect in +the caller routine. +2. RUN_STATE_RUNNING: delay by using bh + +BH changes are based on the similar changes for the vhost-user-net +device: + commit e7c83a885f865128ae3cf1946f8cb538b63cbfba + "vhost-user: delay vhost_user_stop" + +Signed-off-by: Dima Stepanov +Message-Id: <69b73b94dcd066065595266c852810e0863a0895.1590396396.git.dimastep@yandex-team.ru> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Li Feng +Reviewed-by: Raphael Norwitz +Signed-off-by: Peng Liang +--- + hw/block/vhost-user-blk.c | 38 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 37 insertions(+), 1 deletion(-) + +diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c +index dc66f8a5febd..6b719d1d80e1 100644 +--- a/hw/block/vhost-user-blk.c ++++ b/hw/block/vhost-user-blk.c +@@ -346,6 +346,19 @@ static void vhost_user_blk_disconnect(DeviceState *dev) + vhost_dev_cleanup(&s->dev); + } + ++static void vhost_user_blk_event(void *opaque, int event); ++ ++static void vhost_user_blk_chr_closed_bh(void *opaque) ++{ ++ DeviceState *dev = opaque; ++ VirtIODevice *vdev = VIRTIO_DEVICE(dev); ++ VHostUserBlk *s = VHOST_USER_BLK(vdev); ++ ++ vhost_user_blk_disconnect(dev); ++ qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event, ++ NULL, opaque, NULL, true); ++} ++ + static void vhost_user_blk_event(void *opaque, int event) + { + DeviceState *dev = opaque; +@@ -360,7 +373,30 @@ static void vhost_user_blk_event(void *opaque, int event) + } + break; + case CHR_EVENT_CLOSED: +- vhost_user_blk_disconnect(dev); ++ /* ++ * A close event may happen during a read/write, but vhost ++ * code assumes the vhost_dev remains setup, so delay the ++ * stop & clear. There are two possible paths to hit this ++ * disconnect event: ++ * 1. When VM is in the RUN_STATE_PRELAUNCH state. The ++ * vhost_user_blk_device_realize() is a caller. ++ * 2. In tha main loop phase after VM start. ++ * ++ * For p2 the disconnect event will be delayed. We can't ++ * do the same for p1, because we are not running the loop ++ * at this moment. So just skip this step and perform ++ * disconnect in the caller function. ++ * ++ * TODO: maybe it is a good idea to make the same fix ++ * for other vhost-user devices. ++ */ ++ if (runstate_is_running()) { ++ AioContext *ctx = qemu_get_current_aio_context(); ++ ++ qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL, NULL, ++ NULL, NULL, false); ++ aio_bh_schedule_oneshot(ctx, vhost_user_blk_chr_closed_bh, opaque); ++ } + break; + } + } +-- +2.26.2 + diff --git a/vhost-user-blk-delete-virtioqueues-in-unrealize-to-f.patch b/vhost-user-blk-delete-virtioqueues-in-unrealize-to-f.patch new file mode 100644 index 00000000..e57f5b59 --- /dev/null +++ b/vhost-user-blk-delete-virtioqueues-in-unrealize-to-f.patch @@ -0,0 +1,69 @@ +From d8febdc4940d719dba77a17a10a8d36ad08305ab Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Mon, 24 Feb 2020 12:13:35 +0800 +Subject: [PATCH 4/9] vhost-user-blk: delete virtioqueues in unrealize to fix + memleaks + +virtio queues forgot to delete in unrealize, and aslo error path in +realize, this patch fix these memleaks, the leak stack is as follow: + +Direct leak of 114688 byte(s) in 16 object(s) allocated from: + #0 0x7f24024fdbf0 in calloc (/lib64/libasan.so.3+0xcabf0) + #1 0x7f2401642015 in g_malloc0 (/lib64/libglib-2.0.so.0+0x50015) + #2 0x55ad175a6447 in virtio_add_queue /mnt/sdb/qemu/hw/virtio/virtio.c:2327 + #3 0x55ad17570cf9 in vhost_user_blk_device_realize /mnt/sdb/qemu/hw/block/vhost-user-blk.c:419 + #4 0x55ad175a3707 in virtio_device_realize /mnt/sdb/qemu/hw/virtio/virtio.c:3509 + #5 0x55ad176ad0d1 in device_set_realized /mnt/sdb/qemu/hw/core/qdev.c:876 + #6 0x55ad1781ff9d in property_set_bool /mnt/sdb/qemu/qom/object.c:2080 + #7 0x55ad178245ae in object_property_set_qobject /mnt/sdb/qemu/qom/qom-qobject.c:26 + #8 0x55ad17821eb4 in object_property_set_bool /mnt/sdb/qemu/qom/object.c:1338 + #9 0x55ad177aeed7 in virtio_pci_realize /mnt/sdb/qemu/hw/virtio/virtio-pci.c:1801 + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Stefan Hajnoczi +Message-Id: <20200224041336.30790-2-pannengyuan@huawei.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: AlexChen +--- + hw/block/vhost-user-blk.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c +index 6b719d1..dbc0a2e 100644 +--- a/hw/block/vhost-user-blk.c ++++ b/hw/block/vhost-user-blk.c +@@ -469,6 +469,9 @@ reconnect: + virtio_err: + g_free(s->vqs); + g_free(s->inflight); ++ for (i = 0; i < s->num_queues; i++) { ++ virtio_del_queue(vdev, i); ++ } + virtio_cleanup(vdev); + vhost_user_cleanup(&s->vhost_user); + } +@@ -477,6 +480,7 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp) + { + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VHostUserBlk *s = VHOST_USER_BLK(dev); ++ int i; + + virtio_set_status(vdev, 0); + qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL, +@@ -485,6 +489,10 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp) + vhost_dev_free_inflight(s->inflight); + g_free(s->vqs); + g_free(s->inflight); ++ ++ for (i = 0; i < s->num_queues; i++) { ++ virtio_del_queue(vdev, i); ++ } + virtio_cleanup(vdev); + vhost_user_cleanup(&s->vhost_user); + } +-- +1.8.3.1 + diff --git a/virtio-add-ability-to-delete-vq-through-a-pointer.patch b/virtio-add-ability-to-delete-vq-through-a-pointer.patch new file mode 100644 index 00000000..e0989895 --- /dev/null +++ b/virtio-add-ability-to-delete-vq-through-a-pointer.patch @@ -0,0 +1,61 @@ +From 98ae454efe48b2a465dfe9bc3c412b6375f1fbfc Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Mon, 9 Dec 2019 11:46:13 -0500 +Subject: [PATCH 1/9] virtio: add ability to delete vq through a pointer + +Devices tend to maintain vq pointers, allow deleting them trough a vq pointer. + +Signed-off-by: Michael S. Tsirkin +Reviewed-by: David Hildenbrand +Signed-off-by: AlexChen +--- + hw/virtio/virtio.c | 13 +++++++++---- + include/hw/virtio/virtio.h | 2 ++ + 2 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 79c2dcf..3d027d3 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -1636,16 +1636,21 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, + return &vdev->vq[i]; + } + ++void virtio_delete_queue(VirtQueue *vq) ++{ ++ vq->vring.num = 0; ++ vq->vring.num_default = 0; ++ vq->handle_output = NULL; ++ vq->handle_aio_output = NULL; ++} ++ + void virtio_del_queue(VirtIODevice *vdev, int n) + { + if (n < 0 || n >= VIRTIO_QUEUE_MAX) { + abort(); + } + +- vdev->vq[n].vring.num = 0; +- vdev->vq[n].vring.num_default = 0; +- vdev->vq[n].handle_output = NULL; +- vdev->vq[n].handle_aio_output = NULL; ++ virtio_delete_queue(&vdev->vq[n]); + } + + static void virtio_set_isr(VirtIODevice *vdev, int value) +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index f9f6237..ca2fbae 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -187,6 +187,8 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, + + void virtio_del_queue(VirtIODevice *vdev, int n); + ++void virtio_delete_queue(VirtQueue *vq); ++ + void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len); + void virtqueue_flush(VirtQueue *vq, unsigned int count); +-- +1.8.3.1 + diff --git a/virtio-blk-delete-vqs-on-the-error-path-in-realize.patch b/virtio-blk-delete-vqs-on-the-error-path-in-realize.patch new file mode 100644 index 00000000..205f6634 --- /dev/null +++ b/virtio-blk-delete-vqs-on-the-error-path-in-realize.patch @@ -0,0 +1,45 @@ +From ec8a25fec9898f46a6a94aa4f328fe02948b3d59 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Sat, 28 Mar 2020 08:57:04 +0800 +Subject: [PATCH 12/14] virtio-blk: delete vqs on the error path in realize() + +virtio_vqs forgot to free on the error path in realize(). Fix that. + +The asan stack: +Direct leak of 14336 byte(s) in 1 object(s) allocated from: + #0 0x7f58b93fd970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970) + #1 0x7f58b858249d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d) + #2 0x5562cc627f49 in virtio_add_queue /mnt/sdb/qemu/hw/virtio/virtio.c:2413 + #3 0x5562cc4b524a in virtio_blk_device_realize /mnt/sdb/qemu/hw/block/virtio-blk.c:1202 + #4 0x5562cc613050 in virtio_device_realize /mnt/sdb/qemu/hw/virtio/virtio.c:3615 + #5 0x5562ccb7a568 in device_set_realized /mnt/sdb/qemu/hw/core/qdev.c:891 + #6 0x5562cd39cd45 in property_set_bool /mnt/sdb/qemu/qom/object.c:2238 + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Stefano Garzarella +Message-Id: <20200328005705.29898-2-pannengyuan@huawei.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Peng Liang +--- + hw/block/virtio-blk.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index cbb3729158fe..703ed4c93bff 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -1173,6 +1173,9 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) + virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err); + if (err != NULL) { + error_propagate(errp, err); ++ for (i = 0; i < conf->num_queues; i++) { ++ virtio_del_queue(vdev, i); ++ } + virtio_cleanup(vdev); + return; + } +-- +2.26.2 + diff --git a/virtio-crypto-do-delete-ctrl_vq-in-virtio_crypto_dev.patch b/virtio-crypto-do-delete-ctrl_vq-in-virtio_crypto_dev.patch new file mode 100644 index 00000000..aab3e866 --- /dev/null +++ b/virtio-crypto-do-delete-ctrl_vq-in-virtio_crypto_dev.patch @@ -0,0 +1,55 @@ +From 62ded4fc6b38e2642ea4d95a93d70d0f608bee65 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Tue, 25 Feb 2020 15:55:54 +0800 +Subject: [PATCH 3/9] virtio-crypto: do delete ctrl_vq in + virtio_crypto_device_unrealize + +Similar to other virtio-deivces, ctrl_vq forgot to delete in virtio_crypto_device_unrealize, this patch fix it. +This device has aleardy maintained vq pointers. Thus, we use the new virtio_delete_queue function directly to do the cleanup. + +The leak stack: +Direct leak of 10752 byte(s) in 3 object(s) allocated from: + #0 0x7f4c024b1970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970) + #1 0x7f4c018be49d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d) + #2 0x55a2f8017279 in virtio_add_queue /mnt/sdb/qemu-new/qemu_test/qemu/hw/virtio/virtio.c:2333 + #3 0x55a2f8057035 in virtio_crypto_device_realize /mnt/sdb/qemu-new/qemu_test/qemu/hw/virtio/virtio-crypto.c:814 + #4 0x55a2f8005d80 in virtio_device_realize /mnt/sdb/qemu-new/qemu_test/qemu/hw/virtio/virtio.c:3531 + #5 0x55a2f8497d1b in device_set_realized /mnt/sdb/qemu-new/qemu_test/qemu/hw/core/qdev.c:891 + #6 0x55a2f8b48595 in property_set_bool /mnt/sdb/qemu-new/qemu_test/qemu/qom/object.c:2238 + #7 0x55a2f8b54fad in object_property_set_qobject /mnt/sdb/qemu-new/qemu_test/qemu/qom/qom-qobject.c:26 + #8 0x55a2f8b4de2c in object_property_set_bool /mnt/sdb/qemu-new/qemu_test/qemu/qom/object.c:1390 + #9 0x55a2f80609c9 in virtio_crypto_pci_realize /mnt/sdb/qemu-new/qemu_test/qemu/hw/virtio/virtio-crypto-pci.c:58 + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Cc: "Gonglei (Arei)" +Message-Id: <20200225075554.10835-5-pannengyuan@huawei.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: AlexChen +--- + hw/virtio/virtio-crypto.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c +index 45187d3..0076b4b 100644 +--- a/hw/virtio/virtio-crypto.c ++++ b/hw/virtio/virtio-crypto.c +@@ -830,12 +830,13 @@ static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp) + + max_queues = vcrypto->multiqueue ? vcrypto->max_queues : 1; + for (i = 0; i < max_queues; i++) { +- virtio_del_queue(vdev, i); ++ virtio_delete_queue(vcrypto->vqs[i].dataq); + q = &vcrypto->vqs[i]; + qemu_bh_delete(q->dataq_bh); + } + + g_free(vcrypto->vqs); ++ virtio_delete_queue(vcrypto->ctrl_vq); + + virtio_cleanup(vdev); + cryptodev_backend_set_used(vcrypto->cryptodev, false); +-- +1.8.3.1 + diff --git a/virtio-gracefully-handle-invalid-region-caches.patch b/virtio-gracefully-handle-invalid-region-caches.patch new file mode 100644 index 00000000..2793f21b --- /dev/null +++ b/virtio-gracefully-handle-invalid-region-caches.patch @@ -0,0 +1,238 @@ +From 63a3c25baa9c7372b80df80be4447552af6d6ba0 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Fri, 7 Feb 2020 10:46:19 +0000 +Subject: [PATCH 7/9] virtio: gracefully handle invalid region caches + +The virtqueue code sets up MemoryRegionCaches to access the virtqueue +guest RAM data structures. The code currently assumes that +VRingMemoryRegionCaches is initialized before device emulation code +accesses the virtqueue. An assertion will fail in +vring_get_region_caches() when this is not true. Device fuzzing found a +case where this assumption is false (see below). + +Virtqueue guest RAM addresses can also be changed from a vCPU thread +while an IOThread is accessing the virtqueue. This breaks the same +assumption but this time the caches could become invalid partway through +the virtqueue code. The code fetches the caches RCU pointer multiple +times so we will need to validate the pointer every time it is fetched. + +Add checks each time we call vring_get_region_caches() and treat invalid +caches as a nop: memory stores are ignored and memory reads return 0. + +The fuzz test failure is as follows: + + $ qemu -M pc -device virtio-blk-pci,id=drv0,drive=drive0,addr=4.0 \ + -drive if=none,id=drive0,file=null-co://,format=raw,auto-read-only=off \ + -drive if=none,id=drive1,file=null-co://,file.read-zeroes=on,format=raw \ + -display none \ + -qtest stdio + endianness + outl 0xcf8 0x80002020 + outl 0xcfc 0xe0000000 + outl 0xcf8 0x80002004 + outw 0xcfc 0x7 + write 0xe0000000 0x24 0x00ffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffab5cffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffab0000000001 + inb 0x4 + writew 0xe000001c 0x1 + write 0xe0000014 0x1 0x0d + +The following error message is produced: + + qemu-system-x86_64: /home/stefanha/qemu/hw/virtio/virtio.c:286: vring_get_region_caches: Assertion `caches != NULL' failed. + +The backtrace looks like this: + + #0 0x00007ffff5520625 in raise () at /lib64/libc.so.6 + #1 0x00007ffff55098d9 in abort () at /lib64/libc.so.6 + #2 0x00007ffff55097a9 in _nl_load_domain.cold () at /lib64/libc.so.6 + #3 0x00007ffff5518a66 in annobin_assert.c_end () at /lib64/libc.so.6 + #4 0x00005555559073da in vring_get_region_caches (vq=) at qemu/hw/virtio/virtio.c:286 + #5 vring_get_region_caches (vq=) at qemu/hw/virtio/virtio.c:283 + #6 0x000055555590818d in vring_used_flags_set_bit (mask=1, vq=0x5555575ceea0) at qemu/hw/virtio/virtio.c:398 + #7 virtio_queue_split_set_notification (enable=0, vq=0x5555575ceea0) at qemu/hw/virtio/virtio.c:398 + #8 virtio_queue_set_notification (vq=vq@entry=0x5555575ceea0, enable=enable@entry=0) at qemu/hw/virtio/virtio.c:451 + #9 0x0000555555908512 in virtio_queue_set_notification (vq=vq@entry=0x5555575ceea0, enable=enable@entry=0) at qemu/hw/virtio/virtio.c:444 + #10 0x00005555558c697a in virtio_blk_handle_vq (s=0x5555575c57e0, vq=0x5555575ceea0) at qemu/hw/block/virtio-blk.c:775 + #11 0x0000555555907836 in virtio_queue_notify_aio_vq (vq=0x5555575ceea0) at qemu/hw/virtio/virtio.c:2244 + #12 0x0000555555cb5dd7 in aio_dispatch_handlers (ctx=ctx@entry=0x55555671a420) at util/aio-posix.c:429 + #13 0x0000555555cb67a8 in aio_dispatch (ctx=0x55555671a420) at util/aio-posix.c:460 + #14 0x0000555555cb307e in aio_ctx_dispatch (source=, callback=, user_data=) at util/async.c:260 + #15 0x00007ffff7bbc510 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0 + #16 0x0000555555cb5848 in glib_pollfds_poll () at util/main-loop.c:219 + #17 os_host_main_loop_wait (timeout=) at util/main-loop.c:242 + #18 main_loop_wait (nonblocking=) at util/main-loop.c:518 + #19 0x00005555559b20c9 in main_loop () at vl.c:1683 + #20 0x0000555555838115 in main (argc=, argv=, envp=) at vl.c:4441 + +Reported-by: Alexander Bulekov +Cc: Michael Tsirkin +Cc: Cornelia Huck +Cc: Paolo Bonzini +Cc: qemu-stable@nongnu.org +Signed-off-by: Stefan Hajnoczi +Message-Id: <20200207104619.164892-1-stefanha@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: AlexChen +--- + hw/virtio/virtio.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 59 insertions(+), 7 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 3d027d3..90971f4 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -221,15 +221,19 @@ static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc, + + static VRingMemoryRegionCaches *vring_get_region_caches(struct VirtQueue *vq) + { +- VRingMemoryRegionCaches *caches = atomic_rcu_read(&vq->vring.caches); +- assert(caches != NULL); +- return caches; ++ return atomic_rcu_read(&vq->vring.caches); + } ++ + /* Called within rcu_read_lock(). */ + static inline uint16_t vring_avail_flags(VirtQueue *vq) + { + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + hwaddr pa = offsetof(VRingAvail, flags); ++ ++ if (!caches) { ++ return 0; ++ } ++ + return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa); + } + +@@ -238,6 +242,11 @@ static inline uint16_t vring_avail_idx(VirtQueue *vq) + { + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + hwaddr pa = offsetof(VRingAvail, idx); ++ ++ if (!caches) { ++ return 0; ++ } ++ + vq->shadow_avail_idx = virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa); + return vq->shadow_avail_idx; + } +@@ -247,6 +256,11 @@ static inline uint16_t vring_avail_ring(VirtQueue *vq, int i) + { + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + hwaddr pa = offsetof(VRingAvail, ring[i]); ++ ++ if (!caches) { ++ return 0; ++ } ++ + return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa); + } + +@@ -262,6 +276,11 @@ static inline void vring_used_write(VirtQueue *vq, VRingUsedElem *uelem, + { + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + hwaddr pa = offsetof(VRingUsed, ring[i]); ++ ++ if (!caches) { ++ return; ++ } ++ + virtio_tswap32s(vq->vdev, &uelem->id); + virtio_tswap32s(vq->vdev, &uelem->len); + address_space_write_cached(&caches->used, pa, uelem, sizeof(VRingUsedElem)); +@@ -273,6 +292,11 @@ static uint16_t vring_used_idx(VirtQueue *vq) + { + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + hwaddr pa = offsetof(VRingUsed, idx); ++ ++ if (!caches) { ++ return 0; ++ } ++ + return virtio_lduw_phys_cached(vq->vdev, &caches->used, pa); + } + +@@ -281,8 +305,12 @@ static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val) + { + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + hwaddr pa = offsetof(VRingUsed, idx); +- virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val); +- address_space_cache_invalidate(&caches->used, pa, sizeof(val)); ++ ++ if (caches) { ++ virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val); ++ address_space_cache_invalidate(&caches->used, pa, sizeof(val)); ++ } ++ + vq->used_idx = val; + } + +@@ -292,8 +320,13 @@ static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask) + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + VirtIODevice *vdev = vq->vdev; + hwaddr pa = offsetof(VRingUsed, flags); +- uint16_t flags = virtio_lduw_phys_cached(vq->vdev, &caches->used, pa); ++ uint16_t flags; ++ ++ if (!caches) { ++ return; ++ } + ++ flags = virtio_lduw_phys_cached(vq->vdev, &caches->used, pa); + virtio_stw_phys_cached(vdev, &caches->used, pa, flags | mask); + address_space_cache_invalidate(&caches->used, pa, sizeof(flags)); + } +@@ -304,8 +337,13 @@ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask) + VRingMemoryRegionCaches *caches = vring_get_region_caches(vq); + VirtIODevice *vdev = vq->vdev; + hwaddr pa = offsetof(VRingUsed, flags); +- uint16_t flags = virtio_lduw_phys_cached(vq->vdev, &caches->used, pa); ++ uint16_t flags; + ++ if (!caches) { ++ return; ++ } ++ ++ flags = virtio_lduw_phys_cached(vq->vdev, &caches->used, pa); + virtio_stw_phys_cached(vdev, &caches->used, pa, flags & ~mask); + address_space_cache_invalidate(&caches->used, pa, sizeof(flags)); + } +@@ -320,6 +358,10 @@ static inline void vring_set_avail_event(VirtQueue *vq, uint16_t val) + } + + caches = vring_get_region_caches(vq); ++ if (!caches) { ++ return; ++ } ++ + pa = offsetof(VRingUsed, ring[vq->vring.num]); + virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val); + address_space_cache_invalidate(&caches->used, pa, sizeof(val)); +@@ -626,6 +668,11 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, + + max = vq->vring.num; + caches = vring_get_region_caches(vq); ++ if (!caches) { ++ virtio_error(vdev, "Region cached not initialized"); ++ goto err; ++ } ++ + if (caches->desc.len < max * sizeof(VRingDesc)) { + virtio_error(vdev, "Cannot map descriptor ring"); + goto err; +@@ -894,6 +941,11 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) + i = head; + + caches = vring_get_region_caches(vq); ++ if (!caches) { ++ virtio_error(vdev, "Region caches not initialized"); ++ goto done; ++ } ++ + if (caches->desc.len < max * sizeof(VRingDesc)) { + virtio_error(vdev, "Cannot map descriptor ring"); + goto done; +-- +1.8.3.1 + diff --git a/virtio-input-fix-memory-leak-on-unrealize.patch b/virtio-input-fix-memory-leak-on-unrealize.patch new file mode 100644 index 00000000..df83453f --- /dev/null +++ b/virtio-input-fix-memory-leak-on-unrealize.patch @@ -0,0 +1,45 @@ +From e29f08036ff11bf220463b4327b315505e760a44 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 21 Nov 2019 13:56:49 +0400 +Subject: [PATCH 9/9] virtio-input: fix memory leak on unrealize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Spotted by ASAN + minor stylistic change. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Michael S. Tsirkin +Message-Id: <20191121095649.25453-1-marcandre.lureau@redhat.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Marc-André Lureau +Reviewed-by: Michael S. Tsirkin +Signed-off-by: AlexChen +--- + hw/input/virtio-input.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c +index 9946394..401c1de 100644 +--- a/hw/input/virtio-input.c ++++ b/hw/input/virtio-input.c +@@ -275,6 +275,7 @@ static void virtio_input_finalize(Object *obj) + + g_free(vinput->queue); + } ++ + static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) + { + VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); +@@ -288,6 +289,8 @@ static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) + return; + } + } ++ virtio_del_queue(vdev, 0); ++ virtio_del_queue(vdev, 1); + virtio_cleanup(vdev); + } + +-- +1.8.3.1 + diff --git a/virtio-pci-fix-queue_enable-write.patch b/virtio-pci-fix-queue_enable-write.patch new file mode 100644 index 00000000..481b41bb --- /dev/null +++ b/virtio-pci-fix-queue_enable-write.patch @@ -0,0 +1,58 @@ +From aebd6a1512e03ba51f6824fcdbaa09f67e9ff5e2 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 10 Jun 2020 13:43:51 +0800 +Subject: [PATCH 11/11] virtio-pci: fix queue_enable write + +Spec said: The driver uses this to selectively prevent the device from +executing requests from this virtqueue. 1 - enabled; 0 - disabled. + +Though write 0 to queue_enable is forbidden by the spec, we should not +assume that the value is 1. + +Fix this by ignore the write value other than 1. + +Signed-off-by: Jason Wang +Message-Id: <20200610054351.15811-1-jasowang@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Stefano Garzarella +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: BiaoXiang Ye +--- + hw/virtio/virtio-pci.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c +index b4b0ed26..4b8845a6 100644 +--- a/hw/virtio/virtio-pci.c ++++ b/hw/virtio/virtio-pci.c +@@ -1259,16 +1259,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, + virtio_queue_set_vector(vdev, vdev->queue_sel, val); + break; + case VIRTIO_PCI_COMMON_Q_ENABLE: +- virtio_queue_set_num(vdev, vdev->queue_sel, +- proxy->vqs[vdev->queue_sel].num); +- virtio_queue_set_rings(vdev, vdev->queue_sel, ++ if (val == 1) { ++ virtio_queue_set_num(vdev, vdev->queue_sel, ++ proxy->vqs[vdev->queue_sel].num); ++ virtio_queue_set_rings(vdev, vdev->queue_sel, + ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 | + proxy->vqs[vdev->queue_sel].desc[0], + ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 | + proxy->vqs[vdev->queue_sel].avail[0], + ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 | + proxy->vqs[vdev->queue_sel].used[0]); +- proxy->vqs[vdev->queue_sel].enabled = 1; ++ proxy->vqs[vdev->queue_sel].enabled = 1; ++ } else { ++ virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val); ++ } + break; + case VIRTIO_PCI_COMMON_Q_DESCLO: + proxy->vqs[vdev->queue_sel].desc[0] = val; +-- +2.27.0.dirty + diff --git a/virtio-pmem-do-delete-rq_vq-in-virtio_pmem_unrealize.patch b/virtio-pmem-do-delete-rq_vq-in-virtio_pmem_unrealize.patch new file mode 100644 index 00000000..d8ed58fa --- /dev/null +++ b/virtio-pmem-do-delete-rq_vq-in-virtio_pmem_unrealize.patch @@ -0,0 +1,39 @@ +From 637606d18c7208e21d8ab4f318cccde64ae58c76 Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Tue, 25 Feb 2020 15:55:53 +0800 +Subject: [PATCH 2/9] virtio-pmem: do delete rq_vq in virtio_pmem_unrealize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Similar to other virtio-devices, rq_vq forgot to delete in +virtio_pmem_unrealize, this patch fix it. This device has already +maintained a vq pointer, thus we use the new virtio_delete_queue +function directly to do the cleanup. + +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Message-Id: <20200225075554.10835-4-pannengyuan@huawei.com> +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: AlexChen +--- + hw/virtio/virtio-pmem.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c +index 17c196d..c680b0a 100644 +--- a/hw/virtio/virtio-pmem.c ++++ b/hw/virtio/virtio-pmem.c +@@ -127,6 +127,7 @@ static void virtio_pmem_unrealize(DeviceState *dev, Error **errp) + VirtIOPMEM *pmem = VIRTIO_PMEM(dev); + + host_memory_backend_set_mapped(pmem->memdev, false); ++ virtio_delete_queue(pmem->rq_vq); + virtio_cleanup(vdev); + } + +-- +1.8.3.1 + diff --git a/virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch b/virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch new file mode 100644 index 00000000..02069901 --- /dev/null +++ b/virtio-serial-bus-Plug-memory-leak-on-realize-error-.patch @@ -0,0 +1,65 @@ +From 0d93f5455489274201b1054d987b12f8e8a6206e Mon Sep 17 00:00:00 2001 +From: Pan Nengyuan +Date: Mon, 9 Mar 2020 10:17:38 +0800 +Subject: [PATCH 11/14] virtio-serial-bus: Plug memory leak on realize() error + paths + +We neglect to free port->bh on the error paths. Fix that. +Reproducer: + {'execute': 'device_add', 'arguments': {'id': 'virtio_serial_pci0', 'driver': 'virtio-serial-pci', 'bus': 'pci.0', 'addr': '0x5'}, 'id': 'yVkZcGgV'} + {'execute': 'device_add', 'arguments': {'id': 'port1', 'driver': 'virtserialport', 'name': 'port1', 'chardev': 'channel1', 'bus': 'virtio_serial_pci0.0', 'nr': 1}, 'id': '3dXdUgJA'} + {'execute': 'device_add', 'arguments': {'id': 'port2', 'driver': 'virtserialport', 'name': 'port2', 'chardev': 'channel2', 'bus': 'virtio_serial_pci0.0', 'nr': 1}, 'id': 'qLzcCkob'} + {'execute': 'device_add', 'arguments': {'id': 'port2', 'driver': 'virtserialport', 'name': 'port2', 'chardev': 'channel2', 'bus': 'virtio_serial_pci0.0', 'nr': 2}, 'id': 'qLzcCkob'} + +The leak stack: +Direct leak of 40 byte(s) in 1 object(s) allocated from: + #0 0x7f04a8008ae8 in __interceptor_malloc (/lib64/libasan.so.5+0xefae8) + #1 0x7f04a73cf1d5 in g_malloc (/lib64/libglib-2.0.so.0+0x531d5) + #2 0x56273eaee484 in aio_bh_new /mnt/sdb/backup/qemu/util/async.c:125 + #3 0x56273eafe9a8 in qemu_bh_new /mnt/sdb/backup/qemu/util/main-loop.c:532 + #4 0x56273d52e62e in virtser_port_device_realize /mnt/sdb/backup/qemu/hw/char/virtio-serial-bus.c:946 + #5 0x56273dcc5040 in device_set_realized /mnt/sdb/backup/qemu/hw/core/qdev.c:891 + #6 0x56273e5ebbce in property_set_bool /mnt/sdb/backup/qemu/qom/object.c:2238 + #7 0x56273e5e5a9c in object_property_set /mnt/sdb/backup/qemu/qom/object.c:1324 + #8 0x56273e5ef5f8 in object_property_set_qobject /mnt/sdb/backup/qemu/qom/qom-qobject.c:26 + #9 0x56273e5e5e6a in object_property_set_bool /mnt/sdb/backup/qemu/qom/object.c:1390 + #10 0x56273daa40de in qdev_device_add /mnt/sdb/backup/qemu/qdev-monitor.c:680 + #11 0x56273daa53e9 in qmp_device_add /mnt/sdb/backup/qemu/qdev-monitor.c:805 + +Fixes: 199646d81522509ac2dba6d28c31e8c7d807bc93 +Reported-by: Euler Robot +Signed-off-by: Pan Nengyuan +Reviewed-by: Markus Armbruster +Reviewed-by: Amit Shah +Message-Id: <20200309021738.30072-1-pannengyuan@huawei.com> +Reviewed-by: Laurent Vivier +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Peng Liang +--- + hw/char/virtio-serial-bus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c +index f7a54f261b21..2d23dae6d2b7 100644 +--- a/hw/char/virtio-serial-bus.c ++++ b/hw/char/virtio-serial-bus.c +@@ -940,7 +940,6 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + Error *err = NULL; + + port->vser = bus->vser; +- port->bh = qemu_bh_new(flush_queued_data_bh, port); + + assert(vsc->have_data); + +@@ -989,6 +988,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + return; + } + ++ port->bh = qemu_bh_new(flush_queued_data_bh, port); + port->elem = NULL; + } + +-- +2.26.2 + diff --git a/xhci-fix-valid.max_access_size-to-access-address-reg.patch b/xhci-fix-valid.max_access_size-to-access-address-reg.patch new file mode 100644 index 00000000..466cbf26 --- /dev/null +++ b/xhci-fix-valid.max_access_size-to-access-address-reg.patch @@ -0,0 +1,62 @@ +From a71d1847aa780b3c4062e582ab400a7fea0413b3 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Tue, 21 Jul 2020 10:33:22 +0200 +Subject: [PATCH 01/11] xhci: fix valid.max_access_size to access address + registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU XHCI advertises AC64 (64-bit addressing) but doesn't allow +64-bit mode access in "runtime" and "operational" MemoryRegionOps. + +Set the max_access_size based on sizeof(dma_addr_t) as AC64 is set. + +XHCI specs: +"If the xHC supports 64-bit addressing (AC64 = ‘1’), then software +should write 64-bit registers using only Qword accesses. If a +system is incapable of issuing Qword accesses, then writes to the +64-bit address fields shall be performed using 2 Dword accesses; +low Dword-first, high-Dword second. If the xHC supports 32-bit +addressing (AC64 = ‘0’), then the high Dword of registers containing +64-bit address fields are unused and software should write addresses +using only Dword accesses" + +The problem has been detected with SLOF, as linux kernel always accesses +registers using 32-bit access even if AC64 is set and revealed by +5d971f9e6725 ("memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"") + +Suggested-by: Alexey Kardashevskiy +Signed-off-by: Laurent Vivier +Message-id: 20200721083322.90651-1-lvivier@redhat.com +Signed-off-by: Gerd Hoffmann +Signed-off-by: BiaoXiang Ye +--- + hw/usb/hcd-xhci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index a21485fe..24565de1 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -3171,7 +3171,7 @@ static const MemoryRegionOps xhci_oper_ops = { + .read = xhci_oper_read, + .write = xhci_oper_write, + .valid.min_access_size = 4, +- .valid.max_access_size = 4, ++ .valid.max_access_size = sizeof(dma_addr_t), + .endianness = DEVICE_LITTLE_ENDIAN, + }; + +@@ -3187,7 +3187,7 @@ static const MemoryRegionOps xhci_runtime_ops = { + .read = xhci_runtime_read, + .write = xhci_runtime_write, + .valid.min_access_size = 4, +- .valid.max_access_size = 4, ++ .valid.max_access_size = sizeof(dma_addr_t), + .endianness = DEVICE_LITTLE_ENDIAN, + }; + +-- +2.27.0.dirty + -- Gitee