!501 [sync] master branch upgrade to version 6.2.0

From: @yezengruan 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
This commit is contained in:
openeuler-ci-bot 2022-03-20 09:28:22 +00:00 committed by Gitee
commit 393705cbda
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
681 changed files with 32197 additions and 52913 deletions

View File

@ -0,0 +1,59 @@
From 8ddc2bcb196a34cc641d50b057550e4b11dc8700 Mon Sep 17 00:00:00 2001
From: Xu Yandong <xuyandong2@huawei.com>
Date: Wed, 9 Feb 2022 17:39:34 +0800
Subject: [PATCH 3/3] cpu: add Cortex-A72 processor kvm target support
The ARM Cortex-A72 is ARMv8-A micro-architecture,
add kvm target to ARM Cortex-A72 processor definition.
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/arm/cpu64.c | 2 +-
target/arm/kvm-consts.h | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 26419fe994..1b56261964 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -202,6 +202,7 @@ static void aarch64_a72_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,cortex-a72";
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
@@ -265,7 +266,6 @@ static void aarch64_kunpeng_920_initfn(Object *obj)
cpu->isar.id_aa64dfr0 = 0x110305408;
cpu->isar.id_aa64isar0 = 0x10211120;
cpu->isar.id_aa64mmfr0 = 0x101125;
- cpu->kvm_target = KVM_ARM_TARGET_GENERIC_V8;
}
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
index 580f1c1fee..5f1311ade7 100644
--- a/target/arm/kvm-consts.h
+++ b/target/arm/kvm-consts.h
@@ -130,6 +130,8 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED);
#define QEMU_KVM_ARM_TARGET_CORTEX_A57 2
#define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3
#define QEMU_KVM_ARM_TARGET_CORTEX_A53 4
+/* Generic ARM v8 target */
+#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5
/* There's no kernel define for this: sentinel value which
* matches no KVM target value for either 64 or 32 bit
@@ -141,6 +143,7 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8);
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57);
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA);
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53);
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8);
#define CP_REG_ARM64 0x6000000000000000ULL
#define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000
--
2.27.0

View File

@ -1,38 +0,0 @@
From 841b8d099c462cd4282c4ced8c2a6512899fd8d9 Mon Sep 17 00:00:00 2001
From: Jiajun Chen <chenjiajun8@huawei.com>
Date: Mon, 20 Jan 2020 15:11:39 +0100
Subject: [PATCH] 9pfs: local: Fix possible memory leak in local_link()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is a possible memory leak while local_link return -1 without free
odirpath and oname.
Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Jaijun Chen <chenjiajun8@huawei.com>
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 841b8d099c462cd4282c4ced8c2a6512899fd8d9)
---
hw/9pfs/9p-local.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index ca64139..d0592c3 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -947,7 +947,7 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(ctx, name)) {
errno = EINVAL;
- return -1;
+ goto out;
}
odirfd = local_opendir_nofollow(ctx, odirpath);
--
1.8.3.1

View File

@ -1,64 +0,0 @@
From e3a7ec839fa4f823666d726989c375dcf73348a4 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Wed, 15 Apr 2020 16:14:50 +0800
Subject: [PATCH] ARM: KVM: Check KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 for smp_cpus >
256
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Host kernel within [4.18, 5.3] report an erroneous KVM_MAX_VCPUS=512
for ARM. The actual capability to instantiate more than 256 vcpus
was fixed in 5.4 with the upgrade of the KVM_IRQ_LINE ABI to support
vcpu id encoded on 12 bits instead of 8 and a redistributor consuming
a single KVM IO device instead of 2.
So let's check this capability when attempting to use more than 256
vcpus within any ARM kvm accelerated machine.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Message-id: 20191003154640.22451-4-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry-picked from commit fff9f5558d0e0813d4f80bfe1602acf225eca4fd)
[yu: Use the legacy smp_cpus instead of ms->smp.cpus, as we don't have
¦struct CpuTopology in MachineState at that time. See commit
¦edeeec911702 for details.]
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
target/arm/kvm.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 50e86f8b..cc7a46df 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -173,6 +173,8 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
int kvm_arch_init(MachineState *ms, KVMState *s)
{
+ int ret = 0;
+ unsigned int smp_cpus = ms->smp.cpus;
/* For ARM interrupt delivery is always asynchronous,
* whether we are using an in-kernel VGIC or not.
*/
@@ -186,7 +188,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
- return 0;
+ if (smp_cpus > 256 &&
+ !kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) {
+ error_report("Using more than 256 vcpus requires a host kernel "
+ "with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2");
+ ret = -EINVAL;
+ }
+
+ return ret;
}
unsigned long kvm_arch_vcpu_id(CPUState *cpu)
--
2.23.0

View File

