Merge branch 'linus' into tracing/hw-breakpoints
Ingo Molnar [Wed, 17 Jun 2009 10:52:15 +0000 (12:52 +0200)]
Conflicts:
arch/x86/Kconfig
arch/x86/kernel/traps.c
arch/x86/power/cpu.c
arch/x86/power/cpu_32.c
kernel/Makefile

Semantic conflict:
arch/x86/kernel/hw_breakpoint.c

Merge reason: Resolve the conflicts, move from put_cpu_no_sched() to
              put_cpu() in arch/x86/kernel/hw_breakpoint.c.

Signed-off-by: Ingo Molnar <mingo@elte.hu>

16 files changed:
1  2 
arch/x86/Kconfig
arch/x86/include/asm/processor.h
arch/x86/kernel/Makefile
arch/x86/kernel/hw_breakpoint.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/signal.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/traps.c
arch/x86/power/cpu.c
kernel/Makefile
kernel/trace/Kconfig
kernel/trace/Makefile
samples/Kconfig

diff --combined arch/x86/Kconfig
@@@ -46,7 -46,12 +46,13 @@@ config X8
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
 +      select HAVE_HW_BREAKPOINT
+       select HAVE_ARCH_KMEMCHECK
+ config OUTPUT_FORMAT
+       string
+       default "elf32-i386" if X86_32
+       default "elf64-x86-64" if X86_64
  
  config ARCH_DEFCONFIG
        string
@@@ -275,15 -280,9 +281,9 @@@ config SPARSE_IR
  
          If you don't know what to do here, say N.
  
- config NUMA_MIGRATE_IRQ_DESC
-       bool "Move irq desc when changing irq smp_affinity"
+ config NUMA_IRQ_DESC
+       def_bool y
        depends on SPARSE_IRQ && NUMA
-       depends on BROKEN
-       default n
-       ---help---
-         This enables moving irq_desc to cpu/node that irq will use handled.
-         If you don't know what to do here, say N.
  
  config X86_MPPARSE
        bool "Enable MPS table" if ACPI
@@@ -356,7 -355,7 +356,7 @@@ config X86_U
        depends on X86_64
        depends on X86_EXTENDED_PLATFORM
        depends on NUMA
-       select X86_X2APIC
+       depends on X86_X2APIC
        ---help---
          This option is needed in order to support SGI Ultraviolet systems.
          If you don't have one of these, you should say N here.
@@@ -499,6 -498,19 +499,19 @@@ config PARAVIR
          over full virtualization.  However, when run without a hypervisor
          the kernel is theoretically slower and slightly larger.
  
+ config PARAVIRT_SPINLOCKS
+       bool "Paravirtualization layer for spinlocks"
+       depends on PARAVIRT && SMP && EXPERIMENTAL
+       ---help---
+         Paravirtualized spinlocks allow a pvops backend to replace the
+         spinlock implementation with something virtualization-friendly
+         (for example, block the virtual CPU rather than spinning).
+         Unfortunately the downside is an up to 5% performance hit on
+         native kernels, with various workloads.
+         If you are unsure how to answer this question, answer N.
  config PARAVIRT_CLOCK
        bool
        default n
@@@ -728,6 -740,7 +741,7 @@@ config X86_UP_IOAPI
  config X86_LOCAL_APIC
        def_bool y
        depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
+       select HAVE_PERF_COUNTERS if (!M386 && !M486)
  
  config X86_IO_APIC
        def_bool y
@@@ -777,10 -790,26 +791,26 @@@ config X86_MC
          to disable it.  MCE support simply ignores non-MCE processors like
          the 386 and 486, so nearly everyone can say Y here.
  
+ config X86_OLD_MCE
+       depends on X86_32 && X86_MCE
+       bool "Use legacy machine check code (will go away)"
+       default n
+       select X86_ANCIENT_MCE
+       ---help---
+         Use the old i386 machine check code. This is merely intended for
+         testing in a transition period. Try this if you run into any machine
+         check related software problems, but report the problem to
+         linux-kernel.  When in doubt say no.
+ config X86_NEW_MCE
+       depends on X86_MCE
+       bool
+       default y if (!X86_OLD_MCE && X86_32) || X86_64
  config X86_MCE_INTEL
        def_bool y
        prompt "Intel MCE features"
-       depends on X86_64 && X86_MCE && X86_LOCAL_APIC
+       depends on X86_NEW_MCE && X86_LOCAL_APIC
        ---help---
           Additional support for intel specific MCE features such as
           the thermal monitor.
  config X86_MCE_AMD
        def_bool y
        prompt "AMD MCE features"
-       depends on X86_64 && X86_MCE && X86_LOCAL_APIC
+       depends on X86_NEW_MCE && X86_LOCAL_APIC
        ---help---
           Additional support for AMD specific MCE features such as
           the DRAM Error Threshold.
  
+ config X86_ANCIENT_MCE
+       def_bool n
+       depends on X86_32
+       prompt "Support for old Pentium 5 / WinChip machine checks"
+       ---help---
+         Include support for machine check handling on old Pentium 5 or WinChip
+         systems. These typically need to be enabled explicitely on the command
+         line.
  config X86_MCE_THRESHOLD
        depends on X86_MCE_AMD || X86_MCE_INTEL
        bool
        default y
  
+ config X86_MCE_INJECT
+       depends on X86_NEW_MCE
+       tristate "Machine check injector support"
+       ---help---
+         Provide support for injecting machine checks for testing purposes.
+         If you don't know what a machine check is and you don't do kernel
+         QA it is safe to say n.
  config X86_MCE_NONFATAL
        tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
-       depends on X86_32 && X86_MCE
+       depends on X86_OLD_MCE
        ---help---
          Enabling this feature starts a timer that triggers every 5 seconds which
          will look at the machine check registers to see if anything happened.
  
  config X86_MCE_P4THERMAL
        bool "check for P4 thermal throttling interrupt."
-       depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP)
+       depends on X86_OLD_MCE && X86_MCE && (X86_UP_APIC || SMP)
        ---help---
          Enabling this feature will cause a message to be printed when the P4
          enters thermal throttling.
  
+ config X86_THERMAL_VECTOR
+       def_bool y
+       depends on X86_MCE_P4THERMAL || X86_MCE_INTEL
  config VM86
        bool "Enable VM86 support" if EMBEDDED
        default y
@@@ -1454,9 -1504,7 +1505,7 @@@ config KEXEC_JUM
  
  config PHYSICAL_START
        hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
-       default "0x1000000" if X86_NUMAQ
-       default "0x200000" if X86_64
-       default "0x100000"
+       default "0x1000000"
        ---help---
          This gives the physical address where the kernel is loaded.
  
          to be specifically compiled to run from a specific memory area
          (normally a reserved region) and this option comes handy.
  
-         So if you are using bzImage for capturing the crash dump, leave
-         the value here unchanged to 0x100000 and set CONFIG_RELOCATABLE=y.
-         Otherwise if you plan to use vmlinux for capturing the crash dump
-         change this value to start of the reserved region (Typically 16MB
-         0x1000000). In other words, it can be set based on the "X" value as
-         specified in the "crashkernel=YM@XM" command line boot parameter
-         passed to the panic-ed kernel. Typically this parameter is set as
-         crashkernel=64M@16M. Please take a look at
-         Documentation/kdump/kdump.txt for more details about crash dumps.
+         So if you are using bzImage for capturing the crash dump,
+         leave the value here unchanged to 0x1000000 and set
+         CONFIG_RELOCATABLE=y.  Otherwise if you plan to use vmlinux
+         for capturing the crash dump change this value to start of
+         the reserved region.  In other words, it can be set based on
+         the "X" value as specified in the "crashkernel=YM@XM"
+         command line boot parameter passed to the panic-ed
+         kernel. Please take a look at Documentation/kdump/kdump.txt
+         for more details about crash dumps.
  
          Usage of bzImage for capturing the crash dump is recommended as
          one does not have to build two kernels. Same kernel can be used
          Don't change this unless you know what you are doing.
  
  config RELOCATABLE
-       bool "Build a relocatable kernel (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       bool "Build a relocatable kernel"
+       default y
        ---help---
          This builds a kernel image that retains relocation information
          so it can be loaded someplace besides the default 1MB.
          it has been loaded at and the compile time physical address
          (CONFIG_PHYSICAL_START) is ignored.
  
