diff mbox

[RFC,qom-cpu,v2,6/8] i386: implement pc interface pc_hot_del_cpu()

Message ID 974bab7bbd33238e4a80d870735bd80e5e3eb646.1378796990.git.chen.fan.fnst@cn.fujitsu.com
State New
Headers show

Commit Message

chenfan Sept. 10, 2013, 9:43 a.m. UTC
Implement cpu interface pc_hot_del_cpu() for unrealizing device vCPU.
emiting vcpu-remove notifier to ACPI, then ACPI could send sci interrupt
to OS for hot-remove vcpu.

Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
---
 hw/i386/pc.c | 29 ++++++++++++++++++++++++++++-
 qom/cpu.c    | 11 +++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f36903f..6f88e41 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -959,7 +959,34 @@  void pc_hot_add_cpu(const int64_t id, Error **errp)
 
 void pc_hot_del_cpu(const int64_t id, Error **errp)
 {
-    /* TODO: hot remove vCPU. */
+    CPUState *cpu;
+    bool found = false;
+    X86CPUClass *xcc;
+
+    CPU_FOREACH(cpu) {
+        CPUClass *cc = CPU_GET_CLASS(cpu);
+        int64_t cpuid = cc->get_arch_id(cpu);
+
+        if (cpuid == id) {
+            found = true;
+            break;
+        }
+    }
+
+    if (!found) {
+        error_setg(errp, "Unable to find cpu-index: %" PRIi64
+                   ", it doesn't exist or has been deleted.", id);
+        return;
+    }
+
+    if (cpu == first_cpu && !CPU_NEXT(cpu)) {
+        error_setg(errp, "Unable to delete the last"
+                   " cpu when VM running.");
+        return;
+    }
+
+    xcc = X86_CPU_GET_CLASS(DEVICE(cpu));
+    xcc->parent_unrealize(DEVICE(cpu), errp);
 }
 
 void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
diff --git a/qom/cpu.c b/qom/cpu.c
index c6d7ebc..9cd7fcd 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -227,6 +227,16 @@  static void cpu_common_realizefn(DeviceState *dev, Error **errp)
     }
 }
 
+static void cpu_common_unrealizefn(DeviceState *dev, Error **errp)
+{
+    CPUNotifier notifier;
+
+    notifier.dev = dev;
+    notifier.type = UNPLUG;
+
+    notifier_list_notify(&cpu_hotplug_notifiers, &notifier);
+}
+
 static void cpu_common_initfn(Object *obj)
 {
     CPUState *cpu = CPU(obj);
@@ -257,6 +267,7 @@  static void cpu_class_init(ObjectClass *klass, void *data)
     k->gdb_read_register = cpu_common_gdb_read_register;
     k->gdb_write_register = cpu_common_gdb_write_register;
     dc->realize = cpu_common_realizefn;
+    dc->unrealize = cpu_common_unrealizefn;
     dc->no_user = 1;
 }