Skip to contentSkip to conversation

kvm-qemu: Proper vm_stop on debug events

PATCH In review Jan Kiszka 2 participants 3 messages May 23, 2008 KVM

lore
Share & tools
lore

Jan Kiszka

author
#0 lore raw

PATCH 1/1 kvm-qemu: Proper vm_stop on debug events

When a vcpu exits after hitting a debug exception, we have to invoke vm_stop(EXCP_DEBUG). But this has to take place over the io-thread.

This patch introduces kvm_debug_stop_requested to signal this event, and it takes care that the interrupted vcpu itself goes immediately into stop state.

---
 qemu/qemu-kvm.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
qemu/qemu-kvm.c +8 -1
Index: b/qemu/qemu-kvm.c
===================================================================
@@ -58,6 +58,8 @@ pthread_t io_thread;
 static int io_thread_fd = -1;
 static int io_thread_sigfd = -1;
 
+static int kvm_debug_stop_requested;
+
 static inline unsigned long kvm_get_thread_id(void)
 {
     return syscall(SYS_gettid);
@@ -517,6 +519,10 @@ int kvm_main_loop(void)
             qemu_system_powerdown();
         else if (qemu_reset_requested())
 	    qemu_kvm_system_reset();
+	else if (kvm_debug_stop_requested) {
+	    kvm_debug_stop_requested = 0;
+	    vm_stop(EXCP_DEBUG);
+	}
     }
 
     pause_all_threads();
@@ -529,7 +535,8 @@ static int kvm_debug(void *opaque, int v
 {
     CPUState *env = cpu_single_env;
 
-    env->exception_index = EXCP_DEBUG;
+    kvm_debug_stop_requested = 1;
+    vcpu_info[vcpu].stopped = 1;
     return 1;
 }
 
#1 lore raw
Quoted 17 lines · Jan Kiszka

When a vcpu exits after hitting a debug exception, we have to invoke vm_stop(EXCP_DEBUG). But this has to take place over the io-thread.

This patch introduces kvm_debug_stop_requested to signal this event, and it takes care that the interrupted vcpu itself goes immediately into stop state.

---
 qemu/qemu-kvm.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Index: b/qemu/qemu-kvm.c
===================================================================

qemu/qemu-kvm.c pthread_t io_thread; · line 63

Quoted 6 lines
qemu/qemu-kvm.c +2 -0
@@ -58,6 +58,8 @@ pthread_t io_thread;
 static int io_thread_fd = -1;
 static int io_thread_sigfd = -1;
 
+static int kvm_debug_stop_requested;
+
 

Why use this instead of just keying off of exception_index == EXCP_DEBUG?

Quoted 15 lines
qemu/qemu-kvm.c +0 -0
 static inline unsigned long kvm_get_thread_id(void)
 {
     return syscall(SYS_gettid);
qemu/qemu-kvm.c +4 -0
@@ -517,6 +519,10 @@ int kvm_main_loop(void)
             qemu_system_powerdown();
         else if (qemu_reset_requested())
 	    qemu_kvm_system_reset();
+	else if (kvm_debug_stop_requested) {
+	    kvm_debug_stop_requested = 0;
+	    vm_stop(EXCP_DEBUG);
+	}
     }
 
     pause_all_threads();

qemu/qemu-kvm.c static int kvm_debug(void *opaque, int v · line 540

Quoted 7 lines
qemu/qemu-kvm.c +2 -1
@@ -529,7 +535,8 @@ static int kvm_debug(void *opaque, int v
 {
     CPUState *env = cpu_single_env;
 
-    env->exception_index = EXCP_DEBUG;
+    kvm_debug_stop_requested = 1;
+    vcpu_info[vcpu].stopped = 1;
 

This isn't quite right. In the very least, you need to set stopping = 0 and signal on the qemu_pause_cond. Thinking it through more though, a breakpoint should stop all VCPUs, right?

vm_stop(EXCP_DEBUG) will actually do this. It invokes the vm_state_notify callbacks and the io-thread registers one. I think you should probably just issue vm_stop(EXCP_DEBUG) from kvm_debug.

Regards,

Anthony Liguori

Quoted 8 lines
qemu/qemu-kvm.c +0 -1
     return 1;
 }
 
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#2 lore raw
Quoted 45 lines · Anthony Liguori
Quoted 17 lines · Jan Kiszka

When a vcpu exits after hitting a debug exception, we have to invoke vm_stop(EXCP_DEBUG). But this has to take place over the io-thread.

This patch introduces kvm_debug_stop_requested to signal this event, and it takes care that the interrupted vcpu itself goes immediately into stop state.

---
 qemu/qemu-kvm.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Index: b/qemu/qemu-kvm.c
===================================================================

qemu/qemu-kvm.c pthread_t io_thread; · line 63

Quoted 6 lines
qemu/qemu-kvm.c +2 -0
@@ -58,6 +58,8 @@ pthread_t io_thread;
 static int io_thread_fd = -1;
 static int io_thread_sigfd = -1;
 
+static int kvm_debug_stop_requested;
+
 

Why use this instead of just keying off of exception_index == EXCP_DEBUG?

Quoted 18 lines
qemu/qemu-kvm.c +0 -0
 static inline unsigned long kvm_get_thread_id(void)
 {
     return syscall(SYS_gettid);
qemu/qemu-kvm.c +4 -0
@@ -517,6 +519,10 @@ int kvm_main_loop(void)
             qemu_system_powerdown();
         else if (qemu_reset_requested())
         qemu_kvm_system_reset();
+    else if (kvm_debug_stop_requested) {
+        kvm_debug_stop_requested = 0;
+        vm_stop(EXCP_DEBUG);
+    }
     }
 
     pause_all_threads();
@@ -529,7 +535,8 @@ static int kvm_debug(void *opaque, int v
 {
     CPUState *env = cpu_single_env;
 
Quoted 8 lines

qemu/qemu-kvm.c static int kvm_debug(void *opaque, int v · line 542

Quoted 4 lines
qemu/qemu-kvm.c +2 -1
-    env->exception_index = EXCP_DEBUG;
+    kvm_debug_stop_requested = 1;
+    vcpu_info[vcpu].stopped = 1;
 

This isn't quite right. In the very least, you need to set stopping = 0 and signal on the qemu_pause_cond. Thinking it through more though, a breakpoint should stop all VCPUs, right?

It does already, give it a try.

Quoted 4 lines

vm_stop(EXCP_DEBUG) will actually do this. It invokes the vm_state_notify callbacks and the io-thread registers one. I think you should probably just issue vm_stop(EXCP_DEBUG) from kvm_debug.

As explained, it can't be called over the vcpu contexts (there is even an assert() fence against it). This policy has been recently agreed on while fixing other deadlock issues of qemu-kvm.

Jan