qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] target/i386: Give IRQs a chance when resetting HF_INHIBIT_IR


From: Ruihan Li
Subject: Re: [PATCH] target/i386: Give IRQs a chance when resetting HF_INHIBIT_IRQ_MASK
Date: Tue, 19 Dec 2023 23:04:20 +0800

Hi all,

On Mon, Dec 11, 2023 at 03:01:48AM +0800, Ruihan Li wrote:
> When emulated with QEMU, interrupts will never come in the following
> loop. However, if the NOP instruction is uncommented, interrupts will
> fire as normal.
> 
>       loop:
>               cli
>               call do_sti
>               jmp loop
> 
>       do_sti:
>               sti
>               # nop
>               ret
> 
> This behavior is different from that of a real processor. For example,
> if KVM is enabled, interrupts will always fire regardless of whether the
> NOP instruction is commented or not. Also, the Intel Software Developer
> Manual states that after the STI instruction is executed, the interrupt
> inhibit should end as soon as the next instruction (e.g., the RET
> instruction if the NOP instruction is commented) is executed.
> 
> This problem is caused because the previous code may choose not to end
> the TB even if the HF_INHIBIT_IRQ_MASK has just been reset (e.g., in the
> case where the RET instruction is immediately followed by the STI
> instruction), so that IRQs may not have a change to trigger. This commit
> fixes the problem by always terminating the current TB to give IRQs a
> chance to trigger when HF_INHIBIT_IRQ_MASK is reset.
> 
> Signed-off-by: Ruihan Li <lrh2000@pku.edu.cn>
> ---
> The same problem was discovered two years ago, see [StackOverflow][so].
> 
>  [so]: 
> https://stackoverflow.com/questions/68135305/executing-ret-after-sti-doesnt-start-interrupts
> 
>  target/i386/tcg/translate.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 587d886..6b7deb5 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -2767,13 +2767,19 @@ static void gen_bnd_jmp(DisasContext *s)
>  static void
>  do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
>  {
> +    bool inhibit_reset;
> +
>      gen_update_cc_op(s);
>  
>      /* If several instructions disable interrupts, only the first does it.  
> */
>      if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
>          gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
> -    } else {
> +        inhibit_reset = false;
> +    } else if (!inhibit && (s->flags & HF_INHIBIT_IRQ_MASK)) {
>          gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
> +        inhibit_reset = true;
> +    } else {
> +        inhibit_reset = false;
>      }
>  
>      if (s->base.tb->flags & HF_RF_MASK) {
> @@ -2784,7 +2790,9 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool 
> recheck_tf, bool jr)
>          tcg_gen_exit_tb(NULL, 0);
>      } else if (s->flags & HF_TF_MASK) {
>          gen_helper_single_step(tcg_env);
> -    } else if (jr) {
> +    } else if (jr &&
> +               /* give irqs a chance to happen */
> +               !inhibit_reset) {
>          tcg_gen_lookup_and_goto_ptr();
>      } else {
>          tcg_gen_exit_tb(NULL, 0);
> -- 
> 2.43.0

A friendly ping.

Anyone here to confirm this BUG and/or comment on the patch?

Thanks,
Ruihan Li




reply via email to

[Prev in Thread] Current Thread [Next in Thread]