[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instructi
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block |
Date: |
Mon, 20 Aug 2018 11:31:48 +0100 |
From: Roman Kapl <address@hidden>
If an instruction is conditional (like CBZ) and it is executed
conditionally (using the ITx instruction), a jump to an undefined
label is generated, and QEMU crashes.
CBZ in IT block is an UNPREDICTABLE behavior, but we should not
crash. Honouring the condition code is allowed by the spec in this
case (constrained unpredictable, ARMv8, section K1.1.7), and matches
what we do for other "UNPREDICTABLE inside an IT block" instructions.
Fix the 'skip on condition' code to create a new label only if it
does not already exist. Previously multiple labels were created, but
only the last one of them was set.
Signed-off-by: Roman Kapl <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
Message-id: address@hidden
[PMM: fixed ^ 1 being applied to wrong argument, fixed typo]
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
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 f845da7c638..14aa2cd3cd5 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 = DISAS_UPDATE;
}
+/* Generate a label used for skipping this instruction */
+static void arm_gen_condlabel(DisasContext *s)
+{
+ if (!s->condjmp) {
+ s->condlabel = gen_new_label();
+ s->condjmp = 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 ^ 1, s->condlabel);
+}
+
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 != 0xe) {
/* if not always execute, we generate a conditional jump to
next instruction */
- s->condlabel = gen_new_label();
- arm_gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
+ arm_skip_unless(s, cond);
}
if ((insn & 0x0f900000) == 0x03000000) {
if ((insn & (1 << 21)) == 0) {
@@ -11205,9 +11219,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t
insn)
/* Conditional branch. */
op = (insn >> 22) & 0xf;
/* Generate a conditional jump to next instruction. */
- s->condlabel = gen_new_label();
- arm_gen_test_cc(op ^ 1, s->condlabel);
- s->condjmp = 1;
+ arm_skip_unless(s, op);
/* offset[11:1] = insn[10:0] */
offset = (insn & 0x7ff) << 1;
@@ -12131,8 +12143,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t
insn)
case 1: case 3: case 9: case 11: /* czb */
rm = insn & 7;
tmp = load_reg(s, rm);
- s->condlabel = gen_new_label();
- s->condjmp = 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, uint32_t
insn)
break;
}
/* generate a conditional jump to next instruction */
- s->condlabel = gen_new_label();
- arm_gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
+ arm_skip_unless(s, cond);
/* jump to the offset */
val = (uint32_t)s->pc + 2;
@@ -12676,9 +12685,7 @@ static void thumb_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cpu)
uint32_t cond = dc->condexec_cond;
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
- dc->condlabel = gen_new_label();
- arm_gen_test_cc(cond ^ 1, dc->condlabel);
- dc->condjmp = 1;
+ arm_skip_unless(dc, cond);
}
}
--
2.18.0
- [Qemu-devel] [PULL 10/25] target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked), (continued)
- [Qemu-devel] [PULL 10/25] target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked), Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 13/25] sdhci: add i.MX SD Stable Clock bit, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 12/25] hw/arm/virt: Add virt-3.1 machine type, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 03/25] hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 17/25] hw/timer/m48t59: Move away from old_mmio accessors, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 14/25] hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 09/25] target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 16/25] hw/misc: Remove mmio_interface device, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 19/25] nvic: Expose NMI line, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 02/25] docs/generic-loader: mention U-Boot and Intel HEX executable formats, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block,
Peter Maydell <=
- [Qemu-devel] [PULL 15/25] memory: Remove MMIO request_ptr APIs, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 18/25] hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 22/25] hw/dma/pl080: Don't use CPU address space for DMA accesses, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 23/25] hw/dma/pl080: Provide device reset function, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 21/25] hw/dma/pl080: Support all three interrupt lines, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 20/25] hw/dma/pl080: Allow use as embedded-struct device, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 24/25] hw/dma/pl080: Correct bug in register address decode logic, Peter Maydell, 2018/08/20
- [Qemu-devel] [PULL 25/25] hw/dma/pl080: Remove hw_error() if DMA is enabled, Peter Maydell, 2018/08/20
- Re: [Qemu-devel] [PULL 00/25] target-arm queue, Peter Maydell, 2018/08/20