aboutsummaryrefslogtreecommitdiff
path: root/accel/tcg/cpu-exec.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-07-06 17:55:48 +0100
committerRichard Henderson <richard.henderson@linaro.org>2023-07-15 08:02:33 +0100
commitdeba78709ae8ce103e2248413857747f804cd1ef (patch)
tree9e3993af183c57f27270979281ba00e6b92f08a8 /accel/tcg/cpu-exec.c
parentd713cf4d6c71076513a10528303b3e337b4d5998 (diff)
downloadqemu-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.c20
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();