Jason,

This check
atomic_read(&cpu_doing_single_step) != -1
may result in a loss of debug events on other cpus

Changing it to
atomic_read(&cpu_doing_single_step) == raw_smp_processor_id()
corrects that problem

I see that you've checked in this change. Would you mind waiting for 24 hours 
after posting a patch? Thanks.
-Amit

On Wednesday 16 May 2007 00:36, Jason Wessel wrote:
> If there are no objections, I'd like to apply this patch as it fixes a
> critical gap when using source stepping that calls a low level
> singlestep that steps the boundary from the kernel to the user space.
> It is particularly bad when this corner case kills "init" as you get an
> unexpected reboot.
>
> ---
>
> This patch is to fix another corner case where kgdb can pass a single
> step trap to user space which was intended for the kernel.  Now a
> source level "next" which single steps over an iret instruction will
> cause KGDB to continue and print an error to the console, vs the
> unpredictable consequence of sending a trap to unsuspecting code in
> the user space (normally resulting in process termination).
>
> Signed-off-by: Jason Wessel <[EMAIL PROTECTED]>
>
> ---
>  arch/i386/kernel/kgdb.c   |   31 +++++++++++++++++++------------
>  arch/x86_64/kernel/kgdb.c |   17 ++++++++++++-----
>  2 files changed, 31 insertions(+), 17 deletions(-)
>
> Index: linux-2.6.21-standard/arch/i386/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21-standard.orig/arch/i386/kernel/kgdb.c
> +++ linux-2.6.21-standard/arch/i386/kernel/kgdb.c
> @@ -222,7 +222,7 @@ int kgdb_arch_handle_exception(int e_vec
>          if (remcom_in_buffer[0] == 's') {
>              linux_regs->eflags |= TF_MASK;
>              debugger_step = 1;
> -            atomic_set(&cpu_doing_single_step,smp_processor_id());
> +            atomic_set(&cpu_doing_single_step,raw_smp_processor_id());
>          }
>
>          asm volatile ("movl %%db6, %0\n":"=r" (dr6));
> @@ -255,22 +255,29 @@ static int kgdb_notify(struct notifier_b
>
>      /* Bad memory access? */
>      if (cmd == DIE_PAGE_FAULT_NO_CONTEXT && atomic_read(&debugger_active)
> -            && kgdb_may_fault) {
> +        && kgdb_may_fault) {
>          kgdb_fault_longjmp(kgdb_fault_jmp_regs);
>          return NOTIFY_STOP;
>      } else if (cmd == DIE_PAGE_FAULT)
>          /* A normal page fault, ignore. */
>          return NOTIFY_DONE;
> -       else if ((cmd == DIE_NMI || cmd == DIE_NMI_IPI ||
> -               cmd == DIE_NMIWATCHDOG) && atomic_read(&debugger_active)) {
> -               /* CPU roundup */
> -               kgdb_nmihook(smp_processor_id(), regs);
> -               return NOTIFY_STOP;
> -       } else if (cmd == DIE_NMI_IPI || cmd == DIE_NMI ||
> user_mode(regs) ||
> -                       (cmd == DIE_DEBUG &&
> atomic_read(&debugger_active))) -               /* Normal watchdog event or
> userspace debugging, or spurious -                * debug exception,
> ignore. */
> -               return NOTIFY_DONE;
> +    else if ((cmd == DIE_NMI || cmd == DIE_NMI_IPI ||
> +              cmd == DIE_NMIWATCHDOG) && atomic_read(&debugger_active)) {
> +        /* CPU roundup */
> +        kgdb_nmihook(raw_smp_processor_id(), regs);
> +        return NOTIFY_STOP;
> +    } else if (cmd == DIE_DEBUG && atomic_read(&cpu_doing_single_step)
> != -1
> +             && user_mode(regs)) {
> +        /* single step exception from kernel space to user space so
> +         * eat the exception and continue the process
> +         */
> +        printk(KERN_ERR "KGDB: trap/step from kernel to user space,
> resuming...\n");
> +        return NOTIFY_STOP;
> +    } else if (cmd == DIE_NMI_IPI || cmd == DIE_NMI || user_mode(regs) ||
> +               (cmd == DIE_DEBUG && atomic_read(&debugger_active)))
> +        /* Normal watchdog event or userspace debugging, or spurious
> +         * debug exception, ignore. */
> +        return NOTIFY_DONE;
>
>      kgdb_handle_exception(args->trapnr, args->signr, args->err, regs);
>
> Index: linux-2.6.21-standard/arch/x86_64/kernel/kgdb.c
> ===================================================================
> --- linux-2.6.21-standard.orig/arch/x86_64/kernel/kgdb.c
> +++ linux-2.6.21-standard/arch/x86_64/kernel/kgdb.c
> @@ -183,7 +183,7 @@ int kgdb_arch_handle_exception(int e_vec
>              debugger_step = 1;
>              if (kgdb_contthread)
>                  atomic_set(&cpu_doing_single_step,
> -                       smp_processor_id());
> +                       raw_smp_processor_id());
>
>          }
>
> @@ -237,7 +237,7 @@ void kgdb_shadowinfo(struct pt_regs *reg
>      static char intr_desc[] = "Stack at interrupt entrypoint";
>      static char exc_desc[] = "Stack at exception entrypoint";
>      struct pt_regs *stregs;
> -    int cpu = smp_processor_id();
> +    int cpu = raw_smp_processor_id();
>
>      if ((stregs = in_interrupt_stack(regs->rsp, cpu)))
>          kgdb_mem2hex(intr_desc, buffer, strlen(intr_desc));
> @@ -248,7 +248,7 @@ void kgdb_shadowinfo(struct pt_regs *reg
>  struct task_struct *kgdb_get_shadow_thread(struct pt_regs *regs, int
> threadid)
>  {
>      struct pt_regs *stregs;
> -    int cpu = smp_processor_id();
> +    int cpu = raw_smp_processor_id();
>
>      if ((stregs = in_interrupt_stack(regs->rsp, cpu)))
>          return current;
> @@ -261,7 +261,7 @@ struct task_struct *kgdb_get_shadow_thre
>  struct pt_regs *kgdb_shadow_regs(struct pt_regs *regs, int threadid)
>  {
>      struct pt_regs *stregs;
> -    int cpu = smp_processor_id();
> +    int cpu = raw_smp_processor_id();
>
>      if ((stregs = in_interrupt_stack(regs->rsp, cpu)))
>          return stregs;
> @@ -285,9 +285,16 @@ static int kgdb_notify(struct notifier_b
>          return NOTIFY_STOP;
>      /* CPU roundup? */
>      } else if (atomic_read(&debugger_active) && cmd == DIE_NMI_IPI) {
> -        kgdb_nmihook(smp_processor_id(), regs);
> +        kgdb_nmihook(raw_smp_processor_id(), regs);
>          return NOTIFY_STOP;
>          /* See if KGDB is interested. */
> +    } else if (cmd == DIE_DEBUG && atomic_read(&cpu_doing_single_step)
> != -1
> +             && user_mode(regs)) {
> +        /* single step exception from kernel space to user space so
> +         * eat the exception and continue the process
> +         */
> +        printk(KERN_ERR "KGDB: trap/step from kernel to user space,
> resuming...\n");
> +        return NOTIFY_STOP;
>      } else if (cmd == DIE_PAGE_FAULT || user_mode(regs) ||
>             cmd == DIE_NMI_IPI || (cmd == DIE_DEBUG &&
>                        atomic_read(&debugger_active)))

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to