+ # Relocation on x86-32 needs some additional build support
+ config X86_NEED_RELOCS
+       def_bool y
+       depends on X86_32 && RELOCATABLE
  config PHYSICAL_ALIGN
        hex
        prompt "Alignment value to which kernel should be aligned" if X86_32
-       default "0x100000" if X86_32
-       default "0x200000" if X86_64
-       range 0x2000 0x400000
+       default "0x1000000"
+       range 0x2000 0x1000000
        ---help---
          This value puts the alignment restrictions on physical address
          where kernel is loaded and run from. Kernel is compiled for an
@@@ -29,7 -29,6 +29,7 @@@ struct mm_struct
  #include <linux/threads.h>
  #include <linux/init.h>
  
 +#define HBP_NUM 4
  /*
   * Default implementation of macro that returns current
   * instruction pointer ("program counter").
@@@ -136,7 -135,8 +136,8 @@@ extern struct cpuinfo_x86  boot_cpu_data
  extern struct cpuinfo_x86     new_cpu_data;
  
  extern struct tss_struct      doublefault_tss;
- extern __u32                  cleared_cpu_caps[NCAPINTS];
+ extern __u32                  cpu_caps_cleared[NCAPINTS];
+ extern __u32                  cpu_caps_set[NCAPINTS];
  
  #ifdef CONFIG_SMP
  DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
@@@ -410,9 -410,6 +411,6 @@@ DECLARE_PER_CPU(unsigned long, stack_ca
  extern unsigned int xstate_size;
  extern void free_thread_xstate(struct task_struct *);
  extern struct kmem_cache *task_xstate_cachep;
- extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
- extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
- extern unsigned short num_cache_leaves;
  
  struct thread_struct {
        /* Cached TLS descriptors: */
        unsigned short          fsindex;
        unsigned short          gsindex;
  #endif
+ #ifdef CONFIG_X86_32
        unsigned long           ip;
+ #endif
+ #ifdef CONFIG_X86_64
        unsigned long           fs;
+ #endif
        unsigned long           gs;
        /* Hardware debugging registers: */
 -      unsigned long           debugreg0;
 -      unsigned long           debugreg1;
 -      unsigned long           debugreg2;
 -      unsigned long           debugreg3;
 +      unsigned long           debugreg[HBP_NUM];
        unsigned long           debugreg6;
        unsigned long           debugreg7;
 +      /* Hardware breakpoint info */
 +      struct hw_breakpoint    *hbp[HBP_NUM];
        /* Fault info: */
        unsigned long           cr2;
        unsigned long           trap_no;
@@@ -835,6 -837,7 +837,7 @@@ extern unsigned int                BIOS_revision
  
  /* Boot loader type from the setup header: */
  extern int                    bootloader_type;
+ extern int                    bootloader_version;
  
  extern char                   ignore_fpu_irq;
  
