diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-07-06 17:55:48 +0100 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-07-15 08:02:33 +0100 |
commit | deba78709ae8ce103e2248413857747f804cd1ef (patch) | |
tree | 9e3993af183c57f27270979281ba00e6b92f08a8 /accel/tcg/cpu-exec.c | |
parent | d713cf4d6c71076513a10528303b3e337b4d5998 (diff) | |
download | qemu-deba78709ae8ce103e2248413857747f804cd1ef.zip qemu-deba78709ae8ce103e2248413857747f804cd1ef.tar.gz qemu-deba78709ae8ce103e2248413857747f804cd1ef.tar.bz2 |
accel/tcg: Always lock pages before translation
We had done this for user-mode by invoking page_protect
within the translator loop. Extend this to handle system
mode as well. Move page locking out of tb_link_page.
Reported-by: Liren Wei <lrwei@bupt.edu.cn>
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Diffstat (limited to 'accel/tcg/cpu-exec.c')
-rw-r--r-- | accel/tcg/cpu-exec.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 31aa320..fdd6d3e 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -536,6 +536,26 @@ static void cpu_exec_longjmp_cleanup(CPUState *cpu) if (have_mmap_lock()) { mmap_unlock(); } +#else + /* + * For softmmu, a tlb_fill fault during translation will land here, + * and we need to release any page locks held. In system mode we + * have one tcg_ctx per thread, so we know it was this cpu doing + * the translation. + * + * Alternative 1: Install a cleanup to be called via an exception + * handling safe longjmp. It seems plausible that all our hosts + * support such a thing. We'd have to properly register unwind info + * for the JIT for EH, rather that just for GDB. + * + * Alternative 2: Set and restore cpu->jmp_env in tb_gen_code to + * capture the cpu_loop_exit longjmp, perform the cleanup, and + * jump again to arrive here. + */ + if (tcg_ctx->gen_tb) { + tb_unlock_pages(tcg_ctx->gen_tb); + tcg_ctx->gen_tb = NULL; + } #endif if (qemu_mutex_iothread_locked()) { qemu_mutex_unlock_iothread(); |