diff options
author | Sergey Sorokin <afarallax@yandex.ru> | 2015-10-16 11:14:52 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-10-16 11:14:52 +0100 |
commit | 6df99dec9e81838423d723996e96236693fa31fe (patch) | |
tree | 064423bd751b2305a233d2a30277aa877ffedd95 /target-arm/translate-a64.c | |
parent | 82c39f6a8898b028515eddcdbc4ae50959d0af5d (diff) |
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/translate-a64.c')
-rw-r--r-- | target-arm/translate-a64.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index e65e309535..a4580c07a6 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1230,9 +1230,15 @@ static void handle_sync(DisasContext *s, uint32_t insn, return; case 4: /* DSB */ case 5: /* DMB */ - case 6: /* ISB */ /* We don't emulate caches so barriers are no-ops */ return; + case 6: /* ISB */ + /* We need to break the TB after this insn to execute + * a self-modified code correctly and also to take + * any pending interrupts immediately. + */ + s->is_jmp = DISAS_UPDATE; + return; default: unallocated_encoding(s); return; |