@@@ -895,7 -898,6 +898,6 @@@ static inline void spin_lock_prefetch(c
        .vm86_info              = NULL,                                   \
        .sysenter_cs            = __KERNEL_CS,                            \
        .io_bitmap_ptr          = NULL,                                   \
-       .fs                     = __KERNEL_PERCPU,                        \
  }
  
  /*
diff --combined arch/x86/kernel/Makefile
@@@ -28,7 -28,7 +28,7 @@@ CFLAGS_paravirt.o     := $(nostackp
  obj-y                 := process_$(BITS).o signal.o entry_$(BITS).o
  obj-y                 += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
  obj-y                 += time_$(BITS).o ioport.o ldt.o dumpstack.o
- obj-y                 += setup.o i8259.o irqinit_$(BITS).o
+ obj-y                 += setup.o i8259.o irqinit.o
  obj-$(CONFIG_X86_VISWS)       += visws_quirks.o
  obj-$(CONFIG_X86_32)  += probe_roms_32.o
  obj-$(CONFIG_X86_32)  += sys_i386_32.o i386_ksyms_32.o
@@@ -36,7 -36,7 +36,7 @@@ obj-$(CONFIG_X86_64)  += sys_x86_64.o x8
  obj-$(CONFIG_X86_64)  += syscall_64.o vsyscall_64.o
  obj-y                 += bootflag.o e820.o
  obj-y                 += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 -obj-y                 += alternative.o i8253.o pci-nommu.o
 +obj-y                 += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
  obj-y                 += tsc.o io_delay.o rtc.o
  
  obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
@@@ -73,7 -73,7 +73,7 @@@ obj-$(CONFIG_KEXEC)           += machine_kexec_$
  obj-$(CONFIG_KEXEC)           += relocate_kernel_$(BITS).o crash.o
  obj-$(CONFIG_CRASH_DUMP)      += crash_dump_$(BITS).o
  obj-$(CONFIG_KPROBES)         += kprobes.o
- obj-$(CONFIG_MODULES)         += module_$(BITS).o
+ obj-$(CONFIG_MODULES)         += module.o
  obj-$(CONFIG_EFI)             += efi.o efi_$(BITS).o efi_stub_$(BITS).o
  obj-$(CONFIG_DOUBLEFAULT)     += doublefault_32.o
  obj-$(CONFIG_KGDB)            += kgdb.o
@@@ -90,7 -90,8 +90,8 @@@ obj-$(CONFIG_DEBUG_NX_TEST)   += test_nx.
  obj-$(CONFIG_VMI)             += vmi_32.o vmiclock_32.o
  obj-$(CONFIG_KVM_GUEST)               += kvm.o
  obj-$(CONFIG_KVM_CLOCK)               += kvmclock.o
- obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirt_patch_$(BITS).o paravirt-spinlocks.o
+ obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirt_patch_$(BITS).o
+ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
  obj-$(CONFIG_PARAVIRT_CLOCK)  += pvclock.o
  
  obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
index 6945147,0000000..51d9595
mode 100644,000000..100644
--- /dev/null
@@@ -1,391 -1,0 +1,391 @@@
 +/*
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation; either version 2 of the License, or
 + * (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 + *
 + * Copyright (C) 2007 Alan Stern
 + * Copyright (C) 2009 IBM Corporation
 + */
 +
 +/*
 + * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
 + * using the CPU's debug registers.
 + */
 +
 +#include <linux/irqflags.h>
 +#include <linux/notifier.h>
 +#include <linux/kallsyms.h>
 +#include <linux/kprobes.h>
 +#include <linux/percpu.h>
 +#include <linux/kdebug.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/sched.h>
 +#include <linux/init.h>
 +#include <linux/smp.h>
 +
 +#include <asm/hw_breakpoint.h>
 +#include <asm/processor.h>
 +#include <asm/debugreg.h>
 +
 +/* Unmasked kernel DR7 value */
 +static unsigned long kdr7;
 +
 +/*
 + * Masks for the bits corresponding to registers DR0 - DR3 in DR7 register.
 + * Used to clear and verify the status of bits corresponding to DR0 - DR3
 + */
 +static const unsigned long    dr7_masks[HBP_NUM] = {
 +      0x000f0003,     /* LEN0, R/W0, G0, L0 */
 +      0x00f0000c,     /* LEN1, R/W1, G1, L1 */
 +      0x0f000030,     /* LEN2, R/W2, G2, L2 */
 +      0xf00000c0      /* LEN3, R/W3, G3, L3 */
 +};
 +
 +
 +/*
 + * Encode the length, type, Exact, and Enable bits for a particular breakpoint
 + * as stored in debug register 7.
 + */
 +static unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
 +{
 +      unsigned long bp_info;
 +
 +      bp_info = (len | type) & 0xf;
 +      bp_info <<= (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
 +      bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE)) |
 +                              DR_GLOBAL_SLOWDOWN;
 +      return bp_info;
 +}
 +
 +void arch_update_kernel_hw_breakpoint(void *unused)
 +{
 +      struct hw_breakpoint *bp;
 +      int i, cpu = get_cpu();
 +      unsigned long temp_kdr7 = 0;
 +
 +      /* Don't allow debug exceptions while we update the registers */
 +      set_debugreg(0UL, 7);
 +
 +      for (i = hbp_kernel_pos; i < HBP_NUM; i++) {
 +              per_cpu(this_hbp_kernel[i], cpu) = bp = hbp_kernel[i];
 +              if (bp) {
 +                      temp_kdr7 |= encode_dr7(i, bp->info.len, bp->info.type);
 +                      set_debugreg(bp->info.address, i);
 +              }
 +      }
 +
 +      /* No need to set DR6. Update the debug registers with kernel-space
 +       * breakpoint values from kdr7 and user-space requests from the
 +       * current process
 +       */
 +      kdr7 = temp_kdr7;
 +      set_debugreg(kdr7 | current->thread.debugreg7, 7);
-       put_cpu_no_resched();
++      put_cpu();
 +}
 +
 +/*
 + * Install the thread breakpoints in their debug registers.
 + */
 +void arch_install_thread_hw_breakpoint(struct task_struct *tsk)
 +{
 +      struct thread_struct *thread = &(tsk->thread);
 +
 +      switch (hbp_kernel_pos) {
 +      case 4:
 +              set_debugreg(thread->debugreg[3], 3);
 +      case 3:
 +              set_debugreg(thread->debugreg[2], 2);
 +      case 2:
 +              set_debugreg(thread->debugreg[1], 1);
 +      case 1:
 +              set_debugreg(thread->debugreg[0], 0);
 +      default:
 +              break;
 +      }
 +
 +      /* No need to set DR6 */
 +      set_debugreg((kdr7 | thread->debugreg7), 7);
 +}
 +
 +/*
 + * Install the debug register values for just the kernel, no thread.
 + */
 +void arch_uninstall_thread_hw_breakpoint()
 +{
 +      /* Clear the user-space portion of debugreg7 by setting only kdr7 */
 +      set_debugreg(kdr7, 7);
 +
 +}
 +
 +static int get_hbp_len(u8 hbp_len)
 +{
 +      unsigned int len_in_bytes = 0;
 +
 +      switch (hbp_len) {
 +      case HW_BREAKPOINT_LEN_1:
 +              len_in_bytes = 1;
 +              break;
 +      case HW_BREAKPOINT_LEN_2:
 +              len_in_bytes = 2;
 +              break;
 +      case HW_BREAKPOINT_LEN_4:
 +              len_in_bytes = 4;
 +              break;
 +#ifdef CONFIG_X86_64
 +      case HW_BREAKPOINT_LEN_8:
 +              len_in_bytes = 8;
 +              break;
 +#endif
 +      }
 +      return len_in_bytes;
 +}
 +
 +/*
 + * Check for virtual address in user space.
 + */
 +int arch_check_va_in_userspace(unsigned long va, u8 hbp_len)
 +{
 +      unsigned int len;
 +
 +      len = get_hbp_len(hbp_len);
 +
 +      return (va <= TASK_SIZE - len);
 +}
 +
 +/*
 + * Check for virtual address in kernel space.
 + */
 +int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
 +{
 +      unsigned int len;
 +
 +      len = get_hbp_len(hbp_len);
 +
 +      return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 +}
 +
 +/*
 + * Store a breakpoint's encoded address, length, and type.
 + */
 +static int arch_store_info(struct hw_breakpoint *bp, struct task_struct *tsk)
 +{
 +      /*
 +       * User-space requests will always have the address field populated
 +       * Symbol names from user-space are rejected
 +       */
 +      if (tsk && bp->info.name)
 +              return -EINVAL;
 +      /*
 +       * For kernel-addresses, either the address or symbol name can be
 +       * specified.
 +       */
 +      if (bp->info.name)
 +              bp->info.address = (unsigned long)
 +                                      kallsyms_lookup_name(bp->info.name);
 +      if (bp->info.address)
 +              return 0;
 +      return -EINVAL;
 +}
 +
 +/*
 + * Validate the arch-specific HW Breakpoint register settings
 + */
 +int arch_validate_hwbkpt_settings(struct hw_breakpoint *bp,
 +                                              struct task_struct *tsk)
 +{
 +      unsigned int align;
 +      int ret = -EINVAL;
 +
 +      switch (bp->info.type) {
 +      /*
 +       * Ptrace-refactoring code
 +       * For now, we'll allow instruction breakpoint only for user-space
 +       * addresses
 +       */
 +      case HW_BREAKPOINT_EXECUTE:
 +              if ((!arch_check_va_in_userspace(bp->info.address,
 +                                                      bp->info.len)) &&
 +                      bp->info.len != HW_BREAKPOINT_LEN_EXECUTE)
 +                      return ret;
 +              break;
 +      case HW_BREAKPOINT_WRITE:
 +              break;
 +      case HW_BREAKPOINT_RW:
 +              break;
 +      default:
 +              return ret;
 +      }
 +
 +      switch (bp->info.len) {
 +      case HW_BREAKPOINT_LEN_1:
 +              align = 0;
 +              break;
 +      case HW_BREAKPOINT_LEN_2:
 +              align = 1;
 +              break;
 +      case HW_BREAKPOINT_LEN_4:
 +              align = 3;
 +              break;
 +#ifdef CONFIG_X86_64
 +      case HW_BREAKPOINT_LEN_8:
 +              align = 7;
 +              break;
 +#endif
 +      default:
 +              return ret;
 +      }
 +
 +      if (bp->triggered)
 +              ret = arch_store_info(bp, tsk);
 +
 +      if (ret < 0)
 +              return ret;
 +      /*
 +       * Check that the low-order bits of the address are appropriate
 +       * for the alignment implied by len.
 +       */
 +      if (bp->info.address & align)
 +              return -EINVAL;
 +
 +      /* Check that the virtual address is in the proper range */
 +      if (tsk) {
 +              if (!arch_check_va_in_userspace(bp->info.address, bp->info.len))
 +                      return -EFAULT;
 +      } else {
 +              if (!arch_check_va_in_kernelspace(bp->info.address,
 +                                                              bp->info.len))
 +                      return -EFAULT;
 +      }
 +      return 0;
 +}
 +
 +void arch_update_user_hw_breakpoint(int pos, struct task_struct *tsk)
 +{
 +      struct thread_struct *thread = &(tsk->thread);
 +      struct hw_breakpoint *bp = thread->hbp[pos];
 +
 +      thread->debugreg7 &= ~dr7_masks[pos];
 +      if (bp) {
 +              thread->debugreg[pos] = bp->info.address;
 +              thread->debugreg7 |= encode_dr7(pos, bp->info.len,
 +                                                      bp->info.type);
 +      } else
 +              thread->debugreg[pos] = 0;
 +}
 +
 +void arch_flush_thread_hw_breakpoint(struct task_struct *tsk)
 +{
 +      int i;
 +      struct thread_struct *thread = &(tsk->thread);
 +
 +      thread->debugreg7 = 0;
 +      for (i = 0; i < HBP_NUM; i++)
 +              thread->debugreg[i] = 0;
 +}
 +
 +/*
 + * Handle debug exception notifications.
 + *
 + * Return value is either NOTIFY_STOP or NOTIFY_DONE as explained below.
 + *
 + * NOTIFY_DONE returned if one of the following conditions is true.
 + * i) When the causative address is from user-space and the exception
 + * is a valid one, i.e. not triggered as a result of lazy debug register
 + * switching
 + * ii) When there are more bits than trap<n> set in DR6 register (such
 + * as BD, BS or BT) indicating that more than one debug condition is
 + * met and requires some more action in do_debug().
 + *
 + * NOTIFY_STOP returned for all other cases
 + *
 + */
 +int __kprobes hw_breakpoint_handler(struct die_args *args)
 +{
 +      int i, cpu, rc = NOTIFY_STOP;
 +      struct hw_breakpoint *bp;
 +      unsigned long dr7, dr6;
 +      unsigned long *dr6_p;
 +
 +      /* The DR6 value is pointed by args->err */
 +      dr6_p = (unsigned long *)ERR_PTR(args->err);
 +      dr6 = *dr6_p;
 +
 +      /* Do an early return if no trap bits are set in DR6 */
 +      if ((dr6 & DR_TRAP_BITS) == 0)
 +              return NOTIFY_DONE;
 +
 +      /* Lazy debug register switching */
 +      if (!test_tsk_thread_flag(current, TIF_DEBUG))
 +              arch_uninstall_thread_hw_breakpoint();
 +
 +      get_debugreg(dr7, 7);
 +      /* Disable breakpoints during exception handling */
 +      set_debugreg(0UL, 7);
 +      /*
 +       * Assert that local interrupts are disabled
 +       * Reset the DRn bits in the virtualized register value.
 +       * The ptrace trigger routine will add in whatever is needed.
 +       */
 +      current->thread.debugreg6 &= ~DR_TRAP_BITS;
 +      cpu = get_cpu();
 +
 +      /* Handle all the breakpoints that were triggered */
 +      for (i = 0; i < HBP_NUM; ++i) {
 +              if (likely(!(dr6 & (DR_TRAP0 << i))))
 +                      continue;
 +              /*
 +               * Find the corresponding hw_breakpoint structure and
 +               * invoke its triggered callback.
 +               */
 +              if (i >= hbp_kernel_pos)
 +                      bp = per_cpu(this_hbp_kernel[i], cpu);
 +              else {
 +                      bp = current->thread.hbp[i];
 +                      if (bp)
 +                              rc = NOTIFY_DONE;
 +              }
 +              /*
 +               * Reset the 'i'th TRAP bit in dr6 to denote completion of
 +               * exception handling
 +               */
 +              (*dr6_p) &= ~(DR_TRAP0 << i);
 +              /*
 +               * bp can be NULL due to lazy debug register switching
 +               * or due to the delay between updates of hbp_kernel_pos
 +               * and this_hbp_kernel.
 +               */
 +              if (!bp)
 +                      continue;
 +
 +              (bp->triggered)(bp, args->regs);
 +      }
 +      if (dr6 & (~DR_TRAP_BITS))
 +              rc = NOTIFY_DONE;
 +
 +      set_debugreg(dr7, 7);
-       put_cpu_no_resched();
++      put_cpu();
 +      return rc;
 +}
 +
 +/*
 + * Handle debug exception notifications.
 + */
 +int __kprobes hw_breakpoint_exceptions_notify(
 +              struct notifier_block *unused, unsigned long val, void *data)
 +{
 +      if (val != DIE_DEBUG)
 +              return NOTIFY_DONE;
 +
 +      return hw_breakpoint_handler(data);
 +}
