All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@siemens.com>
To: kvm-devel <kvm-devel@lists.sourceforge.net>
Subject: [PATCH] qemu-kvm: fix guest resetting
Date: Thu, 08 May 2008 10:29:32 +0200	[thread overview]
Message-ID: <4822B9EC.3020907@siemens.com> (raw)

Resetting guests used to be racy, deadlock-prone, or simply broken (for
SMP). This patch fixes the issues - at least for me on x86 (tested on
Intel SMP host, UP and SMP guest, in-kernel und user space irqchip,
guest- and monitor-issued resets). Note that ia64 and powerpc may need
to look into the SMP thing as well (=>kvm_arch_cpu_reset).

At this chance, the patch also cleans up some unneeded reset fragments.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 qemu/qemu-kvm-ia64.c    |    4 ++++
 qemu/qemu-kvm-powerpc.c |    4 ++++
 qemu/qemu-kvm-x86.c     |   16 ++++++++++++++++
 qemu/qemu-kvm.c         |   38 ++++++++++++++++++--------------------
 qemu/qemu-kvm.h         |    1 +
 qemu/vl.c               |   11 ++++++-----
 6 files changed, 49 insertions(+), 25 deletions(-)

Index: b/qemu/qemu-kvm.c
===================================================================
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -28,8 +28,6 @@ kvm_context_t kvm_context;
 
 extern int smp_cpus;
 
-static int qemu_kvm_reset_requested;
-
 pthread_mutex_t qemu_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t qemu_aio_cond = PTHREAD_COND_INITIALIZER;
 pthread_cond_t qemu_vcpu_cond = PTHREAD_COND_INITIALIZER;
@@ -56,7 +54,6 @@ struct vcpu_info {
     int signalled;
     int stop;
     int stopped;
-    int reload_regs;
     int created;
 } vcpu_info[256];
 
@@ -257,17 +254,20 @@ static int all_threads_paused(void)
 
 static void pause_all_threads(void)
 {
+    CPUState *cpu_single = cpu_single_env;
     int i;
 
-    for (i = 0; i < smp_cpus; ++i) {
-	vcpu_info[i].stop = 1;
-	pthread_kill(vcpu_info[i].thread, SIG_IPI);
-    }
+    for (i = 0; i < smp_cpus; ++i)
+	if (!cpu_single || cpu_single->cpu_index != i) {
+	    vcpu_info[i].stop = 1;
+	    pthread_kill(vcpu_info[i].thread, SIG_IPI);
+	}
+
     while (!all_threads_paused()) {
 	pthread_mutex_unlock(&qemu_mutex);
-	kvm_eat_signal(&io_signal_table, NULL, 1000);
+	kvm_eat_signal(&io_signal_table, cpu_single, 1000);
 	pthread_mutex_lock(&qemu_mutex);
-	cpu_single_env = NULL;
+	cpu_single_env = cpu_single;
     }
 }
 
@@ -317,11 +317,18 @@ void qemu_kvm_system_reset_request(void)
 {
     int i;
 
+    pause_all_threads();
+
+    qemu_system_reset();
+
+    for (i = 0; i < smp_cpus; ++i)
+	kvm_arch_cpu_reset(vcpu_info[i].env);
+
     for (i = 0; i < smp_cpus; ++i) {
-	vcpu_info[i].reload_regs = 1;
+	vcpu_info[i].stop = 0;
+	vcpu_info[i].stopped = 0;
 	pthread_kill(vcpu_info[i].thread, SIG_IPI);
     }
-    qemu_system_reset();
 }
 
 static int kvm_main_loop_cpu(CPUState *env)
@@ -354,11 +361,6 @@ static int kvm_main_loop_cpu(CPUState *e
 	    kvm_cpu_exec(env);
 	env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
 	kvm_main_loop_wait(env, 0);
-        if (info->reload_regs) {
-	    info->reload_regs = 0;
-	    if (env->cpu_index == 0) /* ap needs to be placed in INIT */
-		kvm_arch_load_regs(env);
-	}
     }
     pthread_mutex_unlock(&qemu_mutex);
     return 0;
