aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-05-16 18:46:55 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2024-05-25 13:28:01 +0200
commitc8494cb8b1fd73a1e6a3a6a022a7e4d7e481bdc1 (patch)
tree06c190aca671c6bd40a95298eccbb09fd755cd54
parent9594b593315a56ca459b8bc2de1cad5a91597f37 (diff)
downloadqemu-c8494cb8b1fd73a1e6a3a6a022a7e4d7e481bdc1.zip
qemu-c8494cb8b1fd73a1e6a3a6a022a7e4d7e481bdc1.tar.gz
qemu-c8494cb8b1fd73a1e6a3a6a022a7e4d7e481bdc1.tar.bz2
target/i386: avoid calling gen_eob_syscall before tb_stop
syscall and sysret only have one exit, so they do not need to generate the end-of-translation code inline. It can be deferred to tb_stop. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--target/i386/tcg/translate.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 1246118..06aaaa0 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -168,6 +168,12 @@ typedef struct DisasContext {
*/
#define DISAS_JUMP DISAS_TARGET_3
+/*
+ * EIP has already been updated. Use updated value of
+ * EFLAGS.TF to determine singlestep trap (SYSCALL/SYSRET).
+ */
+#define DISAS_EOB_RECHECK_TF DISAS_TARGET_4
+
/* The environment in which user-only runs is constrained. */
#ifdef CONFIG_USER_ONLY
#define PE(S) true
@@ -3587,7 +3593,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
/* TF handling for the syscall insn is different. The TF bit is checked
after the syscall insn completes. This allows #DB to not be
generated after one has entered CPL0 if TF is set in FMASK. */
- gen_eob_syscall(s);
+ s->base.is_jmp = DISAS_EOB_RECHECK_TF;
break;
case 0x107: /* sysret */
/* For Intel SYSRET is only valid in long mode */
@@ -3606,7 +3612,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
checked after the sysret insn completes. This allows #DB to be
generated "as if" the syscall insn in userspace has just
completed. */
- gen_eob_syscall(s);
+ s->base.is_jmp = DISAS_EOB_RECHECK_TF;
}
break;
case 0x1a2: /* cpuid */
@@ -4810,6 +4816,9 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
case DISAS_EOB_ONLY:
gen_eob(dc);
break;
+ case DISAS_EOB_RECHECK_TF:
+ gen_eob_syscall(dc);
+ break;
case DISAS_EOB_INHIBIT_IRQ:
gen_update_eip_cur(dc);
gen_eob_inhibit_irq(dc);