diff --combined arch/x86/kernel/kgdb.c
@@@ -43,7 -43,6 +43,7 @@@
  #include <linux/smp.h>
  #include <linux/nmi.h>
  
 +#include <asm/debugreg.h>
  #include <asm/apicdef.h>
  #include <asm/system.h>
  
@@@ -143,7 -142,7 +143,7 @@@ void sleeping_thread_to_gdb_regs(unsign
        gdb_regs32[GDB_PS]      = *(unsigned long *)(p->thread.sp + 8);
        gdb_regs32[GDB_CS]      = __KERNEL_CS;
        gdb_regs32[GDB_SS]      = __KERNEL_DS;
-       gdb_regs[GDB_PC]        = p->thread.ip;
+       gdb_regs[GDB_PC]        = 0;
        gdb_regs[GDB_R8]        = 0;
        gdb_regs[GDB_R9]        = 0;
        gdb_regs[GDB_R10]       = 0;
@@@ -435,11 -434,6 +435,11 @@@ single_step_cont(struct pt_regs *regs, 
                        "resuming...\n");
        kgdb_arch_handle_exception(args->trapnr, args->signr,
                                   args->err, "c", "", regs);
 +      /*
 +       * Reset the BS bit in dr6 (pointed by args->err) to
 +       * denote completion of processing
 +       */
 +      (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP;
  
        return NOTIFY_STOP;
  }
@@@ -8,15 -8,15 +8,17 @@@
  #include <linux/module.h>
  #include <linux/pm.h>
  #include <linux/clockchips.h>
+ #include <linux/random.h>
  #include <trace/power.h>
  #include <asm/system.h>
  #include <asm/apic.h>
+ #include <asm/syscalls.h>
  #include <asm/idle.h>
  #include <asm/uaccess.h>
  #include <asm/i387.h>
  #include <asm/ds.h>
 +#include <asm/debugreg.h>
 +#include <asm/hw_breakpoint.h>
  
  unsigned long idle_halt;
  EXPORT_SYMBOL(idle_halt);
@@@ -48,8 -48,6 +50,8 @@@ void free_thread_xstate(struct task_str
                kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
                tsk->thread.xstate = NULL;
        }
 +      if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
 +              flush_thread_hw_breakpoint(tsk);
  
        WARN(tsk->thread.ds_ctx, "leaking DS context\n");
  }
@@@ -65,7 -63,7 +67,7 @@@ void arch_task_cache_init(void
          task_xstate_cachep =
                kmem_cache_create("task_xstate", xstate_size,
                                  __alignof__(union thread_xstate),
-                                 SLAB_PANIC, NULL);
+                                 SLAB_PANIC | SLAB_NOTRACK, NULL);
  }
  
  /*
@@@ -110,8 -108,12 +112,8 @@@ void flush_thread(void
  
        clear_tsk_thread_flag(tsk, TIF_DEBUG);
  
 -      tsk->thread.debugreg0 = 0;
 -      tsk->thread.debugreg1 = 0;
 -      tsk->thread.debugreg2 = 0;
 -      tsk->thread.debugreg3 = 0;
 -      tsk->thread.debugreg6 = 0;
 -      tsk->thread.debugreg7 = 0;
 +      if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
 +              flush_thread_hw_breakpoint(tsk);
        memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
        /*
         * Forget coprocessor state..
@@@ -193,6 -195,16 +195,6 @@@ void __switch_to_xtra(struct task_struc
        else if (next->debugctlmsr != prev->debugctlmsr)
                update_debugctlmsr(next->debugctlmsr);
  
 -      if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
 -              set_debugreg(next->debugreg0, 0);
 -              set_debugreg(next->debugreg1, 1);
 -              set_debugreg(next->debugreg2, 2);
 -              set_debugreg(next->debugreg3, 3);
 -              /* no 4 and 5 */
 -              set_debugreg(next->debugreg6, 6);
 -              set_debugreg(next->debugreg7, 7);
 -      }
 -
        if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
            test_tsk_thread_flag(next_p, TIF_NOTSC)) {
                /* prev and next are different */
@@@ -604,3 -616,16 +606,16 @@@ static int __init idle_setup(char *str
  }
  early_param("idle", idle_setup);
  
+ unsigned long arch_align_stack(unsigned long sp)
+ {
+       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+               sp -= get_random_int() % 8192;
+       return sp & ~0xf;
+ }
+ unsigned long arch_randomize_brk(struct mm_struct *mm)
+ {
+       unsigned long range_end = mm->brk + 0x02000000;
+       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+ }
@@@ -9,8 -9,6 +9,6 @@@
   * This file handles the architecture-dependent parts of process handling..
   */
  
- #include <stdarg.h>
  #include <linux/stackprotector.h>
  #include <linux/cpu.h>
  #include <linux/errno.h>
@@@ -33,7 -31,6 +31,6 @@@
  #include <linux/module.h>
  #include <linux/kallsyms.h>
  #include <linux/ptrace.h>
- #include <linux/random.h>
  #include <linux/personality.h>
  #include <linux/tick.h>
  #include <linux/percpu.h>
@@@ -61,8 -58,6 +58,8 @@@
  #include <asm/idle.h>
  #include <asm/syscalls.h>
  #include <asm/ds.h>
 +#include <asm/debugreg.h>
 +#include <asm/hw_breakpoint.h>
  
  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
  
@@@ -267,13 -262,7 +264,13 @@@ int copy_thread(unsigned long clone_fla
  
        task_user_gs(p) = get_user_gs(regs);
  
 +      p->thread.io_bitmap_ptr = NULL;
        tsk = current;
 +      err = -ENOMEM;
 +      if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
 +              if (copy_thread_hw_breakpoint(tsk, p, clone_flags))
 +                      goto out;
 +
        if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
                p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
                                                IO_BITMAP_BYTES, GFP_KERNEL);
                err = do_set_thread_area(p, -1,
                        (struct user_desc __user *)childregs->si, 0);
  
 +out:
        if (err && p->thread.io_bitmap_ptr) {
                kfree(p->thread.io_bitmap_ptr);
                p->thread.io_bitmap_max = 0;
        }
 +      if (err)
 +              flush_thread_hw_breakpoint(p);
  
        clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
        p->thread.ds_ctx = NULL;
@@@ -419,7 -405,7 +416,7 @@@ __switch_to(struct task_struct *prev_p
         * done before math_state_restore, so the TS bit is up
         * to date.
         */
-       arch_leave_lazy_cpu_mode();
+       arch_end_context_switch(next_p);
  
        /* If the task has used fpu the last 5 timeslices, just do a full
         * restore of the math state immediately to avoid the trap; the
                lazy_load_gs(next->gs);
  
        percpu_write(current_task, next_p);
 +      /*
 +       * There's a problem with moving the arch_install_thread_hw_breakpoint()
 +       * call before current is updated.  Suppose a kernel breakpoint is
 +       * triggered in between the two, the hw-breakpoint handler will see that
 +       * the 'current' task does not have TIF_DEBUG flag set and will think it
 +       * is leftover from an old task (lazy switching) and will erase it. Then
 +       * until the next context switch, no user-breakpoints will be installed.
 +       *
 +       * The real problem is that it's impossible to update both current and
 +       * physical debug registers at the same instant, so there will always be
 +       * a window in which they disagree and a breakpoint might get triggered.
 +       * Since we use lazy switching, we are forced to assume that a
 +       * disagreement means that current is correct and the exception is due
 +       * to lazy debug register switching.
 +       */
 +      if (unlikely(test_tsk_thread_flag(next_p, TIF_DEBUG)))
 +              arch_install_thread_hw_breakpoint(next_p);
  
        return prev_p;
  }
@@@ -526,15 -495,3 +523,3 @@@ unsigned long get_wchan(struct task_str
        return 0;
  }
  
- unsigned long arch_align_stack(unsigned long sp)
- {
-       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
-               sp -= get_random_int() % 8192;
-       return sp & ~0xf;
- }
- unsigned long arch_randomize_brk(struct mm_struct *mm)
- {
-       unsigned long range_end = mm->brk + 0x02000000;
-       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
- }
@@@ -14,8 -14,6 +14,6 @@@
   * This file handles the architecture-dependent parts of process handling..
   */
  
- #include <stdarg.h>
  #include <linux/stackprotector.h>
  #include <linux/cpu.h>
  #include <linux/errno.h>
@@@ -32,7 -30,6 +30,6 @@@
  #include <linux/delay.h>
  #include <linux/module.h>
  #include <linux/ptrace.h>
- #include <linux/random.h>
  #include <linux/notifier.h>
  #include <linux/kprobes.h>
  #include <linux/kdebug.h>
@@@ -55,8 -52,6 +52,8 @@@
  #include <asm/idle.h>
  #include <asm/syscalls.h>
  #include <asm/ds.h>
 +#include <asm/debugreg.h>
 +#include <asm/hw_breakpoint.h>
  
  asmlinkage extern void ret_from_fork(void);
  
@@@ -250,8 -245,6 +247,8 @@@ void release_thread(struct task_struct 
                        BUG();
                }
        }
 +      if (unlikely(dead_task->thread.debugreg7))
 +              flush_thread_hw_breakpoint(dead_task);
  }
  
  static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
