mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-01 09:42:45 +00:00
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
231 lines
8.2 KiB
Diff
231 lines
8.2 KiB
Diff
From e9ec5f6617c1811f244618e3a23c29ea2fb27c6a Mon Sep 17 00:00:00 2001
|
|
From: Huang Shijie <shijie8@gmail.com>
|
|
Date: Thu, 16 Dec 2021 11:36:25 +0800
|
|
Subject: [PATCH 28/28] armcpuhp: fix bug when maxvcpu number larger than 8
|
|
|
|
The gic version finalized after the use the gic version in
|
|
virt_cpu_mp_affinity. But VIRT_GICVERSION_HOST must be determined before
|
|
used it. So, must call finalize_gic_version before used gic_version.
|
|
|
|
For now cpu socket and thread is not supported, thus we need set thread
|
|
and socket to 1 if they are larger than 1.
|
|
|
|
Signed-off-by: Huang Shijie <shijie8@gmail.com>
|
|
Signed-off-by: Huang Shijie <shijie8@gmail.com>
|
|
---
|
|
hw/arm/virt.c | 183 ++++++++++++++++++++++++++++----------------------
|
|
1 file changed, 102 insertions(+), 81 deletions(-)
|
|
|
|
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
|
index 5c04abb352..23dd2337f6 100644
|
|
--- a/hw/arm/virt.c
|
|
+++ b/hw/arm/virt.c
|
|
@@ -1661,85 +1661,6 @@ void virt_machine_done(Notifier *notifier, void *data)
|
|
virt_remove_disabled_cpus(vms);
|
|
}
|
|
|
|
-static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
|
|
-{
|
|
- uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
|
|
- VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
-
|
|
- if (!vmc->disallow_affinity_adjustment) {
|
|
- /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
|
|
- * GIC's target-list limitations. 32-bit KVM hosts currently
|
|
- * always create clusters of 4 CPUs, but that is expected to
|
|
- * change when they gain support for gicv3. When KVM is enabled
|
|
- * it will override the changes we make here, therefore our
|
|
- * purposes are to make TCG consistent (with 64-bit KVM hosts)
|
|
- * and to improve SGI efficiency.
|
|
- */
|
|
- if (vms->gic_version == VIRT_GIC_VERSION_3) {
|
|
- clustersz = GICV3_TARGETLIST_BITS;
|
|
- } else {
|
|
- clustersz = GIC_TARGETLIST_BITS;
|
|
- }
|
|
- }
|
|
- return arm_cpu_mp_affinity(idx, clustersz);
|
|
-}
|
|
-
|
|
-static void virt_set_memmap(VirtMachineState *vms)
|
|
-{
|
|
- MachineState *ms = MACHINE(vms);
|
|
- hwaddr base, device_memory_base, device_memory_size;
|
|
- int i;
|
|
-
|
|
- vms->memmap = extended_memmap;
|
|
-
|
|
- for (i = 0; i < ARRAY_SIZE(base_memmap); i++) {
|
|
- vms->memmap[i] = base_memmap[i];
|
|
- }
|
|
-
|
|
- if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
|
|
- error_report("unsupported number of memory slots: %"PRIu64,
|
|
- ms->ram_slots);
|
|
- exit(EXIT_FAILURE);
|
|
- }
|
|
-
|
|
- /*
|
|
- * We compute the base of the high IO region depending on the
|
|
- * amount of initial and device memory. The device memory start/size
|
|
- * is aligned on 1GiB. We never put the high IO region below 256GiB
|
|
- * so that if maxram_size is < 255GiB we keep the legacy memory map.
|
|
- * The device region size assumes 1GiB page max alignment per slot.
|
|
- */
|
|
- device_memory_base =
|
|
- ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB);
|
|
- device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * GiB;
|
|
-
|
|
- /* Base address of the high IO region */
|
|
- base = device_memory_base + ROUND_UP(device_memory_size, GiB);
|
|
- if (base < device_memory_base) {
|
|
- error_report("maxmem/slots too huge");
|
|
- exit(EXIT_FAILURE);
|
|
- }
|
|
- if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
|
|
- base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
|
|
- }
|
|
-
|
|
- for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
|
|
- hwaddr size = extended_memmap[i].size;
|
|
-
|
|
- base = ROUND_UP(base, size);
|
|
- vms->memmap[i].base = base;
|
|
- vms->memmap[i].size = size;
|
|
- base += size;
|
|
- }
|
|
- vms->highest_gpa = base - 1;
|
|
- if (device_memory_size > 0) {
|
|
- ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
|
|
- ms->device_memory->base = device_memory_base;
|
|
- memory_region_init(&ms->device_memory->mr, OBJECT(vms),
|
|
- "device-memory", device_memory_size);
|
|
- }
|
|
-}
|
|
-
|
|
/*
|
|
* finalize_gic_version - Determines the final gic_version
|
|
* according to the gic-version property
|
|
@@ -1839,6 +1760,88 @@ static void finalize_gic_version(VirtMachineState *vms)
|
|
}
|
|
}
|
|
|
|
+static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
|
|
+{
|
|
+ uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
|
|
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
+
|
|
+ if(vms->gic_version == VIRT_GIC_VERSION_HOST)
|
|
+ finalize_gic_version(vms);
|
|
+
|
|
+ if (!vmc->disallow_affinity_adjustment) {
|
|
+ /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
|
|
+ * GIC's target-list limitations. 32-bit KVM hosts currently
|
|
+ * always create clusters of 4 CPUs, but that is expected to
|
|
+ * change when they gain support for gicv3. When KVM is enabled
|
|
+ * it will override the changes we make here, therefore our
|
|
+ * purposes are to make TCG consistent (with 64-bit KVM hosts)
|
|
+ * and to improve SGI efficiency.
|
|
+ */
|
|
+ if (vms->gic_version == VIRT_GIC_VERSION_3) {
|
|
+ clustersz = GICV3_TARGETLIST_BITS;
|
|
+ } else {
|
|
+ clustersz = GIC_TARGETLIST_BITS;
|
|
+ }
|
|
+ }
|
|
+ return arm_cpu_mp_affinity(idx, clustersz);
|
|
+}
|
|
+
|
|
+static void virt_set_memmap(VirtMachineState *vms)
|
|
+{
|
|
+ MachineState *ms = MACHINE(vms);
|
|
+ hwaddr base, device_memory_base, device_memory_size;
|
|
+ int i;
|
|
+
|
|
+ vms->memmap = extended_memmap;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(base_memmap); i++) {
|
|
+ vms->memmap[i] = base_memmap[i];
|
|
+ }
|
|
+
|
|
+ if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
|
|
+ error_report("unsupported number of memory slots: %"PRIu64,
|
|
+ ms->ram_slots);
|
|
+ exit(EXIT_FAILURE);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * We compute the base of the high IO region depending on the
|
|
+ * amount of initial and device memory. The device memory start/size
|
|
+ * is aligned on 1GiB. We never put the high IO region below 256GiB
|
|
+ * so that if maxram_size is < 255GiB we keep the legacy memory map.
|
|
+ * The device region size assumes 1GiB page max alignment per slot.
|
|
+ */
|
|
+ device_memory_base =
|
|
+ ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB);
|
|
+ device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * GiB;
|
|
+
|
|
+ /* Base address of the high IO region */
|
|
+ base = device_memory_base + ROUND_UP(device_memory_size, GiB);
|
|
+ if (base < device_memory_base) {
|
|
+ error_report("maxmem/slots too huge");
|
|
+ exit(EXIT_FAILURE);
|
|
+ }
|
|
+ if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
|
|
+ base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
|
|
+ }
|
|
+
|
|
+ for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
|
|
+ hwaddr size = extended_memmap[i].size;
|
|
+
|
|
+ base = ROUND_UP(base, size);
|
|
+ vms->memmap[i].base = base;
|
|
+ vms->memmap[i].size = size;
|
|
+ base += size;
|
|
+ }
|
|
+ vms->highest_gpa = base - 1;
|
|
+ if (device_memory_size > 0) {
|
|
+ ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
|
|
+ ms->device_memory->base = device_memory_base;
|
|
+ memory_region_init(&ms->device_memory->mr, OBJECT(vms),
|
|
+ "device-memory", device_memory_size);
|
|
+ }
|
|
+}
|
|
+
|
|
static void virt_cpu_set_properties(Object *cpuobj, const CPUArchId *cpu_slot)
|
|
{
|
|
MachineState *ms = MACHINE(qdev_get_machine());
|
|
@@ -2928,9 +2931,27 @@ static void virt_smp_parse(MachineState *ms, SMPConfiguration *config, Error **e
|
|
unsigned threads = config->has_threads ? config->threads: 1;
|
|
unsigned int max_cpus;
|
|
|
|
+ if(config->has_cores) {
|
|
+ config->cores = cpus;
|
|
+ cores = cpus;
|
|
+ }
|
|
if (sockets > 1 || threads > 1) {
|
|
- error_report("does not support more than one socket or thread");
|
|
- exit(1);
|
|
+ printf("does not support more than one socket or thread, will put sockets and threads to cores");
|
|
+ if(config->has_cores) {
|
|
+ if(config->has_sockets && config->has_threads) {
|
|
+ threads = 1;
|
|
+ sockets = 1;
|
|
+ config->sockets = 1;
|
|
+ config->threads = 1;
|
|
+ } else if (config->has_sockets) {
|
|
+ sockets = 1;
|
|
+ config->sockets = 1;
|
|
+ } else {
|
|
+ config->threads = 1;
|
|
+ threads = 1;
|
|
+ }
|
|
+ } else
|
|
+ exit(1);
|
|
}
|
|
|
|
if (cores != cpus) {
|
|
--
|
|
2.30.2
|
|
|