@ -1,134 +0,0 @@
From 4646a24045cf53f2cc5e0ef1974da88ef50ef676 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Wed, 27 May 2020 11:54:31 +0800
Subject: [PATCH] ARM64: record vtimer tick when cpu is stopped
The vtimer kick still increases even if the vcpu is stopped when VM has
save/restore or suspend/resume operation. This will cause guest watchdog
soft-lockup if the VM has lots of memory in use.
Signed-off-by: Hao Hong <honghao5@huawei.com>
Signed-off-by: Haibin Wang <wanghaibin.wang@huawei.com>
Signed-off-by: Ying Fang <fangying1@huawei.com>
---
cpus.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
target/arm/cpu.h | 2 ++
target/arm/machine.c | 1 +
3 files changed, 61 insertions(+)
diff --git a/cpus.c b/cpus.c
index 927a00aa..b9aa51f8 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1066,6 +1066,28 @@ void cpu_synchronize_all_pre_loadvm(void)
}
}
+#ifdef __aarch64__
+static void get_vcpu_timer_tick(CPUState *cs)
+{
+ CPUARMState *env = &ARM_CPU(cs)->env;
+ int err;
+ struct kvm_one_reg reg;
+ uint64_t timer_tick;
+
+ reg.id = KVM_REG_ARM_TIMER_CNT;
+ reg.addr = (uintptr_t) &timer_tick;
+
+ err = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (err < 0) {
+ error_report("get vcpu tick failed, ret = %d", err);
+ env->vtimer = 0;
+ return;
+ }
+ env->vtimer = timer_tick;
+ return;
+}
+#endif
+
static int do_vm_stop(RunState state, bool send_stop)
{
int ret = 0;
@@ -1073,6 +1095,11 @@ static int do_vm_stop(RunState state, bool send_stop)
if (runstate_is_running()) {
cpu_disable_ticks();
pause_all_vcpus();
+#ifdef __aarch64__
+ if (first_cpu) {
+ get_vcpu_timer_tick(first_cpu);
+ }
+#endif
runstate_set(state);
vm_state_notify(0, state);
if (send_stop) {
@@ -1918,11 +1945,42 @@ void cpu_resume(CPUState *cpu)
qemu_cpu_kick(cpu);
}
+#ifdef __aarch64__
+static void set_vcpu_timer_tick(CPUState *cs)
+{
+ CPUARMState *env = &ARM_CPU(cs)->env;
+
+ if (env->vtimer == 0) {
+ return;
+ }
+
+ int err;
+ struct kvm_one_reg reg;
+ uint64_t timer_tick = env->vtimer;
+ env->vtimer = 0;
+
+ reg.id = KVM_REG_ARM_TIMER_CNT;
+ reg.addr = (uintptr_t) &timer_tick;
+
+ err = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (err < 0) {
+ error_report("Set vcpu tick failed, ret = %d", err);
+ return;
+ }
+ return;
+}
+#endif
+
void resume_all_vcpus(void)
{
CPUState *cpu;
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
+#ifdef __aarch64__
+ if (first_cpu) {
+ set_vcpu_timer_tick(first_cpu);
+ }
+#endif
CPU_FOREACH(cpu) {
cpu_resume(cpu);
}
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 86eb79cd..aec6a214 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -262,6 +262,8 @@ typedef struct CPUARMState {
uint64_t sp_el[4]; /* AArch64 banked stack pointers */
+ uint64_t vtimer; /* Timer tick when vcpu stop */
+
/* System control coprocessor (cp15) */
struct {
uint32_t c0_cpuid;
diff --git a/target/arm/machine.c b/target/arm/machine.c
index ee3c59a6..ec28b839 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -814,6 +814,7 @@ const VMStateDescription vmstate_arm_cpu = {
VMSTATE_UINT32(env.exception.syndrome, ARMCPU),
VMSTATE_UINT32(env.exception.fsr, ARMCPU),
VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
+ VMSTATE_UINT64(env.vtimer, ARMCPU),
VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU),
VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU),
{
--
2.23.0

View File

@ -1,54 +0,0 @@
From 8cb4d202d4e5713e9b2b5f0ec817234941623f10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Fri, 4 Jun 2021 15:58:25 +0400
Subject: [PATCH 1/6] Add mtod_check()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Recent security issues demonstrate the lack of safety care when casting
a mbuf to a particular structure type. At least, it should check that
the buffer is large enough. The following patches will make use of this
function.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: imxcc <xingchaochao@huawei.com>
---
slirp/src/mbuf.c | 11 +++++++++++
slirp/src/mbuf.h | 1 +
2 files changed, 12 insertions(+)
diff --git a/slirp/src/mbuf.c b/slirp/src/mbuf.c
index 4fd62282..6d0653ed 100644
--- a/slirp/src/mbuf.c
+++ b/slirp/src/mbuf.c
@@ -222,3 +222,14 @@ struct mbuf *dtom(Slirp *slirp, void *dat)
return (struct mbuf *)0;
}
+
+void *mtod_check(struct mbuf *m, size_t len)
+{
+ if (m->m_len >= len) {
+ return m->m_data;
+ }
+
+ DEBUG_ERROR("mtod failed");
+
+ return NULL;
+}
diff --git a/slirp/src/mbuf.h b/slirp/src/mbuf.h
index 546e7852..2015e323 100644
--- a/slirp/src/mbuf.h
+++ b/slirp/src/mbuf.h
@@ -118,6 +118,7 @@ void m_inc(struct mbuf *, int);
void m_adj(struct mbuf *, int);
int m_copy(struct mbuf *, struct mbuf *, int, int);
struct mbuf *dtom(Slirp *, void *);
+void *mtod_check(struct mbuf *, size_t len);
static inline void ifs_init(struct mbuf *ifm)
{
--
2.27.0

BIN
BinDir.tar.gz Normal file

Binary file not shown.

View File

@ -1,32 +0,0 @@
From 38734e26ce3840d459da13607a9d46de24a15388 Mon Sep 17 00:00:00 2001
From: kevinZhu <zhukeqian94@163.com>
Date: Thu, 29 Oct 2020 19:24:48 +0800
Subject: [PATCH] Bugfix: hw/acpi: Use max_cpus instead of cpus when build PPTT
table
The field "cpus" is the initial number of CPU for guest, and the field "max_cpus"
is the max number of CPU after CPU hotplug. When building PPTT for guest, we
should take all CPUs into account, otherwise the "smp_sockets" is wrong.
Fixes: 7cfcd8c8a2fe ("build smt processor structure to support smt topology")
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
hw/acpi/aml-build.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 8a3b51c835..f01669df57 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -167,7 +167,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, int possible_cpus)
struct offset_status offset;
const MachineState *ms = MACHINE(qdev_get_machine());
unsigned int smp_cores = ms->smp.cores;
- unsigned int smp_sockets = ms->smp.cpus / (smp_cores * ms->smp.threads);
+ unsigned int smp_sockets = ms->smp.max_cpus / (smp_cores * ms->smp.threads);
acpi_data_push(table_data, sizeof(AcpiTableHeader));
--
2.27.0

View File

@ -1,60 +0,0 @@
From 124032e79e354f5e7cc28958f2ca6b9f898da719 Mon Sep 17 00:00:00 2001
From: Fan Yang <Fan_Yang@sjtu.edu.cn>
Date: Tue, 24 Sep 2019 22:08:29 +0800
Subject: [PATCH] COLO-compare: Fix incorrect `if` logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
'colo_mark_tcp_pkt' should return 'true' when packets are the same, and
'false' otherwise. However, it returns 'true' when
'colo_compare_packet_payload' returns non-zero while
'colo_compare_packet_payload' is just a 'memcmp'. The result is that
COLO-compare reports inconsistent TCP packets when they are actually
the same.
Fixes: f449c9e549c ("colo: compare the packet based on the tcp sequence number")
Cc: qemu-stable@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Fan Yang <Fan_Yang@sjtu.edu.cn>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 1e907a32b77e5d418538453df5945242e43224fa)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
net/colo-compare.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/colo-compare.c b/net/colo-compare.c
index bf10526..9827c0e 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -287,7 +287,7 @@ static bool colo_mark_tcp_pkt(Packet *ppkt, Packet *spkt,
*mark = 0;
if (ppkt->tcp_seq == spkt->tcp_seq && ppkt->seq_end == spkt->seq_end) {
- if (colo_compare_packet_payload(ppkt, spkt,
+ if (!colo_compare_packet_payload(ppkt, spkt,
ppkt->header_size, spkt->header_size,
ppkt->payload_size)) {
*mark = COLO_COMPARE_FREE_SECONDARY | COLO_COMPARE_FREE_PRIMARY;
@@ -297,7 +297,7 @@ static bool colo_mark_tcp_pkt(Packet *ppkt, Packet *spkt,
/* one part of secondary packet payload still need to be compared */
if (!after(ppkt->seq_end, spkt->seq_end)) {
- if (colo_compare_packet_payload(ppkt, spkt,
+ if (!colo_compare_packet_payload(ppkt, spkt,
ppkt->header_size + ppkt->offset,
spkt->header_size + spkt->offset,
ppkt->payload_size - ppkt->offset)) {
@@ -316,7 +316,7 @@ static bool colo_mark_tcp_pkt(Packet *ppkt, Packet *spkt,
/* primary packet is longer than secondary packet, compare
* the same part and mark the primary packet offset
*/
- if (colo_compare_packet_payload(ppkt, spkt,
+ if (!colo_compare_packet_payload(ppkt, spkt,
ppkt->header_size + ppkt->offset,
spkt->header_size + spkt->offset,
spkt->payload_size - spkt->offset)) {
--
1.8.3.1

View File

@ -0,0 +1,27 @@
From 9e2158495059b485f2c28bb649c8b4a87fb3105c Mon Sep 17 00:00:00 2001
From: Chuan Zheng <zhengchuan@huawei.com>
Date: Wed, 9 Feb 2022 11:24:32 +0800
Subject: [PATCH 12/15] Currently, while kvm and qemu can not handle some kvm
exit, qemu will do vm_stop, which will make vm in pause state. This action
make vm unrecoverable, so send guest panic to libvirt instead.
---
accel/kvm/kvm-all.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index eecd8031cf..b128d311c2 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2970,7 +2970,7 @@ int kvm_cpu_exec(CPUState *cpu)
if (ret < 0) {
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
- vm_stop(RUN_STATE_INTERNAL_ERROR);
+ qemu_system_guest_panicked(cpu_get_crash_info(cpu));
}
qatomic_set(&cpu->exit_request, 0);
--
2.27.0

View File

@ -1,30 +0,0 @@
From e8b555c08061ad78920611a5e98ee14fcd967692 Mon Sep 17 00:00:00 2001
From: Ralf Haferkamp <rhafer@suse.com>
Date: Fri, 11 Sep 2020 10:55:49 +0800
Subject: [PATCH] Drop bogus IPv6 messages
Drop IPv6 message shorter than what's mentioned in the playload
length header (+the size of IPv6 header). They're invalid and could
lead to data leakage in icmp6_send_echoreply().
diff --git a/slirp/src/ip6_input.c b/slirp/src/ip6_input.c
index d9d2b7e..c2dce52 100644
--- a/slirp/src/ip6_input.c
+++ b/slirp/src/ip6_input.c
@@ -49,6 +49,13 @@ void ip6_input(struct mbuf *m)
goto bad;
}
+ // Check if the message size is big enough to hold what's
+ // set in the payload length header. If not this is an invalid
+ // packet
+ if (m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)) {
+ goto bad;
+ }
+
/* check ip_ttl for a correct ICMP reply */
if (ip6->ip_hl == 0) {
icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
--
1.8.3.1

View File

@ -1,39 +0,0 @@
From 126fc13ebe9c5e58a5b1daeb4e102e6fa5845779 Mon Sep 17 00:00:00 2001
From: Kirti Wankhede <kwankhede@nvidia.com>
Date: Fri, 6 Nov 2020 23:32:24 +0530
Subject: [PATCH] Fix use after free in vfio_migration_probe
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes Coverity issue:
CID 1436126: Memory - illegal accesses (USE_AFTER_FREE)
Fixes: a9e271ec9b36 ("vfio: Add migration region initialization and finalize function")
Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com>
Reviewed-by: David Edmondson <dme@dme.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
---
hw/vfio/migration.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 1a97784486..8546075706 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -903,8 +903,8 @@ int vfio_migration_probe(VFIODevice *vbasedev, Error **errp)
goto add_blocker;
}
- g_free(info);
trace_vfio_migration_probe(vbasedev->name, info->index);
+ g_free(info);
return 0;
add_blocker:
--
2.27.0

View File

@ -1,40 +0,0 @@
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,28 @@
From 039e70e84d966ee28267f3fe76c8558ef65619f9 Mon Sep 17 00:00:00 2001
From: Yan Wang <wangyan122@huawei.com>
Date: Sat, 12 Feb 2022 14:31:00 +0800
Subject: [PATCH] IPv6: add support for IPv6 protocol
Add support for IPv6 protocol.
Signed-off-by: Yan Wang <wangyan122@huawei.com>
---
roms/ipxe/src/config/general.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/roms/ipxe/src/config/general.h b/roms/ipxe/src/config/general.h
index 3c14a2c..e7ce2b9 100644
--- a/roms/ipxe/src/config/general.h
+++ b/roms/ipxe/src/config/general.h
@@ -35,7 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
#define NET_PROTO_IPV4 /* IPv4 protocol */
-#undef NET_PROTO_IPV6 /* IPv6 protocol */
+#define NET_PROTO_IPV6 /* IPv6 protocol */
#undef NET_PROTO_FCOE /* Fibre Channel over Ethernet protocol */
#define NET_PROTO_STP /* Spanning Tree protocol */
#define NET_PROTO_LACP /* Link Aggregation control protocol */
--
1.9.1

View File

@ -0,0 +1,49 @@
From 7474971c6fd6c6f77e66ded125e5f2521c7e12a2 Mon Sep 17 00:00:00 2001
From: Mingwang Li <limingwang@huawei.com>
Date: Wed, 9 Feb 2022 17:35:52 +0800
Subject: [PATCH 2/3] Revert "cpu: add Cortex-A72 processor kvm target support"
This reverts commit f0da7fa5230b5f771570b2c12288e4a56a20dd97.
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/arm/cpu64.c | 1 -
target/arm/kvm-consts.h | 3 ---
2 files changed, 4 deletions(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index bd8e5b5676..26419fe994 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -202,7 +202,6 @@ static void aarch64_a72_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,cortex-a72";
- cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8;
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
index 5f1311ade7..580f1c1fee 100644
--- a/target/arm/kvm-consts.h
+++ b/target/arm/kvm-consts.h
@@ -130,8 +130,6 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED);
#define QEMU_KVM_ARM_TARGET_CORTEX_A57 2
#define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3
#define QEMU_KVM_ARM_TARGET_CORTEX_A53 4
-/* Generic ARM v8 target */
-#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5
/* There's no kernel define for this: sentinel value which
* matches no KVM target value for either 64 or 32 bit
@@ -143,7 +141,6 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8);
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57);
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA);
MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53);
-MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8);
#define CP_REG_ARM64 0x6000000000000000ULL
#define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000
--
2.27.0

View File

@ -0,0 +1,67 @@
From cae52ca5b1dd4a295eaabc9649481f3d6a684f06 Mon Sep 17 00:00:00 2001
From: Mingwang Li <limingwang@huawei.com>
Date: Wed, 9 Feb 2022 17:33:26 +0800
Subject: [PATCH 1/3] Revert "cpu: parse +/- feature to avoid failure"
This reverts commit ef83cde8dd2c9b404527354489b14d2bd238733d.
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
target/arm/cpu64.c | 37 -------------------------------------
1 file changed, 37 deletions(-)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 08d886de7b..bd8e5b5676 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -983,47 +983,10 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs)
return g_strdup("aarch64");
}
-/* Parse "+feature,-feature,feature=foo" CPU feature string
- */
-static void arm_cpu_parse_featurestr(const char *typename, char *features,
- Error **errp )
-{
- char *featurestr;
- char *val;
- static bool cpu_globals_initialized;
-
- if (cpu_globals_initialized) {
- return;
- }
- cpu_globals_initialized = true;
-
- featurestr = features ? strtok(features, ",") : NULL;
- while (featurestr) {
- val = strchr(featurestr, '=');
- if (val) {
- GlobalProperty *prop = g_new0(typeof(*prop), 1);
- *val = 0;
- val++;
- prop->driver = typename;
- prop->property = g_strdup(featurestr);
- prop->value = g_strdup(val);
- qdev_prop_register_global(prop);
- } else if (featurestr[0] == '+' || featurestr[0] == '-') {
- warn_report("Ignore %s feature\n", featurestr);
- } else {
- error_setg(errp, "Expected key=value format, found %s.",
- featurestr);
- return;
- }
- featurestr = strtok(NULL, ",");
- }
-}
-
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
- cc->parse_features = arm_cpu_parse_featurestr;
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
cc->gdb_num_core_regs = 34;
--
2.27.0

View File

@ -1,88 +0,0 @@
From 73a5bf472921068e6db10e7e325b7ac46f111834 Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Mon, 29 Jul 2019 18:36:05 -0400
Subject: [PATCH] Revert "ide/ahci: Check for -ECANCELED in aio callbacks"
This reverts commit 0d910cfeaf2076b116b4517166d5deb0fea76394.
It's not correct to just ignore an error code in a callback; we need to
handle that error and possible report failure to the guest so that they
don't wait indefinitely for an operation that will now never finish.
This ought to help cases reported by Nutanix where iSCSI returns a
legitimate -ECANCELED for certain operations which should be propagated
normally.
Reported-by: Shaju Abraham <shaju.abraham@nutanix.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 20190729223605.7163-1-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 8ec41c4265714255d5a138f8b538faf3583dcff6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
hw/ide/ahci.c | 3 ---
hw/ide/core.c | 14 --------------
2 files changed, 17 deletions(-)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 00ba422a48..6aaf66534a 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1023,9 +1023,6 @@ static void ncq_cb(void *opaque, int ret)
IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
ncq_tfs->aiocb = NULL;
- if (ret == -ECANCELED) {
- return;
- }
if (ret < 0) {
bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 6afadf894f..8e1624f7ce 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -722,9 +722,6 @@ static void ide_sector_read_cb(void *opaque, int ret)
s->pio_aiocb = NULL;
s->status &= ~BUSY_STAT;
- if (ret == -ECANCELED) {
- return;
- }
if (ret != 0) {
if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO |
IDE_RETRY_READ)) {
@@ -840,10 +837,6 @@ static void ide_dma_cb(void *opaque, int ret)
uint64_t offset;
bool stay_active = false;
- if (ret == -ECANCELED) {
- return;
- }
-
if (ret == -EINVAL) {
ide_dma_error(s);
return;
@@ -975,10 +968,6 @@ static void ide_sector_write_cb(void *opaque, int ret)
IDEState *s = opaque;
int n;
- if (ret == -ECANCELED) {
- return;
- }
-
s->pio_aiocb = NULL;
s->status &= ~BUSY_STAT;
@@ -1058,9 +1047,6 @@ static void ide_flush_cb(void *opaque, int ret)
s->pio_aiocb = NULL;
- if (ret == -ECANCELED) {
- return;
- }
if (ret < 0) {
/* XXX: What sector number to set here? */
if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) {
--
2.23.0

View File

@ -0,0 +1,133 @@
From 92e9fb334c38cd21652ce8adde9ec01ab4412426 Mon Sep 17 00:00:00 2001
From: Jinhua Cao <caojinhua1@hauwei.com>
Date: Tue, 15 Feb 2022 15:18:17 +0800
Subject: [PATCH] Revert "qmp: add command to query used memslots of vhost-net
and vhost-user"
This reverts commit 1545a60a8b78490c7dc8909b7012bca63dba63cd.
Signed-off-by: Jinhua Cao <caojinhua1@huawei.com>
---
hw/virtio/vhost-backend.c | 2 +-
hw/virtio/vhost-user.c | 2 +-
include/hw/virtio/vhost-backend.h | 2 --
monitor/qmp-cmds.c | 12 ------------
qapi/net.json | 18 ------------------
qapi/pragma.json | 4 +---
6 files changed, 3 insertions(+), 37 deletions(-)
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index d8e1710758..2acfb750fd 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -300,7 +300,7 @@ static void vhost_kernel_set_used_memslots(struct vhost_dev *dev)
vhost_kernel_used_memslots = dev->mem->nregions;
}
-unsigned int vhost_kernel_get_used_memslots(void)
+static unsigned int vhost_kernel_get_used_memslots(void)
{
return vhost_kernel_used_memslots;
}
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 8f69a3b850..176cae9244 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -2544,7 +2544,7 @@ static void vhost_user_set_used_memslots(struct vhost_dev *dev)
vhost_user_used_memslots = counter;
}
-unsigned int vhost_user_get_used_memslots(void)
+static unsigned int vhost_user_get_used_memslots(void)
{
return vhost_user_used_memslots;
}
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 7bbc658161..a64708f456 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -190,6 +190,4 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd);
-unsigned int vhost_kernel_get_used_memslots(void);
-unsigned int vhost_user_get_used_memslots(void);
#endif /* VHOST_BACKEND_H */
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index a138e7dd4b..d71beace6a 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -37,7 +37,6 @@
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-ui.h"
-#include "qapi/qapi-commands-net.h"
#include "qapi/type-helpers.h"
#include "qapi/qmp/qerror.h"
#include "exec/ramlist.h"
@@ -45,7 +44,6 @@
#include "hw/acpi/acpi_dev_interface.h"
#include "hw/intc/intc.h"
#include "hw/rdma/rdma.h"
-#include "hw/virtio/vhost-backend.h"
NameInfo *qmp_query_name(Error **errp)
{
@@ -476,13 +474,3 @@ int64_t qmp_query_rtc_date_diff(Error **errp)
{
return get_rtc_date_diff();
}
-
-uint32_t qmp_query_vhost_kernel_used_memslots(Error **errp)
-{
- return vhost_kernel_get_used_memslots();
-}
-
-uint32_t qmp_query_vhost_user_used_memslots(Error **errp)
-{
- return vhost_user_get_used_memslots();
-}
diff --git a/qapi/net.json b/qapi/net.json
index c9ff849eed..7fab2e7cd8 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -696,21 +696,3 @@
##
{ 'event': 'FAILOVER_NEGOTIATED',
'data': {'device-id': 'str'} }
-
-##
-# @query-vhost-kernel-used-memslots:
-#
-# Get vhost-kernel nic used memslots
-#
-# Since: 4.1
-##
-{ 'command': 'query-vhost-kernel-used-memslots', 'returns': 'uint32' }
-
-##
-# @query-vhost-user-used-memslots:
-#
-# Get vhost-user nic used memslots
-#
-# Since: 4.1
-##
-{ 'command': 'query-vhost-user-used-memslots', 'returns': 'uint32' }
diff --git a/qapi/pragma.json b/qapi/pragma.json
index d35c897acb..b37f6de445 100644
--- a/qapi/pragma.json
+++ b/qapi/pragma.json
@@ -27,9 +27,7 @@
'query-tpm-models',
'query-tpm-types',
'ringbuf-read',
- 'query-rtc-date-diff',
- 'query-vhost-user-used-memslots',
- 'query-vhost-kernel-used-memslots' ],
+ 'query-rtc-date-diff' ],
# Externally visible types whose member names may use uppercase
'member-name-exceptions': [ # visible in:
'ACPISlotType', # query-acpi-ospm-status
--
2.27.0

View File

@ -1,37 +0,0 @@
From ced290d644a00e18e70046194d042bcaa2703b65 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Wed, 27 May 2020 11:16:53 +0800
Subject: [PATCH] Revert: "vtimer: compat cross version migration from v4.0.1"
This reverts commit patch:
vtimer-compat-cross-version-migration-from-v4.0.1.patch
Signed-off-by: Ying Fang <fangying1@huawei.com>
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 2609113d..86eb79cd 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -261,7 +261,6 @@ typedef struct CPUARMState {
uint64_t elr_el[4]; /* AArch64 exception link regs */
uint64_t sp_el[4]; /* AArch64 banked stack pointers */
- uint64_t vtimer; /* Timer tick when vcpu is stopped */
/* System control coprocessor (cp15) */
struct {
diff --git a/target/arm/machine.c b/target/arm/machine.c
index ec28b839..ee3c59a6 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -814,7 +814,6 @@ const VMStateDescription vmstate_arm_cpu = {
VMSTATE_UINT32(env.exception.syndrome, ARMCPU),
VMSTATE_UINT32(env.exception.fsr, ARMCPU),
VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
- VMSTATE_UINT64(env.vtimer, ARMCPU),
VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU),
VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU),
{
--
2.23.0

View File

@ -1,27 +0,0 @@
From 843f593280b93e03bb7b0d0001da7488d61f13f6 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Mon, 6 Apr 2020 08:55:17 +0800
Subject: [PATCH] Typo: Correct the name of CPU hotplug memory region
Replace "acpi-mem-hotplug" with "acpi-cpu-hotplug"
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
hw/acpi/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 7a90c8f82d..0c0bfe479a 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -203,7 +203,7 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
state->devs[i].arch_id = id_list->cpus[i].arch_id;
}
memory_region_init_io(&state->ctrl_reg, owner, &cpu_hotplug_ops, state,
- "acpi-mem-hotplug", ACPI_CPU_HOTPLUG_REG_LEN);
+ "acpi-cpu-hotplug", ACPI_CPU_HOTPLUG_REG_LEN);
memory_region_add_subregion(as, base_addr, &state->ctrl_reg);
}
--
2.19.1

View File

@ -0,0 +1,250 @@
From 97021cac0565f57d14a3e285399dd2208c66c358 Mon Sep 17 00:00:00 2001
From: Yan Wang <wangyan122@huawei.com>
Date: Sat, 12 Feb 2022 15:00:25 +0800
Subject: [PATCH] Use post-increment only in inffast.c.
Fix CVE-2016-9841
patch link: https://github.com/madler/zlib/commit/9aaec95
An old inffast.c optimization turns out to not be optimal anymore
with modern compilers, and furthermore was not compliant with the
C standard, for which decrementing a pointer before its allocated
memory is undefined. Per the recommendation of a security audit of
the zlib code by Trail of Bits and TrustInSoft, in support of the
Mozilla Foundation, this "optimization" was removed, in order to
avoid the possibility of undefined behavior.
Signed-off-by: Yan Wang <wangyan122@huawei.com>
---
roms/u-boot/lib/zlib/inffast.c | 87 +++++++++++++++++-------------------------
1 file changed, 34 insertions(+), 53 deletions(-)
diff --git a/roms/u-boot/lib/zlib/inffast.c b/roms/u-boot/lib/zlib/inffast.c
index e3c7f3b..cdc778e 100644
--- a/roms/u-boot/lib/zlib/inffast.c
+++ b/roms/u-boot/lib/zlib/inffast.c
@@ -12,25 +12,6 @@
#ifndef ASMINF
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
@@ -97,7 +78,7 @@ void inflate_fast(z_streamp strm, unsigned start)
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
+ in = strm->next_in;
last = in + (strm->avail_in - 5);
if (in > last && strm->avail_in > 5) {
/*
@@ -107,7 +88,7 @@ void inflate_fast(z_streamp strm, unsigned start)
strm->avail_in = 0xffffffff - (uintptr_t)in;
last = in + (strm->avail_in - 5);
}
- out = strm->next_out - OFF;
+ out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
@@ -128,9 +109,9 @@ void inflate_fast(z_streamp strm, unsigned start)
input data or output space */
do {
if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
this = lcode[hold & lmask];
@@ -143,14 +124,14 @@ void inflate_fast(z_streamp strm, unsigned start)
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
+ *out++ = (unsigned char)(this.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
@@ -159,9 +140,9 @@ void inflate_fast(z_streamp strm, unsigned start)
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
this = dcode[hold & dmask];
@@ -174,10 +155,10 @@ void inflate_fast(z_streamp strm, unsigned start)
dist = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
}
@@ -200,13 +181,13 @@ void inflate_fast(z_streamp strm, unsigned start)
state->mode = BAD;
break;
}
- from = window - OFF;
+ from = window;
if (write == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
@@ -217,14 +198,14 @@ void inflate_fast(z_streamp strm, unsigned start)
if (op < len) { /* some from end of window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
- from = window - OFF;
+ from = window;
if (write < len) { /* some from start of window */
op = write;
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
@@ -235,21 +216,21 @@ void inflate_fast(z_streamp strm, unsigned start)
if (op < len) { /* some from window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
len -= 3;
}
if (len) {
- PUP(out) = PUP(from);
+ *out++ = *from++;
if (len > 1)
- PUP(out) = PUP(from);
+ *out++ = *from++;
}
}
else {
@@ -259,25 +240,25 @@ void inflate_fast(z_streamp strm, unsigned start)
from = out - dist; /* copy direct from output */
/* minimum length is three */
/* Align out addr */
- if (!((long)(out - 1 + OFF) & 1)) {
- PUP(out) = PUP(from);
+ if (!((long)(out - 1) & 1)) {
+ *out++ = *from++;
len--;
}
- sout = (unsigned short *)(out - OFF);
+ sout = (unsigned short *)(out);
if (dist > 2 ) {
unsigned short *sfrom;
- sfrom = (unsigned short *)(from - OFF);
+ sfrom = (unsigned short *)(from);
loops = len >> 1;
do
- PUP(sout) = get_unaligned(++sfrom);
+ *sout++ = get_unaligned(++sfrom);
while (--loops);
- out = (unsigned char *)sout + OFF;
- from = (unsigned char *)sfrom + OFF;
+ out = (unsigned char *)sout;
+ from = (unsigned char *)sfrom;
} else { /* dist == 1 or dist == 2 */
unsigned short pat16;
- pat16 = *(sout-2+2*OFF);
+ pat16 = *(sout-2);
if (dist == 1)
#if defined(__BIG_ENDIAN)
pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
@@ -288,12 +269,12 @@ void inflate_fast(z_streamp strm, unsigned start)
#endif
loops = len >> 1;
do
- PUP(sout) = pat16;
+ *sout++ = pat16;
while (--loops);
- out = (unsigned char *)sout + OFF;
+ out = (unsigned char *)sout;
}
if (len & 1)
- PUP(out) = PUP(from);
+ *out++ = *from++;
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
@@ -329,8 +310,8 @@ void inflate_fast(z_streamp strm, unsigned start)
hold &= (1U << bits) - 1;
/* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
+ strm->next_in = in;
+ strm->next_out = out;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
--
1.9.1

View File

@ -1,4 +1,4 @@
From 135119d2e82e99adc67346572c761fbe54d73e4a Mon Sep 17 00:00:00 2001
From c950cda47386360e37a89dfa7029d83e33888a40 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 13:04:40 +0800
Subject: [PATCH] accel/kvm: Add pre-park vCPU support
@ -14,11 +14,11 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
2 files changed, 24 insertions(+)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f450f25295..84edbe8bb1 100644
index 8a98446b7c..f2ce5cd45a 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -339,6 +339,29 @@ err:
return ret;
@@ -433,6 +433,29 @@ void kvm_destroy_vcpu(CPUState *cpu)
}
}
+int kvm_create_parked_vcpu(unsigned long vcpu_id)
@ -48,16 +48,17 @@ index f450f25295..84edbe8bb1 100644
{
struct KVMParkedVcpu *cpu;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index acd90aebb6..565adb4e2c 100644
index 7b22aeb6ae..2623775c27 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -216,6 +216,7 @@ int kvm_has_many_ioeventfds(void);
@@ -221,6 +221,7 @@ int kvm_has_pit_state2(void);
int kvm_has_many_ioeventfds(void);
int kvm_has_gsi_routing(void);
int kvm_has_intx_set_mask(void);
+int kvm_create_parked_vcpu(unsigned long vcpu_id);
int kvm_init_vcpu(CPUState *cpu);
int kvm_cpu_exec(CPUState *cpu);
int kvm_destroy_vcpu(CPUState *cpu);
/**
* kvm_arm_supports_user_irq
--
2.19.1
2.27.0

View File

@ -1,45 +0,0 @@
From b50b9a0e2e5e8262c830df5994f3abbe0a37655a Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Thu, 17 Dec 2020 09:49:40 +0800
Subject: [PATCH] accel: kvm: Fix memory waste under mismatch page size
When handle dirty log, we face qemu_real_host_page_size and
TARGET_PAGE_SIZE. The first one is the granule of KVM dirty
bitmap, and the second one is the granule of QEMU dirty bitmap.
As qemu_real_host_page_size >= TARGET_PAGE_SIZE (kvm_init()
enforced it), misuse TARGET_PAGE_SIZE to init kvmslot dirty_bmap
may waste memory. For example, when qemu_real_host_page_size is
64K and TARGET_PAGE_SIZE is 4K, it wastes 93.75% (15/16) memory.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Message-Id: <20201217014941.22872-2-zhukeqian1@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
---
accel/kvm/kvm-all.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 5a6b89cc2a..4daff563a0 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -551,8 +551,12 @@ static void kvm_memslot_init_dirty_bitmap(KVMSlot *mem)
* too, in most cases).
* So for now, let's align to 64 instead of HOST_LONG_BITS here, in
* a hope that sizeof(long) won't become >8 any time soon.
+ *
+ * Note: the granule of kvm dirty log is qemu_real_host_page_size.
+ * And mem->memory_size is aligned to it (otherwise this mem can't
+ * be registered to KVM).
*/
- hwaddr bitmap_size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
+ hwaddr bitmap_size = ALIGN(mem->memory_size / qemu_real_host_page_size,
/*HOST_LONG_BITS*/ 64) / 8;
mem->dirty_bmap = g_malloc0(bitmap_size);
}
--
2.27.0

View File

@ -1,4 +1,4 @@
From 107c267ebe5b8c461268a4ff8384ad2f2b9e8ce0 Mon Sep 17 00:00:00 2001
From 1ab75151c0a486ebdbe50d29c9677c7bc1f05929 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Wed, 22 Apr 2020 16:11:13 +0800
Subject: [PATCH] acpi/cpu: Prepare build_cpus_aml for arm virt
@ -17,16 +17,16 @@ Besides, CPU CPPC building is injected.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/acpi/cpu.c | 32 +++++++++++++++++++++++++-------
hw/acpi/cpu.c | 27 ++++++++++++++++++++-------
hw/i386/acpi-build.c | 2 +-
include/hw/acpi/cpu.h | 3 ++-
3 files changed, 28 insertions(+), 9 deletions(-)
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 0c0bfe479a..72ad1fcff2 100644
index b20903ea30..a9c2ee952a 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -314,7 +314,8 @@ const VMStateDescription vmstate_cpu_hotplug = {
@@ -343,7 +343,8 @@ const VMStateDescription vmstate_cpu_hotplug = {
void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
hwaddr io_base,
const char *res_root,
@ -36,7 +36,7 @@ index 0c0bfe479a..72ad1fcff2 100644
{
Aml *ifctx;
Aml *field;
@@ -342,13 +343,18 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
@@ -371,13 +372,18 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
crs = aml_resource_template();
@ -58,7 +58,7 @@ index 0c0bfe479a..72ad1fcff2 100644
ACPI_CPU_HOTPLUG_REG_LEN));
field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
@@ -517,6 +523,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
@@ -663,6 +669,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
aml_append(dev, aml_name_decl("_UID", uid));
}
@ -70,19 +70,7 @@ index 0c0bfe479a..72ad1fcff2 100644
method = aml_method("_STA", 0, AML_SERIALIZED);
aml_append(method, aml_return(aml_call1(CPU_STS_METHOD, uid)));
aml_append(dev, method);
@@ -535,6 +546,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
apic->flags = cpu_to_le32(1);
break;
}
+ case ACPI_APIC_GENERIC_CPU_INTERFACE: {
+ AcpiMadtGenericCpuInterface *gicc = (void *)madt_buf->data;
+ gicc->flags = cpu_to_le32(1);
+ break;
+ }
default:
assert(0);
}
@@ -570,9 +586,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
@@ -703,9 +714,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
aml_append(sb_scope, cpus_dev);
aml_append(table, sb_scope);
@ -98,11 +86,11 @@ index 0c0bfe479a..72ad1fcff2 100644
g_free(cphp_res_path);
}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 749218561a..c97731ecb3 100644
index a99c6e4fe3..1ce2d67c2e 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1869,7 +1869,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
.acpi_1_compatible = true, .has_legacy_cphp = true
@@ -1513,7 +1513,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
.fw_unplugs_cpu = pm->smi_on_cpu_unplug,
};
build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
- "\\_SB.PCI0", "\\_GPE._E02");
@ -111,10 +99,10 @@ index 749218561a..c97731ecb3 100644
if (pcms->memhp_io_base && nr_mem) {
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index 62f0278ba2..a30ec84a4f 100644
index 999caaf510..a0fdc44bdd 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -55,7 +55,8 @@ typedef struct CPUHotplugFeatures {
@@ -58,7 +58,8 @@ typedef struct CPUHotplugFeatures {
void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
hwaddr io_base,
const char *res_root,
@ -125,4 +113,5 @@ index 62f0278ba2..a30ec84a4f 100644
void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
--
2.19.1
2.27.0

View File

@ -1,41 +0,0 @@
From 3cd6df0b9e7d7b544673ce9a63b405e236d8265b Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 10:05:54 +0800
Subject: [PATCH] acpi/ged: Add virt_madt_cpu_entry to madt_cpu hook
In build_cpus_aml, we will invoke this hook to build _MAT
aml mehtod for cpus.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/acpi/generic_event_device.c | 1 +
include/hw/acpi/generic_event_device.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 9cee90cc70..b834ae3ff6 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -288,6 +288,7 @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
hc->plug = acpi_ged_device_plug_cb;
adevc->send_event = acpi_ged_send_event;
+ adevc->madt_cpu = virt_madt_cpu_entry;
}
static const TypeInfo acpi_ged_info = {
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index d157eac088..f99efad7a3 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -61,6 +61,7 @@
#include "hw/sysbus.h"
#include "hw/acpi/memory_hotplug.h"
+#include "hw/arm/virt.h"
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
--
2.19.1

View File

@ -1,4 +1,4 @@
From 05d22b55133db1a2526cfe305102e075e883b5e2 Mon Sep 17 00:00:00 2001
From 603cbcc5efdd35f518a5bd0a5067d40c2c4eb8d6 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 3 Apr 2020 15:41:01 +0800
Subject: [PATCH] acpi/ged: Extend ACPI GED to support CPU hotplug
@ -26,21 +26,21 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
6 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
index 911a98255b..deb481555d 100644
index 0bd3f9399f..3acd6fcd8b 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -63,7 +63,8 @@ GED IO interface (4 byte access)
bits:
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
0: Memory hotplug event
1: System power down event
- 2-31: Reserved
+ 2: CPU hotplug event
+ 3-31: Reserved
2: NVDIMM hotplug event
- 3-31: Reserved
+ 3: CPU hotplug event
+ 4-31: Reserved
**write_access:**
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 72ad1fcff2..cb6bb67f3c 100644
index a9c2ee952a..f9ce0a7f41 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -6,7 +6,6 @@
@ -52,19 +52,19 @@ index 72ad1fcff2..cb6bb67f3c 100644
#define ACPI_CPU_FLAGS_OFFSET_RW 4
#define ACPI_CPU_CMD_OFFSET_WR 5
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 82139b4314..478a4ee87c 100644
index e28457a7d1..042a8ef8a5 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -23,6 +23,7 @@
static const uint32_t ged_supported_events[] = {
@@ -25,6 +25,7 @@ static const uint32_t ged_supported_events[] = {
ACPI_GED_MEM_HOTPLUG_EVT,
ACPI_GED_PWR_DOWN_EVT,
ACPI_GED_NVDIMM_HOTPLUG_EVT,
+ ACPI_GED_CPU_HOTPLUG_EVT,
};
/*
@@ -110,6 +111,9 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
@@ -117,6 +118,9 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
aml_notify(aml_name("\\_SB.NVDR"),
aml_int(0x80)));
break;
+ case ACPI_GED_CPU_HOTPLUG_EVT:
@ -73,25 +73,25 @@ index 82139b4314..478a4ee87c 100644
default:
/*
* Please make sure all the events in ged_supported_events[]
@@ -176,6 +180,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
@@ -234,6 +238,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
} else {
acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
}
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+ acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
} else {
error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -192,6 +198,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
sel = ACPI_GED_MEM_HOTPLUG_EVT;
} else if (ev & ACPI_POWER_DOWN_STATUS) {
@@ -279,6 +285,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
sel = ACPI_GED_PWR_DOWN_EVT;
} else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
+ } else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
+ sel = ACPI_GED_CPU_HOTPLUG_EVT;
} else {
/* Unknown event. Return without generating interrupt. */
warn_report("GED: Unsupported event %d. No irq injected", ev);
@@ -224,6 +232,16 @@ static const VMStateDescription vmstate_memhp_state = {
@@ -311,6 +319,16 @@ static const VMStateDescription vmstate_memhp_state = {
}
};
@ -108,26 +108,26 @@ index 82139b4314..478a4ee87c 100644
static const VMStateDescription vmstate_ged_state = {
.name = "acpi-ged-state",
.version_id = 1,
@@ -244,6 +262,7 @@ static const VMStateDescription vmstate_acpi_ged = {
},
@@ -360,6 +378,7 @@ static const VMStateDescription vmstate_acpi_ged = {
.subsections = (const VMStateDescription * []) {
&vmstate_memhp_state,
&vmstate_ghes_state,
+ &vmstate_cpuhp_state,
NULL
}
};
@@ -254,6 +273,7 @@ static void acpi_ged_initfn(Object *obj)
@@ -370,6 +389,7 @@ static void acpi_ged_initfn(Object *obj)
AcpiGedState *s = ACPI_GED(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
GEDState *ged_st = &s->ged_state;
+ MachineClass *mc;
memory_region_init_io(&ged_st->io, obj, &ged_ops, ged_st,
memory_region_init_io(&ged_st->evt, obj, &ged_evt_ops, ged_st,
TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN);
@@ -273,6 +293,21 @@ static void acpi_ged_initfn(Object *obj)
sysbus_init_mmio(sbd, &s->container_memhp);
acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev),
&s->memhp_state, 0);
@@ -393,6 +413,21 @@ static void acpi_ged_initfn(Object *obj)
memory_region_init_io(&ged_st->regs, obj, &ged_regs_ops, ged_st,
TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT);
sysbus_init_mmio(sbd, &ged_st->regs);
+
+ mc = MACHINE_GET_CLASS(qdev_get_machine());
+ if (!mc->possible_cpu_arch_ids) {
@ -147,19 +147,19 @@ index 82139b4314..478a4ee87c 100644
static void acpi_ged_class_init(ObjectClass *class, void *data)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index ad7f7c089b..15e18b0a48 100644
index 2d37d29f02..006a4b4c4b 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -24,6 +24,7 @@ config ARM_VIRT
@@ -27,6 +27,7 @@ config ARM_VIRT
select DIMM
select ACPI_MEMORY_HOTPLUG
select ACPI_HW_REDUCED
select ACPI_APEI
+ select ACPI_CPU_HOTPLUG
config CHEETAH
bool
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index a30ec84a4f..e726414459 100644
index a0fdc44bdd..d521025830 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -17,6 +17,8 @@
@ -172,26 +172,26 @@ index a30ec84a4f..e726414459 100644
struct CPUState *cpu;
uint64_t arch_id;
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index f99efad7a3..e702ff1e18 100644
index d49217c445..6bb2ade385 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -62,6 +62,7 @@
#include "hw/sysbus.h"
@@ -63,6 +63,7 @@
#include "hw/acpi/memory_hotplug.h"
#include "hw/arm/virt.h"
#include "hw/acpi/ghes.h"
#include "qom/object.h"
+#include "hw/acpi/cpu.h"
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -83,6 +84,7 @@
*/
@@ -97,6 +98,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
#define ACPI_GED_PWR_DOWN_EVT 0x2
+#define ACPI_GED_CPU_HOTPLUG_EVT 0x4
#define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
+#define ACPI_GED_CPU_HOTPLUG_EVT 0x8
typedef struct GEDState {
MemoryRegion io;
@@ -93,6 +95,8 @@ typedef struct AcpiGedState {
MemoryRegion evt;
@@ -108,6 +110,8 @@ struct AcpiGedState {
SysBusDevice parent_obj;
MemHotplugState memhp_state;
MemoryRegion container_memhp;
@ -201,4 +201,5 @@ index f99efad7a3..e702ff1e18 100644
uint32_t ged_event_bitmap;
qemu_irq irq;
--
2.19.1
2.27.0

View File

@ -1,4 +1,4 @@
From 0288d98f0ef4d17a73cf2bad1b928cd7c044e318 Mon Sep 17 00:00:00 2001
From 8bd05cdb811e868c54ef28ac558c7efb7cf610b9 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 13:40:44 +0800
Subject: [PATCH] acpi/madt: Add pre-sizing capability to MADT GICC struct
@ -9,87 +9,76 @@ of MADT GICC struct, so we should pre-sizing MADT GICC too.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt-acpi-build.c | 26 +++++++++++++++++++++-----
include/hw/acpi/acpi-defs.h | 1 +
2 files changed, 22 insertions(+), 5 deletions(-)
hw/arm/virt-acpi-build.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index dbe9acb148..efac788ba1 100644
index 7cb320d9f2..a16b54086e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -678,6 +678,13 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
const MemMapEntry *memmap = vms->memmap;
AcpiMadtGenericCpuInterface *gicc = acpi_data_push(entry, sizeof(*gicc));
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(uid));
@@ -787,8 +787,16 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i,
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
uint64_t physical_base_address = 0, gich = 0, gicv = 0;
uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0;
- uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ?
- PPI(VIRTUAL_PMU_IRQ) : 0;
+ uint32_t pmu_interrupt, enabled;
+ static bool pmu;
+
+ if (uid == 0) {
+ if (i == 0) {
+ pmu = arm_feature(&armcpu->env, ARM_FEATURE_PMU);
+ }
+ /* FEATURE_PMU should be all enabled or disabled for CPUs */
+ assert(!armcpu || arm_feature(&armcpu->env, ARM_FEATURE_PMU) == pmu);
+ pmu_interrupt = pmu ? PPI(VIRTUAL_PMU_IRQ) : 0;
+ enabled = armcpu || force_enabled ? 1 /* Enabled */ : 0 /* Disabled */;
gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
gicc->length = sizeof(*gicc);
@@ -687,11 +694,15 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
gicc->gicv_base_address = cpu_to_le64(memmap[VIRT_GIC_VCPU].base);
if (vms->gic_version == 2) {
physical_base_address = memmap[VIRT_GIC_CPU].base;
@@ -803,7 +811,7 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i,
build_append_int_noprefix(table_data, i, 4); /* GIC ID */
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */
/* Flags */
- build_append_int_noprefix(table_data, 1, 4); /* Enabled */
+ build_append_int_noprefix(table_data, enabled, 4); /* Enabled */
/* Parking Protocol Version */
build_append_int_noprefix(table_data, 0, 4);
/* Performance Interrupt GSIV */
@@ -817,7 +825,7 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i,
build_append_int_noprefix(table_data, vgic_interrupt, 4);
build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/
/* MPIDR */
- build_append_int_noprefix(table_data, armcpu->mp_affinity, 8);
+ build_append_int_noprefix(table_data, possible_cpus->cpus[i].arch_id, 8);
}
gicc->cpu_interface_number = cpu_to_le32(uid);
- gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
+ gicc->arm_mpidr = possible_cpus->cpus[uid].arch_id;
gicc->uid = cpu_to_le32(uid);
- gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
+ if (armcpu) {
+ gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
+ } else {
+ gicc->flags = cpu_to_le32(ACPI_MADT_GICC_DISABLED);
+ }
- if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
+ if (pmu) {
gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
}
if (vms->virt) {
@@ -704,12 +715,17 @@ static void
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
static void
@@ -825,9 +833,14 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
int i;
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
+ MachineState *ms = MACHINE(vms);
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
int madt_start = table_data->len;
const MemMapEntry *memmap = vms->memmap;
const int *irqmap = vms->irqmap;
AcpiMultipleApicTable *madt;
AcpiMadtGenericDistributor *gicd;
AcpiMadtGenericMsiFrame *gic_msi;
AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = vms->oem_id,
.oem_table_id = vms->oem_table_id };
+ /* The MADT GICC numbers */
+ int num_cpu = vms->smp_cpus;
int i;
+ int num_cpu = ms->smp.cpus;
madt = acpi_data_push(table_data, sizeof *madt);
@@ -720,8 +736,8 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
gicd->version = vms->gic_version;
acpi_table_begin(&table, table_data);
/* Local Interrupt Controller Address */
@@ -846,8 +859,8 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, vms->gic_version, 1);
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
- for (i = 0; i < vms->smp_cpus; i++) {
- virt_madt_cpu_entry(NULL, i, NULL, table_data);
- for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
- virt_madt_cpu_entry(NULL, i, NULL, table_data, false);
+ for (i = 0; i < num_cpu; i++) {
+ virt_madt_cpu_entry(NULL, i, possible_cpus, table_data);
+ virt_madt_cpu_entry(NULL, i, possible_cpus, table_data, false);
}
if (vms->gic_version == 3) {
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 39ae91d3b8..6bfa7f9152 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -306,6 +306,7 @@ typedef struct AcpiMadtGenericCpuInterface AcpiMadtGenericCpuInterface;
/* GICC CPU Interface Flags */
#define ACPI_MADT_GICC_ENABLED 1
+#define ACPI_MADT_GICC_DISABLED 0
struct AcpiMadtGenericDistributor {
ACPI_SUB_HEADER_DEF
--
2.19.1
2.27.0

View File

@ -1,4 +1,4 @@
From a3097eed8b642dc6fe891112340821e869b90cc2 Mon Sep 17 00:00:00 2001
From 4f50ed900713acc14c971c07165fa83670d3f2b8 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Mon, 13 Jan 2020 19:02:20 +0800
Subject: [PATCH] acpi/madt: Factor out the building of MADT GICC struct
@ -10,99 +10,127 @@ out the GICC building code from ACPI MADT and reuse it in build_cpus_aml.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt-acpi-build.c | 51 +++++++++++++++++++++++-----------------
include/hw/arm/virt.h | 3 +++
2 files changed, 32 insertions(+), 22 deletions(-)
hw/arm/virt-acpi-build.c | 77 ++++++++++++++++++++++------------------
include/hw/arm/virt.h | 4 +++
2 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index f48733d9f2..4b6aace433 100644
index 1ca705654b..64b1ed8672 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -664,6 +664,34 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
table_data->len - gtdt_start, 2, NULL, NULL);
@@ -771,6 +771,48 @@ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size)
build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */
}
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
+ const CPUArchIdList *possible_cpus, GArray *entry)
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i,
+ const CPUArchIdList *possible_cpus, GArray *table_data,
+ bool force_enabled)
+{
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
+ const MemMapEntry *memmap = vms->memmap;
+ AcpiMadtGenericCpuInterface *gicc = acpi_data_push(entry, sizeof(*gicc));
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(uid));
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
+ uint64_t physical_base_address = 0, gich = 0, gicv = 0;
+ uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0;
+ uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ?
+ PPI(VIRTUAL_PMU_IRQ) : 0;
+
+ gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
+ gicc->length = sizeof(*gicc);
+ if (vms->gic_version == 2) {
+ gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
+ gicc->gich_base_address = cpu_to_le64(memmap[VIRT_GIC_HYP].base);
+ gicc->gicv_base_address = cpu_to_le64(memmap[VIRT_GIC_VCPU].base);
+ physical_base_address = memmap[VIRT_GIC_CPU].base;
+ gicv = memmap[VIRT_GIC_VCPU].base;
+ gich = memmap[VIRT_GIC_HYP].base;
+ }
+ gicc->cpu_interface_number = cpu_to_le32(uid);
+ gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
+ gicc->uid = cpu_to_le32(uid);
+ gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
+
+ if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
+ gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
+ }
+ if (vms->virt) {
+ gicc->vgic_interrupt = cpu_to_le32(PPI(ARCH_GIC_MAINT_IRQ));
+ }
+ /* 5.2.12.14 GIC Structure */
+ build_append_int_noprefix(table_data, 0xB, 1); /* Type */
+ build_append_int_noprefix(table_data, 76, 1); /* Length */
+ build_append_int_noprefix(table_data, 0, 2); /* Reserved */
+ build_append_int_noprefix(table_data, i, 4); /* GIC ID */
+ build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */
+ /* Flags */
+ build_append_int_noprefix(table_data, 1, 4); /* Enabled */
+ /* Parking Protocol Version */
+ build_append_int_noprefix(table_data, 0, 4);
+ /* Performance Interrupt GSIV */
+ build_append_int_noprefix(table_data, pmu_interrupt, 4);
+ build_append_int_noprefix(table_data, 0, 8); /* Parked Address */
+ /* Physical Base Address */
+ build_append_int_noprefix(table_data, physical_base_address, 8);
+ build_append_int_noprefix(table_data, gicv, 8); /* GICV */
+ build_append_int_noprefix(table_data, gich, 8); /* GICH */
+ /* VGIC Maintenance interrupt */
+ build_append_int_noprefix(table_data, vgic_interrupt, 4);
+ build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/
+ /* MPIDR */
+ build_append_int_noprefix(table_data, armcpu->mp_affinity, 8);
+}
+
/* MADT */
static void
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -686,28 +714,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
gicd->version = vms->gic_version;
{
@@ -798,40 +840,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
for (i = 0; i < vms->smp_cpus; i++) {
- AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
- sizeof(*gicc));
for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
- uint64_t physical_base_address = 0, gich = 0, gicv = 0;
- uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0;
- uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ?
- PPI(VIRTUAL_PMU_IRQ) : 0;
-
- gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
- gicc->length = sizeof(*gicc);
- if (vms->gic_version == 2) {
- gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
- gicc->gich_base_address = cpu_to_le64(memmap[VIRT_GIC_HYP].base);
- gicc->gicv_base_address = cpu_to_le64(memmap[VIRT_GIC_VCPU].base);
- physical_base_address = memmap[VIRT_GIC_CPU].base;
- gicv = memmap[VIRT_GIC_VCPU].base;
- gich = memmap[VIRT_GIC_HYP].base;
- }
- gicc->cpu_interface_number = cpu_to_le32(i);
- gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
- gicc->uid = cpu_to_le32(i);
- gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
-
- if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
- gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
- }
- if (vms->virt) {
- gicc->vgic_interrupt = cpu_to_le32(PPI(ARCH_GIC_MAINT_IRQ));
- }
+ virt_madt_cpu_entry(NULL, i, NULL, table_data);
- /* 5.2.12.14 GIC Structure */
- build_append_int_noprefix(table_data, 0xB, 1); /* Type */
- build_append_int_noprefix(table_data, 76, 1); /* Length */
- build_append_int_noprefix(table_data, 0, 2); /* Reserved */
- build_append_int_noprefix(table_data, i, 4); /* GIC ID */
- build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */
- /* Flags */
- build_append_int_noprefix(table_data, 1, 4); /* Enabled */
- /* Parking Protocol Version */
- build_append_int_noprefix(table_data, 0, 4);
- /* Performance Interrupt GSIV */
- build_append_int_noprefix(table_data, pmu_interrupt, 4);
- build_append_int_noprefix(table_data, 0, 8); /* Parked Address */
- /* Physical Base Address */
- build_append_int_noprefix(table_data, physical_base_address, 8);
- build_append_int_noprefix(table_data, gicv, 8); /* GICV */
- build_append_int_noprefix(table_data, gich, 8); /* GICH */
- /* VGIC Maintenance interrupt */
- build_append_int_noprefix(table_data, vgic_interrupt, 4);
- build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/
- /* MPIDR */
- build_append_int_noprefix(table_data, armcpu->mp_affinity, 8);
+ virt_madt_cpu_entry(NULL, i, NULL, table_data, false);
}
if (vms->gic_version == 3) {
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 3dfefca93b..6b1f10b231 100644
index a4356cf736..36639e8d3e 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -37,6 +37,7 @@
#include "hw/block/flash.h"
@@ -38,6 +38,7 @@
#include "sysemu/kvm.h"
#include "hw/intc/arm_gicv3_common.h"
#include "qom/object.h"
+#include "hw/acpi/acpi_dev_interface.h"
#define NUM_GICV2M_SPIS 64
#define NUM_VIRTIO_TRANSPORTS 32
@@ -154,6 +155,8 @@ typedef struct {
OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
@@ -181,6 +182,9 @@ OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
void virt_acpi_setup(VirtMachineState *vms);
bool virt_is_acpi_enabled(VirtMachineState *vms);
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
+ const CPUArchIdList *cpu_list, GArray *entry);
+ const CPUArchIdList *cpu_list, GArray *entry,
+ bool force_enabled);
/* Return the number of used redistributor regions */
static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
--
2.19.1
2.27.0

View File

@ -1,34 +1,35 @@
From ea7a395de920cfecd9bf99f0cf55914d47718edf Mon Sep 17 00:00:00 2001
From ec35c96006851a956a7e401f29af0ffe137c4bb9 Mon Sep 17 00:00:00 2001
From: Jiadong Zeng <zengjiadong@phytium.com.cn>
Date: Thu, 11 Nov 2021 14:25:38 +0800
Date: Tue, 8 Feb 2022 22:56:37 +0800
Subject: [PATCH] add Phytium's CPU models: FT-2000+ and Tengyun-S2500.
Signed-off-by: Jiadong Zeng <zengjiadong@phytium.com.cn>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
---
hw/arm/virt.c | 2 ++
target/arm/cpu64.c | 28 ++++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7506d0ff32..0e46260116 100644
index a4a35584e9..3c972fdab0 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -195,6 +195,8 @@ static const char *valid_cpus[] = {
@@ -202,6 +202,8 @@ static const char *valid_cpus[] = {
ARM_CPU_TYPE_NAME("cortex-a57"),
ARM_CPU_TYPE_NAME("cortex-a72"),
ARM_CPU_TYPE_NAME("Kunpeng-920"),
+ ARM_CPU_TYPE_NAME("FT-2000+"),
+ ARM_CPU_TYPE_NAME("Tengyun-S2500"),
ARM_CPU_TYPE_NAME("a64fx"),
ARM_CPU_TYPE_NAME("host"),
ARM_CPU_TYPE_NAME("max"),
};
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a1649f8844..4cf5b89db0 100644
index 556b6f3691..08d886de7b 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -327,6 +327,32 @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
error_propagate(errp, err);
}
@@ -676,6 +676,32 @@ static Property arm_cpu_pauth_property =
static Property arm_cpu_pauth_impdef_property =
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
+static void aarch64_max_ft2000plus_initfn(Object *obj)
+{
@ -59,14 +60,14 @@ index a1649f8844..4cf5b89db0 100644
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
* otherwise, a CPU with as many features enabled as our emulation supports.
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -442,6 +468,8 @@ static const ARMCPUInfo aarch64_cpus[] = {
@@ -914,6 +940,8 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
{ .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn },
{ .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn},
+ { .name = "FT-2000+", .initfn = aarch64_max_ft2000plus_initfn },
+ { .name = "Tengyun-S2500", .initfn = aarch64_max_tengyun_s2500_initfn },
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
{ .name = "max", .initfn = aarch64_max_initfn },
{ .name = NULL }
};
--
2.27.0

View File

@ -1,116 +0,0 @@
From 929d29ec7bf9dd6ec3802bea2148a041ff30d59b Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 14 Apr 2020 21:17:09 +0800
Subject: [PATCH] aio-wait: delegate polling of main AioContext if BQL not held
Any thread that is not a iothread returns NULL for qemu_get_current_aio_context().
As a result, it would also return true for
in_aio_context_home_thread(qemu_get_aio_context()), causing
AIO_WAIT_WHILE to invoke aio_poll() directly. This is incorrect
if the BQL is not held, because aio_poll() does not expect to
run concurrently from multiple threads, and it can actually
happen when savevm writes to the vmstate file from the
migration thread.
Therefore, restrict in_aio_context_home_thread to return true
for the main AioContext only if the BQL is held.
The function is moved to aio-wait.h because it is mostly used
there and to avoid a circular reference between main-loop.h
and block/aio.h.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200407140746.8041-5-pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
include/block/aio-wait.h | 22 ++++++++++++++++++++++
include/block/aio.h | 29 ++++++++++-------------------
2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
index afeeb18f..716d2639 100644
--- a/include/block/aio-wait.h
+++ b/include/block/aio-wait.h
@@ -26,6 +26,7 @@
#define QEMU_AIO_WAIT_H
#include "block/aio.h"
+#include "qemu/main-loop.h"
/**
* AioWait:
@@ -124,4 +125,25 @@ void aio_wait_kick(void);
*/
void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
+/**
+ * in_aio_context_home_thread:
+ * @ctx: the aio context
+ *
+ * Return whether we are running in the thread that normally runs @ctx. Note
+ * that acquiring/releasing ctx does not affect the outcome, each AioContext
+ * still only has one home thread that is responsible for running it.
+ */
+static inline bool in_aio_context_home_thread(AioContext *ctx)
+{
+ if (ctx == qemu_get_current_aio_context()) {
+ return true;
+ }
+
+ if (ctx == qemu_get_aio_context()) {
+ return qemu_mutex_iothread_locked();
+ } else {
+ return false;
+ }
+}
+
#endif /* QEMU_AIO_WAIT_H */
diff --git a/include/block/aio.h b/include/block/aio.h
index 6b0d52f7..9d28e247 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -60,12 +60,16 @@ struct AioContext {
QLIST_HEAD(, AioHandler) aio_handlers;
/* Used to avoid unnecessary event_notifier_set calls in aio_notify;
- * accessed with atomic primitives. If this field is 0, everything
- * (file descriptors, bottom halves, timers) will be re-evaluated
- * before the next blocking poll(), thus the event_notifier_set call
- * can be skipped. If it is non-zero, you may need to wake up a
- * concurrent aio_poll or the glib main event loop, making
- * event_notifier_set necessary.
+ * only written from the AioContext home thread, or under the BQL in
+ * the case of the main AioContext. However, it is read from any
+ * thread so it is still accessed with atomic primitives.
+ *
+ * If this field is 0, everything (file descriptors, bottom halves,
+ * timers) will be re-evaluated before the next blocking poll() or
+ * io_uring wait; therefore, the event_notifier_set call can be
+ * skipped. If it is non-zero, you may need to wake up a concurrent
+ * aio_poll or the glib main event loop, making event_notifier_set
+ * necessary.
*
* Bit 0 is reserved for GSource usage of the AioContext, and is 1
* between a call to aio_ctx_prepare and the next call to aio_ctx_check.
@@ -580,19 +584,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co);
*/
AioContext *qemu_get_current_aio_context(void);
-/**
- * in_aio_context_home_thread:
- * @ctx: the aio context
- *
- * Return whether we are running in the thread that normally runs @ctx. Note
- * that acquiring/releasing ctx does not affect the outcome, each AioContext
- * still only has one home thread that is responsible for running it.
- */
-static inline bool in_aio_context_home_thread(AioContext *ctx)
-{
- return ctx == qemu_get_current_aio_context();
-}
-
/**
* aio_context_setup:
* @ctx: the aio context
--
2.23.0

View File

@ -1,50 +0,0 @@
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

@ -1,68 +0,0 @@
From 6d795b30ff09bc1f799daa454f776d682cc77197 Mon Sep 17 00:00:00 2001
From: zhanghao1 <zhanghao1@kylinos.cn>
Date: Tue, 11 May 2021 20:17:16 +0800
Subject: [PATCH] arm/cpu: Fixed function undefined error at compile time under
arm
Add the compilation option CONFIG_KVM while using
"kvm_arm_cpu_feature_supported" and "kvm_arm_get_one_reg".
In arm, the default value of CONFIG_KVM is no.
While the target is arm, the compilation fails because
the function "kvm_arm_cpu_feature_supporte" is declared
or the function "kvm_arm_get_one_reg" is not defined.
Signed-off-by: zhanghao1 <zhanghao1@kylinos.cn>
---
target/arm/helper.c | 4 ++++
target/arm/kvm_arm.h | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bddd355fa0..9d2b2659f6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -284,6 +284,7 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
newval = read_raw_cp_reg(&cpu->env, ri);
if (kvm_sync) {
+#ifdef CONFIG_KVM
if (is_id_reg(ri)) {
/* Only sync if we can sync to KVM successfully. */
uint64_t oldval;
@@ -306,6 +307,7 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
} else {
+#endif
/*
* Only sync if the previous list->cpustate sync succeeded.
* Rather than tracking the success/failure state for every
@@ -324,7 +326,9 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
}
write_raw_cp_reg(&cpu->env, ri, newval);
+#ifdef CONFIG_KVM
}
+#endif
}
cpu->cpreg_values[i] = newval;
}
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 49e80878f4..a223967d4d 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -312,6 +312,10 @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
+static inline bool kvm_arm_cpu_feature_supported(void) {
+ return false;
+}
+
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
{
return -ENOENT;
--
2.27.0

View File

@ -1,4 +1,4 @@
From d8e0b51447d8c64788cd7f9b0fa75c4ccb06f8eb Mon Sep 17 00:00:00 2001
From 42072fd4b33125959d825a0c5cee0d1122072f71 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 10:17:27 +0800
Subject: [PATCH] arm/cpu: assign arm_get_arch_id handler to get_arch_id hook
@ -13,12 +13,12 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
1 file changed, 8 insertions(+)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 39bbe7e2d7..1ccb30e5eb 100644
index 65163f5135..f06ba29885 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2575,6 +2575,13 @@ static gchar *arm_gdb_arch_name(CPUState *cs)
return g_strdup("arm");
}
@@ -2557,6 +2557,13 @@ static const struct TCGCPUOps arm_tcg_ops = {
};
#endif /* CONFIG_TCG */
+static int64_t arm_cpu_get_arch_id(CPUState *cs)
+{
@ -30,13 +30,14 @@ index 39bbe7e2d7..1ccb30e5eb 100644
static void arm_cpu_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@@ -2596,6 +2603,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
@@ -2575,6 +2582,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = arm_cpu_set_pc;
cc->gdb_read_register = arm_cpu_gdb_read_register;
cc->gdb_write_register = arm_cpu_gdb_write_register;
+ cc->get_arch_id = arm_cpu_get_arch_id;
#ifndef CONFIG_USER_ONLY
cc->do_interrupt = arm_cpu_do_interrupt;
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
cc->sysemu_ops = &arm_sysemu_ops;
#endif
--
2.19.1
2.27.0

View File

@ -1,36 +0,0 @@
From b4bab3bf6a75d97d2f1098c4dc52d35ced003c70 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
Date: Mon, 13 Jan 2020 17:01:11 +0800
Subject: [PATCH] arm/translate-a64: fix uninitialized variable warning
Fixes:
target/arm/translate-a64.c: In function 'disas_crypto_three_reg_sha512':
target/arm/translate-a64.c:13625:9: error: 'genfn' may be used uninitialized in this function [-Werror=maybe-uninitialized]
genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
qemu/target/arm/translate-a64.c:13609:8: error: 'feature' may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (!feature) {
Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
---
target/arm/translate-a64.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index dcdeb801..5f423d5d 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13767,6 +13767,8 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
feature = dc_isar_feature(aa64_sha3, s);
genfn = NULL;
break;
+ default:
+ g_assert_not_reached();
}
} else {
switch (opcode) {
--
2.18.1

View File

@ -1,4 +1,4 @@
From 6d287b3f1d961cc4adda1c6a452f41db84466f5a Mon Sep 17 00:00:00 2001
From 209b3e4e522b8f7f41e495feaade96ee9a91e46a Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 3 Apr 2020 16:16:18 +0800
Subject: [PATCH] arm/virt: Add CPU hotplug framework
@ -14,11 +14,11 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d09a5773df..0bd37af26c 100644
index 9b73c479c4..11155fcb70 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2077,11 +2077,25 @@ out:
error_propagate(errp, local_err);
@@ -2586,6 +2586,18 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
dev, &error_abort);
}
+static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
@ -36,31 +36,34 @@ index d09a5773df..0bd37af26c 100644
static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_pre_plug(hotplug_dev, dev, errp);
@@ -2619,6 +2631,8 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
g_free(resv_prop_str);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+ virt_cpu_pre_plug(hotplug_dev, dev, errp);
}
}
@@ -2098,6 +2112,8 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
@@ -2637,6 +2651,8 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
}
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_plug(hotplug_dev, dev, errp);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+ virt_cpu_plug(hotplug_dev, dev, errp);
}
}
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
PCIDevice *pdev = PCI_DEVICE(dev);
@@ -2717,7 +2733,8 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -2112,7 +2128,8 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
DeviceState *dev)
{
if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE) ||
if (device_is_dynamic_sysbus(mc, dev) ||
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+ object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+ (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) ||
+ (object_dynamic_cast(OBJECT(dev), TYPE_CPU))) {
return HOTPLUG_HANDLER(machine);
}
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
--
2.19.1
2.27.0

View File

@ -1,4 +1,4 @@
From cde57fcae2ed16a10e1ef7f2da0ec368883988ba Mon Sep 17 00:00:00 2001
From 5454c00908236dcabcbf9ae246ccb69e1fcea72e Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Mon, 6 Apr 2020 10:54:35 +0800
Subject: [PATCH] arm/virt: Add CPU topology support
@ -10,18 +10,19 @@ plug or unplug.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt.c | 68 +++++++++++++++++++++++++++++++++++++--
include/hw/arm/topology.h | 61 +++++++++++++++++++++++++++++++++++
target/arm/cpu.c | 3 ++
target/arm/cpu.h | 3 ++
4 files changed, 133 insertions(+), 2 deletions(-)
hw/arm/virt.c | 87 ++++++++++++++++++++++++++++++++++++++-
include/hw/arm/topology.h | 68 ++++++++++++++++++++++++++++++
qapi/machine.json | 2 +
target/arm/cpu.c | 4 ++
target/arm/cpu.h | 4 ++
5 files changed, 163 insertions(+), 2 deletions(-)
create mode 100644 include/hw/arm/topology.h
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0bd37af26c..64532b61b2 100644
index 11155fcb70..a12e718686 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -36,6 +36,7 @@
@@ -39,6 +39,7 @@
#include "hw/sysbus.h"
#include "hw/arm/boot.h"
#include "hw/arm/primecell.h"
@ -29,7 +30,7 @@ index 0bd37af26c..64532b61b2 100644
#include "hw/arm/virt.h"
#include "hw/block/flash.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
@@ -2020,6 +2021,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
@@ -2524,6 +2525,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
int n;
unsigned int max_cpus = ms->smp.max_cpus;
VirtMachineState *vms = VIRT_MACHINE(ms);
@ -37,7 +38,7 @@ index 0bd37af26c..64532b61b2 100644
if (ms->possible_cpus) {
assert(ms->possible_cpus->len == max_cpus);
@@ -2031,10 +2033,17 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
@@ -2535,10 +2537,19 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
ms->possible_cpus->len = max_cpus;
for (n = 0; n < ms->possible_cpus->len; n++) {
ms->possible_cpus->cpus[n].type = ms->cpu_type;
@ -45,9 +46,11 @@ index 0bd37af26c..64532b61b2 100644
ms->possible_cpus->cpus[n].arch_id =
virt_cpu_mp_affinity(vms, n);
+
+ topo_ids_from_idx(n, ms->smp.cores, ms->smp.threads, &topo);
+ topo_ids_from_idx(n, ms->smp.clusters, ms->smp.cores, ms->smp.threads, &topo);
+ ms->possible_cpus->cpus[n].props.has_socket_id = true;
+ ms->possible_cpus->cpus[n].props.socket_id = topo.pkg_id;
+ ms->possible_cpus->cpus[n].props.has_cluster_id = true;
+ ms->possible_cpus->cpus[n].props.cluster_id = topo.cluster_id;
+ ms->possible_cpus->cpus[n].props.has_core_id = true;
+ ms->possible_cpus->cpus[n].props.core_id = topo.core_id;
ms->possible_cpus->cpus[n].props.has_thread_id = true;
@ -56,7 +59,7 @@ index 0bd37af26c..64532b61b2 100644
}
return ms->possible_cpus;
}
@@ -2080,7 +2089,62 @@ out:
@@ -2589,7 +2600,79 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@ -65,17 +68,25 @@ index 0bd37af26c..64532b61b2 100644
+ ARMCPUTopoInfo topo;
+ ARMCPU *cpu = ARM_CPU(dev);
+ MachineState *ms = MACHINE(hotplug_dev);
+ int smp_clusters = ms->smp.clusters;
+ int smp_cores = ms->smp.cores;
+ int smp_threads = ms->smp.threads;
+
+ /* if cpu idx is not set, set it based on socket/core/thread properties */
+ /* if cpu idx is not set, set it based on socket/cluster/core/thread
+ * properties
+ */
+ if (cs->cpu_index == UNASSIGNED_CPU_INDEX) {
+ int max_socket = ms->smp.max_cpus / smp_threads / smp_cores;
+ int max_socket = ms->smp.max_cpus / smp_threads / smp_cores / smp_clusters;
+ if (cpu->socket_id < 0 || cpu->socket_id >= max_socket) {
+ error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u",
+ cpu->socket_id, max_socket - 1);
+ return;
+ }
+ if (cpu->cluster_id < 0 || cpu->cluster_id >= smp_clusters) {
+ error_setg(errp, "Invalid CPU cluster-id: %u must be in range 0:%u",
+ cpu->cluster_id, smp_clusters - 1);
+ return;
+ }
+ if (cpu->core_id < 0 || cpu->core_id >= smp_cores) {
+ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u",
+ cpu->core_id, smp_cores - 1);
@ -88,15 +99,17 @@ index 0bd37af26c..64532b61b2 100644
+ }
+
+ topo.pkg_id = cpu->socket_id;
+ topo.cluster_id = cpu->cluster_id;
+ topo.core_id = cpu->core_id;
+ topo.smt_id = cpu->thread_id;
+ cs->cpu_index = idx_from_topo_ids(smp_cores, smp_threads, &topo);
+ cs->cpu_index = idx_from_topo_ids(smp_clusters, smp_cores, smp_threads, &topo);
+ }
+
+ /* if 'address' properties socket-id/core-id/thread-id are not set, set them
+ * so that machine_query_hotpluggable_cpus would show correct values
+ /* if 'address' properties socket-id/cluster-id/core-id/thread-id are not
+ * set, set them so that machine_query_hotpluggable_cpus would show correct
+ * values
+ */
+ topo_ids_from_idx(cs->cpu_index, smp_cores, smp_threads, &topo);
+ topo_ids_from_idx(cs->cpu_index, smp_clusters, smp_cores, smp_threads, &topo);
+ if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {
+ error_setg(errp, "property socket-id: %u doesn't match set idx:"
+ " 0x%x (socket-id: %u)", cpu->socket_id, cs->cpu_index, topo.pkg_id);
@ -104,6 +117,13 @@ index 0bd37af26c..64532b61b2 100644
+ }
+ cpu->socket_id = topo.pkg_id;
+
+ if (cpu->cluster_id != -1 && cpu->cluster_id != topo.cluster_id) {
+ error_setg(errp, "property cluster-id: %u doesn't match set idx:"
+ " 0x%x (cluster-id: %u)", cpu->cluster_id, cs->cpu_index, topo.cluster_id);
+ return;
+ }
+ cpu->cluster_id = topo.cluster_id;
+
+ if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {
+ error_setg(errp, "property core-id: %u doesn't match set idx:"
+ " 0x%x (core-id: %u)", cpu->core_id, cs->cpu_index, topo.core_id);
@ -122,10 +142,10 @@ index 0bd37af26c..64532b61b2 100644
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
diff --git a/include/hw/arm/topology.h b/include/hw/arm/topology.h
new file mode 100644
index 0000000000..a3e5f436c5
index 0000000000..d0dad1a9a3
--- /dev/null
+++ b/include/hw/arm/topology.h
@@ -0,0 +1,61 @@
@@ -0,0 +1,68 @@
+/*
+ * ARM CPU topology data structures and functions
+ *
@ -150,70 +170,100 @@ index 0000000000..a3e5f436c5
+
+typedef struct ARMCPUTopoInfo {
+ unsigned pkg_id;
+ unsigned cluster_id;
+ unsigned core_id;
+ unsigned smt_id;
+} ARMCPUTopoInfo;
+
+/* Calculate (contiguous) CPU index based on topology */
+static inline unsigned idx_from_topo_ids(unsigned nr_cores,
+static inline unsigned idx_from_topo_ids(unsigned nr_clusters,
+ unsigned nr_cores,
+ unsigned nr_threads,
+ const ARMCPUTopoInfo *topo)
+{
+ assert(nr_clusters > 0);
+ assert(nr_cores > 0);
+ assert(nr_threads > 0);
+ assert(topo != NULL);
+
+ return topo->pkg_id * nr_cores * nr_threads +
+ return topo->pkg_id * nr_clusters * nr_cores * nr_threads +
+ topo->cluster_id * nr_cores +
+ topo->core_id * nr_threads +
+ topo->smt_id;
+}
+
+/* Calculate thread/core/package topology
+/* Calculate thread/core/cluster/package topology
+ * based on (contiguous) CPU index
+ */
+static inline void topo_ids_from_idx(unsigned cpu_index,
+ unsigned nr_clusters,
+ unsigned nr_cores,
+ unsigned nr_threads,
+ ARMCPUTopoInfo *topo)
+{
+ assert(nr_clusters > 0);
+ assert(nr_cores > 0);
+ assert(nr_threads > 0);
+ assert(topo != NULL);
+
+ topo->smt_id = cpu_index % nr_threads;
+ topo->core_id = cpu_index / nr_threads % nr_cores;
+ topo->pkg_id = cpu_index / nr_threads / nr_cores;
+ topo->cluster_id = cpu_index / nr_threads / nr_cores % nr_clusters;
+ topo->pkg_id = cpu_index / nr_threads / nr_cores / nr_clusters;
+}
+
+#endif /* HW_ARM_TOPOLOGY_H */
+
diff --git a/qapi/machine.json b/qapi/machine.json
index 8faa51074e..6822cafe2e 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -868,6 +868,7 @@
# @node-id: NUMA node ID the CPU belongs to
# @socket-id: socket number within node/board the CPU belongs to
# @die-id: die number within socket the CPU belongs to (since 4.1)
+# @cluster-id: cluster number within die the CPU belongs to (since 6.2)
# @core-id: core number within die the CPU belongs to
# @thread-id: thread number within core the CPU belongs to
#
@@ -883,6 +884,7 @@
'data': { '*node-id': 'int',
'*socket-id': 'int',
'*die-id': 'int',
+ '*cluster-id': 'int',
'*core-id': 'int',
'*thread-id': 'int'
}
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1ccb30e5eb..91f1e36cd8 100644
index f06ba29885..9fd8e57971 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2560,6 +2560,9 @@ static Property arm_cpu_properties[] = {
@@ -2507,6 +2507,10 @@ static Property arm_cpu_properties[] = {
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
mp_affinity, ARM64_AFFINITY_INVALID),
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
+ DEFINE_PROP_INT32("socket-id", ARMCPU, socket_id, -1),
+ DEFINE_PROP_INT32("cluster-id", ARMCPU, cluster_id, -1),
+ DEFINE_PROP_INT32("core-id", ARMCPU, core_id, -1),
+ DEFINE_PROP_INT32("thread-id", ARMCPU, thread_id, -1),
DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e19531a77b..219c222b89 100644
index 947897d5ac..eb804dffaa 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -916,6 +916,9 @@ struct ARMCPU {
@@ -1006,6 +1006,10 @@ struct ARMCPU {
QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
int32_t node_id; /* NUMA node this CPU belongs to */
+ int32_t socket_id;
+ int32_t cluster_id;
+ int32_t core_id;
+ int32_t thread_id;
/* Used to synchronize KVM and QEMU in-kernel device levels */
uint8_t device_irq_level;
--
2.19.1
2.27.0

View File

@ -1,4 +1,4 @@
From 31873c4c0454fb17654f57adece2bc396415f8bf Mon Sep 17 00:00:00 2001
From 965eb25b03f6977a7656dce3ac5cdb4c95bfe003 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 13:50:40 +0800
Subject: [PATCH] arm/virt: Add cpu_hotplug_enabled field
@ -14,10 +14,10 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
2 files changed, 8 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index dda22194b5..304a4c2d31 100644
index b1224fb1e4..45a0a045b1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1645,6 +1645,7 @@ static void machvirt_init(MachineState *machine)
@@ -2008,6 +2008,7 @@ static void machvirt_init(MachineState *machine)
{
VirtMachineState *vms = VIRT_MACHINE(machine);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
@ -25,7 +25,7 @@ index dda22194b5..304a4c2d31 100644
MachineClass *mc = MACHINE_GET_CLASS(machine);
const CPUArchIdList *possible_cpus;
MemoryRegion *sysmem = get_system_memory();
@@ -1655,6 +1656,7 @@ static void machvirt_init(MachineState *machine)
@@ -2017,6 +2018,7 @@ static void machvirt_init(MachineState *machine)
bool has_ged = !vmc->no_ged;
unsigned int smp_cpus = machine->smp.cpus;
unsigned int max_cpus = machine->smp.max_cpus;
@ -33,29 +33,30 @@ index dda22194b5..304a4c2d31 100644
/*
* In accelerated mode, the memory map is computed earlier in kvm_type()
@@ -1760,6 +1762,11 @@ static void machvirt_init(MachineState *machine)
@@ -2106,6 +2108,11 @@ static void machvirt_init(MachineState *machine)
create_fdt(vms);
qemu_log("cpu init start\n");
+ cpu_class = object_class_by_name(ms->cpu_type);
+ vms->cpu_hotplug_enabled = has_ged && firmware_loaded &&
+ acpi_enabled && vms->gic_version == 3 &&
+ virt_is_acpi_enabled(vms) && vms->gic_version == 3 &&
+ !!object_class_dynamic_cast(cpu_class, TYPE_AARCH64_CPU);
+
possible_cpus = mc->possible_cpu_arch_ids(machine);
assert(possible_cpus->len == max_cpus);
for (n = 0; n < possible_cpus->len; n++) {
Object *cpuobj;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index beef4c8002..b4c53d920e 100644
index 947d41f767..c371d377e0 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -126,6 +126,7 @@ typedef struct {
bool highmem_ecam;
@@ -149,6 +149,7 @@ struct VirtMachineState {
bool its;
bool tcg_its;
bool virt;
+ bool cpu_hotplug_enabled;
int32_t gic_version;
VirtIOMMUType iommu;
struct arm_boot_info bootinfo;
bool ras;
bool mte;
OnOffAuto acpi;
--
2.19.1
2.27.0

View File

@ -1,66 +0,0 @@
From 7cfb37c50209208f853c6fbd0df6673a95e03ef9 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 14:16:40 +0800
Subject: [PATCH] arm/virt: Add some sanity checks in cpu_pre_plug hook
For that user will try to hotplug a CPU when preconditions
are not satisfied, check these CPU hotplug preconditions in
pre_plug hook.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 983084c459..c6a99e683a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2086,10 +2086,30 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(hotplug_dev);
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+ const CPUArchId *cpu_slot = NULL;
MemoryRegion *sysmem = get_system_memory();
int smp_cores = ms->smp.cores;
int smp_threads = ms->smp.threads;
+ /* Some hotplug capability checks */
+
+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
+ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
+ ms->cpu_type);
+ return;
+ }
+
+ if (dev->hotplugged && !vms->acpi_dev) {
+ error_setg(errp, "CPU hotplug is disabled: missing acpi device.");
+ return;
+ }
+
+ if (dev->hotplugged && !vms->cpu_hotplug_enabled) {
+ error_setg(errp, "CPU hotplug is disabled: "
+ "should use AArch64 CPU and GICv3.");
+ return;
+ }
+
/* if cpu idx is not set, set it based on socket/core/thread properties */
if (cs->cpu_index == UNASSIGNED_CPU_INDEX) {
int max_socket = ms->smp.max_cpus / smp_threads / smp_cores;
@@ -2145,6 +2165,13 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
object_property_set_int(cpuobj, possible_cpus->cpus[cs->cpu_index].arch_id,
"mp-affinity", NULL);
+ cpu_slot = &possible_cpus->cpus[cs->cpu_index];
+ if (cpu_slot->cpu) {
+ error_setg(errp, "CPU[%d] with mp_affinity %" PRIu64 " exists",
+ cs->cpu_index, cpu->mp_affinity);
+ return;
+ }
+
numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
&error_fatal);
--
2.19.1

View File

@ -1,4 +1,4 @@
From d38d1d4e859450535ddc6bf0c7a59f6217b1403c Mon Sep 17 00:00:00 2001
From 6b0f94aee82c7558d79e5ec28437483c4873dc65 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Sun, 5 Apr 2020 16:03:15 +0800
Subject: [PATCH] arm/virt: Attach ACPI CPU hotplug support to virt
@ -16,26 +16,26 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8b68a15d76..dbe9acb148 100644
index a93d223879..7cb320d9f2 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -806,6 +806,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
MachineState *ms = MACHINE(vms);
const MemMapEntry *memmap = vms->memmap;
@@ -937,6 +937,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
const int *irqmap = vms->irqmap;
AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id,
.oem_table_id = vms->oem_table_id };
+ bool cpu_aml_built = false;
acpi_table_begin(&table, table_data);
dsdt = init_aml_allocator();
/* Reserve space for header */
@@ -817,7 +818,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -947,7 +948,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
* the RTC ACPI device at all when using UEFI.
*/
scope = aml_scope("\\_SB");
- acpi_dsdt_add_cpus(scope, vms->smp_cpus, vms);
- acpi_dsdt_add_cpus(scope, vms);
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
@@ -845,6 +845,19 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
if (vmc->acpi_expose_flash) {
@@ -977,6 +977,19 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
AML_SYSTEM_MEMORY,
memmap[VIRT_PCDIMM_ACPI].base);
}
@ -51,50 +51,53 @@ index 8b68a15d76..dbe9acb148 100644
+ }
+
+ if (!cpu_aml_built) {
+ acpi_dsdt_add_cpus(scope, vms->smp_cpus, vms);
+ acpi_dsdt_add_cpus(scope, vms);
}
acpi_dsdt_add_power_button(scope);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8638aeedb7..d09a5773df 100644
index 3299d674c8..9b73c479c4 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -140,6 +140,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
[VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
+ [VIRT_CPU_ACPI] = { 0x09090000, ACPI_CPU_HOTPLUG_REG_LEN },
@@ -154,6 +154,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
[VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
+ [VIRT_CPU_ACPI] = { 0x090c0000, ACPI_CPU_HOTPLUG_REG_LEN },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
[VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
@@ -645,11 +646,16 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
event |= ACPI_GED_MEM_HOTPLUG_EVT;
@@ -697,6 +698,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
event |= ACPI_GED_NVDIMM_HOTPLUG_EVT;
}
+ /* event |= ACPI_GED_CPU_HOTPLUG_EVT;
+ * Currently CPU hotplug is not enabled.
+ */
+
dev = qdev_create(NULL, TYPE_ACPI_GED);
dev = qdev_new(TYPE_ACPI_GED);
qdev_prop_set_uint32(dev, "ged-event", event);
@@ -706,6 +711,7 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, vms->memmap[VIRT_CPU_ACPI].base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, vms->memmap[VIRT_CPU_ACPI].base);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
qdev_init_nofail(dev);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index cbdea7ff32..6880ebe07c 100644
index fe26709e1a..2a838620d8 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -81,6 +81,7 @@ enum {
VIRT_SECURE_MEM,
VIRT_PCDIMM_ACPI,
@@ -88,6 +88,7 @@ enum {
VIRT_ACPI_GED,
VIRT_NVDIMM_ACPI,
VIRT_PVTIME,
+ VIRT_CPU_ACPI,
VIRT_LOWMEMMAP_LAST,
};
--
2.19.1
2.27.0

View File

@ -0,0 +1,92 @@
From 3063d421cd68937ece290bc02151cc15b7ec33d0 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 13:55:11 +0800
Subject: [PATCH] arm/virt: Pre-sizing MADT-GICC GICv3 and Pre-park KVM vCPU
Establish all pre-sizing facilities based on cpu_hotplug_enabled
field.
Note: PPTT is constructed for possible_cpus, so it does not need
to pre-sizing it.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt-acpi-build.c | 3 +++
hw/arm/virt.c | 14 ++++++++++++--
target/arm/kvm.c | 4 ++--
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index a16b54086e..1101161d70 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -859,6 +859,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
build_append_int_noprefix(table_data, vms->gic_version, 1);
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
+ if (vms->cpu_hotplug_enabled) {
+ num_cpu = ms->smp.max_cpus;
+ }
for (i = 0; i < num_cpu; i++) {
virt_madt_cpu_entry(NULL, i, possible_cpus, table_data, false);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 45a0a045b1..4eb1b44729 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -833,6 +833,9 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
unsigned int smp_cpus = ms->smp.cpus;
uint32_t nb_redist_regions = 0;
+ if (vms->cpu_hotplug_enabled) {
+ num_cpus = ms->smp.max_cpus;
+ }
assert(num_cpus >= smp_cpus);
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
@@ -2119,8 +2122,15 @@ static void machvirt_init(MachineState *machine)
Object *cpuobj;
CPUState *cs;
+ if (kvm_enabled() && vms->cpu_hotplug_enabled) {
+ if (kvm_create_parked_vcpu(n) < 0) {
+ error_report("mach-virt: Create KVM parked vCPU failed");
+ exit(1);
+ }
+ }
+
if (n >= smp_cpus) {
- break;
+ continue;
}
cpuobj = object_new(possible_cpus->cpus[n].type);
@@ -2208,7 +2218,7 @@ static void machvirt_init(MachineState *machine)
}
vms->bootinfo.ram_size = machine->ram_size;
- vms->bootinfo.nb_cpus = smp_cpus;
+ vms->bootinfo.nb_cpus = vms->cpu_hotplug_enabled ? max_cpus : smp_cpus;
vms->bootinfo.board_id = -1;
vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base;
vms->bootinfo.get_dtb = machvirt_dtb;
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 59d556724f..29ac3f40e0 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -262,9 +262,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
- if (ms->smp.cpus > 256 &&
+ if (ms->smp.max_cpus > 256 &&
!kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) {
- error_report("Using more than 256 vcpus requires a host kernel "
+ error_report("Using more than max 256 vcpus requires a host kernel "
"with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2");
ret = -EINVAL;
}
--
2.27.0

View File

@ -1,124 +0,0 @@
From bf47ef282bfe8b0a98e1f87d8708051ffa7192a1 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 13:55:11 +0800
Subject: [PATCH] arm/virt: Pre-sizing MADT-GICC PPTT GICv3 and Pre-park KVM
vCPU
Establish all pre-sizing facilities based on cpu_hotplug_enabled
field.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt-acpi-build.c | 12 +++++++++++-
hw/arm/virt.c | 14 ++++++++++++--
target/arm/kvm.c | 6 +++---
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index efac788ba1..2cfac7b84f 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -736,6 +736,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
gicd->version = vms->gic_version;
+ if (vms->cpu_hotplug_enabled) {
+ num_cpu = ms->smp.max_cpus;
+ }
for (i = 0; i < num_cpu; i++) {
virt_madt_cpu_entry(NULL, i, possible_cpus, table_data);
}
@@ -902,9 +905,11 @@ static
void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
{
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+ MachineState *ms = MACHINE(vms);
GArray *table_offsets;
unsigned dsdt, xsdt;
GArray *tables_blob = tables->table_data;
+ int num_cpus;
table_offsets = g_array_new(false, true /* clear */,
sizeof(uint32_t));
@@ -923,7 +928,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
acpi_add_table(table_offsets, tables_blob);
- build_pptt(tables_blob, tables->linker, vms->smp_cpus);
+ if (vms->cpu_hotplug_enabled) {
+ num_cpus = ms->smp.max_cpus;
+ } else {
+ num_cpus = ms->smp.cpus;
+ }
+ build_pptt(tables_blob, tables->linker, num_cpus);
acpi_add_table(table_offsets, tables_blob);
build_madt(tables_blob, tables->linker, vms);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 304a4c2d31..983084c459 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -767,6 +767,9 @@ static void create_gic(VirtMachineState *vms)
unsigned int smp_cpus = ms->smp.cpus;
uint32_t nb_redist_regions = 0;
+ if (vms->cpu_hotplug_enabled) {
+ num_cpus = ms->smp.max_cpus;
+ }
assert(num_cpus >= smp_cpus);
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
@@ -1772,8 +1775,15 @@ static void machvirt_init(MachineState *machine)
Object *cpuobj;
CPUState *cs;
+ if (kvm_enabled() && vms->cpu_hotplug_enabled) {
+ if (kvm_create_parked_vcpu(n) < 0) {
+ error_report("mach-virt: Create KVM parked vCPU failed");
+ exit(1);
+ }
+ }
+
if (n >= smp_cpus) {
- break;
+ continue;
}
cpuobj = object_new(possible_cpus->cpus[n].type);
@@ -1857,7 +1867,7 @@ static void machvirt_init(MachineState *machine)
vms->bootinfo.kernel_filename = machine->kernel_filename;
vms->bootinfo.kernel_cmdline = machine->kernel_cmdline;
vms->bootinfo.initrd_filename = machine->initrd_filename;
- vms->bootinfo.nb_cpus = smp_cpus;
+ vms->bootinfo.nb_cpus = vms->cpu_hotplug_enabled ? max_cpus : smp_cpus;
vms->bootinfo.board_id = -1;
vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base;
vms->bootinfo.get_dtb = machvirt_dtb;
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 327b3bc338..4f131f687d 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -202,7 +202,7 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
int kvm_arch_init(MachineState *ms, KVMState *s)
{
int ret = 0;
- unsigned int smp_cpus = ms->smp.cpus;
+ unsigned int max_cpus = ms->smp.max_cpus;
/* For ARM interrupt delivery is always asynchronous,
* whether we are using an in-kernel VGIC or not.
*/
@@ -216,9 +216,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
- if (smp_cpus > 256 &&
+ if (max_cpus > 256 &&
!kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) {
- error_report("Using more than 256 vcpus requires a host kernel "
+ error_report("Using more than max 256 vcpus requires a host kernel "
"with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2");
ret = -EINVAL;
}
--
2.19.1

View File

@ -0,0 +1,237 @@
From a2d8cf86a379bb161cdae850824c9e80fb370599 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 14:16:40 +0800
Subject: [PATCH] arm/virt: Start up CPU hot-plug and cold-plug
All the CPU hotplug facilities are ready. Assemble them
to start up CPU hot-plug capability for arm/virt.
This also adds CPU cold plug support to arm virt machine
board. CPU cold plug means adding CPU by using "-device
xx-arm-cpu" when we bring up Qemu.
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
hw/arm/virt.c | 110 ++++++++++++++++++++++++++++++++++++++++--
hw/core/cpu-common.c | 4 ++
include/hw/arm/virt.h | 1 +
target/arm/cpu.c | 2 +
4 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4eb1b44729..b81d22d68f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -52,6 +52,8 @@
#include "sysemu/tpm.h"
#include "sysemu/kvm.h"
#include "sysemu/hvf.h"
+#include "sysemu/cpus.h"
+#include "sysemu/hw_accel.h"
#include "hw/loader.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
@@ -703,9 +705,9 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
event |= ACPI_GED_NVDIMM_HOTPLUG_EVT;
}
- /* event |= ACPI_GED_CPU_HOTPLUG_EVT;
- * Currently CPU hotplug is not enabled.
- */
+ if (vms->cpu_hotplug_enabled) {
+ event |= ACPI_GED_CPU_HOTPLUG_EVT;
+ }
dev = qdev_new(TYPE_ACPI_GED);
qdev_prop_set_uint32(dev, "ged-event", event);
@@ -2555,11 +2557,18 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(hotplug_dev);
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+ const CPUArchId *cpu_slot = NULL;
MemoryRegion *sysmem = get_system_memory();
int smp_clusters = ms->smp.clusters;
int smp_cores = ms->smp.cores;
int smp_threads = ms->smp.threads;
+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
+ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
+ ms->cpu_type);
+ return;
+ }
+
/* if cpu idx is not set, set it based on socket/cluster/core/thread
* properties
*/
@@ -2593,6 +2602,20 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
cs->cpu_index = idx_from_topo_ids(smp_clusters, smp_cores, smp_threads, &topo);
}
+ /* Some hotplug capability checks */
+ if (cs->cpu_index >= ms->smp.cpus) {
+ if (!vms->acpi_dev) {
+ error_setg(errp, "CPU cold/hot plug is disabled: "
+ "missing acpi device.");
+ return;
+ }
+ if (!vms->cpu_hotplug_enabled) {
+ error_setg(errp, "CPU cold/hot plug is disabled: "
+ "should use AArch64 CPU and GICv3.");
+ return;
+ }
+ }
+
/* if 'address' properties socket-id/cluster-id/core-id/thread-id are not
* set, set them so that machine_query_hotpluggable_cpus would show correct
* values
@@ -2631,6 +2654,13 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
object_property_set_int(cpuobj, "mp-affinity",
possible_cpus->cpus[cs->cpu_index].arch_id, NULL);
+ cpu_slot = &possible_cpus->cpus[cs->cpu_index];
+ if (cpu_slot->cpu) {
+ error_setg(errp, "CPU[%d] with mp_affinity %" PRIu64 " exists",
+ cs->cpu_index, cpu->mp_affinity);
+ return;
+ }
+
numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
&error_fatal);
@@ -2716,12 +2746,83 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
&error_abort);
}
}
+
+ /* If we use KVM accel, we should pause all vcpus to
+ * allow hot access of vcpu registers.
+ */
+ if (dev->hotplugged && kvm_enabled()) {
+ pause_all_vcpus();
+ }
}
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- /* Currently nothing to do */
+ CPUArchId *cpu_slot;
+ CPUState *cs = CPU(dev);
+ int ncpu = cs->cpu_index;
+ MachineState *ms = MACHINE(hotplug_dev);
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ bool pmu = object_property_get_bool(OBJECT(first_cpu), "pmu", NULL);
+ bool steal_time = object_property_get_bool(OBJECT(first_cpu),
+ "kvm-steal-time", NULL);
+ GICv3State *gicv3;
+ ARMGICv3CommonClass *agcc;
+ Error *local_err = NULL;
+
+ /* For CPU that is cold/hot plugged */
+ if (ncpu >= ms->smp.cpus) {
+ /* Realize GIC related parts of CPU */
+ assert(vms->gic_version == 3);
+ gicv3 = ARM_GICV3_COMMON(vms->gic);
+ agcc = ARM_GICV3_COMMON_GET_CLASS(gicv3);
+ agcc->cpu_hotplug_realize(gicv3, ncpu);
+ connect_gic_cpu_irqs(vms, ncpu);
+
+ /* Init PMU and steal_time part */
+ if (kvm_enabled()) {
+ hwaddr pvtime_reg_base = vms->memmap[VIRT_PVTIME].base;
+
+ if (pmu) {
+ assert(arm_feature(&ARM_CPU(cs)->env, ARM_FEATURE_PMU));
+ if (kvm_irqchip_in_kernel()) {
+ kvm_arm_pmu_set_irq(cs, PPI(VIRTUAL_PMU_IRQ));
+ }
+ kvm_arm_pmu_init(cs);
+ }
+ if (steal_time) {
+ kvm_arm_pvtime_init(cs, pvtime_reg_base +
+ ncpu * PVTIME_SIZE_PER_CPU);
+ }
+ }
+
+ /* Register CPU reset and trigger it manually */
+ cpu_synchronize_state(cs);
+ cpu_hotplug_register_reset(ncpu);
+ cpu_hotplug_reset_manually(ncpu);
+ cpu_synchronize_post_reset(cs);
+ }
+
+ if (dev->hotplugged && kvm_enabled()) {
+ resume_all_vcpus();
+ }
+
+ if (vms->acpi_dev) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ }
+
+ vms->boot_cpus++;
+ if (vms->fw_cfg) {
+ fw_cfg_modify_i16(vms->fw_cfg, FW_CFG_NB_CPUS, vms->boot_cpus);
+ }
+
+ cpu_slot = &ms->possible_cpus->cpus[ncpu];
+ cpu_slot->cpu = OBJECT(dev);
+out:
+ error_propagate(errp, local_err);
}
static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
@@ -2940,6 +3041,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
mc->kvm_type = virt_kvm_type;
+ mc->has_hotpluggable_cpus = true;
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
hc->pre_plug = virt_machine_device_pre_plug_cb;
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 9e3241b430..b8d1d820cb 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -208,6 +208,10 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
if (dev->hotplugged) {
cpu_synchronize_post_init(cpu);
+
+#ifdef __aarch64__
+ if (!kvm_enabled())
+#endif
cpu_resume(cpu);
}
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index c371d377e0..4ddee19b18 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -168,6 +168,7 @@ struct VirtMachineState {
uint32_t msi_phandle;
uint32_t iommu_phandle;
int psci_conduit;
+ uint32_t boot_cpus;
hwaddr highest_gpa;
DeviceState *gic;
DeviceState *acpi_dev;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 9fd8e57971..d550022f18 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2580,6 +2580,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
device_class_set_props(dc, arm_cpu_properties);
device_class_set_parent_reset(dc, arm_cpu_reset, &acc->parent_reset);
+ dc->user_creatable = true;
+
cc->class_by_name = arm_cpu_class_by_name;
cc->has_work = arm_cpu_has_work;
cc->dump_state = arm_cpu_dump_state;
--
2.27.0

View File

@ -1,159 +0,0 @@
From 11f9628ceff019259ff12ce469deafbf50eb3075 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 14:20:59 +0800
Subject: [PATCH] arm/virt: Start up CPU hot-plug
All the CPU hotplug facilities are ready. Assemble them
to start up CPU hot-plug capability for arm/virt.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt.c | 61 ++++++++++++++++++++++++++++++++++++++++---
include/hw/arm/virt.h | 1 +
qom/cpu.c | 5 ++++
target/arm/cpu.c | 2 ++
4 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index c6a99e683a..112a6ae7cb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -48,6 +48,8 @@
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
+#include "sysemu/cpus.h"
+#include "sysemu/hw_accel.h"
#include "hw/loader.h"
#include "exec/address-spaces.h"
#include "qemu/bitops.h"
@@ -649,9 +651,9 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
event |= ACPI_GED_MEM_HOTPLUG_EVT;
}
- /* event |= ACPI_GED_CPU_HOTPLUG_EVT;
- * Currently CPU hotplug is not enabled.
- */
+ if (vms->cpu_hotplug_enabled) {
+ event |= ACPI_GED_CPU_HOTPLUG_EVT;
+ }
dev = qdev_create(NULL, TYPE_ACPI_GED);
qdev_prop_set_uint32(dev, "ged-event", event);
@@ -2214,12 +2216,62 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
object_property_set_link(cpuobj, OBJECT(secure_sysmem),
"secure-memory", &error_abort);
}
+
+ /* If we use KVM accel, we should pause all vcpus to
+ * allow hot access of vcpu registers.
+ */
+ if (dev->hotplugged && kvm_enabled()) {
+ pause_all_vcpus();
+ }
}
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- /* Currently nothing to do */
+ CPUArchId *cpu_slot;
+ CPUState *cs = CPU(dev);
+ int ncpu = cs->cpu_index;
+ MachineState *ms = MACHINE(hotplug_dev);
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ GICv3State *gicv3;
+ ARMGICv3CommonClass *agcc;
+ Error *local_err = NULL;
+
+ if (dev->hotplugged) {
+ /* Realize GIC related parts of CPU */
+ assert(vms->gic_version == 3);
+ gicv3 = ARM_GICV3_COMMON(vms->gic);
+ agcc = ARM_GICV3_COMMON_GET_CLASS(gicv3);
+ agcc->cpu_hotplug_realize(gicv3, ncpu);
+ connect_gic_cpu_irqs(vms, ncpu);
+
+ /* Register CPU reset and trigger it manually */
+ cpu_synchronize_state(cs);
+ cpu_hotplug_register_reset(ncpu);
+ cpu_hotplug_reset_manually(ncpu);
+ cpu_synchronize_post_reset(cs);
+
+ if (kvm_enabled()) {
+ resume_all_vcpus();
+ }
+ }
+
+ if (vms->acpi_dev) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ }
+
+ vms->boot_cpus++;
+ if (vms->fw_cfg) {
+ fw_cfg_modify_i16(vms->fw_cfg, FW_CFG_NB_CPUS, vms->boot_cpus);
+ }
+
+ cpu_slot = &ms->possible_cpus->cpus[ncpu];
+ cpu_slot->cpu = OBJECT(dev);
+out:
+ error_propagate(errp, local_err);
}
static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
@@ -2324,6 +2376,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
mc->kvm_type = virt_kvm_type;
+ mc->has_hotpluggable_cpus = true;
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
hc->pre_plug = virt_machine_device_pre_plug_cb;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index b4c53d920e..a9429bed25 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -140,6 +140,7 @@ typedef struct {
uint32_t msi_phandle;
uint32_t iommu_phandle;
int psci_conduit;
+ uint32_t boot_cpus;
hwaddr highest_gpa;
DeviceState *gic;
DeviceState *acpi_dev;
diff --git a/qom/cpu.c b/qom/cpu.c
index f376f782d8..58cd9d5bbc 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -342,7 +342,12 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
if (dev->hotplugged) {
cpu_synchronize_post_init(cpu);
+
+#ifdef __aarch64__
+ if (!kvm_enabled())
+#endif
cpu_resume(cpu);
+
}
/* NOTE: latest generic point where the cpu is fully realized */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 91f1e36cd8..811e5c6365 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2598,6 +2598,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
acc->parent_reset = cc->reset;
cc->reset = arm_cpu_reset;
+ dc->user_creatable = true;
+
cc->class_by_name = arm_cpu_class_by_name;
cc->has_work = arm_cpu_has_work;
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
--
2.19.1

View File

@ -1,92 +0,0 @@
From e3a1af72fca5bbcc840fba44d512bbe69ec55ca9 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Tue, 12 May 2020 15:05:06 +0800
Subject: [PATCH] arm/virt: Support CPU cold plug
This adds CPU cold plug support to arm virt machine board.
CPU cold plug means adding CPU by using "-device xx-arm-cpu"
when we bring up Qemu.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
hw/arm/virt.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 112a6ae7cb..4c7279392f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2093,25 +2093,12 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
int smp_cores = ms->smp.cores;
int smp_threads = ms->smp.threads;
- /* Some hotplug capability checks */
-
if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
ms->cpu_type);
return;
}
- if (dev->hotplugged && !vms->acpi_dev) {
- error_setg(errp, "CPU hotplug is disabled: missing acpi device.");
- return;
- }
-
- if (dev->hotplugged && !vms->cpu_hotplug_enabled) {
- error_setg(errp, "CPU hotplug is disabled: "
- "should use AArch64 CPU and GICv3.");
- return;
- }
-
/* if cpu idx is not set, set it based on socket/core/thread properties */
if (cs->cpu_index == UNASSIGNED_CPU_INDEX) {
int max_socket = ms->smp.max_cpus / smp_threads / smp_cores;
@@ -2137,6 +2124,20 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
cs->cpu_index = idx_from_topo_ids(smp_cores, smp_threads, &topo);
}
+ /* Some hotplug capability checks */
+ if (cs->cpu_index >= ms->smp.cpus) {
+ if (!vms->acpi_dev) {
+ error_setg(errp, "CPU cold/hot plug is disabled: "
+ "missing acpi device.");
+ return;
+ }
+ if (!vms->cpu_hotplug_enabled) {
+ error_setg(errp, "CPU cold/hot plug is disabled: "
+ "should use AArch64 CPU and GICv3.");
+ return;
+ }
+ }
+
/* if 'address' properties socket-id/core-id/thread-id are not set, set them
* so that machine_query_hotpluggable_cpus would show correct values
*/
@@ -2237,7 +2238,8 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev,
ARMGICv3CommonClass *agcc;
Error *local_err = NULL;
- if (dev->hotplugged) {
+ /* For CPU that is cold/hot plugged */
+ if (ncpu >= ms->smp.cpus) {
/* Realize GIC related parts of CPU */
assert(vms->gic_version == 3);
gicv3 = ARM_GICV3_COMMON(vms->gic);
@@ -2250,10 +2252,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev,
cpu_hotplug_register_reset(ncpu);
cpu_hotplug_reset_manually(ncpu);
cpu_synchronize_post_reset(cs);
+ }
- if (kvm_enabled()) {
- resume_all_vcpus();
- }
+ if (dev->hotplugged && kvm_enabled()) {
+ resume_all_vcpus();
}
if (vms->acpi_dev) {
--
2.19.1

View File

@ -1,4 +1,4 @@
From 91fed8840b004ec7bc91969afa10f03e13f311c4 Mon Sep 17 00:00:00 2001
From e3522e63a2f14c3c7d8cd603099b6bb51087f43b Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Wed, 22 Apr 2020 19:52:58 +0800
Subject: [PATCH] arm/virt/acpi: Extend cpufreq to support max_cpus
@ -12,10 +12,10 @@ Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/hw/acpi/cpufreq.c b/hw/acpi/cpufreq.c
index d02a25a6de..38dcab5683 100644
index a84db490b3..a76f7b8fa2 100644
--- a/hw/acpi/cpufreq.c
+++ b/hw/acpi/cpufreq.c
@@ -84,6 +84,7 @@ typedef struct CpuhzState {
@@ -83,6 +83,7 @@ typedef struct CpuhzState {
uint32_t PerformanceLimited;
uint32_t LowestFreq;
uint32_t NominalFreq;
@ -23,7 +23,7 @@ index d02a25a6de..38dcab5683 100644
uint32_t reg_size;
} CpuhzState;
@@ -95,10 +96,7 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset,
@@ -93,10 +94,7 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size)
uint64_t r;
uint64_t n;
@ -35,7 +35,7 @@ index d02a25a6de..38dcab5683 100644
warn_report("cpufreq_read: offset 0x%lx out of range", offset);
return 0;
}
@@ -166,11 +164,10 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset,
@@ -163,11 +161,10 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size)
static void cpufreq_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
@ -49,7 +49,7 @@ index d02a25a6de..38dcab5683 100644
error_printf("cpufreq_write: offset 0x%lx out of range", offset);
return;
}
@@ -251,9 +248,9 @@ static void cpufreq_init(Object *obj)
@@ -248,9 +245,9 @@ static void cpufreq_init(Object *obj)
CpuhzState *s = CPUFREQ(obj);
MachineState *ms = MACHINE(qdev_get_machine());
@ -62,4 +62,5 @@ index d02a25a6de..38dcab5683 100644
error_report("Required space 0x%x excesses the max support 0x%x",
s->reg_size, MAX_SUPPORT_SPACE);
--
2.19.1
2.27.0

View File

@ -1,4 +1,4 @@
From 2fdece10dac6161cb6c1f0f05247391aa3269eed Mon Sep 17 00:00:00 2001
From 06837491e2ece2fdd6fe6cc8572aaab52fbdcb3e Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Wed, 22 Apr 2020 15:58:27 +0800
Subject: [PATCH] arm/virt/acpi: Factor out CPPC building from DSDT CPU aml
@ -9,33 +9,21 @@ in build_cpus_aml.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
hw/acpi/generic_event_device.c | 1 +
hw/arm/virt-acpi-build.c | 33 +++++++++++++++++-----------
hw/arm/virt.c | 1 +
include/hw/acpi/acpi_dev_interface.h | 2 ++
include/hw/arm/virt.h | 2 ++
4 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index b834ae3ff6..82139b4314 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -289,6 +289,7 @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
adevc->send_event = acpi_ged_send_event;
adevc->madt_cpu = virt_madt_cpu_entry;
+ adevc->cpu_cppc = virt_acpi_dsdt_cpu_cppc;
}
static const TypeInfo acpi_ged_info = {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 4b6aace433..8b68a15d76 100644
index 64b1ed8672..a93d223879 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -111,8 +111,24 @@ static void acpi_dsdt_add_cppc(Aml *dev, uint64_t cpu_base, int *regs_offset)
@@ -120,8 +120,24 @@ static void acpi_dsdt_add_cppc(Aml *dev, uint64_t cpu_base, int *regs_offset)
aml_append(dev, aml_name_decl("_CPC", cpc));
}
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus,
-static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms,
- const MemMapEntry *cppc_memmap)
+void virt_acpi_dsdt_cpu_cppc(AcpiDeviceIf *adev, int ncpu, int num_cpu, Aml *dev)
+{
@ -54,11 +42,11 @@ index 4b6aace433..8b68a15d76 100644
+ }
+}
+
+static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus, VirtMachineState *vms)
+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
{
MachineState *ms = MACHINE(vms);
uint16_t i;
@@ -121,16 +137,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus,
@@ -131,16 +147,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms,
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
@ -70,52 +58,65 @@ index 4b6aace433..8b68a15d76 100644
- acpi_dsdt_add_cppc(dev,
- cppc_memmap->base + i * CPPC_REG_PER_CPU_STRIDE,
- cppc_regs_offset);
- acpi_dsdt_add_psd(dev, smp_cpus);
- acpi_dsdt_add_psd(dev, ms->smp.cpus);
- }
+ virt_acpi_dsdt_cpu_cppc(NULL, i, smp_cpus, dev);
+ virt_acpi_dsdt_cpu_cppc(NULL, i, ms->smp.cpus, dev);
aml_append(scope, dev);
}
@@ -810,7 +817,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -940,7 +947,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
* the RTC ACPI device at all when using UEFI.
*/
scope = aml_scope("\\_SB");
- acpi_dsdt_add_cpus(scope, vms->smp_cpus, &memmap[VIRT_CPUFREQ]);
+ acpi_dsdt_add_cpus(scope, vms->smp_cpus, vms);
- acpi_dsdt_add_cpus(scope, vms, &memmap[VIRT_CPUFREQ]);
+ acpi_dsdt_add_cpus(scope, vms);
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
if (vmc->acpi_expose_flash) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 44c29070c4..3299d674c8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -702,6 +702,7 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
adevc = ACPI_DEVICE_IF_GET_CLASS(dev);
adevc->madt_cpu = virt_madt_cpu_entry;
+ adevc->cpu_cppc = virt_acpi_dsdt_cpu_cppc;
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index adcb3a816c..2952914569 100644
index ea6056ab92..601931433a 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -3,6 +3,7 @@
@@ -5,6 +5,7 @@
#include "qom/object.h"
#include "hw/boards.h"
#include "hw/qdev-core.h"
+#include "hw/acpi/aml-build.h"
/* These values are part of guest ABI, and can not be changed */
typedef enum {
@@ -55,5 +56,6 @@ typedef struct AcpiDeviceIfClass {
void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev);
@@ -55,5 +56,6 @@ struct AcpiDeviceIfClass {
void (*madt_cpu)(AcpiDeviceIf *adev, int uid,
const CPUArchIdList *apic_ids, GArray *entry);
const CPUArchIdList *apic_ids, GArray *entry,
bool force_enabled);
+ void (*cpu_cppc)(AcpiDeviceIf *adev, int uid, int num_cpu, Aml *dev);
} AcpiDeviceIfClass;
};
#endif
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 6b1f10b231..cbdea7ff32 100644
index 36639e8d3e..fe26709e1a 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -157,6 +157,8 @@ typedef struct {
void virt_acpi_setup(VirtMachineState *vms);
@@ -185,6 +185,8 @@ bool virt_is_acpi_enabled(VirtMachineState *vms);
void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
const CPUArchIdList *cpu_list, GArray *entry);
const CPUArchIdList *cpu_list, GArray *entry,
bool force_enabled);
+void virt_acpi_dsdt_cpu_cppc(AcpiDeviceIf *adev, int uid,
+ int num_cpu, Aml *dev);
/* Return the number of used redistributor regions */
static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
--
2.19.1
2.27.0

