mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-24 12:35:42 +00:00
0afa0c8ddc
Commit e350d8ca3ac7 ("target/mips: optimize indirect branches") made indirect branches able to directly find the next TB and jump straight to it without breaking out of translated code and going around the main execution loop. This breaks the assumption in target/mips/translate.c that BS_STOP is sufficient to cause pending interrupts to be handled, since interrupts are only checked in the main loop. Fix a few of these assumptions by using gen_save_pc to update the saved PC and using BS_EXCP instead of BS_STOP: - [D]MFC0 CP0_Count may trigger a timer interrupt which should be immediately handled. - [D]MTC0 CP0_Cause may trigger an interrupt (but in fact translation was only even being stopped in the DMTC0 case). - [D]MTC0 CP0_<any> when icount is used is assumed could potentially cause interrupts. - EI may trigger an interrupt which was pending. I specifically hit this case when running KVM nested in mipsel-softmmu. A timer interrupt while the 2nd guest was executing is caught by KVM which switches back to the normal Linux exception base and re-enables interrupts with EI. Since the above commit QEMU doesn't leave translated code until the nested KVM has already restored the KVM exception base and returned to the 2nd guest, at which point it is too late to check for pending interrupts and it gets stuck in an infinite loop of unhandled interrupts. Something similar was needed for ARM in commit b29fd33db578 ("target/arm: use DISAS_EXIT for eret handling"). Backports commit b74cddcbf6063f684725e3f8bca49a68e30cba71 from qemu |
||
---|---|---|
.. | ||
cpu-qom.h | ||
cpu.c | ||
cpu.h | ||
dsp_helper.c | ||
helper.c | ||
helper.h | ||
lmi_helper.c | ||
Makefile.objs | ||
mips-defs.h | ||
msa_helper.c | ||
op_helper.c | ||
TODO | ||
translate.c | ||
translate_init.c | ||
unicorn.c | ||
unicorn.h |