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 a self-modified code need to do IC invalidation to be valid, and ISB after it. So it's enough to end the TB after ISB instruction on the code translation.
Signed-off-by: Sergey Sorokin <afaral...@yandex.ru> --- In the first version of the patch the TB was broken after IC invalidation instead of ISB. target-arm/translate-a64.c | 7 ++++++- target-arm/translate.c | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 5c13e15..9a900c9 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1234,9 +1234,14 @@ 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. + */ + s->is_jmp = DISAS_UPDATE; + return; default: unallocated_encoding(s); return; diff --git a/target-arm/translate.c b/target-arm/translate.c index e27634f..236b3a5 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -7689,10 +7689,15 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) return; case 4: /* dsb */ case 5: /* dmb */ - case 6: /* isb */ ARCH(7); /* We don't emulate caches so these are a no-op. */ return; + case 6: /* isb */ + /* We need to break the TB after this insn to execute + * a self-modified code correctly. + */ + gen_lookup_tb(s); + return; default: goto illegal_op; } @@ -9999,9 +10004,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw break; case 4: /* dsb */ case 5: /* dmb */ - case 6: /* isb */ /* These execute as NOPs. */ break; + case 6: /* isb */ + /* We need to break the TB after this insn + * to execute a self-modified code correctly. + */ + gen_lookup_tb(s); + return; default: goto illegal_op; } -- 1.9.3