View File

@ -1,4 +1,4 @@
From 92124743f4560c490780a229f53ea5881f706383 Mon Sep 17 00:00:00 2001
From 03e050611d6dc9909166fd31dd11abf6fd5012ea Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Sun, 5 Apr 2020 15:29:16 +0800
Subject: [PATCH] arm/virt/gic: Construct irqs connection from create_gic
@ -12,11 +12,11 @@ Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
1 file changed, 49 insertions(+), 41 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 83f4887e57..55d403bad6 100644
index 149e0245d7..0af0a996a1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -706,6 +706,54 @@ static void create_v2m(VirtMachineState *vms)
fdt_add_v2m_gic_node(vms);
@@ -772,6 +772,54 @@ static void create_v2m(VirtMachineState *vms)
vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
}
+static void connect_gic_cpu_irqs(VirtMachineState *vms, int i)
@ -67,10 +67,10 @@ index 83f4887e57..55d403bad6 100644
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+}
+
static void create_gic(VirtMachineState *vms)
static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
{
MachineState *ms = MACHINE(vms);
@@ -775,47 +823,7 @@ static void create_gic(VirtMachineState *vms)
@@ -849,47 +897,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
* and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
*/
for (i = 0; i < smp_cpus; i++) {
@ -120,4 +120,5 @@ index 83f4887e57..55d403bad6 100644
fdt_add_gic_node(vms);
--
2.19.1
2.27.0

View File

@ -1,7 +1,8 @@
From b70d020dba72283d7b16a77c377512c84aab5f81 Mon Sep 17 00:00:00 2001
From e7e28e79988eb671051d0d2af0eb010314c83d41 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Mon, 20 Apr 2020 10:38:12 +0800
Subject: [PATCH] arm64: Add the cpufreq device to show cpufreq info to guest
Date: Tue, 8 Feb 2022 21:01:09 +0800
Subject: [PATCH 24/24] arm64: Add the cpufreq device to show cpufreq info to
guest
On ARM64 platform, cpu frequency is retrieved via ACPI CPPC.
A virtual cpufreq device based on ACPI CPPC is created to
@ -22,46 +23,39 @@ This series is backported from:
https://patchwork.kernel.org/cover/11379943/
Signed-off-by: Ying Fang <fangying1@huawei.com>
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
---
default-configs/aarch64-softmmu.mak | 1 +
hw/acpi/Makefile.objs | 1 +
hw/acpi/aml-build.c | 22 +++
hw/acpi/cpufreq.c | 287 ++++++++++++++++++++++++++++
hw/arm/virt-acpi-build.c | 78 +++++++-
hw/arm/virt.c | 13 ++
configs/devices/aarch64-softmmu/default.mak | 1 +
hw/acpi/aml-build.c | 22 ++
hw/acpi/cpufreq.c | 283 ++++++++++++++++++++
hw/acpi/meson.build | 1 +
hw/arm/virt-acpi-build.c | 77 +++++-
hw/arm/virt.c | 13 +
hw/char/Kconfig | 4 +
include/hw/acpi/acpi-defs.h | 38 ++++
include/hw/acpi/acpi-defs.h | 38 +++
include/hw/acpi/aml-build.h | 3 +
include/hw/arm/virt.h | 1 +
10 files changed, 446 insertions(+), 2 deletions(-)
tests/data/acpi/virt/DSDT | Bin 5196 -> 5669 bytes
tests/data/acpi/virt/DSDT.memhp | Bin 6557 -> 7030 bytes
tests/data/acpi/virt/DSDT.numamem | Bin 5196 -> 5669 bytes
tests/data/acpi/virt/DSDT.pxb | Bin 7679 -> 8152 bytes
14 files changed, 441 insertions(+), 2 deletions(-)
create mode 100644 hw/acpi/cpufreq.c
diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
index 958b1e08..0a030e85 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -6,3 +6,4 @@ include arm-softmmu.mak
diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak
index cf43ac8da1..c7a710a0f1 100644
--- a/configs/devices/aarch64-softmmu/default.mak
+++ b/configs/devices/aarch64-softmmu/default.mak
@@ -6,3 +6,4 @@ include ../arm-softmmu/default.mak
CONFIG_XLNX_ZYNQMP_ARM=y
CONFIG_XLNX_VERSAL=y
CONFIG_SBSA_REF=y
+CONFIG_CPUFREQ=y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 9bb2101e..1a720c38 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -13,6 +13,7 @@ common-obj-y += bios-linker-loader.o
common-obj-y += aml-build.o utils.o
common-obj-$(CONFIG_ACPI_PCI) += pci.o
common-obj-$(CONFIG_TPM) += tpm.o
+common-obj-$(CONFIG_CPUFREQ) += cpufreq.o
common-obj-$(CONFIG_IPMI) += ipmi.o
common-obj-$(call lnot,$(CONFIG_IPMI)) += ipmi-stub.o
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 555c24f2..73f97751 100644
index bebf49622b..c4edaafa4a 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1369,6 +1369,28 @@ Aml *aml_sleep(uint64_t msec)
@@ -1554,6 +1554,28 @@ Aml *aml_sleep(uint64_t msec)
return var;
}
@ -92,10 +86,10 @@ index 555c24f2..73f97751 100644
int hi, lo;
diff --git a/hw/acpi/cpufreq.c b/hw/acpi/cpufreq.c
new file mode 100644
index 00000000..d02a25a6
index 0000000000..a84db490b3
--- /dev/null
+++ b/hw/acpi/cpufreq.c
@@ -0,0 +1,287 @@
@@ -0,0 +1,283 @@
+/*
+ * ACPI CPPC register device
+ *
@ -142,7 +136,6 @@ index 00000000..d02a25a6
+ */
+#define DEFAULT_HZ 2400
+
+
+int cppc_regs_offset[CPPC_REG_COUNT] = {
+ [HIGHEST_PERF] = 0,
+ [NOMINAL_PERF] = 4,
@ -186,8 +179,7 @@ index 00000000..d02a25a6
+} CpuhzState;
+
+
+static uint64_t cpufreq_read(void *opaque, hwaddr offset,
+ unsigned size)
+static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size)
+{
+ CpuhzState *s = (CpuhzState *)opaque;
+ uint64_t r;
@ -231,7 +223,7 @@ index 00000000..d02a25a6
+ break;
+ /*
+ * Guest may still access the register by 32bit; add the process to
+ * eliminate unnecessary warnings
+ * eliminate unnecessary warnings.
+ */
+ case 28:
+ r = s->ReferencePerformanceCounter >> 32;
@ -260,7 +252,6 @@ index 00000000..d02a25a6
+ return r;
+}
+
+
+static void cpufreq_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
@ -292,7 +283,7 @@ index 00000000..d02a25a6
+ const char *endptr = NULL;
+ int ret;
+
+ fd = qemu_open(hostpath, O_RDONLY);
+ fd = qemu_open_old(hostpath, O_RDONLY);
+ if (fd < 0) {
+ return 0;
+ }
@ -382,21 +373,27 @@ index 00000000..d02a25a6
+}
+
+type_init(cpufreq_register_types)
+
diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build
index adf6347bc4..448ea6afb4 100644
--- a/hw/acpi/meson.build
+++ b/hw/acpi/meson.build
@@ -25,6 +25,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('ich9.c', 'tco.c'))
acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c'))
acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c'))
acpi_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
+acpi_ss.add(when: 'CONFIG_CPUFREQ', if_true: files('cpufreq.c'))
softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c'))
softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss)
softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c',
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 0afb3727..29494ebd 100644
index 674f902652..1ca705654b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -45,11 +45,73 @@
#include "hw/arm/virt.h"
#include "sysemu/numa.h"
#include "kvm_arm.h"
+#include "hw/acpi/acpi-defs.h"
@@ -60,7 +60,68 @@
#define ARM_SPI_BASE 32
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
#define ACPI_BUILD_TABLE_SIZE 0x20000
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
-static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
+static void acpi_dsdt_add_psd(Aml *dev, int cpus)
+{
+ Aml *pkg;
@ -457,12 +454,12 @@ index 0afb3727..29494ebd 100644
+ aml_append(dev, aml_name_decl("_CPC", cpc));
+}
+
+static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus,
+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms,
+ const MemMapEntry *cppc_memmap)
{
MachineState *ms = MACHINE(vms);
uint16_t i;
@@ -57,6 +119,18 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
@@ -69,6 +130,18 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
Aml *dev = aml_device("C%.03X", i);
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
@ -475,78 +472,78 @@ index 0afb3727..29494ebd 100644
+ acpi_dsdt_add_cppc(dev,
+ cppc_memmap->base + i * CPPC_REG_PER_CPU_STRIDE,
+ cppc_regs_offset);
+ acpi_dsdt_add_psd(dev, smp_cpus);
+ acpi_dsdt_add_psd(dev, ms->smp.cpus);
+ }
+
aml_append(scope, dev);
}
}
@@ -718,7 +792,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
@@ -858,7 +931,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
* the RTC ACPI device at all when using UEFI.
*/
scope = aml_scope("\\_SB");
- acpi_dsdt_add_cpus(scope, vms->smp_cpus);
+ acpi_dsdt_add_cpus(scope, vms->smp_cpus, &memmap[VIRT_CPUFREQ]);
- acpi_dsdt_add_cpus(scope, vms);
+ acpi_dsdt_add_cpus(scope, vms, &memmap[VIRT_CPUFREQ]);
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
if (vmc->acpi_expose_flash) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d9496c93..0fa355ba 100644
index 529c0d38b6..0538d258fa 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -135,6 +135,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
@@ -154,6 +154,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
[VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
+ [VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
[VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 },
@@ -731,6 +732,16 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
@@ -931,6 +932,16 @@ static void create_uart(const VirtMachineState *vms, int uart,
g_free(nodename);
}
+static void create_cpufreq(const VirtMachineState *vms, MemoryRegion *mem)
+{
+ hwaddr base = vms->memmap[VIRT_CPUFREQ].base;
+ DeviceState *dev = qdev_create(NULL, "cpufreq");
+ DeviceState *dev = qdev_new("cpufreq");
+ SysBusDevice *s = SYS_BUS_DEVICE(dev);
+
+ qdev_init_nofail(dev);
+ sysbus_realize_and_unref(s, &error_fatal);
+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
+}
+
static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
static void create_rtc(const VirtMachineState *vms)
{
char *nodename;
@@ -1682,6 +1693,8 @@ static void machvirt_init(MachineState *machine)
@@ -2190,6 +2201,8 @@ static void machvirt_init(MachineState *machine)
create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
+ create_cpufreq(vms, sysmem);
+
if (vms->secure) {
create_secure_ram(vms, secure_sysmem);
create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
create_secure_ram(vms, secure_sysmem, secure_tag_sysmem);
create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
diff --git a/hw/char/Kconfig b/hw/char/Kconfig
index 40e7a8b8..2f61bf53 100644
index 6b6cf2fc1d..335a60c2c1 100644
--- a/hw/char/Kconfig
+++ b/hw/char/Kconfig
@@ -46,3 +46,7 @@ config SCLPCONSOLE
@@ -71,3 +71,7 @@ config GOLDFISH_TTY
config TERMINAL3270
config SHAKTI_UART
bool
+
+config CPUFREQ
+ bool
+ default y
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 57a3f58b..39ae91d3 100644
index c97e8633ad..ab86583228 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -634,4 +634,42 @@ struct AcpiIortRC {
} QEMU_PACKED;
typedef struct AcpiIortRC AcpiIortRC;
@@ -92,4 +92,42 @@ typedef struct AcpiFadtData {
#define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0)
#define ACPI_FADT_ARM_PSCI_USE_HVC (1 << 1)
+/*
+ * CPPC register definition from kernel header
@ -588,13 +585,13 @@ index 57a3f58b..39ae91d3 100644
+
#endif
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 1a563ad7..375335ab 100644
index 8e8ad8029e..2e00d2e208 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -347,6 +347,9 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
@@ -429,6 +429,9 @@ Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
uint8_t channel);
Aml *aml_sleep(uint64_t msec);
Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source);
+Aml *aml_generic_register(AmlRegionSpace rs, uint8_t reg_width,
+ uint8_t reg_offset, AmlAccessType type,
+ uint64_t addr);
@ -602,10 +599,10 @@ index 1a563ad7..375335ab 100644
/* Block AML object primitives */
Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index a7209420..43a6ce91 100644
index dc6b66ffc8..a4356cf736 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -66,6 +66,7 @@ enum {
@@ -70,6 +70,7 @@ enum {
VIRT_GIC_REDIST,
VIRT_SMMU,
VIRT_UART,
@ -613,6 +610,7 @@ index a7209420..43a6ce91 100644
VIRT_MMIO,
VIRT_RTC,
VIRT_FW_CFG,
--
2.23.0
--
2.27.0

View File

@ -1,171 +0,0 @@
From 787af8ed2bc86dc8688727d62a251965d9c42e00 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Fri, 10 Apr 2020 16:19:50 +0000
Subject: [PATCH 2/2] async: use explicit memory barriers
When using C11 atomics, non-seqcst reads and writes do not participate
in the total order of seqcst operations. In util/async.c and util/aio-posix.c,
in particular, the pattern that we use
write ctx->notify_me write bh->scheduled
read bh->scheduled read ctx->notify_me
if !bh->scheduled, sleep if ctx->notify_me, notify
needs to use seqcst operations for both the write and the read. In
general this is something that we do not want, because there can be
many sources that are polled in addition to bottom halves. The
alternative is to place a seqcst memory barrier between the write
and the read. This also comes with a disadvantage, in that the
memory barrier is implicit on strongly-ordered architectures and
it wastes a few dozen clock cycles.
Fortunately, ctx->notify_me is never written concurrently by two
threads, so we can assert that and relax the writes to ctx->notify_me.
The resulting solution works and performs well on both aarch64 and x86.
Note that the atomic_set/atomic_read combination is not an atomic
read-modify-write, and therefore it is even weaker than C11 ATOMIC_RELAXED;
on x86, ATOMIC_RELAXED compiles to a locked operation.
upstream_url: https://patchwork.kernel.org/patch/11482103/
Analyzed-by: Ying Fang <fangying1@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Ying Fang <fangying1@huawei.com>
Message-Id: <20200407140746.8041-6-pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
util/aio-posix.c | 16 ++++++++++++++--
util/aio-win32.c | 17 ++++++++++++++---
util/async.c | 16 ++++++++++++----
3 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/util/aio-posix.c b/util/aio-posix.c
index 6fbfa792..ca58b9a4 100644
--- a/util/aio-posix.c
+++ b/util/aio-posix.c
@@ -613,6 +613,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
int64_t timeout;
int64_t start = 0;
+ /*
+ * There cannot be two concurrent aio_poll calls for the same AioContext (or
+ * an aio_poll concurrent with a GSource prepare/check/dispatch callback).
+ * We rely on this below to avoid slow locked accesses to ctx->notify_me.
+ */
assert(in_aio_context_home_thread(ctx));
/* aio_notify can avoid the expensive event_notifier_set if
@@ -623,7 +628,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
* so disable the optimization now.
*/
if (blocking) {
- atomic_add(&ctx->notify_me, 2);
+ atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2);
+ /*
+ * Write ctx->notify_me before computing the timeout
+ * (reading bottom half flags, etc.). Pairs with
+ * smp_mb in aio_notify().
+ */
+ smp_mb();
}
qemu_lockcnt_inc(&ctx->list_lock);
@@ -668,7 +679,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
}
if (blocking) {
- atomic_sub(&ctx->notify_me, 2);
+ /* Finish the poll before clearing the flag. */
+ atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2);
aio_notify_accept(ctx);
}
diff --git a/util/aio-win32.c b/util/aio-win32.c
index a23b9c36..729d533f 100644
--- a/util/aio-win32.c
+++ b/util/aio-win32.c
@@ -321,6 +321,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
int count;
int timeout;
+ /*
+ * There cannot be two concurrent aio_poll calls for the same AioContext (or
+ * an aio_poll concurrent with a GSource prepare/check/dispatch callback).
+ * We rely on this below to avoid slow locked accesses to ctx->notify_me.
+ */
+ assert(in_aio_context_home_thread(ctx));
progress = false;
/* aio_notify can avoid the expensive event_notifier_set if
@@ -331,7 +337,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
* so disable the optimization now.
*/
if (blocking) {
- atomic_add(&ctx->notify_me, 2);
+ atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2);
+ /*
+ * Write ctx->notify_me before computing the timeout
+ * (reading bottom half flags, etc.). Pairs with
+ * smp_mb in aio_notify().
+ */
+ smp_mb();
}
qemu_lockcnt_inc(&ctx->list_lock);
@@ -364,8 +376,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
ret = WaitForMultipleObjects(count, events, FALSE, timeout);
if (blocking) {
assert(first);
- assert(in_aio_context_home_thread(ctx));
- atomic_sub(&ctx->notify_me, 2);
+ atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2);
aio_notify_accept(ctx);
}
diff --git a/util/async.c b/util/async.c
index afc17fb3..12b33204 100644
--- a/util/async.c
+++ b/util/async.c
@@ -221,7 +221,14 @@ aio_ctx_prepare(GSource *source, gint *timeout)
{
AioContext *ctx = (AioContext *) source;
- atomic_or(&ctx->notify_me, 1);
+ atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) | 1);
+
+ /*
+ * Write ctx->notify_me before computing the timeout
+ * (reading bottom half flags, etc.). Pairs with
+ * smp_mb in aio_notify().
+ */
+ smp_mb();
/* We assume there is no timeout already supplied */
*timeout = qemu_timeout_ns_to_ms(aio_compute_timeout(ctx));
@@ -239,7 +246,8 @@ aio_ctx_check(GSource *source)
AioContext *ctx = (AioContext *) source;
QEMUBH *bh;
- atomic_and(&ctx->notify_me, ~1);
+ /* Finish computing the timeout before clearing the flag. */
+ atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) & ~1);
aio_notify_accept(ctx);
for (bh = ctx->first_bh; bh; bh = bh->next) {
@@ -344,10 +352,10 @@ LinuxAioState *aio_get_linux_aio(AioContext *ctx)
void aio_notify(AioContext *ctx)
{
/* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs
- * with atomic_or in aio_ctx_prepare or atomic_add in aio_poll.
+ * with smp_mb in aio_ctx_prepare or aio_poll.
*/
smp_mb();
- if (ctx->notify_me) {
+ if (atomic_read(&ctx->notify_me)) {
event_notifier_set(&ctx->notifier);
atomic_mb_set(&ctx->notified, true);
}
--
2.25.2

View File

@ -1,53 +0,0 @@
From 9557ba506470517668ffecb4d5ef4804eca4fd88 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 18 Nov 2020 10:22:32 +0800
Subject: [PATCH] ati: check x y display parameter values
fix CVE-2020-24352
The source and destination x,y display parameters in ati_2d_blt()
may run off the vga limits if either of s->regs.[src|dst]_[xy] is
zero. Check the parameter values to avoid potential crash.
Reported-by: Gaoning Pan <pgn@zju.edu.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 20201021103818.1704030-1-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
cherry-pick from commit ca1f9cbfdce4d63b10d57de80fef89a89d92a540
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
---
hw/display/ati_2d.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 23a8ae0cd8..4dc10ea795 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -75,8 +75,9 @@ void ati_2d_blt(ATIVGAState *s)
dst_stride *= bpp;
}
uint8_t *end = s->vga.vram_ptr + s->vga.vram_size;
- if (dst_bits >= end || dst_bits + dst_x + (dst_y + s->regs.dst_height) *
- dst_stride >= end) {
+ if (dst_x > 0x3fff || dst_y > 0x3fff || dst_bits >= end
+ || dst_bits + dst_x
+ + (dst_y + s->regs.dst_height) * dst_stride >= end) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return;
}
@@ -107,8 +108,9 @@ void ati_2d_blt(ATIVGAState *s)
src_bits += s->regs.crtc_offset & 0x07ffffff;
src_stride *= bpp;
}
- if (src_bits >= end || src_bits + src_x +
- (src_y + s->regs.dst_height) * src_stride >= end) {
+ if (src_x > 0x3fff || src_y > 0x3fff || src_bits >= end
+ || src_bits + src_x
+ + (src_y + s->regs.dst_height) * src_stride >= end) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return;
}
--
2.27.0

View File

@ -1,198 +0,0 @@
From 1ebe0e71d04bfdc76777a3a672e873f006d207e2 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 5 Feb 2021 10:38:24 +0800
Subject: [PATCH] ati: use vga_read_byte in ati_cursor_define
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
fix CVE-2019-20808
This makes sure reads are confined to vga video memory.
v3: use uint32_t, fix cut+paste bug.
v2: fix ati_cursor_draw_line too.
Reported-by: xu hang <flier_m@outlook.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190917111441.27405-3-kraxel@redhat.com
cherry-pick from aab0e2a661b2b6bf7915c0aefe807fb60d6d9d13
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
---
hw/display/ati.c | 21 ++++++++---------
hw/display/vga-access.h | 49 ++++++++++++++++++++++++++++++++++++++++
hw/display/vga-helpers.h | 27 +---------------------
3 files changed, 60 insertions(+), 37 deletions(-)
create mode 100644 hw/display/vga-access.h
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 5943040416..b17569874e 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "ati_int.h"
#include "ati_regs.h"
+#include "vga-access.h"
#include "vga_regs.h"
#include "qemu/log.h"
#include "qemu/module.h"
@@ -125,20 +126,19 @@ static void ati_vga_switch_mode(ATIVGAState *s)
static void ati_cursor_define(ATIVGAState *s)
{
uint8_t data[1024];
- uint8_t *src;
+ uint32_t srcoff;
int i, j, idx = 0;
if ((s->regs.cur_offset & BIT(31)) || s->cursor_guest_mode) {
return; /* Do not update cursor if locked or rendered by guest */
}
/* FIXME handle cur_hv_offs correctly */
- src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
- s->regs.cur_offset - (s->regs.cur_hv_offs >> 16) -
- (s->regs.cur_hv_offs & 0xffff) * 16;
+ srcoff = s->regs.cur_offset -
+ (s->regs.cur_hv_offs >> 16) - (s->regs.cur_hv_offs & 0xffff) * 16;
for (i = 0; i < 64; i++) {
for (j = 0; j < 8; j++, idx++) {
- data[idx] = src[i * 16 + j];
- data[512 + idx] = src[i * 16 + j + 8];
+ data[idx] = vga_read_byte(&s->vga, srcoff + i * 16 + j);
+ data[512 + idx] = vga_read_byte(&s->vga, srcoff + i * 16 + j + 8);
}
}
if (!s->cursor) {
@@ -180,7 +180,7 @@ static void ati_cursor_invalidate(VGACommonState *vga)
static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
{
ATIVGAState *s = container_of(vga, ATIVGAState, vga);
- uint8_t *src;
+ uint32_t srcoff;
uint32_t *dp = (uint32_t *)d;
int i, j, h;
@@ -190,14 +190,13 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
return;
}
/* FIXME handle cur_hv_offs correctly */
- src = s->vga.vram_ptr + (s->regs.crtc_offset & 0x07ffffff) +
- s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
+ srcoff = s->cursor_offset + (scr_y - vga->hw_cursor_y) * 16;
dp = &dp[vga->hw_cursor_x];
h = ((s->regs.crtc_h_total_disp >> 16) + 1) * 8;
for (i = 0; i < 8; i++) {
uint32_t color;
- uint8_t abits = src[i];
- uint8_t xbits = src[i + 8];
+ uint8_t abits = vga_read_byte(vga, srcoff + i);
+ uint8_t xbits = vga_read_byte(vga, srcoff + i + 8);
for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1) {
if (abits & BIT(7)) {
if (xbits & BIT(7)) {
diff --git a/hw/display/vga-access.h b/hw/display/vga-access.h
new file mode 100644
index 0000000000..c0fbd9958b
--- /dev/null
+++ b/hw/display/vga-access.h
@@ -0,0 +1,49 @@
+/*
+ * QEMU VGA Emulator templates
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
+{
+ return vga->vram_ptr[addr & vga->vbe_size_mask];
+}
+
+static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
+{
+ uint32_t offset = addr & vga->vbe_size_mask & ~1;
+ uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
+ return lduw_le_p(ptr);
+}
+
+static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
+{
+ uint32_t offset = addr & vga->vbe_size_mask & ~1;
+ uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
+ return lduw_be_p(ptr);
+}
+
+static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
+{
+ uint32_t offset = addr & vga->vbe_size_mask & ~3;
+ uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
+ return ldl_le_p(ptr);
+}
diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h
index 5a752b3f9e..5b6c02faa6 100644
--- a/hw/display/vga-helpers.h
+++ b/hw/display/vga-helpers.h
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "vga-access.h"
static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
uint32_t xorcol, uint32_t bgcol)
@@ -95,32 +96,6 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
} while (--h);
}
-static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
-{
- return vga->vram_ptr[addr & vga->vbe_size_mask];
-}
-
-static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
-{
- uint32_t offset = addr & vga->vbe_size_mask & ~1;
- uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
- return lduw_le_p(ptr);
-}
-
-static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
-{
- uint32_t offset = addr & vga->vbe_size_mask & ~1;
- uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
- return lduw_be_p(ptr);
-}
-
-static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
-{
- uint32_t offset = addr & vga->vbe_size_mask & ~3;
- uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
- return ldl_le_p(ptr);
-}
-
/*
* 4 color mode
*/
--
2.27.0

View File

@ -1,91 +0,0 @@
From ac2071c3791b67fc7af78b8ceb320c01ca1b5df7 Mon Sep 17 00:00:00 2001
From: BALATON Zoltan <balaton@eik.bme.hu>
Date: Mon, 6 Apr 2020 22:34:26 +0200
Subject: [PATCH] ati-vga: Fix checks in ati_2d_blt() to avoid crash
In some corner cases (that never happen during normal operation but a
malicious guest could program wrong values) pixman functions were
called with parameters that result in a crash. Fix this and add more
checks to disallow such cases.
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-id: 20200406204029.19559747D5D@zero.eik.bme.hu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 42e82311eb..23a8ae0cd8 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -53,12 +53,20 @@ void ati_2d_blt(ATIVGAState *s)
s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds),
surface_bits_per_pixel(ds),
(s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
- int dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
- s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
- int dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
- s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
+ unsigned dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
+ s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
+ unsigned dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
int bpp = ati_bpp_from_datatype(s);
+ if (!bpp) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid bpp\n");
+ return;
+ }
int dst_stride = DEFAULT_CNTL ? s->regs.dst_pitch : s->regs.default_pitch;
+ if (!dst_stride) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Zero dest pitch\n");
+ return;
+ }
uint8_t *dst_bits = s->vga.vram_ptr + (DEFAULT_CNTL ?
s->regs.dst_offset : s->regs.default_offset);
@@ -82,12 +90,16 @@ void ati_2d_blt(ATIVGAState *s)
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
case ROP3_SRCCOPY:
{
- int src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
- s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
- int src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
- s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
+ unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
+ s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
+ unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
int src_stride = DEFAULT_CNTL ?
s->regs.src_pitch : s->regs.default_pitch;
+ if (!src_stride) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Zero source pitch\n");
+ return;
+ }
uint8_t *src_bits = s->vga.vram_ptr + (DEFAULT_CNTL ?
s->regs.src_offset : s->regs.default_offset);
@@ -137,8 +149,10 @@ void ati_2d_blt(ATIVGAState *s)
dst_y * surface_stride(ds),
s->regs.dst_height * surface_stride(ds));
}
- s->regs.dst_x += s->regs.dst_width;
- s->regs.dst_y += s->regs.dst_height;
+ s->regs.dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
+ dst_x + s->regs.dst_width : dst_x);
+ s->regs.dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ dst_y + s->regs.dst_height : dst_y);
break;
}
case ROP3_PATCOPY:
@@ -179,7 +193,8 @@ void ati_2d_blt(ATIVGAState *s)
dst_y * surface_stride(ds),
s->regs.dst_height * surface_stride(ds));
}
- s->regs.dst_y += s->regs.dst_height;
+ s->regs.dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
+ dst_y + s->regs.dst_height : dst_y);
break;
}
default:
--
2.23.0

