!342 some bugfix sync from 20.09

From: @imxcc
Reviewed-by: @kevinzhu1
Signed-off-by: @kevinzhu1
This commit is contained in:
openeuler-ci-bot 2021-07-28 08:32:06 +00:00 committed by Gitee
commit 0ca7fd6709
62 changed files with 4061 additions and 1 deletions

View File

@ -0,0 +1,40 @@
From 41077af2c4283c15c0a822017ea51612d15b68f8 Mon Sep 17 00:00:00 2001
From: Andrew Melnychenko <andrew@daynix.com>
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 <andrew@daynix.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Dmitry Fleytman <dmitry.fleytman@gmail.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,50 @@
From 3bdd21c4b7d80cacc6b5f1b26ab52ef3a0aceb06 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
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 <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
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

View File

@ -0,0 +1,37 @@
From d0c4e8cc25dc3bfed1659c35fb59b2f0418ba1d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Volker=20R=C3=BCmelin?= <vr_qemu@t-online.de>
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 <vr_qemu@t-online.de>
Message-id: 8893a235-66a8-8fbe-7d95-862e29da90b1@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
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

View File

@ -0,0 +1,35 @@
From 6a39af8880c18fb3bcbfb715aef909c64286524e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
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 <eblake@redhat.com>
Message-Id: <20200320183620.1112123-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Tested-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,116 @@
From 3754525eb383f91869634766ccd041cfe40bbf17 Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <child_backing>,
ctx=<optimized out>, perm=<optimized out>, 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 <child_backing>,
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=<optimized out>, fn=<optimized out>) 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 <child_backing>,
ctx=<optimized out>, perm=<optimized out>, 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 <child_backing>,
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 <vsementsov@virtuozzo.com>
Message-Id: <20200316060631.30052-2-vsementsov@virtuozzo.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,33 @@
From 5060ef71fa4621061101a30fa9e0d1690696c5c1 Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <vsementsov@virtuozzo.com>
Message-Id: <20200324155921.23822-1-vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,34 @@
From 682d23829adf0a872d5a3ca6eb4b31c424f558fc Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <vsementsov@virtuozzo.com>
Message-Id: <20200324153630.11882-3-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,67 @@
From 1196a2079a558cbb673e06142fa67a401c5e6c30 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <sgarzare@redhat.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <1575517528-44312-2-git-send-email-pannengyuan@huawei.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[eblake: fix compilation error and commit message]
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,54 @@
From 88ef4e1862987227f8b87228cff94be3af66d054 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200227012950.12256-2-pannengyuan@huawei.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,75 @@
From a583b6b616b086d3fdce93e255d24ab2c865efd3 Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <vsementsov@virtuozzo.com>
Message-Id: <20200302150930.16218-1-vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,126 @@
From 902a8192600ff81681a162509e23bf95619d1f04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20200420112012.567284-1-marcandre.lureau@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,43 @@
From 4488ab4700d344b049ddef808a64eda4b5867902 Mon Sep 17 00:00:00 2001
From: lichun <lichun@ruijie.com.cn>
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 <lichun@ruijie.com.cn>
Message-Id: <20200621213017.17978-1-lichun@ruijie.com.cn>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Commit message improved, cc: qemu-stable]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,90 @@
From 19afb1431bd730a1e4e09e3c0835c35572517268 Mon Sep 17 00:00:00 2001
From: Derek Su <dereksu@qnap.com>
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 <dereksu@qnap.com>
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,139 @@
From d0586065e67b5df2611f4cf61eb791d48b78ff77 Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <pbonzini@redhat.com>
---
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

View File

@ -0,0 +1,35 @@
From 7edca67dc630e31043644e87ede2e05e504f845b Mon Sep 17 00:00:00 2001
From: Cameron Esfahani <dirty@apple.com>
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 <dirty@apple.com>
Message-Id: <d6c26e68db134c7b0c7ce8b61596ca2e65e01e12.1576013209.git.dirty@apple.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
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

View File

@ -0,0 +1,31 @@
From 94be73a20d42482cdf30115e672c36af2fe9068d Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
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 <kwolf@redhat.com>
Message-Id: <20200717105426.51134-4-kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,81 @@
From 0b77995819a596f96c621697643e83624126e668 Mon Sep 17 00:00:00 2001
From: Li Feng <fengli@smartx.com>
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 <fengli@smartx.com>
Message-Id: <20200323052924.29286-1-fengli@smartx.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,48 @@
From 6cb599f75b7844aefd7823ad97fc3bae70eff11f Mon Sep 17 00:00:00 2001
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
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 <dgilbert@redhat.com>
Message-Id: <20200323120822.51266-1-dgilbert@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,54 @@
From b7ef7e6fb5a2b08268f4b19c07c07abd4fbb2064 Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <pbonzini@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
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

