!54 rebase openEuler-20.03-LTS branch to master
Merge pull request !54 from FangYing/master
This commit is contained in:
commit
a4372444dd
@ -1,8 +1,11 @@
|
||||
From f3c1fc4dce1582ccc1754899d5149d233e8629ff Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Thu, 3 Oct 2019 17:46:40 +0200
|
||||
Subject: [PATCH 3/3] ARM: KVM: Check KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 for
|
||||
smp_cpus > 256
|
||||
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
|
||||
@ -21,26 +24,27 @@ 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.]
|
||||
¦struct CpuTopology in MachineState at that time. See commit
|
||||
¦edeeec911702 for details.]
|
||||
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
|
||||
---
|
||||
target/arm/kvm.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
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 f60185ad..383423c4 100644
|
||||
index 50e86f8b..cc7a46df 100644
|
||||
--- a/target/arm/kvm.c
|
||||
+++ b/target/arm/kvm.c
|
||||
@@ -174,6 +174,7 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -187,7 +188,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
@@ -186,7 +188,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
|
||||
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
|
||||
|
||||
@ -57,5 +61,4 @@ index f60185ad..383423c4 100644
|
||||
|
||||
unsigned long kvm_arch_vcpu_id(CPUState *cpu)
|
||||
--
|
||||
2.19.1
|
||||
|
||||
2.23.0
|
||||
@ -1,6 +1,6 @@
|
||||
From d2fd6d1a5200b9a58863839d21d291cd4f76ac31 Mon Sep 17 00:00:00 2001
|
||||
From 4646a24045cf53f2cc5e0ef1974da88ef50ef676 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Mon, 29 Jul 2019 15:47:27 +0800
|
||||
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
|
||||
@ -17,10 +17,10 @@ Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
3 files changed, 61 insertions(+)
|
||||
|
||||
diff --git a/cpus.c b/cpus.c
|
||||
index e83f72b4..f6ec48a2 100644
|
||||
index 927a00aa..b9aa51f8 100644
|
||||
--- a/cpus.c
|
||||
+++ b/cpus.c
|
||||
@@ -1063,6 +1063,28 @@ void cpu_synchronize_all_pre_loadvm(void)
|
||||
@@ -1066,6 +1066,28 @@ void cpu_synchronize_all_pre_loadvm(void)
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ index e83f72b4..f6ec48a2 100644
|
||||
static int do_vm_stop(RunState state, bool send_stop)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1070,6 +1092,11 @@ static int do_vm_stop(RunState state, bool send_stop)
|
||||
@@ -1073,6 +1095,11 @@ static int do_vm_stop(RunState state, bool send_stop)
|
||||
if (runstate_is_running()) {
|
||||
cpu_disable_ticks();
|
||||
pause_all_vcpus();
|
||||
@ -61,7 +61,7 @@ index e83f72b4..f6ec48a2 100644
|
||||
runstate_set(state);
|
||||
vm_state_notify(0, state);
|
||||
if (send_stop) {
|
||||
@@ -1909,11 +1936,42 @@ void cpu_resume(CPUState *cpu)
|
||||
@@ -1918,11 +1945,42 @@ void cpu_resume(CPUState *cpu)
|
||||
qemu_cpu_kick(cpu);
|
||||
}
|
||||
|
||||
@ -105,23 +105,23 @@ index e83f72b4..f6ec48a2 100644
|
||||
cpu_resume(cpu);
|
||||
}
|
||||
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||
index d4d28369..e107e395 100644
|
||||
index 86eb79cd..aec6a214 100644
|
||||
--- a/target/arm/cpu.h
|
||||
+++ b/target/arm/cpu.h
|
||||
@@ -270,6 +270,8 @@ typedef struct CPUARMState {
|
||||
uint64_t elr_el[4]; /* AArch64 exception link regs */
|
||||
@@ -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 b2925496..d64a0057 100644
|
||||
index ee3c59a6..ec28b839 100644
|
||||
--- a/target/arm/machine.c
|
||||
+++ b/target/arm/machine.c
|
||||
@@ -792,6 +792,7 @@ const VMStateDescription vmstate_arm_cpu = {
|
||||
@@ -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),
|
||||
|
||||
88
Revert-ide-ahci-Check-for-ECANCELED-in-aio-callbacks.patch
Normal file
88
Revert-ide-ahci-Check-for-ECANCELED-in-aio-callbacks.patch
Normal file
@ -0,0 +1,88 @@
|
||||
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
|
||||
37
Revert-vtimer-compat-cross-version-migration-from-v4.patch
Normal file
37
Revert-vtimer-compat-cross-version-migration-from-v4.patch
Normal file
@ -0,0 +1,37 @@
|
||||
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
|
||||
|
||||
27
Typo-Correct-the-name-of-CPU-hotplug-memory-region.patch
Normal file
27
Typo-Correct-the-name-of-CPU-hotplug-memory-region.patch
Normal file
@ -0,0 +1,27 @@
|
||||
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
|
||||
63
accel-kvm-Add-pre-park-vCPU-support.patch
Normal file
63
accel-kvm-Add-pre-park-vCPU-support.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 135119d2e82e99adc67346572c761fbe54d73e4a 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
|
||||
|
||||
For that KVM do not support dynamic adjustment of vCPU count,
|
||||
we must pre-park all possible vCPU at start.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 23 +++++++++++++++++++++++
|
||||
include/sysemu/kvm.h | 1 +
|
||||
2 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index f450f25295..84edbe8bb1 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -339,6 +339,29 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int kvm_create_parked_vcpu(unsigned long vcpu_id)
|
||||
+{
|
||||
+ KVMState *s = kvm_state;
|
||||
+ struct KVMParkedVcpu *vcpu = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ DPRINTF("kvm_create_parked_vcpu\n");
|
||||
+
|
||||
+ ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
|
||||
+ if (ret < 0) {
|
||||
+ DPRINTF("kvm_create_vcpu failed\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ vcpu = g_malloc0(sizeof(*vcpu));
|
||||
+ vcpu->vcpu_id = vcpu_id;
|
||||
+ vcpu->kvm_fd = ret;
|
||||
+ QLIST_INSERT_HEAD(&s->kvm_parked_vcpus, vcpu, node);
|
||||
+
|
||||
+err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
|
||||
{
|
||||
struct KVMParkedVcpu *cpu;
|
||||
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
|
||||
index acd90aebb6..565adb4e2c 100644
|
||||
--- a/include/sysemu/kvm.h
|
||||
+++ b/include/sysemu/kvm.h
|
||||
@@ -216,6 +216,7 @@ 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);
|
||||
--
|
||||
2.19.1
|
||||
128
acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch
Normal file
128
acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch
Normal file
@ -0,0 +1,128 @@
|
||||
From 107c267ebe5b8c461268a4ff8384ad2f2b9e8ce0 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
|
||||
|
||||
We will reuse build_cpus_aml to build DSDT cpus aml in arm/virt
|
||||
ACPI to realize cpu hotplug. Three points are added.
|
||||
|
||||
1. Make ACPI IO address space configurable, because ARM64 platforms
|
||||
don't use port IO for ACPI IO space.
|
||||
2. Add GICC struct building support in _MAT of cpu aml.
|
||||
3. Let the hotplug method parameter can be NULL, because ACPI GED
|
||||
will realize it.
|
||||
|
||||
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/i386/acpi-build.c | 2 +-
|
||||
include/hw/acpi/cpu.h | 3 ++-
|
||||
3 files changed, 28 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
|
||||
index 0c0bfe479a..72ad1fcff2 100644
|
||||
--- a/hw/acpi/cpu.c
|
||||
+++ b/hw/acpi/cpu.c
|
||||
@@ -314,7 +314,8 @@ const VMStateDescription vmstate_cpu_hotplug = {
|
||||
void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
|
||||
hwaddr io_base,
|
||||
const char *res_root,
|
||||
- const char *event_handler_method)
|
||||
+ const char *event_handler_method,
|
||||
+ AmlRegionSpace rs)
|
||||
{
|
||||
Aml *ifctx;
|
||||
Aml *field;
|
||||
@@ -342,13 +343,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();
|
||||
- aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
|
||||
- ACPI_CPU_HOTPLUG_REG_LEN));
|
||||
+ if (rs == AML_SYSTEM_IO) {
|
||||
+ aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
|
||||
+ ACPI_CPU_HOTPLUG_REG_LEN));
|
||||
+ } else {
|
||||
+ aml_append(crs, aml_memory32_fixed(io_base,
|
||||
+ ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
|
||||
+ }
|
||||
aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
|
||||
|
||||
/* declare CPU hotplug MMIO region with related access fields */
|
||||
aml_append(cpu_ctrl_dev,
|
||||
- aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
|
||||
+ aml_operation_region("PRST", rs, aml_int(io_base),
|
||||
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,
|
||||
aml_append(dev, aml_name_decl("_UID", uid));
|
||||
}
|
||||
|
||||
+ assert(adevc);
|
||||
+ if (adevc->cpu_cppc) {
|
||||
+ adevc->cpu_cppc(adev, i, arch_ids->len, dev);
|
||||
+ }
|
||||
+
|
||||
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,
|
||||
aml_append(sb_scope, cpus_dev);
|
||||
aml_append(table, sb_scope);
|
||||
|
||||
- method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
|
||||
- aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
|
||||
- aml_append(table, method);
|
||||
+ if (event_handler_method) {
|
||||
+ method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
|
||||
+ aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
|
||||
+ aml_append(table, method);
|
||||
+ }
|
||||
|
||||
g_free(cphp_res_path);
|
||||
}
|
||||
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
||||
index 749218561a..c97731ecb3 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
|
||||
};
|
||||
build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
|
||||
- "\\_SB.PCI0", "\\_GPE._E02");
|
||||
+ "\\_SB.PCI0", "\\_GPE._E02", AML_SYSTEM_IO);
|
||||
}
|
||||
|
||||
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
|
||||
--- a/include/hw/acpi/cpu.h
|
||||
+++ b/include/hw/acpi/cpu.h
|
||||
@@ -55,7 +55,8 @@ typedef struct CPUHotplugFeatures {
|
||||
void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
|
||||
hwaddr io_base,
|
||||
const char *res_root,
|
||||
- const char *event_handler_method);
|
||||
+ const char *event_handler_method,
|
||||
+ AmlRegionSpace rs);
|
||||
|
||||
void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
|
||||
|
||||
--
|
||||
2.19.1
|
||||
41
acpi-ged-Add-virt_madt_cpu_entry-to-madt_cpu-hook.patch
Normal file
41
acpi-ged-Add-virt_madt_cpu_entry-to-madt_cpu-hook.patch
Normal file
@ -0,0 +1,41 @@
|
||||
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
|
||||
204
acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch
Normal file
204
acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch
Normal file
@ -0,0 +1,204 @@
|
||||
From 05d22b55133db1a2526cfe305102e075e883b5e2 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
|
||||
|
||||
This adds a new GED event called ACPI_GED_CPU_HOTPLUG_EVT.
|
||||
The basic workflow is that: GED sends this event to guest,
|
||||
then ACPI driver in guest will call _EVT method of GED aml,
|
||||
then _EVT will call CSCN method in cpus aml to get status of
|
||||
all cpus.
|
||||
|
||||
The status of cpus is maintained by CPUHotplugState in GED and
|
||||
is made accessable to guest through memory region.
|
||||
|
||||
This also adds migration support to CPUHotplugState.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
|
||||
hw/acpi/cpu.c | 1 -
|
||||
hw/acpi/generic_event_device.c | 35 ++++++++++++++++++++++++++
|
||||
hw/arm/Kconfig | 1 +
|
||||
include/hw/acpi/cpu.h | 2 ++
|
||||
include/hw/acpi/generic_event_device.h | 4 +++
|
||||
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
|
||||
--- 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:
|
||||
0: Memory hotplug event
|
||||
1: System power down event
|
||||
- 2-31: Reserved
|
||||
+ 2: CPU hotplug event
|
||||
+ 3-31: Reserved
|
||||
|
||||
**write_access:**
|
||||
|
||||
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
|
||||
index 72ad1fcff2..cb6bb67f3c 100644
|
||||
--- a/hw/acpi/cpu.c
|
||||
+++ b/hw/acpi/cpu.c
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "trace.h"
|
||||
#include "sysemu/numa.h"
|
||||
|
||||
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
|
||||
#define ACPI_CPU_SELECTOR_OFFSET_WR 0
|
||||
#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
|
||||
--- 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[] = {
|
||||
ACPI_GED_MEM_HOTPLUG_EVT,
|
||||
ACPI_GED_PWR_DOWN_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),
|
||||
aml_int(0x80)));
|
||||
break;
|
||||
+ case ACPI_GED_CPU_HOTPLUG_EVT:
|
||||
+ aml_append(if_ctx, aml_call0("\\_SB.CPUS.CSCN"));
|
||||
+ break;
|
||||
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)) {
|
||||
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) {
|
||||
sel = ACPI_GED_PWR_DOWN_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 = {
|
||||
}
|
||||
};
|
||||
|
||||
+static const VMStateDescription vmstate_cpuhp_state = {
|
||||
+ .name = "acpi-ged/cpuhp",
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_CPU_HOTPLUG(cpuhp_state, AcpiGedState),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
static const VMStateDescription vmstate_ged_state = {
|
||||
.name = "acpi-ged-state",
|
||||
.version_id = 1,
|
||||
@@ -244,6 +262,7 @@ static const VMStateDescription vmstate_acpi_ged = {
|
||||
},
|
||||
.subsections = (const VMStateDescription * []) {
|
||||
&vmstate_memhp_state,
|
||||
+ &vmstate_cpuhp_state,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
@@ -254,6 +273,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,
|
||||
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);
|
||||
+
|
||||
+ mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||
+ if (!mc->possible_cpu_arch_ids) {
|
||||
+ /*
|
||||
+ * MachineClass should support possible_cpu_arch_ids in
|
||||
+ * cpu_hotplug_hw_init below.
|
||||
+ */
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ memory_region_init(&s->container_cpuhp, OBJECT(dev), "cpuhp container",
|
||||
+ ACPI_CPU_HOTPLUG_REG_LEN);
|
||||
+ sysbus_init_mmio(sbd, &s->container_cpuhp);
|
||||
+ cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev),
|
||||
+ &s->cpuhp_state, 0);
|
||||
}
|
||||
|
||||
static void acpi_ged_class_init(ObjectClass *class, void *data)
|
||||
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
|
||||
index ad7f7c089b..15e18b0a48 100644
|
||||
--- a/hw/arm/Kconfig
|
||||
+++ b/hw/arm/Kconfig
|
||||
@@ -24,6 +24,7 @@ config ARM_VIRT
|
||||
select DIMM
|
||||
select ACPI_MEMORY_HOTPLUG
|
||||
select ACPI_HW_REDUCED
|
||||
+ 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
|
||||
--- a/include/hw/acpi/cpu.h
|
||||
+++ b/include/hw/acpi/cpu.h
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "hw/acpi/aml-build.h"
|
||||
#include "hw/hotplug.h"
|
||||
|
||||
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
|
||||
+
|
||||
typedef struct AcpiCpuStatus {
|
||||
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
|
||||
--- a/include/hw/acpi/generic_event_device.h
|
||||
+++ b/include/hw/acpi/generic_event_device.h
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/acpi/memory_hotplug.h"
|
||||
#include "hw/arm/virt.h"
|
||||
+#include "hw/acpi/cpu.h"
|
||||
|
||||
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
|
||||
|
||||
@@ -83,6 +84,7 @@
|
||||
*/
|
||||
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
|
||||
#define ACPI_GED_PWR_DOWN_EVT 0x2
|
||||
+#define ACPI_GED_CPU_HOTPLUG_EVT 0x4
|
||||
|
||||
typedef struct GEDState {
|
||||
MemoryRegion io;
|
||||
@@ -93,6 +95,8 @@ typedef struct AcpiGedState {
|
||||
SysBusDevice parent_obj;
|
||||
MemHotplugState memhp_state;
|
||||
MemoryRegion container_memhp;
|
||||
+ CPUHotplugState cpuhp_state;
|
||||
+ MemoryRegion container_cpuhp;
|
||||
GEDState ged_state;
|
||||
uint32_t ged_event_bitmap;
|
||||
qemu_irq irq;
|
||||
--
|
||||
2.19.1
|
||||
95
acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch
Normal file
95
acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From 0288d98f0ef4d17a73cf2bad1b928cd7c044e318 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
|
||||
|
||||
The count of possible CPUs is exposed to guest through the count
|
||||
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(-)
|
||||
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index dbe9acb148..efac788ba1 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));
|
||||
+ static bool pmu;
|
||||
+
|
||||
+ if (uid == 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);
|
||||
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
+ /* The MADT GICC numbers */
|
||||
+ int num_cpu = vms->smp_cpus;
|
||||
int i;
|
||||
|
||||
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;
|
||||
|
||||
- for (i = 0; i < vms->smp_cpus; i++) {
|
||||
- virt_madt_cpu_entry(NULL, i, NULL, table_data);
|
||||
+ for (i = 0; i < num_cpu; i++) {
|
||||
+ virt_madt_cpu_entry(NULL, i, possible_cpus, table_data);
|
||||
}
|
||||
|
||||
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
|
||||
108
acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch
Normal file
108
acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From a3097eed8b642dc6fe891112340821e869b90cc2 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
|
||||
|
||||
To realize CPU hotplug, the cpus aml within ACPI DSDT should contain
|
||||
_MAT mathod, which is equal to the GICC struct in ACPI MADT. Factor
|
||||
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(-)
|
||||
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index f48733d9f2..4b6aace433 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);
|
||||
}
|
||||
|
||||
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
+ const CPUArchIdList *possible_cpus, GArray *entry)
|
||||
+{
|
||||
+ 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));
|
||||
+
|
||||
+ 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);
|
||||
+ }
|
||||
+ 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));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* 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;
|
||||
|
||||
for (i = 0; i < vms->smp_cpus; i++) {
|
||||
- AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
|
||||
- sizeof(*gicc));
|
||||
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
|
||||
-
|
||||
- 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);
|
||||
- }
|
||||
- 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);
|
||||
}
|
||||
|
||||
if (vms->gic_version == 3) {
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index 3dfefca93b..6b1f10b231 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "hw/block/flash.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "hw/intc/arm_gicv3_common.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)
|
||||
|
||||
void virt_acpi_setup(VirtMachineState *vms);
|
||||
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
+ const CPUArchIdList *cpu_list, GArray *entry);
|
||||
|
||||
/* Return the number of used redistributor regions */
|
||||
static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
|
||||
--
|
||||
2.19.1
|
||||
@ -1,8 +1,7 @@
|
||||
From a2bae876b7f694b12073bac8ad6668e4d975ad88 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Fri, 10 Apr 2020 16:08:19 +0000
|
||||
Subject: [PATCH 1/2] aio-wait: delegate polling of main AioContext if BQL not
|
||||
held
|
||||
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
|
||||
@ -20,8 +19,6 @@ 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.
|
||||
|
||||
upstream_url: https://patchwork.kernel.org/patch/11482099/
|
||||
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Message-Id: <20200407140746.8041-5-pbonzini@redhat.com>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
@ -31,7 +28,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
2 files changed, 32 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
|
||||
index afd0ff7e..d349e7e3 100644
|
||||
index afeeb18f..716d2639 100644
|
||||
--- a/include/block/aio-wait.h
|
||||
+++ b/include/block/aio-wait.h
|
||||
@@ -26,6 +26,7 @@
|
||||
@ -67,12 +64,12 @@ index afd0ff7e..d349e7e3 100644
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#endif /* QEMU_AIO_WAIT */
|
||||
#endif /* QEMU_AIO_WAIT_H */
|
||||
diff --git a/include/block/aio.h b/include/block/aio.h
|
||||
index 0ca25dfe..c527893b 100644
|
||||
index 6b0d52f7..9d28e247 100644
|
||||
--- a/include/block/aio.h
|
||||
+++ b/include/block/aio.h
|
||||
@@ -61,12 +61,16 @@ struct AioContext {
|
||||
@@ -60,12 +60,16 @@ struct AioContext {
|
||||
QLIST_HEAD(, AioHandler) aio_handlers;
|
||||
|
||||
/* Used to avoid unnecessary event_notifier_set calls in aio_notify;
|
||||
@ -95,7 +92,7 @@ index 0ca25dfe..c527893b 100644
|
||||
*
|
||||
* 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.
|
||||
@@ -581,19 +585,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co);
|
||||
@@ -580,19 +584,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co);
|
||||
*/
|
||||
AioContext *qemu_get_current_aio_context(void);
|
||||
|
||||
@ -116,5 +113,4 @@ index 0ca25dfe..c527893b 100644
|
||||
* aio_context_setup:
|
||||
* @ctx: the aio context
|
||||
--
|
||||
2.25.2
|
||||
|
||||
2.23.0
|
||||
|
||||
42
arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch
Normal file
42
arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From d8e0b51447d8c64788cd7f9b0fa75c4ccb06f8eb 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
|
||||
|
||||
This hook will be called in get_cpu_status, which is called
|
||||
during cpu hotplug.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
target/arm/cpu.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index 39bbe7e2d7..1ccb30e5eb 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");
|
||||
}
|
||||
|
||||
+static int64_t arm_cpu_get_arch_id(CPUState *cs)
|
||||
+{
|
||||
+ ARMCPU *cpu = ARM_CPU(cs);
|
||||
+
|
||||
+ return cpu->mp_affinity;
|
||||
+}
|
||||
+
|
||||
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;
|
||||
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;
|
||||
--
|
||||
2.19.1
|
||||
66
arm-virt-Add-CPU-hotplug-framework.patch
Normal file
66
arm-virt-Add-CPU-hotplug-framework.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 6d287b3f1d961cc4adda1c6a452f41db84466f5a 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
|
||||
|
||||
Establish the CPU hotplug framework for arm/virt, we will add
|
||||
necessary code legs to this framework gradually to realize CPU
|
||||
hotplug finally.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/virt.c | 19 ++++++++++++++++++-
|
||||
1 file changed, 18 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index d09a5773df..0bd37af26c 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -2077,11 +2077,25 @@ out:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
+static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ /* Currently nothing to do */
|
||||
+}
|
||||
+
|
||||
+static void virt_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ /* Currently nothing to do */
|
||||
+}
|
||||
+
|
||||
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);
|
||||
+ } 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,
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) ||
|
||||
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
|
||||
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
|
||||
+ object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
return HOTPLUG_HANDLER(machine);
|
||||
}
|
||||
|
||||
--
|
||||
2.19.1
|
||||
219
arm-virt-Add-CPU-topology-support.patch
Normal file
219
arm-virt-Add-CPU-topology-support.patch
Normal file
@ -0,0 +1,219 @@
|
||||
From cde57fcae2ed16a10e1ef7f2da0ec368883988ba 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
|
||||
|
||||
The CPU topology specified by user (through -smp options) is used in
|
||||
ACPI PPTT. Now we will use this information to locate which CPU to
|
||||
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(-)
|
||||
create mode 100644 include/hw/arm/topology.h
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 0bd37af26c..64532b61b2 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/arm/boot.h"
|
||||
#include "hw/arm/primecell.h"
|
||||
+#include "hw/arm/topology.h"
|
||||
#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)
|
||||
int n;
|
||||
unsigned int max_cpus = ms->smp.max_cpus;
|
||||
VirtMachineState *vms = VIRT_MACHINE(ms);
|
||||
+ ARMCPUTopoInfo topo;
|
||||
|
||||
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)
|
||||
ms->possible_cpus->len = max_cpus;
|
||||
for (n = 0; n < ms->possible_cpus->len; n++) {
|
||||
ms->possible_cpus->cpus[n].type = ms->cpu_type;
|
||||
+ ms->possible_cpus->cpus[n].vcpus_count = 1;
|
||||
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);
|
||||
+ 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_core_id = true;
|
||||
+ ms->possible_cpus->cpus[n].props.core_id = topo.core_id;
|
||||
ms->possible_cpus->cpus[n].props.has_thread_id = true;
|
||||
- ms->possible_cpus->cpus[n].props.thread_id = n;
|
||||
+ ms->possible_cpus->cpus[n].props.thread_id = topo.smt_id;
|
||||
}
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
@@ -2080,7 +2089,62 @@ out:
|
||||
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
- /* Currently nothing to do */
|
||||
+ CPUState *cs = CPU(dev);
|
||||
+ ARMCPUTopoInfo topo;
|
||||
+ ARMCPU *cpu = ARM_CPU(dev);
|
||||
+ MachineState *ms = MACHINE(hotplug_dev);
|
||||
+ 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 (cs->cpu_index == UNASSIGNED_CPU_INDEX) {
|
||||
+ int max_socket = ms->smp.max_cpus / smp_threads / smp_cores;
|
||||
+ 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->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);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (cpu->thread_id < 0 || cpu->thread_id >= smp_threads) {
|
||||
+ error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u",
|
||||
+ cpu->thread_id, smp_threads - 1);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ topo.pkg_id = cpu->socket_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);
|
||||
+ }
|
||||
+
|
||||
+ /* if 'address' properties socket-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);
|
||||
+ 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);
|
||||
+ return;
|
||||
+ }
|
||||
+ cpu->socket_id = topo.pkg_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);
|
||||
+ return;
|
||||
+ }
|
||||
+ cpu->core_id = topo.core_id;
|
||||
+
|
||||
+ if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {
|
||||
+ error_setg(errp, "property thread-id: %u doesn't match set idx:"
|
||||
+ " 0x%x (thread-id: %u)", cpu->thread_id, cs->cpu_index, topo.smt_id);
|
||||
+ return;
|
||||
+ }
|
||||
+ cpu->thread_id = topo.smt_id;
|
||||
}
|
||||
|
||||
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
|
||||
--- /dev/null
|
||||
+++ b/include/hw/arm/topology.h
|
||||
@@ -0,0 +1,61 @@
|
||||
+/*
|
||||
+ * ARM CPU topology data structures and functions
|
||||
+ *
|
||||
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO.,LTD.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License along
|
||||
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef HW_ARM_TOPOLOGY_H
|
||||
+#define HW_ARM_TOPOLOGY_H
|
||||
+
|
||||
+typedef struct ARMCPUTopoInfo {
|
||||
+ unsigned pkg_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,
|
||||
+ unsigned nr_threads,
|
||||
+ const ARMCPUTopoInfo *topo)
|
||||
+{
|
||||
+ assert(nr_cores > 0);
|
||||
+ assert(nr_threads > 0);
|
||||
+ assert(topo != NULL);
|
||||
+
|
||||
+ return topo->pkg_id * nr_cores * nr_threads +
|
||||
+ topo->core_id * nr_threads +
|
||||
+ topo->smt_id;
|
||||
+}
|
||||
+
|
||||
+/* Calculate thread/core/package topology
|
||||
+ * based on (contiguous) CPU index
|
||||
+ */
|
||||
+static inline void topo_ids_from_idx(unsigned cpu_index,
|
||||
+ unsigned nr_cores,
|
||||
+ unsigned nr_threads,
|
||||
+ ARMCPUTopoInfo *topo)
|
||||
+{
|
||||
+ 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;
|
||||
+}
|
||||
+
|
||||
+#endif /* HW_ARM_TOPOLOGY_H */
|
||||
+
|
||||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
|
||||
index 1ccb30e5eb..91f1e36cd8 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -2560,6 +2560,9 @@ 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("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
|
||||
--- a/target/arm/cpu.h
|
||||
+++ b/target/arm/cpu.h
|
||||
@@ -916,6 +916,9 @@ struct ARMCPU {
|
||||
QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
|
||||
|
||||
int32_t node_id; /* NUMA node this CPU belongs to */
|
||||
+ int32_t socket_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
|
||||
61
arm-virt-Add-cpu_hotplug_enabled-field.patch
Normal file
61
arm-virt-Add-cpu_hotplug_enabled-field.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 31873c4c0454fb17654f57adece2bc396415f8bf 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
|
||||
|
||||
Some conditions must be satisfied to support CPU hotplug, including
|
||||
ACPI, GED, 64bit CPU, GICv3.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/virt.c | 7 +++++++
|
||||
include/hw/arm/virt.h | 1 +
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index dda22194b5..304a4c2d31 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1645,6 +1645,7 @@ static void machvirt_init(MachineState *machine)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(machine);
|
||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
|
||||
+ MachineState *ms = MACHINE(machine);
|
||||
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)
|
||||
bool has_ged = !vmc->no_ged;
|
||||
unsigned int smp_cpus = machine->smp.cpus;
|
||||
unsigned int max_cpus = machine->smp.max_cpus;
|
||||
+ ObjectClass *cpu_class;
|
||||
|
||||
/*
|
||||
* In accelerated mode, the memory map is computed earlier in kvm_type()
|
||||
@@ -1760,6 +1762,11 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
create_fdt(vms);
|
||||
|
||||
+ cpu_class = object_class_by_name(ms->cpu_type);
|
||||
+ vms->cpu_hotplug_enabled = has_ged && firmware_loaded &&
|
||||
+ acpi_enabled && vms->gic_version == 3 &&
|
||||
+ !!object_class_dynamic_cast(cpu_class, TYPE_AARCH64_CPU);
|
||||
+
|
||||
possible_cpus = mc->possible_cpu_arch_ids(machine);
|
||||
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
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -126,6 +126,7 @@ typedef struct {
|
||||
bool highmem_ecam;
|
||||
bool its;
|
||||
bool virt;
|
||||
+ bool cpu_hotplug_enabled;
|
||||
int32_t gic_version;
|
||||
VirtIOMMUType iommu;
|
||||
struct arm_boot_info bootinfo;
|
||||
--
|
||||
2.19.1
|
||||
66
arm-virt-Add-some-sanity-checks-in-cpu_pre_plug-hook.patch
Normal file
66
arm-virt-Add-some-sanity-checks-in-cpu_pre_plug-hook.patch
Normal file
@ -0,0 +1,66 @@
|
||||
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
|
||||
100
arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch
Normal file
100
arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From d38d1d4e859450535ddc6bf0c7a59f6217b1403c 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
|
||||
|
||||
Attach cpus aml building and GED support for CPU hotplug to
|
||||
arm/virt, but currently we make it diabled by not add CPU
|
||||
hotplug event to GED.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/virt-acpi-build.c | 15 ++++++++++++++-
|
||||
hw/arm/virt.c | 6 ++++++
|
||||
include/hw/arm/virt.h | 1 +
|
||||
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
|
||||
--- 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;
|
||||
const int *irqmap = vms->irqmap;
|
||||
+ bool cpu_aml_built = false;
|
||||
|
||||
dsdt = init_aml_allocator();
|
||||
/* Reserve space for header */
|
||||
@@ -817,7 +818,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_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)
|
||||
AML_SYSTEM_MEMORY,
|
||||
memmap[VIRT_PCDIMM_ACPI].base);
|
||||
}
|
||||
+
|
||||
+ if (event & ACPI_GED_CPU_HOTPLUG_EVT) {
|
||||
+ CPUHotplugFeatures opts = {
|
||||
+ .acpi_1_compatible = false, .has_legacy_cphp = false
|
||||
+ };
|
||||
+ build_cpus_aml(dsdt, ms, opts, memmap[VIRT_CPU_ACPI].base,
|
||||
+ "\\_SB", NULL, AML_SYSTEM_MEMORY);
|
||||
+ cpu_aml_built = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!cpu_aml_built) {
|
||||
+ acpi_dsdt_add_cpus(scope, vms->smp_cpus, vms);
|
||||
}
|
||||
|
||||
acpi_dsdt_add_power_button(scope);
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 8638aeedb7..d09a5773df 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 },
|
||||
[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;
|
||||
}
|
||||
|
||||
+ /* event |= ACPI_GED_CPU_HOTPLUG_EVT;
|
||||
+ * Currently CPU hotplug is not enabled.
|
||||
+ */
|
||||
+
|
||||
dev = qdev_create(NULL, TYPE_ACPI_GED);
|
||||
qdev_prop_set_uint32(dev, "ged-event", event);
|
||||
|
||||
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_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index cbdea7ff32..6880ebe07c 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -81,6 +81,7 @@ enum {
|
||||
VIRT_SECURE_MEM,
|
||||
VIRT_PCDIMM_ACPI,
|
||||
VIRT_ACPI_GED,
|
||||
+ VIRT_CPU_ACPI,
|
||||
VIRT_LOWMEMMAP_LAST,
|
||||
};
|
||||
|
||||
--
|
||||
2.19.1
|
||||
124
arm-virt-Pre-sizing-MADT-GICC-PPTT-GICv3-and-Pre-par.patch
Normal file
124
arm-virt-Pre-sizing-MADT-GICC-PPTT-GICv3-and-Pre-par.patch
Normal file
@ -0,0 +1,124 @@
|
||||
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
|
||||
159
arm-virt-Start-up-CPU-hot-plug.patch
Normal file
159
arm-virt-Start-up-CPU-hot-plug.patch
Normal file
@ -0,0 +1,159 @@
|
||||
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
|
||||
92
arm-virt-Support-CPU-cold-plug.patch
Normal file
92
arm-virt-Support-CPU-cold-plug.patch
Normal file
@ -0,0 +1,92 @@
|
||||
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
|
||||
|
||||
65
arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch
Normal file
65
arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 91fed8840b004ec7bc91969afa10f03e13f311c4 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
|
||||
|
||||
We will support CPU hotplug soon, so extend memory region size to
|
||||
allow hotplugged CPU access cpufreq space.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
---
|
||||
hw/acpi/cpufreq.c | 15 ++++++---------
|
||||
1 file changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/cpufreq.c b/hw/acpi/cpufreq.c
|
||||
index d02a25a6de..38dcab5683 100644
|
||||
--- a/hw/acpi/cpufreq.c
|
||||
+++ b/hw/acpi/cpufreq.c
|
||||
@@ -84,6 +84,7 @@ typedef struct CpuhzState {
|
||||
uint32_t PerformanceLimited;
|
||||
uint32_t LowestFreq;
|
||||
uint32_t NominalFreq;
|
||||
+ uint32_t num_cpu;
|
||||
uint32_t reg_size;
|
||||
} CpuhzState;
|
||||
|
||||
@@ -95,10 +96,7 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset,
|
||||
uint64_t r;
|
||||
uint64_t n;
|
||||
|
||||
- MachineState *ms = MACHINE(qdev_get_machine());
|
||||
- unsigned int smp_cpus = ms->smp.cpus;
|
||||
-
|
||||
- if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) {
|
||||
+ if (offset >= s->num_cpu * CPPC_REG_PER_CPU_STRIDE) {
|
||||
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,
|
||||
static void cpufreq_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
+ CpuhzState *s = CPUFREQ(opaque);
|
||||
uint64_t n;
|
||||
- MachineState *ms = MACHINE(qdev_get_machine());
|
||||
- unsigned int smp_cpus = ms->smp.cpus;
|
||||
|
||||
- if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) {
|
||||
+ if (offset >= s->num_cpu * CPPC_REG_PER_CPU_STRIDE) {
|
||||
error_printf("cpufreq_write: offset 0x%lx out of range", offset);
|
||||
return;
|
||||
}
|
||||
@@ -251,9 +248,9 @@ static void cpufreq_init(Object *obj)
|
||||
CpuhzState *s = CPUFREQ(obj);
|
||||
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
- unsigned int smp_cpus = ms->smp.cpus;
|
||||
+ s->num_cpu = ms->smp.max_cpus;
|
||||
|
||||
- s->reg_size = smp_cpus * CPPC_REG_PER_CPU_STRIDE;
|
||||
+ s->reg_size = s->num_cpu * CPPC_REG_PER_CPU_STRIDE;
|
||||
if (s->reg_size > MAX_SUPPORT_SPACE) {
|
||||
error_report("Required space 0x%x excesses the max support 0x%x",
|
||||
s->reg_size, MAX_SUPPORT_SPACE);
|
||||
--
|
||||
2.19.1
|
||||
121
arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch
Normal file
121
arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 2fdece10dac6161cb6c1f0f05247391aa3269eed 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
|
||||
|
||||
When CPU hotplug is enabled, we will use build_cpus_aml instead of
|
||||
acpi_dsdt_add_cpus, so factor out CPPC building and we can reuse it
|
||||
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 +++++++++++++++++-----------
|
||||
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
|
||||
--- 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)
|
||||
aml_append(dev, aml_name_decl("_CPC", cpc));
|
||||
}
|
||||
|
||||
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus,
|
||||
- const MemMapEntry *cppc_memmap)
|
||||
+void virt_acpi_dsdt_cpu_cppc(AcpiDeviceIf *adev, int ncpu, int num_cpu, Aml *dev)
|
||||
+{
|
||||
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
|
||||
+ const MemMapEntry *cppc_memmap = &vms->memmap[VIRT_CPUFREQ];
|
||||
+
|
||||
+ /*
|
||||
+ * Append _CPC and _PSD to support CPU frequence show
|
||||
+ * Check CPPC available by DESIRED_PERF register
|
||||
+ */
|
||||
+ if (cppc_regs_offset[DESIRED_PERF] != -1) {
|
||||
+ acpi_dsdt_add_cppc(dev,
|
||||
+ cppc_memmap->base + ncpu * CPPC_REG_PER_CPU_STRIDE,
|
||||
+ cppc_regs_offset);
|
||||
+ acpi_dsdt_add_psd(dev, num_cpu);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus, VirtMachineState *vms)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
@@ -121,16 +137,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus,
|
||||
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
|
||||
|
||||
- /*
|
||||
- * Append _CPC and _PSD to support CPU frequence show
|
||||
- * Check CPPC available by DESIRED_PERF register
|
||||
- */
|
||||
- if (cppc_regs_offset[DESIRED_PERF] != -1) {
|
||||
- acpi_dsdt_add_cppc(dev,
|
||||
- cppc_memmap->base + i * CPPC_REG_PER_CPU_STRIDE,
|
||||
- cppc_regs_offset);
|
||||
- acpi_dsdt_add_psd(dev, smp_cpus);
|
||||
- }
|
||||
+ virt_acpi_dsdt_cpu_cppc(NULL, i, smp_cpus, dev);
|
||||
|
||||
aml_append(scope, dev);
|
||||
}
|
||||
@@ -810,7 +817,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_uart(scope, &memmap[VIRT_UART],
|
||||
(irqmap[VIRT_UART] + ARM_SPI_BASE));
|
||||
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
|
||||
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
|
||||
index adcb3a816c..2952914569 100644
|
||||
--- a/include/hw/acpi/acpi_dev_interface.h
|
||||
+++ b/include/hw/acpi/acpi_dev_interface.h
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "qom/object.h"
|
||||
#include "hw/boards.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);
|
||||
void (*madt_cpu)(AcpiDeviceIf *adev, int uid,
|
||||
const CPUArchIdList *apic_ids, GArray *entry);
|
||||
+ 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
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -157,6 +157,8 @@ typedef struct {
|
||||
void virt_acpi_setup(VirtMachineState *vms);
|
||||
void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
const CPUArchIdList *cpu_list, GArray *entry);
|
||||
+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
|
||||
123
arm-virt-gic-Construct-irqs-connection-from-create_g.patch
Normal file
123
arm-virt-gic-Construct-irqs-connection-from-create_g.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 92124743f4560c490780a229f53ea5881f706383 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
|
||||
|
||||
Make the irqs can be connected to for individual CPU.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/virt.c | 90 ++++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 49 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 83f4887e57..55d403bad6 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);
|
||||
}
|
||||
|
||||
+static void connect_gic_cpu_irqs(VirtMachineState *vms, int i)
|
||||
+{
|
||||
+ DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
|
||||
+ SysBusDevice *gicbusdev = SYS_BUS_DEVICE(vms->gic);
|
||||
+ int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
|
||||
+ int num_cpus = object_property_get_uint(OBJECT(vms->gic), "num-cpu", NULL);
|
||||
+ int gic_type = vms->gic_version;
|
||||
+ int irq;
|
||||
+ /* Mapping from the output timer irq lines from the CPU to the
|
||||
+ * GIC PPI inputs we use for the virt board.
|
||||
+ */
|
||||
+ const int timer_irq[] = {
|
||||
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
|
||||
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
|
||||
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
|
||||
+ [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
|
||||
+ };
|
||||
+
|
||||
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
|
||||
+ qdev_connect_gpio_out(cpudev, irq,
|
||||
+ qdev_get_gpio_in(vms->gic,
|
||||
+ ppibase + timer_irq[irq]));
|
||||
+ }
|
||||
+
|
||||
+ if (gic_type == 3) {
|
||||
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
+ ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
|
||||
+ 0, irq);
|
||||
+ } else if (vms->virt) {
|
||||
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
+ ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
+ sysbus_connect_irq(gicbusdev, i + 4 * num_cpus, irq);
|
||||
+ }
|
||||
+
|
||||
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
|
||||
+ qdev_get_gpio_in(vms->gic, ppibase
|
||||
+ + VIRTUAL_PMU_IRQ));
|
||||
+
|
||||
+ sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
|
||||
+ sysbus_connect_irq(gicbusdev, i + num_cpus,
|
||||
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
|
||||
+ sysbus_connect_irq(gicbusdev, i + 2 * num_cpus,
|
||||
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
|
||||
+ sysbus_connect_irq(gicbusdev, i + 3 * num_cpus,
|
||||
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
|
||||
+}
|
||||
+
|
||||
static void create_gic(VirtMachineState *vms)
|
||||
{
|
||||
MachineState *ms = MACHINE(vms);
|
||||
@@ -775,47 +823,7 @@ static void create_gic(VirtMachineState *vms)
|
||||
* and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
|
||||
*/
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
- DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
|
||||
- int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
|
||||
- int irq;
|
||||
- /* Mapping from the output timer irq lines from the CPU to the
|
||||
- * GIC PPI inputs we use for the virt board.
|
||||
- */
|
||||
- const int timer_irq[] = {
|
||||
- [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
|
||||
- [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
|
||||
- [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
|
||||
- [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
|
||||
- };
|
||||
-
|
||||
- for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
|
||||
- qdev_connect_gpio_out(cpudev, irq,
|
||||
- qdev_get_gpio_in(vms->gic,
|
||||
- ppibase + timer_irq[irq]));
|
||||
- }
|
||||
-
|
||||
- if (type == 3) {
|
||||
- qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
- ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
- qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
|
||||
- 0, irq);
|
||||
- } else if (vms->virt) {
|
||||
- qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
- ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
- sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
|
||||
- }
|
||||
-
|
||||
- qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
|
||||
- qdev_get_gpio_in(vms->gic, ppibase
|
||||
- + VIRTUAL_PMU_IRQ));
|
||||
-
|
||||
- sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
|
||||
- sysbus_connect_irq(gicbusdev, i + smp_cpus,
|
||||
- qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
|
||||
- sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
|
||||
- qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
|
||||
- sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
|
||||
- qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
|
||||
+ connect_gic_cpu_irqs(vms, i);
|
||||
}
|
||||
|
||||
fdt_add_gic_node(vms);
|
||||
--
|
||||
2.19.1
|
||||
91
ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch
Normal file
91
ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch
Normal file
@ -0,0 +1,91 @@
|
||||
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
|
||||
|
||||
24
bios-tables-test-prepare-to-change-ARM-virt-ACPI-DSDT.patch
Normal file
24
bios-tables-test-prepare-to-change-ARM-virt-ACPI-DSDT.patch
Normal file
@ -0,0 +1,24 @@
|
||||
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
|
||||
59
block-Add-bdrv_co_get_self_request.patch
Normal file
59
block-Add-bdrv_co_get_self_request.patch
Normal file
@ -0,0 +1,59 @@
|
||||
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
|
||||
131
block-Make-wait-mark-serialising-requests-public.patch
Normal file
131
block-Make-wait-mark-serialising-requests-public.patch
Normal file
@ -0,0 +1,131 @@
|
||||
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
|
||||
95
block-create-Do-not-abort-if-a-block-driver-is-not-a.patch
Normal file
95
block-create-Do-not-abort-if-a-block-driver-is-not-a.patch
Normal file
@ -0,0 +1,95 @@
|
||||
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
|
||||
69
block-file-posix-Let-post-EOF-fallocate-serialize.patch
Normal file
69
block-file-posix-Let-post-EOF-fallocate-serialize.patch
Normal file
@ -0,0 +1,69 @@
|
||||
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
|
||||
165
block-file-posix-Reduce-xfsctl-use.patch
Normal file
165
block-file-posix-Reduce-xfsctl-use.patch
Normal file
@ -0,0 +1,165 @@
|
||||
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
|
||||
481
block-io-refactor-padding.patch
Normal file
481
block-io-refactor-padding.patch
Normal file
@ -0,0 +1,481 @@
|
||||
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
|
||||
41
block-nfs-tear-down-aio-before-nfs_close.patch
Normal file
41
block-nfs-tear-down-aio-before-nfs_close.patch
Normal file
@ -0,0 +1,41 @@
|
||||
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
|
||||
343
block-posix-Always-allocate-the-first-block.patch
Normal file
343
block-posix-Always-allocate-the-first-block.patch
Normal file
@ -0,0 +1,343 @@
|
||||
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
|
||||
66
block-qcow2-Fix-corruption-introduced-by-commit-8ac0.patch
Normal file
66
block-qcow2-Fix-corruption-introduced-by-commit-8ac0.patch
Normal file
@ -0,0 +1,66 @@
|
||||
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
|
||||
124
block-snapshot-Restrict-set-of-snapshot-nodes.patch
Normal file
124
block-snapshot-Restrict-set-of-snapshot-nodes.patch
Normal file
@ -0,0 +1,124 @@
|
||||
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
|
||||
61
blockjob-update-nodes-head-while-removing-all-bdrv.patch
Normal file
61
blockjob-update-nodes-head-while-removing-all-bdrv.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 86b0f4022bb43b16979ba5300e8d40a1e6d44b79 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Lopez <slp@redhat.com>
|
||||
Date: Wed, 11 Sep 2019 12:03:16 +0200
|
||||
Subject: [PATCH] blockjob: update nodes head while removing all bdrv
|
||||
|
||||
block_job_remove_all_bdrv() iterates through job->nodes, calling
|
||||
bdrv_root_unref_child() for each entry. The call to the latter may
|
||||
reach child_job_[can_]set_aio_ctx(), which will also attempt to
|
||||
traverse job->nodes, potentially finding entries that where freed
|
||||
on previous iterations.
|
||||
|
||||
To avoid this situation, update job->nodes head on each iteration to
|
||||
ensure that already freed entries are no longer linked to the list.
|
||||
|
||||
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1746631
|
||||
Signed-off-by: Sergio Lopez <slp@redhat.com>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
||||
Message-id: 20190911100316.32282-1-mreitz@redhat.com
|
||||
Reviewed-by: Sergio Lopez <slp@redhat.com>
|
||||
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
||||
(cherry picked from commit d876bf676f5e7c6aa9ac64555e48cba8734ecb2f)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
blockjob.c | 17 +++++++++++++----
|
||||
1 file changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/blockjob.c b/blockjob.c
|
||||
index 20b7f557da..74abb97bfd 100644
|
||||
--- a/blockjob.c
|
||||
+++ b/blockjob.c
|
||||
@@ -186,14 +186,23 @@ static const BdrvChildRole child_job = {
|
||||
|
||||
void block_job_remove_all_bdrv(BlockJob *job)
|
||||
{
|
||||
- GSList *l;
|
||||
- for (l = job->nodes; l; l = l->next) {
|
||||
+ /*
|
||||
+ * bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(),
|
||||
+ * which will also traverse job->nodes, so consume the list one by
|
||||
+ * one to make sure that such a concurrent access does not attempt
|
||||
+ * to process an already freed BdrvChild.
|
||||
+ */
|
||||
+ while (job->nodes) {
|
||||
+ GSList *l = job->nodes;
|
||||
BdrvChild *c = l->data;
|
||||
+
|
||||
+ job->nodes = l->next;
|
||||
+
|
||||
bdrv_op_unblock_all(c->bs, job->blocker);
|
||||
bdrv_root_unref_child(c);
|
||||
+
|
||||
+ g_slist_free_1(l);
|
||||
}
|
||||
- g_slist_free(job->nodes);
|
||||
- job->nodes = NULL;
|
||||
}
|
||||
|
||||
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
|
||||
--
|
||||
2.23.0
|
||||
794
bt-use-size_t-type-for-length-parameters-instead-of-.patch
Normal file
794
bt-use-size_t-type-for-length-parameters-instead-of-.patch
Normal file
@ -0,0 +1,794 @@
|
||||
From f9ab92373813cfccd31f29c0d963232f65cb5f88 Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Fri, 22 May 2020 12:22:26 +0800
|
||||
Subject: [PATCH] bt: use size_t type for length parameters instead of int
|
||||
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
|
||||
The length parameter values are not negative, thus use an unsigned
|
||||
type 'size_t' for them. Many routines pass 'len' values to memcpy(3)
|
||||
calls. If it was negative, it could lead to memory corruption issues.
|
||||
Add check to avoid it.
|
||||
|
||||
Reported-by: Arash TC <tohidi.arash@gmail.com>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
|
||||
diff --git a/bt-host.c b/bt-host.c
|
||||
index 2f8f631..b73a44d 100644
|
||||
--- a/bt-host.c
|
||||
+++ b/bt-host.c
|
||||
@@ -43,7 +43,7 @@ struct bt_host_hci_s {
|
||||
};
|
||||
|
||||
static void bt_host_send(struct HCIInfo *hci,
|
||||
- int type, const uint8_t *data, int len)
|
||||
+ int type, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct bt_host_hci_s *s = (struct bt_host_hci_s *) hci;
|
||||
uint8_t pkt = type;
|
||||
@@ -63,17 +63,17 @@ static void bt_host_send(struct HCIInfo *hci,
|
||||
}
|
||||
}
|
||||
|
||||
-static void bt_host_cmd(struct HCIInfo *hci, const uint8_t *data, int len)
|
||||
+static void bt_host_cmd(struct HCIInfo *hci, const uint8_t *data, size_t len)
|
||||
{
|
||||
bt_host_send(hci, HCI_COMMAND_PKT, data, len);
|
||||
}
|
||||
|
||||
-static void bt_host_acl(struct HCIInfo *hci, const uint8_t *data, int len)
|
||||
+static void bt_host_acl(struct HCIInfo *hci, const uint8_t *data, size_t len)
|
||||
{
|
||||
bt_host_send(hci, HCI_ACLDATA_PKT, data, len);
|
||||
}
|
||||
|
||||
-static void bt_host_sco(struct HCIInfo *hci, const uint8_t *data, int len)
|
||||
+static void bt_host_sco(struct HCIInfo *hci, const uint8_t *data, size_t len)
|
||||
{
|
||||
bt_host_send(hci, HCI_SCODATA_PKT, data, len);
|
||||
}
|
||||
diff --git a/bt-vhci.c b/bt-vhci.c
|
||||
index 886e146..32ef1c5 100644
|
||||
--- a/bt-vhci.c
|
||||
+++ b/bt-vhci.c
|
||||
@@ -89,7 +89,7 @@ static void vhci_read(void *opaque)
|
||||
}
|
||||
|
||||
static void vhci_host_send(void *opaque,
|
||||
- int type, const uint8_t *data, int len)
|
||||
+ int type, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct bt_vhci_s *s = (struct bt_vhci_s *) opaque;
|
||||
#if 0
|
||||
@@ -112,6 +112,7 @@ static void vhci_host_send(void *opaque,
|
||||
static uint8_t buf[4096];
|
||||
|
||||
buf[0] = type;
|
||||
+ assert(len < sizeof(buf));
|
||||
memcpy(buf + 1, data, len);
|
||||
|
||||
while (write(s->fd, buf, len + 1) < 0)
|
||||
@@ -124,13 +125,13 @@ static void vhci_host_send(void *opaque,
|
||||
}
|
||||
|
||||
static void vhci_out_hci_packet_event(void *opaque,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
vhci_host_send(opaque, HCI_EVENT_PKT, data, len);
|
||||
}
|
||||
|
||||
static void vhci_out_hci_packet_acl(void *opaque,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
vhci_host_send(opaque, HCI_ACLDATA_PKT, data, len);
|
||||
}
|
||||
diff --git a/hw/bt/core.c b/hw/bt/core.c
|
||||
index dfb196e..f548b3d 100644
|
||||
--- a/hw/bt/core.c
|
||||
+++ b/hw/bt/core.c
|
||||
@@ -44,7 +44,7 @@ static void bt_dummy_lmp_disconnect_master(struct bt_link_s *link)
|
||||
}
|
||||
|
||||
static void bt_dummy_lmp_acl_resp(struct bt_link_s *link,
|
||||
- const uint8_t *data, int start, int len)
|
||||
+ const uint8_t *data, int start, size_t len)
|
||||
{
|
||||
error_report("%s: stray ACL response PDU, fixme", __func__);
|
||||
exit(-1);
|
||||
diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
|
||||
index 3d60654..f7a74c0 100644
|
||||
--- a/hw/bt/hci-csr.c
|
||||
+++ b/hw/bt/hci-csr.c
|
||||
@@ -103,7 +103,7 @@ static inline void csrhci_fifo_wake(struct csrhci_s *s)
|
||||
}
|
||||
|
||||
#define csrhci_out_packetz(s, len) memset(csrhci_out_packet(s, len), 0, len)
|
||||
-static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len)
|
||||
+static uint8_t *csrhci_out_packet(struct csrhci_s *s, size_t len)
|
||||
{
|
||||
int off = s->out_start + s->out_len;
|
||||
|
||||
@@ -112,14 +112,14 @@ static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len)
|
||||
|
||||
if (off < FIFO_LEN) {
|
||||
if (off + len > FIFO_LEN && (s->out_size = off + len) > FIFO_LEN * 2) {
|
||||
- error_report("%s: can't alloc %i bytes", __func__, len);
|
||||
+ error_report("%s: can't alloc %zu bytes", __func__, len);
|
||||
exit(-1);
|
||||
}
|
||||
return s->outfifo + off;
|
||||
}
|
||||
|
||||
if (s->out_len > s->out_size) {
|
||||
- error_report("%s: can't alloc %i bytes", __func__, len);
|
||||
+ error_report("%s: can't alloc %zu bytes", __func__, len);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len)
|
||||
}
|
||||
|
||||
static inline uint8_t *csrhci_out_packet_csr(struct csrhci_s *s,
|
||||
- int type, int len)
|
||||
+ int type, size_t len)
|
||||
{
|
||||
uint8_t *ret = csrhci_out_packetz(s, len + 2);
|
||||
|
||||
@@ -138,7 +138,7 @@ static inline uint8_t *csrhci_out_packet_csr(struct csrhci_s *s,
|
||||
}
|
||||
|
||||
static inline uint8_t *csrhci_out_packet_event(struct csrhci_s *s,
|
||||
- int evt, int len)
|
||||
+ int evt, size_t len)
|
||||
{
|
||||
uint8_t *ret = csrhci_out_packetz(s,
|
||||
len + 1 + sizeof(struct hci_event_hdr));
|
||||
@@ -151,7 +151,7 @@ static inline uint8_t *csrhci_out_packet_event(struct csrhci_s *s,
|
||||
}
|
||||
|
||||
static void csrhci_in_packet_vendor(struct csrhci_s *s, int ocf,
|
||||
- uint8_t *data, int len)
|
||||
+ uint8_t *data, size_t len)
|
||||
{
|
||||
int offset;
|
||||
uint8_t *rpkt;
|
||||
@@ -320,18 +320,18 @@ static int csrhci_write(struct Chardev *chr,
|
||||
struct csrhci_s *s = (struct csrhci_s *)chr;
|
||||
int total = 0;
|
||||
|
||||
- if (!s->enable)
|
||||
+ if (!s->enable || len <= 0)
|
||||
return 0;
|
||||
|
||||
for (;;) {
|
||||
int cnt = MIN(len, s->in_needed - s->in_len);
|
||||
- if (cnt) {
|
||||
- memcpy(s->inpkt + s->in_len, buf, cnt);
|
||||
- s->in_len += cnt;
|
||||
- buf += cnt;
|
||||
- len -= cnt;
|
||||
- total += cnt;
|
||||
- }
|
||||
+ assert(cnt > 0);
|
||||
+
|
||||
+ memcpy(s->inpkt + s->in_len, buf, cnt);
|
||||
+ s->in_len += cnt;
|
||||
+ buf += cnt;
|
||||
+ len -= cnt;
|
||||
+ total += cnt;
|
||||
|
||||
if (s->in_len < s->in_needed) {
|
||||
break;
|
||||
@@ -363,7 +363,7 @@ static int csrhci_write(struct Chardev *chr,
|
||||
}
|
||||
|
||||
static void csrhci_out_hci_packet_event(void *opaque,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
struct csrhci_s *s = (struct csrhci_s *) opaque;
|
||||
uint8_t *pkt = csrhci_out_packet(s, (len + 2) & ~1); /* Align */
|
||||
@@ -375,7 +375,7 @@ static void csrhci_out_hci_packet_event(void *opaque,
|
||||
}
|
||||
|
||||
static void csrhci_out_hci_packet_acl(void *opaque,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
struct csrhci_s *s = (struct csrhci_s *) opaque;
|
||||
uint8_t *pkt = csrhci_out_packet(s, (len + 2) & ~1); /* Align */
|
||||
diff --git a/hw/bt/hci.c b/hw/bt/hci.c
|
||||
index c7958f6..9c4f957 100644
|
||||
--- a/hw/bt/hci.c
|
||||
+++ b/hw/bt/hci.c
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
struct bt_hci_s {
|
||||
uint8_t *(*evt_packet)(void *opaque);
|
||||
- void (*evt_submit)(void *opaque, int len);
|
||||
+ void (*evt_submit)(void *opaque, size_t len);
|
||||
void *opaque;
|
||||
uint8_t evt_buf[256];
|
||||
|
||||
@@ -61,7 +61,7 @@ struct bt_hci_s {
|
||||
struct bt_hci_master_link_s {
|
||||
struct bt_link_s *link;
|
||||
void (*lmp_acl_data)(struct bt_link_s *link,
|
||||
- const uint8_t *data, int start, int len);
|
||||
+ const uint8_t *data, int start, size_t len);
|
||||
QEMUTimer *acl_mode_timer;
|
||||
} handle[HCI_HANDLES_MAX];
|
||||
uint32_t role_bmp;
|
||||
@@ -433,7 +433,7 @@ static const uint8_t bt_event_reserved_mask[8] = {
|
||||
};
|
||||
|
||||
|
||||
-static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
|
||||
+static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, size_t len)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -451,13 +451,13 @@ struct HCIInfo null_hci = {
|
||||
|
||||
|
||||
static inline uint8_t *bt_hci_event_start(struct bt_hci_s *hci,
|
||||
- int evt, int len)
|
||||
+ int evt, size_t len)
|
||||
{
|
||||
uint8_t *packet, mask;
|
||||
int mask_byte;
|
||||
|
||||
if (len > 255) {
|
||||
- error_report("%s: HCI event params too long (%ib)", __func__, len);
|
||||
+ error_report("%s: HCI event params too long (%zub)", __func__, len);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ static inline uint8_t *bt_hci_event_start(struct bt_hci_s *hci,
|
||||
}
|
||||
|
||||
static inline void bt_hci_event(struct bt_hci_s *hci, int evt,
|
||||
- void *params, int len)
|
||||
+ void *params, size_t len)
|
||||
{
|
||||
uint8_t *packet = bt_hci_event_start(hci, evt, len);
|
||||
|
||||
@@ -499,7 +499,7 @@ static inline void bt_hci_event_status(struct bt_hci_s *hci, int status)
|
||||
}
|
||||
|
||||
static inline void bt_hci_event_complete(struct bt_hci_s *hci,
|
||||
- void *ret, int len)
|
||||
+ void *ret, size_t len)
|
||||
{
|
||||
uint8_t *packet = bt_hci_event_start(hci, EVT_CMD_COMPLETE,
|
||||
len + EVT_CMD_COMPLETE_SIZE);
|
||||
@@ -1476,7 +1476,7 @@ static inline void bt_hci_event_num_comp_pkts(struct bt_hci_s *hci,
|
||||
}
|
||||
|
||||
static void bt_submit_hci(struct HCIInfo *info,
|
||||
- const uint8_t *data, int length)
|
||||
+ const uint8_t *data, size_t length)
|
||||
{
|
||||
struct bt_hci_s *hci = hci_from_info(info);
|
||||
uint16_t cmd;
|
||||
@@ -1970,7 +1970,7 @@ static void bt_submit_hci(struct HCIInfo *info,
|
||||
break;
|
||||
|
||||
short_hci:
|
||||
- error_report("%s: HCI packet too short (%iB)", __func__, length);
|
||||
+ error_report("%s: HCI packet too short (%zuB)", __func__, length);
|
||||
bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);
|
||||
break;
|
||||
}
|
||||
@@ -1981,7 +1981,7 @@ static void bt_submit_hci(struct HCIInfo *info,
|
||||
* know that a packet contained the last fragment of the SDU when the next
|
||||
* SDU starts. */
|
||||
static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle,
|
||||
- const uint8_t *data, int start, int len)
|
||||
+ const uint8_t *data, int start, size_t len)
|
||||
{
|
||||
struct hci_acl_hdr *pkt = (void *) hci->acl_buf;
|
||||
|
||||
@@ -1989,7 +1989,7 @@ static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle,
|
||||
/* TODO: avoid memcpy'ing */
|
||||
|
||||
if (len + HCI_ACL_HDR_SIZE > sizeof(hci->acl_buf)) {
|
||||
- error_report("%s: can't take ACL packets %i bytes long",
|
||||
+ error_report("%s: can't take ACL packets %zu bytes long",
|
||||
__func__, len);
|
||||
return;
|
||||
}
|
||||
@@ -2003,7 +2003,7 @@ static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle,
|
||||
}
|
||||
|
||||
static void bt_hci_lmp_acl_data_slave(struct bt_link_s *btlink,
|
||||
- const uint8_t *data, int start, int len)
|
||||
+ const uint8_t *data, int start, size_t len)
|
||||
{
|
||||
struct bt_hci_link_s *link = (struct bt_hci_link_s *) btlink;
|
||||
|
||||
@@ -2012,14 +2012,14 @@ static void bt_hci_lmp_acl_data_slave(struct bt_link_s *btlink,
|
||||
}
|
||||
|
||||
static void bt_hci_lmp_acl_data_host(struct bt_link_s *link,
|
||||
- const uint8_t *data, int start, int len)
|
||||
+ const uint8_t *data, int start, size_t len)
|
||||
{
|
||||
bt_hci_lmp_acl_data(hci_from_device(link->host),
|
||||
link->handle, data, start, len);
|
||||
}
|
||||
|
||||
static void bt_submit_acl(struct HCIInfo *info,
|
||||
- const uint8_t *data, int length)
|
||||
+ const uint8_t *data, size_t length)
|
||||
{
|
||||
struct bt_hci_s *hci = hci_from_info(info);
|
||||
uint16_t handle;
|
||||
@@ -2027,7 +2027,7 @@ static void bt_submit_acl(struct HCIInfo *info,
|
||||
struct bt_link_s *link;
|
||||
|
||||
if (length < HCI_ACL_HDR_SIZE) {
|
||||
- error_report("%s: ACL packet too short (%iB)", __func__, length);
|
||||
+ error_report("%s: ACL packet too short (%zuB)", __func__, length);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2045,7 +2045,7 @@ static void bt_submit_acl(struct HCIInfo *info,
|
||||
handle &= ~HCI_HANDLE_OFFSET;
|
||||
|
||||
if (datalen > length) {
|
||||
- error_report("%s: ACL packet too short (%iB < %iB)",
|
||||
+ error_report("%s: ACL packet too short (%zuB < %iB)",
|
||||
__func__, length, datalen);
|
||||
return;
|
||||
}
|
||||
@@ -2087,7 +2087,7 @@ static void bt_submit_acl(struct HCIInfo *info,
|
||||
}
|
||||
|
||||
static void bt_submit_sco(struct HCIInfo *info,
|
||||
- const uint8_t *data, int length)
|
||||
+ const uint8_t *data, size_t length)
|
||||
{
|
||||
struct bt_hci_s *hci = hci_from_info(info);
|
||||
uint16_t handle;
|
||||
@@ -2106,7 +2106,7 @@ static void bt_submit_sco(struct HCIInfo *info,
|
||||
}
|
||||
|
||||
if (datalen > length) {
|
||||
- error_report("%s: SCO packet too short (%iB < %iB)",
|
||||
+ error_report("%s: SCO packet too short (%zuB < %iB)",
|
||||
__func__, length, datalen);
|
||||
return;
|
||||
}
|
||||
@@ -2127,7 +2127,7 @@ static uint8_t *bt_hci_evt_packet(void *opaque)
|
||||
return s->evt_buf;
|
||||
}
|
||||
|
||||
-static void bt_hci_evt_submit(void *opaque, int len)
|
||||
+static void bt_hci_evt_submit(void *opaque, size_t len)
|
||||
{
|
||||
/* TODO: notify upper layer */
|
||||
struct bt_hci_s *s = opaque;
|
||||
diff --git a/hw/bt/hid.c b/hw/bt/hid.c
|
||||
index 066ca99..fe15434 100644
|
||||
--- a/hw/bt/hid.c
|
||||
+++ b/hw/bt/hid.c
|
||||
@@ -95,7 +95,7 @@ struct bt_hid_device_s {
|
||||
int data_type;
|
||||
int intr_state;
|
||||
struct {
|
||||
- int len;
|
||||
+ size_t len;
|
||||
uint8_t buffer[1024];
|
||||
} dataother, datain, dataout, feature, intrdataout;
|
||||
enum {
|
||||
@@ -168,7 +168,7 @@ static void bt_hid_disconnect(struct bt_hid_device_s *s)
|
||||
}
|
||||
|
||||
static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t *pkt, hdr = (BT_DATA << 4) | type;
|
||||
int plen;
|
||||
@@ -189,7 +189,7 @@ static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type,
|
||||
}
|
||||
|
||||
static void bt_hid_control_transaction(struct bt_hid_device_s *s,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t type, parameter;
|
||||
int rlen, ret = -1;
|
||||
@@ -361,7 +361,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s,
|
||||
bt_hid_send_handshake(s, ret);
|
||||
}
|
||||
|
||||
-static void bt_hid_control_sdu(void *opaque, const uint8_t *data, int len)
|
||||
+static void bt_hid_control_sdu(void *opaque, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct bt_hid_device_s *hid = opaque;
|
||||
|
||||
@@ -387,7 +387,7 @@ static void bt_hid_datain(HIDState *hs)
|
||||
hid->datain.buffer, hid->datain.len);
|
||||
}
|
||||
|
||||
-static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len)
|
||||
+static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct bt_hid_device_s *hid = opaque;
|
||||
|
||||
diff --git a/hw/bt/l2cap.c b/hw/bt/l2cap.c
|
||||
index d67098a..2f70a03 100644
|
||||
--- a/hw/bt/l2cap.c
|
||||
+++ b/hw/bt/l2cap.c
|
||||
@@ -31,10 +31,10 @@ struct l2cap_instance_s {
|
||||
int role;
|
||||
|
||||
uint8_t frame_in[65535 + L2CAP_HDR_SIZE] __attribute__ ((aligned (4)));
|
||||
- int frame_in_len;
|
||||
+ uint32_t frame_in_len;
|
||||
|
||||
uint8_t frame_out[65535 + L2CAP_HDR_SIZE] __attribute__ ((aligned (4)));
|
||||
- int frame_out_len;
|
||||
+ uint32_t frame_out_len;
|
||||
|
||||
/* Signalling channel timers. They exist per-request but we can make
|
||||
* sure we have no more than one outstanding request at any time. */
|
||||
@@ -48,7 +48,7 @@ struct l2cap_instance_s {
|
||||
struct bt_l2cap_conn_params_s params;
|
||||
|
||||
void (*frame_in)(struct l2cap_chan_s *chan, uint16_t cid,
|
||||
- const l2cap_hdr *hdr, int len);
|
||||
+ const l2cap_hdr *hdr, size_t len);
|
||||
int mps;
|
||||
int min_mtu;
|
||||
|
||||
@@ -67,7 +67,7 @@ struct l2cap_instance_s {
|
||||
|
||||
/* Only flow-controlled, connection-oriented channels */
|
||||
uint8_t sdu[65536]; /* TODO: dynamically allocate */
|
||||
- int len_cur, len_total;
|
||||
+ uint32_t len_cur, len_total;
|
||||
int rexmit;
|
||||
int monitor_timeout;
|
||||
QEMUTimer *monitor_timer;
|
||||
@@ -139,7 +139,7 @@ static const uint16_t l2cap_fcs16_table[256] = {
|
||||
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
|
||||
};
|
||||
|
||||
-static uint16_t l2cap_fcs16(const uint8_t *message, int len)
|
||||
+static uint16_t l2cap_fcs16(const uint8_t *message, size_t len)
|
||||
{
|
||||
uint16_t fcs = 0x0000;
|
||||
|
||||
@@ -185,7 +185,7 @@ static void l2cap_monitor_timer_update(struct l2cap_chan_s *ch)
|
||||
}
|
||||
|
||||
static void l2cap_command_reject(struct l2cap_instance_s *l2cap, int id,
|
||||
- uint16_t reason, const void *data, int plen)
|
||||
+ uint16_t reason, const void *data, size_t plen)
|
||||
{
|
||||
uint8_t *pkt;
|
||||
l2cap_cmd_hdr *hdr;
|
||||
@@ -246,7 +246,7 @@ static void l2cap_connection_response(struct l2cap_instance_s *l2cap,
|
||||
}
|
||||
|
||||
static void l2cap_configuration_request(struct l2cap_instance_s *l2cap,
|
||||
- int dcid, int flag, const uint8_t *data, int len)
|
||||
+ int dcid, int flag, const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t *pkt;
|
||||
l2cap_cmd_hdr *hdr;
|
||||
@@ -274,7 +274,7 @@ static void l2cap_configuration_request(struct l2cap_instance_s *l2cap,
|
||||
}
|
||||
|
||||
static void l2cap_configuration_response(struct l2cap_instance_s *l2cap,
|
||||
- int scid, int flag, int result, const uint8_t *data, int len)
|
||||
+ int scid, int flag, int result, const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t *pkt;
|
||||
l2cap_cmd_hdr *hdr;
|
||||
@@ -321,7 +321,7 @@ static void l2cap_disconnection_response(struct l2cap_instance_s *l2cap,
|
||||
}
|
||||
|
||||
static void l2cap_echo_response(struct l2cap_instance_s *l2cap,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t *pkt;
|
||||
l2cap_cmd_hdr *hdr;
|
||||
@@ -342,7 +342,7 @@ static void l2cap_echo_response(struct l2cap_instance_s *l2cap,
|
||||
}
|
||||
|
||||
static void l2cap_info_response(struct l2cap_instance_s *l2cap, int type,
|
||||
- int result, const uint8_t *data, int len)
|
||||
+ int result, const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t *pkt;
|
||||
l2cap_cmd_hdr *hdr;
|
||||
@@ -365,16 +365,18 @@ static void l2cap_info_response(struct l2cap_instance_s *l2cap, int type,
|
||||
l2cap->signalling_ch.params.sdu_submit(&l2cap->signalling_ch.params);
|
||||
}
|
||||
|
||||
-static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, int len);
|
||||
+static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm,
|
||||
+ size_t len);
|
||||
static void l2cap_bframe_submit(struct bt_l2cap_conn_params_s *parms);
|
||||
#if 0
|
||||
-static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, int len);
|
||||
+static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm,
|
||||
+ size_t len);
|
||||
static void l2cap_iframe_submit(struct bt_l2cap_conn_params_s *parm);
|
||||
#endif
|
||||
static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid,
|
||||
- const l2cap_hdr *hdr, int len);
|
||||
+ const l2cap_hdr *hdr, size_t len);
|
||||
static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid,
|
||||
- const l2cap_hdr *hdr, int len);
|
||||
+ const l2cap_hdr *hdr, size_t len);
|
||||
|
||||
static int l2cap_cid_new(struct l2cap_instance_s *l2cap)
|
||||
{
|
||||
@@ -498,7 +500,7 @@ static void l2cap_channel_config_req_event(struct l2cap_instance_s *l2cap,
|
||||
|
||||
static int l2cap_channel_config(struct l2cap_instance_s *l2cap,
|
||||
struct l2cap_chan_s *ch, int flag,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
l2cap_conf_opt *opt;
|
||||
l2cap_conf_opt_qos *qos;
|
||||
@@ -683,7 +685,7 @@ static int l2cap_channel_config(struct l2cap_instance_s *l2cap,
|
||||
}
|
||||
|
||||
static void l2cap_channel_config_req_msg(struct l2cap_instance_s *l2cap,
|
||||
- int flag, int cid, const uint8_t *data, int len)
|
||||
+ int flag, int cid, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct l2cap_chan_s *ch;
|
||||
|
||||
@@ -715,7 +717,7 @@ static void l2cap_channel_config_req_msg(struct l2cap_instance_s *l2cap,
|
||||
}
|
||||
|
||||
static int l2cap_channel_config_rsp_msg(struct l2cap_instance_s *l2cap,
|
||||
- int result, int flag, int cid, const uint8_t *data, int len)
|
||||
+ int result, int flag, int cid, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct l2cap_chan_s *ch;
|
||||
|
||||
@@ -783,7 +785,7 @@ static void l2cap_info(struct l2cap_instance_s *l2cap, int type)
|
||||
}
|
||||
|
||||
static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
|
||||
- const uint8_t *params, int len)
|
||||
+ const uint8_t *params, size_t len)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -938,7 +940,7 @@ static void l2cap_rexmit_enable(struct l2cap_chan_s *ch, int enable)
|
||||
}
|
||||
|
||||
/* Command frame SDU */
|
||||
-static void l2cap_cframe_in(void *opaque, const uint8_t *data, int len)
|
||||
+static void l2cap_cframe_in(void *opaque, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct l2cap_instance_s *l2cap = opaque;
|
||||
const l2cap_cmd_hdr *hdr;
|
||||
@@ -966,7 +968,7 @@ static void l2cap_cframe_in(void *opaque, const uint8_t *data, int len)
|
||||
}
|
||||
|
||||
/* Group frame SDU */
|
||||
-static void l2cap_gframe_in(void *opaque, const uint8_t *data, int len)
|
||||
+static void l2cap_gframe_in(void *opaque, const uint8_t *data, size_t len)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -977,7 +979,7 @@ static void l2cap_sframe_in(struct l2cap_chan_s *ch, uint16_t ctrl)
|
||||
|
||||
/* Basic L2CAP mode Information frame */
|
||||
static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid,
|
||||
- const l2cap_hdr *hdr, int len)
|
||||
+ const l2cap_hdr *hdr, size_t len)
|
||||
{
|
||||
/* We have a full SDU, no further processing */
|
||||
ch->params.sdu_in(ch->params.opaque, hdr->data, len);
|
||||
@@ -985,7 +987,7 @@ static void l2cap_bframe_in(struct l2cap_chan_s *ch, uint16_t cid,
|
||||
|
||||
/* Flow Control and Retransmission mode frame */
|
||||
static void l2cap_iframe_in(struct l2cap_chan_s *ch, uint16_t cid,
|
||||
- const l2cap_hdr *hdr, int len)
|
||||
+ const l2cap_hdr *hdr, size_t len)
|
||||
{
|
||||
uint16_t fcs = lduw_le_p(hdr->data + len - 2);
|
||||
|
||||
@@ -1076,7 +1078,7 @@ static void l2cap_frame_in(struct l2cap_instance_s *l2cap,
|
||||
|
||||
/* "Recombination" */
|
||||
static void l2cap_pdu_in(struct l2cap_instance_s *l2cap,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
const l2cap_hdr *hdr = (void *) l2cap->frame_in;
|
||||
|
||||
@@ -1123,7 +1125,7 @@ static inline void l2cap_pdu_submit(struct l2cap_instance_s *l2cap)
|
||||
(l2cap->link, l2cap->frame_out, 1, l2cap->frame_out_len);
|
||||
}
|
||||
|
||||
-static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, int len)
|
||||
+static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, size_t len)
|
||||
{
|
||||
struct l2cap_chan_s *chan = (struct l2cap_chan_s *) parm;
|
||||
|
||||
@@ -1146,7 +1148,7 @@ static void l2cap_bframe_submit(struct bt_l2cap_conn_params_s *parms)
|
||||
|
||||
#if 0
|
||||
/* Stub: Only used if an emulated device requests outgoing flow control */
|
||||
-static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, int len)
|
||||
+static uint8_t *l2cap_iframe_out(struct bt_l2cap_conn_params_s *parm, size_t len)
|
||||
{
|
||||
struct l2cap_chan_s *chan = (struct l2cap_chan_s *) parm;
|
||||
|
||||
@@ -1291,7 +1293,7 @@ static void l2cap_lmp_disconnect_slave(struct bt_link_s *link)
|
||||
}
|
||||
|
||||
static void l2cap_lmp_acl_data_slave(struct bt_link_s *link,
|
||||
- const uint8_t *data, int start, int len)
|
||||
+ const uint8_t *data, int start, size_t len)
|
||||
{
|
||||
struct slave_l2cap_instance_s *l2cap =
|
||||
(struct slave_l2cap_instance_s *) link;
|
||||
@@ -1304,7 +1306,7 @@ static void l2cap_lmp_acl_data_slave(struct bt_link_s *link,
|
||||
|
||||
/* Stub */
|
||||
static void l2cap_lmp_acl_data_host(struct bt_link_s *link,
|
||||
- const uint8_t *data, int start, int len)
|
||||
+ const uint8_t *data, int start, size_t len)
|
||||
{
|
||||
struct bt_l2cap_device_s *dev = (struct bt_l2cap_device_s *) link->host;
|
||||
struct l2cap_instance_s *l2cap =
|
||||
diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c
|
||||
index 2860d76..6bfb174 100644
|
||||
--- a/hw/bt/sdp.c
|
||||
+++ b/hw/bt/sdp.c
|
||||
@@ -496,7 +496,7 @@ static ssize_t sdp_svc_search_attr_get(struct bt_l2cap_sdp_state_s *sdp,
|
||||
return end + 2;
|
||||
}
|
||||
|
||||
-static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
|
||||
+static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, size_t len)
|
||||
{
|
||||
struct bt_l2cap_sdp_state_s *sdp = opaque;
|
||||
enum bt_sdp_cmd pdu_id;
|
||||
@@ -506,7 +506,7 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
|
||||
int rsp_len = 0;
|
||||
|
||||
if (len < 5) {
|
||||
- error_report("%s: short SDP PDU (%iB).", __func__, len);
|
||||
+ error_report("%s: short SDP PDU (%zuB).", __func__, len);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -517,7 +517,7 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
|
||||
len -= 5;
|
||||
|
||||
if (len != plen) {
|
||||
- error_report("%s: wrong SDP PDU length (%iB != %iB).",
|
||||
+ error_report("%s: wrong SDP PDU length (%iB != %zuB).",
|
||||
__func__, plen, len);
|
||||
err = SDP_INVALID_PDU_SIZE;
|
||||
goto respond;
|
||||
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
|
||||
index 670ba32..240a901 100644
|
||||
--- a/hw/usb/dev-bluetooth.c
|
||||
+++ b/hw/usb/dev-bluetooth.c
|
||||
@@ -265,7 +265,7 @@ static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s *fifo)
|
||||
}
|
||||
|
||||
static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
int off = fifo->dstart + fifo->dlen;
|
||||
uint8_t *buf;
|
||||
@@ -274,13 +274,13 @@ static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
|
||||
if (off <= DFIFO_LEN_MASK) {
|
||||
if (off + len > DFIFO_LEN_MASK + 1 &&
|
||||
(fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) {
|
||||
- fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len);
|
||||
+ fprintf(stderr, "%s: can't alloc %zu bytes\n", __func__, len);
|
||||
exit(-1);
|
||||
}
|
||||
buf = fifo->data + off;
|
||||
} else {
|
||||
if (fifo->dlen > fifo->dsize) {
|
||||
- fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len);
|
||||
+ fprintf(stderr, "%s: can't alloc %zu bytes\n", __func__, len);
|
||||
exit(-1);
|
||||
}
|
||||
buf = fifo->data + off - fifo->dsize;
|
||||
@@ -319,7 +319,7 @@ static inline void usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo,
|
||||
|
||||
static inline void usb_bt_fifo_out_enqueue(struct USBBtState *s,
|
||||
struct usb_hci_out_fifo_s *fifo,
|
||||
- void (*send)(struct HCIInfo *, const uint8_t *, int),
|
||||
+ void (*send)(struct HCIInfo *, const uint8_t *, size_t),
|
||||
int (*complete)(const uint8_t *, int),
|
||||
USBPacket *p)
|
||||
{
|
||||
@@ -478,7 +478,7 @@ static void usb_bt_handle_data(USBDevice *dev, USBPacket *p)
|
||||
}
|
||||
|
||||
static void usb_bt_out_hci_packet_event(void *opaque,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
struct USBBtState *s = (struct USBBtState *) opaque;
|
||||
|
||||
@@ -489,7 +489,7 @@ static void usb_bt_out_hci_packet_event(void *opaque,
|
||||
}
|
||||
|
||||
static void usb_bt_out_hci_packet_acl(void *opaque,
|
||||
- const uint8_t *data, int len)
|
||||
+ const uint8_t *data, size_t len)
|
||||
{
|
||||
struct USBBtState *s = (struct USBBtState *) opaque;
|
||||
|
||||
diff --git a/include/hw/bt.h b/include/hw/bt.h
|
||||
index b5e11d4..bc362aa 100644
|
||||
--- a/include/hw/bt.h
|
||||
+++ b/include/hw/bt.h
|
||||
@@ -94,9 +94,9 @@ struct bt_device_s {
|
||||
void (*lmp_disconnect_master)(struct bt_link_s *link);
|
||||
void (*lmp_disconnect_slave)(struct bt_link_s *link);
|
||||
void (*lmp_acl_data)(struct bt_link_s *link, const uint8_t *data,
|
||||
- int start, int len);
|
||||
+ int start, size_t len);
|
||||
void (*lmp_acl_resp)(struct bt_link_s *link, const uint8_t *data,
|
||||
- int start, int len);
|
||||
+ int start, size_t len);
|
||||
void (*lmp_mode_change)(struct bt_link_s *link);
|
||||
|
||||
void (*handle_destroy)(struct bt_device_s *device);
|
||||
@@ -148,12 +148,12 @@ struct bt_l2cap_device_s {
|
||||
|
||||
struct bt_l2cap_conn_params_s {
|
||||
/* Input */
|
||||
- uint8_t *(*sdu_out)(struct bt_l2cap_conn_params_s *chan, int len);
|
||||
+ uint8_t *(*sdu_out)(struct bt_l2cap_conn_params_s *chan, size_t len);
|
||||
void (*sdu_submit)(struct bt_l2cap_conn_params_s *chan);
|
||||
int remote_mtu;
|
||||
/* Output */
|
||||
void *opaque;
|
||||
- void (*sdu_in)(void *opaque, const uint8_t *data, int len);
|
||||
+ void (*sdu_in)(void *opaque, const uint8_t *data, size_t len);
|
||||
void (*close)(void *opaque);
|
||||
};
|
||||
|
||||
diff --git a/include/sysemu/bt.h b/include/sysemu/bt.h
|
||||
index 2fd8c0f..df8fb63 100644
|
||||
--- a/include/sysemu/bt.h
|
||||
+++ b/include/sysemu/bt.h
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
typedef struct HCIInfo {
|
||||
int (*bdaddr_set)(struct HCIInfo *hci, const uint8_t *bd_addr);
|
||||
- void (*cmd_send)(struct HCIInfo *hci, const uint8_t *data, int len);
|
||||
- void (*sco_send)(struct HCIInfo *hci, const uint8_t *data, int len);
|
||||
- void (*acl_send)(struct HCIInfo *hci, const uint8_t *data, int len);
|
||||
+ void (*cmd_send)(struct HCIInfo *hci, const uint8_t *data, size_t len);
|
||||
+ void (*sco_send)(struct HCIInfo *hci, const uint8_t *data, size_t len);
|
||||
+ void (*acl_send)(struct HCIInfo *hci, const uint8_t *data, size_t len);
|
||||
void *opaque;
|
||||
- void (*evt_recv)(void *opaque, const uint8_t *data, int len);
|
||||
- void (*acl_recv)(void *opaque, const uint8_t *data, int len);
|
||||
+ void (*evt_recv)(void *opaque, const uint8_t *data, size_t len);
|
||||
+ void (*acl_recv)(void *opaque, const uint8_t *data, size_t len);
|
||||
} HCIInfo;
|
||||
|
||||
/* bt-host.c */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
44
bugfix-Use-gicr_typer-in-arm_gicv3_icc_reset.patch
Normal file
44
bugfix-Use-gicr_typer-in-arm_gicv3_icc_reset.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From b9e4a4ff6f3292927adb1463777c86cd4063a6ef Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Sat, 18 Apr 2020 12:10:11 +0800
|
||||
Subject: [PATCH] bugfix: Use gicr_typer in arm_gicv3_icc_reset
|
||||
|
||||
The KVM_VGIC_ATTR macro expect the second parameter as gicr_typer,
|
||||
of which high 32bit is constructed by mp_affinity. For most case,
|
||||
the high 32bit of mp_affinity is zero, so it will always access the
|
||||
ICC_CTLR_EL1 of CPU0.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
---
|
||||
hw/intc/arm_gicv3_kvm.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
|
||||
index d9c72f85be..b1e74147ba 100644
|
||||
--- a/hw/intc/arm_gicv3_kvm.c
|
||||
+++ b/hw/intc/arm_gicv3_kvm.c
|
||||
@@ -661,13 +661,11 @@ static void kvm_arm_gicv3_get(GICv3State *s)
|
||||
|
||||
static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
- ARMCPU *cpu;
|
||||
GICv3State *s;
|
||||
GICv3CPUState *c;
|
||||
|
||||
c = (GICv3CPUState *)env->gicv3state;
|
||||
s = c->gic;
|
||||
- cpu = ARM_CPU(c->cpu);
|
||||
|
||||
c->icc_pmr_el1 = 0;
|
||||
c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
|
||||
@@ -684,7 +682,7 @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
|
||||
/* Initialize to actual HW supported configuration */
|
||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
|
||||
- KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
|
||||
+ KVM_VGIC_ATTR(ICC_CTLR_EL1, c->gicr_typer),
|
||||
&c->icc_ctlr_el1[GICV3_NS], false, &error_abort);
|
||||
|
||||
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
|
||||
--
|
||||
2.19.1
|
||||
50
coroutine-Add-qemu_co_mutex_assert_locked.patch
Normal file
50
coroutine-Add-qemu_co_mutex_assert_locked.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From e9bb3d942e268a19e03fc5d404586d2ed1564282 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 24 Oct 2019 16:26:57 +0200
|
||||
Subject: [PATCH] coroutine: Add qemu_co_mutex_assert_locked()
|
||||
|
||||
Some functions require that the caller holds a certain CoMutex for them
|
||||
to operate correctly. Add a function so that they can assert the lock is
|
||||
really held.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Tested-by: Michael Weiser <michael.weiser@gmx.de>
|
||||
Reviewed-by: Michael Weiser <michael.weiser@gmx.de>
|
||||
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
Reviewed-by: Denis V. Lunev <den@openvz.org>
|
||||
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
||||
(cherry picked from commit 944f3d5dd216fcd8cb007eddd4f82dced0a15b3d)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
include/qemu/coroutine.h | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
|
||||
index 9801e7f5a4..f4843b5f59 100644
|
||||
--- a/include/qemu/coroutine.h
|
||||
+++ b/include/qemu/coroutine.h
|
||||
@@ -167,6 +167,21 @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
|
||||
*/
|
||||
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
|
||||
|
||||
+/**
|
||||
+ * Assert that the current coroutine holds @mutex.
|
||||
+ */
|
||||
+static inline coroutine_fn void qemu_co_mutex_assert_locked(CoMutex *mutex)
|
||||
+{
|
||||
+ /*
|
||||
+ * mutex->holder doesn't need any synchronisation if the assertion holds
|
||||
+ * true because the mutex protects it. If it doesn't hold true, we still
|
||||
+ * don't mind if another thread takes or releases mutex behind our back,
|
||||
+ * because the condition will be false no matter whether we read NULL or
|
||||
+ * the pointer for any other coroutine.
|
||||
+ */
|
||||
+ assert(atomic_read(&mutex->locked) &&
|
||||
+ mutex->holder == qemu_coroutine_self());
|
||||
+}
|
||||
|
||||
/**
|
||||
* CoQueues are a mechanism to queue coroutines in order to continue executing
|
||||
--
|
||||
2.23.0
|
||||
@ -3,6 +3,8 @@ From: Xu Yandong <xuyandong2@huawei.com>
|
||||
Date: Wed, 28 Aug 2019 01:36:21 -0400
|
||||
Subject: [PATCH] cpu: add Kunpeng-920 cpu support
|
||||
|
||||
Add the Kunpeng-920 CPU model.
|
||||
|
||||
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
|
||||
---
|
||||
hw/arm/virt.c | 1 +
|
||||
@ -62,4 +64,3 @@ index 228906f2..5581d5e1 100644
|
||||
};
|
||||
--
|
||||
2.19.1
|
||||
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
From ba1ca232cfa2ca273c610beda40bee2143f11964 Mon Sep 17 00:00:00 2001
|
||||
From: rpm-build <rpm-build>
|
||||
From: Xu Yandong <xuyandong2@huawei.com>
|
||||
Date: Tue, 3 Sep 2019 16:27:39 +0800
|
||||
Subject: [PATCH] cpu: parse +/- feature to avoid failure
|
||||
|
||||
To avoid cpu feature parse failuer, +/- feature is added.
|
||||
|
||||
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
|
||||
---
|
||||
target/arm/cpu64.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
79
dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch
Normal file
79
dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch
Normal file
@ -0,0 +1,79 @@
|
||||
From fbde196c30e4797a51bda046ba514b187963d4ba Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Mon, 29 Jul 2019 23:34:16 +0200
|
||||
Subject: [PATCH] dma-helpers: ensure AIO callback is invoked after
|
||||
cancellation
|
||||
|
||||
dma_aio_cancel unschedules the BH if there is one, which corresponds
|
||||
to the reschedule_dma case of dma_blk_cb. This can stall the DMA
|
||||
permanently, because dma_complete will never get invoked and therefore
|
||||
nobody will ever invoke the original AIO callback in dbs->common.cb.
|
||||
|
||||
Fix this by invoking the callback (which is ensured to happen after
|
||||
a bdrv_aio_cancel_async, or done manually in the dbs->bh case), and
|
||||
add assertions to check that the DMA state machine is indeed waiting
|
||||
for dma_complete or reschedule_dma, but never both.
|
||||
|
||||
Reported-by: John Snow <jsnow@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Message-id: 20190729213416.1972-1-pbonzini@redhat.com
|
||||
Signed-off-by: John Snow <jsnow@redhat.com>
|
||||
(cherry picked from commit 539343c0a47e19d5dd64d846d64d084d9793681f)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
dma-helpers.c | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dma-helpers.c b/dma-helpers.c
|
||||
index 2d7e02d35e..d3871dc61e 100644
|
||||
--- a/dma-helpers.c
|
||||
+++ b/dma-helpers.c
|
||||
@@ -90,6 +90,7 @@ static void reschedule_dma(void *opaque)
|
||||
{
|
||||
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
||||
|
||||
+ assert(!dbs->acb && dbs->bh);
|
||||
qemu_bh_delete(dbs->bh);
|
||||
dbs->bh = NULL;
|
||||
dma_blk_cb(dbs, 0);
|
||||
@@ -111,15 +112,12 @@ static void dma_complete(DMAAIOCB *dbs, int ret)
|
||||
{
|
||||
trace_dma_complete(dbs, ret, dbs->common.cb);
|
||||
|
||||
+ assert(!dbs->acb && !dbs->bh);
|
||||
dma_blk_unmap(dbs);
|
||||
if (dbs->common.cb) {
|
||||
dbs->common.cb(dbs->common.opaque, ret);
|
||||
}
|
||||
qemu_iovec_destroy(&dbs->iov);
|
||||
- if (dbs->bh) {
|
||||
- qemu_bh_delete(dbs->bh);
|
||||
- dbs->bh = NULL;
|
||||
- }
|
||||
qemu_aio_unref(dbs);
|
||||
}
|
||||
|
||||
@@ -179,14 +177,21 @@ static void dma_aio_cancel(BlockAIOCB *acb)
|
||||
|
||||
trace_dma_aio_cancel(dbs);
|
||||
|
||||
+ assert(!(dbs->acb && dbs->bh));
|
||||
if (dbs->acb) {
|
||||
+ /* This will invoke dma_blk_cb. */
|
||||
blk_aio_cancel_async(dbs->acb);
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
if (dbs->bh) {
|
||||
cpu_unregister_map_client(dbs->bh);
|
||||
qemu_bh_delete(dbs->bh);
|
||||
dbs->bh = NULL;
|
||||
}
|
||||
+ if (dbs->common.cb) {
|
||||
+ dbs->common.cb(dbs->common.opaque, -ECANCELED);
|
||||
+ }
|
||||
}
|
||||
|
||||
static AioContext *dma_get_aio_context(BlockAIOCB *acb)
|
||||
--
|
||||
2.23.0
|
||||
107
docs-specs-Add-ACPI-GED-documentation.patch
Normal file
107
docs-specs-Add-ACPI-GED-documentation.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 9c1752703fb8a5b70985cf4c9caabc3388c5953b Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:31 +0100
|
||||
Subject: [PATCH] docs/specs: Add ACPI GED documentation
|
||||
|
||||
Documents basic concepts of ACPI Generic Event device(GED)
|
||||
and interface between QEMU and the ACPI BIOS.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Message-Id: <20190918130633.4872-10-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
docs/specs/acpi_hw_reduced_hotplug.rst | 70 ++++++++++++++++++++++++++
|
||||
docs/specs/index.rst | 1 +
|
||||
2 files changed, 71 insertions(+)
|
||||
create mode 100644 docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
|
||||
diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
new file mode 100644
|
||||
index 0000000000..911a98255b
|
||||
--- /dev/null
|
||||
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
@@ -0,0 +1,70 @@
|
||||
+==================================================
|
||||
+QEMU and ACPI BIOS Generic Event Device interface
|
||||
+==================================================
|
||||
+
|
||||
+The ACPI *Generic Event Device* (GED) is a HW reduced platform
|
||||
+specific device introduced in ACPI v6.1 that handles all platform
|
||||
+events, including the hotplug ones. GED is modelled as a device
|
||||
+in the namespace with a _HID defined to be ACPI0013. This document
|
||||
+describes the interface between QEMU and the ACPI BIOS.
|
||||
+
|
||||
+GED allows HW reduced platforms to handle interrupts in ACPI ASL
|
||||
+statements. It follows a very similar approach to the _EVT method
|
||||
+from GPIO events. All interrupts are listed in _CRS and the handler
|
||||
+is written in _EVT method. However, the QEMU implementation uses a
|
||||
+single interrupt for the GED device, relying on an IO memory region
|
||||
+to communicate the type of device affected by the interrupt. This way,
|
||||
+we can support up to 32 events with a unique interrupt.
|
||||
+
|
||||
+**Here is an example,**
|
||||
+
|
||||
+::
|
||||
+
|
||||
+ Device (\_SB.GED)
|
||||
+ {
|
||||
+ Name (_HID, "ACPI0013")
|
||||
+ Name (_UID, Zero)
|
||||
+ Name (_CRS, ResourceTemplate ()
|
||||
+ {
|
||||
+ Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
|
||||
+ {
|
||||
+ 0x00000029,
|
||||
+ }
|
||||
+ })
|
||||
+ OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
|
||||
+ Field (EREG, DWordAcc, NoLock, WriteAsZeros)
|
||||
+ {
|
||||
+ ESEL, 32
|
||||
+ }
|
||||
+ Method (_EVT, 1, Serialized)
|
||||
+ {
|
||||
+ Local0 = ESEL // ESEL = IO memory region which specifies the
|
||||
+ // device type.
|
||||
+ If (((Local0 & One) == One))
|
||||
+ {
|
||||
+ MethodEvent1()
|
||||
+ }
|
||||
+ If ((Local0 & 0x2) == 0x2)
|
||||
+ {
|
||||
+ MethodEvent2()
|
||||
+ }
|
||||
+ ...
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+GED IO interface (4 byte access)
|
||||
+--------------------------------
|
||||
+**read access:**
|
||||
+
|
||||
+::
|
||||
+
|
||||
+ [0x0-0x3] Event selector bit field (32 bit) set by QEMU.
|
||||
+
|
||||
+ bits:
|
||||
+ 0: Memory hotplug event
|
||||
+ 1: System power down event
|
||||
+ 2-31: Reserved
|
||||
+
|
||||
+**write_access:**
|
||||
+
|
||||
+Nothing is expected to be written into GED IO memory
|
||||
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
|
||||
index 40adb97c5e..984ba44029 100644
|
||||
--- a/docs/specs/index.rst
|
||||
+++ b/docs/specs/index.rst
|
||||
@@ -12,3 +12,4 @@ Contents:
|
||||
|
||||
ppc-xive
|
||||
ppc-spapr-xive
|
||||
+ acpi_hw_reduced_hotplug
|
||||
--
|
||||
2.19.1
|
||||
50
hbitmap-handle-set-reset-with-zero-length.patch
Normal file
50
hbitmap-handle-set-reset-with-zero-length.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From c0b35d87de345bd3b59a44c604b247a0497f2fc0 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
Date: Fri, 11 Oct 2019 12:07:07 +0300
|
||||
Subject: [PATCH] hbitmap: handle set/reset with zero length
|
||||
|
||||
Passing zero length to these functions leads to unpredicted results.
|
||||
Zero-length set/reset may occur in active-mirror, on zero-length write
|
||||
(which is unlikely, but not guaranteed to never happen).
|
||||
|
||||
Let's just do nothing on zero-length request.
|
||||
|
||||
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
Message-id: 20191011090711.19940-2-vsementsov@virtuozzo.com
|
||||
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
||||
(cherry picked from commit fed33bd175f663cc8c13f8a490a4f35a19756cfe)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
util/hbitmap.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/util/hbitmap.c b/util/hbitmap.c
|
||||
index 71c6ba2c52..c059313b9e 100644
|
||||
--- a/util/hbitmap.c
|
||||
+++ b/util/hbitmap.c
|
||||
@@ -387,6 +387,10 @@ void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count)
|
||||
uint64_t first, n;
|
||||
uint64_t last = start + count - 1;
|
||||
|
||||
+ if (count == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
trace_hbitmap_set(hb, start, count,
|
||||
start >> hb->granularity, last >> hb->granularity);
|
||||
|
||||
@@ -478,6 +482,10 @@ void hbitmap_reset(HBitmap *hb, uint64_t start, uint64_t count)
|
||||
uint64_t last = start + count - 1;
|
||||
uint64_t gran = 1ULL << hb->granularity;
|
||||
|
||||
+ if (count == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
assert(QEMU_IS_ALIGNED(start, gran));
|
||||
assert(QEMU_IS_ALIGNED(count, gran) || (start + count == hb->orig_size));
|
||||
|
||||
--
|
||||
2.23.0
|
||||
478
hw-acpi-Add-ACPI-Generic-Event-Device-Support.patch
Normal file
478
hw-acpi-Add-ACPI-Generic-Event-Device-Support.patch
Normal file
@ -0,0 +1,478 @@
|
||||
From b12d9edd0079d4ee136c25e95333918b0c6d3cd9 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Ortiz <sameo@linux.intel.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:25 +0100
|
||||
Subject: [PATCH] hw/acpi: Add ACPI Generic Event Device Support
|
||||
|
||||
The ACPI Generic Event Device (GED) is a hardware-reduced specific
|
||||
device[ACPI v6.1 Section 5.6.9] that handles all platform events,
|
||||
including the hotplug ones. This patch generates the AML code that
|
||||
defines GEDs.
|
||||
|
||||
Platforms need to specify their own GED Event bitmap to describe
|
||||
what kind of events they want to support through GED. Also this
|
||||
uses a a single interrupt for the GED device, relying on IO
|
||||
memory region to communicate the type of device affected by the
|
||||
interrupt. This way, we can support up to 32 events with a unique
|
||||
interrupt.
|
||||
|
||||
This supports only memory hotplug for now.
|
||||
|
||||
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
|
||||
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Message-Id: <20190918130633.4872-4-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/acpi/Kconfig | 4 +
|
||||
hw/acpi/Makefile.objs | 1 +
|
||||
hw/acpi/generic_event_device.c | 303 +++++++++++++++++++++++++
|
||||
include/hw/acpi/generic_event_device.h | 100 ++++++++
|
||||
4 files changed, 408 insertions(+)
|
||||
create mode 100644 hw/acpi/generic_event_device.c
|
||||
create mode 100644 include/hw/acpi/generic_event_device.h
|
||||
|
||||
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
|
||||
index 7c59cf900b..12e3f1e86e 100644
|
||||
--- a/hw/acpi/Kconfig
|
||||
+++ b/hw/acpi/Kconfig
|
||||
@@ -31,3 +31,7 @@ config ACPI_VMGENID
|
||||
bool
|
||||
default y
|
||||
depends on PC
|
||||
+
|
||||
+config ACPI_HW_REDUCED
|
||||
+ bool
|
||||
+ depends on ACPI
|
||||
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
|
||||
index 1a720c381e..e4b5d101a4 100644
|
||||
--- a/hw/acpi/Makefile.objs
|
||||
+++ b/hw/acpi/Makefile.objs
|
||||
@@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
|
||||
common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
|
||||
common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
|
||||
common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
|
||||
+common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
|
||||
common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
|
||||
|
||||
common-obj-y += acpi_interface.o
|
||||
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
|
||||
new file mode 100644
|
||||
index 0000000000..b94500b08d
|
||||
--- /dev/null
|
||||
+++ b/hw/acpi/generic_event_device.c
|
||||
@@ -0,0 +1,303 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * Copyright (c) 2018 Intel Corporation
|
||||
+ * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
|
||||
+ * Written by Samuel Ortiz, Shameer Kolothum
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms and conditions of the GNU General Public License,
|
||||
+ * version 2 or later, as published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "exec/address-spaces.h"
|
||||
+#include "hw/acpi/acpi.h"
|
||||
+#include "hw/acpi/generic_event_device.h"
|
||||
+#include "hw/irq.h"
|
||||
+#include "hw/mem/pc-dimm.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "migration/vmstate.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
+static const uint32_t ged_supported_events[] = {
|
||||
+ ACPI_GED_MEM_HOTPLUG_EVT,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * The ACPI Generic Event Device (GED) is a hardware-reduced specific
|
||||
+ * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
|
||||
+ * including the hotplug ones. Platforms need to specify their own
|
||||
+ * GED Event bitmap to describe what kind of events they want to support
|
||||
+ * through GED. This routine uses a single interrupt for the GED device,
|
||||
+ * relying on IO memory region to communicate the type of device
|
||||
+ * affected by the interrupt. This way, we can support up to 32 events
|
||||
+ * with a unique interrupt.
|
||||
+ */
|
||||
+void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
|
||||
+ uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base)
|
||||
+{
|
||||
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
|
||||
+ Aml *crs = aml_resource_template();
|
||||
+ Aml *evt, *field;
|
||||
+ Aml *dev = aml_device("%s", name);
|
||||
+ Aml *evt_sel = aml_local(0);
|
||||
+ Aml *esel = aml_name(AML_GED_EVT_SEL);
|
||||
+
|
||||
+ /* _CRS interrupt */
|
||||
+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
|
||||
+ AML_EXCLUSIVE, &ged_irq, 1));
|
||||
+
|
||||
+ aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0013")));
|
||||
+ aml_append(dev, aml_name_decl("_UID", aml_string(GED_DEVICE)));
|
||||
+ aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
+
|
||||
+ /* Append IO region */
|
||||
+ aml_append(dev, aml_operation_region(AML_GED_EVT_REG, rs,
|
||||
+ aml_int(ged_base + ACPI_GED_EVT_SEL_OFFSET),
|
||||
+ ACPI_GED_EVT_SEL_LEN));
|
||||
+ field = aml_field(AML_GED_EVT_REG, AML_DWORD_ACC, AML_NOLOCK,
|
||||
+ AML_WRITE_AS_ZEROS);
|
||||
+ aml_append(field, aml_named_field(AML_GED_EVT_SEL,
|
||||
+ ACPI_GED_EVT_SEL_LEN * BITS_PER_BYTE));
|
||||
+ aml_append(dev, field);
|
||||
+
|
||||
+ /*
|
||||
+ * For each GED event we:
|
||||
+ * - Add a conditional block for each event, inside a loop.
|
||||
+ * - Call a method for each supported GED event type.
|
||||
+ *
|
||||
+ * The resulting ASL code looks like:
|
||||
+ *
|
||||
+ * Local0 = ESEL
|
||||
+ * If ((Local0 & One) == One)
|
||||
+ * {
|
||||
+ * MethodEvent0()
|
||||
+ * }
|
||||
+ *
|
||||
+ * If ((Local0 & 0x2) == 0x2)
|
||||
+ * {
|
||||
+ * MethodEvent1()
|
||||
+ * }
|
||||
+ * ...
|
||||
+ */
|
||||
+ evt = aml_method("_EVT", 1, AML_SERIALIZED);
|
||||
+ {
|
||||
+ Aml *if_ctx;
|
||||
+ uint32_t i;
|
||||
+ uint32_t ged_events = ctpop32(s->ged_event_bitmap);
|
||||
+
|
||||
+ /* Local0 = ESEL */
|
||||
+ aml_append(evt, aml_store(esel, evt_sel));
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) {
|
||||
+ uint32_t event = s->ged_event_bitmap & ged_supported_events[i];
|
||||
+
|
||||
+ if (!event) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if_ctx = aml_if(aml_equal(aml_and(evt_sel, aml_int(event), NULL),
|
||||
+ aml_int(event)));
|
||||
+ switch (event) {
|
||||
+ case ACPI_GED_MEM_HOTPLUG_EVT:
|
||||
+ aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
|
||||
+ MEMORY_SLOT_SCAN_METHOD));
|
||||
+ break;
|
||||
+ default:
|
||||
+ /*
|
||||
+ * Please make sure all the events in ged_supported_events[]
|
||||
+ * are handled above.
|
||||
+ */
|
||||
+ g_assert_not_reached();
|
||||
+ }
|
||||
+
|
||||
+ aml_append(evt, if_ctx);
|
||||
+ ged_events--;
|
||||
+ }
|
||||
+
|
||||
+ if (ged_events) {
|
||||
+ error_report("Unsupported events specified");
|
||||
+ abort();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Append _EVT method */
|
||||
+ aml_append(dev, evt);
|
||||
+
|
||||
+ aml_append(table, dev);
|
||||
+}
|
||||
+
|
||||
+/* Memory read by the GED _EVT AML dynamic method */
|
||||
+static uint64_t ged_read(void *opaque, hwaddr addr, unsigned size)
|
||||
+{
|
||||
+ uint64_t val = 0;
|
||||
+ GEDState *ged_st = opaque;
|
||||
+
|
||||
+ switch (addr) {
|
||||
+ case ACPI_GED_EVT_SEL_OFFSET:
|
||||
+ /* Read the selector value and reset it */
|
||||
+ val = ged_st->sel;
|
||||
+ ged_st->sel = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+/* Nothing is expected to be written to the GED memory region */
|
||||
+static void ged_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
+ unsigned int size)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static const MemoryRegionOps ged_ops = {
|
||||
+ .read = ged_read,
|
||||
+ .write = ged_write,
|
||||
+ .endianness = DEVICE_LITTLE_ENDIAN,
|
||||
+ .valid = {
|
||||
+ .min_access_size = 4,
|
||||
+ .max_access_size = 4,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
|
||||
+
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||
+ acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
|
||||
+ } else {
|
||||
+ error_setg(errp, "virt: device plug request for unsupported device"
|
||||
+ " type: %s", object_get_typename(OBJECT(dev)));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
|
||||
+{
|
||||
+ AcpiGedState *s = ACPI_GED(adev);
|
||||
+ GEDState *ged_st = &s->ged_state;
|
||||
+ uint32_t sel;
|
||||
+
|
||||
+ if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
|
||||
+ sel = ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
+ } else {
|
||||
+ /* Unknown event. Return without generating interrupt. */
|
||||
+ warn_report("GED: Unsupported event %d. No irq injected", ev);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Set the GED selector field to communicate the event type.
|
||||
+ * This will be read by GED aml code to select the appropriate
|
||||
+ * event method.
|
||||
+ */
|
||||
+ ged_st->sel |= sel;
|
||||
+
|
||||
+ /* Trigger the event by sending an interrupt to the guest. */
|
||||
+ qemu_irq_pulse(s->irq);
|
||||
+}
|
||||
+
|
||||
+static Property acpi_ged_properties[] = {
|
||||
+ DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0),
|
||||
+ DEFINE_PROP_END_OF_LIST(),
|
||||
+};
|
||||
+
|
||||
+static const VMStateDescription vmstate_memhp_state = {
|
||||
+ .name = "acpi-ged/memhp",
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_MEMORY_HOTPLUG(memhp_state, AcpiGedState),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const VMStateDescription vmstate_ged_state = {
|
||||
+ .name = "acpi-ged-state",
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_UINT32(sel, GEDState),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const VMStateDescription vmstate_acpi_ged = {
|
||||
+ .name = "acpi-ged",
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState),
|
||||
+ VMSTATE_END_OF_LIST(),
|
||||
+ },
|
||||
+ .subsections = (const VMStateDescription * []) {
|
||||
+ &vmstate_memhp_state,
|
||||
+ NULL
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void acpi_ged_initfn(Object *obj)
|
||||
+{
|
||||
+ DeviceState *dev = DEVICE(obj);
|
||||
+ AcpiGedState *s = ACPI_GED(dev);
|
||||
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
+ GEDState *ged_st = &s->ged_state;
|
||||
+
|
||||
+ memory_region_init_io(&ged_st->io, obj, &ged_ops, ged_st,
|
||||
+ TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN);
|
||||
+ sysbus_init_mmio(sbd, &ged_st->io);
|
||||
+
|
||||
+ sysbus_init_irq(sbd, &s->irq);
|
||||
+
|
||||
+ s->memhp_state.is_enabled = true;
|
||||
+ /*
|
||||
+ * GED handles memory hotplug event and acpi-mem-hotplug
|
||||
+ * memory region gets initialized here. Create an exclusive
|
||||
+ * container for memory hotplug IO and expose it as GED sysbus
|
||||
+ * MMIO so that boards can map it separately.
|
||||
+ */
|
||||
+ memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container",
|
||||
+ MEMORY_HOTPLUG_IO_LEN);
|
||||
+ sysbus_init_mmio(sbd, &s->container_memhp);
|
||||
+ acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev),
|
||||
+ &s->memhp_state, 0);
|
||||
+}
|
||||
+
|
||||
+static void acpi_ged_class_init(ObjectClass *class, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(class);
|
||||
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class);
|
||||
+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class);
|
||||
+
|
||||
+ dc->desc = "ACPI Generic Event Device";
|
||||
+ dc->props = acpi_ged_properties;
|
||||
+ dc->vmsd = &vmstate_acpi_ged;
|
||||
+
|
||||
+ hc->plug = acpi_ged_device_plug_cb;
|
||||
+
|
||||
+ adevc->send_event = acpi_ged_send_event;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo acpi_ged_info = {
|
||||
+ .name = TYPE_ACPI_GED,
|
||||
+ .parent = TYPE_SYS_BUS_DEVICE,
|
||||
+ .instance_size = sizeof(AcpiGedState),
|
||||
+ .instance_init = acpi_ged_initfn,
|
||||
+ .class_init = acpi_ged_class_init,
|
||||
+ .interfaces = (InterfaceInfo[]) {
|
||||
+ { TYPE_HOTPLUG_HANDLER },
|
||||
+ { TYPE_ACPI_DEVICE_IF },
|
||||
+ { }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void acpi_ged_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&acpi_ged_info);
|
||||
+}
|
||||
+
|
||||
+type_init(acpi_ged_register_types)
|
||||
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
|
||||
new file mode 100644
|
||||
index 0000000000..2049e8d873
|
||||
--- /dev/null
|
||||
+++ b/include/hw/acpi/generic_event_device.h
|
||||
@@ -0,0 +1,100 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * Copyright (c) 2018 Intel Corporation
|
||||
+ * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd
|
||||
+ * Written by Samuel Ortiz, Shameer Kolothum
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms and conditions of the GNU General Public License,
|
||||
+ * version 2 or later, as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * The ACPI Generic Event Device (GED) is a hardware-reduced specific
|
||||
+ * device[ACPI v6.1 Section 5.6.9] that handles all platform events,
|
||||
+ * including the hotplug ones. Generic Event Device allows platforms
|
||||
+ * to handle interrupts in ACPI ASL statements. It follows a very
|
||||
+ * similar approach like the _EVT method from GPIO events. All
|
||||
+ * interrupts are listed in _CRS and the handler is written in _EVT
|
||||
+ * method. Here, we use a single interrupt for the GED device, relying
|
||||
+ * on IO memory region to communicate the type of device affected by
|
||||
+ * the interrupt. This way, we can support up to 32 events with a
|
||||
+ * unique interrupt.
|
||||
+ *
|
||||
+ * Here is an example.
|
||||
+ *
|
||||
+ * Device (\_SB.GED)
|
||||
+ * {
|
||||
+ * Name (_HID, "ACPI0013")
|
||||
+ * Name (_UID, Zero)
|
||||
+ * Name (_CRS, ResourceTemplate ()
|
||||
+ * {
|
||||
+ * Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
|
||||
+ * {
|
||||
+ * 0x00000029,
|
||||
+ * }
|
||||
+ * })
|
||||
+ * OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)
|
||||
+ * Field (EREG, DWordAcc, NoLock, WriteAsZeros)
|
||||
+ * {
|
||||
+ * ESEL, 32
|
||||
+ * }
|
||||
+ *
|
||||
+ * Method (_EVT, 1, Serialized) // _EVT: Event
|
||||
+ * {
|
||||
+ * Local0 = ESEL // ESEL = IO memory region which specifies the
|
||||
+ * // device type.
|
||||
+ * If (((Local0 & One) == One))
|
||||
+ * {
|
||||
+ * MethodEvent1()
|
||||
+ * }
|
||||
+ * If ((Local0 & 0x2) == 0x2)
|
||||
+ * {
|
||||
+ * MethodEvent2()
|
||||
+ * }
|
||||
+ * ...
|
||||
+ * }
|
||||
+ * }
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef HW_ACPI_GED_H
|
||||
+#define HW_ACPI_GED_H
|
||||
+
|
||||
+#include "hw/sysbus.h"
|
||||
+#include "hw/acpi/memory_hotplug.h"
|
||||
+
|
||||
+#define TYPE_ACPI_GED "acpi-ged"
|
||||
+#define ACPI_GED(obj) \
|
||||
+ OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
|
||||
+
|
||||
+#define ACPI_GED_EVT_SEL_OFFSET 0x0
|
||||
+#define ACPI_GED_EVT_SEL_LEN 0x4
|
||||
+
|
||||
+#define GED_DEVICE "GED"
|
||||
+#define AML_GED_EVT_REG "EREG"
|
||||
+#define AML_GED_EVT_SEL "ESEL"
|
||||
+
|
||||
+/*
|
||||
+ * Platforms need to specify the GED event bitmap
|
||||
+ * to describe what kind of events they want to support
|
||||
+ * through GED.
|
||||
+ */
|
||||
+#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
|
||||
+
|
||||
+typedef struct GEDState {
|
||||
+ MemoryRegion io;
|
||||
+ uint32_t sel;
|
||||
+} GEDState;
|
||||
+
|
||||
+typedef struct AcpiGedState {
|
||||
+ SysBusDevice parent_obj;
|
||||
+ MemHotplugState memhp_state;
|
||||
+ MemoryRegion container_memhp;
|
||||
+ GEDState ged_state;
|
||||
+ uint32_t ged_event_bitmap;
|
||||
+ qemu_irq irq;
|
||||
+} AcpiGedState;
|
||||
+
|
||||
+void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
|
||||
+ uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.19.1
|
||||
46
hw-acpi-Do-not-create-memory-hotplug-method-when-han.patch
Normal file
46
hw-acpi-Do-not-create-memory-hotplug-method-when-han.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 7a08983315bf4d624966a89112259e2b4949de91 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Ortiz <sameo@linux.intel.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:24 +0100
|
||||
Subject: [PATCH] hw/acpi: Do not create memory hotplug method when handler is
|
||||
not defined
|
||||
|
||||
With Hardware-reduced ACPI, the GED device will manage ACPI
|
||||
hotplug entirely. As a consequence, make the memory specific
|
||||
events AML generation optional. The code will only be added
|
||||
when the method name is not NULL.
|
||||
|
||||
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20190918130633.4872-3-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
hw/acpi/memory_hotplug.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
|
||||
index 9a515c0484..8b30356c1a 100644
|
||||
--- a/hw/acpi/memory_hotplug.c
|
||||
+++ b/hw/acpi/memory_hotplug.c
|
||||
@@ -711,10 +711,12 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
|
||||
}
|
||||
aml_append(table, dev_container);
|
||||
|
||||
- method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
|
||||
- aml_append(method,
|
||||
- aml_call0(MEMORY_DEVICES_CONTAINER "." MEMORY_SLOT_SCAN_METHOD));
|
||||
- aml_append(table, method);
|
||||
+ if (event_handler_method) {
|
||||
+ method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);
|
||||
+ aml_append(method, aml_call0(MEMORY_DEVICES_CONTAINER "."
|
||||
+ MEMORY_SLOT_SCAN_METHOD));
|
||||
+ aml_append(table, method);
|
||||
+ }
|
||||
|
||||
g_free(mhp_res_path);
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
196
hw-acpi-Make-ACPI-IO-address-space-configurable.patch
Normal file
196
hw-acpi-Make-ACPI-IO-address-space-configurable.patch
Normal file
@ -0,0 +1,196 @@
|
||||
From 6cd7281c73ca462b2f27969f1e28f1afd3ebe82d Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:23 +0100
|
||||
Subject: [PATCH] hw/acpi: Make ACPI IO address space configurable
|
||||
|
||||
This is in preparation for adding support for ARM64 platforms
|
||||
where it doesn't use port mapped IO for ACPI IO space. We are
|
||||
making changes so that MMIO region can be accommodated
|
||||
and board can pass the base address into the aml build function.
|
||||
|
||||
Also move few MEMORY_* definitions to header so that other memory
|
||||
hotplug event signalling mechanisms (eg. Generic Event Device on
|
||||
HW-reduced acpi platforms) can use the same from their respective
|
||||
event handler code.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20190918130633.4872-2-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
hw/acpi/memory_hotplug.c | 33 ++++++++++++++------------------
|
||||
hw/i386/acpi-build.c | 7 ++++++-
|
||||
hw/i386/pc.c | 3 +++
|
||||
include/hw/acpi/memory_hotplug.h | 9 +++++++--
|
||||
include/hw/i386/pc.h | 3 +++
|
||||
5 files changed, 33 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
|
||||
index 297812d5f7..9a515c0484 100644
|
||||
--- a/hw/acpi/memory_hotplug.c
|
||||
+++ b/hw/acpi/memory_hotplug.c
|
||||
@@ -29,12 +29,7 @@
|
||||
#define MEMORY_SLOT_PROXIMITY_METHOD "MPXM"
|
||||
#define MEMORY_SLOT_EJECT_METHOD "MEJ0"
|
||||
#define MEMORY_SLOT_NOTIFY_METHOD "MTFY"
|
||||
-#define MEMORY_SLOT_SCAN_METHOD "MSCN"
|
||||
#define MEMORY_HOTPLUG_DEVICE "MHPD"
|
||||
-#define MEMORY_HOTPLUG_IO_LEN 24
|
||||
-#define MEMORY_DEVICES_CONTAINER "\\_SB.MHPC"
|
||||
-
|
||||
-static uint16_t memhp_io_base;
|
||||
|
||||
static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev)
|
||||
{
|
||||
@@ -209,7 +204,7 @@ static const MemoryRegionOps acpi_memory_hotplug_ops = {
|
||||
};
|
||||
|
||||
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
|
||||
- MemHotplugState *state, uint16_t io_base)
|
||||
+ MemHotplugState *state, hwaddr io_base)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
|
||||
@@ -218,12 +213,10 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
|
||||
return;
|
||||
}
|
||||
|
||||
- assert(!memhp_io_base);
|
||||
- memhp_io_base = io_base;
|
||||
state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
|
||||
memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
|
||||
"acpi-mem-hotplug", MEMORY_HOTPLUG_IO_LEN);
|
||||
- memory_region_add_subregion(as, memhp_io_base, &state->io);
|
||||
+ memory_region_add_subregion(as, io_base, &state->io);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,7 +335,8 @@ const VMStateDescription vmstate_memory_hotplug = {
|
||||
|
||||
void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
|
||||
const char *res_root,
|
||||
- const char *event_handler_method)
|
||||
+ const char *event_handler_method,
|
||||
+ AmlRegionSpace rs, hwaddr memhp_io_base)
|
||||
{
|
||||
int i;
|
||||
Aml *ifctx;
|
||||
@@ -351,10 +345,6 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
|
||||
Aml *mem_ctrl_dev;
|
||||
char *mhp_res_path;
|
||||
|
||||
- if (!memhp_io_base) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
mhp_res_path = g_strdup_printf("%s." MEMORY_HOTPLUG_DEVICE, res_root);
|
||||
mem_ctrl_dev = aml_device("%s", mhp_res_path);
|
||||
{
|
||||
@@ -365,14 +355,19 @@ void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
|
||||
aml_name_decl("_UID", aml_string("Memory hotplug resources")));
|
||||
|
||||
crs = aml_resource_template();
|
||||
- aml_append(crs,
|
||||
- aml_io(AML_DECODE16, memhp_io_base, memhp_io_base, 0,
|
||||
- MEMORY_HOTPLUG_IO_LEN)
|
||||
- );
|
||||
+ if (rs == AML_SYSTEM_IO) {
|
||||
+ aml_append(crs,
|
||||
+ aml_io(AML_DECODE16, memhp_io_base, memhp_io_base, 0,
|
||||
+ MEMORY_HOTPLUG_IO_LEN)
|
||||
+ );
|
||||
+ } else {
|
||||
+ aml_append(crs, aml_memory32_fixed(memhp_io_base,
|
||||
+ MEMORY_HOTPLUG_IO_LEN, AML_READ_WRITE));
|
||||
+ }
|
||||
aml_append(mem_ctrl_dev, aml_name_decl("_CRS", crs));
|
||||
|
||||
aml_append(mem_ctrl_dev, aml_operation_region(
|
||||
- MEMORY_HOTPLUG_IO_REGION, AML_SYSTEM_IO,
|
||||
+ MEMORY_HOTPLUG_IO_REGION, rs,
|
||||
aml_int(memhp_io_base), MEMORY_HOTPLUG_IO_LEN)
|
||||
);
|
||||
|
||||
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
||||
index f3fdfefcd5..749218561a 100644
|
||||
--- a/hw/i386/acpi-build.c
|
||||
+++ b/hw/i386/acpi-build.c
|
||||
@@ -1871,7 +1871,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
|
||||
"\\_SB.PCI0", "\\_GPE._E02");
|
||||
}
|
||||
- build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", "\\_GPE._E03");
|
||||
+
|
||||
+ if (pcms->memhp_io_base && nr_mem) {
|
||||
+ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0",
|
||||
+ "\\_GPE._E03", AML_SYSTEM_IO,
|
||||
+ pcms->memhp_io_base);
|
||||
+ }
|
||||
|
||||
scope = aml_scope("_GPE");
|
||||
{
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index d011733ff7..8a914130b0 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -1936,6 +1936,9 @@ void pc_memory_init(PCMachineState *pcms,
|
||||
|
||||
/* Init default IOAPIC address space */
|
||||
pcms->ioapic_as = &address_space_memory;
|
||||
+
|
||||
+ /* Init ACPI memory hotplug IO base address */
|
||||
+ pcms->memhp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
|
||||
index 77c65765d6..dfe9cf3fde 100644
|
||||
--- a/include/hw/acpi/memory_hotplug.h
|
||||
+++ b/include/hw/acpi/memory_hotplug.h
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "hw/acpi/acpi.h"
|
||||
#include "hw/acpi/aml-build.h"
|
||||
|
||||
+#define MEMORY_SLOT_SCAN_METHOD "MSCN"
|
||||
+#define MEMORY_DEVICES_CONTAINER "\\_SB.MHPC"
|
||||
+#define MEMORY_HOTPLUG_IO_LEN 24
|
||||
+
|
||||
/**
|
||||
* MemStatus:
|
||||
* @is_removing: the memory device in slot has been requested to be ejected.
|
||||
@@ -29,7 +33,7 @@ typedef struct MemHotplugState {
|
||||
} MemHotplugState;
|
||||
|
||||
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
|
||||
- MemHotplugState *state, uint16_t io_base);
|
||||
+ MemHotplugState *state, hwaddr io_base);
|
||||
|
||||
void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
|
||||
DeviceState *dev, Error **errp);
|
||||
@@ -48,5 +52,6 @@ void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list);
|
||||
|
||||
void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,
|
||||
const char *res_root,
|
||||
- const char *event_handler_method);
|
||||
+ const char *event_handler_method,
|
||||
+ AmlRegionSpace rs, hwaddr memhp_io_base);
|
||||
#endif
|
||||
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
||||
index 859b64c51d..49b47535cf 100644
|
||||
--- a/include/hw/i386/pc.h
|
||||
+++ b/include/hw/i386/pc.h
|
||||
@@ -69,6 +69,9 @@ struct PCMachineState {
|
||||
/* Address space used by IOAPIC device. All IOAPIC interrupts
|
||||
* will be translated to MSI messages in the address space. */
|
||||
AddressSpace *ioapic_as;
|
||||
+
|
||||
+ /* ACPI Memory hotplug IO base address */
|
||||
+ hwaddr memhp_io_base;
|
||||
};
|
||||
|
||||
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
|
||||
--
|
||||
2.19.1
|
||||
72
hw-arm-Factor-out-powerdown-notifier-from-GPIO.patch
Normal file
72
hw-arm-Factor-out-powerdown-notifier-from-GPIO.patch
Normal file
@ -0,0 +1,72 @@
|
||||
From e6b1fd7bfbfe116e9d5df590f7069336c1eb1983 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:29 +0100
|
||||
Subject: [PATCH] hw/arm: Factor out powerdown notifier from GPIO
|
||||
|
||||
This is in preparation of using GED device for
|
||||
system_powerdown event. Make the powerdown notifier
|
||||
registration independent of create_gpio() fn.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20190918130633.4872-8-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 12 ++++--------
|
||||
include/hw/arm/virt.h | 1 +
|
||||
2 files changed, 5 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index ab33cce4b3..aaefa5578e 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -910,10 +910,6 @@ static void virt_powerdown_req(Notifier *n, void *opaque)
|
||||
qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
|
||||
}
|
||||
|
||||
-static Notifier virt_system_powerdown_notifier = {
|
||||
- .notify = virt_powerdown_req
|
||||
-};
|
||||
-
|
||||
static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
|
||||
{
|
||||
char *nodename;
|
||||
@@ -954,10 +950,6 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
|
||||
KEY_POWER);
|
||||
qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
|
||||
"gpios", phandle, 3, 0);
|
||||
-
|
||||
- /* connect powerdown request */
|
||||
- qemu_register_powerdown_notifier(&virt_system_powerdown_notifier);
|
||||
-
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
@@ -1856,6 +1848,10 @@ static void machvirt_init(MachineState *machine)
|
||||
vms->acpi_dev = create_acpi_ged(vms, pic);
|
||||
}
|
||||
|
||||
+ /* connect powerdown request */
|
||||
+ vms->powerdown_notifier.notify = virt_powerdown_req;
|
||||
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
|
||||
+
|
||||
/* Create mmio transports, so the user can create virtio backends
|
||||
* (which will be automatically plugged in to the transports). If
|
||||
* no backend is created the transport will just sit harmlessly idle.
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index 0350285136..dcceb9c615 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -139,6 +139,7 @@ typedef struct {
|
||||
int psci_conduit;
|
||||
hwaddr highest_gpa;
|
||||
DeviceState *acpi_dev;
|
||||
+ Notifier powerdown_notifier;
|
||||
} VirtMachineState;
|
||||
|
||||
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
|
||||
--
|
||||
2.19.1
|
||||
167
hw-arm-Use-GED-for-system_powerdown-event.patch
Normal file
167
hw-arm-Use-GED-for-system_powerdown-event.patch
Normal file
@ -0,0 +1,167 @@
|
||||
From 0b77f242b180f1ae40b9752999cef4894113df8e Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:30 +0100
|
||||
Subject: [PATCH] hw/arm: Use GED for system_powerdown event
|
||||
|
||||
For machines 4.2 or higher with ACPI boot use GED for system_powerdown
|
||||
event instead of GPIO. Guest boot with DT still uses GPIO.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20190918130633.4872-9-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
hw/acpi/generic_event_device.c | 8 ++++++++
|
||||
hw/arm/virt-acpi-build.c | 6 +++---
|
||||
hw/arm/virt.c | 18 ++++++++++++------
|
||||
include/hw/acpi/acpi_dev_interface.h | 1 +
|
||||
include/hw/acpi/generic_event_device.h | 3 +++
|
||||
5 files changed, 27 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
|
||||
index b94500b08d..9cee90cc70 100644
|
||||
--- a/hw/acpi/generic_event_device.c
|
||||
+++ b/hw/acpi/generic_event_device.c
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
static const uint32_t ged_supported_events[] = {
|
||||
ACPI_GED_MEM_HOTPLUG_EVT,
|
||||
+ ACPI_GED_PWR_DOWN_EVT,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -104,6 +105,11 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
|
||||
aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
|
||||
MEMORY_SLOT_SCAN_METHOD));
|
||||
break;
|
||||
+ case ACPI_GED_PWR_DOWN_EVT:
|
||||
+ aml_append(if_ctx,
|
||||
+ aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
|
||||
+ aml_int(0x80)));
|
||||
+ break;
|
||||
default:
|
||||
/*
|
||||
* Please make sure all the events in ged_supported_events[]
|
||||
@@ -184,6 +190,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
|
||||
|
||||
if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
|
||||
sel = ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
+ } else if (ev & ACPI_POWER_DOWN_STATUS) {
|
||||
+ sel = ACPI_GED_PWR_DOWN_EVT;
|
||||
} else {
|
||||
/* Unknown event. Return without generating interrupt. */
|
||||
warn_report("GED: Unsupported event %d. No irq injected", ev);
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index 9622994e50..f48733d9f2 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "hw/acpi/acpi-defs.h"
|
||||
|
||||
#define ARM_SPI_BASE 32
|
||||
-#define ACPI_POWER_BUTTON_DEVICE "PWRB"
|
||||
|
||||
static void acpi_dsdt_add_psd(Aml *dev, int cpus)
|
||||
{
|
||||
@@ -813,13 +812,14 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
|
||||
acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
|
||||
vms->highmem, vms->highmem_ecam);
|
||||
- acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
|
||||
- (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
|
||||
if (vms->acpi_dev) {
|
||||
build_ged_aml(scope, "\\_SB."GED_DEVICE,
|
||||
HOTPLUG_HANDLER(vms->acpi_dev),
|
||||
irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
|
||||
memmap[VIRT_ACPI_GED].base);
|
||||
+ } else {
|
||||
+ acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
|
||||
+ (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
|
||||
}
|
||||
|
||||
if (vms->acpi_dev) {
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index aaefa5578e..18321e522b 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -639,10 +639,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
|
||||
DeviceState *dev;
|
||||
MachineState *ms = MACHINE(vms);
|
||||
int irq = vms->irqmap[VIRT_ACPI_GED];
|
||||
- uint32_t event = 0;
|
||||
+ uint32_t event = ACPI_GED_PWR_DOWN_EVT;
|
||||
|
||||
if (ms->ram_slots) {
|
||||
- event = ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
+ event |= ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
}
|
||||
|
||||
dev = qdev_create(NULL, TYPE_ACPI_GED);
|
||||
@@ -906,8 +906,14 @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
|
||||
static DeviceState *gpio_key_dev;
|
||||
static void virt_powerdown_req(Notifier *n, void *opaque)
|
||||
{
|
||||
- /* use gpio Pin 3 for power button event */
|
||||
- qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
|
||||
+ VirtMachineState *s = container_of(n, VirtMachineState, powerdown_notifier);
|
||||
+
|
||||
+ if (s->acpi_dev) {
|
||||
+ acpi_send_event(s->acpi_dev, ACPI_POWER_DOWN_STATUS);
|
||||
+ } else {
|
||||
+ /* use gpio Pin 3 for power button event */
|
||||
+ qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
|
||||
@@ -1842,10 +1848,10 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
create_pcie(vms, pic);
|
||||
|
||||
- create_gpio(vms, pic);
|
||||
-
|
||||
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
|
||||
vms->acpi_dev = create_acpi_ged(vms, pic);
|
||||
+ } else {
|
||||
+ create_gpio(vms, pic);
|
||||
}
|
||||
|
||||
/* connect powerdown request */
|
||||
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
|
||||
index 43ff119179..adcb3a816c 100644
|
||||
--- a/include/hw/acpi/acpi_dev_interface.h
|
||||
+++ b/include/hw/acpi/acpi_dev_interface.h
|
||||
@@ -11,6 +11,7 @@ typedef enum {
|
||||
ACPI_MEMORY_HOTPLUG_STATUS = 8,
|
||||
ACPI_NVDIMM_HOTPLUG_STATUS = 16,
|
||||
ACPI_VMGENID_CHANGE_STATUS = 32,
|
||||
+ ACPI_POWER_DOWN_STATUS = 64,
|
||||
} AcpiEventStatusBits;
|
||||
|
||||
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
|
||||
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
|
||||
index 2049e8d873..d157eac088 100644
|
||||
--- a/include/hw/acpi/generic_event_device.h
|
||||
+++ b/include/hw/acpi/generic_event_device.h
|
||||
@@ -62,6 +62,8 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/acpi/memory_hotplug.h"
|
||||
|
||||
+#define ACPI_POWER_BUTTON_DEVICE "PWRB"
|
||||
+
|
||||
#define TYPE_ACPI_GED "acpi-ged"
|
||||
#define ACPI_GED(obj) \
|
||||
OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
|
||||
@@ -79,6 +81,7 @@
|
||||
* through GED.
|
||||
*/
|
||||
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
|
||||
+#define ACPI_GED_PWR_DOWN_EVT 0x2
|
||||
|
||||
typedef struct GEDState {
|
||||
MemoryRegion io;
|
||||
--
|
||||
2.19.1
|
||||
115
hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch
Normal file
115
hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From de86ba0ff72a51b0c1cdbebf790869aea73ae9d3 Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Thu, 9 Apr 2020 09:31:22 +0800
|
||||
Subject: [PATCH] hw/arm/boot: Add manually register and trigger of CPU reset
|
||||
|
||||
We need to register and trigger CPU reset manually for hotplugged
|
||||
CPU. Besides, we gather CPU reset handlers of all CPUs because CPU
|
||||
reset should happen before GIC reset.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/boot.c | 18 ++++++++++++++++++
|
||||
hw/core/reset.c | 25 +++++++++++++++++++++++++
|
||||
include/hw/arm/boot.h | 3 +++
|
||||
include/sysemu/reset.h | 4 ++++
|
||||
4 files changed, 50 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
|
||||
index fc4e021a38..3ab9de6456 100644
|
||||
--- a/hw/arm/boot.c
|
||||
+++ b/hw/arm/boot.c
|
||||
@@ -789,6 +789,24 @@ static void do_cpu_reset(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
+void cpu_hotplug_register_reset(int ncpu)
|
||||
+{
|
||||
+ CPUState *cpu_0 = qemu_get_cpu(0);
|
||||
+ CPUState *cpu = qemu_get_cpu(ncpu);
|
||||
+ QEMUResetEntry *entry = qemu_get_reset_entry(do_cpu_reset, cpu_0);
|
||||
+
|
||||
+ assert(entry);
|
||||
+ /* Gather the reset handlers of all CPUs */
|
||||
+ qemu_register_reset_after(entry, do_cpu_reset, cpu);
|
||||
+}
|
||||
+
|
||||
+void cpu_hotplug_reset_manually(int ncpu)
|
||||
+{
|
||||
+ CPUState *cpu = qemu_get_cpu(ncpu);
|
||||
+
|
||||
+ do_cpu_reset(cpu);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified
|
||||
* by key.
|
||||
diff --git a/hw/core/reset.c b/hw/core/reset.c
|
||||
index 9c477f2bf5..0efaf2d76c 100644
|
||||
--- a/hw/core/reset.c
|
||||
+++ b/hw/core/reset.c
|
||||
@@ -47,6 +47,31 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
|
||||
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
|
||||
}
|
||||
|
||||
+QEMUResetEntry *qemu_get_reset_entry(QEMUResetHandler *func,
|
||||
+ void *opaque)
|
||||
+{
|
||||
+ QEMUResetEntry *re;
|
||||
+
|
||||
+ QTAILQ_FOREACH(re, &reset_handlers, entry) {
|
||||
+ if (re->func == func && re->opaque == opaque) {
|
||||
+ return re;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void qemu_register_reset_after(QEMUResetEntry *entry,
|
||||
+ QEMUResetHandler *func,
|
||||
+ void *opaque)
|
||||
+{
|
||||
+ QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
|
||||
+
|
||||
+ re->func = func;
|
||||
+ re->opaque = opaque;
|
||||
+ QTAILQ_INSERT_AFTER(&reset_handlers, entry, re, entry);
|
||||
+}
|
||||
+
|
||||
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
|
||||
{
|
||||
QEMUResetEntry *re;
|
||||
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
|
||||
index c48cc4c2bc..9452ccd1fa 100644
|
||||
--- a/include/hw/arm/boot.h
|
||||
+++ b/include/hw/arm/boot.h
|
||||
@@ -118,6 +118,9 @@ struct arm_boot_info {
|
||||
arm_endianness endianness;
|
||||
};
|
||||
|
||||
+void cpu_hotplug_register_reset(int ncpu);
|
||||
+void cpu_hotplug_reset_manually(int ncpu);
|
||||
+
|
||||
/**
|
||||
* arm_load_kernel - Loads memory with everything needed to boot
|
||||
*
|
||||
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
|
||||
index 0b0d6d7598..f3ff26c637 100644
|
||||
--- a/include/sysemu/reset.h
|
||||
+++ b/include/sysemu/reset.h
|
||||
@@ -2,7 +2,11 @@
|
||||
#define QEMU_SYSEMU_RESET_H
|
||||
|
||||
typedef void QEMUResetHandler(void *opaque);
|
||||
+typedef struct QEMUResetEntry QEMUResetEntry;
|
||||
|
||||
+QEMUResetEntry *qemu_get_reset_entry(QEMUResetHandler *func, void *opaque);
|
||||
+void qemu_register_reset_after(QEMUResetEntry *entry,
|
||||
+ QEMUResetHandler *func, void *opaque);
|
||||
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
|
||||
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
||||
void qemu_devices_reset(void);
|
||||
--
|
||||
2.19.1
|
||||
47
hw-arm-boot.c-Set-NSACR.-CP11-CP10-for-NS-kernel-boo.patch
Normal file
47
hw-arm-boot.c-Set-NSACR.-CP11-CP10-for-NS-kernel-boo.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 220816989c1e3d490d293b8d7ac85dbc41a4c321 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Fri, 20 Sep 2019 18:40:39 +0100
|
||||
Subject: [PATCH] hw/arm/boot.c: Set NSACR.{CP11,CP10} for NS kernel boots
|
||||
|
||||
If we're booting a Linux kernel directly into Non-Secure
|
||||
state on a CPU which has Secure state, then make sure we
|
||||
set the NSACR CP11 and CP10 bits, so that Non-Secure is allowed
|
||||
to access the FPU. Otherwise an AArch32 kernel will UNDEF as
|
||||
soon as it tries to use the FPU.
|
||||
|
||||
It used to not matter that we didn't do this until commit
|
||||
fc1120a7f5f2d4b6, where we implemented actually honouring
|
||||
these NSACR bits.
|
||||
|
||||
The problem only exists for CPUs where EL3 is AArch32; the
|
||||
equivalent AArch64 trap bits are in CPTR_EL3 and are "0 to
|
||||
not trap, 1 to trap", so the reset value of the register
|
||||
permits NS access, unlike NSACR.
|
||||
|
||||
Fixes: fc1120a7f5
|
||||
Fixes: https://bugs.launchpad.net/qemu/+bug/1844597
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-id: 20190920174039.3916-1-peter.maydell@linaro.org
|
||||
(cherry picked from commit ece628fcf69cbbd4b3efb6fbd203af07609467a2)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
hw/arm/boot.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
|
||||
index c2b89b3bb9..fc4e021a38 100644
|
||||
--- a/hw/arm/boot.c
|
||||
+++ b/hw/arm/boot.c
|
||||
@@ -754,6 +754,8 @@ static void do_cpu_reset(void *opaque)
|
||||
(cs != first_cpu || !info->secure_board_setup)) {
|
||||
/* Linux expects non-secure state */
|
||||
env->cp15.scr_el3 |= SCR_NS;
|
||||
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
|
||||
+ env->cp15.nsacr |= 3 << 10;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
@ -1,54 +1,57 @@
|
||||
From 773b25c55c7428b64d21b23a6b08fc629a665ca5 Mon Sep 17 00:00:00 2001
|
||||
From: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Date: Mon, 29 Jul 2019 09:54:43 +0800
|
||||
Subject: [PATCH] hw/arm: expose host CPU frequency info to guest
|
||||
From b70d020dba72283d7b16a77c377512c84aab5f81 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
|
||||
|
||||
On ARM64, CPU frequency is fetched by ACPI CPPC, so we add virtual
|
||||
CPPC registers and ACPI _CPC objects.
|
||||
On ARM64 platform, cpu frequency is retrieved via ACPI CPPC.
|
||||
A virtual cpufreq device based on ACPI CPPC is created to
|
||||
present cpu frequency info to the guest.
|
||||
|
||||
The default frequency is set to the nominal frequency of Hi1616, which
|
||||
will not support CPPC in future. On Hi1620 we are fetching the value
|
||||
from Host CPPC sys file.
|
||||
The default frequency is set to host cpu nominal frequency,
|
||||
which is obtained from the host CPPC sysfs. Other performance
|
||||
data are set to the same value, since we don't support guest
|
||||
performance scaling here.
|
||||
|
||||
All performance data are set to the same value for we don't support
|
||||
guest initiating performance scaling.
|
||||
|
||||
We don't emulate performance counters and simply return 1 for all
|
||||
counter readings, and guest Linux should fall back to use the desired
|
||||
Performance counters are also not emulated and they simply
|
||||
return 1 if read, and guest should fallback to use desired
|
||||
performance value as the current performance.
|
||||
|
||||
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Guest kernel version above 4.18 is required to make it work.
|
||||
|
||||
This series is backported from:
|
||||
https://patchwork.kernel.org/cover/11379943/
|
||||
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
---
|
||||
default-configs/aarch64-softmmu.mak | 1 +
|
||||
hw/acpi/Makefile.objs | 1 +
|
||||
hw/acpi/aml-build.c | 22 +++
|
||||
hw/acpi/cpufreq.c | 278 ++++++++++++++++++++++++++++
|
||||
hw/acpi/cpufreq.c | 287 ++++++++++++++++++++++++++++
|
||||
hw/arm/virt-acpi-build.c | 78 +++++++-
|
||||
hw/arm/virt.c | 13 ++
|
||||
hw/char/Kconfig | 4 +
|
||||
include/hw/acpi/acpi-defs.h | 38 ++++
|
||||
include/hw/acpi/aml-build.h | 3 +
|
||||
include/hw/arm/virt.h | 1 +
|
||||
10 files changed, 437 insertions(+), 2 deletions(-)
|
||||
10 files changed, 446 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 4ea9add0..37399c14 100644
|
||||
index 958b1e08..0a030e85 100644
|
||||
--- a/default-configs/aarch64-softmmu.mak
|
||||
+++ b/default-configs/aarch64-softmmu.mak
|
||||
@@ -10,3 +10,4 @@ CONFIG_XLNX_ZYNQMP=y
|
||||
@@ -6,3 +6,4 @@ include arm-softmmu.mak
|
||||
CONFIG_XLNX_ZYNQMP_ARM=y
|
||||
CONFIG_XLNX_VERSAL=y
|
||||
CONFIG_ARM_SMMUV3=y
|
||||
CONFIG_SBSA_REF=y
|
||||
+CONFIG_CPUFREQ=y
|
||||
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
|
||||
index 2d46e378..60979db9 100644
|
||||
index 9bb2101e..1a720c38 100644
|
||||
--- a/hw/acpi/Makefile.objs
|
||||
+++ b/hw/acpi/Makefile.objs
|
||||
@@ -12,6 +12,7 @@ common-obj-y += acpi_interface.o
|
||||
common-obj-y += bios-linker-loader.o
|
||||
common-obj-y += aml-build.o
|
||||
@@ -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
|
||||
|
||||
@ -89,10 +92,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..c123a22b
|
||||
index 00000000..d02a25a6
|
||||
--- /dev/null
|
||||
+++ b/hw/acpi/cpufreq.c
|
||||
@@ -0,0 +1,278 @@
|
||||
@@ -0,0 +1,287 @@
|
||||
+/*
|
||||
+ * ACPI CPPC register device
|
||||
+ *
|
||||
@ -124,6 +127,7 @@ index 00000000..c123a22b
|
||||
+#include "hw/acpi/acpi-defs.h"
|
||||
+#include "qemu/cutils.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "hw/boards.h"
|
||||
+
|
||||
+#define TYPE_CPUFREQ "cpufreq"
|
||||
+#define CPUFREQ(obj) OBJECT_CHECK(CpuhzState, (obj), TYPE_CPUFREQ)
|
||||
@ -189,6 +193,9 @@ index 00000000..c123a22b
|
||||
+ uint64_t r;
|
||||
+ uint64_t n;
|
||||
+
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cpus = ms->smp.cpus;
|
||||
+
|
||||
+ if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) {
|
||||
+ warn_report("cpufreq_read: offset 0x%lx out of range", offset);
|
||||
+ return 0;
|
||||
@ -258,6 +265,8 @@ index 00000000..c123a22b
|
||||
+ uint64_t value, unsigned size)
|
||||
+{
|
||||
+ uint64_t n;
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cpus = ms->smp.cpus;
|
||||
+
|
||||
+ if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) {
|
||||
+ error_printf("cpufreq_write: offset 0x%lx out of range", offset);
|
||||
@ -339,6 +348,9 @@ index 00000000..c123a22b
|
||||
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
+ CpuhzState *s = CPUFREQ(obj);
|
||||
+
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cpus = ms->smp.cpus;
|
||||
+
|
||||
+ s->reg_size = smp_cpus * CPPC_REG_PER_CPU_STRIDE;
|
||||
+ if (s->reg_size > MAX_SUPPORT_SPACE) {
|
||||
+ error_report("Required space 0x%x excesses the max support 0x%x",
|
||||
@ -372,7 +384,7 @@ index 00000000..c123a22b
|
||||
+type_init(cpufreq_register_types)
|
||||
+
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index bf9c0bc2..33a8e2e3 100644
|
||||
index 0afb3727..29494ebd 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -45,11 +45,73 @@
|
||||
@ -469,7 +481,7 @@ index bf9c0bc2..33a8e2e3 100644
|
||||
aml_append(scope, dev);
|
||||
}
|
||||
}
|
||||
@@ -740,7 +814,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
@@ -718,7 +792,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
* the RTC ACPI device at all when using UEFI.
|
||||
*/
|
||||
scope = aml_scope("\\_SB");
|
||||
@ -479,10 +491,10 @@ index bf9c0bc2..33a8e2e3 100644
|
||||
(irqmap[VIRT_UART] + ARM_SPI_BASE));
|
||||
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index ce2664a3..ec6f00ab 100644
|
||||
index d9496c93..0fa355ba 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -132,6 +132,7 @@ static const MemMapEntry base_memmap[] = {
|
||||
@@ -135,6 +135,7 @@ static const MemMapEntry base_memmap[] = {
|
||||
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
|
||||
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
|
||||
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
|
||||
@ -490,7 +502,7 @@ index ce2664a3..ec6f00ab 100644
|
||||
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
|
||||
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
|
||||
[VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 },
|
||||
@@ -725,6 +726,16 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
|
||||
@@ -731,6 +732,16 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
@ -507,7 +519,7 @@ index ce2664a3..ec6f00ab 100644
|
||||
static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
|
||||
{
|
||||
char *nodename;
|
||||
@@ -1618,6 +1629,8 @@ static void machvirt_init(MachineState *machine)
|
||||
@@ -1682,6 +1693,8 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
|
||||
|
||||
@ -517,10 +529,10 @@ index ce2664a3..ec6f00ab 100644
|
||||
create_secure_ram(vms, secure_sysmem);
|
||||
create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
|
||||
diff --git a/hw/char/Kconfig b/hw/char/Kconfig
|
||||
index 6360c9ff..8cc3ae2a 100644
|
||||
index 40e7a8b8..2f61bf53 100644
|
||||
--- a/hw/char/Kconfig
|
||||
+++ b/hw/char/Kconfig
|
||||
@@ -40,3 +40,7 @@ config SCLPCONSOLE
|
||||
@@ -46,3 +46,7 @@ config SCLPCONSOLE
|
||||
|
||||
config TERMINAL3270
|
||||
bool
|
||||
@ -529,10 +541,10 @@ index 6360c9ff..8cc3ae2a 100644
|
||||
+ bool
|
||||
+ default y
|
||||
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
|
||||
index f9aa4bd3..b4899a32 100644
|
||||
index 57a3f58b..39ae91d3 100644
|
||||
--- a/include/hw/acpi/acpi-defs.h
|
||||
+++ b/include/hw/acpi/acpi-defs.h
|
||||
@@ -652,4 +652,42 @@ struct AcpiIortRC {
|
||||
@@ -634,4 +634,42 @@ struct AcpiIortRC {
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiIortRC AcpiIortRC;
|
||||
|
||||
@ -590,7 +602,7 @@ 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 507517c6..8465f9bd 100644
|
||||
index a7209420..43a6ce91 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -66,6 +66,7 @@ enum {
|
||||
@ -603,4 +615,3 @@ index 507517c6..8465f9bd 100644
|
||||
VIRT_FW_CFG,
|
||||
--
|
||||
2.19.1
|
||||
|
||||
|
||||
130
hw-arm-virt-Add-memory-hotplug-framework.patch
Normal file
130
hw-arm-virt-Add-memory-hotplug-framework.patch
Normal file
@ -0,0 +1,130 @@
|
||||
From e14fadc66d488ad10a10a2076721b72cc239ded9 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:26 +0100
|
||||
Subject: [PATCH] hw/arm/virt: Add memory hotplug framework
|
||||
|
||||
This patch adds the memory hot-plug/hot-unplug infrastructure
|
||||
in machvirt. The device memory is not yet exposed to the Guest
|
||||
either through DT or ACPI and hence both cold/hot plug of memory
|
||||
is explicitly disabled for now.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Signed-off-by: Kwangwoo Lee <kwangwoo.lee@sk.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20190918130633.4872-5-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
hw/arm/Kconfig | 2 ++
|
||||
hw/arm/virt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 54 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
|
||||
index ab65ecd216..84961c17ab 100644
|
||||
--- a/hw/arm/Kconfig
|
||||
+++ b/hw/arm/Kconfig
|
||||
@@ -20,6 +20,8 @@ config ARM_VIRT
|
||||
select SMBIOS
|
||||
select VIRTIO_MMIO
|
||||
select ACPI_PCI
|
||||
+ select MEM_DEVICE
|
||||
+ select DIMM
|
||||
|
||||
config CHEETAH
|
||||
bool
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 23d72aed97..c7c07fe3ac 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -65,6 +65,8 @@
|
||||
#include "hw/arm/smmuv3.h"
|
||||
#include "hw/acpi/acpi.h"
|
||||
#include "target/arm/internals.h"
|
||||
+#include "hw/mem/pc-dimm.h"
|
||||
+#include "hw/mem/nvdimm.h"
|
||||
|
||||
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
|
||||
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
|
||||
@@ -1998,6 +2000,42 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
|
||||
+static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+
|
||||
+ /*
|
||||
+ * The device memory is not yet exposed to the Guest either through
|
||||
+ * DT or ACPI and hence both cold/hot plug of memory is explicitly
|
||||
+ * disabled for now.
|
||||
+ */
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||
+ error_setg(errp, "memory cold/hot plug is not yet supported");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
|
||||
+}
|
||||
+
|
||||
+static void virt_memory_plug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||
+ Error *local_err = NULL;
|
||||
+
|
||||
+ pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
|
||||
+
|
||||
+ error_propagate(errp, local_err);
|
||||
+}
|
||||
+
|
||||
+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);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
@@ -2009,12 +2047,23 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
SYS_BUS_DEVICE(dev));
|
||||
}
|
||||
}
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||
+ virt_memory_plug(hotplug_dev, dev, errp);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ error_setg(errp, "device unplug request for unsupported device"
|
||||
+ " type: %s", object_get_typename(OBJECT(dev)));
|
||||
}
|
||||
|
||||
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
|
||||
DeviceState *dev)
|
||||
{
|
||||
- if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE) ||
|
||||
+ (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
|
||||
return HOTPLUG_HANDLER(machine);
|
||||
}
|
||||
|
||||
@@ -2078,7 +2127,9 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->kvm_type = virt_kvm_type;
|
||||
assert(!mc->get_hotplug_handler);
|
||||
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
|
||||
+ hc->pre_plug = virt_machine_device_pre_plug_cb;
|
||||
hc->plug = virt_machine_device_plug_cb;
|
||||
+ hc->unplug_request = virt_machine_device_unplug_request_cb;
|
||||
mc->numa_mem_supported = true;
|
||||
}
|
||||
|
||||
--
|
||||
2.19.1
|
||||
252
hw-arm-virt-Enable-device-memory-cold-hot-plug-with-.patch
Normal file
252
hw-arm-virt-Enable-device-memory-cold-hot-plug-with-.patch
Normal file
@ -0,0 +1,252 @@
|
||||
From ce813d8daa2e01df52509f4bb52b9ab774408706 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:27 +0100
|
||||
Subject: [PATCH] hw/arm/virt: Enable device memory cold/hot plug with ACPI
|
||||
boot
|
||||
|
||||
This initializes the GED device with base memory and irq, configures
|
||||
ged memory hotplug event and builds the corresponding aml code. With
|
||||
this, both hot and cold plug of device memory is enabled now for Guest
|
||||
with ACPI boot. Memory cold plug support with Guest DT boot is not yet
|
||||
supported.
|
||||
|
||||
As DSDT table gets changed by this, update bios-tables-test-allowed-diff.h
|
||||
to avoid "make check" failure.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Message-Id: <20190918130633.4872-6-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/arm/Kconfig | 2 ++
|
||||
hw/arm/virt-acpi-build.c | 21 ++++++++++++++
|
||||
hw/arm/virt.c | 59 +++++++++++++++++++++++++++++++++++-----
|
||||
include/hw/arm/virt.h | 4 +++
|
||||
4 files changed, 79 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
|
||||
index 84961c17ab..ad7f7c089b 100644
|
||||
--- a/hw/arm/Kconfig
|
||||
+++ b/hw/arm/Kconfig
|
||||
@@ -22,6 +22,8 @@ config ARM_VIRT
|
||||
select ACPI_PCI
|
||||
select MEM_DEVICE
|
||||
select DIMM
|
||||
+ select ACPI_MEMORY_HOTPLUG
|
||||
+ select ACPI_HW_REDUCED
|
||||
|
||||
config CHEETAH
|
||||
bool
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index fe54411f6a..fca53ae01f 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "hw/acpi/aml-build.h"
|
||||
#include "hw/acpi/utils.h"
|
||||
#include "hw/acpi/pci.h"
|
||||
+#include "hw/acpi/memory_hotplug.h"
|
||||
+#include "hw/acpi/generic_event_device.h"
|
||||
#include "hw/pci/pcie_host.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/arm/virt.h"
|
||||
@@ -779,6 +781,7 @@ static void
|
||||
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
{
|
||||
Aml *scope, *dsdt;
|
||||
+ MachineState *ms = MACHINE(vms);
|
||||
const MemMapEntry *memmap = vms->memmap;
|
||||
const int *irqmap = vms->irqmap;
|
||||
|
||||
@@ -803,6 +806,24 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
vms->highmem, vms->highmem_ecam);
|
||||
acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
|
||||
(irqmap[VIRT_GPIO] + ARM_SPI_BASE));
|
||||
+ if (vms->acpi_dev) {
|
||||
+ build_ged_aml(scope, "\\_SB."GED_DEVICE,
|
||||
+ HOTPLUG_HANDLER(vms->acpi_dev),
|
||||
+ irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
|
||||
+ memmap[VIRT_ACPI_GED].base);
|
||||
+ }
|
||||
+
|
||||
+ if (vms->acpi_dev) {
|
||||
+ uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev),
|
||||
+ "ged-event", &error_abort);
|
||||
+
|
||||
+ if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
|
||||
+ build_memory_hotplug_aml(scope, ms->ram_slots, "\\_SB", NULL,
|
||||
+ AML_SYSTEM_MEMORY,
|
||||
+ memmap[VIRT_PCDIMM_ACPI].base);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
acpi_dsdt_add_power_button(scope);
|
||||
|
||||
aml_append(dsdt, scope);
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index c7c07fe3ac..8ccabd5159 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -67,6 +67,7 @@
|
||||
#include "target/arm/internals.h"
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
+#include "hw/acpi/generic_event_device.h"
|
||||
|
||||
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
|
||||
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
|
||||
@@ -137,6 +138,8 @@ static const MemMapEntry base_memmap[] = {
|
||||
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
|
||||
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
|
||||
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
|
||||
+ [VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
|
||||
+ [VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
|
||||
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
|
||||
[VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 },
|
||||
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
|
||||
@@ -173,6 +176,7 @@ static const int a15irqmap[] = {
|
||||
[VIRT_PCIE] = 3, /* ... to 6 */
|
||||
[VIRT_GPIO] = 7,
|
||||
[VIRT_SECURE_UART] = 8,
|
||||
+ [VIRT_ACPI_GED] = 9,
|
||||
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
|
||||
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
|
||||
[VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
|
||||
@@ -630,6 +634,29 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
|
||||
}
|
||||
}
|
||||
|
||||
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
|
||||
+{
|
||||
+ DeviceState *dev;
|
||||
+ MachineState *ms = MACHINE(vms);
|
||||
+ int irq = vms->irqmap[VIRT_ACPI_GED];
|
||||
+ uint32_t event = 0;
|
||||
+
|
||||
+ if (ms->ram_slots) {
|
||||
+ event = ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
+ }
|
||||
+
|
||||
+ dev = qdev_create(NULL, TYPE_ACPI_GED);
|
||||
+ qdev_prop_set_uint32(dev, "ged-event", event);
|
||||
+
|
||||
+ 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_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
|
||||
+
|
||||
+ qdev_init_nofail(dev);
|
||||
+
|
||||
+ return dev;
|
||||
+}
|
||||
+
|
||||
static void create_its(VirtMachineState *vms, DeviceState *gicdev)
|
||||
{
|
||||
const char *itsclass = its_class_name();
|
||||
@@ -1603,6 +1630,7 @@ static void machvirt_init(MachineState *machine)
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
bool firmware_loaded;
|
||||
bool aarch64 = true;
|
||||
+ bool has_ged = !vmc->no_ged;
|
||||
unsigned int smp_cpus = machine->smp.cpus;
|
||||
unsigned int max_cpus = machine->smp.max_cpus;
|
||||
|
||||
@@ -1824,6 +1852,10 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
create_gpio(vms, pic);
|
||||
|
||||
+ if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
|
||||
+ vms->acpi_dev = create_acpi_ged(vms, pic);
|
||||
+ }
|
||||
+
|
||||
/* Create mmio transports, so the user can create virtio backends
|
||||
* (which will be automatically plugged in to the transports). If
|
||||
* no backend is created the transport will just sit harmlessly idle.
|
||||
@@ -2003,14 +2035,17 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
||||
static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||
+ const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
|
||||
|
||||
- /*
|
||||
- * The device memory is not yet exposed to the Guest either through
|
||||
- * DT or ACPI and hence both cold/hot plug of memory is explicitly
|
||||
- * disabled for now.
|
||||
- */
|
||||
- if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||
- error_setg(errp, "memory cold/hot plug is not yet supported");
|
||||
+ if (is_nvdimm) {
|
||||
+ error_setg(errp, "nvdimm is not yet supported");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!vms->acpi_dev) {
|
||||
+ error_setg(errp,
|
||||
+ "memory hotplug is not enabled: missing acpi-ged device");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2020,11 +2055,18 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
static void virt_memory_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
+ HotplugHandlerClass *hhc;
|
||||
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
|
||||
+ if (local_err) {
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
+ hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
|
||||
+ hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
|
||||
+out:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
@@ -2231,8 +2273,11 @@ DEFINE_VIRT_MACHINE_AS_LATEST(4, 1)
|
||||
|
||||
static void virt_machine_4_0_options(MachineClass *mc)
|
||||
{
|
||||
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
||||
+
|
||||
virt_machine_4_1_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
|
||||
+ vmc->no_ged = true;
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(4, 0)
|
||||
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index a9d6977afc..0350285136 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -78,6 +78,8 @@ enum {
|
||||
VIRT_GPIO,
|
||||
VIRT_SECURE_UART,
|
||||
VIRT_SECURE_MEM,
|
||||
+ VIRT_PCDIMM_ACPI,
|
||||
+ VIRT_ACPI_GED,
|
||||
VIRT_LOWMEMMAP_LAST,
|
||||
};
|
||||
|
||||
@@ -107,6 +109,7 @@ typedef struct {
|
||||
bool claim_edge_triggered_timers;
|
||||
bool smbios_old_sys_ver;
|
||||
bool no_highmem_ecam;
|
||||
+ bool no_ged; /* Machines < 4.1 has no support for ACPI GED device */
|
||||
bool kvm_no_adjvtime;
|
||||
} VirtMachineClass;
|
||||
|
||||
@@ -135,6 +138,7 @@ typedef struct {
|
||||
uint32_t iommu_phandle;
|
||||
int psci_conduit;
|
||||
hwaddr highest_gpa;
|
||||
+ DeviceState *acpi_dev;
|
||||
} VirtMachineState;
|
||||
|
||||
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
|
||||
--
|
||||
2.19.1
|
||||
170
hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch
Normal file
170
hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 3a0af1446395e74476a763ca12713b28c099a144 Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Mon, 6 Apr 2020 12:50:54 +0800
|
||||
Subject: [PATCH] hw/arm/virt: Factor out some CPU init codes to pre_plug hook
|
||||
|
||||
The init path of hotplugged CPU is pre_plug/realize/plug, so we
|
||||
must move these init code in machvirt_init to pre_plug hook, to
|
||||
let them be shared by all CPUs.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/virt.c | 108 +++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 58 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 64532b61b2..83f4887e57 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -196,6 +196,8 @@ static const char *valid_cpus[] = {
|
||||
ARM_CPU_TYPE_NAME("max"),
|
||||
};
|
||||
|
||||
+static MemoryRegion *secure_sysmem;
|
||||
+
|
||||
static bool cpu_type_valid(const char *cpu)
|
||||
{
|
||||
int i;
|
||||
@@ -1629,7 +1631,6 @@ static void machvirt_init(MachineState *machine)
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
const CPUArchIdList *possible_cpus;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
- MemoryRegion *secure_sysmem = NULL;
|
||||
int n, virt_max_cpus;
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
bool firmware_loaded;
|
||||
@@ -1752,57 +1753,10 @@ static void machvirt_init(MachineState *machine)
|
||||
}
|
||||
|
||||
cpuobj = object_new(possible_cpus->cpus[n].type);
|
||||
- object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id,
|
||||
- "mp-affinity", NULL);
|
||||
+ aarch64 &= object_property_get_bool(cpuobj, "aarch64", NULL);
|
||||
|
||||
cs = CPU(cpuobj);
|
||||
cs->cpu_index = n;
|
||||
-
|
||||
- numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
|
||||
- &error_fatal);
|
||||
-
|
||||
- aarch64 &= object_property_get_bool(cpuobj, "aarch64", NULL);
|
||||
-
|
||||
- if (!vms->secure) {
|
||||
- object_property_set_bool(cpuobj, false, "has_el3", NULL);
|
||||
- }
|
||||
-
|
||||
- if (!vms->virt && object_property_find(cpuobj, "has_el2", NULL)) {
|
||||
- object_property_set_bool(cpuobj, false, "has_el2", NULL);
|
||||
- }
|
||||
-
|
||||
- if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
|
||||
- object_property_set_int(cpuobj, vms->psci_conduit,
|
||||
- "psci-conduit", NULL);
|
||||
-
|
||||
- /* Secondary CPUs start in PSCI powered-down state */
|
||||
- if (n > 0) {
|
||||
- object_property_set_bool(cpuobj, true,
|
||||
- "start-powered-off", NULL);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (vmc->kvm_no_adjvtime &&
|
||||
- object_property_find(cpuobj, "kvm-no-adjvtime", NULL)) {
|
||||
- object_property_set_bool(cpuobj, true, "kvm-no-adjvtime", NULL);
|
||||
- }
|
||||
-
|
||||
- if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
|
||||
- object_property_set_bool(cpuobj, false, "pmu", NULL);
|
||||
- }
|
||||
-
|
||||
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
|
||||
- object_property_set_int(cpuobj, vms->memmap[VIRT_CPUPERIPHS].base,
|
||||
- "reset-cbar", &error_abort);
|
||||
- }
|
||||
-
|
||||
- object_property_set_link(cpuobj, OBJECT(sysmem), "memory",
|
||||
- &error_abort);
|
||||
- if (vms->secure) {
|
||||
- object_property_set_link(cpuobj, OBJECT(secure_sysmem),
|
||||
- "secure-memory", &error_abort);
|
||||
- }
|
||||
-
|
||||
object_property_set_bool(cpuobj, true, "realized", &error_fatal);
|
||||
object_unref(cpuobj);
|
||||
}
|
||||
@@ -2089,10 +2043,16 @@ out:
|
||||
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
- CPUState *cs = CPU(dev);
|
||||
ARMCPUTopoInfo topo;
|
||||
+ Object *cpuobj = OBJECT(dev);
|
||||
+ CPUState *cs = CPU(dev);
|
||||
ARMCPU *cpu = ARM_CPU(dev);
|
||||
MachineState *ms = MACHINE(hotplug_dev);
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(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);
|
||||
+ MemoryRegion *sysmem = get_system_memory();
|
||||
int smp_cores = ms->smp.cores;
|
||||
int smp_threads = ms->smp.threads;
|
||||
|
||||
@@ -2145,6 +2105,54 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
return;
|
||||
}
|
||||
cpu->thread_id = topo.smt_id;
|
||||
+
|
||||
+ /* Init some properties */
|
||||
+
|
||||
+ object_property_set_int(cpuobj, possible_cpus->cpus[cs->cpu_index].arch_id,
|
||||
+ "mp-affinity", NULL);
|
||||
+
|
||||
+ numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
|
||||
+ &error_fatal);
|
||||
+
|
||||
+ if (!vms->secure) {
|
||||
+ object_property_set_bool(cpuobj, false, "has_el3", NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (!vms->virt && object_property_find(cpuobj, "has_el2", NULL)) {
|
||||
+ object_property_set_bool(cpuobj, false, "has_el2", NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
|
||||
+ object_property_set_int(cpuobj, vms->psci_conduit,
|
||||
+ "psci-conduit", NULL);
|
||||
+
|
||||
+ /* Secondary CPUs start in PSCI powered-down state */
|
||||
+ if (cs->cpu_index > 0) {
|
||||
+ object_property_set_bool(cpuobj, true,
|
||||
+ "start-powered-off", NULL);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (vmc->kvm_no_adjvtime &&
|
||||
+ object_property_find(cpuobj, "kvm-no-adjvtime", NULL)) {
|
||||
+ object_property_set_bool(cpuobj, true, "kvm-no-adjvtime", NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
|
||||
+ object_property_set_bool(cpuobj, false, "pmu", NULL);
|
||||
+ }
|
||||
+
|
||||
+ if (object_property_find(cpuobj, "reset-cbar", NULL)) {
|
||||
+ object_property_set_int(cpuobj, vms->memmap[VIRT_CPUPERIPHS].base,
|
||||
+ "reset-cbar", &error_abort);
|
||||
+ }
|
||||
+
|
||||
+ object_property_set_link(cpuobj, OBJECT(sysmem), "memory",
|
||||
+ &error_abort);
|
||||
+ if (vms->secure) {
|
||||
+ object_property_set_link(cpuobj, OBJECT(secure_sysmem),
|
||||
+ "secure-memory", &error_abort);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
--
|
||||
2.19.1
|
||||
@ -1,6 +1,6 @@
|
||||
From 123b4eb3cb7b9b4e3e0705a9b5f974b37d3b8431 Mon Sep 17 00:00:00 2001
|
||||
From: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Date: Mon, 5 Aug 2019 15:04:31 +0800
|
||||
From 73fc4af05ebe12d77915e6b3c85c48f5e0c432f3 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Wed, 22 Apr 2020 19:23:27 +0800
|
||||
Subject: [PATCH] hw/arm/virt: Introduce cpu topology support
|
||||
|
||||
Add topology support for guest vcpu by cpu-map in dtb when the guest is booted
|
||||
@ -11,13 +11,13 @@ Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
(picked-from https://patchwork.ozlabs.org/cover/939301/ which is pushed by
|
||||
Andrew Jones <drjones@redhat.com>)
|
||||
---
|
||||
device_tree.c | 32 +++++++++++++++++++++++
|
||||
hw/acpi/aml-build.c | 50 ++++++++++++++++++++++++++++++++++++
|
||||
device_tree.c | 32 ++++++++++++++++++++++
|
||||
hw/acpi/aml-build.c | 53 ++++++++++++++++++++++++++++++++++++
|
||||
hw/arm/virt-acpi-build.c | 4 +++
|
||||
hw/arm/virt.c | 29 +++++++++++++++++++++
|
||||
hw/arm/virt.c | 32 +++++++++++++++++++++-
|
||||
include/hw/acpi/aml-build.h | 2 ++
|
||||
include/sysemu/device_tree.h | 1 +
|
||||
6 files changed, 118 insertions(+)
|
||||
6 files changed, 123 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/device_tree.c b/device_tree.c
|
||||
index f8b46b3c..03906a14 100644
|
||||
@ -63,7 +63,7 @@ index f8b46b3c..03906a14 100644
|
||||
{
|
||||
const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index 73f97751..9d39ad10 100644
|
||||
index 73f97751..f2c8c28f 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -25,6 +25,7 @@
|
||||
@ -74,7 +74,7 @@ index 73f97751..9d39ad10 100644
|
||||
|
||||
static GArray *build_alloc_array(void)
|
||||
{
|
||||
@@ -51,6 +52,55 @@ static void build_append_array(GArray *array, GArray *val)
|
||||
@@ -51,6 +52,58 @@ static void build_append_array(GArray *array, GArray *val)
|
||||
g_array_append_vals(array, val->data, val->len);
|
||||
}
|
||||
|
||||
@ -97,6 +97,9 @@ index 73f97751..9d39ad10 100644
|
||||
+{
|
||||
+ int pptt_start = table_data->len;
|
||||
+ int uid = 0, cpus = 0, socket;
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cores = ms->smp.cores;
|
||||
+ unsigned int smp_threads = ms->smp.threads;
|
||||
+
|
||||
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
|
||||
+
|
||||
@ -131,10 +134,10 @@ index 73f97751..9d39ad10 100644
|
||||
|
||||
static void
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index 33a8e2e3..18653e6d 100644
|
||||
index 29494ebd..fe54411f 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -870,6 +870,10 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||
@@ -848,6 +848,10 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_fadt_rev5(tables_blob, tables->linker, vms, dsdt);
|
||||
|
||||
@ -146,10 +149,10 @@ index 33a8e2e3..18653e6d 100644
|
||||
build_madt(tables_blob, tables->linker, vms);
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 57a78b16..16700a2e 100644
|
||||
index 0fa355ba..272455bc 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -42,6 +42,7 @@
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "net/net.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "sysemu/numa.h"
|
||||
@ -157,7 +160,17 @@ index 57a78b16..16700a2e 100644
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "hw/loader.h"
|
||||
@@ -364,8 +365,36 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
@@ -312,7 +313,8 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
int cpu;
|
||||
int addr_cells = 1;
|
||||
const MachineState *ms = MACHINE(vms);
|
||||
-
|
||||
+ unsigned int smp_cores = ms->smp.cores;
|
||||
+ unsigned int smp_threads = ms->smp.threads;
|
||||
/*
|
||||
* From Documentation/devicetree/bindings/arm/cpus.txt
|
||||
* On ARM v8 64-bit systems value should be set to 2,
|
||||
@@ -368,8 +370,36 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
|
||||
}
|
||||
|
||||
@ -220,5 +233,4 @@ index c16fd69b..d62fc873 100644
|
||||
#define qemu_fdt_setprop_cells(fdt, node_path, property, ...) \
|
||||
do { \
|
||||
--
|
||||
2.19.1
|
||||
|
||||
2.23.0
|
||||
|
||||
402
hw-arm-virt-Simplify-by-moving-the-gic-in-the-machin.patch
Normal file
402
hw-arm-virt-Simplify-by-moving-the-gic-in-the-machin.patch
Normal file
@ -0,0 +1,402 @@
|
||||
From 5d1be90750551f1debf5767d7a6e2b9c50054c05 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
|
||||
Date: Mon, 9 Dec 2019 10:03:06 +0100
|
||||
Subject: [PATCH] hw/arm/virt: Simplify by moving the gic in the machine state
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Make the gic a field in the machine state, and instead of filling
|
||||
an array of qemu_irq and passing it around, directly call
|
||||
qdev_get_gpio_in() on the gic field.
|
||||
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
|
||||
Message-id: 20191209090306.20433-1-philmd@redhat.com
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
---
|
||||
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
|
||||
include/hw/arm/virt.h | 1 +
|
||||
2 files changed, 55 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 18321e522b..8638aeedb7 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -634,7 +634,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
|
||||
}
|
||||
}
|
||||
|
||||
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
|
||||
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
|
||||
{
|
||||
DeviceState *dev;
|
||||
MachineState *ms = MACHINE(vms);
|
||||
@@ -650,14 +650,14 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
|
||||
|
||||
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_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
|
||||
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
|
||||
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
|
||||
+static void create_its(VirtMachineState *vms)
|
||||
{
|
||||
const char *itsclass = its_class_name();
|
||||
DeviceState *dev;
|
||||
@@ -669,7 +669,7 @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
|
||||
|
||||
dev = qdev_create(NULL, itsclass);
|
||||
|
||||
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
|
||||
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
|
||||
&error_abort);
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
|
||||
@@ -677,7 +677,7 @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
|
||||
fdt_add_its_gic_node(vms);
|
||||
}
|
||||
|
||||
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
|
||||
+static void create_v2m(VirtMachineState *vms)
|
||||
{
|
||||
int i;
|
||||
int irq = vms->irqmap[VIRT_GIC_V2M];
|
||||
@@ -690,17 +690,17 @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
|
||||
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
|
||||
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
|
||||
+ qdev_get_gpio_in(vms->gic, irq + i));
|
||||
}
|
||||
|
||||
fdt_add_v2m_gic_node(vms);
|
||||
}
|
||||
|
||||
-static void create_gic(VirtMachineState *vms, qemu_irq *pic)
|
||||
+static void create_gic(VirtMachineState *vms)
|
||||
{
|
||||
MachineState *ms = MACHINE(vms);
|
||||
/* We create a standalone GIC */
|
||||
- DeviceState *gicdev;
|
||||
SysBusDevice *gicbusdev;
|
||||
const char *gictype;
|
||||
int type = vms->gic_version, i;
|
||||
@@ -709,15 +709,15 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
|
||||
|
||||
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
|
||||
|
||||
- gicdev = qdev_create(NULL, gictype);
|
||||
- qdev_prop_set_uint32(gicdev, "revision", type);
|
||||
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
|
||||
+ vms->gic = qdev_create(NULL, gictype);
|
||||
+ qdev_prop_set_uint32(vms->gic, "revision", type);
|
||||
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
|
||||
/* Note that the num-irq property counts both internal and external
|
||||
* interrupts; there are always 32 of the former (mandated by GIC spec).
|
||||
*/
|
||||
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
|
||||
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
- qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
|
||||
+ qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
|
||||
}
|
||||
|
||||
if (type == 3) {
|
||||
@@ -727,25 +727,25 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
|
||||
|
||||
nb_redist_regions = virt_gicv3_redist_region_count(vms);
|
||||
|
||||
- qdev_prop_set_uint32(gicdev, "len-redist-region-count",
|
||||
+ qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
|
||||
nb_redist_regions);
|
||||
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
|
||||
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
|
||||
|
||||
if (nb_redist_regions == 2) {
|
||||
uint32_t redist1_capacity =
|
||||
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
|
||||
|
||||
- qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
|
||||
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
|
||||
MIN(smp_cpus - redist0_count, redist1_capacity));
|
||||
}
|
||||
} else {
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
- qdev_prop_set_bit(gicdev, "has-virtualization-extensions",
|
||||
+ qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
|
||||
vms->virt);
|
||||
}
|
||||
}
|
||||
- qdev_init_nofail(gicdev);
|
||||
- gicbusdev = SYS_BUS_DEVICE(gicdev);
|
||||
+ qdev_init_nofail(vms->gic);
|
||||
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
|
||||
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
|
||||
if (type == 3) {
|
||||
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
|
||||
@@ -781,23 +781,23 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
|
||||
|
||||
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
|
||||
qdev_connect_gpio_out(cpudev, irq,
|
||||
- qdev_get_gpio_in(gicdev,
|
||||
+ qdev_get_gpio_in(vms->gic,
|
||||
ppibase + timer_irq[irq]));
|
||||
}
|
||||
|
||||
if (type == 3) {
|
||||
- qemu_irq irq = qdev_get_gpio_in(gicdev,
|
||||
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
|
||||
0, irq);
|
||||
} else if (vms->virt) {
|
||||
- qemu_irq irq = qdev_get_gpio_in(gicdev,
|
||||
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
|
||||
}
|
||||
|
||||
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
|
||||
- qdev_get_gpio_in(gicdev, ppibase
|
||||
+ qdev_get_gpio_in(vms->gic, ppibase
|
||||
+ VIRTUAL_PMU_IRQ));
|
||||
|
||||
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
|
||||
@@ -809,20 +809,16 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
|
||||
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
|
||||
}
|
||||
|
||||
- for (i = 0; i < NUM_IRQS; i++) {
|
||||
- pic[i] = qdev_get_gpio_in(gicdev, i);
|
||||
- }
|
||||
-
|
||||
fdt_add_gic_node(vms);
|
||||
|
||||
if (type == 3 && vms->its) {
|
||||
- create_its(vms, gicdev);
|
||||
+ create_its(vms);
|
||||
} else if (type == 2) {
|
||||
- create_v2m(vms, pic);
|
||||
+ create_v2m(vms);
|
||||
}
|
||||
}
|
||||
|
||||
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
|
||||
+static void create_uart(const VirtMachineState *vms, int uart,
|
||||
MemoryRegion *mem, Chardev *chr)
|
||||
{
|
||||
char *nodename;
|
||||
@@ -838,7 +834,7 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
|
||||
qdev_init_nofail(dev);
|
||||
memory_region_add_subregion(mem, base,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
- sysbus_connect_irq(s, 0, pic[irq]);
|
||||
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
|
||||
|
||||
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(vms->fdt, nodename);
|
||||
@@ -880,7 +876,7 @@ static void create_cpufreq(const VirtMachineState *vms, MemoryRegion *mem)
|
||||
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;
|
||||
hwaddr base = vms->memmap[VIRT_RTC].base;
|
||||
@@ -888,7 +884,7 @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
|
||||
int irq = vms->irqmap[VIRT_RTC];
|
||||
const char compat[] = "arm,pl031\0arm,primecell";
|
||||
|
||||
- sysbus_create_simple("pl031", base, pic[irq]);
|
||||
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
|
||||
|
||||
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(vms->fdt, nodename);
|
||||
@@ -916,7 +912,7 @@ static void virt_powerdown_req(Notifier *n, void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
|
||||
+static void create_gpio(const VirtMachineState *vms)
|
||||
{
|
||||
char *nodename;
|
||||
DeviceState *pl061_dev;
|
||||
@@ -925,7 +921,8 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
|
||||
int irq = vms->irqmap[VIRT_GPIO];
|
||||
const char compat[] = "arm,pl061\0arm,primecell";
|
||||
|
||||
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
|
||||
+ pl061_dev = sysbus_create_simple("pl061", base,
|
||||
+ qdev_get_gpio_in(vms->gic, irq));
|
||||
|
||||
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
|
||||
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
|
||||
@@ -959,7 +956,7 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
|
||||
+static void create_virtio_devices(const VirtMachineState *vms)
|
||||
{
|
||||
int i;
|
||||
hwaddr size = vms->memmap[VIRT_MMIO].size;
|
||||
@@ -995,7 +992,8 @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
|
||||
int irq = vms->irqmap[VIRT_MMIO] + i;
|
||||
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
|
||||
|
||||
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
|
||||
+ sysbus_create_simple("virtio-mmio", base,
|
||||
+ qdev_get_gpio_in(vms->gic, irq));
|
||||
}
|
||||
|
||||
/* We add dtb nodes in reverse order so that they appear in the finished
|
||||
@@ -1244,7 +1242,7 @@ static void create_pcie_irq_map(const VirtMachineState *vms,
|
||||
0x7 /* PCI irq */);
|
||||
}
|
||||
|
||||
-static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
|
||||
+static void create_smmu(const VirtMachineState *vms,
|
||||
PCIBus *bus)
|
||||
{
|
||||
char *node;
|
||||
@@ -1267,7 +1265,8 @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
|
||||
for (i = 0; i < NUM_SMMU_IRQS; i++) {
|
||||
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
|
||||
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
|
||||
+ qdev_get_gpio_in(vms->gic, irq + i));
|
||||
}
|
||||
|
||||
node = g_strdup_printf("/smmuv3@%" PRIx64, base);
|
||||
@@ -1294,7 +1293,7 @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
|
||||
g_free(node);
|
||||
}
|
||||
|
||||
-static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
|
||||
+static void create_pcie(VirtMachineState *vms)
|
||||
{
|
||||
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
|
||||
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
|
||||
@@ -1354,7 +1353,8 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
|
||||
|
||||
for (i = 0; i < GPEX_NUM_IRQS; i++) {
|
||||
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
|
||||
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
|
||||
+ qdev_get_gpio_in(vms->gic, irq + i));
|
||||
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
|
||||
}
|
||||
|
||||
@@ -1414,7 +1414,7 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
|
||||
if (vms->iommu) {
|
||||
vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
|
||||
|
||||
- create_smmu(vms, pic, pci->bus);
|
||||
+ create_smmu(vms, pci->bus);
|
||||
|
||||
qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
|
||||
0x0, vms->iommu_phandle, 0x0, 0x10000);
|
||||
@@ -1423,7 +1423,7 @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
-static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
|
||||
+static void create_platform_bus(VirtMachineState *vms)
|
||||
{
|
||||
DeviceState *dev;
|
||||
SysBusDevice *s;
|
||||
@@ -1439,8 +1439,8 @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
|
||||
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
|
||||
- int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
|
||||
- sysbus_connect_irq(s, i, pic[irqn]);
|
||||
+ int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i;
|
||||
+ sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq));
|
||||
}
|
||||
|
||||
memory_region_add_subregion(sysmem,
|
||||
@@ -1621,7 +1621,6 @@ static void machvirt_init(MachineState *machine)
|
||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
const CPUArchIdList *possible_cpus;
|
||||
- qemu_irq pic[NUM_IRQS];
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *secure_sysmem = NULL;
|
||||
int n, virt_max_cpus;
|
||||
@@ -1829,29 +1828,29 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
|
||||
|
||||
- create_gic(vms, pic);
|
||||
+ create_gic(vms);
|
||||
|
||||
fdt_add_pmu_nodes(vms);
|
||||
|
||||
- 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_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
|
||||
}
|
||||
|
||||
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
|
||||
|
||||
- create_rtc(vms, pic);
|
||||
+ create_rtc(vms);
|
||||
|
||||
- create_pcie(vms, pic);
|
||||
+ create_pcie(vms);
|
||||
|
||||
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
|
||||
- vms->acpi_dev = create_acpi_ged(vms, pic);
|
||||
+ vms->acpi_dev = create_acpi_ged(vms);
|
||||
} else {
|
||||
- create_gpio(vms, pic);
|
||||
+ create_gpio(vms);
|
||||
}
|
||||
|
||||
/* connect powerdown request */
|
||||
@@ -1862,12 +1861,12 @@ static void machvirt_init(MachineState *machine)
|
||||
* (which will be automatically plugged in to the transports). If
|
||||
* no backend is created the transport will just sit harmlessly idle.
|
||||
*/
|
||||
- create_virtio_devices(vms, pic);
|
||||
+ create_virtio_devices(vms);
|
||||
|
||||
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
|
||||
rom_set_fw(vms->fw_cfg);
|
||||
|
||||
- create_platform_bus(vms, pic);
|
||||
+ create_platform_bus(vms);
|
||||
|
||||
vms->bootinfo.ram_size = machine->ram_size;
|
||||
vms->bootinfo.kernel_filename = machine->kernel_filename;
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index dcceb9c615..3dfefca93b 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -138,6 +138,7 @@ typedef struct {
|
||||
uint32_t iommu_phandle;
|
||||
int psci_conduit;
|
||||
hwaddr highest_gpa;
|
||||
+ DeviceState *gic;
|
||||
DeviceState *acpi_dev;
|
||||
Notifier powerdown_notifier;
|
||||
} VirtMachineState;
|
||||
--
|
||||
2.19.1
|
||||
75
hw-arm-virt-acpi-build-Add-PC-DIMM-in-SRAT.patch
Normal file
75
hw-arm-virt-acpi-build-Add-PC-DIMM-in-SRAT.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 8d287871fd4e1b4654fe9e5011b80614cb44f6d8 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Wed, 18 Sep 2019 14:06:28 +0100
|
||||
Subject: [PATCH] hw/arm/virt-acpi-build: Add PC-DIMM in SRAT
|
||||
|
||||
Generate Memory Affinity Structures for PC-DIMM ranges.
|
||||
|
||||
Also, Linux and Windows need ACPI SRAT table to make memory hotplug
|
||||
work properly, however currently QEMU doesn't create SRAT table if
|
||||
numa options aren't present on CLI. Hence add support(>=4.2) to
|
||||
create numa node automatically (auto_enable_numa_with_memhp) when
|
||||
QEMU is started with memory hotplug enabled but without '-numa'
|
||||
options on CLI.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20190918130633.4872-7-shameerali.kolothum.thodi@huawei.com>
|
||||
Acked-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
---
|
||||
hw/arm/virt-acpi-build.c | 9 +++++++++
|
||||
hw/arm/virt.c | 2 ++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index fca53ae01f..9622994e50 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -592,6 +592,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
int i, srat_start;
|
||||
uint64_t mem_base;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||||
+ MachineState *ms = MACHINE(vms);
|
||||
const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(MACHINE(vms));
|
||||
|
||||
srat_start = table_data->len;
|
||||
@@ -617,6 +618,14 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (ms->device_memory) {
|
||||
+ numamem = acpi_data_push(table_data, sizeof *numamem);
|
||||
+ build_srat_memory(numamem, ms->device_memory->base,
|
||||
+ memory_region_size(&ms->device_memory->mr),
|
||||
+ nb_numa_nodes - 1,
|
||||
+ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
||||
+ }
|
||||
+
|
||||
build_header(linker, table_data, (void *)(table_data->data + srat_start),
|
||||
"SRAT", table_data->len - srat_start, 3, NULL, NULL);
|
||||
}
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 8ccabd5159..ab33cce4b3 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -2173,6 +2173,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
hc->plug = virt_machine_device_plug_cb;
|
||||
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
||||
mc->numa_mem_supported = true;
|
||||
+ mc->auto_enable_numa_with_memhp = true;
|
||||
}
|
||||
|
||||
static void virt_instance_init(Object *obj)
|
||||
@@ -2278,6 +2279,7 @@ static void virt_machine_4_0_options(MachineClass *mc)
|
||||
virt_machine_4_1_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
|
||||
vmc->no_ged = true;
|
||||
+ mc->auto_enable_numa_with_memhp = false;
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(4, 0)
|
||||
|
||||
--
|
||||
2.19.1
|
||||
25
hw-arm-virt-add-missing-compat-for-kvm-no-adjvtime.patch
Normal file
25
hw-arm-virt-add-missing-compat-for-kvm-no-adjvtime.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From fbcb4ffa8648d0aa5be01c11816423a483f245ae Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Tue, 26 May 2020 22:39:23 +0800
|
||||
Subject: [PATCH] hw/arm/virt: add missing compat for kvm-no-adjvtime
|
||||
|
||||
Machine compatibility for kvm-no-adjvtime is missed,
|
||||
let's add it for virt machine 4.0
|
||||
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 4c727939..133d36a4 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -2492,6 +2492,7 @@ static void virt_machine_4_0_options(MachineClass *mc)
|
||||
compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len);
|
||||
vmc->no_ged = true;
|
||||
mc->auto_enable_numa_with_memhp = false;
|
||||
+ vmc->kvm_no_adjvtime = true;
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(4, 0)
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
From 8db6d888e3eb131900111506b93f6101413df5b4 Mon Sep 17 00:00:00 2001
|
||||
From: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Date: Mon, 5 Aug 2019 15:30:05 +0800
|
||||
From 5a0ed254f99ca37498bd81994b906b6984b5ffa9 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Wed, 22 Apr 2020 19:25:00 +0800
|
||||
Subject: [PATCH] hw/arm64: add vcpu cache info support
|
||||
|
||||
Support VCPU Cache info by dtb and PPTT table, including L1, L2 and L3 Cache.
|
||||
@ -8,16 +8,16 @@ Support VCPU Cache info by dtb and PPTT table, including L1, L2 and L3 Cache.
|
||||
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
Signed-off-by: Honghao <honghao5@huawei.com>
|
||||
---
|
||||
hw/acpi/aml-build.c | 124 ++++++++++++++++++++++++++++++++++++
|
||||
hw/arm/virt.c | 76 +++++++++++++++++++++-
|
||||
hw/acpi/aml-build.c | 126 ++++++++++++++++++++++++++++++++++++
|
||||
hw/arm/virt.c | 80 ++++++++++++++++++++++-
|
||||
include/hw/acpi/aml-build.h | 46 +++++++++++++
|
||||
3 files changed, 245 insertions(+), 1 deletion(-)
|
||||
3 files changed, 251 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index 9d39ad10..99209c0a 100644
|
||||
index f2c8c28f..74e95005 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -55,6 +55,129 @@ static void build_append_array(GArray *array, GArray *val)
|
||||
@@ -55,6 +55,131 @@ static void build_append_array(GArray *array, GArray *val)
|
||||
/*
|
||||
* ACPI 6.2 Processor Properties Topology Table (PPTT)
|
||||
*/
|
||||
@ -115,6 +115,8 @@ index 9d39ad10..99209c0a 100644
|
||||
+ int pptt_start = table_data->len;
|
||||
+ int uid = 0, cpus = 0, socket;
|
||||
+ struct offset_status offset;
|
||||
+ const MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cores = ms->smp.cores;
|
||||
+
|
||||
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
|
||||
+
|
||||
@ -147,7 +149,7 @@ index 9d39ad10..99209c0a 100644
|
||||
static void build_cpu_hierarchy(GArray *tbl, uint32_t flags,
|
||||
uint32_t parent, uint32_t id)
|
||||
{
|
||||
@@ -100,6 +223,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, int possible_cpus)
|
||||
@@ -103,6 +228,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, int possible_cpus)
|
||||
(void *)(table_data->data + pptt_start), "PPTT",
|
||||
table_data->len - pptt_start, 1, NULL, NULL);
|
||||
}
|
||||
@ -156,16 +158,18 @@ index 9d39ad10..99209c0a 100644
|
||||
#define ACPI_NAMESEG_LEN 4
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 16700a2e..96f56e2e 100644
|
||||
index 272455bc..9669c70b 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -304,6 +304,77 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
|
||||
@@ -308,6 +308,81 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
|
||||
}
|
||||
|
||||
+static void fdt_add_l3cache_nodes(const VirtMachineState *vms)
|
||||
+{
|
||||
+ int i;
|
||||
+ const MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cores = ms->smp.cores;
|
||||
+ unsigned int sockets = vms->smp_cpus / smp_cores;
|
||||
+
|
||||
+ /* If current is not equal to max */
|
||||
@ -191,6 +195,8 @@ index 16700a2e..96f56e2e 100644
|
||||
+static void fdt_add_l2cache_nodes(const VirtMachineState *vms)
|
||||
+{
|
||||
+ int i, j;
|
||||
+ const MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ unsigned int smp_cores = ms->smp.cores;
|
||||
+ signed int sockets = vms->smp_cpus / smp_cores;
|
||||
+
|
||||
+ /* If current is not equal to max */
|
||||
@ -237,7 +243,7 @@ index 16700a2e..96f56e2e 100644
|
||||
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
{
|
||||
int cpu;
|
||||
@@ -336,6 +407,9 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
@@ -341,6 +416,9 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells);
|
||||
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0);
|
||||
|
||||
@ -247,7 +253,7 @@ index 16700a2e..96f56e2e 100644
|
||||
for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
|
||||
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
|
||||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
|
||||
@@ -364,7 +438,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
@@ -369,7 +447,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
qemu_fdt_setprop_cell(vms->fdt, nodename, "numa-node-id",
|
||||
ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
|
||||
}
|
||||
@ -315,4 +321,3 @@ index bfb0b100..0be3453a 100644
|
||||
*
|
||||
--
|
||||
2.23.0
|
||||
|
||||
|
||||
45
hw-core-loader-Fix-possible-crash-in-rom_copy.patch
Normal file
45
hw-core-loader-Fix-possible-crash-in-rom_copy.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From aae0faa5d3bee91c66dc4c1543190f55a242771e Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Wed, 25 Sep 2019 14:16:43 +0200
|
||||
Subject: [PATCH] hw/core/loader: Fix possible crash in rom_copy()
|
||||
|
||||
Both, "rom->addr" and "addr" are derived from the binary image
|
||||
that can be loaded with the "-kernel" paramer. The code in
|
||||
rom_copy() then calculates:
|
||||
|
||||
d = dest + (rom->addr - addr);
|
||||
|
||||
and uses "d" as destination in a memcpy() some lines later. Now with
|
||||
bad kernel images, it is possible that rom->addr is smaller than addr,
|
||||
thus "rom->addr - addr" gets negative and the memcpy() then tries to
|
||||
copy contents from the image to a bad memory location. This could
|
||||
maybe be used to inject code from a kernel image into the QEMU binary,
|
||||
so we better fix it with an additional sanity check here.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reported-by: Guangming Liu
|
||||
Buglink: https://bugs.launchpad.net/qemu/+bug/1844635
|
||||
Message-Id: <20190925130331.27825-1-thuth@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
(cherry picked from commit e423455c4f23a1a828901c78fe6d03b7dde79319)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
hw/core/loader.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/core/loader.c b/hw/core/loader.c
|
||||
index 425bf69a99..838a34174a 100644
|
||||
--- a/hw/core/loader.c
|
||||
+++ b/hw/core/loader.c
|
||||
@@ -1242,7 +1242,7 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
|
||||
if (rom->addr + rom->romsize < addr) {
|
||||
continue;
|
||||
}
|
||||
- if (rom->addr > end) {
|
||||
+ if (rom->addr > end || rom->addr < addr) {
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
170
hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch
Normal file
170
hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 6bbfb186c8d66b745aeb08143d3198fcedc52d6c Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Mon, 6 Apr 2020 11:26:35 +0800
|
||||
Subject: [PATCH] hw/intc/gicv3: Add CPU hotplug realize hook
|
||||
|
||||
GICv3 exposes individual CPU realization capability through
|
||||
this hook. It will be used for hotplugged CPU.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/intc/arm_gicv3.c | 17 ++++++++++++++++-
|
||||
hw/intc/arm_gicv3_common.c | 8 ++++++++
|
||||
hw/intc/arm_gicv3_kvm.c | 11 +++++++++++
|
||||
include/hw/intc/arm_gicv3.h | 2 ++
|
||||
include/hw/intc/arm_gicv3_common.h | 4 ++++
|
||||
5 files changed, 41 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
|
||||
index 2fe79f794d..cacef26546 100644
|
||||
--- a/hw/intc/arm_gicv3.c
|
||||
+++ b/hw/intc/arm_gicv3.c
|
||||
@@ -361,6 +361,19 @@ static const MemoryRegionOps gic_ops[] = {
|
||||
}
|
||||
};
|
||||
|
||||
+static void gicv3_cpu_realize(GICv3State *s, int i)
|
||||
+{
|
||||
+ gicv3_init_one_cpuif(s, i);
|
||||
+}
|
||||
+
|
||||
+static void arm_gicv3_cpu_hotplug_realize(GICv3State *s, int ncpu)
|
||||
+{
|
||||
+ ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s);
|
||||
+
|
||||
+ agc->parent_cpu_hotplug_realize(s, ncpu);
|
||||
+ gicv3_cpu_realize(s, ncpu);
|
||||
+}
|
||||
+
|
||||
static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
/* Device instance realize function for the GIC sysbus device */
|
||||
@@ -388,7 +401,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- gicv3_init_one_cpuif(s, i);
|
||||
+ gicv3_cpu_realize(s, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,6 +411,8 @@ static void arm_gicv3_class_init(ObjectClass *klass, void *data)
|
||||
ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass);
|
||||
ARMGICv3Class *agc = ARM_GICV3_CLASS(klass);
|
||||
|
||||
+ agc->parent_cpu_hotplug_realize = agcc->cpu_hotplug_realize;
|
||||
+ agcc->cpu_hotplug_realize = arm_gicv3_cpu_hotplug_realize;
|
||||
agcc->post_load = arm_gicv3_post_load;
|
||||
device_class_set_parent_realize(dc, arm_gic_realize, &agc->parent_realize);
|
||||
}
|
||||
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
|
||||
index 798f295d7c..8740a52c9f 100644
|
||||
--- a/hw/intc/arm_gicv3_common.c
|
||||
+++ b/hw/intc/arm_gicv3_common.c
|
||||
@@ -313,6 +313,11 @@ static void arm_gicv3_common_cpu_realize(GICv3State *s, int ncpu)
|
||||
gicv3_set_gicv3state(cpu, &s->cpu[ncpu]);
|
||||
}
|
||||
|
||||
+static void arm_gicv3_common_cpu_hotplug_realize(GICv3State *s, int ncpu)
|
||||
+{
|
||||
+ arm_gicv3_common_cpu_realize(s, ncpu);
|
||||
+}
|
||||
+
|
||||
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
GICv3State *s = ARM_GICV3_COMMON(dev);
|
||||
@@ -357,6 +362,7 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
CPUState *cpu = qemu_get_cpu(i);
|
||||
+
|
||||
uint64_t cpu_affid;
|
||||
int last;
|
||||
|
||||
@@ -508,12 +514,14 @@ static Property arm_gicv3_common_properties[] = {
|
||||
static void arm_gicv3_common_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
+ ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass);
|
||||
ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_CLASS(klass);
|
||||
|
||||
dc->reset = arm_gicv3_common_reset;
|
||||
dc->realize = arm_gicv3_common_realize;
|
||||
dc->props = arm_gicv3_common_properties;
|
||||
dc->vmsd = &vmstate_gicv3;
|
||||
+ agcc->cpu_hotplug_realize = arm_gicv3_common_cpu_hotplug_realize;
|
||||
albifc->arm_linux_init = arm_gic_common_linux_init;
|
||||
}
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
|
||||
index b2936938cb..f8d7be5479 100644
|
||||
--- a/hw/intc/arm_gicv3_kvm.c
|
||||
+++ b/hw/intc/arm_gicv3_kvm.c
|
||||
@@ -78,6 +78,7 @@ typedef struct KVMARMGICv3Class {
|
||||
ARMGICv3CommonClass parent_class;
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(DeviceState *dev);
|
||||
+ CPUHotplugRealize parent_cpu_hotplug_realize;
|
||||
} KVMARMGICv3Class;
|
||||
|
||||
static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level)
|
||||
@@ -768,6 +769,14 @@ static void kvm_arm_gicv3_cpu_realize(GICv3State *s, int ncpu)
|
||||
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||||
}
|
||||
|
||||
+static void kvm_arm_gicv3_cpu_hotplug_realize(GICv3State *s, int ncpu)
|
||||
+{
|
||||
+ KVMARMGICv3Class *kagcc = KVM_ARM_GICV3_GET_CLASS(s);
|
||||
+
|
||||
+ kagcc->parent_cpu_hotplug_realize(s, ncpu);
|
||||
+ kvm_arm_gicv3_cpu_realize(s, ncpu);
|
||||
+}
|
||||
+
|
||||
static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
GICv3State *s = KVM_ARM_GICV3(dev);
|
||||
@@ -884,6 +893,8 @@ static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)
|
||||
ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass);
|
||||
KVMARMGICv3Class *kgc = KVM_ARM_GICV3_CLASS(klass);
|
||||
|
||||
+ kgc->parent_cpu_hotplug_realize = agcc->cpu_hotplug_realize;
|
||||
+ agcc->cpu_hotplug_realize = kvm_arm_gicv3_cpu_hotplug_realize;
|
||||
agcc->pre_save = kvm_arm_gicv3_get;
|
||||
agcc->post_load = kvm_arm_gicv3_put;
|
||||
device_class_set_parent_realize(dc, kvm_arm_gicv3_realize,
|
||||
diff --git a/include/hw/intc/arm_gicv3.h b/include/hw/intc/arm_gicv3.h
|
||||
index 4a6fd85e22..98f2bdb7e9 100644
|
||||
--- a/include/hw/intc/arm_gicv3.h
|
||||
+++ b/include/hw/intc/arm_gicv3.h
|
||||
@@ -26,6 +26,8 @@ typedef struct ARMGICv3Class {
|
||||
ARMGICv3CommonClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
+ CPUHotplugRealize parent_cpu_hotplug_realize;
|
||||
+
|
||||
DeviceRealize parent_realize;
|
||||
} ARMGICv3Class;
|
||||
|
||||
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
|
||||
index 31ec9a1ae4..45cc50ed3b 100644
|
||||
--- a/include/hw/intc/arm_gicv3_common.h
|
||||
+++ b/include/hw/intc/arm_gicv3_common.h
|
||||
@@ -286,11 +286,15 @@ GICV3_BITMAP_ACCESSORS(edge_trigger)
|
||||
#define ARM_GICV3_COMMON_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ARMGICv3CommonClass, (obj), TYPE_ARM_GICV3_COMMON)
|
||||
|
||||
+typedef void (*CPUHotplugRealize)(GICv3State *s, int ncpu);
|
||||
+
|
||||
typedef struct ARMGICv3CommonClass {
|
||||
/*< private >*/
|
||||
SysBusDeviceClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
+ CPUHotplugRealize cpu_hotplug_realize;
|
||||
+
|
||||
void (*pre_save)(GICv3State *s);
|
||||
void (*post_load)(GICv3State *s);
|
||||
} ARMGICv3CommonClass;
|
||||
--
|
||||
2.19.1
|
||||
89
ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch
Normal file
89
ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From ed78352a59ea7acf7520d4d47a96b9911bae7fc3 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Popov <alex.popov@linux.com>
|
||||
Date: Mon, 23 Dec 2019 20:51:16 +0300
|
||||
Subject: [PATCH] ide: Fix incorrect handling of some PRDTs in ide_dma_cb()
|
||||
|
||||
The commit a718978ed58a from July 2015 introduced the assertion which
|
||||
implies that the size of successful DMA transfers handled in ide_dma_cb()
|
||||
should be multiple of 512 (the size of a sector). But guest systems can
|
||||
initiate DMA transfers that don't fit this requirement.
|
||||
|
||||
For fixing that let's check the number of bytes prepared for the transfer
|
||||
by the prepare_buf() handler. The code in ide_dma_cb() must behave
|
||||
according to the Programming Interface for Bus Master IDE Controller
|
||||
(Revision 1.0 5/16/94):
|
||||
1. If PRDs specified a smaller size than the IDE transfer
|
||||
size, then the Interrupt and Active bits in the Controller
|
||||
status register are not set (Error Condition).
|
||||
2. If the size of the physical memory regions was equal to
|
||||
the IDE device transfer size, the Interrupt bit in the
|
||||
Controller status register is set to 1, Active bit is set to 0.
|
||||
3. If PRDs specified a larger size than the IDE transfer size,
|
||||
the Interrupt and Active bits in the Controller status register
|
||||
are both set to 1.
|
||||
|
||||
Signed-off-by: Alexander Popov <alex.popov@linux.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-id: 20191223175117.508990-2-alex.popov@linux.com
|
||||
Signed-off-by: John Snow <jsnow@redhat.com>
|
||||
|
||||
diff --git a/hw/ide/core.c b/hw/ide/core.c
|
||||
index 754ff4dc34..80000eb766 100644
|
||||
--- a/hw/ide/core.c
|
||||
+++ b/hw/ide/core.c
|
||||
@@ -849,6 +849,7 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
int64_t sector_num;
|
||||
uint64_t offset;
|
||||
bool stay_active = false;
|
||||
+ int32_t prep_size = 0;
|
||||
|
||||
if (ret == -EINVAL) {
|
||||
ide_dma_error(s);
|
||||
@@ -863,13 +864,15 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
}
|
||||
}
|
||||
|
||||
- n = s->io_buffer_size >> 9;
|
||||
- if (n > s->nsector) {
|
||||
- /* The PRDs were longer than needed for this request. Shorten them so
|
||||
- * we don't get a negative remainder. The Active bit must remain set
|
||||
- * after the request completes. */
|
||||
+ if (s->io_buffer_size > s->nsector * 512) {
|
||||
+ /*
|
||||
+ * The PRDs were longer than needed for this request.
|
||||
+ * The Active bit must remain set after the request completes.
|
||||
+ */
|
||||
n = s->nsector;
|
||||
stay_active = true;
|
||||
+ } else {
|
||||
+ n = s->io_buffer_size >> 9;
|
||||
}
|
||||
|
||||
sector_num = ide_get_sector(s);
|
||||
@@ -892,9 +895,20 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
n = s->nsector;
|
||||
s->io_buffer_index = 0;
|
||||
s->io_buffer_size = n * 512;
|
||||
- if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size) < 512) {
|
||||
- /* The PRDs were too short. Reset the Active bit, but don't raise an
|
||||
- * interrupt. */
|
||||
+ prep_size = s->bus->dma->ops->prepare_buf(s->bus->dma, s->io_buffer_size);
|
||||
+ /* prepare_buf() must succeed and respect the limit */
|
||||
+ assert(prep_size >= 0 && prep_size <= n * 512);
|
||||
+
|
||||
+ /*
|
||||
+ * Now prep_size stores the number of bytes in the sglist, and
|
||||
+ * s->io_buffer_size stores the number of bytes described by the PRDs.
|
||||
+ */
|
||||
+
|
||||
+ if (prep_size < n * 512) {
|
||||
+ /*
|
||||
+ * The PRDs are too short for this request. Error condition!
|
||||
+ * Reset the Active bit and don't raise the interrupt.
|
||||
+ */
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
dma_buf_commit(s, 0);
|
||||
goto eot;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
357
intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch
Normal file
357
intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch
Normal file
@ -0,0 +1,357 @@
|
||||
From 0a75312c069d89be94bcaa688429d8f60a0c528b Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Fri, 10 Apr 2020 13:15:35 +0800
|
||||
Subject: [PATCH] intc/gicv3: Add pre-sizing capability to GICv3
|
||||
|
||||
Currently GICv3 supports fixed smp_cpus CPUs, and all CPUs are
|
||||
present always. Now we want to pre-sizing GICv3 to support max_cpus
|
||||
CPUs and not all of them are present always, so some sizing codes
|
||||
should be concerned.
|
||||
|
||||
GIC irqs, GICR and GICC are pre-created for all possible CPUs at
|
||||
start, but only smp_cpus CPUs are realize and irqs of smp_cpus CPUs
|
||||
are connected.
|
||||
|
||||
Other code changes are mainly for arm_gicv3, and we do little about
|
||||
kvm_arm_gicv3 becasue KVM will deal with the sizing information properly.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/arm/virt.c | 17 +++++++++++----
|
||||
hw/intc/arm_gicv3.c | 43 +++++++++++++++++++++++++-------------
|
||||
hw/intc/arm_gicv3_common.c | 23 ++++++++++++++++++--
|
||||
hw/intc/arm_gicv3_cpuif.c | 4 ++++
|
||||
hw/intc/arm_gicv3_kvm.c | 28 ++++++++++++++++++++++++-
|
||||
include/hw/arm/virt.h | 3 ++-
|
||||
6 files changed, 96 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 55d403bad6..dda22194b5 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -761,14 +761,19 @@ static void create_gic(VirtMachineState *vms)
|
||||
SysBusDevice *gicbusdev;
|
||||
const char *gictype;
|
||||
int type = vms->gic_version, i;
|
||||
+ /* The max number of CPUs suppored by GIC */
|
||||
+ unsigned int num_cpus = ms->smp.cpus;
|
||||
+ /* The number of CPUs present before boot */
|
||||
unsigned int smp_cpus = ms->smp.cpus;
|
||||
uint32_t nb_redist_regions = 0;
|
||||
|
||||
+ assert(num_cpus >= smp_cpus);
|
||||
+
|
||||
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
|
||||
|
||||
vms->gic = qdev_create(NULL, gictype);
|
||||
qdev_prop_set_uint32(vms->gic, "revision", type);
|
||||
- qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
|
||||
+ qdev_prop_set_uint32(vms->gic, "num-cpu", num_cpus);
|
||||
/* Note that the num-irq property counts both internal and external
|
||||
* interrupts; there are always 32 of the former (mandated by GIC spec).
|
||||
*/
|
||||
@@ -780,7 +785,7 @@ static void create_gic(VirtMachineState *vms)
|
||||
if (type == 3) {
|
||||
uint32_t redist0_capacity =
|
||||
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
|
||||
- uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
|
||||
+ uint32_t redist0_count = MIN(num_cpus, redist0_capacity);
|
||||
|
||||
nb_redist_regions = virt_gicv3_redist_region_count(vms);
|
||||
|
||||
@@ -793,7 +798,7 @@ static void create_gic(VirtMachineState *vms)
|
||||
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
|
||||
|
||||
qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
|
||||
- MIN(smp_cpus - redist0_count, redist1_capacity));
|
||||
+ MIN(num_cpus - redist0_count, redist1_capacity));
|
||||
}
|
||||
} else {
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
@@ -820,7 +825,11 @@ static void create_gic(VirtMachineState *vms)
|
||||
|
||||
/* Wire the outputs from each CPU's generic timer and the GICv3
|
||||
* maintenance interrupt signal to the appropriate GIC PPI inputs,
|
||||
- * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
|
||||
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's
|
||||
+ * inputs.
|
||||
+ *
|
||||
+ * The irqs of remaining CPUs (if we has) will be connected during
|
||||
+ * hotplugging.
|
||||
*/
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
connect_gic_cpu_irqs(vms, i);
|
||||
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
|
||||
index cacef26546..a60185113f 100644
|
||||
--- a/hw/intc/arm_gicv3.c
|
||||
+++ b/hw/intc/arm_gicv3.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/intc/arm_gicv3.h"
|
||||
+#include "qom/cpu.h"
|
||||
#include "gicv3_internal.h"
|
||||
|
||||
static bool irqbetter(GICv3CPUState *cs, int irq, uint8_t prio)
|
||||
@@ -206,7 +207,9 @@ static void gicv3_update_noirqset(GICv3State *s, int start, int len)
|
||||
assert(len > 0);
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- s->cpu[i].seenbetter = false;
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ s->cpu[i].seenbetter = false;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Find the highest priority pending interrupt in this range. */
|
||||
@@ -248,16 +251,18 @@ static void gicv3_update_noirqset(GICv3State *s, int start, int len)
|
||||
* now be the new best one).
|
||||
*/
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- GICv3CPUState *cs = &s->cpu[i];
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ GICv3CPUState *cs = &s->cpu[i];
|
||||
|
||||
- if (cs->seenbetter) {
|
||||
- cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
|
||||
- }
|
||||
+ if (cs->seenbetter) {
|
||||
+ cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
|
||||
+ }
|
||||
|
||||
- if (!cs->seenbetter && cs->hppi.prio != 0xff &&
|
||||
- cs->hppi.irq >= start && cs->hppi.irq < start + len) {
|
||||
- gicv3_full_update_noirqset(s);
|
||||
- break;
|
||||
+ if (!cs->seenbetter && cs->hppi.prio != 0xff &&
|
||||
+ cs->hppi.irq >= start && cs->hppi.irq < start + len) {
|
||||
+ gicv3_full_update_noirqset(s);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +273,9 @@ void gicv3_update(GICv3State *s, int start, int len)
|
||||
|
||||
gicv3_update_noirqset(s, start, len);
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- gicv3_cpuif_update(&s->cpu[i]);
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ gicv3_cpuif_update(&s->cpu[i]);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +287,9 @@ void gicv3_full_update_noirqset(GICv3State *s)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- s->cpu[i].hppi.prio = 0xff;
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ s->cpu[i].hppi.prio = 0xff;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Note that we can guarantee that these functions will not
|
||||
@@ -291,7 +300,9 @@ void gicv3_full_update_noirqset(GICv3State *s)
|
||||
gicv3_update_noirqset(s, GIC_INTERNAL, s->num_irq - GIC_INTERNAL);
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- gicv3_redist_update_noirqset(&s->cpu[i]);
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ gicv3_redist_update_noirqset(&s->cpu[i]);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +315,9 @@ void gicv3_full_update(GICv3State *s)
|
||||
|
||||
gicv3_full_update_noirqset(s);
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- gicv3_cpuif_update(&s->cpu[i]);
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ gicv3_cpuif_update(&s->cpu[i]);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +414,9 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- gicv3_cpu_realize(s, i);
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ gicv3_cpu_realize(s, i);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
|
||||
index 8740a52c9f..913bf068be 100644
|
||||
--- a/hw/intc/arm_gicv3_common.c
|
||||
+++ b/hw/intc/arm_gicv3_common.c
|
||||
@@ -24,10 +24,12 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
+#include "qemu/error-report.h"
|
||||
#include "qom/cpu.h"
|
||||
#include "hw/intc/arm_gicv3_common.h"
|
||||
#include "gicv3_internal.h"
|
||||
#include "hw/arm/linux-boot-if.h"
|
||||
+#include "hw/boards.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
||||
|
||||
@@ -363,10 +365,15 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
CPUState *cpu = qemu_get_cpu(i);
|
||||
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
+ const CPUArchIdList *possible_cpus = NULL;
|
||||
uint64_t cpu_affid;
|
||||
int last;
|
||||
|
||||
- arm_gicv3_common_cpu_realize(s, i);
|
||||
+ if (cpu) {
|
||||
+ arm_gicv3_common_cpu_realize(s, i);
|
||||
+ }
|
||||
|
||||
/* Pre-construct the GICR_TYPER:
|
||||
* For our implementation:
|
||||
@@ -380,7 +387,19 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
* VLPIS == 0 (virtual LPIs not supported)
|
||||
* PLPIS == 0 (physical LPIs not supported)
|
||||
*/
|
||||
- cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
|
||||
+ if (cpu) {
|
||||
+ cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
|
||||
+ } else {
|
||||
+ if (!mc->possible_cpu_arch_ids) {
|
||||
+ error_report("MachineClass must implement possible_cpu_arch_ids "
|
||||
+ "hook to support pre-sizing GICv3");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ possible_cpus = mc->possible_cpu_arch_ids(ms);
|
||||
+ cpu_affid = possible_cpus->cpus[i].arch_id;
|
||||
+ }
|
||||
+
|
||||
last = (i == s->num_cpu - 1);
|
||||
|
||||
/* The CPU mp-affinity property is in MPIDR register format; squash
|
||||
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
|
||||
index 56aa5efede..a20aa693ea 100644
|
||||
--- a/hw/intc/arm_gicv3_cpuif.c
|
||||
+++ b/hw/intc/arm_gicv3_cpuif.c
|
||||
@@ -1648,6 +1648,10 @@ static void icc_generate_sgi(CPUARMState *env, GICv3CPUState *cs,
|
||||
aff, targetlist);
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
+ if (!qemu_get_cpu(i)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
GICv3CPUState *ocs = &s->cpu[i];
|
||||
|
||||
if (irm) {
|
||||
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
|
||||
index f8d7be5479..8eea7c9dd9 100644
|
||||
--- a/hw/intc/arm_gicv3_kvm.c
|
||||
+++ b/hw/intc/arm_gicv3_kvm.c
|
||||
@@ -341,6 +341,10 @@ static void kvm_arm_gicv3_put(GICv3State *s)
|
||||
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
|
||||
GICv3CPUState *c = &s->cpu[ncpu];
|
||||
|
||||
+ if (!qemu_get_cpu(ncpu)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
reg64 = c->gicr_propbaser;
|
||||
regl = (uint32_t)reg64;
|
||||
kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, true);
|
||||
@@ -366,6 +370,10 @@ static void kvm_arm_gicv3_put(GICv3State *s)
|
||||
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
|
||||
GICv3CPUState *c = &s->cpu[ncpu];
|
||||
|
||||
+ if (!qemu_get_cpu(ncpu)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
reg = c->gicr_ctlr;
|
||||
kvm_gicr_access(s, GICR_CTLR, ncpu, ®, true);
|
||||
|
||||
@@ -462,6 +470,10 @@ static void kvm_arm_gicv3_put(GICv3State *s)
|
||||
GICv3CPUState *c = &s->cpu[ncpu];
|
||||
int num_pri_bits;
|
||||
|
||||
+ if (!qemu_get_cpu(ncpu)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
kvm_gicc_access(s, ICC_SRE_EL1, ncpu, &c->icc_sre_el1, true);
|
||||
kvm_gicc_access(s, ICC_CTLR_EL1, ncpu,
|
||||
&c->icc_ctlr_el1[GICV3_NS], true);
|
||||
@@ -525,6 +537,10 @@ static void kvm_arm_gicv3_get(GICv3State *s)
|
||||
/* Redistributor state (one per CPU) */
|
||||
|
||||
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
|
||||
+ if (!qemu_get_cpu(ncpu)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
GICv3CPUState *c = &s->cpu[ncpu];
|
||||
|
||||
kvm_gicr_access(s, GICR_CTLR, ncpu, ®, false);
|
||||
@@ -560,6 +576,10 @@ static void kvm_arm_gicv3_get(GICv3State *s)
|
||||
|
||||
if (redist_typer & GICR_TYPER_PLPIS) {
|
||||
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
|
||||
+ if (!qemu_get_cpu(ncpu)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
GICv3CPUState *c = &s->cpu[ncpu];
|
||||
|
||||
kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, false);
|
||||
@@ -613,6 +633,10 @@ static void kvm_arm_gicv3_get(GICv3State *s)
|
||||
*/
|
||||
|
||||
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
|
||||
+ if (!qemu_get_cpu(ncpu)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
GICv3CPUState *c = &s->cpu[ncpu];
|
||||
int num_pri_bits;
|
||||
|
||||
@@ -806,7 +830,9 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- kvm_arm_gicv3_cpu_realize(s, i);
|
||||
+ if (qemu_get_cpu(i)) {
|
||||
+ kvm_arm_gicv3_cpu_realize(s, i);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Try to create the device via the device control API */
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index 6880ebe07c..beef4c8002 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -168,8 +168,9 @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
|
||||
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
|
||||
|
||||
assert(vms->gic_version == 3);
|
||||
+ GICv3State *s = ARM_GICV3_COMMON(vms->gic);
|
||||
|
||||
- return vms->smp_cpus > redist0_capacity ? 2 : 1;
|
||||
+ return s->num_cpu > redist0_capacity ? 2 : 1;
|
||||
}
|
||||
|
||||
#endif /* QEMU_ARM_VIRT_H */
|
||||
--
|
||||
2.19.1
|
||||
50
intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch
Normal file
50
intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From a7391f391336024986a5997e3beae8882c983ed0 Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Fri, 10 Apr 2020 12:55:17 +0800
|
||||
Subject: [PATCH] intc/gicv3_common: Factor out arm_gicv3_common_cpu_realize
|
||||
|
||||
The CPU object of hotplugged CPU will be defer-created (during
|
||||
hotplug session), so we must factor out realization code to let
|
||||
it can be applied to individual CPU.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/intc/arm_gicv3_common.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
|
||||
index 5edabb928f..798f295d7c 100644
|
||||
--- a/hw/intc/arm_gicv3_common.c
|
||||
+++ b/hw/intc/arm_gicv3_common.c
|
||||
@@ -303,6 +303,16 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||
}
|
||||
}
|
||||
|
||||
+static void arm_gicv3_common_cpu_realize(GICv3State *s, int ncpu)
|
||||
+{
|
||||
+ CPUState *cpu = qemu_get_cpu(ncpu);
|
||||
+
|
||||
+ s->cpu[ncpu].cpu = cpu;
|
||||
+ s->cpu[ncpu].gic = s;
|
||||
+ /* Store GICv3CPUState in CPUARMState gicv3state pointer */
|
||||
+ gicv3_set_gicv3state(cpu, &s->cpu[ncpu]);
|
||||
+}
|
||||
+
|
||||
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
GICv3State *s = ARM_GICV3_COMMON(dev);
|
||||
@@ -350,10 +360,7 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
uint64_t cpu_affid;
|
||||
int last;
|
||||
|
||||
- s->cpu[i].cpu = cpu;
|
||||
- s->cpu[i].gic = s;
|
||||
- /* Store GICv3CPUState in CPUARMState gicv3state pointer */
|
||||
- gicv3_set_gicv3state(cpu, &s->cpu[i]);
|
||||
+ arm_gicv3_common_cpu_realize(s, i);
|
||||
|
||||
/* Pre-construct the GICR_TYPER:
|
||||
* For our implementation:
|
||||
--
|
||||
2.19.1
|
||||
197
intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch
Normal file
197
intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From de97ff4a01008ad98f7d69adc4b84843fff3ce19 Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Fri, 10 Apr 2020 10:59:55 +0800
|
||||
Subject: [PATCH] intc/gicv3_cpuif: Factor out gicv3_init_one_cpuif
|
||||
|
||||
The CPU object of hotplugged CPU will be defer-created (during
|
||||
hotplug session), so we must factor out some code to let it can
|
||||
be applied to individual CPU.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/intc/arm_gicv3.c | 5 +-
|
||||
hw/intc/arm_gicv3_cpuif.c | 122 ++++++++++++++++++--------------------
|
||||
hw/intc/gicv3_internal.h | 2 +-
|
||||
3 files changed, 64 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
|
||||
index 66eaa97198..2fe79f794d 100644
|
||||
--- a/hw/intc/arm_gicv3.c
|
||||
+++ b/hw/intc/arm_gicv3.c
|
||||
@@ -367,6 +367,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
GICv3State *s = ARM_GICV3(dev);
|
||||
ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s);
|
||||
Error *local_err = NULL;
|
||||
+ int i;
|
||||
|
||||
agc->parent_realize(dev, &local_err);
|
||||
if (local_err) {
|
||||
@@ -386,7 +387,9 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
- gicv3_init_cpuif(s);
|
||||
+ for (i = 0; i < s->num_cpu; i++) {
|
||||
+ gicv3_init_one_cpuif(s, i);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void arm_gicv3_class_init(ObjectClass *klass, void *data)
|
||||
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
|
||||
index 3b212d91c8..56aa5efede 100644
|
||||
--- a/hw/intc/arm_gicv3_cpuif.c
|
||||
+++ b/hw/intc/arm_gicv3_cpuif.c
|
||||
@@ -2597,78 +2597,74 @@ static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
|
||||
gicv3_cpuif_update(cs);
|
||||
}
|
||||
|
||||
-void gicv3_init_cpuif(GICv3State *s)
|
||||
+void gicv3_init_one_cpuif(GICv3State *s, int ncpu)
|
||||
{
|
||||
/* Called from the GICv3 realize function; register our system
|
||||
* registers with the CPU
|
||||
*/
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0; i < s->num_cpu; i++) {
|
||||
- ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
|
||||
- GICv3CPUState *cs = &s->cpu[i];
|
||||
-
|
||||
- /* Note that we can't just use the GICv3CPUState as an opaque pointer
|
||||
- * in define_arm_cp_regs_with_opaque(), because when we're called back
|
||||
- * it might be with code translated by CPU 0 but run by CPU 1, in
|
||||
- * which case we'd get the wrong value.
|
||||
- * So instead we define the regs with no ri->opaque info, and
|
||||
- * get back to the GICv3CPUState from the CPUARMState.
|
||||
- */
|
||||
- define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||||
- if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
|
||||
- && cpu->gic_num_lrs) {
|
||||
- int j;
|
||||
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(ncpu));
|
||||
+ GICv3CPUState *cs = &s->cpu[ncpu];
|
||||
+
|
||||
+ /* Note that we can't just use the GICv3CPUState as an opaque pointer
|
||||
+ * in define_arm_cp_regs_with_opaque(), because when we're called back
|
||||
+ * it might be with code translated by CPU 0 but run by CPU 1, in
|
||||
+ * which case we'd get the wrong value.
|
||||
+ * So instead we define the regs with no ri->opaque info, and
|
||||
+ * get back to the GICv3CPUState from the CPUARMState.
|
||||
+ */
|
||||
+ define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||||
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
|
||||
+ && cpu->gic_num_lrs) {
|
||||
+ int j;
|
||||
|
||||
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
|
||||
+ cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
|
||||
|
||||
- cs->num_list_regs = cpu->gic_num_lrs;
|
||||
- cs->vpribits = cpu->gic_vpribits;
|
||||
- cs->vprebits = cpu->gic_vprebits;
|
||||
+ cs->num_list_regs = cpu->gic_num_lrs;
|
||||
+ cs->vpribits = cpu->gic_vpribits;
|
||||
+ cs->vprebits = cpu->gic_vprebits;
|
||||
|
||||
- /* Check against architectural constraints: getting these
|
||||
- * wrong would be a bug in the CPU code defining these,
|
||||
- * and the implementation relies on them holding.
|
||||
- */
|
||||
- g_assert(cs->vprebits <= cs->vpribits);
|
||||
- g_assert(cs->vprebits >= 5 && cs->vprebits <= 7);
|
||||
- g_assert(cs->vpribits >= 5 && cs->vpribits <= 8);
|
||||
+ /* Check against architectural constraints: getting these
|
||||
+ * wrong would be a bug in the CPU code defining these,
|
||||
+ * and the implementation relies on them holding.
|
||||
+ */
|
||||
+ g_assert(cs->vprebits <= cs->vpribits);
|
||||
+ g_assert(cs->vprebits >= 5 && cs->vprebits <= 7);
|
||||
+ g_assert(cs->vpribits >= 5 && cs->vpribits <= 8);
|
||||
|
||||
- define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo);
|
||||
+ define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo);
|
||||
|
||||
- for (j = 0; j < cs->num_list_regs; j++) {
|
||||
- /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs
|
||||
- * are split into two cp15 regs, LR (the low part, with the
|
||||
- * same encoding as the AArch64 LR) and LRC (the high part).
|
||||
- */
|
||||
- ARMCPRegInfo lr_regset[] = {
|
||||
- { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH,
|
||||
- .opc0 = 3, .opc1 = 4, .crn = 12,
|
||||
- .crm = 12 + (j >> 3), .opc2 = j & 7,
|
||||
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
- .access = PL2_RW,
|
||||
- .readfn = ich_lr_read,
|
||||
- .writefn = ich_lr_write,
|
||||
- },
|
||||
- { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32,
|
||||
- .cp = 15, .opc1 = 4, .crn = 12,
|
||||
- .crm = 14 + (j >> 3), .opc2 = j & 7,
|
||||
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
- .access = PL2_RW,
|
||||
- .readfn = ich_lr_read,
|
||||
- .writefn = ich_lr_write,
|
||||
- },
|
||||
- REGINFO_SENTINEL
|
||||
- };
|
||||
- define_arm_cp_regs(cpu, lr_regset);
|
||||
- }
|
||||
- if (cs->vprebits >= 6) {
|
||||
- define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo);
|
||||
- }
|
||||
- if (cs->vprebits == 7) {
|
||||
- define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
|
||||
- }
|
||||
+ for (j = 0; j < cs->num_list_regs; j++) {
|
||||
+ /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs
|
||||
+ * are split into two cp15 regs, LR (the low part, with the
|
||||
+ * same encoding as the AArch64 LR) and LRC (the high part).
|
||||
+ */
|
||||
+ ARMCPRegInfo lr_regset[] = {
|
||||
+ { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH,
|
||||
+ .opc0 = 3, .opc1 = 4, .crn = 12,
|
||||
+ .crm = 12 + (j >> 3), .opc2 = j & 7,
|
||||
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
+ .access = PL2_RW,
|
||||
+ .readfn = ich_lr_read,
|
||||
+ .writefn = ich_lr_write,
|
||||
+ },
|
||||
+ { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32,
|
||||
+ .cp = 15, .opc1 = 4, .crn = 12,
|
||||
+ .crm = 14 + (j >> 3), .opc2 = j & 7,
|
||||
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||||
+ .access = PL2_RW,
|
||||
+ .readfn = ich_lr_read,
|
||||
+ .writefn = ich_lr_write,
|
||||
+ },
|
||||
+ REGINFO_SENTINEL
|
||||
+ };
|
||||
+ define_arm_cp_regs(cpu, lr_regset);
|
||||
+ }
|
||||
+ if (cs->vprebits >= 6) {
|
||||
+ define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo);
|
||||
+ }
|
||||
+ if (cs->vprebits == 7) {
|
||||
+ define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
|
||||
}
|
||||
- arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
|
||||
}
|
||||
+ arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
|
||||
}
|
||||
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
|
||||
index 05303a55c8..cfbfe8a549 100644
|
||||
--- a/hw/intc/gicv3_internal.h
|
||||
+++ b/hw/intc/gicv3_internal.h
|
||||
@@ -297,7 +297,7 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
|
||||
void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
|
||||
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
|
||||
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
|
||||
-void gicv3_init_cpuif(GICv3State *s);
|
||||
+void gicv3_init_one_cpuif(GICv3State *s, int ncpu);
|
||||
|
||||
/**
|
||||
* gicv3_cpuif_update:
|
||||
--
|
||||
2.19.1
|
||||
45
intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch
Normal file
45
intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From f45964c7e0df4ef17457a9ea92bfd255064139e1 Mon Sep 17 00:00:00 2001
|
||||
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Date: Fri, 10 Apr 2020 12:49:12 +0800
|
||||
Subject: [PATCH] intc/kvm_gicv3: Factor out kvm_arm_gicv3_cpu_realize
|
||||
|
||||
The CPU object of hotplugged CPU will be defer-created (during
|
||||
hotplug session), so we must factor out realization code to let
|
||||
it can be applied to individual CPU.
|
||||
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
---
|
||||
hw/intc/arm_gicv3_kvm.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
|
||||
index b1e74147ba..b2936938cb 100644
|
||||
--- a/hw/intc/arm_gicv3_kvm.c
|
||||
+++ b/hw/intc/arm_gicv3_kvm.c
|
||||
@@ -761,6 +761,12 @@ static void vm_change_state_handler(void *opaque, int running,
|
||||
}
|
||||
}
|
||||
|
||||
+static void kvm_arm_gicv3_cpu_realize(GICv3State *s, int ncpu)
|
||||
+{
|
||||
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(ncpu));
|
||||
+
|
||||
+ define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||||
+}
|
||||
|
||||
static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
@@ -791,9 +797,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
- ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
|
||||
-
|
||||
- define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||||
+ kvm_arm_gicv3_cpu_realize(s, i);
|
||||
}
|
||||
|
||||
/* Try to create the device via the device control API */
|
||||
--
|
||||
2.19.1
|
||||
40
ip_reass-Fix-use-after-free.patch
Normal file
40
ip_reass-Fix-use-after-free.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 63b07dfe20a0d4971b0929d27359f478ba2d816b Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
Date: Fri, 22 May 2020 10:52:55 +0800
|
||||
Subject: [PATCH] ip_reass: Fix use after free
|
||||
|
||||
Using ip_deq after m_free might read pointers from an allocation reuse.
|
||||
|
||||
This would be difficult to exploit, but that is still related with
|
||||
CVE-2019-14378 which generates fragmented IP packets that would trigger this
|
||||
issue and at least produce a DoS.
|
||||
Signed-off-by: Samuel Thibault's avatarSamuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
|
||||
diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c
|
||||
index 8c75d91..c07d7d4 100644
|
||||
--- a/slirp/src/ip_input.c
|
||||
+++ b/slirp/src/ip_input.c
|
||||
@@ -292,6 +292,7 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
|
||||
*/
|
||||
while (q != (struct ipasfrag *)&fp->frag_link &&
|
||||
ip->ip_off + ip->ip_len > q->ipf_off) {
|
||||
+ struct ipasfrag *prev;
|
||||
i = (ip->ip_off + ip->ip_len) - q->ipf_off;
|
||||
if (i < q->ipf_len) {
|
||||
q->ipf_len -= i;
|
||||
@@ -299,9 +300,10 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
|
||||
m_adj(dtom(slirp, q), i);
|
||||
break;
|
||||
}
|
||||
+ prev = q;
|
||||
q = q->ipf_next;
|
||||
- m_free(dtom(slirp, q->ipf_prev));
|
||||
- ip_deq(q->ipf_prev);
|
||||
+ ip_deq(prev);
|
||||
+ m_free(dtom(slirp, prev));
|
||||
}
|
||||
|
||||
insert:
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
42
libvhost-user-fix-SLAVE_SEND_FD-handling.patch
Normal file
42
libvhost-user-fix-SLAVE_SEND_FD-handling.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 28a9a3558a427493049723fff390add7026653eb Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Tue, 3 Sep 2019 23:04:22 +0300
|
||||
Subject: [PATCH] libvhost-user: fix SLAVE_SEND_FD handling
|
||||
|
||||
It doesn't look like this could possibly work properly since
|
||||
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD is defined to 10, but the
|
||||
dev->protocol_features has a bitmap. I suppose the peer this
|
||||
was tested with also supported VHOST_USER_PROTOCOL_F_LOG_SHMFD,
|
||||
in which case the test would always be false, but nevertheless
|
||||
the code seems wrong.
|
||||
|
||||
Use has_feature() to fix this.
|
||||
|
||||
Fixes: d84599f56c82 ("libvhost-user: support host notifier")
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Message-Id: <20190903200422.11693-1-johannes@sipsolutions.net>
|
||||
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry picked from commit 8726b70b449896f1211f869ec4f608904f027207)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
contrib/libvhost-user/libvhost-user.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
|
||||
index 4b36e35a82..cb5f5770e4 100644
|
||||
--- a/contrib/libvhost-user/libvhost-user.c
|
||||
+++ b/contrib/libvhost-user/libvhost-user.c
|
||||
@@ -1097,7 +1097,8 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
|
||||
|
||||
vmsg.fd_num = fd_num;
|
||||
|
||||
- if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
|
||||
+ if (!has_feature(dev->protocol_features,
|
||||
+ VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
@ -1,7 +1,7 @@
|
||||
From 896b9892d4df316b85836daa973e442c0c64cec6 Mon Sep 17 00:00:00 2001
|
||||
From 27a9f40b308efd8ddcb81e286441865b5a0cb541 Mon Sep 17 00:00:00 2001
|
||||
From: Zenghui Yu <yuzenghui@huawei.com>
|
||||
Date: Fri, 3 Jan 2020 17:16:55 +0800
|
||||
Subject: [PATCH 1/3] linux headers: update against "KVM/ARM: Fix >256 vcpus"
|
||||
Date: Tue, 14 Apr 2020 21:52:42 +0800
|
||||
Subject: [PATCH] linux headers: update against "KVM/ARM: Fix >256 vcpus"
|
||||
|
||||
This is part of upstream commit f363d039e883 ("linux headers: update
|
||||
against v5.4-rc1"), authored by Eric Auger <eric.auger@redhat.com>.
|
||||
@ -30,10 +30,10 @@ index e1f8b745..137a2730 100644
|
||||
#define KVM_ARM_IRQ_VCPU_MASK 0xff
|
||||
#define KVM_ARM_IRQ_NUM_SHIFT 0
|
||||
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
|
||||
index e6a98c14..dfd3a028 100644
|
||||
index 2431ec35..cdfd5f33 100644
|
||||
--- a/linux-headers/asm-arm64/kvm.h
|
||||
+++ b/linux-headers/asm-arm64/kvm.h
|
||||
@@ -265,8 +265,10 @@ struct kvm_vcpu_events {
|
||||
@@ -308,8 +308,10 @@ struct kvm_vcpu_events {
|
||||
#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
|
||||
|
||||
/* KVM_IRQ_LINE irq field index values */
|
||||
@ -46,17 +46,16 @@ index e6a98c14..dfd3a028 100644
|
||||
#define KVM_ARM_IRQ_VCPU_MASK 0xff
|
||||
#define KVM_ARM_IRQ_NUM_SHIFT 0
|
||||
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||
index b53ee597..086cea4d 100644
|
||||
index c8423e76..744e888e 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -988,6 +988,7 @@ struct kvm_ppc_resize_hpt {
|
||||
#define KVM_CAP_ARM_VM_IPA_SIZE 165
|
||||
#define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166
|
||||
#define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166 /* Obsolete */
|
||||
#define KVM_CAP_HYPERV_CPUID 167
|
||||
+#define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
#define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 168
|
||||
#define KVM_CAP_PPC_IRQ_XIVE 169
|
||||
#define KVM_CAP_ARM_SVE 170
|
||||
--
|
||||
2.19.1
|
||||
|
||||
2.23.0
|
||||
|
||||
181
log-Add-some-logs-on-VM-runtime-path.patch
Normal file
181
log-Add-some-logs-on-VM-runtime-path.patch
Normal file
@ -0,0 +1,181 @@
|
||||
From 0c83403e6e3ab21a01941be4ec57b02388eeb9c4 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Fri, 22 May 2020 18:56:09 +0800
|
||||
Subject: [PATCH] log: Add some logs on VM runtime path
|
||||
|
||||
Add logs on VM runtime path, to make it easier to do trouble shooting.
|
||||
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
|
||||
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
|
||||
index f6d2223..b4b0ed2 100644
|
||||
--- a/hw/virtio/virtio-pci.c
|
||||
+++ b/hw/virtio/virtio-pci.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "qemu/range.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "qapi/visitor.h"
|
||||
+#include "qemu/log.h"
|
||||
|
||||
#define VIRTIO_PCI_REGION_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_present(dev))
|
||||
|
||||
@@ -1659,7 +1660,9 @@ static void virtio_pci_device_unplugged(DeviceState *d)
|
||||
VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
|
||||
bool modern = virtio_pci_modern(proxy);
|
||||
bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
|
||||
+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||
|
||||
+ qemu_log("unplug device name: %s\n", !vdev ? "NULL" : vdev->name);
|
||||
virtio_pci_stop_ioeventfd(proxy);
|
||||
|
||||
if (modern) {
|
||||
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
||||
index 7c3822c..79c2dcf 100644
|
||||
--- a/hw/virtio/virtio.c
|
||||
+++ b/hw/virtio/virtio.c
|
||||
@@ -1172,7 +1172,14 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val)
|
||||
k->set_status(vdev, val);
|
||||
}
|
||||
vdev->status = val;
|
||||
-
|
||||
+ if (val) {
|
||||
+ qemu_log("%s device status is %d that means %s\n",
|
||||
+ vdev->name, val,
|
||||
+ (val & VIRTIO_CONFIG_S_DRIVER_OK) ? "DRIVER OK" :
|
||||
+ (val & VIRTIO_CONFIG_S_DRIVER) ? "DRIVER" :
|
||||
+ (val & VIRTIO_CONFIG_S_ACKNOWLEDGE) ? "ACKNOWLEDGE" :
|
||||
+ (val & VIRTIO_CONFIG_S_FAILED) ? "FAILED" : "UNKNOWN");
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1614,8 +1621,11 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE)
|
||||
+ if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) {
|
||||
+ qemu_log("unacceptable queue_size (%d) or num (%d)\n",
|
||||
+ queue_size, i);
|
||||
abort();
|
||||
+ }
|
||||
|
||||
vdev->vq[i].vring.num = queue_size;
|
||||
vdev->vq[i].vring.num_default = queue_size;
|
||||
diff --git a/monitor/monitor.c b/monitor/monitor.c
|
||||
index 3ef2817..6f726e8 100644
|
||||
--- a/monitor/monitor.c
|
||||
+++ b/monitor/monitor.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "qapi/qapi-emit-events.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
+#include "qapi/qmp/qjson.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/option.h"
|
||||
#include "sysemu/qtest.h"
|
||||
@@ -254,6 +255,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
|
||||
{
|
||||
Monitor *mon;
|
||||
MonitorQMP *qmp_mon;
|
||||
+ QString *json;
|
||||
|
||||
trace_monitor_protocol_event_emit(event, qdict);
|
||||
QTAILQ_FOREACH(mon, &mon_list, entry) {
|
||||
@@ -264,6 +266,13 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
|
||||
qmp_mon = container_of(mon, MonitorQMP, common);
|
||||
if (qmp_mon->commands != &qmp_cap_negotiation_commands) {
|
||||
qmp_send_response(qmp_mon, qdict);
|
||||
+ json = qobject_to_json(QOBJECT(qdict));
|
||||
+ if (json) {
|
||||
+ if (!strstr(json->string, "RTC_CHANGE")) {
|
||||
+ qemu_log("%s\n", qstring_get_str(json));
|
||||
+ }
|
||||
+ qobject_unref(json);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
|
||||
index e2c366e..6dfdad5 100644
|
||||
--- a/qapi/qmp-dispatch.c
|
||||
+++ b/qapi/qmp-dispatch.c
|
||||
@@ -17,7 +17,9 @@
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "qapi/qmp/qbool.h"
|
||||
+#include "qapi/qmp/qstring.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
+#include "qemu/log.h"
|
||||
|
||||
static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
|
||||
Error **errp)
|
||||
@@ -83,6 +85,7 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
|
||||
const char *command;
|
||||
QDict *args, *dict;
|
||||
QmpCommand *cmd;
|
||||
+ QString *json;
|
||||
QObject *ret = NULL;
|
||||
|
||||
dict = qmp_dispatch_check_obj(request, allow_oob, errp);
|
||||
@@ -128,6 +131,19 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
|
||||
qobject_ref(args);
|
||||
}
|
||||
|
||||
+ json = qobject_to_json(QOBJECT(args));
|
||||
+ if (json) {
|
||||
+ if ((strcmp(command, "query-block-jobs") != 0)
|
||||
+ && (strcmp(command, "query-migrate") != 0)
|
||||
+ && (strcmp(command, "query-blockstats") != 0)
|
||||
+ && (strcmp(command, "query-balloon") != 0)
|
||||
+ && (strcmp(command, "set_password") != 0)) {
|
||||
+ qemu_log("qmp_cmd_name: %s, arguments: %s\n",
|
||||
+ command, qstring_get_str(json));
|
||||
+ }
|
||||
+ qobject_unref(json);
|
||||
+ }
|
||||
+
|
||||
cmd->fn(args, &ret, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
diff --git a/qdev-monitor.c b/qdev-monitor.c
|
||||
index 58222c2..c6c1d3f 100644
|
||||
--- a/qdev-monitor.c
|
||||
+++ b/qdev-monitor.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "migration/misc.h"
|
||||
+#include "qemu/log.h"
|
||||
|
||||
/*
|
||||
* Aliases were a bad idea from the start. Let's keep them
|
||||
@@ -586,6 +587,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
||||
if (path != NULL) {
|
||||
bus = qbus_find(path, errp);
|
||||
if (!bus) {
|
||||
+ error_setg(errp, "can not find bus for %s", driver);
|
||||
return NULL;
|
||||
}
|
||||
if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) {
|
||||
@@ -627,6 +629,8 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
||||
|
||||
/* set properties */
|
||||
if (qemu_opt_foreach(opts, set_property, dev, &err)) {
|
||||
+ error_setg(errp, "the bus %s -driver %s set property failed",
|
||||
+ bus ? bus->name : "None", driver);
|
||||
goto err_del_dev;
|
||||
}
|
||||
|
||||
@@ -636,6 +640,8 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
|
||||
dev->opts = NULL;
|
||||
goto err_del_dev;
|
||||
}
|
||||
+ qemu_log("add qdev %s:%s success\n", driver,
|
||||
+ qemu_opts_id(opts) ? qemu_opts_id(opts) : "none");
|
||||
return dev;
|
||||
|
||||
err_del_dev:
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
60
make-release-pull-in-edk2-submodules-so-we-can-build.patch
Normal file
60
make-release-pull-in-edk2-submodules-so-we-can-build.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From c5c9b1362d1652a9d0f79f6d9ae2f80d4b5fe432 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
Date: Thu, 12 Sep 2019 18:12:01 -0500
|
||||
Subject: [PATCH] make-release: pull in edk2 submodules so we can build it from
|
||||
tarballs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The `make efi` target added by 536d2173 is built from the roms/edk2
|
||||
submodule, which in turn relies on additional submodules nested under
|
||||
roms/edk2.
|
||||
|
||||
The make-release script currently only pulls in top-level submodules,
|
||||
so these nested submodules are missing in the resulting tarball.
|
||||
|
||||
We could try to address this situation more generally by recursively
|
||||
pulling in all submodules, but this doesn't necessarily ensure the
|
||||
end-result will build properly (this case also required other changes).
|
||||
|
||||
Additionally, due to the nature of submodules, we may not always have
|
||||
control over how these sorts of things are dealt with, so for now we
|
||||
continue to handle it on a case-by-case in the make-release script.
|
||||
|
||||
Cc: Laszlo Ersek <lersek@redhat.com>
|
||||
Cc: Bruce Rogers <brogers@suse.com>
|
||||
Cc: qemu-stable@nongnu.org # v4.1.0
|
||||
Reported-by: Bruce Rogers <brogers@suse.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
Message-Id: <20190912231202.12327-2-mdroth@linux.vnet.ibm.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
(cherry picked from commit 45c61c6c23918e3b05ed9ecac5b2328ebae5f774)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
scripts/make-release | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/scripts/make-release b/scripts/make-release
|
||||
index b4af9c9e52..a2a8cda33c 100755
|
||||
--- a/scripts/make-release
|
||||
+++ b/scripts/make-release
|
||||
@@ -20,6 +20,14 @@ git checkout "v${version}"
|
||||
git submodule update --init
|
||||
(cd roms/seabios && git describe --tags --long --dirty > .version)
|
||||
(cd roms/skiboot && ./make_version.sh > .version)
|
||||
+# Fetch edk2 submodule's submodules, since it won't have access to them via
|
||||
+# the tarball later.
|
||||
+#
|
||||
+# A more uniform way to handle this sort of situation would be nice, but we
|
||||
+# don't necessarily have much control over how a submodule handles its
|
||||
+# submodule dependencies, so we continue to handle these on a case-by-case
|
||||
+# basis for now.
|
||||
+(cd roms/edk2 && git submodule update --init)
|
||||
popd
|
||||
tar --exclude=.git -cjf ${destination}.tar.bz2 ${destination}
|
||||
rm -rf ${destination}
|
||||
--
|
||||
2.23.0
|
||||
@ -1,85 +0,0 @@
|
||||
From b9f43f0cca03586a31b53e47ade72e77db01cb4c Mon Sep 17 00:00:00 2001
|
||||
From: King Wang <king.wang@huawei.com>
|
||||
Date: Fri, 12 Jul 2019 14:52:41 +0800
|
||||
Subject: [PATCH 2/5] memory: unref the memory region in simplify flatview
|
||||
|
||||
The memory region reference is increased when insert a range
|
||||
into flatview range array, then decreased by destroy flatview.
|
||||
If some flat range merged by flatview_simplify, the memory region
|
||||
reference can not be decreased by destroy flatview any more.
|
||||
|
||||
In this case, start virtual machine by the command line:
|
||||
qemu-system-x86_64
|
||||
-name guest=ubuntu,debug-threads=on
|
||||
-machine pc,accel=kvm,usb=off,dump-guest-core=off
|
||||
-cpu host
|
||||
-m 16384
|
||||
-realtime mlock=off
|
||||
-smp 8,sockets=2,cores=4,threads=1
|
||||
-object memory-backend-file,id=ram-node0,prealloc=yes,mem-path=/dev/hugepages,share=yes,size=8589934592
|
||||
-numa node,nodeid=0,cpus=0-3,memdev=ram-node0
|
||||
-object memory-backend-file,id=ram-node1,prealloc=yes,mem-path=/dev/hugepages,share=yes,size=8589934592
|
||||
-numa node,nodeid=1,cpus=4-7,memdev=ram-node1
|
||||
-no-user-config
|
||||
-nodefaults
|
||||
-rtc base=utc
|
||||
-no-shutdown
|
||||
-boot strict=on
|
||||
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2
|
||||
-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x2
|
||||
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3
|
||||
-drive file=ubuntu.qcow2,format=qcow2,if=none,id=drive-virtio-disk0,cache=none,aio=native
|
||||
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
|
||||
-chardev pty,id=charserial0
|
||||
-device isa-serial,chardev=charserial0,id=serial0
|
||||
-device usb-tablet,id=input0,bus=usb.0,port=1
|
||||
-vnc 0.0.0.0:0
|
||||
-device VGA,id=video0,vgamem_mb=16,bus=pci.0,addr=0x5
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
|
||||
-msg timestamp=on
|
||||
|
||||
And run the script in guest OS:
|
||||
while true
|
||||
do
|
||||
setpci -s 00:06.0 04.b=03
|
||||
setpci -s 00:06.0 04.b=07
|
||||
done
|
||||
|
||||
I found the reference of node0 HostMemoryBackendFile is a big one.
|
||||
(gdb) p numa_info[0]->node_memdev->parent.ref
|
||||
$6 = 1636278
|
||||
(gdb)
|
||||
|
||||
Signed-off-by: King Wang<king.wang@huawei.com>
|
||||
Message-Id: <20190712065241.11784-1-king.wang@huawei.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
memory.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/memory.c b/memory.c
|
||||
index 9fbca52..0b49281 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -320,7 +320,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
|
||||
/* Attempt to simplify a view by merging adjacent ranges */
|
||||
static void flatview_simplify(FlatView *view)
|
||||
{
|
||||
- unsigned i, j;
|
||||
+ unsigned i, j, k;
|
||||
|
||||
i = 0;
|
||||
while (i < view->nr) {
|
||||
@@ -331,6 +331,9 @@ static void flatview_simplify(FlatView *view)
|
||||
++j;
|
||||
}
|
||||
++i;
|
||||
+ for (k = i; k < j; k++) {
|
||||
+ memory_region_unref(view->ranges[k].mr);
|
||||
+ }
|
||||
memmove(&view->ranges[i], &view->ranges[j],
|
||||
(view->nr - j) * sizeof(view->ranges[j]));
|
||||
view->nr -= j - i;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
80
migration-Compat-virtual-timer-adjust-for-v4.0.1-and.patch
Normal file
80
migration-Compat-virtual-timer-adjust-for-v4.0.1-and.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From 79d722679731233ccb1aa775d896a4bf21e13d44 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Fang <fangying1@huawei.com>
|
||||
Date: Wed, 27 May 2020 10:02:06 +0800
|
||||
Subject: [PATCH] migration: Compat virtual timer adjust for v4.0.1 and v4.1.0
|
||||
|
||||
Vtimer adjust is used in openEuler qemu-4.0.1, however kvm_adjvtime
|
||||
is introduced in openEuler qemu-4.1.0. To maintain the compatibility
|
||||
and enable cross version migration, let's enable vtimer adjust only
|
||||
if kvm_adjvtime is not enabled, otherwise there may be conflicts
|
||||
between vtimer adjust and kvm_adjvtime.
|
||||
|
||||
After this modification:
|
||||
1: openEuler qemu-4.0.1 use vtimer as the default virtual timer
|
||||
2: openEuler qemu-4.1.0 use kvm_adjvtime as the defaut virtual timer
|
||||
|
||||
Migration from openEuler qemu-4.0.1 to openEuler qemu-4.1.0 will
|
||||
be ok, but migration path from upstream qemu-4.0.1 to openEuler
|
||||
qemu-4..0.1 will be broken.
|
||||
|
||||
Since openEuler qemu-4.1.0, kvm_adjvtime is used as the default
|
||||
virtual timer. So please upgrade to openEuler qemu-4.1.0 and
|
||||
use the virt-4.1 machine.
|
||||
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
|
||||
diff --git a/cpus.c b/cpus.c
|
||||
index b9aa51f8..6a28bdef 100644
|
||||
--- a/cpus.c
|
||||
+++ b/cpus.c
|
||||
@@ -1067,6 +1067,12 @@ void cpu_synchronize_all_pre_loadvm(void)
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
+static bool kvm_adjvtime_enabled(CPUState *cs)
|
||||
+{
|
||||
+ ARMCPU *cpu = ARM_CPU(cs);
|
||||
+ return cpu->kvm_adjvtime == true;
|
||||
+}
|
||||
+
|
||||
static void get_vcpu_timer_tick(CPUState *cs)
|
||||
{
|
||||
CPUARMState *env = &ARM_CPU(cs)->env;
|
||||
@@ -1096,7 +1102,13 @@ static int do_vm_stop(RunState state, bool send_stop)
|
||||
cpu_disable_ticks();
|
||||
pause_all_vcpus();
|
||||
#ifdef __aarch64__
|
||||
- if (first_cpu) {
|
||||
+ /* vtimer adjust is used in openEuler qemu-4.0.1, however kvm_adjvtime
|
||||
+ * is introduced in openEuler qemu-4.1.0. To maintain the compatibility
|
||||
+ * and enable cross version migration, let's enable vtimer adjust only
|
||||
+ * if kvm_adjvtime is not enabled, otherwise there may be conflicts
|
||||
+ * between vtimer adjust and kvm_adjvtime.
|
||||
+ */
|
||||
+ if (first_cpu && !kvm_adjvtime_enabled(first_cpu)) {
|
||||
get_vcpu_timer_tick(first_cpu);
|
||||
}
|
||||
#endif
|
||||
@@ -1946,6 +1958,7 @@ void cpu_resume(CPUState *cpu)
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
+
|
||||
static void set_vcpu_timer_tick(CPUState *cs)
|
||||
{
|
||||
CPUARMState *env = &ARM_CPU(cs)->env;
|
||||
@@ -1977,7 +1990,10 @@ void resume_all_vcpus(void)
|
||||
|
||||
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
|
||||
#ifdef __aarch64__
|
||||
- if (first_cpu) {
|
||||
+ /* Enable vtimer adjust only if kvm_adjvtime is not enabled, otherwise
|
||||
+ * there may be conflicts between vtimer adjust and kvm_adjvtime.
|
||||
+ */
|
||||
+ if (first_cpu && !kvm_adjvtime_enabled(first_cpu)) {
|
||||
set_vcpu_timer_tick(first_cpu);
|
||||
}
|
||||
#endif
|
||||
--
|
||||
2.23.0
|
||||
|
||||
100
migration-Make-global-sem_sync-semaphore-by-channel.patch
Normal file
100
migration-Make-global-sem_sync-semaphore-by-channel.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From 8c3794d709eefdae777477bef7ff3511d55bf418 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Quintela <quintela@redhat.com>
|
||||
Date: Wed, 14 Aug 2019 04:02:14 +0200
|
||||
Subject: [PATCH 05/10] migration: Make global sem_sync semaphore by channel
|
||||
|
||||
This makes easy to debug things because when you want for all threads
|
||||
to arrive at that semaphore, you know which one your are waiting for.
|
||||
|
||||
Change-Id: I533af8cdc68f619b68eff8e4e573c4de371a3954
|
||||
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
||||
Message-Id: <20190814020218.1868-3-quintela@redhat.com>
|
||||
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
---
|
||||
migration/ram.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index c75716bb..51811c2d 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -661,6 +661,8 @@ typedef struct {
|
||||
uint64_t num_packets;
|
||||
/* pages sent through this channel */
|
||||
uint64_t num_pages;
|
||||
+ /* syncs main thread and channels */
|
||||
+ QemuSemaphore sem_sync;
|
||||
} MultiFDSendParams;
|
||||
|
||||
typedef struct {
|
||||
@@ -896,8 +898,6 @@ struct {
|
||||
MultiFDSendParams *params;
|
||||
/* array of pages to sent */
|
||||
MultiFDPages_t *pages;
|
||||
- /* syncs main thread and channels */
|
||||
- QemuSemaphore sem_sync;
|
||||
/* global number of generated multifd packets */
|
||||
uint64_t packet_num;
|
||||
/* send channels ready */
|
||||
@@ -1037,6 +1037,7 @@ void multifd_save_cleanup(void)
|
||||
p->c = NULL;
|
||||
qemu_mutex_destroy(&p->mutex);
|
||||
qemu_sem_destroy(&p->sem);
|
||||
+ qemu_sem_destroy(&p->sem_sync);
|
||||
g_free(p->name);
|
||||
p->name = NULL;
|
||||
multifd_pages_clear(p->pages);
|
||||
@@ -1046,7 +1047,6 @@ void multifd_save_cleanup(void)
|
||||
p->packet = NULL;
|
||||
}
|
||||
qemu_sem_destroy(&multifd_send_state->channels_ready);
|
||||
- qemu_sem_destroy(&multifd_send_state->sem_sync);
|
||||
g_free(multifd_send_state->params);
|
||||
multifd_send_state->params = NULL;
|
||||
multifd_pages_clear(multifd_send_state->pages);
|
||||
@@ -1096,7 +1096,7 @@ static void multifd_send_sync_main(RAMState *rs)
|
||||
MultiFDSendParams *p = &multifd_send_state->params[i];
|
||||
|
||||
trace_multifd_send_sync_main_wait(p->id);
|
||||
- qemu_sem_wait(&multifd_send_state->sem_sync);
|
||||
+ qemu_sem_wait(&p->sem_sync);
|
||||
}
|
||||
trace_multifd_send_sync_main(multifd_send_state->packet_num);
|
||||
}
|
||||
@@ -1156,7 +1156,7 @@ static void *multifd_send_thread(void *opaque)
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
|
||||
if (flags & MULTIFD_FLAG_SYNC) {
|
||||
- qemu_sem_post(&multifd_send_state->sem_sync);
|
||||
+ qemu_sem_post(&p->sem_sync);
|
||||
}
|
||||
qemu_sem_post(&multifd_send_state->channels_ready);
|
||||
} else if (p->quit) {
|
||||
@@ -1179,7 +1179,7 @@ out:
|
||||
*/
|
||||
if (ret != 0) {
|
||||
if (flags & MULTIFD_FLAG_SYNC) {
|
||||
- qemu_sem_post(&multifd_send_state->sem_sync);
|
||||
+ qemu_sem_post(&p->sem_sync);
|
||||
}
|
||||
qemu_sem_post(&multifd_send_state->channels_ready);
|
||||
}
|
||||
@@ -1225,7 +1225,6 @@ int multifd_save_setup(void)
|
||||
multifd_send_state = g_malloc0(sizeof(*multifd_send_state));
|
||||
multifd_send_state->params = g_new0(MultiFDSendParams, thread_count);
|
||||
multifd_send_state->pages = multifd_pages_init(page_count);
|
||||
- qemu_sem_init(&multifd_send_state->sem_sync, 0);
|
||||
qemu_sem_init(&multifd_send_state->channels_ready, 0);
|
||||
|
||||
for (i = 0; i < thread_count; i++) {
|
||||
@@ -1233,6 +1232,7 @@ int multifd_save_setup(void)
|
||||
|
||||
qemu_mutex_init(&p->mutex);
|
||||
qemu_sem_init(&p->sem, 0);
|
||||
+ qemu_sem_init(&p->sem_sync, 0);
|
||||
p->quit = false;
|
||||
p->pending_job = 0;
|
||||
p->id = i;
|
||||
--
|
||||
2.19.1
|
||||
57
migration-Maybe-VM-is-paused-when-migration-is-cance.patch
Normal file
57
migration-Maybe-VM-is-paused-when-migration-is-cance.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 5e99e1329fa52dce8ab784a960e64a3e19b429aa Mon Sep 17 00:00:00 2001
|
||||
From: Zhimin Feng <fengzhimin1@huawei.com>
|
||||
Date: Tue, 14 Jan 2020 17:43:09 +0800
|
||||
Subject: [PATCH 07/10] migration: Maybe VM is paused when migration is
|
||||
cancelled
|
||||
|
||||
If the migration is cancelled when it is in the completion phase,
|
||||
the migration state is set to MIGRATION_STATUS_CANCELLING.
|
||||
The VM maybe wait for the 'pause_sem' semaphore in migration_maybe_pause
|
||||
function, so that VM always is paused.
|
||||
|
||||
Change-Id: Ib2f2f42ee1edbb14da269ee19ba1fe16dd363822
|
||||
Reported-by: Euler Robot <euler.robot@huawei.com>
|
||||
Signed-off-by: Zhimin Feng <fengzhimin1@huawei.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
||||
---
|
||||
migration/migration.c | 24 ++++++++++++++++--------
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/migration/migration.c b/migration/migration.c
|
||||
index bea9b1d7..114c33a1 100644
|
||||
--- a/migration/migration.c
|
||||
+++ b/migration/migration.c
|
||||
@@ -2731,14 +2731,22 @@ static int migration_maybe_pause(MigrationState *s,
|
||||
/* This block intentionally left blank */
|
||||
}
|
||||
|
||||
- qemu_mutex_unlock_iothread();
|
||||
- migrate_set_state(&s->state, *current_active_state,
|
||||
- MIGRATION_STATUS_PRE_SWITCHOVER);
|
||||
- qemu_sem_wait(&s->pause_sem);
|
||||
- migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
|
||||
- new_state);
|
||||
- *current_active_state = new_state;
|
||||
- qemu_mutex_lock_iothread();
|
||||
+ /*
|
||||
+ * If the migration is cancelled when it is in the completion phase,
|
||||
+ * the migration state is set to MIGRATION_STATUS_CANCELLING.
|
||||
+ * So we don't need to wait a semaphore, otherwise we would always
|
||||
+ * wait for the 'pause_sem' semaphore.
|
||||
+ */
|
||||
+ if (s->state != MIGRATION_STATUS_CANCELLING) {
|
||||
+ qemu_mutex_unlock_iothread();
|
||||
+ migrate_set_state(&s->state, *current_active_state,
|
||||
+ MIGRATION_STATUS_PRE_SWITCHOVER);
|
||||
+ qemu_sem_wait(&s->pause_sem);
|
||||
+ migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
|
||||
+ new_state);
|
||||
+ *current_active_state = new_state;
|
||||
+ qemu_mutex_lock_iothread();
|
||||
+ }
|
||||
|
||||
return s->state == new_state ? 0 : -EINVAL;
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
50
migration-add-qemu_file_update_transfer-interface.patch
Normal file
50
migration-add-qemu_file_update_transfer-interface.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 7572495245a437da717e6829a9ce852cc3f229c9 Mon Sep 17 00:00:00 2001
|
||||
From: Zheng Chuan <zhengchuan@huawei.com>
|
||||
Date: Mon, 20 Apr 2020 15:13:47 +0800
|
||||
Subject: [PATCH 02/10] migration: add qemu_file_update_transfer interface
|
||||
|
||||
Add qemu_file_update_transfer for just update bytes_xfer for speed
|
||||
limitation. This will be used for further migration feature such as
|
||||
multifd migration.
|
||||
|
||||
Change-Id: I969aa15305c961254b6fb9805b0ed2d65826cc5d
|
||||
Signed-off-by: Ivan Ren <ivanren@tencent.com>
|
||||
Reviewed-by: Wei Yang <richardw.yang@linux.intel.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Message-Id: <1564464816-21804-2-git-send-email-ivanren@tencent.com>
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
---
|
||||
migration/qemu-file.c | 5 +++++
|
||||
migration/qemu-file.h | 1 +
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
|
||||
index 04315855..18f48052 100644
|
||||
--- a/migration/qemu-file.c
|
||||
+++ b/migration/qemu-file.c
|
||||
@@ -615,6 +615,11 @@ void qemu_file_reset_rate_limit(QEMUFile *f)
|
||||
f->bytes_xfer = 0;
|
||||
}
|
||||
|
||||
+void qemu_file_update_transfer(QEMUFile *f, int64_t len)
|
||||
+{
|
||||
+ f->bytes_xfer += len;
|
||||
+}
|
||||
+
|
||||
void qemu_put_be16(QEMUFile *f, unsigned int v)
|
||||
{
|
||||
qemu_put_byte(f, v >> 8);
|
||||
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
|
||||
index 13baf896..5de9fa2e 100644
|
||||
--- a/migration/qemu-file.h
|
||||
+++ b/migration/qemu-file.h
|
||||
@@ -147,6 +147,7 @@ int qemu_peek_byte(QEMUFile *f, int offset);
|
||||
void qemu_file_skip(QEMUFile *f, int size);
|
||||
void qemu_update_position(QEMUFile *f, size_t size);
|
||||
void qemu_file_reset_rate_limit(QEMUFile *f);
|
||||
+void qemu_file_update_transfer(QEMUFile *f, int64_t len);
|
||||
void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
|
||||
int64_t qemu_file_get_rate_limit(QEMUFile *f);
|
||||
void qemu_file_set_error(QEMUFile *f, int ret);
|
||||
--
|
||||
2.19.1
|
||||
127
migration-add-speed-limit-for-multifd-migration.patch
Normal file
127
migration-add-speed-limit-for-multifd-migration.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From bc5780480db9e38699df0b4697e60a9f36258dc4 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Ren <ivanren@tencent.com>
|
||||
Date: Tue, 30 Jul 2019 13:33:35 +0800
|
||||
Subject: [PATCH 03/10] migration: add speed limit for multifd migration
|
||||
|
||||
Limit the speed of multifd migration through common speed limitation
|
||||
qemu file.
|
||||
|
||||
Change-Id: Id2abfc7ea85679bd53130a43043cc70179a52e87
|
||||
Signed-off-by: Ivan Ren <ivanren@tencent.com>
|
||||
Message-Id: <1564464816-21804-3-git-send-email-ivanren@tencent.com>
|
||||
Reviewed-by: Wei Yang <richardw.yang@linux.intel.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
---
|
||||
migration/ram.c | 22 ++++++++++++----------
|
||||
1 file changed, 12 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 889148dd..88ddd2bb 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -922,7 +922,7 @@ struct {
|
||||
* false.
|
||||
*/
|
||||
|
||||
-static int multifd_send_pages(void)
|
||||
+static int multifd_send_pages(RAMState *rs)
|
||||
{
|
||||
int i;
|
||||
static int next_channel;
|
||||
@@ -954,6 +954,7 @@ static int multifd_send_pages(void)
|
||||
multifd_send_state->pages = p->pages;
|
||||
p->pages = pages;
|
||||
transferred = ((uint64_t) pages->used) * TARGET_PAGE_SIZE + p->packet_len;
|
||||
+ qemu_file_update_transfer(rs->f, transferred);
|
||||
ram_counters.multifd_bytes += transferred;
|
||||
ram_counters.transferred += transferred;;
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
@@ -962,7 +963,7 @@ static int multifd_send_pages(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int multifd_queue_page(RAMBlock *block, ram_addr_t offset)
|
||||
+static int multifd_queue_page(RAMState *rs, RAMBlock *block, ram_addr_t offset)
|
||||
{
|
||||
MultiFDPages_t *pages = multifd_send_state->pages;
|
||||
|
||||
@@ -981,12 +982,12 @@ static int multifd_queue_page(RAMBlock *block, ram_addr_t offset)
|
||||
}
|
||||
}
|
||||
|
||||
- if (multifd_send_pages() < 0) {
|
||||
+ if (multifd_send_pages(rs) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pages->block != block) {
|
||||
- return multifd_queue_page(block, offset);
|
||||
+ return multifd_queue_page(rs, block, offset);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -1054,7 +1055,7 @@ void multifd_save_cleanup(void)
|
||||
multifd_send_state = NULL;
|
||||
}
|
||||
|
||||
-static void multifd_send_sync_main(void)
|
||||
+static void multifd_send_sync_main(RAMState *rs)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1062,7 +1063,7 @@ static void multifd_send_sync_main(void)
|
||||
return;
|
||||
}
|
||||
if (multifd_send_state->pages->used) {
|
||||
- if (multifd_send_pages() < 0) {
|
||||
+ if (multifd_send_pages(rs) < 0) {
|
||||
error_report("%s: multifd_send_pages fail", __func__);
|
||||
return;
|
||||
}
|
||||
@@ -1083,6 +1084,7 @@ static void multifd_send_sync_main(void)
|
||||
p->packet_num = multifd_send_state->packet_num++;
|
||||
p->flags |= MULTIFD_FLAG_SYNC;
|
||||
p->pending_job++;
|
||||
+ qemu_file_update_transfer(rs->f, p->packet_len);
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
qemu_sem_post(&p->sem);
|
||||
}
|
||||
@@ -2079,7 +2081,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage)
|
||||
static int ram_save_multifd_page(RAMState *rs, RAMBlock *block,
|
||||
ram_addr_t offset)
|
||||
{
|
||||
- if (multifd_queue_page(block, offset) < 0) {
|
||||
+ if (multifd_queue_page(rs, block, offset) < 0) {
|
||||
return -1;
|
||||
}
|
||||
ram_counters.normal++;
|
||||
@@ -3482,7 +3484,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||
ram_control_before_iterate(f, RAM_CONTROL_SETUP);
|
||||
ram_control_after_iterate(f, RAM_CONTROL_SETUP);
|
||||
|
||||
- multifd_send_sync_main();
|
||||
+ multifd_send_sync_main(*rsp);
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
qemu_fflush(f);
|
||||
|
||||
@@ -3570,7 +3572,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
|
||||
ram_control_after_iterate(f, RAM_CONTROL_ROUND);
|
||||
|
||||
out:
|
||||
- multifd_send_sync_main();
|
||||
+ multifd_send_sync_main(rs);
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
qemu_fflush(f);
|
||||
ram_counters.transferred += 8;
|
||||
@@ -3629,7 +3631,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
- multifd_send_sync_main();
|
||||
+ multifd_send_sync_main(rs);
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
qemu_fflush(f);
|
||||
|
||||
--
|
||||
2.19.1
|
||||
125
migration-always-initialise-ram_counters-for-a-new-m.patch
Normal file
125
migration-always-initialise-ram_counters-for-a-new-m.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From af2aa4f553565ae6b2248204c154748f38ec4746 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Ren <ivanren@tencent.com>
|
||||
Date: Fri, 2 Aug 2019 18:18:41 +0800
|
||||
Subject: [PATCH 01/10] migration: always initialise ram_counters for a new
|
||||
migration
|
||||
|
||||
This patch fix a multifd migration bug in migration speed calculation, this
|
||||
problem can be reproduced as follows:
|
||||
1. start a vm and give a heavy memory write stress to prevent the vm be
|
||||
successfully migrated to destination
|
||||
2. begin a migration with multifd
|
||||
3. migrate for a long time [actually, this can be measured by transferred bytes]
|
||||
4. migrate cancel
|
||||
5. begin a new migration with multifd, the migration will directly run into
|
||||
migration_completion phase
|
||||
|
||||
Reason as follows:
|
||||
|
||||
Migration update bandwidth and s->threshold_size in function
|
||||
migration_update_counters after BUFFER_DELAY time:
|
||||
|
||||
current_bytes = migration_total_bytes(s);
|
||||
transferred = current_bytes - s->iteration_initial_bytes;
|
||||
time_spent = current_time - s->iteration_start_time;
|
||||
bandwidth = (double)transferred / time_spent;
|
||||
s->threshold_size = bandwidth * s->parameters.downtime_limit;
|
||||
|
||||
In multifd migration, migration_total_bytes function return
|
||||
qemu_ftell(s->to_dst_file) + ram_counters.multifd_bytes.
|
||||
s->iteration_initial_bytes will be initialized to 0 at every new migration,
|
||||
but ram_counters is a global variable, and history migration data will be
|
||||
accumulated. So if the ram_counters.multifd_bytes is big enough, it may lead
|
||||
pending_size >= s->threshold_size become false in migration_iteration_run
|
||||
after the first migration_update_counters.
|
||||
|
||||
Change-Id: Ib153d8676a5b82650bfb1156060e09f0d29f3ac6
|
||||
Signed-off-by: Ivan Ren <ivanren@tencent.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Reviewed-by: Wei Yang <richardw.yang@linux.intel.com>
|
||||
Suggested-by: Wei Yang <richardw.yang@linux.intel.com>
|
||||
Message-Id: <1564741121-1840-1-git-send-email-ivanren@tencent.com>
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
---
|
||||
migration/migration.c | 25 +++++++++++++++++++------
|
||||
migration/savevm.c | 1 +
|
||||
2 files changed, 20 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/migration/migration.c b/migration/migration.c
|
||||
index 8a607fe1..bea9b1d7 100644
|
||||
--- a/migration/migration.c
|
||||
+++ b/migration/migration.c
|
||||
@@ -1908,6 +1908,11 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
|
||||
}
|
||||
|
||||
migrate_init(s);
|
||||
+ /*
|
||||
+ * set ram_counters memory to zero for a
|
||||
+ * new migration
|
||||
+ */
|
||||
+ memset(&ram_counters, 0, sizeof(ram_counters));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3025,6 +3030,17 @@ static void migration_calculate_complete(MigrationState *s)
|
||||
}
|
||||
}
|
||||
|
||||
+static void update_iteration_initial_status(MigrationState *s)
|
||||
+{
|
||||
+ /*
|
||||
+ * Update these three fields at the same time to avoid mismatch info lead
|
||||
+ * wrong speed calculation.
|
||||
+ */
|
||||
+ s->iteration_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
+ s->iteration_initial_bytes = migration_total_bytes(s);
|
||||
+ s->iteration_initial_pages = ram_get_total_transferred_pages();
|
||||
+}
|
||||
+
|
||||
static void migration_update_counters(MigrationState *s,
|
||||
int64_t current_time)
|
||||
{
|
||||
@@ -3060,9 +3076,7 @@ static void migration_update_counters(MigrationState *s,
|
||||
|
||||
qemu_file_reset_rate_limit(s->to_dst_file);
|
||||
|
||||
- s->iteration_start_time = current_time;
|
||||
- s->iteration_initial_bytes = current_bytes;
|
||||
- s->iteration_initial_pages = ram_get_total_transferred_pages();
|
||||
+ update_iteration_initial_status(s);
|
||||
|
||||
trace_migrate_transferred(transferred, time_spent,
|
||||
bandwidth, s->threshold_size);
|
||||
@@ -3186,7 +3200,7 @@ static void *migration_thread(void *opaque)
|
||||
rcu_register_thread();
|
||||
|
||||
object_ref(OBJECT(s));
|
||||
- s->iteration_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
+ update_iteration_initial_status(s);
|
||||
|
||||
qemu_savevm_state_header(s->to_dst_file);
|
||||
|
||||
@@ -3251,8 +3265,7 @@ static void *migration_thread(void *opaque)
|
||||
* the local variables. This is important to avoid
|
||||
* breaking transferred_bytes and bandwidth calculation
|
||||
*/
|
||||
- s->iteration_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
- s->iteration_initial_bytes = 0;
|
||||
+ update_iteration_initial_status(s);
|
||||
}
|
||||
|
||||
current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
diff --git a/migration/savevm.c b/migration/savevm.c
|
||||
index 79ed44d4..480c511b 100644
|
||||
--- a/migration/savevm.c
|
||||
+++ b/migration/savevm.c
|
||||
@@ -1424,6 +1424,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
|
||||
}
|
||||
|
||||
migrate_init(ms);
|
||||
+ memset(&ram_counters, 0, sizeof(ram_counters));
|
||||
ms->to_dst_file = f;
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
--
|
||||
2.19.1
|
||||
64
migration-multifd-fix-destroyed-mutex-access-in-term.patch
Normal file
64
migration-multifd-fix-destroyed-mutex-access-in-term.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 34d797aa134a33c1d67ca85d9d9f996d58162276 Mon Sep 17 00:00:00 2001
|
||||
From: Jiahui Cen <cenjiahui@huawei.com>
|
||||
Date: Wed, 23 Oct 2019 11:47:37 +0800
|
||||
Subject: [PATCH 09/10] migration/multifd: fix destroyed mutex access in
|
||||
terminating multifd threads
|
||||
|
||||
One multifd will lock all the other multifds' IOChannel mutex to inform them
|
||||
to quit by setting p->quit or shutting down p->c. In this senario, if some
|
||||
multifds had already been terminated and multifd_load_cleanup/multifd_save_cleanup
|
||||
had destroyed their mutex, it could cause destroyed mutex access when trying
|
||||
lock their mutex.
|
||||
|
||||
Here is the coredump stack:
|
||||
#0 0x00007f81a2794437 in raise () from /usr/lib64/libc.so.6
|
||||
#1 0x00007f81a2795b28 in abort () from /usr/lib64/libc.so.6
|
||||
#2 0x00007f81a278d1b6 in __assert_fail_base () from /usr/lib64/libc.so.6
|
||||
#3 0x00007f81a278d262 in __assert_fail () from /usr/lib64/libc.so.6
|
||||
#4 0x000055eb1bfadbd3 in qemu_mutex_lock_impl (mutex=0x55eb1e2d1988, file=<optimized out>, line=<optimized out>) at util/qemu-thread-posix.c:64
|
||||
#5 0x000055eb1bb4564a in multifd_send_terminate_threads (err=<optimized out>) at migration/ram.c:1015
|
||||
#6 0x000055eb1bb4bb7f in multifd_send_thread (opaque=0x55eb1e2d19f8) at migration/ram.c:1171
|
||||
#7 0x000055eb1bfad628 in qemu_thread_start (args=0x55eb1e170450) at util/qemu-thread-posix.c:502
|
||||
#8 0x00007f81a2b36df5 in start_thread () from /usr/lib64/libpthread.so.0
|
||||
#9 0x00007f81a286048d in clone () from /usr/lib64/libc.so.6
|
||||
|
||||
To fix it up, let's destroy the mutex after all the other multifd threads had
|
||||
been terminated.
|
||||
|
||||
Change-Id: I4124d43e8558ba302052bdc53fdae7cfcf9d8687
|
||||
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
||||
---
|
||||
migration/ram.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 029f1cdf..d7d2d5ec 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -1033,6 +1033,10 @@ void multifd_save_cleanup(void)
|
||||
if (p->running) {
|
||||
qemu_thread_join(&p->thread);
|
||||
}
|
||||
+ }
|
||||
+ for (i = 0; i < migrate_multifd_channels(); i++) {
|
||||
+ MultiFDSendParams *p = &multifd_send_state->params[i];
|
||||
+
|
||||
socket_send_channel_destroy(p->c);
|
||||
p->c = NULL;
|
||||
qemu_mutex_destroy(&p->mutex);
|
||||
@@ -1306,6 +1310,10 @@ int multifd_load_cleanup(Error **errp)
|
||||
qemu_sem_post(&p->sem_sync);
|
||||
qemu_thread_join(&p->thread);
|
||||
}
|
||||
+ }
|
||||
+ for (i = 0; i < migrate_multifd_channels(); i++) {
|
||||
+ MultiFDRecvParams *p = &multifd_recv_state->params[i];
|
||||
+
|
||||
object_unref(OBJECT(p->c));
|
||||
p->c = NULL;
|
||||
qemu_mutex_destroy(&p->mutex);
|
||||
--
|
||||
2.19.1
|
||||
62
migration-multifd-fix-nullptr-access-in-multifd_send.patch
Normal file
62
migration-multifd-fix-nullptr-access-in-multifd_send.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 6a08ee257a95d9f2514bd995e90ddf46d3f78b41 Mon Sep 17 00:00:00 2001
|
||||
From: Zheng Chuan <zhengchuan@huawei.com>
|
||||
Date: Tue, 21 Apr 2020 19:49:26 +0800
|
||||
Subject: [PATCH 10/10] migration/multifd: fix nullptr access in
|
||||
multifd_send_terminate_threads
|
||||
|
||||
If the multifd_send_threads is not created when migration is failed,
|
||||
multifd_save_cleanup would be called twice. In this senario, the
|
||||
multifd_send_state is accessed after it has been released, the result
|
||||
is that the source VM is crashing down.
|
||||
|
||||
Here is the coredump stack:
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
0x00005629333a78ef in multifd_send_terminate_threads (err=err@entry=0x0) at migration/ram.c:1012
|
||||
1012 MultiFDSendParams *p = &multifd_send_state->params[i];
|
||||
#0 0x00005629333a78ef in multifd_send_terminate_threads (err=err@entry=0x0) at migration/ram.c:1012
|
||||
#1 0x00005629333ab8a9 in multifd_save_cleanup () at migration/ram.c:1028
|
||||
#2 0x00005629333abaea in multifd_new_send_channel_async (task=0x562935450e70, opaque=<optimized out>) at migration/ram.c:1202
|
||||
#3 0x000056293373a562 in qio_task_complete (task=task@entry=0x562935450e70) at io/task.c:196
|
||||
#4 0x000056293373a6e0 in qio_task_thread_result (opaque=0x562935450e70) at io/task.c:111
|
||||
#5 0x00007f475d4d75a7 in g_idle_dispatch () from /usr/lib64/libglib-2.0.so.0
|
||||
#6 0x00007f475d4da9a9 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
|
||||
#7 0x0000562933785b33 in glib_pollfds_poll () at util/main-loop.c:219
|
||||
#8 os_host_main_loop_wait (timeout=<optimized out>) at util/main-loop.c:242
|
||||
#9 main_loop_wait (nonblocking=nonblocking@entry=0) at util/main-loop.c:518
|
||||
#10 0x00005629334c5acf in main_loop () at vl.c:1810
|
||||
#11 0x000056293334d7bb in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4471
|
||||
|
||||
If the multifd_send_threads is not created when migration is failed.
|
||||
In this senario, we don't call multifd_save_cleanup in multifd_new_send_channel_async.
|
||||
|
||||
Change-Id: I7441efe2ed542054ecd2a4da8146e2652824b452
|
||||
Signed-off-by: Zhimin Feng <fengzhimin1@huawei.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
||||
---
|
||||
migration/ram.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index d7d2d5ec..1858d66c 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -1205,7 +1205,15 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
|
||||
|
||||
if (qio_task_propagate_error(task, &local_err)) {
|
||||
migrate_set_error(migrate_get_current(), local_err);
|
||||
- multifd_save_cleanup();
|
||||
+ /* Error happen, we need to tell who pay attention to me */
|
||||
+ qemu_sem_post(&multifd_send_state->channels_ready);
|
||||
+ qemu_sem_post(&p->sem_sync);
|
||||
+ /*
|
||||
+ * Although multifd_send_thread is not created, but main migration
|
||||
+ * thread neet to judge whether it is running, so we need to mark
|
||||
+ * its status.
|
||||
+ */
|
||||
+ p->quit = true;
|
||||
} else {
|
||||
p->c = QIO_CHANNEL(sioc);
|
||||
qio_channel_set_delay(p->c, false);
|
||||
--
|
||||
2.19.1
|
||||
75
migration-multifd-fix-nullptr-access-in-terminating-m.patch
Normal file
75
migration-multifd-fix-nullptr-access-in-terminating-m.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From d9a847f0982fcca6f63031215065c346fcc27bbc Mon Sep 17 00:00:00 2001
|
||||
From: Zheng Chuan <zhengchuan@huawei.com>
|
||||
Date: Fri, 24 Apr 2020 11:58:33 +0800
|
||||
Subject: [PATCH 06/10] migration/multifd: fix nullptr access in terminating
|
||||
multifd threads
|
||||
|
||||
One multifd channel will shutdown all the other multifd's IOChannel when it
|
||||
fails to receive an IOChannel. In this senario, if some multifds had not
|
||||
received its IOChannel yet, it would try to shutdown its IOChannel which could
|
||||
cause nullptr access at qio_channel_shutdown.
|
||||
|
||||
Here is the coredump stack:
|
||||
#0 object_get_class (obj=obj@entry=0x0) at qom/object.c:908
|
||||
#1 0x00005563fdbb8f4a in qio_channel_shutdown (ioc=0x0, how=QIO_CHANNEL_SHUTDOWN_BOTH, errp=0x0) at io/channel.c:355
|
||||
#2 0x00005563fd7b4c5f in multifd_recv_terminate_threads (err=<optimized out>) at migration/ram.c:1280
|
||||
#3 0x00005563fd7bc019 in multifd_recv_new_channel (ioc=ioc@entry=0x556400255610, errp=errp@entry=0x7ffec07dce00) at migration/ram.c:1478
|
||||
#4 0x00005563fda82177 in migration_ioc_process_incoming (ioc=ioc@entry=0x556400255610, errp=errp@entry=0x7ffec07dce30) at migration/migration.c:605
|
||||
#5 0x00005563fda8567d in migration_channel_process_incoming (ioc=0x556400255610) at migration/channel.c:44
|
||||
#6 0x00005563fda83ee0 in socket_accept_incoming_migration (listener=0x5563fff6b920, cioc=0x556400255610, opaque=<optimized out>) at migration/socket
|
||||
.c:166
|
||||
#7 0x00005563fdbc25cd in qio_net_listener_channel_func (ioc=<optimized out>, condition=<optimized out>, opaque=<optimized out>) at io/net-listener.c:54
|
||||
#8 0x00007f895b6fe9a9 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
|
||||
#9 0x00005563fdc18136 in glib_pollfds_poll () at util/main-loop.c:218
|
||||
#10 0x00005563fdc181b5 in os_host_main_loop_wait (timeout=1000000000) at util/main-loop.c:241
|
||||
#11 0x00005563fdc183a2 in main_loop_wait (nonblocking=nonblocking@entry=0) at util/main-loop.c:517
|
||||
#12 0x00005563fd8edb37 in main_loop () at vl.c:1791
|
||||
#13 0x00005563fd74fd45 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4473
|
||||
|
||||
To fix it up, let's check p->c before calling qio_channel_shutdown.
|
||||
|
||||
Change-Id: Ib36c1b3d866a3ad92d1460512df840cfb8736ab6
|
||||
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Signed-off-by: Juan Quintela <quintela@redhat.com>
|
||||
---
|
||||
migration/ram.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 51811c2d..756a525f 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -1112,6 +1112,7 @@ static void *multifd_send_thread(void *opaque)
|
||||
rcu_register_thread();
|
||||
|
||||
if (multifd_send_initial_packet(p, &local_err) < 0) {
|
||||
+ ret = -1;
|
||||
goto out;
|
||||
}
|
||||
/* initial packet */
|
||||
@@ -1178,9 +1179,7 @@ out:
|
||||
* who pay attention to me.
|
||||
*/
|
||||
if (ret != 0) {
|
||||
- if (flags & MULTIFD_FLAG_SYNC) {
|
||||
- qemu_sem_post(&p->sem_sync);
|
||||
- }
|
||||
+ qemu_sem_post(&p->sem_sync);
|
||||
qemu_sem_post(&multifd_send_state->channels_ready);
|
||||
}
|
||||
|
||||
@@ -1279,7 +1278,9 @@ static void multifd_recv_terminate_threads(Error *err)
|
||||
- normal quit, i.e. everything went fine, just finished
|
||||
- error quit: We close the channels so the channel threads
|
||||
finish the qio_channel_read_all_eof() */
|
||||
- qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
|
||||
+ if (p->c) {
|
||||
+ qio_channel_shutdown(p->c, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
|
||||
+ }
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
294
migration-multifd-fix-potential-wrong-acception-orde.patch
Normal file
294
migration-multifd-fix-potential-wrong-acception-orde.patch
Normal file
@ -0,0 +1,294 @@
|
||||
From 71f3e496c128b46f803cc4776154b02a5e505cb2 Mon Sep 17 00:00:00 2001
|
||||
From: Zheng Chuan <zhengchuan@huawei.com>
|
||||
Date: Wed, 22 Apr 2020 13:45:39 +0800
|
||||
Subject: [PATCH] migration/multifd: fix potential wrong acception order of
|
||||
IOChannel
|
||||
|
||||
Multifd assumes the migration thread IOChannel is always established before
|
||||
the multifd IOChannels, but this assumption will be broken in many situations
|
||||
like network packet loss.
|
||||
|
||||
For example:
|
||||
Step1: Source (migration thread IOChannel) --SYN--> Destination
|
||||
Step2: Source (migration thread IOChannel) <--SYNACK Destination
|
||||
Step3: Source (migration thread IOChannel, lost) --ACK-->X Destination
|
||||
Step4: Source (multifd IOChannel) --SYN--> Destination
|
||||
Step5: Source (multifd IOChannel) <--SYNACK Destination
|
||||
Step6: Source (multifd IOChannel, ESTABLISHED) --ACK--> Destination
|
||||
Step7: Destination accepts multifd IOChannel
|
||||
Step8: Source (migration thread IOChannel, ESTABLISHED) -ACK,DATA-> Destination
|
||||
Step9: Destination accepts migration thread IOChannel
|
||||
|
||||
The above situation can be reproduced by creating a weak network environment,
|
||||
such as "tc qdisc add dev eth0 root netem loss 50%". The wrong acception order
|
||||
will cause magic check failure and thus lead to migration failure.
|
||||
|
||||
This patch fixes this issue by sending a migration IOChannel initial packet with
|
||||
a unique id when using multifd migration. Since the multifd IOChannels will also
|
||||
send initial packets, the destination can judge whether the processing IOChannel
|
||||
belongs to multifd by checking the id in the initial packet. This mechanism can
|
||||
ensure that different IOChannels will go to correct branches in our test.
|
||||
|
||||
Change-Id: I63d1c32c7b66063bd6a3c5e7d63500555bd148b9
|
||||
Signed-off-by: Jiahui Cen <cenjiahui@huawei.com>
|
||||
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
||||
|
||||
diff --git a/migration/channel.c b/migration/channel.c
|
||||
index 20e4c8e2..74621814 100644
|
||||
--- a/migration/channel.c
|
||||
+++ b/migration/channel.c
|
||||
@@ -82,6 +82,15 @@ void migration_channel_connect(MigrationState *s,
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
+ if (migrate_use_multifd()) {
|
||||
+ /* multifd migration cannot distinguish migration IOChannel
|
||||
+ * from multifd IOChannels, so we need to send an initial packet
|
||||
+ * to show it is migration IOChannel
|
||||
+ */
|
||||
+ migration_send_initial_packet(ioc,
|
||||
+ migrate_multifd_channels(),
|
||||
+ &error);
|
||||
+ }
|
||||
QEMUFile *f = qemu_fopen_channel_output(ioc);
|
||||
|
||||
qemu_mutex_lock(&s->qemu_file_lock);
|
||||
diff --git a/migration/migration.c b/migration/migration.c
|
||||
index 114c33a1..8f2fc2b4 100644
|
||||
--- a/migration/migration.c
|
||||
+++ b/migration/migration.c
|
||||
@@ -517,12 +517,6 @@ static void migration_incoming_setup(QEMUFile *f)
|
||||
{
|
||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||
|
||||
- if (multifd_load_setup() != 0) {
|
||||
- /* We haven't been able to create multifd threads
|
||||
- nothing better to do */
|
||||
- exit(EXIT_FAILURE);
|
||||
- }
|
||||
-
|
||||
if (!mis->from_src_file) {
|
||||
mis->from_src_file = f;
|
||||
}
|
||||
@@ -580,36 +574,41 @@ void migration_fd_process_incoming(QEMUFile *f)
|
||||
void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
|
||||
{
|
||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||
- bool start_migration;
|
||||
-
|
||||
- if (!mis->from_src_file) {
|
||||
- /* The first connection (multifd may have multiple) */
|
||||
- QEMUFile *f = qemu_fopen_channel_input(ioc);
|
||||
+ Error *local_err = NULL;
|
||||
+ int id = 0;
|
||||
|
||||
- /* If it's a recovery, we're done */
|
||||
- if (postcopy_try_recover(f)) {
|
||||
- return;
|
||||
- }
|
||||
+ if (migrate_use_multifd()) {
|
||||
+ id = migration_recv_initial_packet(ioc, &local_err);
|
||||
+ }
|
||||
+ if (!migrate_use_multifd() || id == migrate_multifd_channels()) {
|
||||
+ if (!mis->from_src_file) {
|
||||
+ /* The migration connection (multifd may have multiple) */
|
||||
+ QEMUFile *f = qemu_fopen_channel_input(ioc);
|
||||
|
||||
- migration_incoming_setup(f);
|
||||
+ /* If it's a recovery, we're done */
|
||||
+ if (postcopy_try_recover(f)) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- /*
|
||||
- * Common migration only needs one channel, so we can start
|
||||
- * right now. Multifd needs more than one channel, we wait.
|
||||
- */
|
||||
- start_migration = !migrate_use_multifd();
|
||||
- } else {
|
||||
- Error *local_err = NULL;
|
||||
+ migration_incoming_setup(f);
|
||||
+ }
|
||||
+ } else if (id >= 0) {
|
||||
/* Multiple connections */
|
||||
assert(migrate_use_multifd());
|
||||
- start_migration = multifd_recv_new_channel(ioc, &local_err);
|
||||
+ multifd_recv_new_channel(ioc, id, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
+ } else {
|
||||
+ /* Bad connections */
|
||||
+ multifd_recv_terminate_threads(local_err);
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
}
|
||||
|
||||
- if (start_migration) {
|
||||
+ /* Once we have all the channels we need, we can start migration */
|
||||
+ if (migration_has_all_channels()) {
|
||||
migration_incoming_process();
|
||||
}
|
||||
}
|
||||
diff --git a/migration/migration.h b/migration/migration.h
|
||||
index 1fdd7b21..feb34430 100644
|
||||
--- a/migration/migration.h
|
||||
+++ b/migration/migration.h
|
||||
@@ -339,4 +339,7 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
|
||||
void migration_make_urgent_request(void);
|
||||
void migration_consume_urgent_request(void);
|
||||
|
||||
+int migration_send_initial_packet(QIOChannel *c, uint8_t id, Error **errp);
|
||||
+int migration_recv_initial_packet(QIOChannel *c, Error **errp);
|
||||
+
|
||||
#endif
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 756a525f..029f1cdf 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -593,7 +593,7 @@ typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t unused1[7]; /* Reserved for future use */
|
||||
uint64_t unused2[4]; /* Reserved for future use */
|
||||
-} __attribute__((packed)) MultiFDInit_t;
|
||||
+} __attribute__((packed)) MigrationInit_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
@@ -702,26 +702,26 @@ typedef struct {
|
||||
QemuSemaphore sem_sync;
|
||||
} MultiFDRecvParams;
|
||||
|
||||
-static int multifd_send_initial_packet(MultiFDSendParams *p, Error **errp)
|
||||
+int migration_send_initial_packet(QIOChannel *c, uint8_t id, Error **errp)
|
||||
{
|
||||
- MultiFDInit_t msg;
|
||||
+ MigrationInit_t msg;
|
||||
int ret;
|
||||
|
||||
msg.magic = cpu_to_be32(MULTIFD_MAGIC);
|
||||
msg.version = cpu_to_be32(MULTIFD_VERSION);
|
||||
- msg.id = p->id;
|
||||
+ msg.id = id;
|
||||
memcpy(msg.uuid, &qemu_uuid.data, sizeof(msg.uuid));
|
||||
|
||||
- ret = qio_channel_write_all(p->c, (char *)&msg, sizeof(msg), errp);
|
||||
+ ret = qio_channel_write_all(c, (char *)&msg, sizeof(msg), errp);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int multifd_recv_initial_packet(QIOChannel *c, Error **errp)
|
||||
+int migration_recv_initial_packet(QIOChannel *c, Error **errp)
|
||||
{
|
||||
- MultiFDInit_t msg;
|
||||
+ MigrationInit_t msg;
|
||||
int ret;
|
||||
|
||||
ret = qio_channel_read_all(c, (char *)&msg, sizeof(msg), errp);
|
||||
@@ -756,8 +756,8 @@ static int multifd_recv_initial_packet(QIOChannel *c, Error **errp)
|
||||
}
|
||||
|
||||
if (msg.id > migrate_multifd_channels()) {
|
||||
- error_setg(errp, "multifd: received channel version %d "
|
||||
- "expected %d", msg.version, MULTIFD_VERSION);
|
||||
+ error_setg(errp, "multifd: received channel id %d "
|
||||
+ "expected [0-%d]", msg.id, migrate_multifd_channels());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1111,7 +1111,7 @@ static void *multifd_send_thread(void *opaque)
|
||||
trace_multifd_send_thread_start(p->id);
|
||||
rcu_register_thread();
|
||||
|
||||
- if (multifd_send_initial_packet(p, &local_err) < 0) {
|
||||
+ if (migration_send_initial_packet(p->c, p->id, &local_err) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -1255,7 +1255,7 @@ struct {
|
||||
uint64_t packet_num;
|
||||
} *multifd_recv_state;
|
||||
|
||||
-static void multifd_recv_terminate_threads(Error *err)
|
||||
+void multifd_recv_terminate_threads(Error *err)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1470,21 +1470,10 @@ bool multifd_recv_all_channels_created(void)
|
||||
* - Return false and do not set @errp when correctly receiving the current one;
|
||||
* - Return false and set @errp when failing to receive the current channel.
|
||||
*/
|
||||
-bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
|
||||
+void multifd_recv_new_channel(QIOChannel *ioc, int id, Error **errp)
|
||||
{
|
||||
MultiFDRecvParams *p;
|
||||
Error *local_err = NULL;
|
||||
- int id;
|
||||
-
|
||||
- id = multifd_recv_initial_packet(ioc, &local_err);
|
||||
- if (id < 0) {
|
||||
- multifd_recv_terminate_threads(local_err);
|
||||
- error_propagate_prepend(errp, local_err,
|
||||
- "failed to receive packet"
|
||||
- " via multifd channel %d: ",
|
||||
- atomic_read(&multifd_recv_state->count));
|
||||
- return false;
|
||||
- }
|
||||
|
||||
p = &multifd_recv_state->params[id];
|
||||
if (p->c != NULL) {
|
||||
@@ -1492,7 +1481,7 @@ bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
|
||||
id);
|
||||
multifd_recv_terminate_threads(local_err);
|
||||
error_propagate(errp, local_err);
|
||||
- return false;
|
||||
+ return;
|
||||
}
|
||||
p->c = ioc;
|
||||
object_ref(OBJECT(ioc));
|
||||
@@ -1503,8 +1492,6 @@ bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp)
|
||||
qemu_thread_create(&p->thread, p->name, multifd_recv_thread, p,
|
||||
QEMU_THREAD_JOINABLE);
|
||||
atomic_inc(&multifd_recv_state->count);
|
||||
- return atomic_read(&multifd_recv_state->count) ==
|
||||
- migrate_multifd_channels();
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/migration/ram.h b/migration/ram.h
|
||||
index bd0eee79..a788ff0e 100644
|
||||
--- a/migration/ram.h
|
||||
+++ b/migration/ram.h
|
||||
@@ -46,7 +46,8 @@ void multifd_save_cleanup(void);
|
||||
int multifd_load_setup(void);
|
||||
int multifd_load_cleanup(Error **errp);
|
||||
bool multifd_recv_all_channels_created(void);
|
||||
-bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
|
||||
+void multifd_recv_new_channel(QIOChannel *ioc, int id, Error **errp);
|
||||
+void multifd_recv_terminate_threads(Error *err);
|
||||
|
||||
uint64_t ram_pagesize_summary(void);
|
||||
int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len);
|
||||
diff --git a/migration/socket.c b/migration/socket.c
|
||||
index 98efdc02..bc0960c6 100644
|
||||
--- a/migration/socket.c
|
||||
+++ b/migration/socket.c
|
||||
@@ -181,6 +181,12 @@ static void socket_start_incoming_migration(SocketAddress *saddr,
|
||||
|
||||
qio_net_listener_set_name(listener, "migration-socket-listener");
|
||||
|
||||
+ if (multifd_load_setup() != 0) {
|
||||
+ /* We haven't been able to create multifd threads
|
||||
+ nothing better to do */
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
if (qio_net_listener_open_sync(listener, saddr, errp) < 0) {
|
||||
object_unref(OBJECT(listener));
|
||||
return;
|
||||
--
|
||||
2.23.0
|
||||
69
migration-ram-Do-error_free-after-migrate_set_error-.patch
Normal file
69
migration-ram-Do-error_free-after-migrate_set_error-.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 05d1fbd2390d441e5acb606dba3d308d506a8eb1 Mon Sep 17 00:00:00 2001
|
||||
From: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
Date: Tue, 5 May 2020 11:44:20 +0800
|
||||
Subject: [PATCH 1/3] migration/ram: Do error_free after migrate_set_error to
|
||||
avoid memleaks
|
||||
|
||||
If local_err is not NULL, it use error_copy to set migrate error in
|
||||
multifd_send_terminate_threads. Thus, we should free it.
|
||||
|
||||
Similarly, fix another leak in multifd_recv_thread.
|
||||
|
||||
The leak stack:
|
||||
Direct leak of 96 byte(s) in 2 object(s) allocated from:
|
||||
#0 0xfffdd97fe938 in __interceptor_calloc (/lib64/libasan.so.4+0xee938)
|
||||
#1 0xfffdd85a8bb0 in g_malloc0 (/lib64/libglib-2.0.so.0+0x58bb0)
|
||||
#2 0xaaadfc6e41c4 in error_setv util/error.c:61
|
||||
#3 0xaaadfc6e4880 in error_setg_errno_internal util/error.c:109
|
||||
#4 0xaaadfc6192a8 in qio_channel_socket_writev io/channel-socket.c:552
|
||||
#5 0xaaadfc614604 in qio_channel_writev_all io/channel.c:171
|
||||
#6 0xaaadfc6147ec in qio_channel_write_all io/channel.c:257
|
||||
#7 0xaaadfbaec5fc in multifd_send_thread /usr/src/debug/qemu-4.1.0-4_asan.aarch64/migration/ram.c:1145
|
||||
#8 0xaaadfc6db768 in qemu_thread_start util/qemu-thread-posix.c:502
|
||||
#9 0xfffdd79a88c8 (/lib64/libpthread.so.0+0x88c8)
|
||||
#10 0xfffdd78e9578 (/lib64/libc.so.6+0xd9578)
|
||||
|
||||
Indirect leak of 104 byte(s) in 2 object(s) allocated from:
|
||||
#0 0xfffdd97feb40 in realloc (/lib64/libasan.so.4+0xeeb40)
|
||||
#1 0xfffdd78fa6e0 in __vasprintf_chk (/lib64/libc.so.6+0xea6e0)
|
||||
#2 0xfffdd85ee710 in g_vasprintf (/lib64/libglib-2.0.so.0+0x9e710)
|
||||
#3 0xfffdd85c45c4 in g_strdup_vprintf (/lib64/libglib-2.0.so.0+0x745c4)
|
||||
#4 0xfffdd85c4674 in g_strdup_printf (/lib64/libglib-2.0.so.0+0x74674)
|
||||
#5 0xaaadfc6e4214 in error_setv util/error.c:65
|
||||
#6 0xaaadfc6e4880 in error_setg_errno_internal util/error.c:109
|
||||
#7 0xaaadfc6192a8 in qio_channel_socket_writev io/channel-socket.c:552
|
||||
#8 0xaaadfc614604 in qio_channel_writev_all io/channel.c:171
|
||||
#9 0xaaadfc6147ec in qio_channel_write_all io/channel.c:257
|
||||
#10 0xaaadfbaec5fc in multifd_send_thread /usr/src/debug/qemu-4.1.0-4_asan.aarch64/migration/ram.c:1145
|
||||
#11 0xaaadfc6db768 in qemu_thread_start util/qemu-thread-posix.c:502
|
||||
#12 0xfffdd79a88c8 (/lib64/libpthread.so.0+0x88c8)
|
||||
#13 0xfffdd78e9578 (/lib64/libc.so.6+0xd9578)
|
||||
|
||||
Reported-by: Euler Robot <euler.robot@huawei.com>
|
||||
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
---
|
||||
migration/ram.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 1858d66c..6baf1412 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -1176,6 +1176,7 @@ static void *multifd_send_thread(void *opaque)
|
||||
out:
|
||||
if (local_err) {
|
||||
multifd_send_terminate_threads(local_err);
|
||||
+ error_free(local_err);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1427,6 +1428,7 @@ static void *multifd_recv_thread(void *opaque)
|
||||
|
||||
if (local_err) {
|
||||
multifd_recv_terminate_threads(local_err);
|
||||
+ error_free(local_err);
|
||||
}
|
||||
qemu_mutex_lock(&p->mutex);
|
||||
p->running = false;
|
||||
--
|
||||
2.23.0
|
||||
54
migration-ram-fix-memleaks-in-multifd_new_send_chann.patch
Normal file
54
migration-ram-fix-memleaks-in-multifd_new_send_chann.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 4d456b243a41a8e91535b2820fd6ed4f6fb4a194 Mon Sep 17 00:00:00 2001
|
||||
From: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
Date: Tue, 5 May 2020 15:50:54 +0800
|
||||
Subject: [PATCH 2/3] migration/ram: fix memleaks in
|
||||
multifd_new_send_channel_async
|
||||
|
||||
When error happen in multifd_new_send_channel_async, 'sioc' will not be used
|
||||
to create the multifd_send_thread. Let's free it to avoid a memleak. And also
|
||||
do error_free after migrate_set_error() to avoid another leak in the same place.
|
||||
|
||||
The leak stack:
|
||||
Direct leak of 2160 byte(s) in 6 object(s) allocated from:
|
||||
#0 0xfffdd97fe754 in malloc (/lib64/libasan.so.4+0xee754)
|
||||
#1 0xfffdd85a8b48 in g_malloc (/lib64/libglib-2.0.so.0+0x58b48)
|
||||
#2 0xaaadfc4e2b10 in object_new_with_type qom/object.c:634
|
||||
#3 0xaaadfc619468 in qio_channel_socket_new io/channel-socket.c:56
|
||||
#4 0xaaadfc3d3e74 in socket_send_channel_create migration/socket.c:37
|
||||
#5 0xaaadfbaed6f4 in multifd_save_setup /usr/src/debug/qemu-4.1.0-4_asan.aarch64/migration/ram.c:1255
|
||||
#6 0xaaadfc3d2f78 in migrate_fd_connect migration/migration.c:3359
|
||||
#7 0xaaadfc3d6240 in migration_channel_connect migration/channel.c:101
|
||||
#8 0xaaadfc3d3590 in socket_outgoing_migration migration/socket.c:108
|
||||
#9 0xaaadfc625a64 in qio_task_complete io/task.c:195
|
||||
#10 0xaaadfc625ed0 in qio_task_thread_result io/task.c:111
|
||||
#11 0xfffdd859edec (/lib64/libglib-2.0.so.0+0x4edec)
|
||||
#12 0xfffdd85a2a78 in g_main_context_dispatch (/lib64/libglib-2.0.so.0+0x52a78)
|
||||
#13 0xaaadfc6d3b84 in glib_pollfds_poll util/main-loop.c:218
|
||||
#14 0xaaadfc6d3b84 in os_host_main_loop_wait util/main-loop.c:241
|
||||
#15 0xaaadfc6d3b84 in main_loop_wait util/main-loop.c:517
|
||||
#16 0xaaadfbf9206c in main_loop /usr/src/debug/qemu-4.1.0-4_asan.aarch64/vl.c:1791
|
||||
#17 0xaaadfba1b124 in main /usr/src/debug/qemu-4.1.0-4_asan.aarch64/vl.c:4473
|
||||
#18 0xfffdd7833f5c in __libc_start_main (/lib64/libc.so.6+0x23f5c)
|
||||
#19 0xaaadfba26360 (/usr/libexec/qemu-kvm+0x886360)
|
||||
|
||||
Reported-by: Euler Robot <euler.robot@huawei.com>
|
||||
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
---
|
||||
migration/ram.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 6baf1412..840e3548 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -1215,6 +1215,8 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
|
||||
* its status.
|
||||
*/
|
||||
p->quit = true;
|
||||
+ object_unref(OBJECT(sioc));
|
||||
+ error_free(local_err);
|
||||
} else {
|
||||
p->c = QIO_CHANNEL(sioc);
|
||||
qio_channel_set_delay(p->c, false);
|
||||
--
|
||||
2.23.0
|
||||
43
migration-rdma-fix-a-memleak-on-error-path-in-rdma_s.patch
Normal file
43
migration-rdma-fix-a-memleak-on-error-path-in-rdma_s.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 8ae2e3b8be812bcbdeb6151c685026bcaedd4a4b Mon Sep 17 00:00:00 2001
|
||||
From: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
Date: Sat, 9 May 2020 15:25:42 +0800
|
||||
Subject: [PATCH 3/3] migration/rdma: fix a memleak on error path in
|
||||
rdma_start_incoming_migration
|
||||
|
||||
'rdma->host' is malloced in qemu_rdma_data_init, but forgot to free on the error
|
||||
path in rdma_start_incoming_migration(), this patch fix that.
|
||||
|
||||
Direct leak of 2 byte(s) in 1 object(s) allocated from:
|
||||
#0 0xfffce56d34fb in __interceptor_malloc (/lib64/libasan.so.4+0xd34fb)
|
||||
#1 0xfffce5158aa3 in g_malloc (/lib64/libglib-2.0.so.0+0x58aa3)
|
||||
#2 0xfffce5174213 in g_strdup (/lib64/libglib-2.0.so.0+0x74213)
|
||||
#3 0xaaad7c569ddf in qemu_rdma_data_init /Images/qemu/migration/rdma.c:2647
|
||||
#4 0xaaad7c57c99f in rdma_start_incoming_migration /Images/qemu/migration/rdma.c:4020
|
||||
#5 0xaaad7c52b35f in qemu_start_incoming_migration /Images/qemu/migration/migration.c:371
|
||||
#6 0xaaad7be173bf in qemu_init /Images/qemu/softmmu/vl.c:4464
|
||||
#7 0xaaad7bb29843 in main /Images/qemu/softmmu/main.c:48
|
||||
#8 0xfffce3713f5f in __libc_start_main (/lib64/libc.so.6+0x23f5f)
|
||||
#9 0xaaad7bb2bf73 (/Images/qemu/build/aarch64-softmmu/qemu-system-aarch64+0x8fbf73)
|
||||
|
||||
Reported-by: Euler Robot <euler.robot@huawei.com>
|
||||
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
---
|
||||
migration/rdma.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/migration/rdma.c b/migration/rdma.c
|
||||
index 3036221e..b5fdb6a7 100644
|
||||
--- a/migration/rdma.c
|
||||
+++ b/migration/rdma.c
|
||||
@@ -4068,6 +4068,9 @@ void rdma_start_incoming_migration(const char *host_port, Error **errp)
|
||||
return;
|
||||
err:
|
||||
error_propagate(errp, local_err);
|
||||
+ if (rdma) {
|
||||
+ g_free(rdma->host);
|
||||
+ }
|
||||
g_free(rdma);
|
||||
g_free(rdma_return_path);
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
35
migration-update-ram_counters-for-multifd-sync-packe.patch
Normal file
35
migration-update-ram_counters-for-multifd-sync-packe.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From e93040851d683f1f7750acfa0e862b4405678f24 Mon Sep 17 00:00:00 2001
|
||||
From: Zheng Chuan <zhengchuan@huawei.com>
|
||||
Date: Fri, 24 Apr 2020 11:50:41 +0800
|
||||
Subject: [PATCH 04/10] migration: update ram_counters for multifd sync packet
|
||||
|
||||
Multifd sync will send MULTIFD_FLAG_SYNC flag info to destination, add
|
||||
these bytes to ram_counters record.
|
||||
|
||||
Change-Id: I885166f412f58e74de40ea6ffec1c35e82ae4619
|
||||
Signed-off-by: Ivan Ren <ivanren@tencent.com>
|
||||
Suggested-by: Wei Yang <richardw.yang@linux.intel.com>
|
||||
Message-Id: <1564464816-21804-4-git-send-email-ivanren@tencent.com>
|
||||
Reviewed-by: Juan Quintela <quintela@redhat.com>
|
||||
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
---
|
||||
migration/ram.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 88ddd2bb..c75716bb 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -1085,6 +1085,10 @@ static void multifd_send_sync_main(RAMState *rs)
|
||||
p->flags |= MULTIFD_FLAG_SYNC;
|
||||
p->pending_job++;
|
||||
qemu_file_update_transfer(rs->f, p->packet_len);
|
||||
+ ram_counters.multifd_bytes += p->packet_len;
|
||||
+ ram_counters.transferred += p->packet_len;
|
||||
+ ram_counters.multifd_bytes += p->packet_len;
|
||||
+ ram_counters.transferred += p->packet_len;
|
||||
qemu_mutex_unlock(&p->mutex);
|
||||
qemu_sem_post(&p->sem);
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
52
mirror-Keep-mirror_top_bs-drained-after-dropping-per.patch
Normal file
52
mirror-Keep-mirror_top_bs-drained-after-dropping-per.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From e092a17d3825a8f2c93cb429aaa5d857b579b64c Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Mon, 22 Jul 2019 17:44:27 +0200
|
||||
Subject: [PATCH] mirror: Keep mirror_top_bs drained after dropping permissions
|
||||
|
||||
mirror_top_bs is currently implicitly drained through its connection to
|
||||
the source or the target node. However, the drain section for target_bs
|
||||
ends early after moving mirror_top_bs from src to target_bs, so that
|
||||
requests can already be restarted while mirror_top_bs is still present
|
||||
in the chain, but has dropped all permissions and therefore runs into an
|
||||
assertion failure like this:
|
||||
|
||||
qemu-system-x86_64: block/io.c:1634: bdrv_co_write_req_prepare:
|
||||
Assertion `child->perm & BLK_PERM_WRITE' failed.
|
||||
|
||||
Keep mirror_top_bs drained until all graph changes have completed.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
||||
(cherry picked from commit d2da5e288a2e71e82866c8fdefd41b5727300124)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
block/mirror.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 0e3f7923cf..681b305de6 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -661,7 +661,10 @@ static int mirror_exit_common(Job *job)
|
||||
s->target = NULL;
|
||||
|
||||
/* We don't access the source any more. Dropping any WRITE/RESIZE is
|
||||
- * required before it could become a backing file of target_bs. */
|
||||
+ * required before it could become a backing file of target_bs. Not having
|
||||
+ * these permissions any more means that we can't allow any new requests on
|
||||
+ * mirror_top_bs from now on, so keep it drained. */
|
||||
+ bdrv_drained_begin(mirror_top_bs);
|
||||
bs_opaque->stop = true;
|
||||
bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing,
|
||||
&error_abort);
|
||||
@@ -729,6 +732,7 @@ static int mirror_exit_common(Job *job)
|
||||
bs_opaque->job = NULL;
|
||||
|
||||
bdrv_drained_end(src);
|
||||
+ bdrv_drained_end(mirror_top_bs);
|
||||
s->in_drain = false;
|
||||
bdrv_unref(mirror_top_bs);
|
||||
bdrv_unref(src);
|
||||
--
|
||||
2.23.0
|
||||
@ -1,6 +1,6 @@
|
||||
From 6f7a7f18f4460b0891eabbe1ca69e599216427b7 Mon Sep 17 00:00:00 2001
|
||||
From 117082ef493e62e6e2cd972b309e0cd72682ab02 Mon Sep 17 00:00:00 2001
|
||||
From: Chen Qun <kuhn.chenqun@huawei.com>
|
||||
Date: Mon, 16 Mar 2020 14:26:06 +0800
|
||||
Date: Tue, 14 Apr 2020 19:50:59 +0800
|
||||
Subject: [PATCH] moniter: fix memleak in monitor_fdset_dup_fd_find_remove
|
||||
|
||||
When remove dup_fd in monitor_fdset_dup_fd_find_remove function,
|
||||
@ -25,14 +25,14 @@ Reported-by: Euler Robot <euler.robot@huawei.com>
|
||||
Signed-off-by: Chen Qun <kuhn.chenqun@huawei.com>
|
||||
(cherry picked from commit a661614de18c89f58cad3fc1bb8aab44e820183a)
|
||||
---
|
||||
monitor.c | 1 +
|
||||
monitor/misc.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index 4807bbe..b5b15b5 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -2596,6 +2596,7 @@ static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove)
|
||||
diff --git a/monitor/misc.c b/monitor/misc.c
|
||||
index 00338c00..0d6369ba 100644
|
||||
--- a/monitor/misc.c
|
||||
+++ b/monitor/misc.c
|
||||
@@ -1746,6 +1746,7 @@ static int64_t monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove)
|
||||
if (mon_fdset_fd_dup->fd == dup_fd) {
|
||||
if (remove) {
|
||||
QLIST_REMOVE(mon_fdset_fd_dup, next);
|
||||
@ -41,5 +41,4 @@ index 4807bbe..b5b15b5 100644
|
||||
monitor_fdset_cleanup(mon_fdset);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
2.23.0
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
From 32c6cb39cbadd6fc2026ff6311fcf58549f71d49 Mon Sep 17 00:00:00 2001
|
||||
From: Pan Nengyuan <pannengyuan@huawei.com>
|
||||
Date: Wed, 15 Apr 2020 14:29:04 +0800
|
||||
Subject: [PATCH] nbd: Fix regression with multiple meta contexts
|
||||
|
||||
Detected by a hang in the libnbd testsuite. If a client requests
|
||||
multiple meta contexts (both base:allocation and qemu:dirty-bitmap:x)
|
||||
at the same time, our attempt to silence a false-positive warning
|
||||
about a potential uninitialized variable introduced botched logic: we
|
||||
were short-circuiting the second context, and never sending the
|
||||
NBD_REPLY_FLAG_DONE. Combining two 'if' into one 'if/else' in
|
||||
bdf200a55 was wrong (I'm a bit embarrassed that such a change was my
|
||||
initial suggestion after the v1 patch, then I did not review the v2
|
||||
patch that actually got committed). Revert that, and instead silence
|
||||
the false positive warning by replacing 'return ret' with 'return 0'
|
||||
(the value it always has at that point in the code, even though it
|
||||
eluded the deduction abilities of the robot that reported the false
|
||||
positive).
|
||||
|
||||
Fixes: bdf200a5535
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
Message-Id: <20200206173832.130004-1-eblake@redhat.com>
|
||||
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
|
||||
(cherry picked from commit 73e064ccf09d908febc83761addcc6e76feabf78)
|
||||
---
|
||||
nbd/server.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index aefb07d..3630352 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -2304,15 +2304,22 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
|
||||
!client->export_meta.bitmap,
|
||||
NBD_META_ID_BASE_ALLOCATION,
|
||||
errp);
|
||||
- } else { /* client->export_meta.bitmap */
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ if (client->export_meta.bitmap) {
|
||||
ret = nbd_co_send_bitmap(client, request->handle,
|
||||
client->exp->export_bitmap,
|
||||
request->from, request->len,
|
||||
dont_fragment,
|
||||
true, NBD_META_ID_DIRTY_BITMAP, errp);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ return 0;
|
||||
} else {
|
||||
return nbd_send_generic_reply(client, request->handle, -EINVAL,
|
||||
"CMD_BLOCK_STATUS not negotiated",
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
102
pc-Don-t-make-die-id-mandatory-unless-necessary.patch
Normal file
102
pc-Don-t-make-die-id-mandatory-unless-necessary.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 7ebcd375ade505358c1c45542de22f188c599bdd Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Date: Fri, 16 Aug 2019 14:07:50 -0300
|
||||
Subject: [PATCH] pc: Don't make die-id mandatory unless necessary
|
||||
|
||||
We have this issue reported when using libvirt to hotplug CPUs:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1741451
|
||||
|
||||
Basically, libvirt is not copying die-id from
|
||||
query-hotpluggable-cpus, but die-id is now mandatory.
|
||||
|
||||
We could blame libvirt and say it is not following the documented
|
||||
interface, because we have this buried in the QAPI schema
|
||||
documentation:
|
||||
|
||||
> Note: currently there are 5 properties that could be present
|
||||
> but management should be prepared to pass through other
|
||||
> properties with device_add command to allow for future
|
||||
> interface extension. This also requires the filed names to be kept in
|
||||
> sync with the properties passed to -device/device_add.
|
||||
|
||||
But I don't think this would be reasonable from us. We can just
|
||||
make QEMU more flexible and let die-id to be omitted when there's
|
||||
no ambiguity. This will allow us to keep compatibility with
|
||||
existing libvirt versions.
|
||||
|
||||
Test case included to ensure we don't break this again.
|
||||
|
||||
Fixes: commit 176d2cda0dee ("i386/cpu: Consolidate die-id validity in smp context")
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Message-Id: <20190816170750.23910-1-ehabkost@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit fea374e7c8079563bca7c8fac895c6a880f76adc)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
hw/i386/pc.c | 8 ++++++
|
||||
tests/acceptance/pc_cpu_hotplug_props.py | 35 ++++++++++++++++++++++++
|
||||
2 files changed, 43 insertions(+)
|
||||
create mode 100644 tests/acceptance/pc_cpu_hotplug_props.py
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 549c437050..947f81070f 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -2403,6 +2403,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
int max_socket = (ms->smp.max_cpus - 1) /
|
||||
smp_threads / smp_cores / pcms->smp_dies;
|
||||
|
||||
+ /*
|
||||
+ * die-id was optional in QEMU 4.0 and older, so keep it optional
|
||||
+ * if there's only one die per socket.
|
||||
+ */
|
||||
+ if (cpu->die_id < 0 && pcms->smp_dies == 1) {
|
||||
+ cpu->die_id = 0;
|
||||
+ }
|
||||
+
|
||||
if (cpu->socket_id < 0) {
|
||||
error_setg(errp, "CPU socket-id is not set");
|
||||
return;
|
||||
diff --git a/tests/acceptance/pc_cpu_hotplug_props.py b/tests/acceptance/pc_cpu_hotplug_props.py
|
||||
new file mode 100644
|
||||
index 0000000000..08b7e632c6
|
||||
--- /dev/null
|
||||
+++ b/tests/acceptance/pc_cpu_hotplug_props.py
|
||||
@@ -0,0 +1,35 @@
|
||||
+#
|
||||
+# Ensure CPU die-id can be omitted on -device
|
||||
+#
|
||||
+# Copyright (c) 2019 Red Hat Inc
|
||||
+#
|
||||
+# Author:
|
||||
+# Eduardo Habkost <ehabkost@redhat.com>
|
||||
+#
|
||||
+# This library is free software; you can redistribute it and/or
|
||||
+# modify it under the terms of the GNU Lesser General Public
|
||||
+# License as published by the Free Software Foundation; either
|
||||
+# version 2 of the License, or (at your option) any later version.
|
||||
+#
|
||||
+# This library is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+# Lesser General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU Lesser General Public
|
||||
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
+#
|
||||
+
|
||||
+from avocado_qemu import Test
|
||||
+
|
||||
+class OmittedCPUProps(Test):
|
||||
+ """
|
||||
+ :avocado: tags=arch:x86_64
|
||||
+ """
|
||||
+ def test_no_die_id(self):
|
||||
+ self.vm.add_args('-nodefaults', '-S')
|
||||
+ self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8')
|
||||
+ self.vm.add_args('-cpu', 'qemu64')
|
||||
+ self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
|
||||
+ self.vm.launch()
|
||||
+ self.assertEquals(len(self.vm.command('query-cpus')), 2)
|
||||
--
|
||||
2.23.0
|
||||
39
pr-manager-Fix-invalid-g_free-crash-bug.patch
Normal file
39
pr-manager-Fix-invalid-g_free-crash-bug.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 57fdf4a13ff16d9d48a43f02a5e7b42e3d264f83 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Armbruster <armbru@redhat.com>
|
||||
Date: Thu, 22 Aug 2019 15:38:46 +0200
|
||||
Subject: [PATCH] pr-manager: Fix invalid g_free() crash bug
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
pr_manager_worker() passes its @opaque argument to g_free(). Wrong;
|
||||
it points to pr_manager_worker()'s automatic @data. Broken when
|
||||
commit 2f3a7ab39be converted @data from heap- to stack-allocated. Fix
|
||||
by deleting the g_free().
|
||||
|
||||
Fixes: 2f3a7ab39bec4ba8022dc4d42ea641165b004e3e
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 6b9d62c2a9e83bbad73fb61406f0ff69b46ff6f3)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
scsi/pr-manager.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c
|
||||
index ee43663576..0c866e8698 100644
|
||||
--- a/scsi/pr-manager.c
|
||||
+++ b/scsi/pr-manager.c
|
||||
@@ -39,7 +39,6 @@ static int pr_manager_worker(void *opaque)
|
||||
int fd = data->fd;
|
||||
int r;
|
||||
|
||||
- g_free(data);
|
||||
trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
|
||||
|
||||
/* The reference was taken in pr_manager_execute. */
|
||||
--
|
||||
2.23.0
|
||||
35
qcow2-Fix-QCOW2_COMPRESSED_SECTOR_MASK.patch
Normal file
35
qcow2-Fix-QCOW2_COMPRESSED_SECTOR_MASK.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 405deba14f6b61b9c557484b46e863308c8cf373 Mon Sep 17 00:00:00 2001
|
||||
From: Max Reitz <mreitz@redhat.com>
|
||||
Date: Mon, 28 Oct 2019 17:18:40 +0100
|
||||
Subject: [PATCH] qcow2: Fix QCOW2_COMPRESSED_SECTOR_MASK
|
||||
|
||||
Masks for L2 table entries should have 64 bit.
|
||||
|
||||
Fixes: b6c246942b14d3e0dec46a6c5868ed84e7dbea19
|
||||
Buglink: https://bugs.launchpad.net/qemu/+bug/1850000
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
||||
Message-id: 20191028161841.1198-2-mreitz@redhat.com
|
||||
Reviewed-by: Alberto Garcia <berto@igalia.com>
|
||||
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
||||
(cherry picked from commit 24552feb6ae2f615b76c2b95394af43901f75046)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
block/qcow2.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/qcow2.h b/block/qcow2.h
|
||||
index fc1b0d3c1e..359197f89f 100644
|
||||
--- a/block/qcow2.h
|
||||
+++ b/block/qcow2.h
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
/* Defined in the qcow2 spec (compressed cluster descriptor) */
|
||||
#define QCOW2_COMPRESSED_SECTOR_SIZE 512U
|
||||
-#define QCOW2_COMPRESSED_SECTOR_MASK (~(QCOW2_COMPRESSED_SECTOR_SIZE - 1))
|
||||
+#define QCOW2_COMPRESSED_SECTOR_MASK (~(QCOW2_COMPRESSED_SECTOR_SIZE - 1ULL))
|
||||
|
||||
/* Must be at least 2 to cover COW */
|
||||
#define MIN_L2_CACHE_SIZE 2 /* cache entries */
|
||||
--
|
||||
2.23.0
|
||||
71
qcow2-Fix-corruption-bug-in-qcow2_detect_metadata_pr.patch
Normal file
71
qcow2-Fix-corruption-bug-in-qcow2_detect_metadata_pr.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From 416a692e51b8b582407e30046ddcffbbe52ecf77 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 24 Oct 2019 16:26:58 +0200
|
||||
Subject: [PATCH] qcow2: Fix corruption bug in
|
||||
qcow2_detect_metadata_preallocation()
|
||||
|
||||
qcow2_detect_metadata_preallocation() calls qcow2_get_refcount() which
|
||||
requires s->lock to be taken to protect its accesses to the refcount
|
||||
table and refcount blocks. However, nothing in this code path actually
|
||||
took the lock. This could cause the same cache entry to be used by two
|
||||
requests at the same time, for different tables at different offsets,
|
||||
resulting in image corruption.
|
||||
|
||||
As it would be preferable to base the detection on consistent data (even
|
||||
though it's just heuristics), let's take the lock not only around the
|
||||
qcow2_get_refcount() calls, but around the whole function.
|
||||
|
||||
This patch takes the lock in qcow2_co_block_status() earlier and asserts
|
||||
in qcow2_detect_metadata_preallocation() that we hold the lock.
|
||||
|
||||
Fixes: 69f47505ee66afaa513305de0c1895a224e52c45
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reported-by: Michael Weiser <michael.weiser@gmx.de>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Tested-by: Michael Weiser <michael.weiser@gmx.de>
|
||||
Reviewed-by: Michael Weiser <michael.weiser@gmx.de>
|
||||
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
||||
(cherry picked from commit 5e9785505210e2477e590e61b1ab100d0ec22b01)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
block/qcow2-refcount.c | 2 ++
|
||||
block/qcow2.c | 3 ++-
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
|
||||
index ef965d7895..0d64bf5a5e 100644
|
||||
--- a/block/qcow2-refcount.c
|
||||
+++ b/block/qcow2-refcount.c
|
||||
@@ -3455,6 +3455,8 @@ int qcow2_detect_metadata_preallocation(BlockDriverState *bs)
|
||||
int64_t i, end_cluster, cluster_count = 0, threshold;
|
||||
int64_t file_length, real_allocation, real_clusters;
|
||||
|
||||
+ qemu_co_mutex_assert_locked(&s->lock);
|
||||
+
|
||||
file_length = bdrv_getlength(bs->file->bs);
|
||||
if (file_length < 0) {
|
||||
return file_length;
|
||||
diff --git a/block/qcow2.c b/block/qcow2.c
|
||||
index 865839682c..c0f5439dc8 100644
|
||||
--- a/block/qcow2.c
|
||||
+++ b/block/qcow2.c
|
||||
@@ -1899,6 +1899,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
||||
unsigned int bytes;
|
||||
int status = 0;
|
||||
|
||||
+ qemu_co_mutex_lock(&s->lock);
|
||||
+
|
||||
if (!s->metadata_preallocation_checked) {
|
||||
ret = qcow2_detect_metadata_preallocation(bs);
|
||||
s->metadata_preallocation = (ret == 1);
|
||||
@@ -1906,7 +1908,6 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
bytes = MIN(INT_MAX, count);
|
||||
- qemu_co_mutex_lock(&s->lock);
|
||||
ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
if (ret < 0) {
|
||||
--
|
||||
2.23.0
|
||||
58
qcow2-Fix-the-calculation-of-the-maximum-L2-cache-si.patch
Normal file
58
qcow2-Fix-the-calculation-of-the-maximum-L2-cache-si.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From c9ffb12754b1575babfef45168b6e1b1af80a95f Mon Sep 17 00:00:00 2001
|
||||
From: Alberto Garcia <berto@igalia.com>
|
||||
Date: Fri, 16 Aug 2019 15:17:42 +0300
|
||||
Subject: [PATCH] qcow2: Fix the calculation of the maximum L2 cache size
|
||||
|
||||
The size of the qcow2 L2 cache defaults to 32 MB, which can be easily
|
||||
larger than the maximum amount of L2 metadata that the image can have.
|
||||
For example: with 64 KB clusters the user would need a qcow2 image
|
||||
with a virtual size of 256 GB in order to have 32 MB of L2 metadata.
|
||||
|
||||
Because of that, since commit b749562d9822d14ef69c9eaa5f85903010b86c30
|
||||
we forbid the L2 cache to become larger than the maximum amount of L2
|
||||
metadata for the image, calculated using this formula:
|
||||
|
||||
uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
|
||||
|
||||
The problem with this formula is that the result should be rounded up
|
||||
to the cluster size because an L2 table on disk always takes one full
|
||||
cluster.
|
||||
|
||||
For example, a 1280 MB qcow2 image with 64 KB clusters needs exactly
|
||||
160 KB of L2 metadata, but we need 192 KB on disk (3 clusters) even if
|
||||
the last 32 KB of those are not going to be used.
|
||||
|
||||
However QEMU rounds the numbers down and only creates 2 cache tables
|
||||
(128 KB), which is not enough for the image.
|
||||
|
||||
A quick test doing 4KB random writes on a 1280 MB image gives me
|
||||
around 500 IOPS, while with the correct cache size I get 16K IOPS.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Alberto Garcia <berto@igalia.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit b70d08205b2e4044c529eefc21df2c8ab61b473b)
|
||||
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||
---
|
||||
block/qcow2.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/block/qcow2.c b/block/qcow2.c
|
||||
index 039bdc2f7e..865839682c 100644
|
||||
--- a/block/qcow2.c
|
||||
+++ b/block/qcow2.c
|
||||
@@ -826,7 +826,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
||||
bool l2_cache_entry_size_set;
|
||||
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
|
||||
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
|
||||
- uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
|
||||
+ uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);
|
||||
+ /* An L2 table is always one cluster in size so the max cache size
|
||||
+ * should be a multiple of the cluster size. */
|
||||
+ uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
|
||||
+ s->cluster_size);
|
||||
|
||||
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
|
||||
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
|
||||
--
|
||||
2.23.0
|
||||
Binary file not shown.
@ -1,75 +0,0 @@
|
||||
From 3283dde4b5b5cce0f96f48d536bebff66d97ce0b Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Tue, 23 Jul 2019 16:17:53 +0530
|
||||
Subject: [PATCH 2/2] qemu-bridge-helper: move repeating code in parse_acl_file
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Move repeating error handling sequence in parse_acl_file routine
|
||||
to an 'err' label.
|
||||
|
||||
This patch fixes CVE-2019-13164.
|
||||
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Reviewed-by: Li Qiang <liq3ea@gmail.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
(cherry-picked from commit 3283dde4b5b5cce0f96f48d536bebff66d97ce0b)
|
||||
---
|
||||
qemu-bridge-helper.c | 19 +++++++++----------
|
||||
1 file changed, 9 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
|
||||
index 2058e10454..3d50ec094c 100644
|
||||
--- a/qemu-bridge-helper.c
|
||||
+++ b/qemu-bridge-helper.c
|
||||
@@ -102,9 +102,7 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
|
||||
|
||||
if (arg == NULL) {
|
||||
fprintf(stderr, "Invalid config line:\n %s\n", line);
|
||||
- fclose(f);
|
||||
- errno = EINVAL;
|
||||
- return -1;
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
*arg = 0;
|
||||
@@ -121,9 +119,7 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
|
||||
|
||||
if (!g_str_equal(cmd, "include") && strlen(arg) >= IFNAMSIZ) {
|
||||
fprintf(stderr, "name `%s' too long: %zu\n", arg, strlen(arg));
|
||||
- fclose(f);
|
||||
- errno = EINVAL;
|
||||
- return -1;
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
if (strcmp(cmd, "deny") == 0) {
|
||||
@@ -149,15 +145,18 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
|
||||
parse_acl_file(arg, acl_list);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown command `%s'\n", cmd);
|
||||
- fclose(f);
|
||||
- errno = EINVAL;
|
||||
- return -1;
|
||||
+ goto err;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
-
|
||||
return 0;
|
||||
+
|
||||
+err:
|
||||
+ fclose(f);
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+
|
||||
}
|
||||
|
||||
static bool has_vnet_hdr(int fd)
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
From 6f5d8671225dc77190647f18a27a0d156d4ca97a Mon Sep 17 00:00:00 2001
|
||||
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Date: Tue, 23 Jul 2019 16:17:52 +0530
|
||||
Subject: [PATCH 1/2] qemu-bridge-helper: restrict interface name to IFNAMSIZ
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The network interface name in Linux is defined to be of size
|
||||
IFNAMSIZ(=16), including the terminating null('\0') byte.
|
||||
The same is applied to interface names read from 'bridge.conf'
|
||||
file to form ACL rules. If user supplied '--br=bridge' name
|
||||
is not restricted to the same length, it could lead to ACL bypass
|
||||
issue. Restrict interface name to IFNAMSIZ, including null byte.
|
||||
|
||||
This patch fixes CVE-2019-13164.
|
||||
|
||||
Reported-by: Riccardo Schirone <rschiron@redhat.com>
|
||||
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Reviewed-by: Li Qiang <liq3ea@gmail.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
(cherry-picked from commit 6f5d8671225dc77190647f18a27a0d156d4ca97a)
|
||||
---
|
||||
qemu-bridge-helper.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
|
||||
index 95624bc300..2058e10454 100644
|
||||
--- a/qemu-bridge-helper.c
|
||||
+++ b/qemu-bridge-helper.c
|
||||
@@ -119,6 +119,13 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
|
||||
}
|
||||
*argend = 0;
|
||||
|
||||
+ if (!g_str_equal(cmd, "include") && strlen(arg) >= IFNAMSIZ) {
|
||||
+ fprintf(stderr, "name `%s' too long: %zu\n", arg, strlen(arg));
|
||||
+ fclose(f);
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (strcmp(cmd, "deny") == 0) {
|
||||
acl_rule = g_malloc(sizeof(*acl_rule));
|
||||
if (strcmp(arg, "all") == 0) {
|
||||
@@ -269,6 +276,10 @@ int main(int argc, char **argv)
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
+ if (strlen(bridge) >= IFNAMSIZ) {
|
||||
+ fprintf(stderr, "name `%s' too long: %zu\n", bridge, strlen(bridge));
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
|
||||
/* parse default acl file */
|
||||
QSIMPLEQ_INIT(&acl_list);
|
||||
--
|
||||
2.19.1
|
||||
|
||||
398
qemu.spec
398
qemu.spec
@ -1,6 +1,6 @@
|
||||
Name: qemu
|
||||
Version: 4.0.1
|
||||
Release: 11
|
||||
Version: 4.1.0
|
||||
Release: 13
|
||||
Epoch: 2
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY
|
||||
@ -10,60 +10,170 @@ Source1: 80-kvm.rules
|
||||
Source2: 99-qemu-guest-agent.rules
|
||||
Source3: bridge.conf
|
||||
|
||||
Patch0001: qxl-check-release-info-object.patch
|
||||
Patch0002: ARM64-record-vtimer-tick-when-cpu-is-stopped.patch
|
||||
Patch0003: pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch
|
||||
Patch0004: pl031-support-rtc-timer-property-for-pl031.patch
|
||||
Patch0005: vhost-cancel-migration-when-vhost-user-restarted.patch
|
||||
Patch0006: qcow2-fix-memory-leak-in-qcow2_read_extensions.patch
|
||||
Patch0007: hw-arm-expose-host-CPU-frequency-info-to-guest.patch
|
||||
Patch0008: qemu-bridge-helper-restrict-interface-name-to-IFNAMS.patch
|
||||
Patch0009: qemu-bridge-helper-move-repeating-code-in-parse_acl.patch
|
||||
Patch0010: smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch
|
||||
Patch0011: hw-arm-virt-Introduce-cpu-topology-support.patch
|
||||
Patch0012: hw-arm64-add-vcpu-cache-info-support.patch
|
||||
Patch0013: xhci-Fix-memory-leak-in-xhci_address_slot.patch
|
||||
Patch0014: xhci-Fix-memory-leak-in-xhci_kick_epctx.patch
|
||||
Patch0015: ehci-fix-queue-dev-null-ptr-dereference.patch
|
||||
Patch0016: memory-unref-the-memory-region-in-simplify-flatview.patch
|
||||
Patch0017: util-async-hold-AioContext-ref-to-prevent-use-after-free.patch
|
||||
Patch0018: vhost-user-scsi-prevent-using-uninitialized-vqs.patch
|
||||
Patch0019: cpu-add-Kunpeng-920-cpu-support.patch
|
||||
Patch0020: cpu-parse-feature-to-avoid-failure.patch
|
||||
Patch0021: cpu-add-Cortex-A72-processor-kvm-target-support.patch
|
||||
Patch0022: vnc-fix-memory-leak-when-vnc-disconnect.patch
|
||||
Patch0023: pcie-disable-the-PCI_EXP_LINKSTA_DLLA-cap.patch
|
||||
Patch0024: linux-headers-update-against-KVM-ARM-Fix-256-vcpus.patch
|
||||
Patch0025: intc-arm_gic-Support-IRQ-injection-for-more-than-256.patch
|
||||
Patch0026: ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch
|
||||
Patch0027: 9pfs-local-Fix-possible-memory-leak-in-local_link.patch
|
||||
Patch0028: scsi-disk-define-props-in-scsi_block_disk-to-avoid-memleaks.patch
|
||||
Patch0029: arm-translate-a64-fix-uninitialized-variable-warning.patch
|
||||
Patch0030: nbd-fix-uninitialized-variable-warning.patch
|
||||
Patch0031: xhci-Fix-memory-leak-in-xhci_kick_epctx-when-poweroff.patch
|
||||
Patch0032: block-fix-memleaks-in-bdrv_refresh_filename.patch
|
||||
Patch0033: iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
|
||||
Patch0034: tcp_emu-Fix-oob-access.patch
|
||||
Patch0035: slirp-use-correct-size-while-emulating-IRC-commands.patch
|
||||
Patch0036: slirp-use-correct-size-while-emulating-commands.patch
|
||||
Patch0037: tcp_emu-fix-unsafe-snprintf-usages.patch
|
||||
Patch0038: block-iscsi-use-MIN-between-mx_sb_len-and-sb_len_wr.patch
|
||||
Patch0039: monitor-fix-memory-leak-in-monitor_fdset_dup_fd_find.patch
|
||||
Patch0001: pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch
|
||||
Patch0002: pl031-support-rtc-timer-property-for-pl031.patch
|
||||
Patch0003: vhost-cancel-migration-when-vhost-user-restarted.patch
|
||||
Patch0004: qcow2-fix-memory-leak-in-qcow2_read_extensions.patch
|
||||
Patch0005: bios-tables-test-prepare-to-change-ARM-virt-ACPI-DSDT.patch
|
||||
Patch0006: hw-arm-expose-host-CPU-frequency-info-to-guest.patch
|
||||
Patch0007: smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch
|
||||
Patch0008: tests-bios-tables-test-disable-this-testcase.patch
|
||||
Patch0009: hw-arm-virt-Introduce-cpu-topology-support.patch
|
||||
Patch0010: hw-arm64-add-vcpu-cache-info-support.patch
|
||||
Patch0011: xhci-Fix-memory-leak-in-xhci_address_slot.patch
|
||||
Patch0012: xhci-Fix-memory-leak-in-xhci_kick_epctx.patch
|
||||
Patch0013: ehci-fix-queue-dev-null-ptr-dereference.patch
|
||||
Patch0014: util-async-hold-AioContext-ref-to-prevent-use-after-free.patch
|
||||
Patch0015: vhost-user-scsi-prevent-using-uninitialized-vqs.patch
|
||||
Patch0016: cpu-add-Kunpeng-920-cpu-support.patch
|
||||
Patch0017: cpu-parse-feature-to-avoid-failure.patch
|
||||
Patch0018: cpu-add-Cortex-A72-processor-kvm-target-support.patch
|
||||
Patch0019: pcie-disable-the-PCI_EXP_LINKSTA_DLLA-cap.patch
|
||||
Patch0020: vnc-fix-memory-leak-when-vnc-disconnect.patch
|
||||
Patch0021: linux-headers-update-against-KVM-ARM-Fix-256-vcpus.patch
|
||||
Patch0022: intc-arm_gic-Support-IRQ-injection-for-more-than-256.patch
|
||||
Patch0023: ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp.patch
|
||||
Patch0024: 9pfs-local-Fix-possible-memory-leak-in-local_link.patch
|
||||
Patch0025: scsi-disk-define-props-in-scsi_block_disk-to-avoid-memleaks.patch
|
||||
Patch0026: arm-translate-a64-fix-uninitialized-variable-warning.patch
|
||||
Patch0027: nbd-fix-uninitialized-variable-warning.patch
|
||||
Patch0028: xhci-Fix-memory-leak-in-xhci_kick_epctx-when-poweroff.patch
|
||||
Patch0029: block-fix-memleaks-in-bdrv_refresh_filename.patch
|
||||
Patch0030: iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
|
||||
Patch0031: tcp_emu-Fix-oob-access.patch
|
||||
Patch0032: slirp-use-correct-size-while-emulating-IRC-commands.patch
|
||||
Patch0033: slirp-use-correct-size-while-emulating-commands.patch
|
||||
Patch0034: util-add-slirp_fmt-helpers.patch
|
||||
Patch0035: tcp_emu-fix-unsafe-snprintf-usages.patch
|
||||
Patch0036: block-iscsi-use-MIN-between-mx_sb_len-and-sb_len_wr.patch
|
||||
Patch0037: monitor-fix-memory-leak-in-monitor_fdset_dup_fd_find.patch
|
||||
Patch0038: memory-Align-MemoryRegionSections-fields.patch
|
||||
Patch0039: memory-Provide-an-equality-function-for-MemoryRegion.patch
|
||||
Patch0040: vhost-Fix-memory-region-section-comparison.patch
|
||||
Patch0041: memory-Align-MemoryRegionSections-fields.patch
|
||||
Patch0042: memory-Provide-an-equality-function-for-MemoryRegion.patch
|
||||
Patch0043: file-posix-Handle-undetectable-alignment.patch
|
||||
Patch0044: block-backup-fix-max_transfer-handling-for-copy_rang.patch
|
||||
Patch0045: block-backup-fix-backup_cow_with_offload-for-last-cl.patch
|
||||
Patch0046: qcow2-Limit-total-allocation-range-to-INT_MAX.patch
|
||||
Patch0047: mirror-Do-not-dereference-invalid-pointers.patch
|
||||
Patch0048: COLO-compare-Fix-incorrect-if-logic.patch
|
||||
Patch0049: qcow2-bitmap-Fix-uint64_t-left-shift-overflow.patch
|
||||
Patch0050: pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch
|
||||
Patch0051: pcie-Compat-with-devices-which-do-not-support-Link-W.patch
|
||||
Patch0052: aio-wait-delegate-polling-of-main-AioContext-if-BQL-not-held.patch
|
||||
Patch0053: async-use-explicit-memory-barriers.patch
|
||||
Patch0054: nbd-Fix-regression-with-multiple-meta-contexts.patch
|
||||
Patch0041: file-posix-Handle-undetectable-alignment.patch
|
||||
Patch0042: block-backup-fix-max_transfer-handling-for-copy_rang.patch
|
||||
Patch0043: block-backup-fix-backup_cow_with_offload-for-last-cl.patch
|
||||
Patch0044: qcow2-Limit-total-allocation-range-to-INT_MAX.patch
|
||||
Patch0045: mirror-Do-not-dereference-invalid-pointers.patch
|
||||
Patch0046: COLO-compare-Fix-incorrect-if-logic.patch
|
||||
Patch0047: qcow2-bitmap-Fix-uint64_t-left-shift-overflow.patch
|
||||
Patch0048: pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch
|
||||
Patch0049: pcie-Compat-with-devices-which-do-not-support-Link-W.patch
|
||||
Patch0050: aio-wait-delegate-polling-of-main-AioContext-if-BQL-not-held.patch
|
||||
Patch0051: async-use-explicit-memory-barriers.patch
|
||||
Patch0052: dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch
|
||||
Patch0053: Revert-ide-ahci-Check-for-ECANCELED-in-aio-callbacks.patch
|
||||
Patch0054: pc-Don-t-make-die-id-mandatory-unless-necessary.patch
|
||||
Patch0055: block-file-posix-Reduce-xfsctl-use.patch
|
||||
Patch0056: pr-manager-Fix-invalid-g_free-crash-bug.patch
|
||||
Patch0057: x86-do-not-advertise-die-id-in-query-hotpluggbale-cp.patch
|
||||
Patch0058: vpc-Return-0-from-vpc_co_create-on-success.patch
|
||||
Patch0059: target-arm-Free-TCG-temps-in-trans_VMOV_64_sp.patch
|
||||
Patch0060: target-arm-Don-t-abort-on-M-profile-exception-return.patch
|
||||
Patch0061: libvhost-user-fix-SLAVE_SEND_FD-handling.patch
|
||||
Patch0062: qcow2-Fix-the-calculation-of-the-maximum-L2-cache-si.patch
|
||||
Patch0063: block-nfs-tear-down-aio-before-nfs_close.patch
|
||||
Patch0064: blockjob-update-nodes-head-while-removing-all-bdrv.patch
|
||||
Patch0065: block-qcow2-Fix-corruption-introduced-by-commit-8ac0.patch
|
||||
Patch0066: coroutine-Add-qemu_co_mutex_assert_locked.patch
|
||||
Patch0067: qcow2-Fix-corruption-bug-in-qcow2_detect_metadata_pr.patch
|
||||
Patch0068: hw-arm-boot.c-Set-NSACR.-CP11-CP10-for-NS-kernel-boo.patch
|
||||
Patch0069: make-release-pull-in-edk2-submodules-so-we-can-build.patch
|
||||
Patch0070: roms-Makefile.edk2-don-t-pull-in-submodules-when-bui.patch
|
||||
Patch0071: block-snapshot-Restrict-set-of-snapshot-nodes.patch
|
||||
Patch0072: vhost-user-save-features-if-the-char-dev-is-closed.patch
|
||||
Patch0073: hw-core-loader-Fix-possible-crash-in-rom_copy.patch
|
||||
Patch0074: ui-Fix-hanging-up-Cocoa-display-on-macOS-10.15-Catal.patch
|
||||
Patch0075: virtio-new-post_load-hook.patch
|
||||
Patch0076: virtio-net-prevent-offloads-reset-on-migration.patch
|
||||
Patch0077: util-hbitmap-strict-hbitmap_reset.patch
|
||||
Patch0078: hbitmap-handle-set-reset-with-zero-length.patch
|
||||
Patch0079: target-arm-Allow-reading-flags-from-FPSCR-for-M-prof.patch
|
||||
Patch0080: scsi-lsi-exit-infinite-loop-while-executing-script-C.patch
|
||||
Patch0081: virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch
|
||||
Patch0082: qcow2-Fix-QCOW2_COMPRESSED_SECTOR_MASK.patch
|
||||
Patch0083: util-iov-introduce-qemu_iovec_init_extended.patch
|
||||
Patch0084: util-iov-improve-qemu_iovec_is_zero.patch
|
||||
Patch0085: block-io-refactor-padding.patch
|
||||
Patch0086: block-Make-wait-mark-serialising-requests-public.patch
|
||||
Patch0087: block-Add-bdrv_co_get_self_request.patch
|
||||
Patch0088: block-file-posix-Let-post-EOF-fallocate-serialize.patch
|
||||
Patch0089: block-posix-Always-allocate-the-first-block.patch
|
||||
Patch0090: block-create-Do-not-abort-if-a-block-driver-is-not-a.patch
|
||||
Patch0091: mirror-Keep-mirror_top_bs-drained-after-dropping-per.patch
|
||||
Patch0092: target-arm-kvm-trivial-Clean-up-header-documentation.patch
|
||||
Patch0093: target-arm-kvm64-kvm64-cpus-have-timer-registers.patch
|
||||
Patch0094: target-arm-kvm-Implement-virtual-time-adjustment.patch
|
||||
Patch0095: target-arm-cpu-Add-the-kvm-no-adjvtime-CPU-property.patch
|
||||
Patch0096: hw-acpi-Make-ACPI-IO-address-space-configurable.patch
|
||||
Patch0097: hw-acpi-Do-not-create-memory-hotplug-method-when-han.patch
|
||||
Patch0098: hw-acpi-Add-ACPI-Generic-Event-Device-Support.patch
|
||||
Patch0099: hw-arm-virt-Add-memory-hotplug-framework.patch
|
||||
Patch0100: hw-arm-virt-Enable-device-memory-cold-hot-plug-with-.patch
|
||||
Patch0101: hw-arm-virt-acpi-build-Add-PC-DIMM-in-SRAT.patch
|
||||
Patch0102: hw-arm-Factor-out-powerdown-notifier-from-GPIO.patch
|
||||
Patch0103: hw-arm-Use-GED-for-system_powerdown-event.patch
|
||||
Patch0104: docs-specs-Add-ACPI-GED-documentation.patch
|
||||
Patch0105: tests-Update-ACPI-tables-list-for-upcoming-arm-virt-.patch
|
||||
Patch0106: tests-acpi-add-empty-files.patch
|
||||
Patch0107: tests-allow-empty-expected-files.patch
|
||||
Patch0108: tests-Add-bios-tests-to-arm-virt.patch
|
||||
Patch0109: tests-document-how-to-update-acpi-tables.patch
|
||||
Patch0110: hw-arm-virt-Simplify-by-moving-the-gic-in-the-machin.patch
|
||||
Patch0111: bugfix-Use-gicr_typer-in-arm_gicv3_icc_reset.patch
|
||||
Patch0112: Typo-Correct-the-name-of-CPU-hotplug-memory-region.patch
|
||||
Patch0113: acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch
|
||||
Patch0114: acpi-ged-Add-virt_madt_cpu_entry-to-madt_cpu-hook.patch
|
||||
Patch0115: arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch
|
||||
Patch0116: acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch
|
||||
Patch0117: acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch
|
||||
Patch0118: arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch
|
||||
Patch0119: arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch
|
||||
Patch0120: arm-virt-Add-CPU-hotplug-framework.patch
|
||||
Patch0121: arm-virt-Add-CPU-topology-support.patch
|
||||
Patch0122: test-numa-Adjust-aarch64-numa-test.patch
|
||||
Patch0123: hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch
|
||||
Patch0124: hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch
|
||||
Patch0125: arm-virt-gic-Construct-irqs-connection-from-create_g.patch
|
||||
Patch0126: intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch
|
||||
Patch0127: intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch
|
||||
Patch0128: intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch
|
||||
Patch0129: hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch
|
||||
Patch0130: accel-kvm-Add-pre-park-vCPU-support.patch
|
||||
Patch0131: intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch
|
||||
Patch0132: acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch
|
||||
Patch0133: arm-virt-Add-cpu_hotplug_enabled-field.patch
|
||||
Patch0134: arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch
|
||||
Patch0135: arm-virt-Pre-sizing-MADT-GICC-PPTT-GICv3-and-Pre-par.patch
|
||||
Patch0136: arm-virt-Add-some-sanity-checks-in-cpu_pre_plug-hook.patch
|
||||
Patch0137: arm-virt-Start-up-CPU-hot-plug.patch
|
||||
Patch0138: migration-always-initialise-ram_counters-for-a-new-m.patch
|
||||
Patch0139: migration-add-qemu_file_update_transfer-interface.patch
|
||||
Patch0140: migration-add-speed-limit-for-multifd-migration.patch
|
||||
Patch0141: migration-update-ram_counters-for-multifd-sync-packe.patch
|
||||
Patch0142: migration-Make-global-sem_sync-semaphore-by-channel.patch
|
||||
Patch0143: migration-multifd-fix-nullptr-access-in-terminating-m.patch
|
||||
Patch0144: migration-Maybe-VM-is-paused-when-migration-is-cance.patch
|
||||
Patch0145: migration-multifd-fix-potential-wrong-acception-orde.patch
|
||||
Patch0146: migration-multifd-fix-destroyed-mutex-access-in-term.patch
|
||||
Patch0147: migration-multifd-fix-nullptr-access-in-multifd_send.patch
|
||||
Patch0148: vtimer-compat-cross-version-migration-from-v4.0.1.patch
|
||||
Patch0149: migration-ram-Do-error_free-after-migrate_set_error-.patch
|
||||
Patch0150: migration-ram-fix-memleaks-in-multifd_new_send_chann.patch
|
||||
Patch0151: migration-rdma-fix-a-memleak-on-error-path-in-rdma_s.patch
|
||||
Patch0152: arm-virt-Support-CPU-cold-plug.patch
|
||||
Patch0153: ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch
|
||||
Patch0154: ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch
|
||||
Patch0155: slirp-tftp-restrict-relative-path-access.patch
|
||||
Patch0156: ip_reass-Fix-use-after-free.patch
|
||||
Patch0157: bt-use-size_t-type-for-length-parameters-instead-of-.patch
|
||||
Patch0158: log-Add-some-logs-on-VM-runtime-path.patch
|
||||
Patch0159: Revert-vtimer-compat-cross-version-migration-from-v4.patch
|
||||
Patch0160: ARM64-record-vtimer-tick-when-cpu-is-stopped.patch
|
||||
Patch0161: hw-arm-virt-add-missing-compat-for-kvm-no-adjvtime.patch
|
||||
Patch0162: migration-Compat-virtual-timer-adjust-for-v4.0.1-and.patch
|
||||
Patch0163: vtimer-Drop-vtimer-virtual-timer-adjust.patch
|
||||
Patch0164: target-arm-Add-the-kvm_adjvtime-vcpu-property-for-Co.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: bison
|
||||
@ -250,7 +360,9 @@ install -D -m 0644 %{_sourcedir}/99-qemu-guest-agent.rules %{buildroot}%{_udevdi
|
||||
mkdir -p %{buildroot}%{_localstatedir}/log
|
||||
touch %{buildroot}%{_localstatedir}/log/qga-fsfreeze-hook.log
|
||||
|
||||
# For qemu docs package
|
||||
%global qemudocdir %{_docdir}/%{name}
|
||||
rm -rf %{buildroot}%{qemudocdir}/specs
|
||||
install -D -p -m 0644 -t %{buildroot}%{qemudocdir} Changelog README COPYING COPYING.LIB LICENSE
|
||||
chmod -x %{buildroot}%{_mandir}/man1/*
|
||||
|
||||
@ -265,6 +377,9 @@ rm -rf %{buildroot}%{_datadir}/%{name}/multiboot.bin
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/linuxboot_dma.bin
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/pvh.bin
|
||||
%endif
|
||||
%ifarch x86_64
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/vgabios-ati.bin
|
||||
%endif
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/openbios-*
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/slof.bin
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/QEMU,*.bin
|
||||
@ -280,6 +395,11 @@ rm -rf %{buildroot}%{_datadir}/%{name}/skiboot.lid
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/spapr-*
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/u-boot*
|
||||
rm -rf %{buildroot}%{_bindir}/ivshmem*
|
||||
rm -f %{buildroot}%{_datadir}/%{name}/edk2*
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/firmware
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/opensbi*
|
||||
rm -rf %{buildroot}%{_datadir}/%{name}/qemu-nsis.bmp
|
||||
|
||||
|
||||
for f in %{buildroot}%{_bindir}/* %{buildroot}%{_libdir}/* \
|
||||
%{buildroot}%{_libexecdir}/*; do
|
||||
@ -399,96 +519,146 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Apr 9 2020 backport nbd fix from qemu upstream
|
||||
- nbd: Fix regression with multiple meta contexts
|
||||
* Fri May 29 Huawei Technologies Co., Ltd <fangying1@huawei.com>
|
||||
- target/arm: Add the kvm_adjvtime vcpu property for Cortex-A72
|
||||
|
||||
* Sat Apr 11 4 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
* Wed May 27 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- Revert: "vtimer: compat cross version migration from v4.0.1"
|
||||
- ARM64: record vtimer tick when cpu is stopped
|
||||
- hw/arm/virt: add missing compat for kvm-no-adjvtime
|
||||
- migration: Compat virtual timer adjust for v4.0.1 and v4.1.0
|
||||
- vtimer: Drop vtimer virtual timer adjust
|
||||
|
||||
* Fri May 22 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- ip_reass: Fix use after free
|
||||
- bt: use size_t type for length parameters instead of int
|
||||
- log: Add some logs on VM runtime path
|
||||
|
||||
* Fri May 15 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- ide: Fix incorrect handling of some PRDTs in ide_dma_cb()
|
||||
- ati-vga: Fix checks in ati_2d_blt() to avoid crash
|
||||
- slirp: tftp: restrict relative path access
|
||||
|
||||
* Tue May 12 2020 Huawei Technologies Co., Ltd. <zhukeqian1@huawei.com>
|
||||
- arm/virt: Support CPU cold plug
|
||||
|
||||
* Sat May 9 2020 Huawei Technologies Co., Ltd. <pannengyuan@huawei.com>
|
||||
- migration/ram: do error_free after migrate_set_error to avoid memleaks.
|
||||
- migration/ram: fix memleaks in multifd_new_send_channel_async.
|
||||
- migration/rdma: fix a memleak on error path in rdma_start_incoming_migration.
|
||||
|
||||
* Fri May 8 2020 Huawei Technologies Co., Ltd. <zhengchuan@huawei.com>
|
||||
- vtimer: compat cross version migration from v4.0.1
|
||||
|
||||
* Fri Apr 24 2020 Huawei Technologies Co., Ltd. <zhengchuan@huawei.com>
|
||||
- migration: backport migration patches from upstream
|
||||
|
||||
* Fri Apr 24 2020 Huawei Technologies Co., Ltd. <zhukeqian1@huawei.com>
|
||||
- arm/virt: Add CPU hotplug support
|
||||
|
||||
* Wed Apr 22 2020 Huawei Technologies Co., Ltd. <zhukeqian1@huawei.com>
|
||||
- backport patch to enable arm/virt memory hotplug
|
||||
|
||||
* Wed Apr 22 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- backport patch to enable target/arm/kvm Adjust virtual time
|
||||
|
||||
* Fri Apr 17 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- backport patch bundles from qemu stable v4.1.1
|
||||
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- aio-wait: delegate polling of main AioContext if BQL not held
|
||||
- async: use explicit memory barriers
|
||||
|
||||
* Wed Mar 18 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- pcie: Add pcie-root-port fast plug/unplug feature
|
||||
- pcie: Compat with devices which do not support Link Width
|
||||
- pcie: Compat with devices which do not support Link Width, such as ioh3420
|
||||
|
||||
* Tue Mar 17 2020 Huawei Technologies Co., Ltd. <zhang.zhanghailiang@huawei.com>
|
||||
- Put linuxboot_dma.bin and pvh.bin in x86 package
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- qcow2-bitmap: Fix uint64_t left-shift overflow
|
||||
|
||||
* Mon Mar 16 2020 backport some bug fix patches from upstream
|
||||
- Patch from number 0040 to 0049 are picked from stable-4.1.1
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- COLO-compare: Fix incorrect `if` logic
|
||||
|
||||
* Mon Mar 16 2020 Huawei Technologies Co., Ltd. <kuhn.chenqun@huawei.com>
|
||||
- moniter: fix memleak in monitor_fdset_dup_fd_find_remove
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- block/backup: fix max_transfer handling for copy_range
|
||||
- block/backup: fix backup_cow_with_offload for last cluster
|
||||
- qcow2: Limit total allocation range to INT_MAX
|
||||
- mirror: Do not dereference invalid pointers
|
||||
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- file-posix: Handle undetectable alignment
|
||||
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- vhost: Fix memory region section comparison
|
||||
- memory: Provide an equality function for MemoryRegionSections
|
||||
- memory: Align MemoryRegionSections fields
|
||||
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- block/iscsi: use MIN() between mx_sb_len and sb_len_wr
|
||||
- moniter: fix memleak in monitor_fdset_dup_fd_find_remove
|
||||
|
||||
* Wed Mar 11 2020 backport from qemu upstream
|
||||
- tcp_emu: Fix oob access
|
||||
- slirp: use correct size while emulating IRC commands
|
||||
- slirp: use correct size while emulating commands
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- tcp_emu: fix unsafe snprintf() usages
|
||||
|
||||
* Mon Mar 9 2020 backport from qemu upstream
|
||||
- util: add slirp_fmt() helpers
|
||||
- slirp: use correct size while emulating commands
|
||||
- slirp: use correct size while emulating IRC commands
|
||||
- tcp_emu: Fix oob access
|
||||
- iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711)
|
||||
|
||||
* Thu Feb 6 2020 Huawei Technologies Co., Ltd. <zhang.zhanghailiang@huawei.com>
|
||||
- spec: remove fno-inline option for configure
|
||||
|
||||
* Thu Jan 16 2020 Huawei Technologies Co., Ltd. <pannengyuan@huawei.com>
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- 9pfs: local: Fix possible memory leak in local_link()
|
||||
- scsi-disk: define props in scsi_block_disk to avoid memleaks
|
||||
- arm/translate-a64: fix uninitialized variable warning
|
||||
- block: fix memleaks in bdrv_refresh_filename
|
||||
- vnc: fix memory leak when vnc disconnect
|
||||
- block: fix memleaks in bdrv_refresh_filename
|
||||
|
||||
* Mon Jan 13 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- 9pfs: Fix a possible memory leak in local_link
|
||||
- scsi-disk: disk define props in scsi_block to avoid memleaks
|
||||
- arm/translate-a64: fix uninitialized variable warning
|
||||
- nbd: fix uninitialized variable warning
|
||||
- xhci: Fix memory leak in xhci_kick_epctx when poweroff
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- linux headers: update against "KVM/ARM: Fix >256 vcpus"
|
||||
- intc/arm_gic: Support IRQ injection for more than 256 vcpus
|
||||
- ARM: KVM: Check KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 for smp_cpus >
|
||||
|
||||
* Mon Jan 6 2020 backport from qemu upstream
|
||||
- linux headers: update against "KVM/ARM: Fix >256 vcp
|
||||
- intc/arm_gic: Support IRQ injection for more than 256 vpus
|
||||
- ARM: KVM: Check KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 for smp_cpus > 256
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- vnc: fix memory leak when vnc disconnect
|
||||
|
||||
* Thu Dec 12 2019 backport from qemu upstream v4.0.1 release
|
||||
- tpm: Exit in reset when backend indicates failure
|
||||
- tpm_emulator: Translate TPM error codes to strings
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- pcie: disable the PCI_EXP_LINKSTA_DLLA cap for pcie-root-port by default
|
||||
|
||||
* Thu Oct 17 2019 backport from qemu upstream
|
||||
- vnc-fix-memory-leak-when-vnc-disconnect.patch
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- cpu: add Kunpeng-920 cpu support
|
||||
- cpu: parse +/- feature to avoid failure
|
||||
- cpu: add Cortex-A72 processor kvm target support
|
||||
|
||||
* Mon Sep 9 2019 backport from qemu upstream
|
||||
- ehci-fix-queue-dev-null-ptr-dereference.patch
|
||||
- memory-unref-the-memory-region-in-simplify-flatview.patch
|
||||
- util-async-hold-AioContext-ref-to-prevent-use-after-.patch
|
||||
- vhost-user-scsi-prevent-using-uninitialized-vqs.patch
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- vhost-user-scsi: prevent using uninitialized vqs
|
||||
|
||||
* Fri Aug 30 2019 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- util/async: hold AioContext ref to prevent use-after-free
|
||||
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- xhci: Fix memory leak in xhci_address_slot
|
||||
- xhci: Fix memory leak in xhci_kick_epctx
|
||||
- ehci: fix queue->dev null ptr dereference
|
||||
|
||||
* Wed Aug 7 2019 Huawei Technologies Co., Ltd. <zhang.zhanghailiang@huawei.com>
|
||||
* Thu Apr 16 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- tests/bios-tables-test: disable this testcase
|
||||
- hw/arm/virt: Introduce cpu topology support
|
||||
- hw/arm64: add vcpu cache info support
|
||||
|
||||
* Tue Aug 6 2019 Huawei Technologies Co., Ltd. <zhang.zhanghailiang@huawei.com>
|
||||
- Update release version to 4.0.0-2
|
||||
|
||||
* Mon Aug 5 2019 Huawei Technologies Co., Ltd. <zhang.zhanghailiang@huawei.com>
|
||||
- enable make check
|
||||
* Wed Apr 15 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- smbios: Add missing member of type 4 for smbios 3.0
|
||||
|
||||
* Mon Aug 5 2019 fix CVE-2019-13164
|
||||
- qemu-bridge-helper: restrict interface name to IFNAMSIZ
|
||||
- qemu-bridge-helper: move repeating code in parse_acl_file
|
||||
* Wed Apr 15 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- bios-tables-test: prepare to change ARM virt ACPI DSDT
|
||||
- arm64: Add the cpufreq device to show cpufreq info to guest
|
||||
|
||||
* Tue Jul 30 2019 Huawei Technologies Co., Ltd. <zhang.zhanghailiang@huawei.com
|
||||
* Wed Apr 15 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- qcow2: fix memory leak in qcow2_read_extensions
|
||||
- hw/arm: expose host CPU frequency info to guest
|
||||
|
||||
* Fri Jul 26 2019 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- vhost: cancel migration when vhost-user restarted
|
||||
* Wed Apr 15 2020 Huawei Technologies Co., Ltd. <fangying1@huawei.com>
|
||||
- pl011: reset read FIFIO when UARTTIMSC=0 & UARTICR=0xff
|
||||
- pl031: support rtc-timer property for pl031
|
||||
- pl011: reset read FIFO when UARTTIMSC=0 & UARTICR=0xffff
|
||||
- ARM64: record vtimer tick when cpu is stopped
|
||||
- vhost: cancel migration when vhost-user restarted
|
||||
|
||||
* Tue Jul 23 2019 openEuler Buildteam <buildteam@openeuler.org> - version-release
|
||||
* Mon Apr 13 2020 openEuler Buildteam <buildteam@openeuler.org> - version-release
|
||||
- Package init
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user