View File

@ -1,59 +0,0 @@
From 89554d2f71d4c79c5d8e804d90d74f3985d7ded5 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Thu, 4 Jun 2020 14:38:30 +0530
Subject: [PATCH 3/9] ati-vga: check mm_index before recursive call
(CVE-2020-13800)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
While accessing VGA registers via ati_mm_read/write routines,
a guest may set 's->regs.mm_index' such that it leads to infinite
recursion. Check mm_index value to avoid such recursion. Log an
error message for wrong values.
Reported-by: Ren Ding <rding@gatech.edu>
Reported-by: Hanqing Zhao <hanqing@gatech.edu>
Reported-by: Yi Ren <c4tren@gmail.com>
Message-id: 20200604090830.33885-1-ppandit@redhat.com
Suggested-by: BALATON Zoltan <balaton@eik.bme.hu>
Suggested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/display/ati.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/hw/display/ati.c b/hw/display/ati.c
index a747c4cc98..5943040416 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -261,8 +261,11 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
if (idx <= s->vga.vram_size - size) {
val = ldn_le_p(s->vga.vram_ptr + idx, size);
}
- } else {
+ } else if (s->regs.mm_index > MM_DATA + 3) {
val = ati_mm_read(s, s->regs.mm_index + addr - MM_DATA, size);
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ati_mm_read: mm_index too small: %u\n", s->regs.mm_index);
}
break;
case BIOS_0_SCRATCH ... BUS_CNTL - 1:
@@ -472,8 +475,11 @@ static void ati_mm_write(void *opaque, hwaddr addr,
if (idx <= s->vga.vram_size - size) {
stn_le_p(s->vga.vram_ptr + idx, size, data);
}
- } else {
+ } else if (s->regs.mm_index > MM_DATA + 3) {
ati_mm_write(s, s->regs.mm_index + addr - MM_DATA, data, size);
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ati_mm_write: mm_index too small: %u\n", s->regs.mm_index);
}
break;
case BIOS_0_SCRATCH ... BUS_CNTL - 1:
--
2.25.1