View File

@ -0,0 +1,62 @@
From 1aa42c9269c762ad1b7efa41e92f734b093dce1c Mon Sep 17 00:00:00 2001
From: Klaus Jensen <k.jensen@samsung.com>
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 <k.jensen@samsung.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Message-Id: <20200609190333.59390-2-its@irrelevant.dk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,87 @@
From 74ef18c90684f0ae18aef071b9e11a5e8796177b Mon Sep 17 00:00:00 2001
From: alexchen <alex.chen@huawei.com>
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" <mst@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Message-Id: <20200609190333.59390-8-its@irrelevant.dk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,67 @@
From 595a0d0a0f21cd73863ea3b78ecccb6e0ea8b7a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <f4bug@amsat.org>
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 <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20200601142930.29408-4-f4bug@amsat.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
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

View File

@ -0,0 +1,28 @@
From df35f8fe2687df32cb65f6a03b8dd80314cc4c53 Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <pbonzini@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
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

View File

@ -0,0 +1,34 @@
From 7b4aded3f772ef43e2b600594f755eadd5da5958 Mon Sep 17 00:00:00 2001
From: Jonathan Marler <johnnymarler@gmail.com>
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 <johnnymarler@gmail.com>
Reviewded-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20200502161225.14346-1-johnnymarler@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
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

View File

@ -0,0 +1,77 @@
From d50be5295c49be1b6024f5902948b52e683b4c23 Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <pbonzini@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
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

View File

@ -0,0 +1,102 @@
From e3dfb5d2848975e9e947cb894afac87ce386a2bc Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <armbru@redhat.com>
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
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

View File

@ -0,0 +1,29 @@
From 07b7cdb648124748c34be299fbfdfe3b6e38a521 Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <pbonzini@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
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

View File

@ -0,0 +1,32 @@
From 2ff9c28e2b72cd359a0c4e931412e355baee8e1e Mon Sep 17 00:00:00 2001
From: lizhengui <lizhengui@huawei.com>
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 <pbonzini@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
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

View File

@ -0,0 +1,158 @@
From 2eadc5c611ca8cc916f74c0f393f1fd942903ef7 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
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 <quintela@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
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

View File

@ -0,0 +1,74 @@
From 63320ae36834e4ff2f0d139f205c464caa3887b4 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
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 <zhukeqian1@huawei.com>
Message-Id: <20200622032037.31112-1-zhukeqian1@huawei.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,237 @@
From 21e049e2941b108df45c9089cbf7539caae538e6 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
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 <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
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

View File

@ -0,0 +1,33 @@
From 663e9b5f25d22834260a0686f77a27c957cd7b2f Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <vsementsov@virtuozzo.com>
Message-Id: <20200324153630.11882-5-vsementsov@virtuozzo.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,64 @@
From 1d7c227bbb24665cea03f96a984ad6be223ac40c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Message-Id: <20200325184723.2029630-2-marcandre.lureau@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,51 @@
From 0f7e704a4faa661583ea6d82659f206e561f23d4 Mon Sep 17 00:00:00 2001
From: Wei Yang <richardw.yang@linux.intel.com>
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 <richardw.yang@linux.intel.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
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

View File

@ -0,0 +1,41 @@
From 7331554bd6ab230404b20d612aed20a95c20eba6 Mon Sep 17 00:00:00 2001
From: Wei Yang <richardw.yang@linux.intel.com>
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 <richardw.yang@linux.intel.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
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

View File

@ -0,0 +1,33 @@
From 019526f7f7b42a7d1b8a74e1db6a8050adf9e1fb Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <vsementsov@virtuozzo.com>
Message-Id: <20200324153630.11882-6-vsementsov@virtuozzo.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,58 @@
From 9867dc6fc3f131324b73664b9617376270d8d013 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Message-Id: <20200508100755.7875-3-pannengyuan@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
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

View File

@ -0,0 +1,63 @@
From 0d8c145e986d4f500f065d2d8645e95175324e62 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,58 @@
From b77ade9bb37b2e9813a42008cb21d0c743aa50a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200110153039.1379601-19-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,34 @@
From d2bb5b4c4ed3b1dbc0096deb195b6df33f813f23 Mon Sep 17 00:00:00 2001
From: Yifan Luo <luoyifan@cmss.chinamobile.com>
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 <luoyifan@cmss.chinamobile.com>
Message-Id: <02cf01d55267$86cf2850$946d78f0$@cmss.chinamobile.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
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

View File

@ -0,0 +1,33 @@
From d22af5cb41c16829dbf3ed3c611ef56ceeb840ff Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Message-Id: <20200227012950.12256-3-pannengyuan@huawei.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

126
qemu.spec
View File

