From patchwork Wed Oct 19 18:05:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 78318 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp385528qge; Wed, 19 Oct 2016 11:17:41 -0700 (PDT) X-Received: by 10.31.67.203 with SMTP id q194mr6330586vka.38.1476901061933; Wed, 19 Oct 2016 11:17:41 -0700 (PDT) Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id u5si604109vke.157.2016.10.19.11.17.41 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 19 Oct 2016 11:17:41 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:50268 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwvQr-0007oC-EF for patch@linaro.org; Wed, 19 Oct 2016 14:17:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60652) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwvFZ-0006Dk-Pb for qemu-devel@nongnu.org; Wed, 19 Oct 2016 14:06:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bwvFV-0001sN-GQ for qemu-devel@nongnu.org; Wed, 19 Oct 2016 14:06:01 -0400 Received: from mail-qk0-x232.google.com ([2607:f8b0:400d:c09::232]:33617) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bwvFV-0001sC-Au for qemu-devel@nongnu.org; Wed, 19 Oct 2016 14:05:57 -0400 Received: by mail-qk0-x232.google.com with SMTP id n189so50349099qke.0 for ; Wed, 19 Oct 2016 11:05:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to; bh=UVCC82yruNi440L7y5kOcJdrguiLecZRj9hma5x7DmY=; b=QhsA3kSdZCTpM+TM1Xe6e/XlqNEQdB6GyuEdi8couOQRfOBqsmKE2fppoE9+GFR/lp rC/qJSf0aCLiIrC1tuYaumJOliZHH0MWHvA8Gn8sZiHmXjxpTwyapwf1wsPedHnBWERR eknqjJQSZLpT/fe8sjiFJdQbJq6a0b1AsXRuRfmdxW7tablTOiWqif4CcG0qj4sVCFgW PP82NaQjkz96N8XfekcYPD/LXUfs2nsS/U/4fBEOlVCKvfFPtqcHdYEaEKiE87gb0cUJ BJIufhAnSIL3BPldeg+O7DT0xw8wJhvyxZcH9AN+0KBfZu0kEo4PlTqwbtqlVsU4mCEP w0aA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:subject:to:references:cc:from:message-id :date:user-agent:mime-version:in-reply-to; bh=UVCC82yruNi440L7y5kOcJdrguiLecZRj9hma5x7DmY=; b=Z9KruVG4OaUl6vW4i/o4Edik7064cRsm+9UCmU+1TyzL4OudndqJuuDnd7ZvAWuYUH cXtY6qdDj7DOOe3DXZ2PvcgGO3PEEEZOoAcF98dYk0E239IbbU00bvNIP/lxh7LuPEaz mPXR5LufSzoO8iklrF7vpIashYKw5pXGSGQJPwbe24fWzbGX6s/+35/9/tH+w93zZXAY Tfr4DEvHNvPSOlC9Xh0re9OLAJI2GAydevCh2hBbKPcH3PBBbtyBwnJrwPOwzM/ZBORQ ENJZOob1uuXjbSPS+QYr21f98oCaYedNyoYAnP7AEKCfPLwhQF3lZ3if3EMBwI8NYTjN hawA== X-Gm-Message-State: ABUngvemuS1s68w14R3yCZmyWc4fQXChHKYbNn5UB/nPffNgPv040kKMA/Wl9wLwNaKMqg== X-Received: by 10.55.20.31 with SMTP id e31mr4743925qkh.27.1476900356657; Wed, 19 Oct 2016 11:05:56 -0700 (PDT) Received: from bigtime.twiddle.net (174-24-157-40.tukw.qwest.net. [174.24.157.40]) by smtp.googlemail.com with ESMTPSA id h6sm865144qkd.38.2016.10.19.11.05.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Oct 2016 11:05:56 -0700 (PDT) To: qemu-devel@nongnu.org References: <1476897727-791-1-git-send-email-rth@twiddle.net> From: Richard Henderson Message-ID: <14b21cd9-40f5-556e-e5c9-020751de0f44@twiddle.net> Date: Wed, 19 Oct 2016 11:05:53 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 In-Reply-To: <1476897727-791-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c09::232 Subject: [Qemu-devel] [PATCH v7 06/35] tcg: Add EXCP_ATOMIC X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: cota@braap.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" As appears to be usual, patch 6 was eaten. Attachment worked last time... r~ >From 6ce760bc19546e4d139732e9a5eb44b578dd834b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 29 Jun 2016 22:12:55 -0700 Subject: [PATCH v7 06/35] tcg: Add EXCP_ATOMIC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we cannot emulate an atomic operation within a parallel context, this exception allows us to stop the world and try again in a serial context. Reviewed-by: Emilio G. Cota Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- cpu-exec-common.c | 6 ++++++ cpu-exec.c | 30 ++++++++++++++++++++++++++++++ cpus.c | 2 ++ include/exec/cpu-all.h | 1 + include/exec/exec-all.h | 1 + include/qemu-common.h | 1 + linux-user/main.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ tcg/tcg.h | 1 + translate-all.c | 1 + 9 files changed, 88 insertions(+) diff --git a/cpu-exec-common.c b/cpu-exec-common.c index 0cb4ae6..767d9c6 100644 --- a/cpu-exec-common.c +++ b/cpu-exec-common.c @@ -77,3 +77,9 @@ void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) } siglongjmp(cpu->jmp_env, 1); } + +void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc) +{ + cpu->exception_index = EXCP_ATOMIC; + cpu_loop_exit_restore(cpu, pc); +} diff --git a/cpu-exec.c b/cpu-exec.c index e114fcd..c999793 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -222,6 +222,36 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles, } #endif +static void cpu_exec_step(CPUState *cpu) +{ + CPUArchState *env = (CPUArchState *)cpu->env_ptr; + TranslationBlock *tb; + target_ulong cs_base, pc; + uint32_t flags; + + cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); + tb = tb_gen_code(cpu, pc, cs_base, flags, + 1 | CF_NOCACHE | CF_IGNORE_ICOUNT); + tb->orig_tb = NULL; + /* execute the generated code */ + trace_exec_tb_nocache(tb, pc); + cpu_tb_exec(cpu, tb); + tb_phys_invalidate(tb, -1); + tb_free(tb); +} + +void cpu_exec_step_atomic(CPUState *cpu) +{ + start_exclusive(); + + /* Since we got here, we know that parallel_cpus must be true. */ + parallel_cpus = false; + cpu_exec_step(cpu); + parallel_cpus = true; + + end_exclusive(); +} + struct tb_desc { target_ulong pc; target_ulong cs_base; diff --git a/cpus.c b/cpus.c index 31204bb..cfd5cdc 100644 --- a/cpus.c +++ b/cpus.c @@ -1497,6 +1497,8 @@ static void tcg_exec_all(void) if (r == EXCP_DEBUG) { cpu_handle_guest_debug(cpu); break; + } else if (r == EXCP_ATOMIC) { + cpu_exec_step_atomic(cpu); } } else if (cpu->stop || cpu->stopped) { if (cpu->unplug) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index b6a7059..1f7e9d8 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -31,6 +31,7 @@ #define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */ #define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */ #define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */ +#define EXCP_ATOMIC 0x10005 /* stop-the-world and emulate atomic */ /* some important defines: * diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 336a57c..13633a2 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -60,6 +60,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, void cpu_exec_init(CPUState *cpu, Error **errp); void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc); +void QEMU_NORETURN cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc); #if !defined(CONFIG_USER_ONLY) void cpu_reloading_memory_map(void); diff --git a/include/qemu-common.h b/include/qemu-common.h index 9e8b0bd..291f98d 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -80,6 +80,7 @@ void tcg_exec_init(unsigned long tb_size); bool tcg_enabled(void); void cpu_exec_init_all(void); +void cpu_exec_step_atomic(CPUState *cpu); /** * Sends a (part of) iovec down a socket, yielding when the socket is full, or diff --git a/linux-user/main.c b/linux-user/main.c index 0e31dad..a6406ce 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -354,6 +354,9 @@ void cpu_loop(CPUX86State *env) } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: pc = env->segs[R_CS].base + env->eip; EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", @@ -848,6 +851,9 @@ void cpu_loop(CPUARMState *env) case EXCP_YIELD: /* nothing to do here for user-mode, just resume guest code */ break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: error: EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); @@ -1048,6 +1054,9 @@ void cpu_loop(CPUARMState *env) case EXCP_YIELD: /* nothing to do here for user-mode, just resume guest code */ break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); abort(); @@ -1139,6 +1148,9 @@ void cpu_loop(CPUUniCore32State *env) } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: goto error; } @@ -1412,6 +1424,9 @@ void cpu_loop (CPUSPARCState *env) } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); @@ -1951,6 +1966,9 @@ void cpu_loop(CPUPPCState *env) case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: cpu_abort(cs, "Unknown exception 0x%x. Aborting\n", trapnr); break; @@ -2626,6 +2644,9 @@ done_syscall: } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: error: EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); @@ -2713,6 +2734,9 @@ void cpu_loop(CPUOpenRISCState *env) case EXCP_NR: qemu_log_mask(CPU_LOG_INT, "\nNR\n"); break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n", trapnr); @@ -2789,6 +2813,9 @@ void cpu_loop(CPUSH4State *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); @@ -2856,6 +2883,9 @@ void cpu_loop(CPUCRISState *env) } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); @@ -2972,6 +3002,9 @@ void cpu_loop(CPUMBState *env) } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); @@ -3075,6 +3108,9 @@ void cpu_loop(CPUM68KState *env) } } break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); abort(); @@ -3311,6 +3347,9 @@ void cpu_loop(CPUAlphaState *env) case EXCP_INTERRUPT: /* Just indicate that signals should be handled asap. */ break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); @@ -3440,6 +3479,9 @@ void cpu_loop(CPUS390XState *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); @@ -3694,6 +3736,9 @@ void cpu_loop(CPUTLGState *env) case TILEGX_EXCP_REG_UDN_ACCESS: gen_sigill_reg(env); break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; default: fprintf(stderr, "trapnr is %d[0x%x].\n", trapnr, trapnr); g_assert_not_reached(); diff --git a/tcg/tcg.h b/tcg/tcg.h index c9949aa..3b21156 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -704,6 +704,7 @@ struct TCGContext { }; extern TCGContext tcg_ctx; +extern bool parallel_cpus; static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v) { diff --git a/translate-all.c b/translate-all.c index 8ca393c..4200869 100644 --- a/translate-all.c +++ b/translate-all.c @@ -119,6 +119,7 @@ static void *l1_map[V_L1_SIZE]; /* code generation context */ TCGContext tcg_ctx; +bool parallel_cpus; /* translation block context */ #ifdef CONFIG_USER_ONLY -- 2.7.4