View File

@ -1,37 +0,0 @@
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

@ -1,51 +0,0 @@
From 0b66aef5389d622434128fc7db9abd2cd4724b51 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 3 Jun 2020 16:03:19 +0100
Subject: [PATCH] backup: Improve error for bdrv_getlength() failure
RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <20200603160325.67506-6-kwolf@redhat.com>
Patchwork-id: 97103
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 05/11] backup: Improve error for bdrv_getlength() failure
Bugzilla: 1778593
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
bdrv_get_device_name() will be an empty string with modern management
tools that don't use -drive. Use bdrv_get_device_or_node_name() instead
so that the node name is used if the BlockBackend is anonymous.
While at it, start with upper case to make the message consistent with
the rest of the function.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-Id: <20200430142755.315494-3-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 58226634c4b02af7b10862f7fbd3610a344bfb7f)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
block/backup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index 8761f1f9a7..88354dcb32 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -613,8 +613,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
len = bdrv_getlength(bs);
if (len < 0) {
- error_setg_errno(errp, -len, "unable to get length for '%s'",
- bdrv_get_device_name(bs));
+ error_setg_errno(errp, -len, "Unable to get length for '%s'",
+ bdrv_get_device_or_node_name(bs));
goto error;
}
--
2.27.0

View File

@ -0,0 +1,23 @@
From 00c4115a1388ee72295b99fce1f6ad49bf761134 Mon Sep 17 00:00:00 2001
From: Yan Wang <wangyan122@huawei.com>
Date: Thu, 10 Feb 2022 17:08:08 +0800
Subject: [PATCH] bios-tables-test: Allow changes to q35/SSDT.dimmpxm file
List test/data/acpi/q35/SSDT.dimmpxm as the expected files allowed to
be changed in tests/qtest/bios-tables-test-allowed-diff.h
Signed-off-by: Yan Wang <wangyan122@huawei.com>
---
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..81148a604f 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/SSDT.dimmpxm",
--
2.27.0

View File

@ -0,0 +1,79 @@
From 8940f11a055da0a744d10b53cf999dea7967be25 Mon Sep 17 00:00:00 2001
From: Yan Wang <wangyan122@huawei.com>
Date: Thu, 10 Feb 2022 17:12:35 +0800
Subject: [PATCH] bios-tables-test: Update expected q35/SSDT.dimmpxm file
Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory
to update q35/SSDT.dimmpxm file. Also empty bios-tables-test-allowed-diff.h.
The disassembled differences between actual and expected SSDT.dimmpxm:
/*
* Intel ACPI Component Architecture
* AML/ASL+ Disassembler version 20210604 (64-bit version)
* Copyright (c) 2000 - 2021 Intel Corporation
*
* Disassembling to symbolic ASL+ operators
*
- * Disassembly of tests/data/acpi/q35/SSDT.dimmpxm, Thu Feb 10 15:03:52 2022
+ * Disassembly of /tmp/aml-CK68G1, Thu Feb 10 15:03:52 2022
*
* Original Table Header:
* Signature "SSDT"
* Length 0x000002DE (734)
* Revision 0x01
- * Checksum 0x06
+ * Checksum 0x16
* OEM ID "BOCHS "
* OEM Table ID "NVDIMM "
* OEM Revision 0x00000001 (1)
* Compiler ID "BXPC"
* Compiler Version 0x00000001 (1)
*/
DefinitionBlock ("", "SSDT", 1, "BOCHS ", "NVDIMM ", 0x00000001)
{
Scope (\_SB)
{
Device (NVDR)
{
Name (_HID, "ACPI0012" /* NVDIMM Root Device */) // _HID: Hardware ID
Method (NCAL, 5, Serialized)
{
Local6 = MEMA /* \MEMA */
@@ -187,19 +187,19 @@
{
Return (NCAL (Arg0, Arg1, Arg2, Arg3, 0x02))
}
}
Device (NV02)
{
Name (_ADR, 0x03) // _ADR: Address
Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method
{
Return (NCAL (Arg0, Arg1, Arg2, Arg3, 0x03))
}
}
}
}
- Name (MEMA, 0x07FFF000)
+ Name (MEMA, 0x07FFE000)
}
Signed-off-by: Yan Wang <wangyan122@huawei.com>
---
tests/data/acpi/q35/SSDT.dimmpxm | Bin 734 -> 734 bytes
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
2 files changed, 1 deletion(-)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index 81148a604f..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,2 +1 @@
/* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/SSDT.dimmpxm",
--
2.27.0

View File

@ -1,24 +0,0 @@
From 2892a4b1f7dfc75e06d0ce770d44a062b6334eb0 Mon Sep 17 00:00:00 2001
From: Ying Fang <fangying1@huawei.com>
Date: Wed, 15 Apr 2020 17:03:54 +0800
Subject: [PATCH] bios-tables-test: prepare to change ARM virt ACPI DSDT
We will change ARM virt ACPI DSDT table in order to add the cpufreq device,
which use ACPI CPPC to show CPU frequency info to guest.
Signed-off-by: Ying Fang <fangying1@huawei.com>
---
tests/bios-tables-test-allowed-diff.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
index dfb8523c..32a401ae 100644
--- a/tests/bios-tables-test-allowed-diff.h
+++ b/tests/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/virt/DSDT",
+"tests/data/acpi/virt/DSDT.memhp",
+"tests/data/acpi/virt/DSDT.numamem",
--
2.23.0

View File

@ -1,59 +0,0 @@
From d9b88f7e0d56feb4d7daa2506e2756fc48e975a1 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Fri, 1 Nov 2019 16:25:09 +0100
Subject: [PATCH] block: Add bdrv_co_get_self_request()
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20191101152510.11719-3-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit c28107e9e55b11cd35cf3dc2505e3e69d10dcf13)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/io.c | 18 ++++++++++++++++++
include/block/block_int.h | 1 +
2 files changed, 19 insertions(+)
diff --git a/block/io.c b/block/io.c
index d4ceaaa2ce..65b5102714 100644
--- a/block/io.c
+++ b/block/io.c
@@ -721,6 +721,24 @@ static bool is_request_serialising_and_aligned(BdrvTrackedRequest *req)
(req->bytes == req->overlap_bytes);
}
+/**
+ * Return the tracked request on @bs for the current coroutine, or
+ * NULL if there is none.
+ */
+BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
+{
+ BdrvTrackedRequest *req;
+ Coroutine *self = qemu_coroutine_self();
+
+ QLIST_FOREACH(req, &bs->tracked_requests, list) {
+ if (req->co == self) {
+ return req;
+ }
+ }
+
+ return NULL;
+}
+
/**
* Round a region to cluster boundaries
*/
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 4465b02242..05ee6b4866 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -964,6 +964,7 @@ void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self);
void bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align);
+BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs);
int get_tmp_filename(char *filename, int size);
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
--
2.23.0

View File

