Allow the iothread to run while vcpu is in guest mode. To be tuned with SMP support. Signed-off-by: Marcelo Tosatti Index: trunk/kvm-all.c =================================================================== --- trunk.orig/kvm-all.c +++ trunk/kvm-all.c @@ -451,6 +451,7 @@ int kvm_cpu_exec(CPUState *env) do { kvm_arch_pre_run(env, run); + kvm_pre_run(env); if (env->exit_request) { dprintf("interrupt exit requested\n"); @@ -459,6 +460,7 @@ int kvm_cpu_exec(CPUState *env) } ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); + kvm_post_run(env); kvm_arch_post_run(env, run); if (ret == -EINTR || ret == -EAGAIN) { Index: trunk/kvm.h =================================================================== --- trunk.orig/kvm.h +++ trunk/kvm.h @@ -27,6 +27,10 @@ extern int kvm_allowed; struct kvm_run; +/* main loop interface, vl.c */ +void kvm_pre_run(CPUState *env); +void kvm_post_run(CPUState *env); + /* external API */ int kvm_init(int smp_cpus); Index: trunk/target-i386/helper.c =================================================================== --- trunk.orig/target-i386/helper.c +++ trunk/target-i386/helper.c @@ -1668,9 +1668,6 @@ CPUX86State *cpu_x86_init(const char *cp #ifdef USE_KQEMU kqemu_init(env); #endif - if (kvm_enabled()) - kvm_init_vcpu(env); - qemu_init_vcpu(env); return env; Index: trunk/target-ppc/helper.c =================================================================== --- trunk.orig/target-ppc/helper.c +++ trunk/target-ppc/helper.c @@ -2829,8 +2829,6 @@ CPUPPCState *cpu_ppc_init (const char *c cpu_ppc_register_internal(env, def); cpu_ppc_reset(env); - if (kvm_enabled()) - kvm_init_vcpu(env); qemu_init_vcpu(env); return env; Index: trunk/vl.c =================================================================== --- trunk.orig/vl.c +++ trunk/vl.c @@ -3842,6 +3842,8 @@ void qemu_cpu_kick(void *_env) { CPUState *env = _env; qemu_cond_broadcast(env->halt_cond); + if (kvm_enabled()) + qemu_thread_signal(env->thread, SIGUSR1); } int qemu_cpu_self(void *env) @@ -3902,6 +3904,16 @@ static void qemu_signal_lock(unsigned in qemu_mutex_unlock(&qemu_fair_mutex); } +static void qemu_mutex_lock_iothread(void) +{ + if (kvm_enabled()) { + qemu_mutex_lock(&qemu_fair_mutex); + qemu_mutex_lock(&qemu_global_mutex); + qemu_mutex_unlock(&qemu_fair_mutex); + } else + qemu_signal_lock(100); +} + static int all_vcpus_paused(void) { CPUState *penv = first_cpu; @@ -3998,7 +4010,7 @@ void main_loop_wait(int timeout) */ qemu_mutex_unlock(&qemu_global_mutex); ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - qemu_signal_lock(100); + qemu_mutex_lock_iothread(); if (ret > 0) { IOHandlerRecord **pioh; @@ -4206,9 +4218,8 @@ static void *cpu_main_loop(void *arg) return NULL; } -void qemu_init_vcpu(void *_env) +static void tcg_init_vcpu(CPUState *env) { - CPUState *env = _env; /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { env->thread = qemu_mallocz(sizeof(QemuThread)); @@ -4225,6 +4236,39 @@ void qemu_init_vcpu(void *_env) } } +static void kvm_start_vcpu(CPUState *env) +{ + kvm_init_vcpu(env); + env->thread = qemu_mallocz(sizeof(QemuThread)); + env->halt_cond = qemu_mallocz(sizeof(QemuCond)); + qemu_cond_init(env->halt_cond); + qemu_thread_create(env->thread, cpu_main_loop, env); + while (env->created == 0) + qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); +} + +void kvm_pre_run(CPUState *env) +{ + cpu_single_env = NULL; + qemu_mutex_unlock(&qemu_global_mutex); +} + +void kvm_post_run(CPUState *env) +{ + qemu_mutex_lock(&qemu_global_mutex); + cpu_single_env = env; +} + +void qemu_init_vcpu(void *_env) +{ + CPUState *env = _env; + + if (kvm_enabled()) + kvm_start_vcpu(env); + else + tcg_init_vcpu(env); +} + static void qemu_init_state(void) { qemu_cond_init(&qemu_pause_cond);