@@@ -307,18 -300,12 +304,18 @@@ int copy_thread(unsigned long clone_fla
  
        p->thread.fs = me->thread.fs;
        p->thread.gs = me->thread.gs;
 +      p->thread.io_bitmap_ptr = NULL;
  
        savesegment(gs, p->thread.gsindex);
        savesegment(fs, p->thread.fsindex);
        savesegment(es, p->thread.es);
        savesegment(ds, p->thread.ds);
  
 +      err = -ENOMEM;
 +      if (unlikely(test_tsk_thread_flag(me, TIF_DEBUG)))
 +              if (copy_thread_hw_breakpoint(me, p, clone_flags))
 +                      goto out;
 +
        if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
                p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
                if (!p->thread.io_bitmap_ptr) {
@@@ -357,9 -344,6 +354,9 @@@ out
                kfree(p->thread.io_bitmap_ptr);
                p->thread.io_bitmap_max = 0;
        }
 +      if (err)
 +              flush_thread_hw_breakpoint(p);
 +
        return err;
  }
  
@@@ -442,7 -426,7 +439,7 @@@ __switch_to(struct task_struct *prev_p
         * done before math_state_restore, so the TS bit is up
         * to date.
         */
-       arch_leave_lazy_cpu_mode();
+       arch_end_context_switch(next_p);
  
        /*
         * Switch FS and GS.
         */
        if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
                math_state_restore();
 +      /*
 +       * There's a problem with moving the arch_install_thread_hw_breakpoint()
 +       * call before current is updated.  Suppose a kernel breakpoint is
 +       * triggered in between the two, the hw-breakpoint handler will see that
 +       * the 'current' task does not have TIF_DEBUG flag set and will think it
 +       * is leftover from an old task (lazy switching) and will erase it. Then
 +       * until the next context switch, no user-breakpoints will be installed.
 +       *
 +       * The real problem is that it's impossible to update both current and
 +       * physical debug registers at the same instant, so there will always be
 +       * a window in which they disagree and a breakpoint might get triggered.
 +       * Since we use lazy switching, we are forced to assume that a
 +       * disagreement means that current is correct and the exception is due
 +       * to lazy debug register switching.
 +       */
 +      if (unlikely(test_tsk_thread_flag(next_p, TIF_DEBUG)))
 +              arch_install_thread_hw_breakpoint(next_p);
 +
        return prev_p;
  }
  
@@@ -692,15 -658,3 +689,3 @@@ long sys_arch_prctl(int code, unsigned 
        return do_arch_prctl(current, code, addr);
  }
  
- unsigned long arch_align_stack(unsigned long sp)
- {
-       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
-               sp -= get_random_int() % 8192;
-       return sp & ~0xf;
- }
- unsigned long arch_randomize_brk(struct mm_struct *mm)
- {
-       unsigned long range_end = mm->brk + 0x02000000;
-       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
- }
diff --combined arch/x86/kernel/signal.c
@@@ -6,7 -6,6 +6,6 @@@
   *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
   *  2000-2002   x86-64 support by Andi Kleen
   */
  #include <linux/sched.h>
  #include <linux/mm.h>
  #include <linux/smp.h>
  #include <asm/ucontext.h>
  #include <asm/i387.h>
  #include <asm/vdso.h>
+ #include <asm/mce.h>
  
  #ifdef CONFIG_X86_64
  #include <asm/proto.h>
  #include <asm/ia32_unistd.h>
- #include <asm/mce.h>
  #endif /* CONFIG_X86_64 */
  
  #include <asm/syscall.h>
@@@ -800,6 -799,15 +799,6 @@@ static void do_signal(struct pt_regs *r
  
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
 -              /*
 -               * Re-enable any watchpoints before delivering the
 -               * signal to user space. The processor register will
 -               * have been cleared if the watchpoint triggered
 -               * inside the kernel.
 -               */
 -              if (current->thread.debugreg7)
 -                      set_debugreg(current->thread.debugreg7, 7);
 -
                /* Whee! Actually deliver the signal.  */
                if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
                        /*
  void
  do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
  {
- #if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
+ #ifdef CONFIG_X86_NEW_MCE
        /* notify userspace of pending MCEs */
        if (thread_info_flags & _TIF_MCE_NOTIFY)
-               mce_notify_user();
+               mce_notify_process();
  #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
  
        /* deal with pending signal delivery */
@@@ -63,7 -63,6 +63,7 @@@
  #include <asm/apic.h>
  #include <asm/setup.h>
  #include <asm/uv/uv.h>
 +#include <asm/debugreg.h>
  #include <linux/mc146818rtc.h>
  
  #include <asm/smpboot_hooks.h>
@@@ -327,7 -326,6 +327,7 @@@ notrace static void __cpuinit start_sec
        setup_secondary_clock();
  
        wmb();
 +      load_debug_registers();
        cpu_idle();
  }
  
