From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35173) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZG6tb-0000Kf-04 for qemu-devel@nongnu.org; Fri, 17 Jul 2015 10:45:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZG6tV-00070X-3g for qemu-devel@nongnu.org; Fri, 17 Jul 2015 10:45:50 -0400 Received: from greensocs.com ([193.104.36.180]:59978) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZG6tU-0006zx-QF for qemu-devel@nongnu.org; Fri, 17 Jul 2015 10:45:45 -0400 From: fred.konrad@greensocs.com Date: Fri, 17 Jul 2015 16:45:36 +0200 Message-Id: <1437144337-21442-3-git-send-email-fred.konrad@greensocs.com> In-Reply-To: <1437144337-21442-1-git-send-email-fred.konrad@greensocs.com> References: <1437144337-21442-1-git-send-email-fred.konrad@greensocs.com> Subject: [Qemu-devel] [RFC PATCH V3 2/3] cpus: add tcg_exec_flag. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, mttcg@listserver.greensocs.com Cc: mark.burton@greensocs.com, a.rigo@virtualopensystems.com, guillaume.delbergue@greensocs.com, pbonzini@redhat.com, alex.bennee@linaro.org, fred.konrad@greensocs.com From: KONRAD Frederic This flag indicates the state of the VCPU thread: * 0 if the VCPU is allowed to execute code. * 1 if the VCPU is currently executing code. * -1 if the VCPU is not allowed to execute code. This allows to atomically check and run safe work or check and continue the TCG execution. Signed-off-by: KONRAD Frederic Changes V2 -> V3: * introduce a third state which allow or not the execution. * atomically check and set the flag when starting or blocking the code execution. Changes V1 -> V2: * do both tcg_executing = 0 or 1 in cpu_exec(). --- cpu-exec.c | 5 +++++ include/qom/cpu.h | 32 ++++++++++++++++++++++++++++++++ qom/cpu.c | 19 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/cpu-exec.c b/cpu-exec.c index 75694f3..e16666a 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -371,6 +371,10 @@ int cpu_exec(CPUState *cpu) cpu->halted = 0; } + if (!tcg_cpu_try_start_execution(cpu)) { + cpu->exit_request = 1; + return 0; + } current_cpu = cpu; /* As long as current_cpu is null, up to the assignment just above, @@ -583,5 +587,6 @@ int cpu_exec(CPUState *cpu) /* fail safe : never use current_cpu outside cpu_exec() */ current_cpu = NULL; + tcg_cpu_allow_execution(cpu); return ret; } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index efa9624..de7487e 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -226,6 +226,7 @@ struct kvm_run; * @stopped: Indicates the CPU has been artificially stopped. * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this * CPU and return to its top level loop. + * @tcg_exec_flag: See tcg_cpu_flag_* function. * @singlestep_enabled: Flags for single-stepping. * @icount_extra: Instructions until next timer event. * @icount_decr: Number of cycles left, with interrupt flag in high bit. @@ -322,6 +323,8 @@ struct CPUState { (absolute value) offset as small as possible. This reduces code size, especially for hosts without large memory offsets. */ volatile sig_atomic_t tcg_exit_req; + + int tcg_exec_flag; }; QTAILQ_HEAD(CPUTailQ, CPUState); @@ -337,6 +340,35 @@ extern struct CPUTailQ cpus; DECLARE_TLS(CPUState *, current_cpu); #define current_cpu tls_var(current_cpu) + +/** + * tcg_cpu_try_block_execution + * @cpu: The CPU to block the execution + * + * Try to set the tcg_exec_flag to -1 saying the CPU can't execute code if the + * CPU is not executing code. + * Returns true if the cpu execution is blocked, false otherwise. + */ +bool tcg_cpu_try_block_execution(CPUState *cpu); + +/** + * tcg_cpu_allow_execution + * @cpu: The CPU to allow the execution. + * + * Just reset the state of tcg_exec_flag, and allow the execution of some code. + */ +void tcg_cpu_allow_execution(CPUState *cpu); + +/** + * tcg_cpu_try_start_execution + * @cpu: The CPU to start the execution. + * + * Just set the tcg_exec_flag to 1 saying the CPU is executing code if the CPU + * is allowed to run some code. + * Returns true if the cpu can execute, false otherwise. + */ +bool tcg_cpu_try_start_execution(CPUState *cpu); + /** * cpu_paging_enabled: * @cpu: The CPU whose state is to be inspected. diff --git a/qom/cpu.c b/qom/cpu.c index 4e12598..e32f90c 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -26,6 +26,23 @@ #include "qemu/error-report.h" #include "sysemu/sysemu.h" +bool tcg_cpu_try_block_execution(CPUState *cpu) +{ + return (atomic_cmpxchg(&cpu->tcg_exec_flag, 0, -1) + || (cpu->tcg_exec_flag == -1)); +} + +void tcg_cpu_allow_execution(CPUState *cpu) +{ + cpu->tcg_exec_flag = 0; +} + +bool tcg_cpu_try_start_execution(CPUState *cpu) +{ + return (atomic_cmpxchg(&cpu->tcg_exec_flag, 0, 1) + || (cpu->tcg_exec_flag == 1)); +} + bool cpu_exists(int64_t id) { CPUState *cpu; @@ -249,6 +266,8 @@ static void cpu_common_reset(CPUState *cpu) cpu->icount_decr.u32 = 0; cpu->can_do_io = 0; cpu->exception_index = -1; + + tcg_cpu_allow_execution(cpu); memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *)); } -- 1.9.0