NetBSD-Bugs archive

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

Re: port-amd64/51934: ATF tests hang at kernel/t_ptrace_wait:signal4 under qemu



The following reply was made to PR port-amd64/51934; it has been noted by GNATS.

From: "J. Hannken-Illjes" <hannken%eis.cs.tu-bs.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: port-amd64/51934: ATF tests hang at kernel/t_ptrace_wait:signal4
 under qemu
Date: Fri, 17 Feb 2017 09:18:41 +0100

 This is a qemu/amd64 bug fixed recently with these two commits:
 
 commit c52ab08aee6f7d4717fc6b517174043126bd302f
 Author: Doug Evans <dje%google.com@localhost>
 Date:   Tue Dec 6 23:06:30 2016 +0000
 
     target-i386: Fix eflags.TF/#DB handling of syscall/sysret insns
     
     The syscall and sysret instructions behave a bit differently:
     TF is checked after the instruction completes.
     This allows the o/s to disable #DB at a syscall by adding TF to FMASK.
     And then when the sysret is executed the #DB is taken "as if" the
     syscall insn just completed.
     
 commit 410e98146ffde201ab4c778823ac8beaa74c4c3f
 Author: Doug Evans <dje%google.com@localhost>
 Date:   Sat Dec 24 20:29:33 2016 +0000
 
     target/i386: Fix bad patch application to translate.c
     
     In commit c52ab08aee6f7d4717fc6b517174043126bd302f,
     the patch snippet for the "syscall" insn got applied to "iret".
 
 After applying these two commits with this patch (against 2.6.0) the
 ATF tests complete.
 
 --- target-i386/bpt_helper.c	2016-05-11 17:56:13.000000000 +0200
 +++ target-i386/bpt_helper.c	2017-02-15 18:19:50.000000000 +0100
 @@ -244,4 +244,11 @@
  }
  
 +void helper_rechecking_single_step(CPUX86State *env)
 +{
 +    if ((env->eflags & TF_MASK) != 0) {
 +        helper_single_step(env);
 +    }
 +}
 +
  void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
  {
 --- target-i386/helper.h	2016-05-11 17:56:13.000000000 +0200
 +++ target-i386/helper.h	2017-02-15 18:19:50.000000000 +0100
 @@ -80,4 +80,5 @@
  #endif
  DEF_HELPER_1(single_step, void, env)
 +DEF_HELPER_1(rechecking_single_step, void, env)
  DEF_HELPER_1(cpuid, void, env)
  DEF_HELPER_1(rdtsc, void, env)
 --- target-i386/translate.c	2016-05-11 17:56:13.000000000 +0200
 +++ target-i386/translate.c	2017-02-15 18:20:05.000000000 +0100
 @@ -2452,6 +2452,8 @@
  
  /* Generate an end of block. Trace exception is also generated if needed.
 -   If IIM, set HF_INHIBIT_IRQ_MASK if it isn't already set.  */
 -static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
 +   If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
 +   If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
 +   S->TF.  This is used by the syscall/sysret insns.  */
 +static void gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
  {
      gen_update_cc_op(s);
 @@ -2469,4 +2471,7 @@
      if (s->singlestep_enabled) {
          gen_helper_debug(cpu_env);
 +    } else if (recheck_tf) {
 +        gen_helper_rechecking_single_step(cpu_env);
 +        tcg_gen_exit_tb(0);
      } else if (s->tf) {
          gen_helper_single_step(cpu_env);
 @@ -2477,8 +2482,15 @@
  }
  
 +/* End of block.
 +   If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.  */
 +static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
 +{
 +    gen_eob_worker(s, inhibit, false);
 +}
 +
  /* End of block, resetting the inhibit irq flag.  */
  static void gen_eob(DisasContext *s)
  {
 -    gen_eob_inhibit_irq(s, false);
 +    gen_eob_worker(s, false, false);
  }
  
 @@ -6978,5 +6990,8 @@
          gen_jmp_im(pc_start - s->cs_base);
          gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
 -        gen_eob(s);
 +        /* 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_worker(s, false, true);
          break;
      case 0x107: /* sysret */
 @@ -6989,5 +7004,9 @@
                  set_cc_op(s, CC_OP_EFLAGS);
              }
 -            gen_eob(s);
 +            /* TF handling for the sysret insn is different. The TF bit is
 +               checked after the sysret insn completes. This allows #DB to be
 +               generated "as if" the syscall insn in userspace has just
 +               completed.  */
 +            gen_eob_worker(s, false, true);
          }
          break;
 


Home | Main Index | Thread Index | Old Index