Merge git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-kgdb
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Apr 2008 15:37:01 +0000 (08:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Apr 2008 15:37:01 +0000 (08:37 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-kgdb:
  kgdb: always use icache flush for sw breakpoints
  kgdb: fix SMP NMI kgdb_handle_exception exit race
  kgdb: documentation fixes
  kgdb: allow static kgdbts boot configuration
  kgdb: add documentation
  kgdb: Kconfig fix
  kgdb: add kgdb internal test suite
  kgdb: fix several kgdb regressions
  kgdb: kgdboc pl011 I/O module
  kgdb: fix optional arch functions and probe_kernel_*
  kgdb: add x86 HW breakpoints
  kgdb: print breakpoint removed on exception
  kgdb: clocksource watchdog
  kgdb: fix NMI hangs
  kgdb: fix kgdboc dynamic module configuration
  kgdb: document parameters
  x86: kgdb support
  consoles: polling support, kgdboc
  kgdb: core
  uaccess: add probe_kernel_write()

1  2 
Documentation/kernel-parameters.txt
arch/x86/Kconfig
arch/x86/kernel/Makefile
arch/x86/kernel/setup64.c
arch/x86/kernel/traps_32.c
arch/x86/kernel/traps_64.c
include/asm-x86/kdebug.h
kernel/Makefile
lib/Kconfig.debug

@@@ -812,19 -812,6 +812,19 @@@ and is between 256 and 4096 characters
  
        inttest=        [IA64]
  
 +      iommu=          [x86]
 +              off
 +              force
 +              noforce
 +              biomerge
 +              panic
 +              nopanic
 +              merge
 +              nomerge
 +              forcesac
 +              soft
 +
 +
        intel_iommu=    [DMAR] Intel IOMMU driver (DMAR) option
                off
                        Disable intel iommu driver.
        kstack=N        [X86-32,X86-64] Print N words from the kernel stack
                        in oops dumps.
  
+       kgdboc=         [HW] kgdb over consoles.
+                       Requires a tty driver that supports console polling.
+                       (only serial suported for now)
+                       Format: <serial_device>[,baud]
        l2cr=           [PPC]
  
        lapic           [X86-32,APIC] Enable the local APIC even if BIOS
                                 or
                                 memmap=0x10000$0x18690000
  
 +      memtest=        [KNL,X86_64] Enable memtest
 +                      Format: <integer>
 +                      range: 0,4 : pattern number
 +                      default : 0 <disable>
 +
        meye.*=         [HW] Set MotionEye Camera parameters
                        See Documentation/video4linux/meye.txt.
  
diff --combined arch/x86/Kconfig
@@@ -23,6 -23,7 +23,7 @@@ config X8
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
+       select HAVE_ARCH_KGDB
  
  
  config GENERIC_LOCKBREAK
@@@ -53,6 -54,9 +54,6 @@@ config STACKTRACE_SUPPOR
  config HAVE_LATENCYTOP_SUPPORT
        def_bool y
  
 -config SEMAPHORE_SLEEPERS
 -      def_bool y
 -
  config FAST_CMPXCHG_LOCAL
        bool
        default y
@@@ -114,7 -118,7 +115,7 @@@ config ARCH_HAS_CPU_RELA
        def_bool y
  
  config HAVE_SETUP_PER_CPU_AREA
 -      def_bool X86_64
 +      def_bool X86_64 || (X86_SMP && !X86_VOYAGER)
  
  config ARCH_HIBERNATION_POSSIBLE
        def_bool y
@@@ -168,7 -172,7 +169,7 @@@ config X86_64_SM
  config X86_HT
        bool
        depends on SMP
 -      depends on (X86_32 && !(X86_VISWS || X86_VOYAGER)) || (X86_64 && !MK8)
 +      depends on (X86_32 && !(X86_VISWS || X86_VOYAGER)) || X86_64
        default y
  
  config X86_BIOS_REBOOT
  
  config X86_TRAMPOLINE
        bool
 -      depends on X86_SMP || (X86_VOYAGER && SMP)
 +      depends on X86_SMP || (X86_VOYAGER && SMP) || (64BIT && ACPI_SLEEP)
        default y
  
  config KTIME_SCALAR
@@@ -238,7 -242,8 +239,7 @@@ config X86_ELA
  
  config X86_VOYAGER
        bool "Voyager (NCR)"
 -      depends on X86_32
 -      select SMP if !BROKEN
 +      depends on X86_32 && (SMP || BROKEN)
        help
          Voyager is an MCA-based 32-way capable SMP architecture proprietary
          to NCR Corp.  Machine classes 345x/35xx/4100/51xx are Voyager-based.
  
  config X86_NUMAQ
        bool "NUMAQ (IBM/Sequent)"
 -      select SMP
 +      depends on SMP && X86_32
        select NUMA
 -      depends on X86_32
        help
          This option is used for getting Linux to run on a (IBM/Sequent) NUMA
          multiquad box. This changes the way that processors are bootstrapped,
@@@ -322,9 -328,8 +323,9 @@@ config X86_RDC321
  
  config X86_VSMP
        bool "Support for ScaleMP vSMP"
 -      depends on X86_64 && PCI
 -       help
 +      select PARAVIRT
 +      depends on X86_64
 +      help
          Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
          supposed to run on these EM64T-based machines.  Only choose this option
          if you have one of these machines.
@@@ -379,35 -384,6 +380,35 @@@ config PARAVIR
  
  endif
  
 +config MEMTEST_BOOTPARAM
 +      bool "Memtest boot parameter"
 +      depends on X86_64
 +      default y
 +      help
 +        This option adds a kernel parameter 'memtest', which allows memtest
 +        to be disabled at boot.  If this option is selected, memtest
 +        functionality can be disabled with memtest=0 on the kernel
 +        command line.  The purpose of this option is to allow a single
 +        kernel image to be distributed with memtest built in, but not
 +        necessarily enabled.
 +
 +        If you are unsure how to answer this question, answer Y.
 +
 +config MEMTEST_BOOTPARAM_VALUE
 +      int "Memtest boot parameter default value (0-4)"
 +      depends on MEMTEST_BOOTPARAM
 +      range 0 4
 +      default 0
 +      help
 +        This option sets the default value for the kernel parameter
 +        'memtest', which allows memtest to be disabled at boot.  If this
 +        option is set to 0 (zero), the memtest kernel parameter will
 +        default to 0, disabling memtest at bootup.  If this option is
 +        set to 4, the memtest kernel parameter will default to 4,
 +        enabling memtest at bootup, and use that as pattern number.
 +
 +        If you are unsure how to answer this question, answer 0.
 +
  config ACPI_SRAT
        def_bool y
        depends on X86_32 && ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH)
@@@ -532,7 -508,7 +533,7 @@@ config NR_CPU
  
  config SCHED_SMT
        bool "SMT (Hyperthreading) scheduler support"
 -      depends on (X86_64 && SMP) || (X86_32 && X86_HT)
 +      depends on X86_HT
        help
          SMT scheduler support improves the CPU scheduler's decision making
          when dealing with Intel Pentium 4 chips with HyperThreading at a
  config SCHED_MC
        def_bool y
        prompt "Multi-core scheduler support"
 -      depends on (X86_64 && SMP) || (X86_32 && X86_HT)
 +      depends on X86_HT
        help
          Multi-core scheduler support improves the CPU scheduler's decision
          making when dealing with multi-core CPU chips at a cost of slightly
@@@ -911,7 -887,7 +912,7 @@@ config NUMA_EM
          number of nodes. This is only useful for debugging.
  
  config NODES_SHIFT
 -      int
 +      int "Max num nodes shift(1-15)"
        range 1 15  if X86_64
        default "6" if X86_64
        default "4" if X86_NUMAQ
@@@ -1035,21 -1011,6 +1036,21 @@@ config MTR
  
          See <file:Documentation/mtrr.txt> for more information.
  
 +config X86_PAT
 +      def_bool y
 +      prompt "x86 PAT support"
 +      depends on MTRR && NONPROMISC_DEVMEM
 +      help
 +        Use PAT attributes to setup page level cache control.
 +
 +        PATs are the modern equivalents of MTRRs and are much more
 +        flexible than MTRRs.
 +
 +        Say N here if you see bootup problems (boot crash, boot hang,
 +        spontaneous reboots) or a non-working video driver.
 +
 +        If unsure, say Y.
 +
  config EFI
        def_bool n
        prompt "EFI runtime service support"
@@@ -1118,7 -1079,6 +1119,7 @@@ source kernel/Kconfig.h
  
  config KEXEC
        bool "kexec system call"
 +      depends on X86_64 || X86_BIOS_REBOOT
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
@@@ -1420,7 -1380,7 +1421,7 @@@ endmen
  menu "Bus options (PCI etc.)"
  
  config PCI
 -      bool "PCI support" if !X86_VISWS
 +      bool "PCI support" if !X86_VISWS && !X86_VSMP
        depends on !X86_VOYAGER
        default y
        select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
diff --combined arch/x86/kernel/Makefile
@@@ -2,7 -2,8 +2,7 @@@
  # Makefile for the linux kernel.
  #
  
 -extra-y                := head_$(BITS).o init_task.o vmlinux.lds
 -extra-$(CONFIG_X86_64) += head64.o
 +extra-y                := head_$(BITS).o head$(BITS).o init_task.o vmlinux.lds
  
  CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
  
@@@ -18,7 -19,7 +18,7 @@@ CFLAGS_tsc_64.o               := $(nostackp
  obj-y                 := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
  obj-y                 += traps_$(BITS).o irq_$(BITS).o
  obj-y                 += time_$(BITS).o ioport.o ldt.o
 -obj-y                 += setup_$(BITS).o i8259_$(BITS).o
 +obj-y                 += setup_$(BITS).o i8259_$(BITS).o setup.o
  obj-$(CONFIG_X86_32)  += sys_i386_32.o i386_ksyms_32.o
  obj-$(CONFIG_X86_64)  += sys_x86_64.o x8664_ksyms_64.o
  obj-$(CONFIG_X86_64)  += syscall_64.o vsyscall_64.o setup64.o
@@@ -28,7 -29,6 +28,7 @@@ obj-y                 += alternative.o i8253.
  obj-$(CONFIG_X86_64)  += pci-nommu_64.o bugs_64.o
  obj-y                 += tsc_$(BITS).o io_delay.o rtc.o
  
 +obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
  obj-y                         += i387.o
  obj-y                         += ptrace.o
  obj-y                         += ds.o
@@@ -47,12 -47,11 +47,12 @@@ obj-$(CONFIG_MICROCODE)            += microcode.
  obj-$(CONFIG_PCI)             += early-quirks.o
  apm-y                         := apm_32.o
  obj-$(CONFIG_APM)             += apm.o
 -obj-$(CONFIG_X86_SMP)         += smp_$(BITS).o smpboot_$(BITS).o tsc_sync.o
 -obj-$(CONFIG_X86_32_SMP)      += smpcommon_32.o
 -obj-$(CONFIG_X86_64_SMP)      += smp_64.o smpboot_64.o tsc_sync.o
 +obj-$(CONFIG_X86_SMP)         += smp.o
 +obj-$(CONFIG_X86_SMP)         += smpboot.o tsc_sync.o ipi.o tlb_$(BITS).o
 +obj-$(CONFIG_X86_32_SMP)      += smpcommon.o
 +obj-$(CONFIG_X86_64_SMP)      += tsc_sync.o smpcommon.o
  obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline_$(BITS).o
 -obj-$(CONFIG_X86_MPPARSE)     += mpparse_$(BITS).o
 +obj-$(CONFIG_X86_MPPARSE)     += mpparse.o
  obj-$(CONFIG_X86_LOCAL_APIC)  += apic_$(BITS).o nmi_$(BITS).o
  obj-$(CONFIG_X86_IO_APIC)     += io_apic_$(BITS).o
  obj-$(CONFIG_X86_REBOOTFIXUPS)        += reboot_fixups_32.o
@@@ -61,12 -60,13 +61,13 @@@ obj-$(CONFIG_KEXEC)                += relocate_kernel
  obj-$(CONFIG_CRASH_DUMP)      += crash_dump_$(BITS).o
  obj-$(CONFIG_X86_NUMAQ)               += numaq_32.o
  obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_32.o
 -obj-$(CONFIG_X86_VSMP)                += vsmp_64.o
 +obj-y                         += vsmp_64.o
  obj-$(CONFIG_KPROBES)         += kprobes.o
  obj-$(CONFIG_MODULES)         += module_$(BITS).o
  obj-$(CONFIG_ACPI_SRAT)       += srat_32.o
  obj-$(CONFIG_EFI)             += efi.o efi_$(BITS).o efi_stub_$(BITS).o
  obj-$(CONFIG_DOUBLEFAULT)     += doublefault_32.o
+ obj-$(CONFIG_KGDB)            += kgdb.o
  obj-$(CONFIG_VM86)            += vm86_32.o
  obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
  
@@@ -90,7 -90,7 +91,7 @@@ scx200-y                      += scx200_32.
  ###
  # 64 bit specific files
  ifeq ($(CONFIG_X86_64),y)
 -        obj-y                         += genapic_64.o genapic_flat_64.o
 +        obj-y                         += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o
          obj-$(CONFIG_X86_PM_TIMER)    += pmtimer_64.o
          obj-$(CONFIG_AUDIT)           += audit_64.o
  
@@@ -11,6 -11,7 +11,7 @@@
  #include <linux/bootmem.h>
  #include <linux/bitops.h>
  #include <linux/module.h>
+ #include <linux/kgdb.h>
  #include <asm/pda.h>
  #include <asm/pgtable.h>
  #include <asm/processor.h>
@@@ -23,7 -24,6 +24,7 @@@
  #include <asm/proto.h>
  #include <asm/sections.h>
  #include <asm/setup.h>
 +#include <asm/genapic.h>
  
  #ifndef CONFIG_DEBUG_BOOT_PARAMS
  struct boot_params __initdata boot_params;
@@@ -86,6 -86,83 +87,6 @@@ static int __init nonx32_setup(char *st
  }
  __setup("noexec32=", nonx32_setup);
  
 -/*
 - * Copy data used in early init routines from the initial arrays to the
 - * per cpu data areas.  These arrays then become expendable and the
 - * *_early_ptr's are zeroed indicating that the static arrays are gone.
 - */
 -static void __init setup_per_cpu_maps(void)
 -{
 -      int cpu;
 -
 -      for_each_possible_cpu(cpu) {
 -#ifdef CONFIG_SMP
 -              if (per_cpu_offset(cpu)) {
 -#endif
 -                      per_cpu(x86_cpu_to_apicid, cpu) =
 -                                              x86_cpu_to_apicid_init[cpu];
 -                      per_cpu(x86_bios_cpu_apicid, cpu) =
 -                                              x86_bios_cpu_apicid_init[cpu];
 -#ifdef CONFIG_NUMA
 -                      per_cpu(x86_cpu_to_node_map, cpu) =
 -                                              x86_cpu_to_node_map_init[cpu];
 -#endif
 -#ifdef CONFIG_SMP
 -              }
 -              else
 -                      printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n",
 -                                                                      cpu);
 -#endif
 -      }
 -
 -      /* indicate the early static arrays will soon be gone */
 -      x86_cpu_to_apicid_early_ptr = NULL;
 -      x86_bios_cpu_apicid_early_ptr = NULL;
 -#ifdef CONFIG_NUMA
 -      x86_cpu_to_node_map_early_ptr = NULL;
 -#endif
 -}
 -
 -/*
 - * Great future plan:
 - * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
 - * Always point %gs to its beginning
 - */
 -void __init setup_per_cpu_areas(void)
 -{ 
 -      int i;
 -      unsigned long size;
 -
 -#ifdef CONFIG_HOTPLUG_CPU
 -      prefill_possible_map();
 -#endif
 -
 -      /* Copy section for each CPU (we discard the original) */
 -      size = PERCPU_ENOUGH_ROOM;
 -
 -      printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size);
 -      for_each_cpu_mask (i, cpu_possible_map) {
 -              char *ptr;
 -#ifndef CONFIG_NEED_MULTIPLE_NODES
 -              ptr = alloc_bootmem_pages(size);
 -#else
 -              int node = early_cpu_to_node(i);
 -
 -              if (!node_online(node) || !NODE_DATA(node))
 -                      ptr = alloc_bootmem_pages(size);
 -              else
 -                      ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
 -#endif
 -              if (!ptr)
 -                      panic("Cannot allocate cpu data for CPU %d\n", i);
 -              cpu_pda(i)->data_offset = ptr - __per_cpu_start;
 -              memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
 -      }
 -
 -      /* setup percpu data maps early */
 -      setup_per_cpu_maps();
 -} 
 -
  void pda_init(int cpu)
  { 
        struct x8664_pda *pda = cpu_pda(cpu);
@@@ -251,6 -328,17 +252,17 @@@ void __cpuinit cpu_init (void
        load_TR_desc();
        load_LDT(&init_mm.context);
  
+ #ifdef CONFIG_KGDB
+       /*
+        * If the kgdb is connected no debug regs should be altered.  This
+        * is only applicable when KGDB and a KGDB I/O module are built
+        * into the kernel and you are using early debugging with
+        * kgdbwait. KGDB will control the kernel HW breakpoint registers.
+        */
+       if (kgdb_connected && arch_kgdb_ops.correct_hw_break)
+               arch_kgdb_ops.correct_hw_break();
+       else {
+ #endif
        /*
         * Clear all 6 debug registers:
         */
        set_debugreg(0UL, 3);
        set_debugreg(0UL, 6);
        set_debugreg(0UL, 7);
+ #ifdef CONFIG_KGDB
+       /* If the kgdb is connected no debug regs should be altered. */
+       }
+ #endif
  
        fpu_init(); 
  
        raw_local_save_flags(kernel_eflags);
 +
 +      if (is_uv_system())
 +              uv_cpu_init();
  }
@@@ -9,28 -9,26 +9,28 @@@
   * 'Traps.c' handles hardware traps and faults after we have saved some
   * state in 'asm.s'.
   */
 -#include <linux/sched.h>
 +#include <linux/interrupt.h>
 +#include <linux/kallsyms.h>
 +#include <linux/spinlock.h>
 +#include <linux/highmem.h>
 +#include <linux/kprobes.h>
 +#include <linux/uaccess.h>
 +#include <linux/utsname.h>
 +#include <linux/kdebug.h>
  #include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/ptrace.h>
  #include <linux/string.h>
 +#include <linux/unwind.h>
 +#include <linux/delay.h>
  #include <linux/errno.h>
 +#include <linux/kexec.h>
 +#include <linux/sched.h>
  #include <linux/timer.h>
 -#include <linux/mm.h>
  #include <linux/init.h>
 -#include <linux/delay.h>
 -#include <linux/spinlock.h>
 -#include <linux/interrupt.h>
 -#include <linux/highmem.h>
 -#include <linux/kallsyms.h>
 -#include <linux/ptrace.h>
 -#include <linux/utsname.h>
 -#include <linux/kprobes.h>
 -#include <linux/kexec.h>
 -#include <linux/unwind.h>
 -#include <linux/uaccess.h>
 -#include <linux/nmi.h>
  #include <linux/bug.h>
 +#include <linux/nmi.h>
 +#include <linux/mm.h>
  
  #ifdef CONFIG_EISA
  #include <linux/ioport.h>
  #include <linux/edac.h>
  #endif
  
 +#include <asm/arch_hooks.h>
 +#include <asm/stacktrace.h>
  #include <asm/processor.h>
 -#include <asm/system.h>
 -#include <asm/io.h>
 -#include <asm/atomic.h>
  #include <asm/debugreg.h>
 +#include <asm/atomic.h>
 +#include <asm/system.h>
 +#include <asm/unwind.h>
  #include <asm/desc.h>
  #include <asm/i387.h>
  #include <asm/nmi.h>
 -#include <asm/unwind.h>
  #include <asm/smp.h>
 -#include <asm/arch_hooks.h>
 -#include <linux/kdebug.h>
 -#include <asm/stacktrace.h>
 -
 -#include <linux/module.h>
 +#include <asm/io.h>
  
  #include "mach_traps.h"
  
@@@ -68,7 -69,7 +68,7 @@@ EXPORT_SYMBOL_GPL(used_vectors)
  asmlinkage int system_call(void);
  
  /* Do we ignore FPU interrupts ? */
 -char ignore_fpu_irq = 0;
 +char ignore_fpu_irq;
  
  /*
   * The IDT has to be page-aligned to simplify the Pentium
@@@ -104,13 -105,12 +104,13 @@@ static unsigned int code_bytes = 64
  void printk_address(unsigned long address, int reliable)
  {
  #ifdef CONFIG_KALLSYMS
 -      unsigned long offset = 0, symsize;
 +      char namebuf[KSYM_NAME_LEN];
 +      unsigned long offset = 0;
 +      unsigned long symsize;
        const char *symname;
 -      char *modname;
 -      char *delim = ":";
 -      char namebuf[128];
        char reliab[4] = "";
 +      char *delim = ":";
 +      char *modname;
  
        symname = kallsyms_lookup(address, &symsize, &offset,
                                        &modname, namebuf);
@@@ -138,14 -138,13 +138,14 @@@ static inline int valid_stack_ptr(struc
  
  /* The form of the top of the frame on the stack */
  struct stack_frame {
 -      struct stack_frame *next_frame;
 -      unsigned long return_address;
 +      struct stack_frame      *next_frame;
 +      unsigned long           return_address;
  };
  
 -static inline unsigned long print_context_stack(struct thread_info *tinfo,
 -                              unsigned long *stack, unsigned long bp,
 -                              const struct stacktrace_ops *ops, void *data)
 +static inline unsigned long
 +print_context_stack(struct thread_info *tinfo,
 +                  unsigned long *stack, unsigned long bp,
 +                  const struct stacktrace_ops *ops, void *data)
  {
        struct stack_frame *frame = (struct stack_frame *)bp;
  
        return bp;
  }
  
 -#define MSG(msg) ops->warning(data, msg)
 +#define MSG(msg)              ops->warning(data, msg)
  
  void dump_trace(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp,
  
        if (!stack) {
                unsigned long dummy;
 +
                stack = &dummy;
                if (task != current)
                        stack = (unsigned long *)task->thread.sp;
        if (!bp) {
                if (task == current) {
                        /* Grab bp right from our regs */
 -                      asm ("movl %%ebp, %0" : "=r" (bp) : );
 +                      asm("movl %%ebp, %0" : "=r" (bp) :);
                } else {
                        /* bp is the last reg pushed by switch_to */
                        bp = *(unsigned long *) task->thread.sp;
  
        while (1) {
                struct thread_info *context;
 +
                context = (struct thread_info *)
                        ((unsigned long)stack & (~(THREAD_SIZE - 1)));
                bp = print_context_stack(context, stack, bp, ops, data);
 -              /* Should be after the line below, but somewhere
 -                 in early boot context comes out corrupted and we
 -                 can't reference it -AK */
 +              /*
 +               * Should be after the line below, but somewhere
 +               * in early boot context comes out corrupted and we
 +               * can't reference it:
 +               */
                if (ops->stack(data, "IRQ") < 0)
                        break;
 -              stack = (unsigned long*)context->previous_esp;
 +              stack = (unsigned long *)context->previous_esp;
                if (!stack)
                        break;
                touch_nmi_watchdog();
@@@ -248,15 -243,15 +248,15 @@@ static void print_trace_address(void *d
  }
  
  static const struct stacktrace_ops print_trace_ops = {
 -      .warning = print_trace_warning,
 -      .warning_symbol = print_trace_warning_symbol,
 -      .stack = print_trace_stack,
 -      .address = print_trace_address,
 +      .warning                = print_trace_warning,
 +      .warning_symbol         = print_trace_warning_symbol,
 +      .stack                  = print_trace_stack,
 +      .address                = print_trace_address,
  };
  
  static void
  show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
 -              unsigned long *stack, unsigned long bp, char *log_lvl)
 +                 unsigned long *stack, unsigned long bp, char *log_lvl)
  {
        dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
        printk("%s =======================\n", log_lvl);
@@@ -268,22 -263,21 +268,22 @@@ void show_trace(struct task_struct *tas
        show_trace_log_lvl(task, regs, stack, bp, "");
  }
  
 -static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
 -                     unsigned long *sp, unsigned long bp, char *log_lvl)
 +static void
 +show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
 +                 unsigned long *sp, unsigned long bp, char *log_lvl)
  {
        unsigned long *stack;
        int i;
  
        if (sp == NULL) {
                if (task)
 -                      sp = (unsigned long*)task->thread.sp;
 +                      sp = (unsigned long *)task->thread.sp;
                else
                        sp = (unsigned long *)&sp;
        }
  
        stack = sp;
 -      for(i = 0; i < kstack_depth_to_print; i++) {
 +      for (i = 0; i < kstack_depth_to_print; i++) {
                if (kstack_end(stack))
                        break;
                if (i && ((i % 8) == 0))
                printk("%08lx ", *stack++);
        }
        printk("\n%sCall Trace:\n", log_lvl);
 +
        show_trace_log_lvl(task, regs, sp, bp, log_lvl);
  }
  
@@@ -306,8 -299,8 +306,8 @@@ void show_stack(struct task_struct *tas
   */
  void dump_stack(void)
  {
 -      unsigned long stack;
        unsigned long bp = 0;
 +      unsigned long stack;
  
  #ifdef CONFIG_FRAME_POINTER
        if (!bp)
                init_utsname()->release,
                (int)strcspn(init_utsname()->version, " "),
                init_utsname()->version);
 +
        show_trace(current, NULL, &stack, bp);
  }
  
@@@ -331,7 -323,6 +331,7 @@@ void show_registers(struct pt_regs *reg
  
        print_modules();
        __show_registers(regs, 0);
 +
        printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
                TASK_COMM_LEN, current->comm, task_pid_nr(current),
                current_thread_info(), current, task_thread_info(current));
         * time of the fault..
         */
        if (!user_mode_vm(regs)) {
                unsigned int code_prologue = code_bytes * 43 / 64;
                unsigned int code_len = code_bytes;
                unsigned char c;
 +              u8 *ip;
  
                printk("\n" KERN_EMERG "Stack: ");
                show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
                }
        }
        printk("\n");
 -}     
 +}
  
  int is_valid_bugaddr(unsigned long ip)
  {
  
  static int die_counter;
  
 -int __kprobes __die(const char * str, struct pt_regs * regs, long err)
 +int __kprobes __die(const char *str, struct pt_regs *regs, long err)
  {
 -      unsigned long sp;
        unsigned short ss;
 +      unsigned long sp;
  
        printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
  #ifdef CONFIG_PREEMPT
        printk("\n");
  
        if (notify_die(DIE_OOPS, str, regs, err,
 -                              current->thread.trap_no, SIGSEGV) !=
 -                      NOTIFY_STOP) {
 +                      current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) {
 +
                show_registers(regs);
                /* Executive summary in case the oops scrolled away */
                sp = (unsigned long) (&regs->sp);
                printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
                print_symbol("%s", regs->ip);
                printk(" SS:ESP %04x:%08lx\n", ss, sp);
 +
                return 0;
 -      } else {
 -              return 1;
        }
 +
 +      return 1;
  }
  
  /*
 - * This is gone through when something in the kernel has done something bad and
 - * is about to be terminated.
 + * This is gone through when something in the kernel has done something bad
 + * and is about to be terminated:
   */
 -void die(const char * str, struct pt_regs * regs, long err)
 +void die(const char *str, struct pt_regs *regs, long err)
  {
        static struct {
                raw_spinlock_t lock;
                die.lock_owner = smp_processor_id();
                die.lock_owner_depth = 0;
                bust_spinlocks(1);
 -      } else
 +      } else {
                raw_local_irq_save(flags);
 +      }
  
        if (++die.lock_owner_depth < 3) {
                report_bug(regs->ip, regs);
        do_exit(SIGSEGV);
  }
  
 -static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
 +static inline void
 +die_if_kernel(const char *str, struct pt_regs *regs, long err)
  {
        if (!user_mode_vm(regs))
                die(str, regs, err);
  }
  
 -static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
 -                            struct pt_regs * regs, long error_code,
 -                            siginfo_t *info)
 +static void __kprobes
 +do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs *regs,
 +      long error_code, siginfo_t *info)
  {
        struct task_struct *tsk = current;
  
 -      if (regs->flags & VM_MASK) {
 +      if (regs->flags & X86_VM_MASK) {
                if (vm86)
                        goto vm86_trap;
                goto trap_signal;
        if (!user_mode(regs))
                goto kernel_trap;
  
 -      trap_signal: {
 -              /*
 -               * We want error_code and trap_no set for userspace faults and
 -               * kernelspace faults which result in die(), but not
 -               * kernelspace faults which are fixed up.  die() gives the
 -               * process no chance to handle the signal and notice the
 -               * kernel fault information, so that won't result in polluting
 -               * the information about previously queued, but not yet
 -               * delivered, faults.  See also do_general_protection below.
 -               */
 -              tsk->thread.error_code = error_code;
 -              tsk->thread.trap_no = trapnr;
 +trap_signal:
 +      /*
 +       * We want error_code and trap_no set for userspace faults and
 +       * kernelspace faults which result in die(), but not
 +       * kernelspace faults which are fixed up.  die() gives the
 +       * process no chance to handle the signal and notice the
 +       * kernel fault information, so that won't result in polluting
 +       * the information about previously queued, but not yet
 +       * delivered, faults.  See also do_general_protection below.
 +       */
 +      tsk->thread.error_code = error_code;
 +      tsk->thread.trap_no = trapnr;
  
 -              if (info)
 -                      force_sig_info(signr, info, tsk);
 -              else
 -                      force_sig(signr, tsk);
 -              return;
 -      }
 +      if (info)
 +              force_sig_info(signr, info, tsk);
 +      else
 +              force_sig(signr, tsk);
 +      return;
  
 -      kernel_trap: {
 -              if (!fixup_exception(regs)) {
 -                      tsk->thread.error_code = error_code;
 -                      tsk->thread.trap_no = trapnr;
 -                      die(str, regs, error_code);
 -              }
 -              return;
 +kernel_trap:
 +      if (!fixup_exception(regs)) {
 +              tsk->thread.error_code = error_code;
 +              tsk->thread.trap_no = trapnr;
 +              die(str, regs, error_code);
        }
 +      return;
  
 -      vm86_trap: {
 -              int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
 -              if (ret) goto trap_signal;
 -              return;
 -      }
 +vm86_trap:
 +      if (handle_vm86_trap((struct kernel_vm86_regs *) regs,
 +                                              error_code, trapnr))
 +              goto trap_signal;
 +      return;
  }
  
 -#define DO_ERROR(trapnr, signr, str, name) \
 -void do_##name(struct pt_regs * regs, long error_code) \
 -{ \
 -      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
 -                                              == NOTIFY_STOP) \
 -              return; \
 -      do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
 +#define DO_ERROR(trapnr, signr, str, name)                            \
 +void do_##name(struct pt_regs *regs, long error_code)                 \
 +{                                                                     \
 +      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)  \
 +                                              == NOTIFY_STOP)         \
 +              return;                                                 \
 +      do_trap(trapnr, signr, str, 0, regs, error_code, NULL);         \
  }
  
 -#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \
 -void do_##name(struct pt_regs * regs, long error_code) \
 -{ \
 -      siginfo_t info; \
 -      if (irq) \
 -              local_irq_enable(); \
 -      info.si_signo = signr; \
 -      info.si_errno = 0; \
 -      info.si_code = sicode; \
 -      info.si_addr = (void __user *)siaddr; \
 -      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
 -                                              == NOTIFY_STOP) \
 -              return; \
 -      do_trap(trapnr, signr, str, 0, regs, error_code, &info); \
 +#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq)  \
 +void do_##name(struct pt_regs *regs, long error_code)                 \
 +{                                                                     \
 +      siginfo_t info;                                                 \
 +      if (irq)                                                        \
 +              local_irq_enable();                                     \
 +      info.si_signo = signr;                                          \
 +      info.si_errno = 0;                                              \
 +      info.si_code = sicode;                                          \
 +      info.si_addr = (void __user *)siaddr;                           \
 +      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)  \
 +                                              == NOTIFY_STOP)         \
 +              return;                                                 \
 +      do_trap(trapnr, signr, str, 0, regs, error_code, &info);        \
  }
  
 -#define DO_VM86_ERROR(trapnr, signr, str, name) \
 -void do_##name(struct pt_regs * regs, long error_code) \
 -{ \
 -      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
 -                                              == NOTIFY_STOP) \
 -              return; \
 -      do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
 +#define DO_VM86_ERROR(trapnr, signr, str, name)                               \
 +void do_##name(struct pt_regs *regs, long error_code)                 \
 +{                                                                     \
 +      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)  \
 +                                              == NOTIFY_STOP)         \
 +              return;                                                 \
 +      do_trap(trapnr, signr, str, 1, regs, error_code, NULL);         \
  }
  
 -#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
 -void do_##name(struct pt_regs * regs, long error_code) \
 -{ \
 -      siginfo_t info; \
 -      info.si_signo = signr; \
 -      info.si_errno = 0; \
 -      info.si_code = sicode; \
 -      info.si_addr = (void __user *)siaddr; \
 -      trace_hardirqs_fixup(); \
 -      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
 -                                              == NOTIFY_STOP) \
 -              return; \
 -      do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
 +#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr)  \
 +void do_##name(struct pt_regs *regs, long error_code)                 \
 +{                                                                     \
 +      siginfo_t info;                                                 \
 +      info.si_signo = signr;                                          \
 +      info.si_errno = 0;                                              \
 +      info.si_code = sicode;                                          \
 +      info.si_addr = (void __user *)siaddr;                           \
 +      trace_hardirqs_fixup();                                         \
 +      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)  \
 +                                              == NOTIFY_STOP)         \
 +              return;                                                 \
 +      do_trap(trapnr, signr, str, 1, regs, error_code, &info);        \
  }
  
 -DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->ip)
 +DO_VM86_ERROR_INFO(0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->ip)
  #ifndef CONFIG_KPROBES
 -DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
 +DO_VM86_ERROR(3, SIGTRAP, "int3", int3)
  #endif
 -DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
 -DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
 -DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
 -DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
 +DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow)
 +DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds)
 +DO_ERROR_INFO(6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
 +DO_ERROR(9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
  DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
  DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
  DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
  DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
  DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1)
  
 -void __kprobes do_general_protection(struct pt_regs * regs,
 -                                            long error_code)
 +void __kprobes do_general_protection(struct pt_regs *regs, long error_code)
  {
 -      int cpu = get_cpu();
 -      struct tss_struct *tss = &per_cpu(init_tss, cpu);
 -      struct thread_struct *thread = &current->thread;
 +      struct thread_struct *thread;
 +      struct tss_struct *tss;
 +      int cpu;
 +
 +      cpu = get_cpu();
 +      tss = &per_cpu(init_tss, cpu);
 +      thread = &current->thread;
  
        /*
         * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
                 * If the previously set map was extending to higher ports
                 * than the current one, pad extra space with 0xff (no access).
                 */
 -              if (thread->io_bitmap_max < tss->io_bitmap_max)
 +              if (thread->io_bitmap_max < tss->io_bitmap_max) {
                        memset((char *) tss->io_bitmap +
                                thread->io_bitmap_max, 0xff,
                                tss->io_bitmap_max - thread->io_bitmap_max);
 +              }
                tss->io_bitmap_max = thread->io_bitmap_max;
                tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
                tss->io_bitmap_owner = thread;
                put_cpu();
 +
                return;
        }
        put_cpu();
  
 -      if (regs->flags & VM_MASK)
 +      if (regs->flags & X86_VM_MASK)
                goto gp_in_vm86;
  
        if (!user_mode(regs))
  
        current->thread.error_code = error_code;
        current->thread.trap_no = 13;
 +
        if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
            printk_ratelimit()) {
                printk(KERN_INFO
@@@ -682,24 -666,21 +682,24 @@@ gp_in_kernel
  }
  
  static __kprobes void
 -mem_parity_error(unsigned char reason, struct pt_regs * regs)
 +mem_parity_error(unsigned char reason, struct pt_regs *regs)
  {
 -      printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on "
 -              "CPU %d.\n", reason, smp_processor_id());
 -      printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n");
 +      printk(KERN_EMERG
 +              "Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
 +                      reason, smp_processor_id());
 +
 +      printk(KERN_EMERG
 +              "You have some hardware problem, likely on the PCI bus.\n");
  
  #if defined(CONFIG_EDAC)
 -      if(edac_handler_set()) {
 +      if (edac_handler_set()) {
                edac_atomic_assert_error();
                return;
        }
  #endif
  
        if (panic_on_unrecovered_nmi)
 -                panic("NMI: Not continuing");
 +              panic("NMI: Not continuing");
  
        printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
  
  }
  
  static __kprobes void
 -io_check_error(unsigned char reason, struct pt_regs * regs)
 +io_check_error(unsigned char reason, struct pt_regs *regs)
  {
        unsigned long i;
  
        /* Re-enable the IOCK line, wait for a few seconds */
        reason = (reason & 0xf) | 8;
        outb(reason, 0x61);
 +
        i = 2000;
 -      while (--i) udelay(1000);
 +      while (--i)
 +              udelay(1000);
 +
        reason &= ~8;
        outb(reason, 0x61);
  }
  
  static __kprobes void
 -unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 +unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
  {
+       if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
+               return;
  #ifdef CONFIG_MCA
 -      /* Might actually be able to figure out what the guilty party
 -      * is. */
 -      if( MCA_bus ) {
 +      /*
 +       * Might actually be able to figure out what the guilty party
 +       * is:
 +       */
 +      if (MCA_bus) {
                mca_handle_nmi();
                return;
        }
  #endif
 -      printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on "
 -              "CPU %d.\n", reason, smp_processor_id());
 +      printk(KERN_EMERG
 +              "Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
 +                      reason, smp_processor_id());
 +
        printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n");
        if (panic_on_unrecovered_nmi)
 -                panic("NMI: Not continuing");
 +              panic("NMI: Not continuing");
  
        printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
  }
@@@ -755,13 -731,14 +757,13 @@@ static DEFINE_SPINLOCK(nmi_print_lock)
  
  void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
  {
 -      if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) ==
 -          NOTIFY_STOP)
 +      if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == NOTIFY_STOP)
                return;
  
        spin_lock(&nmi_print_lock);
        /*
        * We are in trouble anyway, lets at least try
 -      * to get a message out.
 +      * to get a message out:
        */
        bust_spinlocks(1);
        printk(KERN_EMERG "%s", msg);
        spin_unlock(&nmi_print_lock);
        bust_spinlocks(0);
  
 -      /* If we are in kernel we are probably nested up pretty bad
 -       * and might aswell get out now while we still can.
 -      */
 +      /*
 +       * If we are in kernel we are probably nested up pretty bad
 +       * and might aswell get out now while we still can:
 +       */
        if (!user_mode_vm(regs)) {
                current->thread.trap_no = 2;
                crash_kexec(regs);
        do_exit(SIGSEGV);
  }
  
 -static __kprobes void default_do_nmi(struct pt_regs * regs)
 +static __kprobes void default_do_nmi(struct pt_regs *regs)
  {
        unsigned char reason = 0;
  
 -      /* Only the BSP gets external NMIs from the system */
 +      /* Only the BSP gets external NMIs from the system: */
        if (!smp_processor_id())
                reason = get_nmi_reason();
 - 
 +
        if (!(reason & 0xc0)) {
                if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
                                                        == NOTIFY_STOP)
                if (nmi_watchdog_tick(regs, reason))
                        return;
                if (!do_nmi_callback(regs, smp_processor_id()))
 -#endif
                        unknown_nmi_error(reason, regs);
 +#else
 +              unknown_nmi_error(reason, regs);
 +#endif
  
                return;
        }
                io_check_error(reason, regs);
        /*
         * Reassert NMI in case it became active meanwhile
 -       * as it's edge-triggered.
 +       * as it's edge-triggered:
         */
        reassert_nmi();
  }
  
  static int ignore_nmis;
  
 -__kprobes void do_nmi(struct pt_regs * regs, long error_code)
 +__kprobes void do_nmi(struct pt_regs *regs, long error_code)
  {
        int cpu;
  
@@@ -862,12 -836,9 +864,12 @@@ void __kprobes do_int3(struct pt_regs *
        if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
                        == NOTIFY_STOP)
                return;
 -      /* This is an interrupt gate, because kprobes wants interrupts
 -      disabled.  Normal trap handlers don't. */
 +      /*
 +       * This is an interrupt gate, because kprobes wants interrupts
 +       * disabled. Normal trap handlers don't.
 +       */
        restore_interrupts(regs);
 +
        do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
  }
  #endif
   * from user space. Such code must not hold kernel locks (since it
   * can equally take a page fault), therefore it is safe to call
   * force_sig_info even though that claims and releases locks.
 - * 
 + *
   * Code in ./signal.c ensures that the debug control register
   * is restored before we deliver any signal, and therefore that
   * user code runs with the correct debug control register even though
   * find every occurrence of the TF bit that could be saved away even
   * by user code)
   */
 -void __kprobes do_debug(struct pt_regs * regs, long error_code)
 +void __kprobes do_debug(struct pt_regs *regs, long error_code)
  {
 -      unsigned int condition;
        struct task_struct *tsk = current;
 +      unsigned int condition;
  
        trace_hardirqs_fixup();
  
                        goto clear_dr7;
        }
  
 -      if (regs->flags & VM_MASK)
 +      if (regs->flags & X86_VM_MASK)
                goto debug_vm86;
  
        /* Save debug status register where ptrace can see it */
        /* Ok, finally something we can handle */
        send_sigtrap(tsk, regs, error_code);
  
 -      /* Disable additional traps. They'll be re-enabled when
 +      /*
 +       * Disable additional traps. They'll be re-enabled when
         * the signal is delivered.
         */
  clear_dr7:
