qemu/hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch
Keqian Zhu 1c823f0431 arm/virt: Add ACPI CPU hotplug support
This series is an attempt to provide CPU hotplug support on ARM
virt platform. This is based on ACPI GED device.

We should enable ACPI support, and use vGICv3 and 64bit CPU to
support CPU hotplug.

Under KVM accel, the KVM vCPUs is pre-created. Besides, vGIC IRIs
is pre-created too. However, QEMU vCPU objects are defer-created.

Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
2020-06-01 09:13:39 +00:00

116 lines
3.5 KiB
Diff

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