提交 6792a57b 编写于 作者: J Jan Kiszka 提交者: Marcelo Tosatti

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: NJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
上级 83f338f7
...@@ -226,13 +226,11 @@ int cpu_exec(CPUState *env1) ...@@ -226,13 +226,11 @@ int cpu_exec(CPUState *env1)
} }
#if defined(TARGET_I386) #if defined(TARGET_I386)
if (!kvm_enabled()) { /* put eflags in CPU temporary format */
/* put eflags in CPU temporary format */ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); DF = 1 - (2 * ((env->eflags >> 10) & 1));
DF = 1 - (2 * ((env->eflags >> 10) & 1)); CC_OP = CC_OP_EFLAGS;
CC_OP = CC_OP_EFLAGS; env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
}
#elif defined(TARGET_SPARC) #elif defined(TARGET_SPARC)
#elif defined(TARGET_M68K) #elif defined(TARGET_M68K)
env->cc_op = CC_OP_FLAGS; env->cc_op = CC_OP_FLAGS;
...@@ -257,7 +255,7 @@ int cpu_exec(CPUState *env1) ...@@ -257,7 +255,7 @@ int cpu_exec(CPUState *env1)
if (setjmp(env->jmp_env) == 0) { if (setjmp(env->jmp_env) == 0) {
#if defined(__sparc__) && !defined(CONFIG_SOLARIS) #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
#undef env #undef env
env = cpu_single_env; env = cpu_single_env;
#define env cpu_single_env #define env cpu_single_env
#endif #endif
/* if an exception is pending, we execute it here */ /* if an exception is pending, we execute it here */
...@@ -316,11 +314,6 @@ int cpu_exec(CPUState *env1) ...@@ -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 */ next_tb = 0; /* force lookup of first TB */
for(;;) { for(;;) {
interrupt_request = env->interrupt_request; interrupt_request = env->interrupt_request;
......
...@@ -800,8 +800,6 @@ static void qemu_kvm_wait_io_event(CPUState *env) ...@@ -800,8 +800,6 @@ static void qemu_kvm_wait_io_event(CPUState *env)
qemu_wait_io_event_common(env); qemu_wait_io_event_common(env);
} }
static int qemu_cpu_exec(CPUState *env);
static void *qemu_kvm_cpu_thread_fn(void *arg) static void *qemu_kvm_cpu_thread_fn(void *arg)
{ {
CPUState *env = arg; CPUState *env = arg;
...@@ -829,7 +827,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) ...@@ -829,7 +827,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
while (1) { while (1) {
if (cpu_can_run(env)) { if (cpu_can_run(env)) {
r = qemu_cpu_exec(env); r = kvm_cpu_exec(env);
if (r == EXCP_DEBUG) { if (r == EXCP_DEBUG) {
cpu_handle_debug_exception(env); cpu_handle_debug_exception(env);
} }
...@@ -1040,7 +1038,7 @@ void vm_stop(int reason) ...@@ -1040,7 +1038,7 @@ void vm_stop(int reason)
#endif #endif
static int qemu_cpu_exec(CPUState *env) static int tcg_cpu_exec(CPUState *env)
{ {
int ret; int ret;
#ifdef CONFIG_PROFILER #ifdef CONFIG_PROFILER
...@@ -1095,9 +1093,11 @@ bool cpu_exec_all(void) ...@@ -1095,9 +1093,11 @@ bool cpu_exec_all(void)
break; break;
} }
if (cpu_can_run(env)) { if (cpu_can_run(env)) {
r = qemu_cpu_exec(env);
if (kvm_enabled()) { if (kvm_enabled()) {
r = kvm_cpu_exec(env);
qemu_kvm_eat_signals(env); qemu_kvm_eat_signals(env);
} else {
r = tcg_cpu_exec(env);
} }
if (r == EXCP_DEBUG) { if (r == EXCP_DEBUG) {
cpu_handle_debug_exception(env); cpu_handle_debug_exception(env);
......
...@@ -895,10 +895,11 @@ int kvm_cpu_exec(CPUState *env) ...@@ -895,10 +895,11 @@ int kvm_cpu_exec(CPUState *env)
if (kvm_arch_process_irqchip_events(env)) { if (kvm_arch_process_irqchip_events(env)) {
env->exit_request = 0; env->exit_request = 0;
env->exception_index = EXCP_HLT; return EXCP_HLT;
return 0;
} }
cpu_single_env = env;
do { do {
if (env->kvm_vcpu_dirty) { if (env->kvm_vcpu_dirty) {
kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE); kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
...@@ -927,7 +928,6 @@ int kvm_cpu_exec(CPUState *env) ...@@ -927,7 +928,6 @@ int kvm_cpu_exec(CPUState *env)
kvm_flush_coalesced_mmio_buffer(); kvm_flush_coalesced_mmio_buffer();
if (ret == -EINTR || ret == -EAGAIN) { if (ret == -EINTR || ret == -EAGAIN) {
cpu_exit(env);
DPRINTF("io window exit\n"); DPRINTF("io window exit\n");
ret = 0; ret = 0;
break; break;
...@@ -978,8 +978,8 @@ int kvm_cpu_exec(CPUState *env) ...@@ -978,8 +978,8 @@ int kvm_cpu_exec(CPUState *env)
DPRINTF("kvm_exit_debug\n"); DPRINTF("kvm_exit_debug\n");
#ifdef KVM_CAP_SET_GUEST_DEBUG #ifdef KVM_CAP_SET_GUEST_DEBUG
if (kvm_arch_debug(&run->debug.arch)) { if (kvm_arch_debug(&run->debug.arch)) {
env->exception_index = EXCP_DEBUG; ret = EXCP_DEBUG;
return 0; goto out;
} }
/* re-enter, this exception was guest-internal */ /* re-enter, this exception was guest-internal */
ret = 1; ret = 1;
...@@ -995,13 +995,12 @@ int kvm_cpu_exec(CPUState *env) ...@@ -995,13 +995,12 @@ int kvm_cpu_exec(CPUState *env)
if (ret < 0) { if (ret < 0) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
vm_stop(VMSTOP_PANIC); 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; return ret;
} }
......
...@@ -1502,12 +1502,13 @@ int kvm_arch_post_run(CPUState *env, struct kvm_run *run) ...@@ -1502,12 +1502,13 @@ int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
int kvm_arch_process_irqchip_events(CPUState *env) 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) { if (env->interrupt_request & CPU_INTERRUPT_INIT) {
kvm_cpu_synchronize_state(env); kvm_cpu_synchronize_state(env);
do_cpu_init(env); do_cpu_init(env);
env->exception_index = EXCP_HALTED;
} }
if (env->interrupt_request & CPU_INTERRUPT_SIPI) { if (env->interrupt_request & CPU_INTERRUPT_SIPI) {
kvm_cpu_synchronize_state(env); kvm_cpu_synchronize_state(env);
do_cpu_sipi(env); do_cpu_sipi(env);
...@@ -1522,7 +1523,6 @@ static int kvm_handle_halt(CPUState *env) ...@@ -1522,7 +1523,6 @@ static int kvm_handle_halt(CPUState *env)
(env->eflags & IF_MASK)) && (env->eflags & IF_MASK)) &&
!(env->interrupt_request & CPU_INTERRUPT_NMI)) { !(env->interrupt_request & CPU_INTERRUPT_NMI)) {
env->halted = 1; env->halted = 1;
env->exception_index = EXCP_HLT;
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册