Signed-off-by: Anthony Liguori<address@hidden>
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);