From patchwork Wed Sep 9 16:01:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Sorokin X-Patchwork-Id: 515941 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1CD42140180 for ; Thu, 10 Sep 2015 02:52:44 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=yandex.ru header.i=@yandex.ru header.b=B5WTw09f; dkim-atps=neutral Received: from localhost ([::1]:44039 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZZiby-0004wH-7f for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2015 12:52:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59673) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZZhpI-0004x6-6C for qemu-devel@nongnu.org; Wed, 09 Sep 2015 12:02:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZZhpC-0002ZV-Qf for qemu-devel@nongnu.org; Wed, 09 Sep 2015 12:02:22 -0400 Received: from forward20h.cmail.yandex.net ([87.250.230.162]:47654) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZZhpC-0002ZJ-B0 for qemu-devel@nongnu.org; Wed, 09 Sep 2015 12:02:18 -0400 Received: from smtp1h.mail.yandex.net (smtp1h.mail.yandex.net [84.201.187.144]) by forward20h.cmail.yandex.net (Yandex) with ESMTP id 73C8621A39; Wed, 9 Sep 2015 19:02:15 +0300 (MSK) Received: from smtp1h.mail.yandex.net (localhost [127.0.0.1]) by smtp1h.mail.yandex.net (Yandex) with ESMTP id F213613411D7; Wed, 9 Sep 2015 19:02:14 +0300 (MSK) Received: by smtp1h.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id uwXjq5DciK-2EweTtho; Wed, 9 Sep 2015 19:02:14 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1441814534; bh=iHP9y7VfRo14uRtdI/3a/gI3rSp4L6NnNImQ8kASWEE=; h=From:To:Cc:Subject:Date:Message-Id:X-Mailer; b=B5WTw09fUQ2VijOIoXfEWls6u+NNiIxwH4+SVmNXLzfrF9Uos/RM59fePNFcViI6k iHpgLqyPtIFNMUCGKtojQ30p1YDCPqNwvaOqHXSUjmetbLZQqhwcZlTM/7qbeWBITH QRv0TyRLNsSW2wz2RMq5zSn9ihUcH9kema6IY7w0= Authentication-Results: smtp1h.mail.yandex.net; dkim=pass header.i=@yandex.ru X-Yandex-ForeignMX: US From: Sergey Sorokin To: qemu-devel@nongnu.org Date: Wed, 9 Sep 2015 19:01:57 +0300 Message-Id: <1441814517-16041-1-git-send-email-afarallax@yandex.ru> X-Mailer: git-send-email 1.9.3 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.250.230.162 Cc: Peter Maydell , Sergey Sorokin Subject: [Qemu-devel] [PATCH v3] target-arm: Break the TB after ISB to execute self-modified code correctly X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org If any store instruction writes the code inside the same TB after this store insn, the execution of the TB must be stopped to execute new code correctly. As described in ARMv8 manual D3.4.6 a self-modified code need to do IC invalidation to be valid, and ISB after it. So it's enough to end the TB after ISB instruction on the code translation. Also this TB break is necessary to take any pending interrupts immediately according to ARMv8 ARM D1.14.4. Signed-off-by: Sergey Sorokin --- Changes since previous version: * ARMv6 ISB was also fixed. * Second reason for TB breaking was mentioned in comments and the commit message. target-arm/helper.c | 6 +++++- target-arm/translate-a64.c | 8 +++++++- target-arm/translate.c | 17 +++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index fc4b65f..a12841f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -627,8 +627,12 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { { .name = "MVA_prefetch", .cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1, .access = PL1_W, .type = ARM_CP_NOP }, + /* We need to break the TB after ISB to execute a self-modified code + * correctly and also to take any pending interrupts immediately. + * So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag. + */ { .name = "ISB", .cp = 15, .crn = 7, .crm = 5, .opc1 = 0, .opc2 = 4, - .access = PL0_W, .type = ARM_CP_NOP }, + .access = PL0_W, .type = ARM_CP_NO_RAW, .writefn = arm_cp_write_ignore }, { .name = "DSB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 4, .access = PL0_W, .type = ARM_CP_NOP }, { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5, diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index faece2c..11dfd4b 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1235,9 +1235,15 @@ static void handle_sync(DisasContext *s, uint32_t insn, return; case 4: /* DSB */ case 5: /* DMB */ - case 6: /* ISB */ /* We don't emulate caches so barriers are no-ops */ return; + case 6: /* ISB */ + /* We need to break the TB after this insn to execute + * a self-modified code correctly and also to take + * any pending interrupts immediately. + */ + s->is_jmp = DISAS_UPDATE; + return; default: unallocated_encoding(s); return; diff --git a/target-arm/translate.c b/target-arm/translate.c index 0bd3d05..00e0e4d 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -7689,10 +7689,16 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) return; case 4: /* dsb */ case 5: /* dmb */ - case 6: /* isb */ ARCH(7); /* We don't emulate caches so these are a no-op. */ return; + case 6: /* isb */ + /* We need to break the TB after this insn to execute + * a self-modified code correctly and also to take + * any pending interrupts immediately. + */ + gen_lookup_tb(s); + return; default: goto illegal_op; } @@ -9999,9 +10005,16 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw break; case 4: /* dsb */ case 5: /* dmb */ - case 6: /* isb */ /* These execute as NOPs. */ break; + case 6: /* isb */ + /* We need to break the TB after this insn + * to execute a self-modified code correctly + * and also to take any pending interrupts + * immediately. + */ + gen_lookup_tb(s); + return; default: goto illegal_op; }