@@@ -959,7 -929,7 +961,7 @@@ debug_vm86
  
  clear_TF_reenable:
        set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
 -      regs->flags &= ~TF_MASK;
 +      regs->flags &= ~X86_EFLAGS_TF;
        return;
  }
  
   */
  void math_error(void __user *ip)
  {
 -      struct task_struct * task;
 +      struct task_struct *task;
 +      unsigned short cwd;
 +      unsigned short swd;
        siginfo_t info;
 -      unsigned short cwd, swd;
  
        /*
         * Save the info for the exception handler and clear the error.
        cwd = get_fpu_cwd(task);
        swd = get_fpu_swd(task);
        switch (swd & ~cwd & 0x3f) {
 -              case 0x000: /* No unmasked exception */
 -                      return;
 -              default:    /* Multiple exceptions */
 -                      break;
 -              case 0x001: /* Invalid Op */
 -                      /*
 -                       * swd & 0x240 == 0x040: Stack Underflow
 -                       * swd & 0x240 == 0x240: Stack Overflow
 -                       * User must clear the SF bit (0x40) if set
 -                       */
 -                      info.si_code = FPE_FLTINV;
 -                      break;
 -              case 0x002: /* Denormalize */
 -              case 0x010: /* Underflow */
 -                      info.si_code = FPE_FLTUND;
 -                      break;
 -              case 0x004: /* Zero Divide */
 -                      info.si_code = FPE_FLTDIV;
 -                      break;
 -              case 0x008: /* Overflow */
 -                      info.si_code = FPE_FLTOVF;
 -                      break;
 -              case 0x020: /* Precision */
 -                      info.si_code = FPE_FLTRES;
 -                      break;
 +      case 0x000: /* No unmasked exception */
 +              return;
 +      default:    /* Multiple exceptions */
 +              break;
 +      case 0x001: /* Invalid Op */
 +              /*
 +               * swd & 0x240 == 0x040: Stack Underflow
 +               * swd & 0x240 == 0x240: Stack Overflow
 +               * User must clear the SF bit (0x40) if set
 +               */
 +              info.si_code = FPE_FLTINV;
 +              break;
 +      case 0x002: /* Denormalize */
 +      case 0x010: /* Underflow */
 +              info.si_code = FPE_FLTUND;
 +              break;
 +      case 0x004: /* Zero Divide */
 +              info.si_code = FPE_FLTDIV;
 +              break;
 +      case 0x008: /* Overflow */
 +              info.si_code = FPE_FLTOVF;
 +              break;
 +      case 0x020: /* Precision */
 +              info.si_code = FPE_FLTRES;
 +              break;
        }
        force_sig_info(SIGFPE, &info, task);
  }
  
 -void do_coprocessor_error(struct pt_regs * regs, long error_code)
 +void do_coprocessor_error(struct pt_regs *regs, long error_code)
  {
        ignore_fpu_irq = 1;
        math_error((void __user *)regs->ip);
  
  static void simd_math_error(void __user *ip)
  {
 -      struct task_struct * task;
 -      siginfo_t info;
 +      struct task_struct *task;
        unsigned short mxcsr;
 +      siginfo_t info;
  
        /*
         * Save the info for the exception handler and clear the error.
         */
        mxcsr = get_fpu_mxcsr(task);
        switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
 -              case 0x000:
 -              default:
 -                      break;
 -              case 0x001: /* Invalid Op */
 -                      info.si_code = FPE_FLTINV;
 -                      break;
 -              case 0x002: /* Denormalize */
 -              case 0x010: /* Underflow */
 -                      info.si_code = FPE_FLTUND;
 -                      break;
 -              case 0x004: /* Zero Divide */
 -                      info.si_code = FPE_FLTDIV;
 -                      break;
 -              case 0x008: /* Overflow */
 -                      info.si_code = FPE_FLTOVF;
 -                      break;
 -              case 0x020: /* Precision */
 -                      info.si_code = FPE_FLTRES;
 -                      break;
 +      case 0x000:
 +      default:
 +              break;
 +      case 0x001: /* Invalid Op */
 +              info.si_code = FPE_FLTINV;
 +              break;
 +      case 0x002: /* Denormalize */
 +      case 0x010: /* Underflow */
 +              info.si_code = FPE_FLTUND;
 +              break;
 +      case 0x004: /* Zero Divide */
 +              info.si_code = FPE_FLTDIV;
 +              break;
 +      case 0x008: /* Overflow */
 +              info.si_code = FPE_FLTOVF;
 +              break;
 +      case 0x020: /* Precision */
 +              info.si_code = FPE_FLTRES;
 +              break;
        }
        force_sig_info(SIGFPE, &info, task);
  }
  
 -void do_simd_coprocessor_error(struct pt_regs * regs,
 -                                        long error_code)
 +void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
  {
        if (cpu_has_xmm) {
                /* Handle SIMD FPU exceptions on PIII+ processors. */
                ignore_fpu_irq = 1;
                simd_math_error((void __user *)regs->ip);
 -      } else {
 -              /*
 -               * Handle strange cache flush from user space exception
 -               * in all other cases.  This is undocumented behaviour.
 -               */
 -              if (regs->flags & VM_MASK) {
 -                      handle_vm86_fault((struct kernel_vm86_regs *)regs,
 -                                        error_code);
 -                      return;
 -              }
 -              current->thread.trap_no = 19;
 -              current->thread.error_code = error_code;
 -              die_if_kernel("cache flush denied", regs, error_code);
 -              force_sig(SIGSEGV, current);
 +              return;
 +      }
 +      /*
 +       * Handle strange cache flush from user space exception
 +       * in all other cases.  This is undocumented behaviour.
 +       */
 +      if (regs->flags & X86_VM_MASK) {
 +              handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
 +              return;
        }
 +      current->thread.trap_no = 19;
 +      current->thread.error_code = error_code;
 +      die_if_kernel("cache flush denied", regs, error_code);
 +      force_sig(SIGSEGV, current);
  }
  
 -void do_spurious_interrupt_bug(struct pt_regs * regs,
 -                                        long error_code)
 +void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
  {
  #if 0
        /* No need to warn about this any longer. */
 -      printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
 +      printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
  #endif
  }
  
 -unsigned long patch_espfix_desc(unsigned long uesp,
 -                                        unsigned long kesp)
 +unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
  {
        struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
        unsigned long base = (kesp - uesp) & -THREAD_SIZE;
        unsigned long new_kesp = kesp - base;
        unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
        __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
 +
        /* Set up base for espfix segment */
 -      desc &= 0x00f0ff0000000000ULL;
 -      desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
 +      desc &= 0x00f0ff0000000000ULL;
 +      desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
                ((((__u64)base) << 32) & 0xff00000000000000ULL) |
                ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
                (lim_pages & 0xffff);
        *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
 +
        return new_kesp;
  }
  
  /*
 - *  'math_state_restore()' saves the current math information in the
 + * 'math_state_restore()' saves the current math information in the
   * old math state array, and gets the new ones from the current task
   *
   * Careful.. There are problems with IBM-designed IRQ13 behaviour.
@@@ -1146,7 -1117,7 +1148,7 @@@ asmlinkage void math_state_restore(void
        struct thread_info *thread = current_thread_info();
        struct task_struct *tsk = thread->task;
  
 -      clts();         /* Allow maths ops (or we recurse) */
 +      clts();                         /* Allow maths ops (or we recurse) */
        if (!tsk_used_math(tsk))
                init_fpu(tsk);
        restore_fpu(tsk);
