summaryrefslogtreecommitdiffstats
path: root/target-arm/helper.c
diff options
context:
space:
mode:
authorSergey Sorokin2015-10-16 12:14:52 +0200
committerPeter Maydell2015-10-16 12:14:52 +0200
commit6df99dec9e81838423d723996e96236693fa31fe (patch)
tree064423bd751b2305a233d2a30277aa877ffedd95 /target-arm/helper.c
parenttarget-arm: Add missing 'static' attribute (diff)
downloadqemu-6df99dec9e81838423d723996e96236693fa31fe.tar.gz
qemu-6df99dec9e81838423d723996e96236693fa31fe.tar.xz
qemu-6df99dec9e81838423d723996e96236693fa31fe.zip
target-arm: Break the TB after ISB to execute self-modified code correctly
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 self-modifying code must do an IC invalidation to be valid, and an 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 after an ISB (as required by ARMv8 ARM D1.14.4). Signed-off-by: Sergey Sorokin <afarallax@yandex.ru> [PMM: tweaked commit message and comments slightly] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 584f6df80d..b4986705c4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -657,8 +657,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 self-modifying 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,