@@@ -506,7 -504,7 +506,7 @@@ void __inquire_remote_apic(int apicid
   * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
   * won't ... remember to clear down the APIC, etc later.
   */
- int __devinit
+ int __cpuinit
  wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
  {
        unsigned long send_status, accept_status = 0;
        return (send_status | accept_status);
  }
  
- int __devinit
+ static int __cpuinit
  wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
  {
        unsigned long send_status, accept_status = 0;
@@@ -824,10 -822,12 +824,12 @@@ do_rest
        /* mark "stuck" area as not stuck */
        *((volatile unsigned long *)trampoline_base) = 0;
  
-       /*
-        * Cleanup possible dangling ends...
-        */
-       smpboot_restore_warm_reset_vector();
+       if (get_uv_system_type() != UV_NON_UNIQUE_APIC) {
+               /*
+                * Cleanup possible dangling ends...
+                */
+               smpboot_restore_warm_reset_vector();
+       }
  
        return boot_error;
  }
@@@ -873,7 -873,7 +875,7 @@@ int __cpuinit native_cpu_up(unsigned in
  
        err = do_boot_cpu(apicid, cpu);
  
-       zap_low_mappings();
+       zap_low_mappings(false);
        low_mappings = 0;
  #else
        err = do_boot_cpu(apicid, cpu);
@@@ -992,10 -992,12 +994,12 @@@ static int __init smp_sanity_check(unsi
         */
        if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) &&
            !cpu_has_apic) {
-               printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
-                       boot_cpu_physical_apicid);
-               printk(KERN_ERR "... forcing use of dummy APIC emulation."
+               if (!disable_apic) {
+                       pr_err("BIOS bug, local APIC #%d not detected!...\n",
+                               boot_cpu_physical_apicid);
+                       pr_err("... forcing use of dummy APIC emulation."
                                "(tell your hw vendor)\n");
+               }
                smpboot_clear_io_apic();
                arch_disable_smp_support();
                return -1;
@@@ -1252,7 -1254,6 +1256,7 @@@ void cpu_disable_common(void
        remove_cpu_from_maps(cpu);
        unlock_vector_lock();
        fixup_irqs();
 +      hw_breakpoint_disable();
  }
  
  int native_cpu_disable(void)
diff --combined arch/x86/kernel/traps.c
@@@ -45,6 -45,7 +45,7 @@@
  #include <linux/edac.h>
  #endif
  
+ #include <asm/kmemcheck.h>
  #include <asm/stacktrace.h>
  #include <asm/processor.h>
  #include <asm/debugreg.h>
@@@ -529,52 -530,77 +530,56 @@@ asmlinkage __kprobes struct pt_regs *sy
  dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
  {
        struct task_struct *tsk = current;
 -      unsigned long condition;
 +      unsigned long dr6;
        int si_code;
  
 -      get_debugreg(condition, 6);
 +      get_debugreg(dr6, 6);
  
+       /* Catch kmemcheck conditions first of all! */
 -      if (condition & DR_STEP && kmemcheck_trap(regs))
++      if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
+               return;
 +      /* DR6 may or may not be cleared by the CPU */
 +      set_debugreg(0, 6);
        /*
         * The processor cleared BTF, so don't mark that we need it set.
         */
        clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
        tsk->thread.debugctlmsr = 0;
  
 -      if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
 -                                              SIGTRAP) == NOTIFY_STOP)
 +      /* Store the virtualized DR6 value */
 +      tsk->thread.debugreg6 = dr6;
 +
 +      if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
 +                                                      SIGTRAP) == NOTIFY_STOP)
                return;
  
        /* It's safe to allow irq's after DR6 has been saved */
        preempt_conditional_sti(regs);
  
 -      /* Mask out spurious debug traps due to lazy DR7 setting */
 -      if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 -              if (!tsk->thread.debugreg7)
 -                      goto clear_dr7;
 +      if (regs->flags & X86_VM_MASK) {
 +              handle_vm86_trap((struct kernel_vm86_regs *) regs,
 +                              error_code, 1);
 +              return;
        }
  
 -#ifdef CONFIG_X86_32
 -      if (regs->flags & X86_VM_MASK)
 -              goto debug_vm86;
 -#endif
 -
 -      /* Save debug status register where ptrace can see it */
 -      tsk->thread.debugreg6 = condition;
 -
        /*
 -       * Single-stepping through TF: make sure we ignore any events in
 -       * kernel space (but re-enable TF when returning to user mode).
 +       * Single-stepping through system calls: ignore any exceptions in
 +       * kernel space, but re-enable TF when returning to user mode.
 +       *
 +       * We already checked v86 mode above, so we can check for kernel mode
 +       * by just checking the CPL of CS.
         */
 -      if (condition & DR_STEP) {
 -              if (!user_mode(regs))
 -                      goto clear_TF_reenable;
 +      if ((dr6 & DR_STEP) && !user_mode(regs)) {
 +              tsk->thread.debugreg6 &= ~DR_STEP;
 +              set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
 +              regs->flags &= ~X86_EFLAGS_TF;
        }
 -
 -      si_code = get_si_code(condition);
 -      /* Ok, finally something we can handle */
 -      send_sigtrap(tsk, regs, error_code, si_code);
 -
 -      /*
 -       * Disable additional traps. They'll be re-enabled when
 -       * the signal is delivered.
 -       */
 -clear_dr7:
 -      set_debugreg(0, 7);
 +      si_code = get_si_code(tsk->thread.debugreg6);
 +      if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
 +              send_sigtrap(tsk, regs, error_code, si_code);
        preempt_conditional_cli(regs);
 -      return;
  
 -#ifdef CONFIG_X86_32
 -debug_vm86:
 -      /* reenable preemption: handle_vm86_trap() might sleep */
 -      dec_preempt_count();
 -      handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
 -      conditional_cli(regs);
 -      return;
 -#endif
 -
 -clear_TF_reenable:
 -      set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
 -      regs->flags &= ~X86_EFLAGS_TF;
 -      preempt_conditional_cli(regs);
        return;
  }
  
@@@ -777,15 -803,15 +782,15 @@@ unsigned long patch_espfix_desc(unsigne
  
        return new_kesp;
  }
- #else
+ #endif
  asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
  {
  }
  
- asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
+ asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
  {
  }
- #endif
  
  /*
   * 'math_state_restore()' saves the current math information in the
@@@ -818,9 -844,6 +823,6 @@@ asmlinkage void math_state_restore(void
        }
  
        clts();                         /* Allow maths ops (or we recurse) */
- #ifdef CONFIG_X86_32
-       restore_fpu(tsk);
- #else
        /*
         * Paranoid restore. send a SIGSEGV if we fail to restore the state.
         */
                force_sig(SIGSEGV, tsk);
                return;
        }
- #endif
        thread->status |= TS_USEDFPU;   /* So we fnsave on switch_to() */
        tsk->fpu_counter++;
  }
@@@ -924,8 -947,13 +926,13 @@@ void __init trap_init(void
  #endif
        set_intr_gate(19, &simd_coprocessor_error);
  
+       /* Reserve all the builtin and the syscall vector: */
+       for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
+               set_bit(i, used_vectors);
  #ifdef CONFIG_IA32_EMULATION
        set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
+       set_bit(IA32_SYSCALL_VECTOR, used_vectors);
  #endif
  
  #ifdef CONFIG_X86_32
        }
  
        set_system_trap_gate(SYSCALL_VECTOR, &system_call);
- #endif
-       /* Reserve all the builtin and the syscall vector: */
-       for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
-               set_bit(i, used_vectors);
- #ifdef CONFIG_X86_64
-       set_bit(IA32_SYSCALL_VECTOR, used_vectors);
- #else
        set_bit(SYSCALL_VECTOR, used_vectors);
  #endif
        /*
         * Should be a barrier for any external CPU state:
         */