@ -1,7 +1,7 @@
From 3464a135565d718d0fedadd67081a0f76d81a9c6 Mon Sep 17 00:00:00 2001
From a58fda7b158441c645e143bf658d12914ffbc7b8 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 21 Jan 2021 15:46:50 +0800
Subject: [PATCH] block: Add error retry param setting
Subject: [PATCH 6/7] block: Add error retry param setting
Add "retry_interval" and "retry_timeout" parameter for drive and device
option. These parameter are valid only when werror/rerror=retry.
@ -10,6 +10,7 @@ eg. --drive file=image,rerror=retry,retry_interval=1000,retry_timeout=5000
Signed-off-by: Jiahui Cen <cenjiahui(a)huawei.com>
Signed-off-by: Ying Fang <fangying1(a)huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 13 +++++++--
blockdev.c | 50 ++++++++++++++++++++++++++++++++++
@ -19,10 +20,10 @@ Signed-off-by: Ying Fang <fangying1(a)huawei.com>
5 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 0fe99ffe52..2d812e2254 100644
index 37e21c473e..d3d90a95a5 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -31,9 +31,6 @@
@@ -35,9 +35,6 @@
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
@ -32,7 +33,7 @@ index 0fe99ffe52..2d812e2254 100644
typedef struct BlockBackendAioNotifier {
void (*attached_aio_context)(AioContext *new_context, void *opaque);
void (*detach_aio_context)(void *opaque);
@@ -1633,6 +1630,16 @@ void blk_drain_all(void)
@@ -1766,6 +1763,16 @@ void blk_drain_all(void)
bdrv_drain_all_end();
}
@ -50,10 +51,10 @@ index 0fe99ffe52..2d812e2254 100644
{
/* No timeout set, infinite retries. */
diff --git a/blockdev.c b/blockdev.c
index 0f49fd290e..99c92b96d2 100644
index 6f1981635b..10a73fa423 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -470,6 +470,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
@@ -480,6 +480,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
const char *buf;
int bdrv_flags = 0;
int on_read_error, on_write_error;
@ -61,7 +62,7 @@ index 0f49fd290e..99c92b96d2 100644
bool account_invalid, account_failed;
bool writethrough, read_only;
BlockBackend *blk;
@@ -565,6 +566,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
@@ -572,6 +573,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
}
}
@ -72,7 +73,7 @@ index 0f49fd290e..99c92b96d2 100644
if (snapshot) {
bdrv_flags |= BDRV_O_SNAPSHOT;
}
@@ -629,6 +634,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
@@ -635,6 +640,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
blk_set_enable_write_cache(blk, !writethrough);
blk_set_on_error(blk, on_read_error, on_write_error);
@ -84,7 +85,7 @@ index 0f49fd290e..99c92b96d2 100644
if (!monitor_add_blk(blk, id, errp)) {
blk_unref(blk);
@@ -754,6 +764,14 @@ QemuOptsList qemu_legacy_drive_opts = {
@@ -761,6 +771,14 @@ QemuOptsList qemu_legacy_drive_opts = {
.name = "werror",
.type = QEMU_OPT_STRING,
.help = "write error action",
@ -99,7 +100,7 @@ index 0f49fd290e..99c92b96d2 100644
},{
.name = "copy-on-read",
.type = QEMU_OPT_BOOL,
@@ -776,6 +794,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
@@ -783,6 +801,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
BlockInterfaceType type;
int max_devs, bus_id, unit_id, index;
const char *werror, *rerror;
@ -107,7 +108,7 @@ index 0f49fd290e..99c92b96d2 100644
bool read_only = false;
bool copy_on_read;
const char *filename;
@@ -992,6 +1011,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
@@ -990,6 +1009,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
qdict_put_str(bs_opts, "rerror", rerror);
}
@ -135,9 +136,9 @@ index 0f49fd290e..99c92b96d2 100644
+ }
+
/* Actual block device init: Functionality shared with blockdev-add */
blk = blockdev_init(filename, bs_opts, &local_err);
blk = blockdev_init(filename, bs_opts, errp);
bs_opts = NULL;
@@ -4593,6 +4635,14 @@ QemuOptsList qemu_common_drive_opts = {
@@ -3806,6 +3848,14 @@ QemuOptsList qemu_common_drive_opts = {
.name = "werror",
.type = QEMU_OPT_STRING,
.help = "write error action",
@ -153,10 +154,10 @@ index 0f49fd290e..99c92b96d2 100644
.name = BDRV_OPT_READ_ONLY,
.type = QEMU_OPT_BOOL,
diff --git a/hw/block/block.c b/hw/block/block.c
index bf56c7612b..56141940ca 100644
index d47ebf005a..26c0767552 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -134,6 +134,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
@@ -206,6 +206,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
blk_set_enable_write_cache(blk, wce);
blk_set_on_error(blk, rerror, werror);
@ -174,10 +175,10 @@ index bf56c7612b..56141940ca 100644
}
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 607539057a..d12603aabd 100644
index 5902c0440a..24fb7d77af 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -30,6 +30,8 @@ typedef struct BlockConf {
@@ -33,6 +33,8 @@ typedef struct BlockConf {
bool share_rw;
BlockdevOnError rerror;
BlockdevOnError werror;
@ -186,7 +187,7 @@ index 607539057a..d12603aabd 100644
} BlockConf;
static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -71,7 +73,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -79,7 +81,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \
BLOCKDEV_ON_ERROR_AUTO), \
DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \
@ -199,7 +200,7 @@ index 607539057a..d12603aabd 100644
/* Backend access helpers */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 58dde446ca..dc10e507ae 100644
index 56a403883d..887c19ff5d 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -25,6 +25,9 @@
@ -212,7 +213,7 @@ index 58dde446ca..dc10e507ae 100644
/* Callbacks for block device models */
typedef struct BlockDevOps {
/*
@@ -184,6 +187,8 @@ void blk_inc_in_flight(BlockBackend *blk);
@@ -198,6 +201,8 @@ void blk_inc_in_flight(BlockBackend *blk);
void blk_dec_in_flight(BlockBackend *blk);
void blk_drain(BlockBackend *blk);
void blk_drain_all(void);

View File

@ -1,24 +1,40 @@
From 6642b2c6fcad2e1099c61b56f4fe78f3180d005e Mon Sep 17 00:00:00 2001
From f329ec9bd971ba7776cadb57e7311bfb6da41060 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 18 Mar 2021 19:45:11 +0800
Subject: [PATCH] block: Add sanity check when setting retry parameters
Subject: [PATCH 9/9] block: Add sanity check when setting retry parameters
Add sanity check when setting retry parameters to avoid invalid retry
configuration.
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
hw/core/qdev-properties.c | 45 ++++++++++++++++++++++++++++++++++++
include/hw/block/block.h | 7 +++---
include/hw/qdev-properties.h | 8 +++++++
3 files changed, 57 insertions(+), 3 deletions(-)
hw/core/qdev-prop-internal.h | 2 ++
hw/core/qdev-properties-system.c | 45 +++++++++++++++++++++++++++++
hw/core/qdev-properties.c | 4 +--
include/hw/block/block.h | 7 +++--
include/hw/qdev-properties-system.h | 8 +++++
5 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 709f9e0f9d..2601091f8f 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -628,6 +628,51 @@ const PropertyInfo qdev_prop_blockdev_on_error = {
.set_default_value = set_default_value_enum,
diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index d7b77844fe..68b1b9d10c 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -22,6 +22,8 @@ void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp);
+void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp);
void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp);
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 6a6ff03be7..b93ed9b4dd 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -612,6 +612,51 @@ const PropertyInfo qdev_prop_blockdev_on_error = {
.set_default_value = qdev_propinfo_set_default_value_enum,
};
+static void set_retry_time(Object *obj, Visitor *v, const char *name,
@ -26,7 +42,7 @@ index 709f9e0f9d..2601091f8f 100644
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ int64_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t value, *ptr = object_field_prop_ptr(obj, prop);
+ Error *local_err = NULL;
+
+ if (dev->realized) {
@ -53,27 +69,49 @@ index 709f9e0f9d..2601091f8f 100644
+const PropertyInfo qdev_prop_blockdev_retry_interval = {
+ .name = "BlockdevRetryInterval",
+ .description = "Interval for retry error handling policy",
+ .get = get_int64,
+ .get = qdev_propinfo_get_int64,
+ .set = set_retry_time,
+ .set_default_value = set_default_value_int,
+ .set_default_value = qdev_propinfo_set_default_value_int,
+};
+
+const PropertyInfo qdev_prop_blockdev_retry_timeout = {
+ .name = "BlockdevRetryTimeout",
+ .description = "Timeout for retry error handling policy",
+ .get = get_int64,
+ .get = qdev_propinfo_get_int64,
+ .set = set_retry_time,
+ .set_default_value = set_default_value_int,
+ .set_default_value = qdev_propinfo_set_default_value_int,
+};
+
/* --- BIOS CHS translation */
QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index c34aac6ebc..2d5f662663 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -396,7 +396,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
visit_type_uint64(v, name, ptr, errp);
}
-static void get_int64(Object *obj, Visitor *v, const char *name,
+void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
Property *prop = opaque;
@@ -423,7 +423,7 @@ const PropertyInfo qdev_prop_uint64 = {
const PropertyInfo qdev_prop_int64 = {
.name = "int64",
- .get = get_int64,
+ .get = qdev_propinfo_get_int64,
.set = set_int64,
.set_default_value = qdev_propinfo_set_default_value_int,
};
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index d12603aabd..c5276fec0d 100644
index 24fb7d77af..282929e8f0 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -74,9 +74,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -82,9 +82,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
BLOCKDEV_ON_ERROR_AUTO), \
DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \
BLOCKDEV_ON_ERROR_AUTO), \
@ -87,12 +125,12 @@ index d12603aabd..c5276fec0d 100644
/* Backend access helpers */
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index a22a532eb8..d7742be3bc 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -26,6 +26,8 @@ extern const PropertyInfo qdev_prop_on_off_auto;
extern const PropertyInfo qdev_prop_compress_method;
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index 0ac327ae60..906a027676 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -9,6 +9,8 @@ extern const PropertyInfo qdev_prop_reserved_region;
extern const PropertyInfo qdev_prop_multifd_compression;
extern const PropertyInfo qdev_prop_losttickpolicy;
extern const PropertyInfo qdev_prop_blockdev_on_error;
+extern const PropertyInfo qdev_prop_blockdev_retry_interval;
@ -100,7 +138,7 @@ index a22a532eb8..d7742be3bc 100644
extern const PropertyInfo qdev_prop_bios_chs_trans;
extern const PropertyInfo qdev_prop_fdc_drive_type;
extern const PropertyInfo qdev_prop_drive;
@@ -215,6 +217,12 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
@@ -47,6 +49,12 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
#define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
BlockdevOnError)

View File

@ -1,35 +0,0 @@
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

@ -1,105 +0,0 @@
From e94c1625c0f8155740b1bb7b2c749df759e04526 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 10 Jun 2020 18:32:02 -0400
Subject: [PATCH] block: Call attention to truncation of long NBD exports
RH-Author: Eric Blake <eblake@redhat.com>
Message-id: <20200610183202.3780750-3-eblake@redhat.com>
Patchwork-id: 97495
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] block: Call attention to truncation of long NBD exports
Bugzilla: 1845384
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Commit 93676c88 relaxed our NBD client code to request export names up
to the NBD protocol maximum of 4096 bytes without NUL terminator, even
though the block layer can't store anything longer than 4096 bytes
including NUL terminator for display to the user. Since this means
there are some export names where we have to truncate things, we can
at least try to make the truncation a bit more obvious for the user.
Note that in spite of the truncated display name, we can still
communicate with an NBD server using such a long export name; this was
deemed nicer than refusing to even connect to such a server (since the
server may not be under our control, and since determining our actual
length limits gets tricky when nbd://host:port/export and
nbd+unix:///export?socket=/path are themselves variable-length
expansions beyond the export name but count towards the block layer
name length).
Reported-by: Xueqiang Wei <xuwei@redhat.com>
Fixes: https://bugzilla.redhat.com/1843684
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200610163741.3745251-3-eblake@redhat.com>
(cherry picked from commit 5c86bdf1208916ece0b87e1151c9b48ee54faa3e)
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
block.c | 7 +++++--
block/nbd.c | 21 +++++++++++++--------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/block.c b/block.c
index 38880eabf8..ba36b53a00 100644
--- a/block.c
+++ b/block.c
@@ -6444,8 +6444,11 @@ void bdrv_refresh_filename(BlockDriverState *bs)
pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
} else {
QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
- snprintf(bs->filename, sizeof(bs->filename), "json:%s",
- qstring_get_str(json));
+ if (snprintf(bs->filename, sizeof(bs->filename), "json:%s",
+ qstring_get_str(json)) >= sizeof(bs->filename)) {
+ /* Give user a hint if we truncated things. */
+ strcpy(bs->filename + sizeof(bs->filename) - 4, "...");
+ }
qobject_unref(json);
}
}
diff --git a/block/nbd.c b/block/nbd.c
index 3977b1efc7..63cdd051ab 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -1714,6 +1714,7 @@ static void nbd_refresh_filename(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
const char *host = NULL, *port = NULL, *path = NULL;
+ size_t len = 0;
if (s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
const InetSocketAddress *inet = &s->saddr->u.inet;
@@ -1726,17 +1727,21 @@ static void nbd_refresh_filename(BlockDriverState *bs)
} /* else can't represent as pseudo-filename */
if (path && s->export) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd+unix:///%s?socket=%s", s->export, path);
+ len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+ "nbd+unix:///%s?socket=%s", s->export, path);
} else if (path && !s->export) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd+unix://?socket=%s", path);
+ len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+ "nbd+unix://?socket=%s", path);
} else if (host && s->export) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd://%s:%s/%s", host, port, s->export);
+ len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+ "nbd://%s:%s/%s", host, port, s->export);
} else if (host && !s->export) {
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
- "nbd://%s:%s", host, port);
+ len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+ "nbd://%s:%s", host, port);
+ }
+ if (len > sizeof(bs->exact_filename)) {
+ /* Name is too long to represent exactly, so leave it empty. */
+ bs->exact_filename[0] = '\0';
}
}
--
2.27.0

View File

@ -1,78 +0,0 @@
From ec96b9f64c239736003413d70dc3999ad0b8271c Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 10 Mar 2020 12:38:29 +0100
Subject: [PATCH] block: Fix cross-AioContext blockdev-snapshot
external_snapshot_prepare() tries to move the overlay to the AioContext
of the backing file (the snapshotted node). However, it's possible that
this doesn't work, but the backing file can instead be moved to the
overlay's AioContext (e.g. opening the backing chain for a mirror
target).
bdrv_append() already indirectly uses bdrv_attach_node(), which takes
care to move nodes to make sure they use the same AioContext and which
tries both directions.
So the problem has a simple fix: Just delete the unnecessary extra
bdrv_try_set_aio_context() call in external_snapshot_prepare() and
instead assert in bdrv_append() that both nodes were indeed moved to the
same AioContext.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200310113831.27293-6-kwolf@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 1 +
blockdev.c | 16 ----------------
2 files changed, 1 insertion(+), 16 deletions(-)
diff --git a/block.c b/block.c
index ba36b53a00..824025f781 100644
--- a/block.c
+++ b/block.c
@@ -4165,6 +4165,7 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
bdrv_ref(from);
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
+ assert(bdrv_get_aio_context(from) == bdrv_get_aio_context(to));
bdrv_drained_begin(from);
/* Put all parents into @list and calculate their cumulative permissions */
diff --git a/blockdev.c b/blockdev.c
index 79112be2e6..d1a3b6a630 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1578,8 +1578,6 @@ static void external_snapshot_prepare(BlkActionState *common,
DO_UPCAST(ExternalSnapshotState, common, common);
TransactionAction *action = common->action;
AioContext *aio_context;
- AioContext *old_context;
- int ret;
/* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
* purpose but a different set of parameters */
@@ -1719,20 +1717,6 @@ static void external_snapshot_prepare(BlkActionState *common,
goto out;
}
- /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
- old_context = bdrv_get_aio_context(state->new_bs);
- aio_context_release(aio_context);
- aio_context_acquire(old_context);
-
- ret = bdrv_try_set_aio_context(state->new_bs, aio_context, errp);
-
- aio_context_release(old_context);
- aio_context_acquire(aio_context);
-
- if (ret < 0) {
- goto out;
- }
-
/* This removes our old bs and adds the new bs. This is an operation that
* can fail, so we need to do it in .prepare; undoing it for abort is
* always possible. */
--
2.27.0

View File

@ -1,131 +0,0 @@
From 590cff8230749794ba09b38f3ea4eb6b0f2f73b5 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Fri, 1 Nov 2019 16:25:08 +0100
Subject: [PATCH] block: Make wait/mark serialising requests public
Make both bdrv_mark_request_serialising() and
bdrv_wait_serialising_requests() public so they can be used from block
drivers.
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20191101152510.11719-2-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 304d9d7f034ff7f5e1e66a65b7f720f63a72c57e)
Conflicts:
block/io.c
*drop context dependency on 1acc3466a2
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/io.c | 24 ++++++++++++------------
include/block/block_int.h | 3 +++
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/block/io.c b/block/io.c
index 07d2d825c3..d4ceaaa2ce 100644
--- a/block/io.c
+++ b/block/io.c
@@ -694,7 +694,7 @@ static void tracked_request_begin(BdrvTrackedRequest *req,
qemu_co_mutex_unlock(&bs->reqs_lock);
}
-static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
+void bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
{
int64_t overlap_offset = req->offset & ~(align - 1);
uint64_t overlap_bytes = ROUND_UP(req->offset + req->bytes, align)
@@ -784,7 +784,7 @@ void bdrv_dec_in_flight(BlockDriverState *bs)
bdrv_wakeup(bs);
}
-static bool coroutine_fn wait_serialising_requests(BdrvTrackedRequest *self)
+bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self)
{
BlockDriverState *bs = self->bs;
BdrvTrackedRequest *req;
@@ -1340,14 +1340,14 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
* with each other for the same cluster. For example, in copy-on-read
* it ensures that the CoR read and write operations are atomic and
* guest writes cannot interleave between them. */
- mark_request_serialising(req, bdrv_get_cluster_size(bs));
+ bdrv_mark_request_serialising(req, bdrv_get_cluster_size(bs));
}
/* BDRV_REQ_SERIALISING is only for write operation */
assert(!(flags & BDRV_REQ_SERIALISING));
if (!(flags & BDRV_REQ_NO_SERIALISING)) {
- wait_serialising_requests(req);
+ bdrv_wait_serialising_requests(req);
}
if (flags & BDRV_REQ_COPY_ON_READ) {
@@ -1736,10 +1736,10 @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, uint64_t bytes,
assert(!(flags & ~BDRV_REQ_MASK));
if (flags & BDRV_REQ_SERIALISING) {
- mark_request_serialising(req, bdrv_get_cluster_size(bs));
+ bdrv_mark_request_serialising(req, bdrv_get_cluster_size(bs));
}
- waited = wait_serialising_requests(req);
+ waited = bdrv_wait_serialising_requests(req);
assert(!waited || !req->serialising ||
is_request_serialising_and_aligned(req));
@@ -1905,8 +1905,8 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
padding = bdrv_init_padding(bs, offset, bytes, &pad);
if (padding) {
- mark_request_serialising(req, align);
- wait_serialising_requests(req);
+ bdrv_mark_request_serialising(req, align);
+ bdrv_wait_serialising_requests(req);
bdrv_padding_rmw_read(child, req, &pad, true);
@@ -1993,8 +1993,8 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
}
if (bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad)) {
- mark_request_serialising(&req, align);
- wait_serialising_requests(&req);
+ bdrv_mark_request_serialising(&req, align);
+ bdrv_wait_serialising_requests(&req);
bdrv_padding_rmw_read(child, &req, &pad, false);
}
@@ -3078,7 +3078,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
/* BDRV_REQ_SERIALISING is only for write operation */
assert(!(read_flags & BDRV_REQ_SERIALISING));
if (!(read_flags & BDRV_REQ_NO_SERIALISING)) {
- wait_serialising_requests(&req);
+ bdrv_wait_serialising_requests(&req);
}
ret = src->bs->drv->bdrv_co_copy_range_from(src->bs,
@@ -3205,7 +3205,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset,
* new area, we need to make sure that no write requests are made to it
* concurrently or they might be overwritten by preallocation. */
if (new_bytes) {
- mark_request_serialising(&req, 1);
+ bdrv_mark_request_serialising(&req, 1);
}
if (bs->read_only) {
error_setg(errp, "Image is read-only");
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 3aa1e832a8..4465b02242 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -962,6 +962,9 @@ extern unsigned int bdrv_drain_all_count;
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
+bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self);
+void bdrv_mark_request_serialising(BdrvTrackedRequest *req, uint64_t align);
+
int get_tmp_filename(char *filename, int size);
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
const char *filename);
--
2.23.0

View File

@ -1,31 +0,0 @@
From b353d059bddf4b211c2560e7c123f874ed5c8cf6 Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Wed, 21 Oct 2020 17:12:52 +0800
Subject: [PATCH] block: Remove unused include
The "qemu-common.h" include is not used, remove it.
Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
Message-Id: <5F8FFB94.3030209@huawei.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry-picked from commit 3d86af858e)
---
block/dmg-lzfse.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/block/dmg-lzfse.c b/block/dmg-lzfse.c
index 19d25bc646..6798cf4fbf 100644
--- a/block/dmg-lzfse.c
+++ b/block/dmg-lzfse.c
@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "dmg.h"
#include <lzfse.h>
--
2.27.0

View File

