From patchwork Thu Apr 28 21:33:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: sergey.fedorov@linaro.org X-Patchwork-Id: 8975201 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6E1609F1C1 for ; Thu, 28 Apr 2016 21:39:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8693820117 for ; Thu, 28 Apr 2016 21:39:08 +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 934A2200CC for ; Thu, 28 Apr 2016 21:39:07 +0000 (UTC) Received: from localhost ([::1]:51106 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1avteM-0004Az-TW for patchwork-qemu-devel@patchwork.kernel.org; Thu, 28 Apr 2016 17:39:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1avtZf-0002ur-F8 for qemu-devel@nongnu.org; Thu, 28 Apr 2016 17:34:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1avtZe-0005TE-0e for qemu-devel@nongnu.org; Thu, 28 Apr 2016 17:34:15 -0400 Received: from mail-lf0-x22f.google.com ([2a00:1450:4010:c07::22f]:35152) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1avtZd-0005T8-LQ for qemu-devel@nongnu.org; Thu, 28 Apr 2016 17:34:13 -0400 Received: by mail-lf0-x22f.google.com with SMTP id c126so111930845lfb.2 for ; Thu, 28 Apr 2016 14:34:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jAVzd6knGHS8ni0KNTX7DqfMPj8ytt8fOnoi3hXdErA=; b=hxlo574kGyS9zexpwIrLOkv+Gd3UIkSOZUM/pZdqzpvzfzzcBaAi3r+Cwdr9EPlOCU Ck+e92ZVDQuOt63Bzaaq9NlI34l4Kdk6+MxFjRHsMw5RM+Iv4kfVcLwUAZ/oUANyO3iL VFLsuRAibCNfbdwqlza07u71dJUWTrNFcX3VI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jAVzd6knGHS8ni0KNTX7DqfMPj8ytt8fOnoi3hXdErA=; b=k7UWkGRm107c4dVb7CstMhU0WhD+g8Fz3Ox+x5tBAH1OCFkoMFhXb9zIetD3La8GcF g6Ab4DYWE5IH9qxCaBd+ng9lYh+7Oisy3z9WXHiWAEpByC7r8K2ISukDow/GX+oZAjlO Lwl5TJ9qA5EVmYh/ZGiqL0n2Y9COrHPA0v0qFFHIF9qoOMNbodngGUkKNQlcG4zfEptb fA+O3gkHzGY4f/Iw8fxgSiyS05UNR5+ra1cjMJS3Z3a1SUYl5RFiKQrc0Nuzs2Zs4dph Z74d1tZ5hdGDBLjbH+w2CqRbK7oD/c8sOHayLBWzjMgRl4AniemSH0SGnWQYSqvMIA1K RSSg== X-Gm-Message-State: AOPr4FVdGgUkkSjQm9ULGGaShG547vBKaOkOtPwthACeW1RZjcPs1327dtFFrNWpoREYCS5B X-Received: by 10.112.50.107 with SMTP id b11mr7488678lbo.15.1461879252907; Thu, 28 Apr 2016 14:34:12 -0700 (PDT) Received: from sergey-laptop.Dlink (broadband-46-188-121-115.2com.net. [46.188.121.115]) by smtp.gmail.com with ESMTPSA id m7sm1953148lbr.6.2016.04.28.14.34.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 Apr 2016 14:34:11 -0700 (PDT) From: Sergey Fedorov To: qemu-devel@nongnu.org Date: Fri, 29 Apr 2016 00:33:54 +0300 Message-Id: <1461879235-7694-10-git-send-email-sergey.fedorov@linaro.org> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1461879235-7694-1-git-send-email-sergey.fedorov@linaro.org> References: <1461879235-7694-1-git-send-email-sergey.fedorov@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:4010:c07::22f Subject: [Qemu-devel] [PATCH v5 09/10] 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 , Eduardo Habkost , Sergey Fedorov , Peter Crosthwaite , "Edgar E. Iglesias" , Alexander Graf , qemu-arm@nongnu.org, Paolo Bonzini , Sergey Fedorov , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson 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 --- Changes in v4: * Documented tcg_gen_goto_tb() declaration * Destination PC check explanatory comments moved to tcg_gen_goto_tb() declaration comment * Updated commit message 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 debc65ca691a..f984dc71cbf1 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 940ec8d981d1..34196a821772 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 a73176c118b0..9c8ff8f2308a 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 3a32f65f8de8..058d85a1abf7 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 7560c3a80841..e2ce6c615e07 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 c871ef2bb302..c5179fe05d7e 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 c446d3dc7293..ace39619ef89 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