@@ -824,6 +824,19 @@ static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
return arch_id;
}
+/* Find cpu slot in machine->possible_cpus by arch_id */
+static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
+{
+ int n;
+ for (n = 0; n < ms->possible_cpus->len; n++) {
+ if (ms->possible_cpus->cpus[n].arch_id == arch_id) {
+ return &ms->possible_cpus->cpus[n];
+ }
+ }
+
+ return NULL;
+}
+
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -832,11 +845,56 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
+ Error *err = NULL;
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+ CPUState *cs = CPU(dev);
+
+ if (cs->cpu_index == 0) {
+ error_setg(&err, "hot-unplug of boot cpu(id%d=%d:%d:%d) not supported",
+ cs->cpu_index, cpu->socket_id,
+ cpu->core_id, cpu->thread_id);
+ error_propagate(errp, err);
+ return;
+ }
+
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ }
}
static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ CPUArchId *cpu_slot;
+ Error *err = NULL;
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
+
+ /* Notify ipi and extioi irqchip to remove interrupt routing to CPU */
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->ipi), dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->extioi), dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ /* Notify acpi ged CPU removed */
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
+ cpu_slot->cpu = NULL;
+ return;
}
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
Implement cpu unplug interfaces including virt_cpu_unplug_request() and virt_cpu_unplug(). Co-developed-by: Xianglai Li <lixianglai@loongson.cn> Signed-off-by: Bibo Mao <maobibo@loongson.cn> --- hw/loongarch/virt.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+)