From patchwork Fri May 13 00:13:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9087181 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BFEA4BF29F for ; Fri, 13 May 2016 00:28:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DB848201F2 for ; Fri, 13 May 2016 00:28:35 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D8CFF200DC for ; Fri, 13 May 2016 00:28:34 +0000 (UTC) Received: from localhost ([::1]:60421 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b10y1-00085k-MO for patchwork-qemu-devel@patchwork.kernel.org; Thu, 12 May 2016 20:28:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38679) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b10lK-0001vp-P4 for qemu-devel@nongnu.org; Thu, 12 May 2016 20:15:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b10lI-0002zn-SF for qemu-devel@nongnu.org; Thu, 12 May 2016 20:15:26 -0400 Received: from mail-qg0-x241.google.com ([2607:f8b0:400d:c04::241]:36456) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b10lI-0002zg-M9 for qemu-devel@nongnu.org; Thu, 12 May 2016 20:15:24 -0400 Received: by mail-qg0-x241.google.com with SMTP id f74so6834872qge.3 for ; Thu, 12 May 2016 17:15:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PdtPuqprwWQqCpkZcfRLDJJdaUtdQQYfykbr75IR72k=; b=sRRC+Oz3TzA5qWe5KZSE3zQ29B/4aYkfPMpN8IK7Gf/TphVuUiG+a2cYjTzuAQMQjt sc8N1sh5mMx0hI5KV3SB3U6ldxE6cRM/YUxhn1szUZnabPmwkbp/onHqt2rkCPLP2vY4 rBwUykvWKhNeR+zI8iXt3chw1JeZw0tJJGoy8uipYW4PN44U47a700qwc82dobOqtcSb 9718/sUcqjbhexayqFU0g9o+tCeDusQ5wt5BVuYZ561OTNdXHwm2XWxxdJo4SWC9h9VQ r+C2FbPHfsFn3ElNpUIakZE4PGw0cxy1m3js+M9gV17290b8+0MATDYCyUGLsrDDu3VF Nzvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=PdtPuqprwWQqCpkZcfRLDJJdaUtdQQYfykbr75IR72k=; b=DxY8DaOTUEtwdqgti0WRwo3le+eNaSyFMHnFTcCJ3SZ/jOAw3YVc57eCZUknaO57O4 X+98UN9oMirKKU4BSrwbMyq4Fc90NyueflEPa0TnXnl5uYoWABT7wBGZ4a93XjqHlloH gGMWTsc5cMBgFvizIwbPYM18Nj5UXiJCZEOk0piFP/jjMgCe7dLp2ls0psG6HAUdEjnu mgyojs+ZIjTq+toU3Qvjo/XI5XfKKyKO28PJKqL1wvYJ+j8wxaltxNRpzJbooo9Y7Q8f ulpfSslOWBrJ8vWLakA4WKhaDZMZdkh7bSYP46+ar9hXcEFkyJnaCDXItnXUt5zGTzOe 8ZHw== X-Gm-Message-State: AOPr4FX0anEeFJNrVLjzucHOoBp3d+Oze05aiQq/1UG+PUllVrxO/t2MGYi6xzQ0QXvW0w== X-Received: by 10.140.31.74 with SMTP id e68mr12597747qge.86.1463098524430; Thu, 12 May 2016 17:15:24 -0700 (PDT) Received: from bigtime.com ([172.56.44.137]) by smtp.gmail.com with ESMTPSA id w16sm7171321qka.35.2016.05.12.17.15.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 May 2016 17:15:24 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 12 May 2016 14:13:25 -1000 Message-Id: <1463098420-29113-25-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1463098420-29113-1-git-send-email-rth@twiddle.net> References: <1463098420-29113-1-git-send-email-rth@twiddle.net> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c04::241 Subject: [Qemu-devel] [PULL 24/39] tcg: Clean up direct block chaining safety checks 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: peter.maydell@linaro.org, Sergey Fedorov , Sergey Fedorov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sergey Fedorov We don't take care of direct jumps when address mapping changes. Thus we must be sure to generate direct jumps so that they always keep valid even if address mapping changes. Luckily, we can only allow to execute a TB if it was generated from the pages which match with current mapping. Document tcg_gen_goto_tb() declaration and note the reason for destination PC limitations. Some targets with variable length instructions allow TB to straddle a page boundary. However, we make sure that both of TB pages match the current address mapping when looking up TBs. So it is safe to do direct jumps into the both pages. Correct the checks for some of those targets. Given that, we can safely patch a TB which spans two pages. Remove the unnecessary check in cpu_exec() and allow such TBs to be patched. Signed-off-by: Sergey Fedorov Signed-off-by: Sergey Fedorov Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- cpu-exec.c | 7 ++----- target-arm/translate.c | 3 ++- target-cris/translate.c | 4 +++- target-i386/translate.c | 2 +- target-m68k/translate.c | 2 +- target-s390x/translate.c | 2 +- tcg/tcg-op.h | 10 ++++++++++ 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index debc65c..f984dc7 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -508,11 +508,8 @@ int cpu_exec(CPUState *cpu) next_tb = 0; tcg_ctx.tb_ctx.tb_invalidated_flag = 0; } - /* see if we can patch the calling TB. When the TB - spans two pages, we cannot safely do a direct - jump. */ - if (next_tb != 0 && tb->page_addr[1] == -1 - && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { + /* See if we can patch the calling TB. */ + if (next_tb != 0 && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK), next_tb & TB_EXIT_MASK, tb); } diff --git a/target-arm/translate.c b/target-arm/translate.c index 940ec8d..34196a8 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -4054,7 +4054,8 @@ static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) TranslationBlock *tb; tb = s->tb; - if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) || + ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); gen_set_pc_im(s, dest); tcg_gen_exit_tb((uintptr_t)tb + n); diff --git a/target-cris/translate.c b/target-cris/translate.c index a73176c..9c8ff8f 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -524,7 +524,9 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) { TranslationBlock *tb; tb = dc->tb; - if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { + + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) || + (dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(env_pc, dest); tcg_gen_exit_tb((uintptr_t)tb + n); diff --git a/target-i386/translate.c b/target-i386/translate.c index 3a32f65..058d85a 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2094,7 +2094,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) tb = s->tb; /* NOTE: we handle the case where the TB spans two pages here */ if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || - (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { + (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK)) { /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); gen_jmp_im(eip); diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 7560c3a..e2ce6c6 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -861,7 +861,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) if (unlikely(s->singlestep_enabled)) { gen_exception(s, dest, EXCP_DEBUG); } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) || - (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { + (s->insn_pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(QREG_PC, dest); tcg_gen_exit_tb((uintptr_t)tb + n); diff --git a/target-s390x/translate.c b/target-s390x/translate.c index c871ef2..c5179fe 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -610,7 +610,7 @@ static int use_goto_tb(DisasContext *s, uint64_t dest) { /* NOTE: we handle the case where the TB spans two pages here */ return (((dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) - || (dest & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) + || (dest & TARGET_PAGE_MASK) == (s->pc & TARGET_PAGE_MASK)) && !s->singlestep_enabled && !(s->tb->cflags & CF_LAST_IO) && !(s->tb->flags & FLAG_MASK_PER)); diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index c446d3d..ace3961 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -753,6 +753,16 @@ static inline void tcg_gen_exit_tb(uintptr_t val) tcg_gen_op1i(INDEX_op_exit_tb, val); } +/** + * tcg_gen_goto_tb() - output goto_tb TCG operation + * @idx: Direct jump slot index (0 or 1) + * + * See tcg/README for more info about this TCG operation. + * + * NOTE: Direct jumps with goto_tb are only safe within the pages this TB + * resides in because we don't take care of direct jumps when address mapping + * changes, e.g. in tlb_flush(). + */ void tcg_gen_goto_tb(unsigned idx); #if TARGET_LONG_BITS == 32