diff --combined arch/x86/power/cpu.c
index 0000000,d277ef1..394cbb8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,259 +1,241 @@@
+ /*
+  * Suspend support specific for i386/x86-64.
+  *
+  * Distribute under GPLv2
+  *
+  * Copyright (c) 2007 Rafael J. Wysocki <rjw@sisk.pl>
+  * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
+  * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+  */
+ #include <linux/suspend.h>
+ #include <linux/smp.h>
+ #include <asm/pgtable.h>
+ #include <asm/proto.h>
+ #include <asm/mtrr.h>
+ #include <asm/page.h>
+ #include <asm/mce.h>
+ #include <asm/xcr.h>
+ #include <asm/suspend.h>
++#include <asm/debugreg.h>
+ #ifdef CONFIG_X86_32
+ static struct saved_context saved_context;
+ unsigned long saved_context_ebx;
+ unsigned long saved_context_esp, saved_context_ebp;
+ unsigned long saved_context_esi, saved_context_edi;
+ unsigned long saved_context_eflags;
+ #else
+ /* CONFIG_X86_64 */
+ struct saved_context saved_context;
+ #endif
+ /**
+  *    __save_processor_state - save CPU registers before creating a
+  *            hibernation image and before restoring the memory state from it
+  *    @ctxt - structure to store the registers contents in
+  *
+  *    NOTE: If there is a CPU register the modification of which by the
+  *    boot kernel (ie. the kernel used for loading the hibernation image)
+  *    might affect the operations of the restored target kernel (ie. the one
+  *    saved in the hibernation image), then its contents must be saved by this
+  *    function.  In other words, if kernel A is hibernated and different
+  *    kernel B is used for loading the hibernation image into memory, the
+  *    kernel A's __save_processor_state() function must save all registers
+  *    needed by kernel A, so that it can operate correctly after the resume
+  *    regardless of what kernel B does in the meantime.
+  */
+ static void __save_processor_state(struct saved_context *ctxt)
+ {
+ #ifdef CONFIG_X86_32
+       mtrr_save_fixed_ranges(NULL);
+ #endif
+       kernel_fpu_begin();
+       /*
+        * descriptor tables
+        */
+ #ifdef CONFIG_X86_32
+       store_gdt(&ctxt->gdt);
+       store_idt(&ctxt->idt);
+ #else
+ /* CONFIG_X86_64 */
+       store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
+       store_idt((struct desc_ptr *)&ctxt->idt_limit);
+ #endif
+       store_tr(ctxt->tr);
+       /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
+       /*
+        * segment registers
+        */
+ #ifdef CONFIG_X86_32
+       savesegment(es, ctxt->es);
+       savesegment(fs, ctxt->fs);
+       savesegment(gs, ctxt->gs);
+       savesegment(ss, ctxt->ss);
+ #else
+ /* CONFIG_X86_64 */
+       asm volatile ("movw %%ds, %0" : "=m" (ctxt->ds));
+       asm volatile ("movw %%es, %0" : "=m" (ctxt->es));
+       asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs));
+       asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs));
+       asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss));
+       rdmsrl(MSR_FS_BASE, ctxt->fs_base);
+       rdmsrl(MSR_GS_BASE, ctxt->gs_base);
+       rdmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base);
+       mtrr_save_fixed_ranges(NULL);
+       rdmsrl(MSR_EFER, ctxt->efer);
+ #endif
+       /*
+        * control registers
+        */
+       ctxt->cr0 = read_cr0();
+       ctxt->cr2 = read_cr2();
+       ctxt->cr3 = read_cr3();
+ #ifdef CONFIG_X86_32
+       ctxt->cr4 = read_cr4_safe();
+ #else
+ /* CONFIG_X86_64 */
+       ctxt->cr4 = read_cr4();
+       ctxt->cr8 = read_cr8();
+ #endif
++      hw_breakpoint_disable();
+ }
+ /* Needed by apm.c */
+ void save_processor_state(void)
+ {
+       __save_processor_state(&saved_context);
+ }
+ #ifdef CONFIG_X86_32
+ EXPORT_SYMBOL(save_processor_state);
+ #endif
+ static void do_fpu_end(void)
+ {
+       /*
+        * Restore FPU regs if necessary.
+        */
+       kernel_fpu_end();
+ }
+ static void fix_processor_context(void)
+ {
+       int cpu = smp_processor_id();
+       struct tss_struct *t = &per_cpu(init_tss, cpu);
+       set_tss_desc(cpu, t);   /*
+                                * This just modifies memory; should not be
+                                * necessary. But... This is necessary, because
+                                * 386 hardware has concept of busy TSS or some
+                                * similar stupidity.
+                                */
+ #ifdef CONFIG_X86_64
+       get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
+       syscall_init();                         /* This sets MSR_*STAR and related */
+ #endif
+       load_TR_desc();                         /* This does ltr */
+       load_LDT(&current->active_mm->context); /* This does lldt */
+       /*
+        * Now maybe reload the debug registers
+        */
 -      if (current->thread.debugreg7) {
 -#ifdef CONFIG_X86_32
 -              set_debugreg(current->thread.debugreg0, 0);
 -              set_debugreg(current->thread.debugreg1, 1);
 -              set_debugreg(current->thread.debugreg2, 2);
 -              set_debugreg(current->thread.debugreg3, 3);
 -              /* no 4 and 5 */
 -              set_debugreg(current->thread.debugreg6, 6);
 -              set_debugreg(current->thread.debugreg7, 7);
 -#else
 -              /* CONFIG_X86_64 */
 -              loaddebug(&current->thread, 0);
 -              loaddebug(&current->thread, 1);
 -              loaddebug(&current->thread, 2);
 -              loaddebug(&current->thread, 3);
 -              /* no 4 and 5 */
 -              loaddebug(&current->thread, 6);
 -              loaddebug(&current->thread, 7);
 -#endif
 -      }
 -
++      load_debug_registers();
+ }
+ /**
+  *    __restore_processor_state - restore the contents of CPU registers saved
+  *            by __save_processor_state()
+  *    @ctxt - structure to load the registers contents from
+  */
+ static void __restore_processor_state(struct saved_context *ctxt)
+ {
+       /*
+        * control registers
+        */
+       /* cr4 was introduced in the Pentium CPU */
+ #ifdef CONFIG_X86_32
+       if (ctxt->cr4)
+               write_cr4(ctxt->cr4);
+ #else
+ /* CONFIG X86_64 */
+       wrmsrl(MSR_EFER, ctxt->efer);
+       write_cr8(ctxt->cr8);
+       write_cr4(ctxt->cr4);
+ #endif
+       write_cr3(ctxt->cr3);
+       write_cr2(ctxt->cr2);
+       write_cr0(ctxt->cr0);
+       /*
+        * now restore the descriptor tables to their proper values
+        * ltr is done i fix_processor_context().
+        */
+ #ifdef CONFIG_X86_32
+       load_gdt(&ctxt->gdt);
+       load_idt(&ctxt->idt);
+ #else
+ /* CONFIG_X86_64 */
+       load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
+       load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+ #endif
+       /*
+        * segment registers
+        */
+ #ifdef CONFIG_X86_32
+       loadsegment(es, ctxt->es);
+       loadsegment(fs, ctxt->fs);
+       loadsegment(gs, ctxt->gs);
+       loadsegment(ss, ctxt->ss);
+       /*
+        * sysenter MSRs
+        */
+       if (boot_cpu_has(X86_FEATURE_SEP))
+               enable_sep_cpu();
+ #else
+ /* CONFIG_X86_64 */
+       asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds));
+       asm volatile ("movw %0, %%es" :: "r" (ctxt->es));
+       asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs));
+       load_gs_index(ctxt->gs);
+       asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss));
+       wrmsrl(MSR_FS_BASE, ctxt->fs_base);
+       wrmsrl(MSR_GS_BASE, ctxt->gs_base);
+       wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base);
+ #endif
+       /*
+        * restore XCR0 for xsave capable cpu's.
+        */
+       if (cpu_has_xsave)
+               xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask);
+       fix_processor_context();
+       do_fpu_end();
+       mtrr_ap_init();
+ #ifdef CONFIG_X86_32
+       mcheck_init(&boot_cpu_data);
+ #endif
+ }
+ /* Needed by apm.c */
+ void restore_processor_state(void)
+ {
+       __restore_processor_state(&saved_context);
+ }
+ #ifdef CONFIG_X86_32
+ EXPORT_SYMBOL(restore_processor_state);
+ #endif
diff --combined kernel/Makefile
@@@ -11,6 -11,7 +11,7 @@@ obj-y     = sched.o fork.o exec_domain.
            hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
            notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
            async.o
+ obj-y += groups.o
  
  ifdef CONFIG_FUNCTION_TRACER
  # Do not trace debug files and internal ftrace files
@@@ -96,7 -97,7 +97,8 @@@ obj-$(CONFIG_TRACING) += trace
  obj-$(CONFIG_X86_DS) += trace/
  obj-$(CONFIG_SMP) += sched_cpupri.o
  obj-$(CONFIG_SLOW_WORK) += slow-work.o
 +obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
+ obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o
  
  ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
  # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --combined kernel/trace/Kconfig
@@@ -56,6 -56,13 +56,13 @@@ config CONTEXT_SWITCH_TRACE
        select MARKERS
        bool
  
+ # All tracer options should select GENERIC_TRACER. For those options that are
+ # enabled by all tracers (context switch and event tracer) they select TRACING.
+ # This allows those options to appear when no other tracer is selected. But the
+ # options do not appear when something else selects it. We need the two options
+ # GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the
+ # hidding of the automatic options options.
  config TRACING
        bool
        select DEBUG_FS
        select BINARY_PRINTF
        select EVENT_TRACING
  
+ config GENERIC_TRACER
+       bool
+       select TRACING
  #
  # Minimum requirements an architecture has to meet for us to
  # be able to offer generic tracing facilities:
@@@ -95,7 -106,7 +106,7 @@@ config FUNCTION_TRACE
        depends on HAVE_FUNCTION_TRACER
        select FRAME_POINTER
        select KALLSYMS
-       select TRACING
+       select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
        help
          Enable the kernel to trace every kernel function. This is done
@@@ -126,7 -137,7 +137,7 @@@ config IRQSOFF_TRACE
        depends on TRACE_IRQFLAGS_SUPPORT
        depends on GENERIC_TIME
        select TRACE_IRQFLAGS
