Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Qemu: Enable the vcpu-hotplug for arm
Initially enable vcpu hotplug in qemu for arm base on Salli's work[1]. Fixes:#3280 Signed-off-by: Huang Shijie <shijie8@gmail.com> [1] https://github.com/salil-mehta/qemu/tree/virt-cpuhp-armv8/rfc-v1
- Loading branch information
Showing
29 changed files
with
4,177 additions
and
0 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
.../packaging/qemu/patches/6.1.x/0001-arm-cpuhp-Add-QMP-vcpu-params-validation-support.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
From cbc35b3747ff8c50e64e3b8aeecf1b782ee27cad Mon Sep 17 00:00:00 2001 | ||
From: Huang Shijie <shijie8@gmail.com> | ||
Date: Mon, 22 Nov 2021 17:51:11 +0800 | ||
Subject: [PATCH 01/28] arm/cpuhp: Add QMP vcpu params validation support | ||
|
||
From Salil Mehta <salil.mehta@huawei.com> | ||
For now, vcpu hotplug is only supported with single socket single thread, | ||
single die. NUMA is not supported either and everthing falls into single | ||
node. Work to properly support these could be taken later once community | ||
agrees with the base framework changes being presented to support ARM vcpu | ||
hotplug in QEMU. Hence, these checks. | ||
|
||
Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com> | ||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com> | ||
Signed-off-by: Huang Shijie <shijie8@gmail.com> | ||
--- | ||
hw/arm/virt.c | 39 +++++++++++++++++++++++++++++++++++++++ | ||
1 file changed, 39 insertions(+) | ||
|
||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c | ||
index 81eda46b0b..99d59fada2 100644 | ||
--- a/hw/arm/virt.c | ||
+++ b/hw/arm/virt.c | ||
@@ -2564,6 +2564,44 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, | ||
return NULL; | ||
} | ||
|
||
+static void virt_smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp) | ||
+{ | ||
+ unsigned cpus = config->has_cpus ? config->cpus : 1; | ||
+ unsigned sockets = config->has_sockets ? config->sockets: 1; | ||
+ unsigned cores = config->has_cores ? config->cores : cpus; | ||
+ unsigned threads = config->has_threads ? config->threads: 1; | ||
+ unsigned int max_cpus; | ||
+ | ||
+ if (sockets > 1 || threads > 1) { | ||
+ error_report("does not support more than one socket or thread"); | ||
+ exit(1); | ||
+ } | ||
+ | ||
+ if (cores != cpus) { | ||
+ error_report("cpu topology: " | ||
+ "sockets (%u) * cores (%u) * threads (%u) < " | ||
+ "smp_cpus (%u)", | ||
+ sockets, cores, threads, cpus); | ||
+ exit(1); | ||
+ } | ||
+ | ||
+ max_cpus = config->has_maxcpus ? config->maxcpus : cpus; | ||
+ if (sockets * cores * threads > max_cpus) { | ||
+ error_report("cpu topology: " | ||
+ "sockets (%u) * cores (%u) * threads (%u) > " | ||
+ "maxcpus (%u)", | ||
+ sockets, cores, threads, | ||
+ max_cpus); | ||
+ exit(1); | ||
+ } | ||
+ | ||
+ ms->smp.max_cpus = max_cpus; | ||
+ ms->smp.sockets = sockets; | ||
+ ms->smp.cpus = cpus; | ||
+ ms->smp.cores = cores; | ||
+ ms->smp.threads = threads; | ||
+} | ||
+ | ||
/* | ||
* for arm64 kvm_type [7-0] encodes the requested number of bits | ||
* in the IPA address space | ||
@@ -2641,6 +2679,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) | ||
mc->auto_enable_numa_with_memhp = true; | ||
mc->auto_enable_numa_with_memdev = true; | ||
mc->default_ram_id = "mach-virt.ram"; | ||
+ mc->smp_parse = virt_smp_parse; | ||
|
||
object_class_property_add(oc, "acpi", "OnOffAuto", | ||
virt_get_acpi, virt_set_acpi, | ||
-- | ||
2.30.2 | ||
|
101 changes: 101 additions & 0 deletions
101
tools/packaging/qemu/patches/6.1.x/0002-arm-cpuhp-Add-new-ARMCPU-core-id-property.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
From a24ce04b7c2e958a0730f19e6f54e6570a075b20 Mon Sep 17 00:00:00 2001 | ||
From: Salil Mehta <salil.mehta@huawei.com> | ||
Date: Tue, 23 Nov 2021 15:08:45 +0800 | ||
Subject: [PATCH 02/28] arm/cpuhp: Add new ARMCPU core-id property | ||
|
||
This shall be used to store user specified core index and shall be directly | ||
used as slot-index during hot{plug|unplug} of vcpu. | ||
|
||
For now, we are not taking into account of other topology info like thread-id, | ||
socket-id to derive mp-affinity. Host KVM uses vcpu-id to derive the mpidr for | ||
the vcpu of the guest. This is not in exact corroboration with the ARM spec | ||
view of the MPIDR. Hence, the concept of threads or SMT bit present as part of | ||
the MPIDR_EL1 also gets lost. | ||
|
||
Also, we need ACPI PPTT Table support in QEMU to be able to export this | ||
topology info to the guest VM and the info should be consistent with what host | ||
cpu supports if accel=kvm is being used. | ||
|
||
Perhaps some comments on this will help? @Andrew/drjones@redhat.com | ||
|
||
Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com> | ||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com> | ||
Signed-off-by: Huang Shijie <shijie8@gmail.com> | ||
--- | ||
hw/arm/virt.c | 5 +++++ | ||
target/arm/cpu.c | 5 +++++ | ||
target/arm/cpu.h | 1 + | ||
3 files changed, 11 insertions(+) | ||
|
||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c | ||
index 99d59fada2..86e1470925 100644 | ||
--- a/hw/arm/virt.c | ||
+++ b/hw/arm/virt.c | ||
@@ -1944,6 +1944,7 @@ static void machvirt_init(MachineState *machine) | ||
&error_fatal); | ||
|
||
aarch64 &= object_property_get_bool(cpuobj, "aarch64", NULL); | ||
+ object_property_set_int(cpuobj, "core-id", n, NULL); | ||
|
||
if (!vms->secure) { | ||
object_property_set_bool(cpuobj, "has_el3", false, NULL); | ||
@@ -2357,6 +2358,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) | ||
{ | ||
int n; | ||
unsigned int max_cpus = ms->smp.max_cpus; | ||
+ unsigned int smp_threads = ms->smp.threads; | ||
VirtMachineState *vms = VIRT_MACHINE(ms); | ||
|
||
if (ms->possible_cpus) { | ||
@@ -2369,10 +2371,13 @@ 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 = smp_threads; | ||
ms->possible_cpus->cpus[n].arch_id = | ||
virt_cpu_mp_affinity(vms, n); | ||
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.has_core_id = true; | ||
+ ms->possible_cpus->cpus[n].props.core_id = n; | ||
} | ||
return ms->possible_cpus; | ||
} | ||
diff --git a/target/arm/cpu.c b/target/arm/cpu.c | ||
index 2866dd7658..5dc3fa6c3a 100644 | ||
--- a/target/arm/cpu.c | ||
+++ b/target/arm/cpu.c | ||
@@ -1130,6 +1130,9 @@ static Property arm_cpu_has_dsp_property = | ||
static Property arm_cpu_has_mpu_property = | ||
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); | ||
|
||
+static Property arm_cpu_coreid_property = | ||
+ DEFINE_PROP_INT32("core-id", ARMCPU, core_id, -1); | ||
+ | ||
/* This is like DEFINE_PROP_UINT32 but it doesn't set the default value, | ||
* because the CPU initfn will have already set cpu->pmsav7_dregion to | ||
* the right value for that particular CPU type, and we don't want | ||
@@ -1303,6 +1306,8 @@ void arm_cpu_post_init(Object *obj) | ||
kvm_arm_add_vcpu_properties(obj); | ||
} | ||
|
||
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_coreid_property); | ||
+ | ||
#ifndef CONFIG_USER_ONLY | ||
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && | ||
cpu_isar_feature(aa64_mte, cpu)) { | ||
diff --git a/target/arm/cpu.h b/target/arm/cpu.h | ||
index 9f0a5f84d5..ba11468ab5 100644 | ||
--- a/target/arm/cpu.h | ||
+++ b/target/arm/cpu.h | ||
@@ -999,6 +999,7 @@ struct ARMCPU { | ||
QLIST_HEAD(, ARMELChangeHook) el_change_hooks; | ||
|
||
int32_t node_id; /* NUMA node this CPU belongs to */ | ||
+ int32_t core_id; /* core-id of this ARM VCPU */ | ||
|
||
/* Used to synchronize KVM and QEMU in-kernel device levels */ | ||
uint8_t device_irq_level; | ||
-- | ||
2.30.2 | ||
|
97 changes: 97 additions & 0 deletions
97
...ckaging/qemu/patches/6.1.x/0003-arm-cpuhp-Add-common-cpu-utility-for-possible-vcpus.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
From cf832166791bddea562ba9372795db04ea41a581 Mon Sep 17 00:00:00 2001 | ||
From: Salil Mehta <salil.mehta@huawei.com> | ||
Date: Tue, 23 Nov 2021 15:22:27 +0800 | ||
Subject: [PATCH 03/28] arm/cpuhp: Add common cpu utility for possible vcpus | ||
|
||
Adds various utility functions which might be required to fetch or check the | ||
state of the possible vcpus. This also introduces concept of *disabled* vcpus, | ||
which are part of the *possible* vcpus but are not part of the *present* vcpu. | ||
This state shall be used during machine init time to check the presence of | ||
vcpus. | ||
|
||
Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com> | ||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com> | ||
--- | ||
cpus-common.c | 19 +++++++++++++++++++ | ||
include/hw/core/cpu.h | 21 +++++++++++++++++++++ | ||
2 files changed, 40 insertions(+) | ||
|
||
diff --git a/cpus-common.c b/cpus-common.c | ||
index 6e73d3e58d..4f0fa42a2e 100644 | ||
--- a/cpus-common.c | ||
+++ b/cpus-common.c | ||
@@ -23,6 +23,7 @@ | ||
#include "hw/core/cpu.h" | ||
#include "sysemu/cpus.h" | ||
#include "qemu/lockable.h" | ||
+#include "hw/boards.h" | ||
|
||
static QemuMutex qemu_cpu_list_lock; | ||
static QemuCond exclusive_cond; | ||
@@ -86,6 +87,24 @@ void cpu_list_add(CPUState *cpu) | ||
QTAILQ_INSERT_TAIL_RCU(&cpus, cpu, node); | ||
} | ||
|
||
+CPUState *qemu_get_possible_cpu(int index) | ||
+{ | ||
+ MachineState *ms = MACHINE(qdev_get_machine()); | ||
+ const CPUArchIdList *possible_cpus = ms->possible_cpus; | ||
+ CPUState *cpu; | ||
+ | ||
+ assert((index >= 0) && (index < possible_cpus->len)); | ||
+ | ||
+ cpu = CPU(possible_cpus->cpus[index].cpu); | ||
+ | ||
+ return cpu; | ||
+} | ||
+ | ||
+bool qemu_present_cpu(CPUState *cpu) | ||
+{ | ||
+ return (cpu && !cpu->disabled); | ||
+} | ||
+ | ||
void cpu_list_remove(CPUState *cpu) | ||
{ | ||
QEMU_LOCK_GUARD(&qemu_cpu_list_lock); | ||
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h | ||
index bc864564ce..5a2571af3e 100644 | ||
--- a/include/hw/core/cpu.h | ||
+++ b/include/hw/core/cpu.h | ||
@@ -391,6 +391,7 @@ struct CPUState { | ||
SavedIOTLB saved_iotlb; | ||
#endif | ||
|
||
+ bool disabled; | ||
/* TODO Move common fields from CPUArchState here. */ | ||
int cpu_index; | ||
int cluster_index; | ||
@@ -749,6 +750,26 @@ static inline bool cpu_in_exclusive_context(const CPUState *cpu) | ||
*/ | ||
CPUState *qemu_get_cpu(int index); | ||
|
||
+/** | ||
+ * qemu_get_possible_cpu: | ||
+ * @index: The CPUState@cpu_index value of the CPU to obtain. | ||
+ * | ||
+ * Gets a CPU matching @index. | ||
+ * | ||
+ * Returns: The possible CPU or %NULL if there is no matching CPU. | ||
+ */ | ||
+CPUState *qemu_get_possible_cpu(int index); | ||
+ | ||
+/** | ||
+ * qemu_present_cpu: | ||
+ * @cpu: The vCPU to check | ||
+ * | ||
+ * Checks if the vcpu is amongst the present possible vcpus. | ||
+ * | ||
+ * Returns: True if it is present possible vcpu else false | ||
+ */ | ||
+bool qemu_present_cpu(CPUState *cpu); | ||
+ | ||
/** | ||
* cpu_exists: | ||
* @id: Guest-exposed CPU ID to lookup. | ||
-- | ||
2.30.2 | ||
|
Oops, something went wrong.