@@@ -1159,52 -1130,53 +1161,52 @@@ EXPORT_SYMBOL_GPL(math_state_restore)
  
  asmlinkage void math_emulate(long arg)
  {
 -      printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n");
 -      printk(KERN_EMERG "killing %s.\n",current->comm);
 -      force_sig(SIGFPE,current);
 +      printk(KERN_EMERG
 +              "math-emulation not enabled and no coprocessor found.\n");
 +      printk(KERN_EMERG "killing %s.\n", current->comm);
 +      force_sig(SIGFPE, current);
        schedule();
  }
  
  #endif /* CONFIG_MATH_EMULATION */
  
 -
  void __init trap_init(void)
  {
        int i;
  
  #ifdef CONFIG_EISA
        void __iomem *p = early_ioremap(0x0FFFD9, 4);
 -      if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
 +
 +      if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
                EISA_bus = 1;
 -      }
        early_iounmap(p, 4);
  #endif
  
  #ifdef CONFIG_X86_LOCAL_APIC
        init_apic_mappings();
  #endif
 -
 -      set_trap_gate(0,&divide_error);
 -      set_intr_gate(1,&debug);
 -      set_intr_gate(2,&nmi);
 +      set_trap_gate(0,  &divide_error);
 +      set_intr_gate(1,  &debug);
 +      set_intr_gate(2,  &nmi);
        set_system_intr_gate(3, &int3); /* int3/4 can be called from all */
 -      set_system_gate(4,&overflow);
 -      set_trap_gate(5,&bounds);
 -      set_trap_gate(6,&invalid_op);
 -      set_trap_gate(7,&device_not_available);
 -      set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
 -      set_trap_gate(9,&coprocessor_segment_overrun);
 -      set_trap_gate(10,&invalid_TSS);
 -      set_trap_gate(11,&segment_not_present);
 -      set_trap_gate(12,&stack_segment);
 -      set_trap_gate(13,&general_protection);
 -      set_intr_gate(14,&page_fault);
 -      set_trap_gate(15,&spurious_interrupt_bug);
 -      set_trap_gate(16,&coprocessor_error);
 -      set_trap_gate(17,&alignment_check);
 +      set_system_gate(4, &overflow);
 +      set_trap_gate(5,  &bounds);
 +      set_trap_gate(6,  &invalid_op);
 +      set_trap_gate(7,  &device_not_available);
 +      set_task_gate(8,  GDT_ENTRY_DOUBLEFAULT_TSS);
 +      set_trap_gate(9,  &coprocessor_segment_overrun);
 +      set_trap_gate(10, &invalid_TSS);
 +      set_trap_gate(11, &segment_not_present);
 +      set_trap_gate(12, &stack_segment);
 +      set_trap_gate(13, &general_protection);
 +      set_intr_gate(14, &page_fault);
 +      set_trap_gate(15, &spurious_interrupt_bug);
 +      set_trap_gate(16, &coprocessor_error);
 +      set_trap_gate(17, &alignment_check);
  #ifdef CONFIG_X86_MCE
 -      set_trap_gate(18,&machine_check);
 +      set_trap_gate(18, &machine_check);
  #endif
 -      set_trap_gate(19,&simd_coprocessor_error);
 +      set_trap_gate(19, &simd_coprocessor_error);
  
        /*
         * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
                printk("done.\n");
        }
        if (cpu_has_xmm) {
 -              printk(KERN_INFO "Enabling unmasked SIMD FPU exception "
 -                              "support... ");
 +              printk(KERN_INFO
 +                      "Enabling unmasked SIMD FPU exception support... ");
                set_in_cr4(X86_CR4_OSXMMEXCPT);
                printk("done.\n");
        }
  
 -      set_system_gate(SYSCALL_VECTOR,&system_call);
 +      set_system_gate(SYSCALL_VECTOR, &system_call);
  
 -      /* Reserve all the builtin and the syscall vector. */
 +      /* Reserve all the builtin and the syscall vector: */
        for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
                set_bit(i, used_vectors);
 +
        set_bit(SYSCALL_VECTOR, used_vectors);
  
        /*
 -       * Should be a barrier for any external CPU state.
 +       * Should be a barrier for any external CPU state:
         */
        cpu_init();
  
  static int __init kstack_setup(char *s)
  {
        kstack_depth_to_print = simple_strtoul(s, NULL, 0);
 +
        return 1;
  }
  __setup("kstack=", kstack_setup);
