qemu-cr16/target/arm
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
..
hvf target/arm/hvf: sign extend the data for a load operation when SSE=1 2025-02-25 15:32:58 +00:00
tcg target/arm: Don't assert() for ISB/SB inside IT block 2025-05-08 10:22:21 +03:00
arch_dump.c target/arm: Move arm_current_el() and arm_el_is_aa64() to internals.h 2025-03-14 10:49:20 +00:00
arm-powerctl.c include: Rename sysemu/ -> system/ 2024-12-20 17:44:56 +01:00
arm-powerctl.h
arm-qmp-cmds.c qapi: Move include/qapi/qmp/ to include/qobject/ 2025-02-10 15:33:16 +01:00
common-semi-target.h target/arm/common-semi-target.h: Remove unnecessary boot.h include 2023-10-19 14:32:13 +01:00
cortex-regs.c target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing 2023-05-18 11:39:33 +01:00
cpregs.h target/arm: Move A32_BANKED_REG_{GET,SET} macros to cpregs.h 2025-03-14 10:49:20 +00:00
cpu-features.h target/arm: Plumb FEAT_RPRES frecpe and frsqrte through to new helper 2025-02-11 16:22:07 +00:00
cpu-param.h target/*: Remove TARGET_LONG_BITS from cpu-param.h 2025-02-08 12:41:33 -08:00
cpu-qom.h target/arm: Add support for Non-maskable Interrupt 2024-04-25 10:21:04 +01:00
cpu.c target/arm: Move has_work() from CPUClass to SysemuCPUOps 2025-03-09 17:00:47 +01:00
cpu.h target/arm: Move arm_current_el() and arm_el_is_aa64() to internals.h 2025-03-14 10:49:20 +00:00
cpu64.c target/arm: change default pauth algorithm to impdef 2025-01-13 12:35:34 +00:00
debug_helper.c target/arm: Make dummy debug registers RAZ, not NOP 2025-03-07 10:33:41 +00:00
gdbstub.c include: Rename sysemu/ -> system/ 2024-12-20 17:44:56 +01:00
gdbstub64.c gdbstub: Add support for MTE in system mode 2024-09-10 23:33:51 +01:00
gtimer.h target/arm: Document the architectural names of our GTIMERs 2025-03-07 10:08:21 +00:00
helper.c target/arm: HCR_EL2.RW should be RAO/WI if EL1 doesn't support AArch32 2025-03-14 12:54:33 +00:00
helper.h target/arm: Plumb FEAT_RPRES frecpe and frsqrte through to new helper 2025-02-11 16:22:07 +00:00
hvf_arm.h hvf: arm: Implement and use hvf_get_physical_address_range 2024-09-13 15:31:47 +01:00
hyp_gdbstub.c target/arm: remove break after g_assert_not_reached() 2024-09-24 13:53:35 +02:00
idau.h
internals.h target/arm: SCR_EL3.RW should be treated as 1 if EL2 doesn't support AArch32 2025-03-14 10:49:20 +00:00
Kconfig kconfig: express dependency of individual boards on libfdt 2024-05-10 15:45:15 +02:00
kvm-consts.h exec: Rename NEED_CPU_H -> COMPILING_PER_TARGET 2024-04-26 09:49:51 +02:00
kvm-stub.c target/arm: Avoid bare abort() or assert(0) 2022-05-05 09:35:51 +01:00
kvm.c acpi/ghes: better name GHES memory error function 2025-01-15 13:07:10 -05:00
kvm_arm.h include: Rename sysemu/ -> system/ 2024-12-20 17:44:56 +01:00
machine.c include: Rename sysemu/ -> system/ 2024-12-20 17:44:56 +01:00
meson.build target/arm: Rename vfp_helper.c to vfp_fpscr.c 2025-02-25 15:32:58 +00:00
multiprocessing.h target/arm: Expose arm_cpu_mp_affinity() in 'multiprocessing.h' header 2024-01-26 11:30:48 +00:00
ptw.c tcg: Remove TCG_OVERSIZED_GUEST 2025-02-18 07:33:42 -08:00
syndrome.h target/arm: fix exception syndrome for AArch32 bkpt insn 2024-02-02 13:51:57 +00:00
tcg-stubs.c target/arm: Move softfloat specific FPCR/FPSR handling to tcg/ 2025-02-25 15:32:58 +00:00
trace-events target/arm: Implement FEAT_ECV CNTPOFF_EL2 handling 2024-03-07 12:19:03 +00:00
trace.h
vfp_fpscr.c target/arm: Rename vfp_helper.c to vfp_fpscr.c 2025-02-25 15:32:58 +00:00