-       select TRACING
+       select GENERIC_TRACER
        select TRACER_MAX_TRACE
        help
          This option measures the time spent in irqs-off critical
          disabled by default and can be runtime (re-)started
          via:
  
-             echo 0 > /debugfs/tracing/tracing_max_latency
+             echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
  
          (Note that kernel size and overhead increases with this option
          enabled. This option and the preempt-off timing option can be
@@@ -147,7 -158,7 +158,7 @@@ config PREEMPT_TRACE
        default n
        depends on GENERIC_TIME
        depends on PREEMPT
-       select TRACING
+       select GENERIC_TRACER
        select TRACER_MAX_TRACE
        help
          This option measures the time spent in preemption off critical
          disabled by default and can be runtime (re-)started
          via:
  
-             echo 0 > /debugfs/tracing/tracing_max_latency
+             echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
  
          (Note that kernel size and overhead increases with this option
          enabled. This option and the irqs-off timing option can be
  config SYSPROF_TRACER
        bool "Sysprof Tracer"
        depends on X86
-       select TRACING
+       select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
        help
          This tracer provides the trace needed by the 'Sysprof' userspace
  
  config SCHED_TRACER
        bool "Scheduling Latency Tracer"
-       select TRACING
+       select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
        select TRACER_MAX_TRACE
        help
          This tracer tracks the latency of the highest priority task
          to be scheduled in, starting from the point it has woken up.
  
- config ENABLE_CONTEXT_SWITCH_TRACER
-       bool "Trace process context switches"
-       select TRACING
-       select CONTEXT_SWITCH_TRACER
-       help
-         This tracer gets called from the context switch and records
-         all switching of tasks.
- config ENABLE_EVENT_TRACING
-       bool "Trace various events in the kernel"
+ config ENABLE_DEFAULT_TRACERS
+       bool "Trace process context switches and events"
+       depends on !GENERIC_TRACER
        select TRACING
        help
          This tracer hooks to various trace points in the kernel
          allowing the user to pick and choose which trace point they
-         want to trace.
-         Note, all tracers enable event tracing. This option is
-         only a convenience to enable event tracing when no other
-         tracers are selected.
+         want to trace. It also includes the sched_switch tracer plugin.
  
  config FTRACE_SYSCALLS
        bool "Trace syscalls"
        depends on HAVE_FTRACE_SYSCALLS
-       select TRACING
+       select GENERIC_TRACER
        select KALLSYMS
        help
          Basic tracer to catch the syscall entry and exit events.
  
  config BOOT_TRACER
        bool "Trace boot initcalls"
-       select TRACING
+       select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
        help
          This tracer helps developers to optimize boot times: it records
  
  config TRACE_BRANCH_PROFILING
        bool
-       select TRACING
+       select GENERIC_TRACER
  
  choice
        prompt "Branch Profiling"
@@@ -261,7 -261,7 +261,7 @@@ config PROFILE_ANNOTATED_BRANCHE
          This tracer profiles all the the likely and unlikely macros
          in the kernel. It will display the results in:
  
-         /debugfs/tracing/profile_annotated_branch
+         /sys/kernel/debug/tracing/profile_annotated_branch
  
          Note: this will add a significant overhead, only turn this
          on if you need to profile the system's use of these macros.
@@@ -274,7 -274,7 +274,7 @@@ config PROFILE_ALL_BRANCHE
          taken in the kernel is recorded whether it hit or miss.
          The results will be displayed in:
  
-         /debugfs/tracing/profile_branch
+         /sys/kernel/debug/tracing/profile_branch
  
          This option also enables the likely/unlikely profiler.
  
@@@ -308,33 -308,12 +308,33 @@@ config BRANCH_TRACE
  config POWER_TRACER
        bool "Trace power consumption behavior"
        depends on X86
-       select TRACING
+       select GENERIC_TRACER
        help
          This tracer helps developers to analyze and optimize the kernels
          power management decisions, specifically the C-state and P-state
          behavior.
  
 +config KSYM_TRACER
 +      bool "Trace read and write access on kernel memory locations"
 +      depends on HAVE_HW_BREAKPOINT
 +      select TRACING
 +      help
 +        This tracer helps find read and write operations on any given kernel
 +        symbol i.e. /proc/kallsyms.
 +
 +config PROFILE_KSYM_TRACER
 +      bool "Profile all kernel memory accesses on 'watched' variables"
 +      depends on KSYM_TRACER
 +      help
 +        This tracer profiles kernel accesses on variables watched through the
 +        ksym tracer ftrace plugin. Depending upon the hardware, all read
 +        and write operations on kernel variables can be monitored for
 +        accesses.
 +
 +        The results will be displayed in:
 +        /debugfs/tracing/profile_ksym
 +
 +        Say N if unsure.
  
  config STACK_TRACER
        bool "Trace max stack"
        select KALLSYMS
        help
          This special tracer records the maximum stack footprint of the
-         kernel and displays it in debugfs/tracing/stack_trace.
+         kernel and displays it in /sys/kernel/debug/tracing/stack_trace.
  
          This tracer works by hooking into every function call that the
          kernel executes, and keeping a maximum stack depth value and
  config HW_BRANCH_TRACER
        depends on HAVE_HW_BRANCH_TRACER
        bool "Trace hw branches"
-       select TRACING
+       select GENERIC_TRACER
        help
          This tracer records all branches on the system in a circular
          buffer giving access to the last N branches for each cpu.
  
  config KMEMTRACE
        bool "Trace SLAB allocations"
-       select TRACING
+       select GENERIC_TRACER
        help
          kmemtrace provides tracing for slab allocator functions, such as
          kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected
  
  config WORKQUEUE_TRACER
        bool "Trace workqueues"
-       select TRACING
+       select GENERIC_TRACER
        help
          The workqueue tracer provides some statistical informations
            about each cpu workqueue thread such as the number of the
@@@ -406,7 -385,7 +406,7 @@@ config BLK_DEV_IO_TRAC
        select RELAY
        select DEBUG_FS
        select TRACEPOINTS
-       select TRACING
+       select GENERIC_TRACER
        select STACKTRACE
        help
          Say Y here if you want to be able to trace the block layer actions
@@@ -467,7 -446,7 +467,7 @@@ config FTRACE_SELFTES
  
  config FTRACE_STARTUP_TEST
        bool "Perform a startup test on ftrace"
-       depends on TRACING
+       depends on GENERIC_TRACER
        select FTRACE_SELFTEST
        help
          This option performs a series of startup tests on ftrace. On bootup
  config MMIOTRACE
        bool "Memory mapped IO tracing"
        depends on HAVE_MMIOTRACE_SUPPORT && PCI
-       select TRACING
+       select GENERIC_TRACER
        help
          Mmiotrace traces Memory Mapped I/O access and is meant for
          debugging and reverse engineering. It is called from the ioremap
diff --combined kernel/trace/Makefile
@@@ -45,12 -45,14 +45,15 @@@ obj-$(CONFIG_HW_BRANCH_TRACER) += trace
  obj-$(CONFIG_POWER_TRACER) += trace_power.o
  obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
  obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
- obj-$(CONFIG_BLK_DEV_IO_TRACE)        += blktrace.o
+ obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
+ ifeq ($(CONFIG_BLOCK),y)
+ obj-$(CONFIG_EVENT_TRACING) += blktrace.o
+ endif
  obj-$(CONFIG_EVENT_TRACING) += trace_events.o
  obj-$(CONFIG_EVENT_TRACING) += trace_export.o
  obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
  obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
  obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
 +obj-$(CONFIG_KSYM_TRACER) += trace_ksym.o
  
  libftrace-y := ftrace.o
diff --combined samples/Kconfig
@@@ -26,7 -26,8 +26,8 @@@ config SAMPLE_TRACE_EVENT
          This build trace event example modules.
  
  config SAMPLE_KOBJECT
-       tristate "Build kobject examples"
+       tristate "Build kobject examples -- loadable modules only"
+       depends on m
        help
          This config option will allow you to build a number of
          different kobject sample modules showing how to use kobjects,
@@@ -45,11 -46,5 +46,11 @@@ config SAMPLE_KRETPROBE
        default m
        depends on SAMPLE_KPROBES && KRETPROBES
  
 +config SAMPLE_HW_BREAKPOINT
 +      tristate "Build kernel hardware breakpoint examples -- loadable module only"
 +      depends on HAVE_HW_BREAKPOINT && m
 +      help
 +        This builds kernel hardware breakpoint example modules.
 +
  endif # SAMPLES