qemu-cr16/target
Peter Maydell ac32612b93 target/arm: Don't assert() for ISB/SB inside IT block
If the guest code has an ISB or SB insn inside an IT block, we
generate incorrect code which trips a TCG assertion:

qemu-system-arm: ../tcg/tcg-op.c:3343: void tcg_gen_goto_tb(unsigned int): Assertion `(tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0' failed.

This is because we call gen_goto_tb(dc, 1, ...) twice:

 brcond_i32 ZF,$0x0,ne,$L1
 add_i32 pc,pc,$0x4
 goto_tb $0x1
 exit_tb $0x73d948001b81
 set_label $L1
 add_i32 pc,pc,$0x4
 goto_tb $0x1
 exit_tb $0x73d948001b81

Both calls are in arm_tr_tb_stop(), one for the
DISAS_NEXT/DISAS_TOO_MANY handling, and one for the dc->condjump
condition-failed codepath.  The DISAS_NEXT handling doesn't have this
problem because arm_post_translate_insn() does the handling of "emit
the label for the condition-failed conditional execution" and so
arm_tr_tb_stop() doesn't have dc->condjump set.  But for
DISAS_TOO_MANY we don't do that.

Fix the bug by making arm_post_translate_insn() handle the
DISAS_TOO_MANY case.  This only affects the SB and ISB insns when
used in Thumb mode inside an IT block: only these insns specifically
set is_jmp to TOO_MANY, and their A32 encodings are unconditional.

For the major TOO_MANY case (breaking the TB because it would cross a
page boundary) we do that check and set is_jmp to TOO_MANY only after
the call to arm_post_translate_insn(); so arm_post_translate_insn()
sees is_jmp == DISAS_NEXT, and  we emit the correct code for that
situation.

With this fix we generate the somewhat more sensible set of TCG ops:
 brcond_i32 ZF,$0x0,ne,$L1
 set_label $L1
 add_i32 pc,pc,$0x4
 goto_tb $0x1
 exit_tb $0x7c5434001b81

(NB: the TCG optimizer doesn't optimize out the jump-to-next, but
we can't really avoid emitting it because we don't know at the
point we're emitting the handling for the condexec check whether
this insn is going to happen to be a nop for us or not.)

Cc: qemu-stable@nongnu.org
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2942
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250501125544.727038-1-peter.maydell@linaro.org
(cherry picked from commit 8ed7c0b648)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-05-08 10:22:21 +03:00
..
alpha target/alpha: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
arm target/arm: Don't assert() for ISB/SB inside IT block 2025-05-08 10:22:21 +03:00
avr target/avr: Improve decode of LDS, STS 2025-04-24 10:30:44 +03:00
hexagon target/hexagon: Remove CPUClass:has_work() handler 2025-03-09 17:00:47 +01:00
hppa target/hppa: Remove duplicated CPU_RESOLVING_TYPE definition 2025-03-31 21:32:43 +02:00
i386 target/i386/hvf: fix lflags_to_rflags 2025-04-24 10:27:39 +03:00
loongarch target/loongarch: Fix the cpu unplug resource leak 2025-03-27 20:29:17 +08:00
m68k target/m68k: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
microblaze target/microblaze: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
mips target/mips: Fix MIPS16e translation 2025-04-29 10:03:15 +03:00
openrisc target/openrisc: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
ppc hw/core: Get default_cpu_type calling machine_class_default_cpu_type() 2025-04-29 10:01:21 +03:00
riscv Revert "target/riscv/kvm: add missing KVM CSRs" 2025-03-28 16:50:25 +10:00
rx target/rx: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
s390x target/s390x: Fix a typo in s390_cpu_class_init() 2025-03-27 08:59:35 +01:00
sh4 target/sh4: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
sparc target/sparc: Log unimplemented ASI load/store accesses 2025-03-31 21:32:43 +02:00
tricore target/tricore: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
xtensa target/xtensa: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
Kconfig target/cris: Remove the deprecated CRIS target 2024-09-13 20:11:13 +02:00
meson.build target/cris: Remove the deprecated CRIS target 2024-09-13 20:11:13 +02:00