@@ -467,10 +469,6 @@ int kvm_main_loop(void)
             break;
         else if (qemu_powerdown_requested())
             qemu_system_powerdown();
-        else if (qemu_reset_requested()) {
-            pthread_kill(vcpu_info[0].thread, SIG_IPI);
-            qemu_kvm_reset_requested = 1;
-        }
         pthread_mutex_unlock(&qemu_mutex);
     }
 
Index: b/qemu/qemu-kvm-ia64.c
===================================================================
--- a/qemu/qemu-kvm-ia64.c
+++ b/qemu/qemu-kvm-ia64.c
@@ -61,3 +61,7 @@ int kvm_arch_try_push_interrupts(void *o
 void kvm_arch_update_regs_for_sipi(CPUState *env)
 {
 }
+
+void kvm_arch_cpu_reset(CPUState *env)
+{
+}
Index: b/qemu/qemu-kvm-powerpc.c
===================================================================
--- a/qemu/qemu-kvm-powerpc.c
+++ b/qemu/qemu-kvm-powerpc.c
@@ -213,3 +213,7 @@ int handle_powerpc_dcr_write(int vcpu, u
 
     return 0; /* XXX ignore failed DCR ops */
 }
+
+void kvm_arch_cpu_reset(CPUState *env)
+{
+}
Index: b/qemu/qemu-kvm-x86.c
===================================================================
--- a/qemu/qemu-kvm-x86.c
+++ b/qemu/qemu-kvm-x86.c
@@ -689,3 +689,19 @@ int handle_tpr_access(void *opaque, int 
     kvm_tpr_access_report(cpu_single_env, rip, is_write);
     return 0;
 }
+
+void kvm_arch_cpu_reset(CPUState *env)
+{
+    struct kvm_mp_state mp_state = { .mp_state = KVM_MP_STATE_UNINITIALIZED };
+
+    kvm_arch_load_regs(env);
+    if (env->cpu_index != 0) {
+	if (kvm_irqchip_in_kernel(kvm_context))
+	    kvm_set_mpstate(kvm_context, env->cpu_index, &mp_state);
+	else {
+	    env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+	    env->hflags |= HF_HALTED_MASK;
+	    env->exception_index = EXCP_HLT;
+	}
+    }
+}
Index: b/qemu/qemu-kvm.h
===================================================================
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -55,6 +55,7 @@ void kvm_arch_post_kvm_run(void *opaque,
 int kvm_arch_has_work(CPUState *env);
 int kvm_arch_try_push_interrupts(void *opaque);
 void kvm_arch_update_regs_for_sipi(CPUState *env);
+void kvm_arch_cpu_reset(CPUState *env);
 
 CPUState *qemu_kvm_cpu_env(int index);
 
Index: b/qemu/vl.c
===================================================================
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -7235,6 +7235,12 @@ void qemu_system_reset(void)
 
 void qemu_system_reset_request(void)
 {
+#ifdef USE_KVM
+    if (kvm_allowed && !no_reboot) {
+        qemu_kvm_system_reset_request();
+        return;
+    }
+#endif
     if (no_reboot) {
         shutdown_requested = 1;
     } else {
@@ -7242,11 +7248,6 @@ void qemu_system_reset_request(void)
     }
     if (cpu_single_env)
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KVM
-    if (kvm_allowed)
-        if (!no_reboot)
-            qemu_kvm_system_reset_request();
-#endif
 }
 
 void qemu_system_shutdown_request(void)

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

             reply	other threads:[~2008-05-08  8:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-08  8:29 Jan Kiszka [this message]
2008-05-08 23:35 ` [PATCH] qemu-kvm: fix guest resetting Marcelo Tosatti
2008-05-09  8:13   ` Jan Kiszka
2008-05-09 16:59     ` Marcelo Tosatti
2008-05-09 18:46       ` Anthony Liguori
2008-05-10  8:26         ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4822B9EC.3020907@siemens.com \
    --to=jan.kiszka@siemens.com \
    --cc=kvm-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.