@ -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 <xingchaochao@huawei.com>
- 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 <xingchaochao@huawei.com>
- hw/arm/virt: Init PMU for hotplugged vCPU

View File

@ -0,0 +1,40 @@
From 1580682eafb489eaf417456778267662629cf696 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
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<INDEX>/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 <mdroth@linux.vnet.ibm.com>
Cc: Hailiang Zhang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Message-Id: <20200630090351.1247703-9-armbru@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,49 @@
From 15847279f29b0bd67b95daefff395cab8fad80d3 Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
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 <vsementsov@virtuozzo.com>
Message-Id: <20200324153630.11882-7-vsementsov@virtuozzo.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,47 @@
From aeccff89333c565c7a894f99c17c0044d7d43be2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <mdroth@linux.vnet.ibm.com>
Reported-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,47 @@
From 1f1949368d4ac7a18973aa83a074daf01daf97ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Message-Id: <20200325184723.2029630-3-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,57 @@
From b54ca94f19a9b22537712638ae05d2095258eb80 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
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 <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,42 @@
From ad6ce039cab07b6a99ccaa36fbb0043ae85a74c9 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
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 <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,31 @@
From 88e3146118230de8b99280db219a6a6c47bebce1 Mon Sep 17 00:00:00 2001
From: Peng Liang <liangpeng10@huawei.com>
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 <zhang.zhanghailiang@huawei.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,54 @@
From 66fce891aecec3969d1ba979cf0a9a6df70afecd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190807084048.4258-1-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
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

View File

@ -0,0 +1,99 @@
From 30d20e1258722431198cd2a8298c85b7af2a0c1b Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <pannengyuan@huawei.com>
Message-Id: <20200224041336.30790-3-pannengyuan@huawei.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,90 @@
From 632a841b6ba547906b475250f5c2cb46774ab4af Mon Sep 17 00:00:00 2001
From: Dima Stepanov <dimastep@yandex-team.ru>
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 <dimastep@yandex-team.ru>
Message-Id: <69b73b94dcd066065595266c852810e0863a0895.1590396396.git.dimastep@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Li Feng <fengli@smartx.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,69 @@
From d8febdc4940d719dba77a17a10a8d36ad08305ab Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20200224041336.30790-2-pannengyuan@huawei.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,61 @@
From 98ae454efe48b2a465dfe9bc3c412b6375f1fbfc Mon Sep 17 00:00:00 2001
From: "Michael S. Tsirkin" <mst@redhat.com>
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 <mst@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,45 @@
From ec8a25fec9898f46a6a94aa4f328fe02948b3d59 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Message-Id: <20200328005705.29898-2-pannengyuan@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,55 @@
From 62ded4fc6b38e2642ea4d95a93d70d0f608bee65 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Cc: "Gonglei (Arei)" <arei.gonglei@huawei.com>
Message-Id: <20200225075554.10835-5-pannengyuan@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,238 @@
From 63a3c25baa9c7372b80df80be4447552af6d6ba0 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
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=<optimized out>) at qemu/hw/virtio/virtio.c:286
#5 vring_get_region_caches (vq=<optimized out>) 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=<optimized out>, callback=<optimized out>, user_data=<optimized out>) 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=<optimized out>) at util/main-loop.c:242
#18 main_loop_wait (nonblocking=<optimized out>) at util/main-loop.c:518
#19 0x00005555559b20c9 in main_loop () at vl.c:1683
#20 0x0000555555838115 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4441
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Cc: Michael Tsirkin <mst@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20200207104619.164892-1-stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,45 @@
From e29f08036ff11bf220463b4327b315505e760a44 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
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 <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20191121095649.25453-1-marcandre.lureau@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,58 @@
From aebd6a1512e03ba51f6824fcdbaa09f67e9ff5e2 Mon Sep 17 00:00:00 2001
From: Jason Wang <jasowang@redhat.com>
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 <jasowang@redhat.com>
Message-Id: <20200610054351.15811-1-jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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

View File

@ -0,0 +1,39 @@
From 637606d18c7208e21d8ab4f318cccde64ae58c76 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Message-Id: <20200225075554.10835-4-pannengyuan@huawei.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
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

View File

@ -0,0 +1,65 @@
From 0d93f5455489274201b1054d987b12f8e8a6206e Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
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 <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Amit Shah <amit@kernel.org>
Message-Id: <20200309021738.30072-1-pannengyuan@huawei.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
---
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

View File

@ -0,0 +1,62 @@
From a71d1847aa780b3c4062e582ab400a7fea0413b3 Mon Sep 17 00:00:00 2001
From: Laurent Vivier <lvivier@redhat.com>
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 <aik@au1.ibm.com>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Message-id: 20200721083322.90651-1-lvivier@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: BiaoXiang Ye <yebiaoxiang@huawei.com>
---
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