@ -1,7 +1,7 @@
From f74edc7c8c85874691daf8801c159874ef45aae0 Mon Sep 17 00:00:00 2001
From dfda8c57de71f2f10b57cf21b1e36f18d4ed37a3 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 21 Jan 2021 15:46:47 +0800
Subject: [PATCH] block-backend: Add device specific retry callback
Subject: [PATCH 3/7] block-backend: Add device specific retry callback
Add retry_request_cb in BlockDevOps to do device specific retry action.
Backend's timer would be registered only when the backend is set 'retry'
@ -9,16 +9,17 @@ on errors and the device supports retry action.
Signed-off-by: Jiahui Cen <cenjiahui(a)huawei.com>
Signed-off-by: Ying Fang <fangying1(a)huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 8 ++++++++
include/sysemu/block-backend.h | 4 ++++
2 files changed, 12 insertions(+)
diff --git a/block/block-backend.c b/block/block-backend.c
index a9a43b1440..b8f535a5fd 100644
index 257cd775c0..24003adf0b 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -958,6 +958,14 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
@@ -1018,6 +1018,14 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
blk->dev_ops = ops;
blk->dev_opaque = opaque;
@ -34,13 +35,13 @@ index a9a43b1440..b8f535a5fd 100644
if (blk->quiesce_counter && ops->drained_begin) {
ops->drained_begin(opaque);
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 733c4957eb..b58dc6bde8 100644
index e5e1524f06..a7a13d47de 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -66,6 +66,10 @@ typedef struct BlockDevOps {
* Runs when the backend's last drain request ends.
@@ -70,6 +70,10 @@ typedef struct BlockDevOps {
* Is the device still busy?
*/
void (*drained_end)(void *opaque);
bool (*drained_poll)(void *opaque);
+ /*
+ * Runs when retrying failed requests.
+ */

View File

@ -1,7 +1,7 @@
From c58269c64af18bc2a22bbef8b92e489214272429 Mon Sep 17 00:00:00 2001
From 953590f4854d75e6051237f668c9fb393235f471 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 21 Jan 2021 15:46:49 +0800
Subject: [PATCH] block-backend: Add timeout support for retry
Subject: [PATCH 5/7] block-backend: Add timeout support for retry
Retry should only be triggered when timeout is not reached, so let's check
timeout before retry. Device should also reset retry_start_time after
@ -9,16 +9,17 @@ successful retry.
Signed-off-by: Jiahui Cen <cenjiahui(a)huawei.com>
Signed-off-by: Ying Fang <fangying1(a)huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 25 ++++++++++++++++++++++++-
include/sysemu/block-backend.h | 1 +
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 11f8ff4301..0fe99ffe52 100644
index 5a016d32fa..37e21c473e 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1633,6 +1633,29 @@ void blk_drain_all(void)
@@ -1766,6 +1766,29 @@ void blk_drain_all(void)
bdrv_drain_all_end();
}
@ -48,7 +49,7 @@ index 11f8ff4301..0fe99ffe52 100644
void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
BlockdevOnError on_write_error)
{
@@ -1661,7 +1684,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
@@ -1794,7 +1817,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
case BLOCKDEV_ON_ERROR_IGNORE:
return BLOCK_ERROR_ACTION_IGNORE;
case BLOCKDEV_ON_ERROR_RETRY:
@ -58,10 +59,10 @@ index 11f8ff4301..0fe99ffe52 100644
case BLOCKDEV_ON_ERROR_AUTO:
default:
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index b58dc6bde8..58dde446ca 100644
index a7a13d47de..56a403883d 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -184,6 +184,7 @@ void blk_inc_in_flight(BlockBackend *blk);
@@ -198,6 +198,7 @@ void blk_inc_in_flight(BlockBackend *blk);
void blk_dec_in_flight(BlockBackend *blk);
void blk_drain(BlockBackend *blk);
void blk_drain_all(void);

View File

@ -1,22 +1,23 @@
From 8df36cddd1e5e2b3c3598c83a70e8cbb81c26cec Mon Sep 17 00:00:00 2001
From 2e1c75e5a0339d2bf417e5a4437d8e627a303286 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 21 Jan 2021 15:46:48 +0800
Subject: [PATCH] block-backend: Enable retry action on errors
Subject: [PATCH 4/7] block-backend: Enable retry action on errors
Enable retry action when backend's retry timer is available. It would
trigger the timer to do device specific retry action.
Signed-off-by: Jiahui Cen <cenjiahui(a)huawei.com>
Signed-off-by: Ying Fang <fangying1(a)huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/block/block-backend.c b/block/block-backend.c
index b8f535a5fd..11f8ff4301 100644
index 24003adf0b..5a016d32fa 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1660,6 +1660,9 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
@@ -1793,6 +1793,9 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
return BLOCK_ERROR_ACTION_REPORT;
case BLOCKDEV_ON_ERROR_IGNORE:
return BLOCK_ERROR_ACTION_IGNORE;
@ -26,7 +27,7 @@ index b8f535a5fd..11f8ff4301 100644
case BLOCKDEV_ON_ERROR_AUTO:
default:
abort();
@@ -1707,6 +1710,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
@@ -1840,6 +1843,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
qemu_system_vmstop_request_prepare();
send_qmp_error_event(blk, action, is_read, error);
qemu_system_vmstop_request(RUN_STATE_IO_ERROR);

View File

@ -1,21 +1,22 @@
From 805c2e121e1ad612f63bafec458284554e76d034 Mon Sep 17 00:00:00 2001
From 4dc180e87fb641f64fce7be3a0807488d0cc0a51 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 21 Jan 2021 15:46:46 +0800
Subject: [PATCH] block-backend: Introduce retry timer
Subject: [PATCH 2/7] block-backend: Introduce retry timer
Add a timer to regularly trigger retry on errors.
Signed-off-by: Jiahui Cen <cenjiahui(a)huawei.com>
Signed-off-by: Ying Fang <fangying1(a)huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/block/block-backend.c b/block/block-backend.c
index 0056b526b8..a9a43b1440 100644
index 12ef80ea17..257cd775c0 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -31,6 +31,9 @@
@@ -35,6 +35,9 @@
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
@ -25,7 +26,7 @@ index 0056b526b8..a9a43b1440 100644
typedef struct BlockBackendAioNotifier {
void (*attached_aio_context)(AioContext *new_context, void *opaque);
void (*detach_aio_context)(void *opaque);
@@ -88,6 +91,15 @@ struct BlockBackend {
@@ -95,6 +98,15 @@ struct BlockBackend {
* Accessed with atomic ops.
*/
unsigned int in_flight;
@ -41,7 +42,7 @@ index 0056b526b8..a9a43b1440 100644
};
typedef struct BlockBackendAIOCB {
@@ -337,6 +349,11 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
@@ -353,6 +365,11 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT;
blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
@ -52,8 +53,8 @@ index 0056b526b8..a9a43b1440 100644
+
block_acct_init(&blk->stats);
notifier_list_init(&blk->remove_bs_notifiers);
@@ -423,6 +440,10 @@ static void blk_delete(BlockBackend *blk)
qemu_co_queue_init(&blk->queued_requests);
@@ -471,6 +488,10 @@ static void blk_delete(BlockBackend *blk)
QTAILQ_REMOVE(&block_backends, blk, link);
drive_info_del(blk->legacy_dinfo);
block_acct_cleanup(&blk->stats);

View File

@ -1,7 +1,7 @@
From da64af4b1e92c345296d937e66136f86027d1ca2 Mon Sep 17 00:00:00 2001
From 06db37983cfd20d7e92001ac3cb06867a281f1c9 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 25 Feb 2021 18:03:57 +0800
Subject: [PATCH] block-backend: Stop retrying when draining
Subject: [PATCH 8/9] block-backend: Stop retrying when draining
Retrying failed requests when draining would make the draining hung. So it
is better not to trigger the retry timer when draining. And after the
@ -9,15 +9,16 @@ virtual devices go back to work, they would retry those queued requests.
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
Signed-off-by: Ying Fang <fangying1@huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 2d812e2254..f6c918f1d9 100644
index d3d90a95a5..49d236b2a4 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1741,9 +1741,11 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
@@ -1874,9 +1874,11 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
send_qmp_error_event(blk, action, is_read, error);
qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
} else if (action == BLOCK_ERROR_ACTION_RETRY) {

View File

@ -1,252 +0,0 @@
From e0a0150e671e8129f11aa3df907e444e91711f53 Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Mon, 29 Jul 2019 16:35:52 -0400
Subject: [PATCH] block/backup: Add mirror sync mode 'bitmap'
We don't need or want a new sync mode for simple differences in
semantics. Create a new mode simply named "BITMAP" that is designed to
make use of the new Bitmap Sync Mode field.
Because the only bitmap sync mode is 'on-success', this adds no new
functionality to the backup job (yet). The old incremental backup mode
is maintained as a syntactic sugar for sync=bitmap, mode=on-success.
Add all of the plumbing necessary to support this new instruction.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190709232550.10724-6-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
---
block/backup.c | 20 ++++++++++++--------
block/mirror.c | 6 ++++--
block/replication.c | 2 +-
blockdev.c | 25 +++++++++++++++++++++++--
include/block/block_int.h | 4 +++-
qapi/block-core.json | 21 +++++++++++++++------
6 files changed, 58 insertions(+), 20 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index 88354dcb32..e37eda80cd 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -38,9 +38,9 @@ typedef struct CowRequest {
typedef struct BackupBlockJob {
BlockJob common;
BlockBackend *target;
- /* bitmap for sync=incremental */
BdrvDirtyBitmap *sync_bitmap;
MirrorSyncMode sync_mode;
+ BitmapSyncMode bitmap_mode;
BlockdevOnError on_source_error;
BlockdevOnError on_target_error;
CoRwlock flush_rwlock;
@@ -461,7 +461,7 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
job_progress_set_remaining(job, s->len);
- if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
+ if (s->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
backup_incremental_init_copy_bitmap(s);
} else {
hbitmap_set(s->copy_bitmap, 0, s->len);
@@ -545,6 +545,7 @@ static int64_t backup_calculate_cluster_size(BlockDriverState *target,
BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockDriverState *target, int64_t speed,
MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
+ BitmapSyncMode bitmap_mode,
bool compress,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
@@ -592,10 +593,13 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
return NULL;
}
- if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
+ /* QMP interface should have handled translating this to bitmap mode */
+ assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
+
+ if (sync_mode == MIRROR_SYNC_MODE_BITMAP) {
if (!sync_bitmap) {
error_setg(errp, "must provide a valid bitmap name for "
- "\"incremental\" sync mode");
+ "'%s' sync mode", MirrorSyncMode_str(sync_mode));
return NULL;
}
@@ -605,8 +609,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
}
} else if (sync_bitmap) {
error_setg(errp,
- "a sync_bitmap was provided to backup_run, "
- "but received an incompatible sync_mode (%s)",
+ "a bitmap was given to backup_job_create, "
+ "but it received an incompatible sync_mode (%s)",
MirrorSyncMode_str(sync_mode));
return NULL;
}
@@ -648,8 +652,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
job->on_source_error = on_source_error;
job->on_target_error = on_target_error;
job->sync_mode = sync_mode;
- job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
- sync_bitmap : NULL;
+ job->sync_bitmap = sync_bitmap;
+ job->bitmap_mode = bitmap_mode;
job->compress = compress;
/* Detect image-fleecing (and similar) schemes */
diff --git a/block/mirror.c b/block/mirror.c
index abcf60a961..ccae49a28e 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1770,8 +1770,10 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
bool is_none_mode;
BlockDriverState *base;
- if (mode == MIRROR_SYNC_MODE_INCREMENTAL) {
- error_setg(errp, "Sync mode 'incremental' not supported");
+ if ((mode == MIRROR_SYNC_MODE_INCREMENTAL) ||
+ (mode == MIRROR_SYNC_MODE_BITMAP)) {
+ error_setg(errp, "Sync mode '%s' not supported",
+ MirrorSyncMode_str(mode));
return;
}
is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
diff --git a/block/replication.c b/block/replication.c
index 23b2993d74..936b2f8b5a 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -543,7 +543,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
s->backup_job = backup_job_create(
NULL, s->secondary_disk->bs, s->hidden_disk->bs,
- 0, MIRROR_SYNC_MODE_NONE, NULL, false,
+ 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false,
BLOCKDEV_ON_ERROR_REPORT,
BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
backup_job_completed, bs, NULL, &local_err);
diff --git a/blockdev.c b/blockdev.c
index aa15ed1f00..34c8b651e1 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3508,12 +3508,31 @@ static BlockJob *do_backup_common(BackupCommon *backup,
return NULL;
}
+ if (backup->sync == MIRROR_SYNC_MODE_INCREMENTAL) {
+ if (backup->has_bitmap_mode &&
+ backup->bitmap_mode != BITMAP_SYNC_MODE_ON_SUCCESS) {
+ error_setg(errp, "Bitmap sync mode must be '%s' "
+ "when using sync mode '%s'",
+ BitmapSyncMode_str(BITMAP_SYNC_MODE_ON_SUCCESS),
+ MirrorSyncMode_str(backup->sync));
+ return NULL;
+ }
+ backup->has_bitmap_mode = true;
+ backup->sync = MIRROR_SYNC_MODE_BITMAP;
+ backup->bitmap_mode = BITMAP_SYNC_MODE_ON_SUCCESS;
+ }
+
if (backup->has_bitmap) {
bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
if (!bmap) {
error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
return NULL;
}
+ if (!backup->has_bitmap_mode) {
+ error_setg(errp, "Bitmap sync mode must be given "
+ "when providing a bitmap");
+ return NULL;
+ }
if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
return NULL;
}
@@ -3527,8 +3546,10 @@ static BlockJob *do_backup_common(BackupCommon *backup,
}
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
- backup->sync, bmap, backup->compress,
- backup->on_source_error, backup->on_target_error,
+ backup->sync, bmap, backup->bitmap_mode,
+ backup->compress,
+ backup->on_source_error,
+ backup->on_target_error,
job_flags, NULL, NULL, txn, errp);
return job;
}
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 05ee6b4866..76117a761a 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1152,7 +1152,8 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
* @target: Block device to write to.
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
* @sync_mode: What parts of the disk image should be copied to the destination.
- * @sync_bitmap: The dirty bitmap if sync_mode is MIRROR_SYNC_MODE_INCREMENTAL.
+ * @sync_bitmap: The dirty bitmap if sync_mode is 'bitmap' or 'incremental'
+ * @bitmap_mode: The bitmap synchronization policy to use.
* @on_source_error: The action to take upon error reading from the source.
* @on_target_error: The action to take upon error writing to the target.
* @creation_flags: Flags that control the behavior of the Job lifetime.
@@ -1168,6 +1169,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockDriverState *target, int64_t speed,
MirrorSyncMode sync_mode,
BdrvDirtyBitmap *sync_bitmap,
+ BitmapSyncMode bitmap_mode,
bool compress,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index b8d12a4951..97baff3a8c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1127,12 +1127,15 @@
#
# @none: only copy data written from now on
#
-# @incremental: only copy data described by the dirty bitmap. Since: 2.4
+# @incremental: only copy data described by the dirty bitmap. (since: 2.4)
+#
+# @bitmap: only copy data described by the dirty bitmap. (since: 4.2)
+# Behavior on completion is determined by the BitmapSyncMode.
#
# Since: 1.3
##
{ 'enum': 'MirrorSyncMode',
- 'data': ['top', 'full', 'none', 'incremental'] }
+ 'data': ['top', 'full', 'none', 'incremental', 'bitmap'] }
##
# @BitmapSyncMode:
@@ -1343,9 +1346,14 @@
# @speed: the maximum speed, in bytes per second. The default is 0,
# for unlimited.
#
-# @bitmap: the name of dirty bitmap if sync is "incremental".
-# Must be present if sync is "incremental", must NOT be present
-# otherwise. (Since 2.4 (drive-backup), 3.1 (blockdev-backup))
+# @bitmap: the name of a dirty bitmap if sync is "bitmap" or "incremental".
+# Must be present if sync is "bitmap" or "incremental".
+# Must not be present otherwise.
+# (Since 2.4 (drive-backup), 3.1 (blockdev-backup))
+#
+# @bitmap-mode: Specifies the type of data the bitmap should contain after
+# the operation concludes. Must be present if sync is "bitmap".
+# Must NOT be present otherwise. (Since 4.2)
#
# @compress: true to compress data, if the target format supports it.
# (default: false) (since 2.8)
@@ -1380,7 +1388,8 @@
{ 'struct': 'BackupCommon',
'data': { '*job-id': 'str', 'device': 'str',
'sync': 'MirrorSyncMode', '*speed': 'int',
- '*bitmap': 'str', '*compress': 'bool',
+ '*bitmap': 'str', '*bitmap-mode': 'BitmapSyncMode',
+ '*compress': 'bool',
'*on-source-error': 'BlockdevOnError',
'*on-target-error': 'BlockdevOnError',
'*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
--
2.27.0

View File

@ -1,59 +0,0 @@
From 98ed0f915cf3335768ed84ee5dfa54f4e99aaf00 Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Mon, 29 Jul 2019 16:35:53 -0400
Subject: [PATCH] block/backup: add 'never' policy to bitmap sync mode
This adds a "never" policy for bitmap synchronization. Regardless of if
the job succeeds or fails, we never update the bitmap. This can be used
to perform differential backups, or simply to avoid the job modifying a
bitmap.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190709232550.10724-7-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
---
block/backup.c | 7 +++++--
qapi/block-core.json | 5 ++++-
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index e37eda80cd..84a56337ac 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -274,8 +274,11 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
BdrvDirtyBitmap *bm;
BlockDriverState *bs = blk_bs(job->common.blk);
- if (ret < 0) {
- /* Merge the successor back into the parent, delete nothing. */
+ if (ret < 0 || job->bitmap_mode == BITMAP_SYNC_MODE_NEVER) {
+ /*
+ * Failure, or we don't want to synchronize the bitmap.
+ * Merge the successor back into the parent, delete nothing.
+ */
bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
assert(bm);
} else {
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 97baff3a8c..48a0bfab63 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1146,10 +1146,13 @@
# @on-success: The bitmap is only synced when the operation is successful.
# This is the behavior always used for 'INCREMENTAL' backups.
#
+# @never: The bitmap is never synchronized with the operation, and is
+# treated solely as a read-only manifest of blocks to copy.
+#
# Since: 4.2
##
{ 'enum': 'BitmapSyncMode',
- 'data': ['on-success'] }
+ 'data': ['on-success', 'never'] }
##
# @MirrorCopyMode:
--
2.27.0

View File

@ -1,83 +0,0 @@
From 3cf14b9a7daf0a40eb2af7a86e67cb05f6d2bea6 Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Date: Tue, 30 Jul 2019 19:32:49 +0300
Subject: [PATCH] block/backup: deal with zero detection
We have detect_zeroes option, so at least for blockdev-backup user
should define it if zero-detection is needed. For drive-backup leave
detection enabled by default but do it through existing option instead
of open-coding.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190730163251.755248-2-vsementsov@virtuozzo.com
Signed-off-by: John Snow <jsnow@redhat.com>
---
block/backup.c | 15 ++++++---------
blockdev.c | 8 ++++----
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index cc19643b47..6023573299 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -110,7 +110,10 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
BlockBackend *blk = job->common.blk;
int nbytes;
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
- int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
+ int write_flags =
+ (job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0) |
+ (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
+
assert(QEMU_IS_ALIGNED(start, job->cluster_size));
hbitmap_reset(job->copy_bitmap, start, job->cluster_size);
@@ -128,14 +131,8 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
goto fail;
}
- if (buffer_is_zero(*bounce_buffer, nbytes)) {
- ret = blk_co_pwrite_zeroes(job->target, start,
- nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
- } else {
- ret = blk_co_pwrite(job->target, start,
- nbytes, *bounce_buffer, write_flags |
- (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
- }
+ ret = blk_co_pwrite(job->target, start, nbytes, *bounce_buffer,
+ write_flags);
if (ret < 0) {
trace_backup_do_cow_write_fail(job, start, ret);
if (error_is_read) {
diff --git a/blockdev.c b/blockdev.c
index 0a71a15fa2..94e5aee30b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3572,7 +3572,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
BlockDriverState *source = NULL;
BlockJob *job = NULL;
AioContext *aio_context;
- QDict *options = NULL;
+ QDict *options;
Error *local_err = NULL;
int flags;
int64_t size;
@@ -3645,10 +3645,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
goto out;
}
+ options = qdict_new();
+ qdict_put_str(options, "discard", "unmap");
+ qdict_put_str(options, "detect-zeroes", "unmap");
if (backup->format) {
- if (!options) {
- options = qdict_new();
- }
qdict_put_str(options, "driver", backup->format);
}
--
2.27.0

View File

@ -1,35 +0,0 @@
From adb934c8d2cfd8b920e69712f07a8fb9399fdc2d Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Date: Fri, 20 Sep 2019 17:20:43 +0300
Subject: [PATCH] block/backup: fix backup_cow_with_offload for last cluster
We shouldn't try to copy bytes beyond EOF. Fix it.
Fixes: 9ded4a0114968e
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 20190920142056.12778-3-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 1048ddf0a32dcdaa952e581bd503d49adad527cc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/backup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/backup.c b/block/backup.c
index 8119d3c..55736ea 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -169,7 +169,7 @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
assert(QEMU_IS_ALIGNED(start, job->cluster_size));
- nbytes = MIN(job->copy_range_size, end - start);
+ nbytes = MIN(job->copy_range_size, MIN(end, job->len) - start);
nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size);
hbitmap_reset(job->copy_bitmap, start, job->cluster_size * nr_clusters);
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
--
1.8.3.1

View File

@ -1,51 +0,0 @@
From bad8a640a29f16b4d333673577b06880894766e1 Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Date: Fri, 20 Sep 2019 17:20:42 +0300
Subject: [PATCH] block/backup: fix max_transfer handling for copy_range
Of course, QEMU_ALIGN_UP is a typo, it should be QEMU_ALIGN_DOWN, as we
are trying to find aligned size which satisfy both source and target.
Also, don't ignore too small max_transfer. In this case seems safer to
disable copy_range.
Fixes: 9ded4a0114968e
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190920142056.12778-2-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 981fb5810aa3f68797ee6e261db338bd78857614)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/backup.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index 381659d..8119d3c 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -666,12 +666,19 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
job->cluster_size = cluster_size;
job->copy_bitmap = copy_bitmap;
copy_bitmap = NULL;
- job->use_copy_range = !compress; /* compression isn't supported for it */
job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
blk_get_max_transfer(job->target));
- job->copy_range_size = MAX(job->cluster_size,
- QEMU_ALIGN_UP(job->copy_range_size,
- job->cluster_size));
+ job->copy_range_size = QEMU_ALIGN_DOWN(job->copy_range_size,
+ job->cluster_size);
+ /*
+ * Set use_copy_range, consider the following:
+ * 1. Compression is not supported for copy_range.
+ * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
+ * that in here. If max_transfer is smaller than the job->cluster_size,
+ * we do not use copy_range (in that case it's zero after aligning down
+ * above).
+ */
+ job->use_copy_range = !compress && job->copy_range_size > 0;
/* Required permissions are already taken with target's blk_new() */
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
--
1.8.3.1

View File

@ -1,73 +0,0 @@
From 9cc9e9657aad126502183fa4ceb9b962b55471cb Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Mon, 29 Jul 2019 16:35:55 -0400
Subject: [PATCH] block/backup: hoist bitmap check into QMP interface
This is nicer to do in the unified QMP interface that we have now,
because it lets us use the right terminology back at the user.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190716000117.25219-5-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
---
block/backup.c | 13 ++++---------
blockdev.c | 10 ++++++++++
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index 59ac2c0396..cc19643b47 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -565,6 +565,10 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
assert(bs);
assert(target);
+ /* QMP interface protects us from these cases */
+ assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
+ assert(sync_bitmap || sync_mode != MIRROR_SYNC_MODE_BITMAP);
+
if (bs == target) {
error_setg(errp, "Source and target cannot be the same");
return NULL;
@@ -596,16 +600,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
return NULL;
}
- /* QMP interface should have handled translating this to bitmap mode */
- assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
-
if (sync_mode == MIRROR_SYNC_MODE_BITMAP) {
- if (!sync_bitmap) {
- error_setg(errp, "must provide a valid bitmap name for "
- "'%s' sync mode", MirrorSyncMode_str(sync_mode));
- return NULL;
- }
-
/* If we need to write to this bitmap, check that we can: */
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER &&
bdrv_dirty_bitmap_check(sync_bitmap, BDRV_BITMAP_DEFAULT, errp)) {
diff --git a/blockdev.c b/blockdev.c
index efb69d343a..0a71a15fa2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3508,6 +3508,16 @@ static BlockJob *do_backup_common(BackupCommon *backup,
return NULL;
}
+ if ((backup->sync == MIRROR_SYNC_MODE_BITMAP) ||
+ (backup->sync == MIRROR_SYNC_MODE_INCREMENTAL)) {
+ /* done before desugaring 'incremental' to print the right message */
+ if (!backup->has_bitmap) {
+ error_setg(errp, "must provide a valid bitmap name for "
+ "'%s' sync mode", MirrorSyncMode_str(backup->sync));
+ return NULL;
+ }
+ }
+
if (backup->sync == MIRROR_SYNC_MODE_INCREMENTAL) {
if (backup->has_bitmap_mode &&
backup->bitmap_mode != BITMAP_SYNC_MODE_ON_SUCCESS) {
--
2.27.0

View File

@ -1,51 +0,0 @@
From 801e9452bc80a38ee26fe12ba42356851acd6a9e Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com>
Date: Mon, 29 Jul 2019 16:35:54 -0400
Subject: [PATCH] block/backup: loosen restriction on readonly bitmaps
With the "never" sync policy, we actually can utilize readonly bitmaps
now. Loosen the check at the QMP level, and tighten it based on
provided arguments down at the job creation level instead.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190709232550.10724-19-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
---
block/backup.c | 6 ++++++
blockdev.c | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/block/backup.c b/block/backup.c
index 84a56337ac..59ac2c0396 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -606,6 +606,12 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
return NULL;
}
+ /* If we need to write to this bitmap, check that we can: */
+ if (bitmap_mode != BITMAP_SYNC_MODE_NEVER &&
+ bdrv_dirty_bitmap_check(sync_bitmap, BDRV_BITMAP_DEFAULT, errp)) {
+ return NULL;
+ }
+
/* Create a new bitmap, and freeze/disable this one. */
if (bdrv_dirty_bitmap_create_successor(bs, sync_bitmap, errp) < 0) {
return NULL;
diff --git a/blockdev.c b/blockdev.c
index 34c8b651e1..efb69d343a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3533,7 +3533,7 @@ static BlockJob *do_backup_common(BackupCommon *backup,
"when providing a bitmap");
return NULL;
}
- if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
+ if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_ALLOW_RO, errp)) {
return NULL;
}
}
--
2.27.0

View File

@ -1,116 +0,0 @@
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 d0586db311e8b78732923ce46f149fdf8251a59c Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 16:10:22 +0800
Subject: [PATCH] block: bugfix: Don't pause vm when NOSPACE EIO happened
When backend disk is FULL and disk IO type is 'dataplane',
QEMU will pause the vm, and this may cause endless-loop in
QEMU main thread if we do the snapshot merge now.
When backend disk is FULL, only reporting an error rather
than pausing the virtual machine.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
blockdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/blockdev.c b/blockdev.c
index 37e3ee6f26..3ce294ec4a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -556,7 +556,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
qdict_put_str(bs_opts, "driver", buf);
}
- on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
+ on_write_error = BLOCKDEV_ON_ERROR_REPORT;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
on_write_error = parse_block_error_action(buf, 0, &error);
if (error) {
--
2.27.0

View File

@ -0,0 +1,43 @@
From 87d8b7dcd880e0cef0c043dfef5ae649652cfe21 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:51:43 +0800
Subject: [PATCH] block: bugfix: disable process AIO when attach scsi disk
When initializing the virtio-scsi disk, hd_geometry_guess() will
be called to process AIO. At this time, the scsi disk has not
been fully initialized, and some fields in struct SCSIDiskState,
such as vendor and version, are NULL. If processing AIO at this
time, qemu may crash down.
Add aio_disable_external() before hd_geometry_guess() to disable
processing AIO at that time.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
hw/block/block.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/block/block.c b/hw/block/block.c
index 26c0767552..2cfc93a68e 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -224,9 +224,16 @@ bool blkconf_geometry(BlockConf *conf, int *ptrans,
Error **errp)
{
if (!conf->cyls && !conf->heads && !conf->secs) {
+ AioContext *ctx = blk_get_aio_context(conf->blk);
+
+ /* Callers may not expect this function to dispatch aio handlers, so
+ * disable external aio such as guest device emulation.
+ */
+ aio_disable_external(ctx);
hd_geometry_guess(conf->blk,
&conf->cyls, &conf->heads, &conf->secs,
ptrans);
+ aio_enable_external(ctx);
} else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
*ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
}
--
2.27.0

View File

@ -1,95 +0,0 @@
From 088f1e8fd9e790bc5766bd43af134230abcff6dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
Date: Thu, 12 Sep 2019 00:08:49 +0200
Subject: [PATCH] block/create: Do not abort if a block driver is not available
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The 'blockdev-create' QMP command was introduced as experimental
feature in commit b0292b851b8, using the assert() debug call.
It got promoted to 'stable' command in 3fb588a0f2c, but the
assert call was not removed.
Some block drivers are optional, and bdrv_find_format() might
return a NULL value, triggering the assertion.
Stable code is not expected to abort, so return an error instead.
This is easily reproducible when libnfs is not installed:
./configure
[...]
module support no
Block whitelist (rw)
Block whitelist (ro)
libiscsi support yes
libnfs support no
[...]
Start QEMU:
$ qemu-system-x86_64 -S -qmp unix:/tmp/qemu.qmp,server,nowait
Send the 'blockdev-create' with the 'nfs' driver:
$ ( cat << 'EOF'
{'execute': 'qmp_capabilities'}
{'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'}
EOF
) | socat STDIO UNIX:/tmp/qemu.qmp
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 4}, "package": "v4.1.0-733-g89ea03a7dc"}, "capabilities": ["oob"]}}
{"return": {}}
QEMU crashes:
$ gdb qemu-system-x86_64 core
Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 0x00007ffff510957f in raise () at /lib64/libc.so.6
#1 0x00007ffff50f3895 in abort () at /lib64/libc.so.6
#2 0x00007ffff50f3769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6
#3 0x00007ffff5101a26 in .annobin_assert.c_end () at /lib64/libc.so.6
#4 0x0000555555d7e1f1 in qmp_blockdev_create (job_id=0x555556baee40 "x", options=0x555557666610, errp=0x7fffffffc770) at block/create.c:69
#5 0x0000555555c96b52 in qmp_marshal_blockdev_create (args=0x7fffdc003830, ret=0x7fffffffc7f8, errp=0x7fffffffc7f0) at qapi/qapi-commands-block-core.c:1314
#6 0x0000555555deb0a0 in do_qmp_dispatch (cmds=0x55555645de70 <qmp_commands>, request=0x7fffdc005c70, allow_oob=false, errp=0x7fffffffc898) at qapi/qmp-dispatch.c:131
#7 0x0000555555deb2a1 in qmp_dispatch (cmds=0x55555645de70 <qmp_commands>, request=0x7fffdc005c70, allow_oob=false) at qapi/qmp-dispatch.c:174
With this patch applied, QEMU returns a QMP error:
{'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'}
{"id": "x", "error": {"class": "GenericError", "desc": "Block driver 'nfs' not found or not supported"}}
Cc: qemu-stable@nongnu.org
Reported-by: Xu Tian <xutian@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d90d5cae2b10efc0e8d0b3cc91ff16201853d3ba)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/create.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/block/create.c b/block/create.c
index 95341219ef..de5e97bb18 100644
--- a/block/create.c
+++ b/block/create.c
@@ -63,9 +63,13 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
const char *fmt = BlockdevDriver_str(options->driver);
BlockDriver *drv = bdrv_find_format(fmt);
+ if (!drv) {
+ error_setg(errp, "Block driver '%s' not found or not supported", fmt);
+ return;
+ }
+
/* If the driver is in the schema, we know that it exists. But it may not
* be whitelisted. */
- assert(drv);
if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
error_setg(errp, "Driver is not whitelisted");
return;
--
2.23.0

View File

@ -1,54 +0,0 @@
From ae2c6d13c4ac625a2c6b217a7f6a17506a2b26e5 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Thu, 28 May 2020 14:27:37 +0100
Subject: [PATCH] block/curl: HTTP header field names are case insensitive
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Richard Jones <rjones@redhat.com>
Message-id: <20200528142737.17318-3-rjones@redhat.com>
Patchwork-id: 96895
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] block/curl: HTTP header field names are case insensitive
Bugzilla: 1841038
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
From: David Edmondson <david.edmondson@oracle.com>
RFC 7230 section 3.2 indicates that HTTP header field names are case
insensitive.
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
Message-Id: <20200224101310.101169-3-david.edmondson@oracle.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 69032253c33ae1774233c63cedf36d32242a85fc)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
block/curl.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index bfabe7eabd..a298fcc591 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -214,11 +214,12 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
size_t realsize = size * nmemb;
const char *header = (char *)ptr;
const char *end = header + realsize;
- const char *accept_ranges = "Accept-Ranges:";
+ const char *accept_ranges = "accept-ranges:";
const char *bytes = "bytes";
if (realsize >= strlen(accept_ranges)
- && strncmp(header, accept_ranges, strlen(accept_ranges)) == 0) {
+ && g_ascii_strncasecmp(header, accept_ranges,
+ strlen(accept_ranges)) == 0) {
char *p = strchr(header, ':') + 1;
--
2.27.0

View File

@ -1,75 +0,0 @@
From c8fd37c06fd24d1242629dda329dd16bea20f319 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones@redhat.com>
Date: Thu, 28 May 2020 14:27:36 +0100
Subject: [PATCH] block/curl: HTTP header fields allow whitespace around values
RH-Author: Richard Jones <rjones@redhat.com>
Message-id: <20200528142737.17318-2-rjones@redhat.com>
Patchwork-id: 96894
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/2] block/curl: HTTP header fields allow whitespace around values
Bugzilla: 1841038
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Max Reitz <mreitz@redhat.com>
RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
From: David Edmondson <david.edmondson@oracle.com>
RFC 7230 section 3.2 indicates that whitespace is permitted between
the field name and field value and after the field value.
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
Message-Id: <20200224101310.101169-2-david.edmondson@oracle.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 7788a319399f17476ff1dd43164c869e320820a2)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
block/curl.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index d4c8e94f3e..bfabe7eabd 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -212,11 +212,34 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
BDRVCURLState *s = opaque;
size_t realsize = size * nmemb;
- const char *accept_line = "Accept-Ranges: bytes";
+ const char *header = (char *)ptr;
+ const char *end = header + realsize;
+ const char *accept_ranges = "Accept-Ranges:";
+ const char *bytes = "bytes";
- if (realsize >= strlen(accept_line)
- && strncmp((char *)ptr, accept_line, strlen(accept_line)) == 0) {
- s->accept_range = true;
+ if (realsize >= strlen(accept_ranges)
+ && strncmp(header, accept_ranges, strlen(accept_ranges)) == 0) {
+
+ char *p = strchr(header, ':') + 1;
+
+ /* Skip whitespace between the header name and value. */
+ while (p < end && *p && g_ascii_isspace(*p)) {
+ p++;
+ }
+
+ if (end - p >= strlen(bytes)
+ && strncmp(p, bytes, strlen(bytes)) == 0) {
+
+ /* Check that there is nothing but whitespace after the value. */
+ p += strlen(bytes);
+ while (p < end && *p && g_ascii_isspace(*p)) {
+ p++;
+ }
+
+ if (p == end || !*p) {
+ s->accept_range = true;
+ }
+ }
}
return realsize;
--
2.27.0

View File

@ -0,0 +1,47 @@
From 0a2c96ee5a3463e82397afb9cb36f340a93264c2 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:29:15 +0800
Subject: [PATCH] block: disallow block jobs when there is a BDRV_O_INACTIVE
flag
Currently, migration will put a BDRV_O_INACTIVE flag
on bs's open_flags until another resume being called. In that case,
any IO from vm or block jobs will cause a qemu crash with an assert
'assert(!(bs->open_flags & BDRV_O_INACTIVE))' failure in bdrv_co_pwritev
function. we hereby disallow block jobs by faking a blocker.
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
block.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/block.c b/block.c
index 0ac5b163d2..26c3982567 100644
--- a/block.c
+++ b/block.c
@@ -6692,6 +6692,22 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
bdrv_get_device_or_node_name(bs));
return true;
}
+
+ /*
+ * When migration puts a BDRV_O_INACTIVE flag on driver's open_flags,
+ * we fake a blocker that doesn't exist. From now on, block jobs
+ * will not be permitted.
+ */
+ if ((op == BLOCK_OP_TYPE_RESIZE || op == BLOCK_OP_TYPE_COMMIT_SOURCE ||
+ op == BLOCK_OP_TYPE_MIRROR_SOURCE || op == BLOCK_OP_TYPE_MIRROR_TARGET) &&
+ (bs->open_flags & BDRV_O_INACTIVE)) {
+ if (errp) {
+ error_setg(errp, "block device is in use by migration with"
+ " a driver BDRV_O_INACTIVE flag setted");
+ }
+ return true;
+ }
+
return false;
}
--
2.27.0

View File

@ -0,0 +1,49 @@
From 21b172a3ce13c3b499e4265628f7d7c7e1189749 Mon Sep 17 00:00:00 2001
From: WangJian <wangjian161@huawei.com>
Date: Wed, 9 Feb 2022 11:18:21 +0800
Subject: [PATCH] block: enable cache mode of empty cdrom
enable cache mode even if cdrom is empty
Signed-off-by: wangjian161 <wangjian161@huawei.com>
---
blockdev.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/blockdev.c b/blockdev.c
index 10a73fa423..37e3ee6f26 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -492,6 +492,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
QDict *interval_dict = NULL;
QList *interval_list = NULL;
const char *id;
+ const char *cache;
BlockdevDetectZeroesOptions detect_zeroes =
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
const char *throttling_group = NULL;
@@ -583,6 +584,21 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false);
+ if (!file || !*file) {
+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
+ if (cache && !strcmp(cache, "on")) {
+ bdrv_flags |= BDRV_O_NO_FLUSH;
+ }
+
+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_DIRECT);
+ if (cache && !strcmp(cache, "on")) {
+ bdrv_flags |= BDRV_O_NOCACHE;
+ }
+
+ qdict_del(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
+ qdict_del(bs_opts, BDRV_OPT_CACHE_DIRECT);
+ }
+
/* init */
if ((!file || !*file) && !qdict_size(bs_opts)) {
BlockBackendRootState *blk_rs;
--
2.27.0

View File

@ -1,69 +0,0 @@
From 7db05c8a732fbdc986a40aadf0de6dd23057d044 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Fri, 1 Nov 2019 16:25:10 +0100
Subject: [PATCH] block/file-posix: Let post-EOF fallocate serialize
The XFS kernel driver has a bug that may cause data corruption for qcow2
images as of qemu commit c8bb23cbdbe32f. We can work around it by
treating post-EOF fallocates as serializing up until infinity (INT64_MAX
in practice).
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20191101152510.11719-4-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 292d06b925b2787ee6f2430996b95651cae42fce)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/file-posix.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/block/file-posix.c b/block/file-posix.c
index 992eb4a798..c5df61b477 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2623,6 +2623,42 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
RawPosixAIOData acb;
ThreadPoolFunc *handler;
+#ifdef CONFIG_FALLOCATE
+ if (offset + bytes > bs->total_sectors * BDRV_SECTOR_SIZE) {
+ BdrvTrackedRequest *req;
+ uint64_t end;
+
+ /*
+ * This is a workaround for a bug in the Linux XFS driver,
+ * where writes submitted through the AIO interface will be
+ * discarded if they happen beyond a concurrently running
+ * fallocate() that increases the file length (i.e., both the
+ * write and the fallocate() happen beyond the EOF).
+ *
+ * To work around it, we extend the tracked request for this
+ * zero write until INT64_MAX (effectively infinity), and mark
+ * it as serializing.
+ *
+ * We have to enable this workaround for all filesystems and
+ * AIO modes (not just XFS with aio=native), because for
+ * remote filesystems we do not know the host configuration.
+ */
+
+ req = bdrv_co_get_self_request(bs);
+ assert(req);
+ assert(req->type == BDRV_TRACKED_WRITE);
+ assert(req->offset <= offset);
+ assert(req->offset + req->bytes >= offset + bytes);
+
+ end = INT64_MAX & -(uint64_t)bs->bl.request_alignment;
+ req->bytes = end - req->offset;
+ req->overlap_bytes = req->bytes;
+
+ bdrv_mark_request_serialising(req, bs->bl.request_alignment);
+ bdrv_wait_serialising_requests(req);
+ }
+#endif
+
acb = (RawPosixAIOData) {
.bs = bs,
.aio_fildes = s->fd,
--
2.23.0

View File

@ -1,165 +0,0 @@
From 6f1a94035b02d3676a897ea5fa4cda4c62128228 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Fri, 23 Aug 2019 15:03:40 +0200
Subject: [PATCH] block/file-posix: Reduce xfsctl() use
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch removes xfs_write_zeroes() and xfs_discard(). Both functions
have been added just before the same feature was present through
fallocate():
- fallocate() has supported PUNCH_HOLE for XFS since Linux 2.6.38 (March
2011); xfs_discard() was added in December 2010.
- fallocate() has supported ZERO_RANGE for XFS since Linux 3.15 (June
2014); xfs_write_zeroes() was added in November 2013.
Nowadays, all systems that qemu runs on should support both fallocate()
features (RHEL 7's kernel does).
xfsctl() is still useful for getting the request alignment for O_DIRECT,
so this patch does not remove our dependency on it completely.
Note that xfs_write_zeroes() had a bug: It calls ftruncate() when the
file is shorter than the specified range (because ZERO_RANGE does not
increase the file length). ftruncate() may yield and then discard data
that parallel write requests have written past the EOF in the meantime.
Dropping the function altogether fixes the bug.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Fixes: 50ba5b2d994853b38fed10e0841b119da0f8b8e5
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Tested-by: Stefano Garzarella <sgarzare@redhat.com>
Tested-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b2c6f23f4a9f6d8f1b648705cd46d3713b78d6a2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/file-posix.c | 77 +---------------------------------------------
1 file changed, 1 insertion(+), 76 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 4479cc7ab4..992eb4a798 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1445,59 +1445,6 @@ out:
}
}
-#ifdef CONFIG_XFS
-static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
-{
- int64_t len;
- struct xfs_flock64 fl;
- int err;
-
- len = lseek(s->fd, 0, SEEK_END);
- if (len < 0) {
- return -errno;
- }
-
- if (offset + bytes > len) {
- /* XFS_IOC_ZERO_RANGE does not increase the file length */
- if (ftruncate(s->fd, offset + bytes) < 0) {
- return -errno;
- }
- }
-
- memset(&fl, 0, sizeof(fl));
- fl.l_whence = SEEK_SET;
- fl.l_start = offset;
- fl.l_len = bytes;
-
- if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) {
- err = errno;
- trace_file_xfs_write_zeroes(strerror(errno));
- return -err;
- }
-
- return 0;
-}
-
-static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
-{
- struct xfs_flock64 fl;
- int err;
-
- memset(&fl, 0, sizeof(fl));
- fl.l_whence = SEEK_SET;
- fl.l_start = offset;
- fl.l_len = bytes;
-
- if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
- err = errno;
- trace_file_xfs_discard(strerror(errno));
- return -err;
- }
-
- return 0;
-}
-#endif
-
static int translate_err(int err)
{
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
@@ -1553,10 +1500,8 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
static int handle_aiocb_write_zeroes(void *opaque)
{
RawPosixAIOData *aiocb = opaque;
-#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
- BDRVRawState *s = aiocb->bs->opaque;
-#endif
#ifdef CONFIG_FALLOCATE
+ BDRVRawState *s = aiocb->bs->opaque;
int64_t len;
#endif
@@ -1564,12 +1509,6 @@ static int handle_aiocb_write_zeroes(void *opaque)
return handle_aiocb_write_zeroes_block(aiocb);
}
-#ifdef CONFIG_XFS
- if (s->is_xfs) {
- return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
- }
-#endif
-
#ifdef CONFIG_FALLOCATE_ZERO_RANGE
if (s->has_write_zeroes) {
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
@@ -1632,14 +1571,6 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
}
#endif
-#ifdef CONFIG_XFS
- if (s->is_xfs) {
- /* xfs_discard() guarantees that the discarded area reads as all-zero
- * afterwards, so we can use it here. */
- return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
- }
-#endif
-
/* If we couldn't manage to unmap while guaranteed that the area reads as
* all-zero afterwards, just write zeroes without unmapping */
ret = handle_aiocb_write_zeroes(aiocb);
@@ -1716,12 +1647,6 @@ static int handle_aiocb_discard(void *opaque)
ret = -errno;
#endif
} else {
-#ifdef CONFIG_XFS
- if (s->is_xfs) {
- return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
- }
-#endif
-
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
aiocb->aio_offset, aiocb->aio_nbytes);
--
2.23.0

View File

@ -1,33 +0,0 @@
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

@ -1,56 +0,0 @@
From d09b8364d9f89c9d5f36dc983c4d4a36bb7388b9 Mon Sep 17 00:00:00 2001
From: Pan Nengyuan <pannengyuan@huawei.com>
Date: Thu, 16 Jan 2020 17:29:29 +0800
Subject: [PATCH] block: fix memleaks in bdrv_refresh_filename
If we call the qmp 'query-block' while qemu is working on 'block-commit',
it will cause memleaks. The memory leak stack is as follow:
Indirect leak of 12360 byte(s) in 3 object(s) allocated from:
#0 0x7f80f0b6d970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
#1 0x7f80ee86049d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
#2 0x55ea95b5bb67 in qdict_new /mnt/sdb/qemu/qobject/qdict.c
#3 0x55ea956cd043 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#4 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#5 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#6 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#7 0x55ea958818ea in bdrv_block_device_info /mnt/sdb/qemu/block/qapi.c
#8 0x55ea958879de in bdrv_query_info /mnt/sdb/qemu/block/qapi.c
#9 0x55ea9588b58f in qmp_query_block /mnt/sdb/qemu/block/qapi.c
#10 0x55ea95567392 in qmp_marshal_query_block qapi/qapi-commands-block-core.c
Indirect leak of 4120 byte(s) in 1 object(s) allocated from:
#0 0x7f80f0b6d970 in __interceptor_calloc (/lib64/libasan.so.5+0xef970)
#1 0x7f80ee86049d in g_malloc0 (/lib64/libglib-2.0.so.0+0x5249d)
#2 0x55ea95b5bb67 in qdict_new /mnt/sdb/qemu/qobject/qdict.c
#3 0x55ea956cd043 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#4 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#5 0x55ea956cc950 in bdrv_refresh_filename /mnt/sdb/qemu/block.c
#6 0x55ea9569f301 in bdrv_backing_attach /mnt/sdb/qemu/block.c
#7 0x55ea956a99dd in bdrv_replace_child_noperm /mnt/sdb/qemu/block.c
#8 0x55ea956b9b53 in bdrv_replace_node /mnt/sdb/qemu/block.c
#9 0x55ea956b9e49 in bdrv_append /mnt/sdb/qemu/block.c
#10 0x55ea958c3472 in commit_start /mnt/sdb/qemu/block/commit.c
#11 0x55ea94b68ab0 in qmp_block_commit /mnt/sdb/qemu/blockdev.c
Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
---
block.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/block.c b/block.c
index 9ae5c0e..52bad05 100644
--- a/block.c
+++ b/block.c
@@ -6048,6 +6048,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
child->bs->exact_filename);
pstrcpy(bs->filename, sizeof(bs->filename), child->bs->filename);
+ qobject_unref(bs->full_open_options);
bs->full_open_options = qobject_ref(child->bs->full_open_options);
return;
--
1.8.3.1

View File

