From 83f338f73ecb88cc6f85d6e7b81ebef112ce07be Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 7 Feb 2011 12:19:17 +0100 Subject: Move debug exception handling out of cpu_exec To prepare splitting up KVM and TCG CPU entry/exit, move the debug exception into cpus.c and invoke cpu_handle_debug_exception on return from qemu_cpu_exec. This also allows to clean up the debug request signaling: We can assign the job of informing main-loop to qemu_system_debug_request and stop the calling cpu directly in cpu_handle_debug_exception. That means a debug stop will now only be signaled via debug_requested and not additionally via vmstop_requested. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpu-exec.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'cpu-exec.c') diff --git a/cpu-exec.c b/cpu-exec.c index 8c9fb8b1a2..9c0b10d1db 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -196,28 +196,6 @@ static inline TranslationBlock *tb_find_fast(void) return tb; } -static CPUDebugExcpHandler *debug_excp_handler; - -CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler) -{ - CPUDebugExcpHandler *old_handler = debug_excp_handler; - - debug_excp_handler = handler; - return old_handler; -} - -static void cpu_handle_debug_exception(CPUState *env) -{ - CPUWatchpoint *wp; - - if (!env->watchpoint_hit) - QTAILQ_FOREACH(wp, &env->watchpoints, entry) - wp->flags &= ~BP_WATCHPOINT_HIT; - - if (debug_excp_handler) - debug_excp_handler(env); -} - /* main execution loop */ volatile sig_atomic_t exit_request; @@ -287,8 +265,6 @@ int cpu_exec(CPUState *env1) if (env->exception_index >= EXCP_INTERRUPT) { /* exit request from the cpu execution loop */ ret = env->exception_index; - if (ret == EXCP_DEBUG) - cpu_handle_debug_exception(env); break; } else { #if defined(CONFIG_USER_ONLY) -- cgit 1.4.1 From 6792a57bf19ab37f61f5acf0f8e3003cf08814af Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 7 Feb 2011 12:19:18 +0100 Subject: kvm: Separate TCG from KVM cpu execution Mixing up TCG bits with KVM already led to problems around eflags emulation on x86. Moreover, quite some code that TCG requires on cpu enty/exit is useless for KVM. So dispatch between tcg_cpu_exec and kvm_cpu_exec as early as possible. The core logic of cpu_halted from cpu_exec is added to kvm_arch_process_irqchip_events. Moving away from cpu_exec makes exception_index meaningless for KVM, we can simply pass the exit reason directly (only "EXCP_DEBUG vs. rest" is relevant). Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpu-exec.c | 19 ++++++------------- cpus.c | 10 +++++----- kvm-all.c | 19 +++++++++---------- target-i386/kvm.c | 6 +++--- 4 files changed, 23 insertions(+), 31 deletions(-) (limited to 'cpu-exec.c') diff --git a/cpu-exec.c b/cpu-exec.c index 9c0b10d1db..b03b3a749a 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -226,13 +226,11 @@ int cpu_exec(CPUState *env1) } #if defined(TARGET_I386) - if (!kvm_enabled()) { - /* put eflags in CPU temporary format */ - CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); - CC_OP = CC_OP_EFLAGS; - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - } + /* put eflags in CPU temporary format */ + CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((env->eflags >> 10) & 1)); + CC_OP = CC_OP_EFLAGS; + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_SPARC) #elif defined(TARGET_M68K) env->cc_op = CC_OP_FLAGS; @@ -257,7 +255,7 @@ int cpu_exec(CPUState *env1) if (setjmp(env->jmp_env) == 0) { #if defined(__sparc__) && !defined(CONFIG_SOLARIS) #undef env - env = cpu_single_env; + env = cpu_single_env; #define env cpu_single_env #endif /* if an exception is pending, we execute it here */ @@ -316,11 +314,6 @@ int cpu_exec(CPUState *env1) } } - if (kvm_enabled()) { - kvm_cpu_exec(env); - longjmp(env->jmp_env, 1); - } - next_tb = 0; /* force lookup of first TB */ for(;;) { interrupt_request = env->interrupt_request; diff --git a/cpus.c b/cpus.c index c7e86c29f4..468544cc3a 100644 --- a/cpus.c +++ b/cpus.c @@ -800,8 +800,6 @@ static void qemu_kvm_wait_io_event(CPUState *env) qemu_wait_io_event_common(env); } -static int qemu_cpu_exec(CPUState *env); - static void *qemu_kvm_cpu_thread_fn(void *arg) { CPUState *env = arg; @@ -829,7 +827,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) while (1) { if (cpu_can_run(env)) { - r = qemu_cpu_exec(env); + r = kvm_cpu_exec(env); if (r == EXCP_DEBUG) { cpu_handle_debug_exception(env); } @@ -1040,7 +1038,7 @@ void vm_stop(int reason) #endif -static int qemu_cpu_exec(CPUState *env) +static int tcg_cpu_exec(CPUState *env) { int ret; #ifdef CONFIG_PROFILER @@ -1095,9 +1093,11 @@ bool cpu_exec_all(void) break; } if (cpu_can_run(env)) { - r = qemu_cpu_exec(env); if (kvm_enabled()) { + r = kvm_cpu_exec(env); qemu_kvm_eat_signals(env); + } else { + r = tcg_cpu_exec(env); } if (r == EXCP_DEBUG) { cpu_handle_debug_exception(env); diff --git a/kvm-all.c b/kvm-all.c index 19cf1884cf..802c6b8369 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -895,10 +895,11 @@ int kvm_cpu_exec(CPUState *env) if (kvm_arch_process_irqchip_events(env)) { env->exit_request = 0; - env->exception_index = EXCP_HLT; - return 0; + return EXCP_HLT; } + cpu_single_env = env; + do { if (env->kvm_vcpu_dirty) { kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE); @@ -927,7 +928,6 @@ int kvm_cpu_exec(CPUState *env) kvm_flush_coalesced_mmio_buffer(); if (ret == -EINTR || ret == -EAGAIN) { - cpu_exit(env); DPRINTF("io window exit\n"); ret = 0; break; @@ -978,8 +978,8 @@ int kvm_cpu_exec(CPUState *env) DPRINTF("kvm_exit_debug\n"); #ifdef KVM_CAP_SET_GUEST_DEBUG if (kvm_arch_debug(&run->debug.arch)) { - env->exception_index = EXCP_DEBUG; - return 0; + ret = EXCP_DEBUG; + goto out; } /* re-enter, this exception was guest-internal */ ret = 1; @@ -995,13 +995,12 @@ int kvm_cpu_exec(CPUState *env) if (ret < 0) { cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); vm_stop(VMSTOP_PANIC); - env->exit_request = 1; - } - if (env->exit_request) { - env->exit_request = 0; - env->exception_index = EXCP_INTERRUPT; } + ret = EXCP_INTERRUPT; +out: + env->exit_request = 0; + cpu_single_env = NULL; return ret; } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ba183c4159..377a0a352b 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1502,12 +1502,13 @@ int kvm_arch_post_run(CPUState *env, struct kvm_run *run) int kvm_arch_process_irqchip_events(CPUState *env) { + if (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)) { + env->halted = 0; + } if (env->interrupt_request & CPU_INTERRUPT_INIT) { kvm_cpu_synchronize_state(env); do_cpu_init(env); - env->exception_index = EXCP_HALTED; } - if (env->interrupt_request & CPU_INTERRUPT_SIPI) { kvm_cpu_synchronize_state(env); do_cpu_sipi(env); @@ -1522,7 +1523,6 @@ static int kvm_handle_halt(CPUState *env) (env->eflags & IF_MASK)) && !(env->interrupt_request & CPU_INTERRUPT_NMI)) { env->halted = 1; - env->exception_index = EXCP_HLT; return 0; } -- cgit 1.4.1