From 641565ba90a36e4135a1e1427ea815b243b0e11a Mon Sep 17 00:00:00 2001 From: Yaniv Kamay <yaniv@qumranet.com> Date: Thu, 19 Mar 2009 00:02:14 +0200 Subject: [PATCH 1/2] kvm: qemu: stop/start cpus before/after devices Stop cpus before devices when stopping the VM, start cpus after devices when starting VM. Otherwise a vcpu could access a stopped device. (cherry-picked from commit 4e9b07f80709ed62ced04f9988a55e340ada3e39) Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Bugzilla: 492355 RH-Upstream-status: pending Acked-by: Dor Laor <dlaor@redhat.com> Acked-with-reservation-by: Juan Quintela <quintela@redhat.com> Acked-by: Amit Shah <amit.shah@redhat.com> --- qemu/qemu-kvm.c | 19 +++++-------------- qemu/qemu-kvm.h | 3 +++ qemu/vl.c | 6 ++++++ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index 8c75579..18c5258 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -292,7 +292,7 @@ static int all_threads_paused(void) return 1; } -static void pause_all_threads(void) +void qemu_kvm_pause_all_threads(void) { CPUState *penv = first_cpu; @@ -312,7 +312,7 @@ static void pause_all_threads(void) qemu_cond_wait(&qemu_pause_cond); } -static void resume_all_threads(void) +void qemu_kvm_resume_all_threads(void) { CPUState *penv = first_cpu; @@ -326,14 +326,6 @@ static void resume_all_threads(void) } } -static void kvm_vm_state_change_handler(void *context, int running) -{ - if (running) - resume_all_threads(); - else - pause_all_threads(); -} - static void update_regs_for_sipi(CPUState *env) { kvm_arch_update_regs_for_sipi(env); @@ -378,7 +370,7 @@ void qemu_kvm_system_reset(void) { CPUState *penv = first_cpu; - pause_all_threads(); + qemu_kvm_pause_all_threads(); qemu_system_reset(); @@ -387,7 +379,7 @@ void qemu_kvm_system_reset(void) penv = (CPUState *)penv->next_cpu; } - resume_all_threads(); + qemu_kvm_resume_all_threads(); } static int kvm_main_loop_cpu(CPUState *env) @@ -473,7 +465,6 @@ int kvm_init_ap(void) #ifdef TARGET_I386 kvm_tpr_opt_setup(); #endif - qemu_add_vm_change_state_handler(kvm_vm_state_change_handler, NULL); signal(SIG_IPI, sig_ipi_handler); return 0; @@ -617,7 +608,7 @@ int kvm_main_loop(void) #endif } - pause_all_threads(); + qemu_kvm_pause_all_threads(); pthread_mutex_unlock(&qemu_mutex); return 0; diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h index 8795362..050e6e9 100644 --- a/qemu/qemu-kvm.h +++ b/qemu/qemu-kvm.h @@ -121,6 +121,9 @@ int qemu_kvm_unregister_coalesced_mmio(target_phys_addr_t addr, void qemu_kvm_system_reset_request(void); +void qemu_kvm_pause_all_threads(void); +void qemu_kvm_resume_all_threads(void); + int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); diff --git a/qemu/vl.c b/qemu/vl.c index b2bb644..ca8e68e 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -3611,6 +3611,9 @@ void vm_start(void) cpu_enable_ticks(); vm_running = 1; vm_state_notify(1); + if (kvm_enabled()) { + qemu_kvm_resume_all_threads(); + } qemu_rearm_alarm_timer(alarm_timer); } } @@ -3625,6 +3628,9 @@ void vm_stop(int reason) vm_stop_cb(vm_stop_opaque, reason); } } + if (kvm_enabled()) { + qemu_kvm_pause_all_threads(); + } vm_state_notify(0); } } -- 1.6.1