@ -1,481 +0,0 @@
From 2e2ad02f2cecf419eaad0df982ceb5b41170cc7e Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Date: Tue, 4 Jun 2019 19:15:05 +0300
Subject: [PATCH] block/io: refactor padding
We have similar padding code in bdrv_co_pwritev,
bdrv_co_do_pwrite_zeroes and bdrv_co_preadv. Let's combine and unify
it.
[Squashed in Vladimir's qemu-iotests 077 fix
--Stefan]
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190604161514.262241-4-vsementsov@virtuozzo.com
Message-Id: <20190604161514.262241-4-vsementsov@virtuozzo.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 7a3f542fbdfd799be4fa6f8b96dc8c1e6933fce4)
*prereq for 292d06b9
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/io.c | 365 +++++++++++++++++++++++++++++------------------------
1 file changed, 200 insertions(+), 165 deletions(-)
diff --git a/block/io.c b/block/io.c
index dccf687acc..07d2d825c3 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1408,28 +1408,177 @@ out:
}
/*
- * Handle a read request in coroutine context
+ * Request padding
+ *
+ * |<---- align ----->| |<----- align ---->|
+ * |<- head ->|<------------- bytes ------------->|<-- tail -->|
+ * | | | | | |
+ * -*----------$-------*-------- ... --------*-----$------------*---
+ * | | | | | |
+ * | offset | | end |
+ * ALIGN_DOWN(offset) ALIGN_UP(offset) ALIGN_DOWN(end) ALIGN_UP(end)
+ * [buf ... ) [tail_buf )
+ *
+ * @buf is an aligned allocation needed to store @head and @tail paddings. @head
+ * is placed at the beginning of @buf and @tail at the @end.
+ *
+ * @tail_buf is a pointer to sub-buffer, corresponding to align-sized chunk
+ * around tail, if tail exists.
+ *
+ * @merge_reads is true for small requests,
+ * if @buf_len == @head + bytes + @tail. In this case it is possible that both
+ * head and tail exist but @buf_len == align and @tail_buf == @buf.
+ */
+typedef struct BdrvRequestPadding {
+ uint8_t *buf;
+ size_t buf_len;
+ uint8_t *tail_buf;
+ size_t head;
+ size_t tail;
+ bool merge_reads;
+ QEMUIOVector local_qiov;
+} BdrvRequestPadding;
+
+static bool bdrv_init_padding(BlockDriverState *bs,
+ int64_t offset, int64_t bytes,
+ BdrvRequestPadding *pad)
+{
+ uint64_t align = bs->bl.request_alignment;
+ size_t sum;
+
+ memset(pad, 0, sizeof(*pad));
+
+ pad->head = offset & (align - 1);
+ pad->tail = ((offset + bytes) & (align - 1));
+ if (pad->tail) {
+ pad->tail = align - pad->tail;
+ }
+
+ if ((!pad->head && !pad->tail) || !bytes) {
+ return false;
+ }
+
+ sum = pad->head + bytes + pad->tail;
+ pad->buf_len = (sum > align && pad->head && pad->tail) ? 2 * align : align;
+ pad->buf = qemu_blockalign(bs, pad->buf_len);
+ pad->merge_reads = sum == pad->buf_len;
+ if (pad->tail) {
+ pad->tail_buf = pad->buf + pad->buf_len - align;
+ }
+
+ return true;
+}
+
+static int bdrv_padding_rmw_read(BdrvChild *child,
+ BdrvTrackedRequest *req,
+ BdrvRequestPadding *pad,
+ bool zero_middle)
+{
+ QEMUIOVector local_qiov;
+ BlockDriverState *bs = child->bs;
+ uint64_t align = bs->bl.request_alignment;
+ int ret;
+
+ assert(req->serialising && pad->buf);
+
+ if (pad->head || pad->merge_reads) {
+ uint64_t bytes = pad->merge_reads ? pad->buf_len : align;
+
+ qemu_iovec_init_buf(&local_qiov, pad->buf, bytes);
+
+ if (pad->head) {
+ bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
+ }
+ if (pad->merge_reads && pad->tail) {
+ bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
+ }
+ ret = bdrv_aligned_preadv(child, req, req->overlap_offset, bytes,
+ align, &local_qiov, 0);
+ if (ret < 0) {
+ return ret;
+ }
+ if (pad->head) {
+ bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
+ }
+ if (pad->merge_reads && pad->tail) {
+ bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
+ }
+
+ if (pad->merge_reads) {
+ goto zero_mem;
+ }
+ }
+
+ if (pad->tail) {
+ qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align);
+
+ bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
+ ret = bdrv_aligned_preadv(
+ child, req,
+ req->overlap_offset + req->overlap_bytes - align,
+ align, align, &local_qiov, 0);
+ if (ret < 0) {
+ return ret;
+ }
+ bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
+ }
+
+zero_mem:
+ if (zero_middle) {
+ memset(pad->buf + pad->head, 0, pad->buf_len - pad->head - pad->tail);
+ }
+
+ return 0;
+}
+
+static void bdrv_padding_destroy(BdrvRequestPadding *pad)
+{
+ if (pad->buf) {
+ qemu_vfree(pad->buf);
+ qemu_iovec_destroy(&pad->local_qiov);
+ }
+}
+
+/*
+ * bdrv_pad_request
+ *
+ * Exchange request parameters with padded request if needed. Don't include RMW
+ * read of padding, bdrv_padding_rmw_read() should be called separately if
+ * needed.
+ *
+ * All parameters except @bs are in-out: they represent original request at
+ * function call and padded (if padding needed) at function finish.
+ *
+ * Function always succeeds.
*/
+static bool bdrv_pad_request(BlockDriverState *bs, QEMUIOVector **qiov,
+ int64_t *offset, unsigned int *bytes,
+ BdrvRequestPadding *pad)
+{
+ if (!bdrv_init_padding(bs, *offset, *bytes, pad)) {
+ return false;
+ }
+
+ qemu_iovec_init_extended(&pad->local_qiov, pad->buf, pad->head,
+ *qiov, 0, *bytes,
+ pad->buf + pad->buf_len - pad->tail, pad->tail);
+ *bytes += pad->head + pad->tail;
+ *offset -= pad->head;
+ *qiov = &pad->local_qiov;
+
+ return true;
+}
+
int coroutine_fn bdrv_co_preadv(BdrvChild *child,
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
BdrvRequestFlags flags)
{
BlockDriverState *bs = child->bs;
- BlockDriver *drv = bs->drv;
BdrvTrackedRequest req;
-
- uint64_t align = bs->bl.request_alignment;
- uint8_t *head_buf = NULL;
- uint8_t *tail_buf = NULL;
- QEMUIOVector local_qiov;
- bool use_local_qiov = false;
+ BdrvRequestPadding pad;
int ret;
- trace_bdrv_co_preadv(child->bs, offset, bytes, flags);
-
- if (!drv) {
- return -ENOMEDIUM;
- }
+ trace_bdrv_co_preadv(bs, offset, bytes, flags);
ret = bdrv_check_byte_request(bs, offset, bytes);
if (ret < 0) {
@@ -1443,43 +1592,16 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child,
flags |= BDRV_REQ_COPY_ON_READ;
}
- /* Align read if necessary by padding qiov */
- if (offset & (align - 1)) {
- head_buf = qemu_blockalign(bs, align);
- qemu_iovec_init(&local_qiov, qiov->niov + 2);
- qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1));
- qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);
- use_local_qiov = true;
-
- bytes += offset & (align - 1);
- offset = offset & ~(align - 1);
- }
-
- if ((offset + bytes) & (align - 1)) {
- if (!use_local_qiov) {
- qemu_iovec_init(&local_qiov, qiov->niov + 1);
- qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);
- use_local_qiov = true;
- }
- tail_buf = qemu_blockalign(bs, align);
- qemu_iovec_add(&local_qiov, tail_buf,
- align - ((offset + bytes) & (align - 1)));
-
- bytes = ROUND_UP(bytes, align);
- }
+ bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad);
tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ);
- ret = bdrv_aligned_preadv(child, &req, offset, bytes, align,
- use_local_qiov ? &local_qiov : qiov,
- flags);
+ ret = bdrv_aligned_preadv(child, &req, offset, bytes,
+ bs->bl.request_alignment,
+ qiov, flags);
tracked_request_end(&req);
bdrv_dec_in_flight(bs);
- if (use_local_qiov) {
- qemu_iovec_destroy(&local_qiov);
- qemu_vfree(head_buf);
- qemu_vfree(tail_buf);
- }
+ bdrv_padding_destroy(&pad);
return ret;
}
@@ -1775,44 +1897,34 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
BdrvTrackedRequest *req)
{
BlockDriverState *bs = child->bs;
- uint8_t *buf = NULL;
QEMUIOVector local_qiov;
uint64_t align = bs->bl.request_alignment;
- unsigned int head_padding_bytes, tail_padding_bytes;
int ret = 0;
+ bool padding;
+ BdrvRequestPadding pad;
- head_padding_bytes = offset & (align - 1);
- tail_padding_bytes = (align - (offset + bytes)) & (align - 1);
-
-
- assert(flags & BDRV_REQ_ZERO_WRITE);
- if (head_padding_bytes || tail_padding_bytes) {
- buf = qemu_blockalign(bs, align);
- qemu_iovec_init_buf(&local_qiov, buf, align);
- }
- if (head_padding_bytes) {
- uint64_t zero_bytes = MIN(bytes, align - head_padding_bytes);
-
- /* RMW the unaligned part before head. */
+ padding = bdrv_init_padding(bs, offset, bytes, &pad);
+ if (padding) {
mark_request_serialising(req, align);
wait_serialising_requests(req);
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
- ret = bdrv_aligned_preadv(child, req, offset & ~(align - 1), align,
- align, &local_qiov, 0);
- if (ret < 0) {
- goto fail;
- }
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
- memset(buf + head_padding_bytes, 0, zero_bytes);
- ret = bdrv_aligned_pwritev(child, req, offset & ~(align - 1), align,
- align, &local_qiov,
- flags & ~BDRV_REQ_ZERO_WRITE);
- if (ret < 0) {
- goto fail;
+ bdrv_padding_rmw_read(child, req, &pad, true);
+
+ if (pad.head || pad.merge_reads) {
+ int64_t aligned_offset = offset & ~(align - 1);
+ int64_t write_bytes = pad.merge_reads ? pad.buf_len : align;
+
+ qemu_iovec_init_buf(&local_qiov, pad.buf, write_bytes);
+ ret = bdrv_aligned_pwritev(child, req, aligned_offset, write_bytes,
+ align, &local_qiov,
+ flags & ~BDRV_REQ_ZERO_WRITE);
+ if (ret < 0 || pad.merge_reads) {
+ /* Error or all work is done */
+ goto out;
+ }
+ offset += write_bytes - pad.head;
+ bytes -= write_bytes - pad.head;
}
- offset += zero_bytes;
- bytes -= zero_bytes;
}
assert(!bytes || (offset & (align - 1)) == 0);
@@ -1822,7 +1934,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
ret = bdrv_aligned_pwritev(child, req, offset, aligned_bytes, align,
NULL, flags);
if (ret < 0) {
- goto fail;
+ goto out;
}
bytes -= aligned_bytes;
offset += aligned_bytes;
@@ -1830,26 +1942,17 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
assert(!bytes || (offset & (align - 1)) == 0);
if (bytes) {
- assert(align == tail_padding_bytes + bytes);
- /* RMW the unaligned part after tail. */
- mark_request_serialising(req, align);
- wait_serialising_requests(req);
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
- ret = bdrv_aligned_preadv(child, req, offset, align,
- align, &local_qiov, 0);
- if (ret < 0) {
- goto fail;
- }
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
+ assert(align == pad.tail + bytes);
- memset(buf, 0, bytes);
+ qemu_iovec_init_buf(&local_qiov, pad.tail_buf, align);
ret = bdrv_aligned_pwritev(child, req, offset, align, align,
&local_qiov, flags & ~BDRV_REQ_ZERO_WRITE);
}
-fail:
- qemu_vfree(buf);
- return ret;
+out:
+ bdrv_padding_destroy(&pad);
+
+ return ret;
}
/*
@@ -1862,10 +1965,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
BlockDriverState *bs = child->bs;
BdrvTrackedRequest req;
uint64_t align = bs->bl.request_alignment;
- uint8_t *head_buf = NULL;
- uint8_t *tail_buf = NULL;
- QEMUIOVector local_qiov;
- bool use_local_qiov = false;
+ BdrvRequestPadding pad;
int ret;
trace_bdrv_co_pwritev(child->bs, offset, bytes, flags);
@@ -1892,86 +1992,21 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
goto out;
}
- if (offset & (align - 1)) {
- QEMUIOVector head_qiov;
-
+ if (bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad)) {
mark_request_serialising(&req, align);
wait_serialising_requests(&req);
-
- head_buf = qemu_blockalign(bs, align);
- qemu_iovec_init_buf(&head_qiov, head_buf, align);
-
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
- ret = bdrv_aligned_preadv(child, &req, offset & ~(align - 1), align,
- align, &head_qiov, 0);
- if (ret < 0) {
- goto fail;
- }
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
-
- qemu_iovec_init(&local_qiov, qiov->niov + 2);
- qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1));
- qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);
- use_local_qiov = true;
-
- bytes += offset & (align - 1);
- offset = offset & ~(align - 1);
-
- /* We have read the tail already if the request is smaller
- * than one aligned block.
- */
- if (bytes < align) {
- qemu_iovec_add(&local_qiov, head_buf + bytes, align - bytes);
- bytes = align;
- }
- }
-
- if ((offset + bytes) & (align - 1)) {
- QEMUIOVector tail_qiov;
- size_t tail_bytes;
- bool waited;
-
- mark_request_serialising(&req, align);
- waited = wait_serialising_requests(&req);
- assert(!waited || !use_local_qiov);
-
- tail_buf = qemu_blockalign(bs, align);
- qemu_iovec_init_buf(&tail_qiov, tail_buf, align);
-
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
- ret = bdrv_aligned_preadv(child, &req, (offset + bytes) & ~(align - 1),
- align, align, &tail_qiov, 0);
- if (ret < 0) {
- goto fail;
- }
- bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
-
- if (!use_local_qiov) {
- qemu_iovec_init(&local_qiov, qiov->niov + 1);
- qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);
- use_local_qiov = true;
- }
-
- tail_bytes = (offset + bytes) & (align - 1);
- qemu_iovec_add(&local_qiov, tail_buf + tail_bytes, align - tail_bytes);
-
- bytes = ROUND_UP(bytes, align);
+ bdrv_padding_rmw_read(child, &req, &pad, false);
}
ret = bdrv_aligned_pwritev(child, &req, offset, bytes, align,
- use_local_qiov ? &local_qiov : qiov,
- flags);
+ qiov, flags);
-fail:
+ bdrv_padding_destroy(&pad);
- if (use_local_qiov) {
- qemu_iovec_destroy(&local_qiov);
- }
- qemu_vfree(head_buf);
- qemu_vfree(tail_buf);
out:
tracked_request_end(&req);
bdrv_dec_in_flight(bs);
+
return ret;
}
--
2.23.0

View File

@ -1,30 +0,0 @@
From 547b06bb04287eb97ffb02e213aa8466c15cce65 Mon Sep 17 00:00:00 2001
From: Chen Qun <kuhn.chenqun@huawei.com>
Date: Mon, 16 Mar 2020 14:35:34 +0800
Subject: [PATCH] block/iscsi: use MIN() between mx_sb_len and sb_len_wr
Use MIN() macro between mx_sb_len and sb_len_wr the len for sbp copy data.
Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Chen Qun <kuhn.chenqun@huawei.com>
---
block/iscsi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/block/iscsi.c b/block/iscsi.c
index 3f86aaf..5c3c598 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -989,8 +989,7 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
acb->ioh->sb_len_wr = acb->task->datain.size - 2;
- ss = (acb->ioh->mx_sb_len >= acb->ioh->sb_len_wr) ?
- acb->ioh->mx_sb_len : acb->ioh->sb_len_wr;
+ ss = MIN(acb->ioh->mx_sb_len, acb->ioh->sb_len_wr);
memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
}
--
1.8.3.1

View File

@ -0,0 +1,32 @@
From 7448eb87ee59856aa0f0853f2aa5b803c832fccf Mon Sep 17 00:00:00 2001
From: jiangdongxu <jiangdongxu1@huawei.com>
Date: Thu, 10 Feb 2022 21:37:49 +0800
Subject: [PATCH] block/mirror: fix file-system went to read-only after
block-mirror
config vm disk with prdm, keep the disk writing data continuously
during block-mirror, the file-system will went to read-only after
block-mirror, fix it.
Signed-off-by: caojinhua <caojinhua1@huawei.com>
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
---
block/mirror.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/mirror.c b/block/mirror.c
index efec2c7674..b7f0cba9b9 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1640,7 +1640,7 @@ static BlockJob *mirror_start_job(
* reads on the top, while disabling it in the intermediate nodes, and make
* the backing chain writable. */
mirror_top_bs = bdrv_new_open_driver(&bdrv_mirror_top, filter_node_name,
- BDRV_O_RDWR, errp);
+ BDRV_O_RDWR | BDRV_O_NOCACHE, errp);
if (mirror_top_bs == NULL) {
return NULL;
}
--
2.27.0

View File

@ -1,34 +0,0 @@
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

@ -1,67 +0,0 @@
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

@ -1,41 +0,0 @@
From 0694c489cd240620fee5675e8d24c7ce02d1d67d Mon Sep 17 00:00:00 2001
From: Peter Lieven <pl@kamp.de>
Date: Tue, 10 Sep 2019 17:41:09 +0200
Subject: [PATCH] block/nfs: tear down aio before nfs_close
nfs_close is a sync call from libnfs and has its own event
handler polling on the nfs FD. Avoid that both QEMU and libnfs
are intefering here.
CC: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 601dc6559725f7a614b6f893611e17ff0908e914)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/nfs.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/nfs.c b/block/nfs.c
index d93241b3bb..2b7a078241 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -390,12 +390,14 @@ static void nfs_attach_aio_context(BlockDriverState *bs,
static void nfs_client_close(NFSClient *client)
{
if (client->context) {
+ qemu_mutex_lock(&client->mutex);
+ aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
+ false, NULL, NULL, NULL, NULL);
+ qemu_mutex_unlock(&client->mutex);
if (client->fh) {
nfs_close(client->context, client->fh);
client->fh = NULL;
}
- aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
- false, NULL, NULL, NULL, NULL);
nfs_destroy_context(client->context);
client->context = NULL;
}
--
2.23.0

View File

@ -1,343 +0,0 @@
From 3d018ff3bdd8aec260254036b600cfa8d694ced4 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nirsof@gmail.com>
Date: Tue, 27 Aug 2019 04:05:27 +0300
Subject: [PATCH] block: posix: Always allocate the first block
When creating an image with preallocation "off" or "falloc", the first
block of the image is typically not allocated. When using Gluster
storage backed by XFS filesystem, reading this block using direct I/O
succeeds regardless of request length, fooling alignment detection.
In this case we fallback to a safe value (4096) instead of the optimal
value (512), which may lead to unneeded data copying when aligning
requests. Allocating the first block avoids the fallback.
Since we allocate the first block even with preallocation=off, we no
longer create images with zero disk size:
$ ./qemu-img create -f raw test.raw 1g
Formatting 'test.raw', fmt=raw size=1073741824
$ ls -lhs test.raw
4.0K -rw-r--r--. 1 nsoffer nsoffer 1.0G Aug 16 23:48 test.raw
And converting the image requires additional cluster:
$ ./qemu-img measure -f raw -O qcow2 test.raw
required size: 458752
fully allocated size: 1074135040
When using format like vmdk with multiple files per image, we allocate
one block per file:
$ ./qemu-img create -f vmdk -o subformat=twoGbMaxExtentFlat test.vmdk 4g
Formatting 'test.vmdk', fmt=vmdk size=4294967296 compat6=off hwversion=undefined subformat=twoGbMaxExtentFlat
$ ls -lhs test*.vmdk
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f001.vmdk
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f002.vmdk
4.0K -rw-r--r--. 1 nsoffer nsoffer 353 Aug 27 03:23 test.vmdk
I did quick performance test for copying disks with qemu-img convert to
new raw target image to Gluster storage with sector size of 512 bytes:
for i in $(seq 10); do
rm -f dst.raw
sleep 10
time ./qemu-img convert -f raw -O raw -t none -T none src.raw dst.raw
done
Here is a table comparing the total time spent:
Type Before(s) After(s) Diff(%)
---------------------------------------
real 530.028 469.123 -11.4
user 17.204 10.768 -37.4
sys 17.881 7.011 -60.7
We can see very clear improvement in CPU usage.
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
Message-id: 20190827010528.8818-2-nsoffer@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 3a20013fbb26d2a1bd11ef148eefdb1508783787)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/file-posix.c | 51 +++++++++++++++++++
tests/qemu-iotests/059.out | 2 +-
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
tests/qemu-iotests/150.out.raw | 12 +++++
tests/qemu-iotests/175 | 19 ++++---
tests/qemu-iotests/175.out | 8 +--
tests/qemu-iotests/178.out.qcow2 | 4 +-
tests/qemu-iotests/221.out | 12 +++--
tests/qemu-iotests/253.out | 12 +++--
9 files changed, 99 insertions(+), 21 deletions(-)
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
create mode 100644 tests/qemu-iotests/150.out.raw
diff --git a/block/file-posix.c b/block/file-posix.c
index be32dd8c51..2184aa980c 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1674,6 +1674,43 @@ static int handle_aiocb_discard(void *opaque)
return ret;
}
+/*
+ * Help alignment probing by allocating the first block.
+ *
+ * When reading with direct I/O from unallocated area on Gluster backed by XFS,
+ * reading succeeds regardless of request length. In this case we fallback to
+ * safe alignment which is not optimal. Allocating the first block avoids this
+ * fallback.
+ *
+ * fd may be opened with O_DIRECT, but we don't know the buffer alignment or
+ * request alignment, so we use safe values.
+ *
+ * Returns: 0 on success, -errno on failure. Since this is an optimization,
+ * caller may ignore failures.
+ */
+static int allocate_first_block(int fd, size_t max_size)
+{
+ size_t write_size = (max_size < MAX_BLOCKSIZE)
+ ? BDRV_SECTOR_SIZE
+ : MAX_BLOCKSIZE;
+ size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
+ void *buf;
+ ssize_t n;
+ int ret;
+
+ buf = qemu_memalign(max_align, write_size);
+ memset(buf, 0, write_size);
+
+ do {
+ n = pwrite(fd, buf, write_size, 0);
+ } while (n == -1 && errno == EINTR);
+
+ ret = (n == -1) ? -errno : 0;
+
+ qemu_vfree(buf);
+ return ret;
+}
+
static int handle_aiocb_truncate(void *opaque)
{
RawPosixAIOData *aiocb = opaque;
@@ -1713,6 +1750,17 @@ static int handle_aiocb_truncate(void *opaque)
/* posix_fallocate() doesn't set errno. */
error_setg_errno(errp, -result,
"Could not preallocate new data");
+ } else if (current_length == 0) {
+ /*
+ * posix_fallocate() uses fallocate() if the filesystem
+ * supports it, or fallback to manually writing zeroes. If
+ * fallocate() was used, unaligned reads from the fallocated
+ * area in raw_probe_alignment() will succeed, hence we need to
+ * allocate the first block.
+ *
+ * Optimize future alignment probing; ignore failures.
+ */
+ allocate_first_block(fd, offset);
}
} else {
result = 0;
@@ -1774,6 +1822,9 @@ static int handle_aiocb_truncate(void *opaque)
if (ftruncate(fd, offset) != 0) {
result = -errno;
error_setg_errno(errp, -result, "Could not resize file");
+ } else if (current_length == 0 && offset > current_length) {
+ /* Optimize future alignment probing; ignore failures. */
+ allocate_first_block(fd, offset);
}
return result;
default:
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 4fab42a28c..fe3f861f3c 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -27,7 +27,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMax
image: TEST_DIR/t.vmdk
file format: vmdk
virtual size: 0.977 TiB (1073741824000 bytes)
-disk size: 16 KiB
+disk size: 1.97 MiB
Format specific information:
cid: XXXXXXXX
parent cid: XXXXXXXX
diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out.qcow2
similarity index 100%
rename from tests/qemu-iotests/150.out
rename to tests/qemu-iotests/150.out.qcow2
diff --git a/tests/qemu-iotests/150.out.raw b/tests/qemu-iotests/150.out.raw
new file mode 100644
index 0000000000..3cdc7727a5
--- /dev/null
+++ b/tests/qemu-iotests/150.out.raw
@@ -0,0 +1,12 @@
+QA output created by 150
+
+=== Mapping sparse conversion ===
+
+Offset Length File
+0 0x1000 TEST_DIR/t.IMGFMT
+
+=== Mapping non-sparse conversion ===
+
+Offset Length File
+0 0x100000 TEST_DIR/t.IMGFMT
+*** done
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
index 51e62c8276..7ba28b3c1b 100755
--- a/tests/qemu-iotests/175
+++ b/tests/qemu-iotests/175
@@ -37,14 +37,16 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
# the file size. This function hides the resulting difference in the
# stat -c '%b' output.
# Parameter 1: Number of blocks an empty file occupies
-# Parameter 2: Image size in bytes
+# Parameter 2: Minimal number of blocks in an image
+# Parameter 3: Image size in bytes
_filter_blocks()
{
extra_blocks=$1
- img_size=$2
+ min_blocks=$2
+ img_size=$3
- sed -e "s/blocks=$extra_blocks\\(\$\\|[^0-9]\\)/nothing allocated/" \
- -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/everything allocated/"
+ sed -e "s/blocks=$min_blocks\\(\$\\|[^0-9]\\)/min allocation/" \
+ -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
}
# get standard environment, filters and checks
@@ -60,16 +62,21 @@ size=$((1 * 1024 * 1024))
touch "$TEST_DIR/empty"
extra_blocks=$(stat -c '%b' "$TEST_DIR/empty")
+# We always write the first byte; check how many blocks this filesystem
+# allocates to match empty image alloation.
+printf "\0" > "$TEST_DIR/empty"
+min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
+
echo
echo "== creating image with default preallocation =="
_make_test_img $size | _filter_imgfmt
-stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
+stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
for mode in off full falloc; do
echo
echo "== creating image with preallocation $mode =="
IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
- stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
done
# success, all done
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
index 6d9a5ed84e..263e521262 100644
--- a/tests/qemu-iotests/175.out
+++ b/tests/qemu-iotests/175.out
@@ -2,17 +2,17 @@ QA output created by 175
== creating image with default preallocation ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
-size=1048576, nothing allocated
+size=1048576, min allocation
== creating image with preallocation off ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=off
-size=1048576, nothing allocated
+size=1048576, min allocation
== creating image with preallocation full ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=full
-size=1048576, everything allocated
+size=1048576, max allocation
== creating image with preallocation falloc ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
-size=1048576, everything allocated
+size=1048576, max allocation
*** done
diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
index 55a8dc926f..9e7d8c44df 100644
--- a/tests/qemu-iotests/178.out.qcow2
+++ b/tests/qemu-iotests/178.out.qcow2
@@ -101,7 +101,7 @@ converted image file size in bytes: 196608
== raw input image with data (human) ==
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
-required size: 393216
+required size: 458752
fully allocated size: 1074135040
wrote 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -257,7 +257,7 @@ converted image file size in bytes: 196608
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
{
- "required": 393216,
+ "required": 458752,
"fully-allocated": 1074135040
}
wrote 512/512 bytes at offset 512
diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out
index 9f9dd52bb0..dca024a0c3 100644
--- a/tests/qemu-iotests/221.out
+++ b/tests/qemu-iotests/221.out
@@ -3,14 +3,18 @@ QA output created by 221
=== Check mapping of unaligned raw image ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
wrote 1/1 bytes at offset 65536
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
*** done
diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out
index 607c0baa0b..3d08b305d7 100644
--- a/tests/qemu-iotests/253.out
+++ b/tests/qemu-iotests/253.out
@@ -3,12 +3,16 @@ QA output created by 253
=== Check mapping of unaligned raw image ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
wrote 65535/65535 bytes at offset 983040
63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
*** done
--
2.23.0

View File

@ -1,66 +0,0 @@
From 84f22c728520792f1010074e0d5ac2ec8e2e372c Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <mlevitsk@redhat.com>
Date: Sun, 15 Sep 2019 23:36:53 +0300
Subject: [PATCH] block/qcow2: Fix corruption introduced by commit 8ac0f15f335
This fixes subtle corruption introduced by luks threaded encryption
in commit 8ac0f15f335
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922
The corruption happens when we do a write that
* writes to two or more unallocated clusters at once
* doesn't fully cover the first sector
* doesn't fully cover the last sector
* uses luks encryption
In this case, when allocating the new clusters we COW both areas
prior to the write and after the write, and we encrypt them.
The above mentioned commit accidentally made it so we encrypt the
second COW area using the physical cluster offset of the first area.
The problem is that offset_in_cluster in do_perform_cow_encrypt
can be larger that the cluster size, thus cluster_offset
will no longer point to the start of the cluster at which encrypted
area starts.
Next patch in this series will refactor the code to avoid all these
assumptions.
In the bugreport that was triggered by rebasing a luks image to new,
zero filled base, which lot of such writes, and causes some files
with zero areas to contain garbage there instead.
But as described above it can happen elsewhere as well
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20190915203655.21638-2-mlevitsk@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 38e7d54bdc518b5a05a922467304bcace2396945)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/qcow2-cluster.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cc5609e27a..760564c8fb 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -473,9 +473,10 @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
assert(s->crypto);
- if (qcow2_co_encrypt(bs, cluster_offset,
- src_cluster_offset + offset_in_cluster,
- buffer, bytes) < 0) {
+ if (qcow2_co_encrypt(bs,
+ start_of_cluster(s, cluster_offset + offset_in_cluster),
+ src_cluster_offset + offset_in_cluster,
+ buffer, bytes) < 0) {
return false;
}
}
--
2.23.0

View File

@ -1,54 +0,0 @@
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

@ -1,75 +0,0 @@
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

@ -1,124 +0,0 @@
From 7a8aa6c734bb1c2927ad0cc1d10bcacb53cf4ae3 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 17 Sep 2019 12:26:23 +0200
Subject: [PATCH] block/snapshot: Restrict set of snapshot nodes
Nodes involved in internal snapshots were those that were returned by
bdrv_next(), inserted and not read-only. bdrv_next() in turn returns all
nodes that are either the root node of a BlockBackend or monitor-owned
nodes.
With the typical -drive use, this worked well enough. However, in the
typical -blockdev case, the user defines one node per option, making all
nodes monitor-owned nodes. This includes protocol nodes etc. which often
are not snapshottable, so "savevm" only returns an error.
Change the conditions so that internal snapshot still include all nodes
that have a BlockBackend attached (we definitely want to snapshot
anything attached to a guest device and probably also the built-in NBD
server; snapshotting block job BlockBackends is more of an accident, but
a preexisting one), but other monitor-owned nodes are only included if
they have no parents.
This makes internal snapshots usable again with typical -blockdev
configurations.
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 05f4aced658a02b02d3e89a6c7a2281008fcf26c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
block/snapshot.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/block/snapshot.c b/block/snapshot.c
index f2f48f926a..8081616ae9 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -31,6 +31,7 @@
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qstring.h"
#include "qemu/option.h"
+#include "sysemu/block-backend.h"
QemuOptsList internal_snapshot_opts = {
.name = "snapshot",
@@ -384,6 +385,16 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
return ret;
}
+static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
+{
+ if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
+ return false;
+ }
+
+ /* Include all nodes that are either in use by a BlockBackend, or that
+ * aren't attached to any node, but owned by the monitor. */
+ return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents);
+}
/* Group operations. All block drivers are involved.
* These functions will properly handle dataplane (take aio_context_acquire
@@ -399,7 +410,7 @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
- if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {
+ if (bdrv_all_snapshots_includes_bs(bs)) {
ok = bdrv_can_snapshot(bs);
}
aio_context_release(ctx);
@@ -426,8 +437,9 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
- if (bdrv_can_snapshot(bs) &&
- bdrv_snapshot_find(bs, snapshot, name) >= 0) {
+ if (bdrv_all_snapshots_includes_bs(bs) &&
+ bdrv_snapshot_find(bs, snapshot, name) >= 0)
+ {
ret = bdrv_snapshot_delete(bs, snapshot->id_str,
snapshot->name, err);
}
@@ -455,7 +467,7 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs,
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
- if (bdrv_can_snapshot(bs)) {
+ if (bdrv_all_snapshots_includes_bs(bs)) {
ret = bdrv_snapshot_goto(bs, name, errp);
}
aio_context_release(ctx);
@@ -481,7 +493,7 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx);
- if (bdrv_can_snapshot(bs)) {
+ if (bdrv_all_snapshots_includes_bs(bs)) {
err = bdrv_snapshot_find(bs, &sn, name);
}
aio_context_release(ctx);
@@ -512,7 +524,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
if (bs == vm_state_bs) {
sn->vm_state_size = vm_state_size;
err = bdrv_snapshot_create(bs, sn);
- } else if (bdrv_can_snapshot(bs)) {
+ } else if (bdrv_all_snapshots_includes_bs(bs)) {
sn->vm_state_size = 0;
err = bdrv_snapshot_create(bs, sn);
}
@@ -538,7 +550,7 @@ BlockDriverState *bdrv_all_find_vmstate_bs(void)
bool found;
aio_context_acquire(ctx);
- found = bdrv_can_snapshot(bs);
+ found = bdrv_all_snapshots_includes_bs(bs) && bdrv_can_snapshot(bs);
aio_context_release(ctx);
if (found) {
--
2.23.0

Some files were not shown because too many files have changed in this diff Show More