diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2024-05-16 18:46:55 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2024-05-25 13:28:01 +0200 |
commit | c8494cb8b1fd73a1e6a3a6a022a7e4d7e481bdc1 (patch) | |
tree | 06c190aca671c6bd40a95298eccbb09fd755cd54 | |
parent | 9594b593315a56ca459b8bc2de1cad5a91597f37 (diff) | |
download | qemu-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.c | 13 |
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); |