Loading cpu-all.h +2 −0 Original line number Diff line number Diff line Loading @@ -821,6 +821,8 @@ void cpu_watchpoint_remove_all(CPUState *env, int mask); void cpu_single_step(CPUState *env, int enabled); void cpu_reset(CPUState *s); int cpu_is_stopped(CPUState *env); void run_on_cpu(CPUState *env, void (*func)(void *data), void *data); #define CPU_LOG_TB_OUT_ASM (1 << 0) #define CPU_LOG_TB_IN_ASM (1 << 1) Loading cpu-defs.h +4 −2 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ typedef struct icount_decr_u16 { struct kvm_run; struct KVMState; struct qemu_work_item; typedef struct CPUBreakpoint { target_ulong pc; Loading @@ -158,8 +159,6 @@ typedef struct CPUWatchpoint { target_ulong mem_io_vaddr; /* target virtual addr at which the \ memory was accessed */ \ uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ uint32_t stop; /* Stop request */ \ uint32_t stopped; /* Artificially stopped */ \ uint32_t interrupt_request; \ volatile sig_atomic_t exit_request; \ CPU_COMMON_TLB \ Loading Loading @@ -202,8 +201,11 @@ typedef struct CPUWatchpoint { void *opaque; \ \ uint32_t created; \ uint32_t stop; /* Stop request */ \ uint32_t stopped; /* Artificially stopped */ \ struct QemuThread *thread; \ struct QemuCond *halt_cond; \ struct qemu_work_item *queued_work_first, *queued_work_last; \ const char *cpu_model_str; \ struct KVMState *kvm_state; \ struct kvm_run *kvm_run; \ Loading cpu-exec.c +7 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,8 @@ static void cpu_handle_debug_exception(CPUState *env) /* main execution loop */ volatile sig_atomic_t exit_request; int cpu_exec(CPUState *env1) { volatile host_reg_t saved_env_reg; Loading @@ -234,6 +236,11 @@ int cpu_exec(CPUState *env1) asm(""); env = env1; if (exit_request) { env->exit_request = 1; exit_request = 0; } #if defined(TARGET_I386) if (!kvm_enabled()) { /* put eflags in CPU temporary format */ Loading cpus.c +69 −19 Original line number Diff line number Diff line Loading @@ -91,6 +91,11 @@ void cpu_synchronize_all_post_init(void) } } int cpu_is_stopped(CPUState *env) { return !vm_running || env->stopped; } static void do_vm_stop(int reason) { if (vm_running) { Loading @@ -115,6 +120,8 @@ static int cpu_has_work(CPUState *env) { if (env->stop) return 1; if (env->queued_work_first) return 1; if (env->stopped || !vm_running) return 0; if (!env->halted) Loading Loading @@ -252,6 +259,11 @@ int qemu_cpu_self(void *env) return 1; } void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) { func(data); } void resume_all_vcpus(void) { } Loading Loading @@ -304,6 +316,7 @@ static QemuCond qemu_cpu_cond; /* system init */ static QemuCond qemu_system_cond; static QemuCond qemu_pause_cond; static QemuCond qemu_work_cond; static void tcg_block_io_signals(void); static void kvm_block_io_signals(CPUState *env); Loading Loading @@ -334,6 +347,50 @@ void qemu_main_loop_start(void) qemu_cond_broadcast(&qemu_system_cond); } void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) { struct qemu_work_item wi; if (qemu_cpu_self(env)) { func(data); return; } wi.func = func; wi.data = data; if (!env->queued_work_first) env->queued_work_first = &wi; else env->queued_work_last->next = &wi; env->queued_work_last = &wi; wi.next = NULL; wi.done = false; qemu_cpu_kick(env); while (!wi.done) { CPUState *self_env = cpu_single_env; qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex); cpu_single_env = self_env; } } static void flush_queued_work(CPUState *env) { struct qemu_work_item *wi; if (!env->queued_work_first) return; while ((wi = env->queued_work_first)) { env->queued_work_first = wi->next; wi->func(wi->data); wi->done = true; } env->queued_work_last = NULL; qemu_cond_broadcast(&qemu_work_cond); } static void qemu_wait_io_event_common(CPUState *env) { if (env->stop) { Loading @@ -341,6 +398,7 @@ static void qemu_wait_io_event_common(CPUState *env) env->stopped = 1; qemu_cond_signal(&qemu_pause_cond); } flush_queued_work(env); } static void qemu_wait_io_event(CPUState *env) Loading Loading @@ -454,7 +512,6 @@ void qemu_cpu_kick(void *_env) { CPUState *env = _env; qemu_cond_broadcast(env->halt_cond); if (kvm_enabled()) qemu_thread_signal(env->thread, SIG_IPI); } Loading @@ -472,6 +529,7 @@ static void cpu_signal(int sig) { if (cpu_single_env) cpu_exit(cpu_single_env); exit_request = 1; } static void tcg_block_io_signals(void) Loading Loading @@ -542,26 +600,20 @@ static void unblock_io_signals(void) pthread_sigmask(SIG_BLOCK, &set, NULL); } static void qemu_signal_lock(unsigned int msecs) { qemu_mutex_lock(&qemu_fair_mutex); while (qemu_mutex_trylock(&qemu_global_mutex)) { qemu_thread_signal(tcg_cpu_thread, SIG_IPI); if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs)) break; } qemu_mutex_unlock(&qemu_fair_mutex); } 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); } else { qemu_mutex_lock(&qemu_fair_mutex); if (qemu_mutex_trylock(&qemu_global_mutex)) { qemu_thread_signal(tcg_cpu_thread, SIG_IPI); qemu_mutex_lock(&qemu_global_mutex); } qemu_mutex_unlock(&qemu_fair_mutex); } } void qemu_mutex_unlock_iothread(void) Loading @@ -588,7 +640,6 @@ void pause_all_vcpus(void) while (penv) { penv->stop = 1; qemu_thread_signal(penv->thread, SIG_IPI); qemu_cpu_kick(penv); penv = (CPUState *)penv->next_cpu; } Loading @@ -597,7 +648,7 @@ void pause_all_vcpus(void) qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100); penv = first_cpu; while (penv) { qemu_thread_signal(penv->thread, SIG_IPI); qemu_cpu_kick(penv); penv = (CPUState *)penv->next_cpu; } } Loading @@ -610,7 +661,6 @@ void resume_all_vcpus(void) while (penv) { penv->stop = 0; penv->stopped = 0; qemu_thread_signal(penv->thread, SIG_IPI); qemu_cpu_kick(penv); penv = (CPUState *)penv->next_cpu; } Loading exec-all.h +3 −0 Original line number Diff line number Diff line Loading @@ -351,4 +351,7 @@ CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); /* vl.c */ extern int singlestep; /* cpu-exec.c */ extern volatile sig_atomic_t exit_request; #endif Loading
cpu-all.h +2 −0 Original line number Diff line number Diff line Loading @@ -821,6 +821,8 @@ void cpu_watchpoint_remove_all(CPUState *env, int mask); void cpu_single_step(CPUState *env, int enabled); void cpu_reset(CPUState *s); int cpu_is_stopped(CPUState *env); void run_on_cpu(CPUState *env, void (*func)(void *data), void *data); #define CPU_LOG_TB_OUT_ASM (1 << 0) #define CPU_LOG_TB_IN_ASM (1 << 1) Loading
cpu-defs.h +4 −2 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ typedef struct icount_decr_u16 { struct kvm_run; struct KVMState; struct qemu_work_item; typedef struct CPUBreakpoint { target_ulong pc; Loading @@ -158,8 +159,6 @@ typedef struct CPUWatchpoint { target_ulong mem_io_vaddr; /* target virtual addr at which the \ memory was accessed */ \ uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ uint32_t stop; /* Stop request */ \ uint32_t stopped; /* Artificially stopped */ \ uint32_t interrupt_request; \ volatile sig_atomic_t exit_request; \ CPU_COMMON_TLB \ Loading Loading @@ -202,8 +201,11 @@ typedef struct CPUWatchpoint { void *opaque; \ \ uint32_t created; \ uint32_t stop; /* Stop request */ \ uint32_t stopped; /* Artificially stopped */ \ struct QemuThread *thread; \ struct QemuCond *halt_cond; \ struct qemu_work_item *queued_work_first, *queued_work_last; \ const char *cpu_model_str; \ struct KVMState *kvm_state; \ struct kvm_run *kvm_run; \ Loading
cpu-exec.c +7 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,8 @@ static void cpu_handle_debug_exception(CPUState *env) /* main execution loop */ volatile sig_atomic_t exit_request; int cpu_exec(CPUState *env1) { volatile host_reg_t saved_env_reg; Loading @@ -234,6 +236,11 @@ int cpu_exec(CPUState *env1) asm(""); env = env1; if (exit_request) { env->exit_request = 1; exit_request = 0; } #if defined(TARGET_I386) if (!kvm_enabled()) { /* put eflags in CPU temporary format */ Loading
cpus.c +69 −19 Original line number Diff line number Diff line Loading @@ -91,6 +91,11 @@ void cpu_synchronize_all_post_init(void) } } int cpu_is_stopped(CPUState *env) { return !vm_running || env->stopped; } static void do_vm_stop(int reason) { if (vm_running) { Loading @@ -115,6 +120,8 @@ static int cpu_has_work(CPUState *env) { if (env->stop) return 1; if (env->queued_work_first) return 1; if (env->stopped || !vm_running) return 0; if (!env->halted) Loading Loading @@ -252,6 +259,11 @@ int qemu_cpu_self(void *env) return 1; } void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) { func(data); } void resume_all_vcpus(void) { } Loading Loading @@ -304,6 +316,7 @@ static QemuCond qemu_cpu_cond; /* system init */ static QemuCond qemu_system_cond; static QemuCond qemu_pause_cond; static QemuCond qemu_work_cond; static void tcg_block_io_signals(void); static void kvm_block_io_signals(CPUState *env); Loading Loading @@ -334,6 +347,50 @@ void qemu_main_loop_start(void) qemu_cond_broadcast(&qemu_system_cond); } void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) { struct qemu_work_item wi; if (qemu_cpu_self(env)) { func(data); return; } wi.func = func; wi.data = data; if (!env->queued_work_first) env->queued_work_first = &wi; else env->queued_work_last->next = &wi; env->queued_work_last = &wi; wi.next = NULL; wi.done = false; qemu_cpu_kick(env); while (!wi.done) { CPUState *self_env = cpu_single_env; qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex); cpu_single_env = self_env; } } static void flush_queued_work(CPUState *env) { struct qemu_work_item *wi; if (!env->queued_work_first) return; while ((wi = env->queued_work_first)) { env->queued_work_first = wi->next; wi->func(wi->data); wi->done = true; } env->queued_work_last = NULL; qemu_cond_broadcast(&qemu_work_cond); } static void qemu_wait_io_event_common(CPUState *env) { if (env->stop) { Loading @@ -341,6 +398,7 @@ static void qemu_wait_io_event_common(CPUState *env) env->stopped = 1; qemu_cond_signal(&qemu_pause_cond); } flush_queued_work(env); } static void qemu_wait_io_event(CPUState *env) Loading Loading @@ -454,7 +512,6 @@ void qemu_cpu_kick(void *_env) { CPUState *env = _env; qemu_cond_broadcast(env->halt_cond); if (kvm_enabled()) qemu_thread_signal(env->thread, SIG_IPI); } Loading @@ -472,6 +529,7 @@ static void cpu_signal(int sig) { if (cpu_single_env) cpu_exit(cpu_single_env); exit_request = 1; } static void tcg_block_io_signals(void) Loading Loading @@ -542,26 +600,20 @@ static void unblock_io_signals(void) pthread_sigmask(SIG_BLOCK, &set, NULL); } static void qemu_signal_lock(unsigned int msecs) { qemu_mutex_lock(&qemu_fair_mutex); while (qemu_mutex_trylock(&qemu_global_mutex)) { qemu_thread_signal(tcg_cpu_thread, SIG_IPI); if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs)) break; } qemu_mutex_unlock(&qemu_fair_mutex); } 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); } else { qemu_mutex_lock(&qemu_fair_mutex); if (qemu_mutex_trylock(&qemu_global_mutex)) { qemu_thread_signal(tcg_cpu_thread, SIG_IPI); qemu_mutex_lock(&qemu_global_mutex); } qemu_mutex_unlock(&qemu_fair_mutex); } } void qemu_mutex_unlock_iothread(void) Loading @@ -588,7 +640,6 @@ void pause_all_vcpus(void) while (penv) { penv->stop = 1; qemu_thread_signal(penv->thread, SIG_IPI); qemu_cpu_kick(penv); penv = (CPUState *)penv->next_cpu; } Loading @@ -597,7 +648,7 @@ void pause_all_vcpus(void) qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100); penv = first_cpu; while (penv) { qemu_thread_signal(penv->thread, SIG_IPI); qemu_cpu_kick(penv); penv = (CPUState *)penv->next_cpu; } } Loading @@ -610,7 +661,6 @@ void resume_all_vcpus(void) while (penv) { penv->stop = 0; penv->stopped = 0; qemu_thread_signal(penv->thread, SIG_IPI); qemu_cpu_kick(penv); penv = (CPUState *)penv->next_cpu; } Loading
exec-all.h +3 −0 Original line number Diff line number Diff line Loading @@ -351,4 +351,7 @@ CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); /* vl.c */ extern int singlestep; /* cpu-exec.c */ extern volatile sig_atomic_t exit_request; #endif