@@@ -33,8 -33,6 +33,8 @@@
  #include <linux/kdebug.h>
  #include <linux/utsname.h>
  
 +#include <mach_traps.h>
 +
  #if defined(CONFIG_EDAC)
  #include <linux/edac.h>
  #endif
@@@ -602,8 -600,13 +602,13 @@@ void die(const char * str, struct pt_re
  
  void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
  {
-       unsigned long flags = oops_begin();
+       unsigned long flags;
  
+       if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) ==
+           NOTIFY_STOP)
+               return;
+       flags = oops_begin();
        /*
         * We are in trouble anyway, lets at least try
         * to get a message out.
@@@ -808,6 -811,8 +813,8 @@@ io_check_error(unsigned char reason, st
  static __kprobes void
  unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
  {
+       if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
+               return;
        printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
                reason);
        printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n");
diff --combined include/asm-x86/kdebug.h
@@@ -20,15 -20,16 +20,16 @@@ enum die_val 
        DIE_CALL,
        DIE_NMI_IPI,
        DIE_PAGE_FAULT,
+       DIE_NMIUNKNOWN,
  };
  
  extern void printk_address(unsigned long address, int reliable);
 -extern void die(const char *,struct pt_regs *,long);
 +extern void die(const char *, struct pt_regs *,long);
  extern int __must_check __die(const char *, struct pt_regs *, long);
  extern void show_registers(struct pt_regs *regs);
  extern void __show_registers(struct pt_regs *, int all);
  extern void show_trace(struct task_struct *t, struct pt_regs *regs,
 -                      unsigned long *sp, unsigned long bp);
 +                     unsigned long *sp, unsigned long bp);
  extern void __show_regs(struct pt_regs *regs);
  extern void show_regs(struct pt_regs *regs);
  extern unsigned long oops_begin(void);
diff --combined kernel/Makefile
@@@ -8,7 -8,7 +8,7 @@@ obj-y     = sched.o fork.o exec_domain.
            signal.o sys.o kmod.o workqueue.o pid.o \
            rcupdate.o extable.o params.o posix-timers.o \
            kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
 -          hrtimer.o rwsem.o nsproxy.o srcu.o \
 +          hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
            notifier.o ksysfs.o pm_qos_params.o
  
  obj-$(CONFIG_SYSCTL) += sysctl_check.o
@@@ -53,6 -53,7 +53,7 @@@ obj-$(CONFIG_AUDIT) += audit.o auditfil
  obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
  obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
  obj-$(CONFIG_KPROBES) += kprobes.o
+ obj-$(CONFIG_KGDB) += kgdb.o
  obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
  obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
  obj-$(CONFIG_SECCOMP) += seccomp.o
diff --combined lib/Kconfig.debug
@@@ -211,7 -211,7 +211,7 @@@ config SLUB_DEBUG_O
  config SLUB_STATS
        default n
        bool "Enable SLUB performance statistics"
 -      depends on SLUB
 +      depends on SLUB && SLUB_DEBUG && SYSFS
        help
          SLUB statistics are useful to debug SLUBs allocation behavior in
          order find ways to optimize the allocator. This should never be
@@@ -265,6 -265,16 +265,6 @@@ config DEBUG_MUTEXE
         This feature allows mutex semantics violations to be detected and
         reported.
  
 -config DEBUG_SEMAPHORE
 -      bool "Semaphore debugging"
 -      depends on DEBUG_KERNEL
 -      depends on ALPHA || FRV
 -      default n
 -      help
 -        If you say Y here then semaphore processing will issue lots of
 -        verbose debugging messages.  If you suspect a semaphore problem or a
 -        kernel hacker asks for this option then say Y.  Otherwise say N.
 -
  config DEBUG_LOCK_ALLOC
        bool "Lock debugging: detect incorrect freeing of live locks"
        depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@@ -612,3 -622,5 +612,5 @@@ config PROVIDE_OHCI1394_DMA_INI
          See Documentation/debugging-via-ohci1394.txt for more information.
  
  source "samples/Kconfig"
+ source "lib/Kconfig.kgdb"