From patchwork Mon Feb 7 11:19:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 82178 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 09C47B70DE for ; Tue, 8 Feb 2011 09:27:23 +1100 (EST) Received: from localhost ([127.0.0.1]:60562 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmPIA-0001x4-RE for incoming@patchwork.ozlabs.org; Mon, 07 Feb 2011 06:30:02 -0500 Received: from [140.186.70.92] (port=45663 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmP7z-0006mb-Hm for qemu-devel@nongnu.org; Mon, 07 Feb 2011 06:19:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PmP7y-0007wK-7l for qemu-devel@nongnu.org; Mon, 07 Feb 2011 06:19:31 -0500 Received: from goliath.siemens.de ([192.35.17.28]:23595) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PmP7x-0007vW-NV for qemu-devel@nongnu.org; Mon, 07 Feb 2011 06:19:30 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.13.6/8.13.6) with ESMTP id p17BJSSw003812; Mon, 7 Feb 2011 12:19:28 +0100 Received: from mchn199C.mchp.siemens.de ([139.25.109.49]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p17BJQKO027537; Mon, 7 Feb 2011 12:19:28 +0100 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Date: Mon, 7 Feb 2011 12:19:18 +0100 Message-Id: <149ef70e3a2ebe96529b0956da4bd4009099e3ac.1297077507.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 192.35.17.28 Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH 07/15] kvm: Separate TCG from KVM cpu execution X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- cpu-exec.c | 19 ++++++------------- cpus.c | 10 +++++----- kvm-all.c | 19 +++++++++---------- target-i386/kvm.c | 6 +++--- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 9c0b10d..b03b3a7 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 d4b5e80..2414316 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 19cf188..802c6b8 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 ba183c4..377a0a3 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; }