aboutsummaryrefslogtreecommitdiff
path: root/target/microblaze/cpu.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-09-04 12:08:24 -0700
committerThomas Huth <thuth@redhat.com>2020-09-07 12:34:17 +0200
commit88e74b6122bb40852b1c98befd47a572f0c06930 (patch)
treeffc95474b4531f624455deba98b68409cc98fe30 /target/microblaze/cpu.c
parentcc9962d8ea80b39118d921109fd2f8db308e1d4a (diff)
downloadqemu-88e74b6122bb40852b1c98befd47a572f0c06930.zip
qemu-88e74b6122bb40852b1c98befd47a572f0c06930.tar.gz
qemu-88e74b6122bb40852b1c98befd47a572f0c06930.tar.bz2
target/microblaze: Collected fixes for env->iflags
There are several problems here that can result in soft lockup, depending on exactly where an interrupt or exception is delivered: Include BIMM_FLAG in IFLAGS_TB_MASK, since it needs to follow D_FLAG. Ensure that iflags is 0 when entering an interrupt/exception handler. Add mb_cpu_synchronize_from_tb to restore iflags from tb->flags. The change to t_sync_flags is cosmetic, but makes the code clearer. This fixes the reported regression in acceptance/replay_kernel.py. Fixes: 683a247ed7a4 ("target/microblaze: Store "current" iflags in insn_start") Tested-by: Thomas Huth <thuth@redhat.com> Reported-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20200904190842.2282109-2-richard.henderson@linaro.org> Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'target/microblaze/cpu.c')
-rw-r--r--target/microblaze/cpu.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 67017ec..6392524 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -80,6 +80,16 @@ static void mb_cpu_set_pc(CPUState *cs, vaddr value)
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
cpu->env.pc = value;
+ /* Ensure D_FLAG and IMM_FLAG are clear for the new PC */
+ cpu->env.iflags = 0;
+}
+
+static void mb_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+
+ cpu->env.pc = tb->pc;
+ cpu->env.iflags = tb->flags & IFLAGS_TB_MASK;
}
static bool mb_cpu_has_work(CPUState *cs)
@@ -321,6 +331,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
cc->dump_state = mb_cpu_dump_state;
cc->set_pc = mb_cpu_set_pc;
+ cc->synchronize_from_tb = mb_cpu_synchronize_from_tb;
cc->gdb_read_register = mb_cpu_gdb_read_register;
cc->gdb_write_register = mb_cpu_gdb_write_register;
cc->tlb_fill = mb_cpu_tlb_fill;