diff mbox

qemu-kvm: introduce cpu_start/cpu_stop commands

Message ID 1290466818-5230-1-git-send-email-aliguori@us.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Anthony Liguori Nov. 22, 2010, 11 p.m. UTC
None
diff mbox

Patch

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ba6de28..827bd67 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -279,6 +279,24 @@  Resume emulation.
 ETEXI
 
     {
+        .name       = "cpu_start",
+        .args_type  = "cpu:i",
+        .params     = "[cpu]",
+        .help       = "start cpu emulation",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_vcpu_start,
+    },
+
+    {
+        .name       = "cpu_stop",
+        .args_type  = "cpu:i",
+        .params     = "[cpu]",
+        .help       = "stop cpu emulation",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_vcpu_stop,
+    },
+
+    {
         .name       = "gdbserver",
         .args_type  = "device:s?",
         .params     = "[device]",
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 471306b..35121ed 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1351,6 +1351,65 @@  static void pause_all_threads(void)
     }
 }
 
+static void vcpu_stop(int cpu)
+{
+    CPUState *env = first_cpu;
+
+    for (env = first_cpu; env; env = env->next_cpu) {
+        if (env->cpu_index == cpu) {
+            break;
+        }
+    }
+
+    if (env) {
+        if (env != cpu_single_env) {
+            env->stop = 1;
+            pthread_kill(env->kvm_cpu_state.thread, SIG_IPI);
+        } else {
+            env->stop = 0;
+            env->stopped = 1;
+            cpu_exit(env);
+        }
+
+        while (!env->stopped) {
+            qemu_cond_wait(&qemu_pause_cond);
+        }
+    }
+}
+
+static void vcpu_start(int cpu)
+{
+    CPUState *env = first_cpu;
+
+    assert(!cpu_single_env);
+
+    for (env = first_cpu; env; env = env->next_cpu) {
+        if (env->cpu_index == cpu) {
+            break;
+        }
+    }
+
+    if (env) {
+        env->stop = 0;
+        env->stopped = 0;
+        pthread_kill(env->kvm_cpu_state.thread, SIG_IPI);
+    }
+}
+
+int do_vcpu_stop(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    int vcpu = qdict_get_int(qdict, "cpu");
+    vcpu_stop(vcpu);
+    return 0;
+}
+
+int do_vcpu_start(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    int vcpu = qdict_get_int(qdict, "cpu");
+    vcpu_start(vcpu);
+    return 0;
+}
+
 static void resume_all_threads(void)
 {
     CPUState *penv = first_cpu;
diff --git a/sysemu.h b/sysemu.h
index 849dc8c..3ef68dd 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -61,6 +61,9 @@  void qemu_system_reset(void);
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
+int do_vcpu_stop(Monitor *mon, const QDict *qdict, QObject **ret_data);
+int do_vcpu_start(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
 void do_savevm(Monitor *mon, const QDict *qdict);
 int load_vmstate(const char *name);
 void do_delvm(Monitor *mon, const QDict *qdict);