From nobody Wed Nov 5 11:00:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534421245821180.90848519880421; Thu, 16 Aug 2018 05:07:25 -0700 (PDT) Received: from localhost ([::1]:55235 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqH3g-00019A-2m for importer@patchew.org; Thu, 16 Aug 2018 08:07:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37267) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqH2B-0008CH-GK for qemu-devel@nongnu.org; Thu, 16 Aug 2018 08:05:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fqH29-0004Al-M9 for qemu-devel@nongnu.org; Thu, 16 Aug 2018 08:05:47 -0400 Received: from mail.sysgo.com ([176.9.12.79]:54484) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fqH25-00047Q-8R; Thu, 16 Aug 2018 08:05:41 -0400 From: Roman Kapl To: Date: Thu, 16 Aug 2018 14:05:33 +0200 Message-Id: <20180816120533.6587-1-rka@sysgo.com> X-Mailer: git-send-email 2.11.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 176.9.12.79 Subject: [Qemu-devel] [PATCH v2] target/arm: crash on conditional instr in it block 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 , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Roman Kapl Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" If an instruction is conditional (like CBZ) and it is executed conditionally (using the ITx instruction), a jump to undefined label is generated. CBZ in IT block is an unpredictable behavior, and honouring the condition c= ode is allowed by the spec in this case (constrained unpredictable, ARMv8, sect= ion K1.1.7). Fix the 'skip on condtion' code to create a new label only if it does not already exist. Previously multiple labels were created, but only the last o= ne of them was set. Signed-off-by: Roman Kapl Reviewed-by: Richard Henderson --- v1 -> v2 Split arm_conditional_skip into arm_gen_condlabel and arm_skip_unless to a) cover all usages b) do not force callers to ^1 the condition Add note about CBZ in IT block to the commit message. target/arm/translate.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index f845da7c63..e54e0ca2ba 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -8480,6 +8480,22 @@ static void gen_srs(DisasContext *s, s->base.is_jmp =3D DISAS_UPDATE; } =20 +/* Generate a labe used for skipping this instruction */ +static void arm_gen_condlabel(DisasContext *s) +{ + if (!s->condjmp) { + s->condlabel =3D gen_new_label(); + s->condjmp =3D 1; + } +} + +/* Skip this instruction if the ARM condition is false */ +static void arm_skip_unless(DisasContext *s, uint32_t cond) +{ + arm_gen_condlabel(s); + arm_gen_test_cc(cond, s->condlabel ^ 1); +} + static void disas_arm_insn(DisasContext *s, unsigned int insn) { unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh; @@ -8709,9 +8725,7 @@ static void disas_arm_insn(DisasContext *s, unsigned = int insn) if (cond !=3D 0xe) { /* if not always execute, we generate a conditional jump to next instruction */ - s->condlabel =3D gen_new_label(); - arm_gen_test_cc(cond ^ 1, s->condlabel); - s->condjmp =3D 1; + arm_skip_unless(s, cond); } if ((insn & 0x0f900000) =3D=3D 0x03000000) { if ((insn & (1 << 21)) =3D=3D 0) { @@ -11205,9 +11219,7 @@ static void disas_thumb2_insn(DisasContext *s, uint= 32_t insn) /* Conditional branch. */ op =3D (insn >> 22) & 0xf; /* Generate a conditional jump to next instruction. */ - s->condlabel =3D gen_new_label(); - arm_gen_test_cc(op ^ 1, s->condlabel); - s->condjmp =3D 1; + arm_skip_unless(s, op); =20 /* offset[11:1] =3D insn[10:0] */ offset =3D (insn & 0x7ff) << 1; @@ -12131,8 +12143,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) case 1: case 3: case 9: case 11: /* czb */ rm =3D insn & 7; tmp =3D load_reg(s, rm); - s->condlabel =3D gen_new_label(); - s->condjmp =3D 1; + arm_gen_condlabel(s); if (insn & (1 << 11)) tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel); else @@ -12295,9 +12306,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) break; } /* generate a conditional jump to next instruction */ - s->condlabel =3D gen_new_label(); - arm_gen_test_cc(cond ^ 1, s->condlabel); - s->condjmp =3D 1; + arm_skip_unless(s, cond); =20 /* jump to the offset */ val =3D (uint32_t)s->pc + 2; @@ -12676,9 +12685,7 @@ static void thumb_tr_translate_insn(DisasContextBas= e *dcbase, CPUState *cpu) uint32_t cond =3D dc->condexec_cond; =20 if (cond !=3D 0x0e) { /* Skip conditional when condition is AL= . */ - dc->condlabel =3D gen_new_label(); - arm_gen_test_cc(cond ^ 1, dc->condlabel); - dc->condjmp =3D 1; + arm_skip_unless(dc, cond); } } =20 --=20 2.11.0