Merge branch 'linus' into stackprotector
authorIngo Molnar <mingo@elte.hu>
Wed, 31 Dec 2008 07:31:57 +0000 (08:31 +0100)
committerIngo Molnar <mingo@elte.hu>
Wed, 31 Dec 2008 07:31:57 +0000 (08:31 +0100)
Conflicts:
arch/x86/include/asm/pda.h
kernel/fork.c

14 files changed:
1  2 
arch/x86/Kconfig
arch/x86/Kconfig.debug
arch/x86/Makefile
arch/x86/include/asm/pda.h
arch/x86/include/asm/system.h
arch/x86/kernel/Makefile
arch/x86/kernel/process_64.c
arch/x86/mm/fault.c
include/linux/sched.h
init/main.c
kernel/exit.c
kernel/fork.c
kernel/panic.c
kernel/sched.c

diff --combined arch/x86/Kconfig
@@@ -19,6 -19,8 +19,8 @@@ config X86_6
  config X86
        def_bool y
        select HAVE_AOUT if X86_32
+       select HAVE_READQ
+       select HAVE_WRITEQ
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_KPROBES
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_KRETPROBES
+       select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
-       select HAVE_FTRACE
+       select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
        select HAVE_ARCH_KGDB if !X86_VOYAGER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_GENERIC_DMA_COHERENT if X86_32
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
+       select USER_STACKTRACE_SUPPORT
  
  config ARCH_DEFCONFIG
        string
        default "arch/x86/configs/i386_defconfig" if X86_32
        default "arch/x86/configs/x86_64_defconfig" if X86_64
  
- config GENERIC_LOCKBREAK
-       def_bool n
  config GENERIC_TIME
        def_bool y
  
@@@ -90,12 -92,16 +92,16 @@@ config GENERIC_IOMA
  config GENERIC_BUG
        def_bool y
        depends on BUG
+       select GENERIC_BUG_RELATIVE_POINTERS if X86_64
+ config GENERIC_BUG_RELATIVE_POINTERS
+       bool
  
  config GENERIC_HWEIGHT
        def_bool y
  
  config GENERIC_GPIO
-       def_bool n
+       bool
  
  config ARCH_MAY_HAVE_PC_FDC
        def_bool y
@@@ -106,12 -112,6 +112,6 @@@ config RWSEM_GENERIC_SPINLOC
  config RWSEM_XCHGADD_ALGORITHM
        def_bool X86_XADD
  
- config ARCH_HAS_ILOG2_U32
-       def_bool n
- config ARCH_HAS_ILOG2_U64
-       def_bool n
  config ARCH_HAS_CPU_IDLE_WAIT
        def_bool y
  
@@@ -125,6 -125,9 +125,9 @@@ config GENERIC_TIME_VSYSCAL
  config ARCH_HAS_CPU_RELAX
        def_bool y
  
+ config ARCH_HAS_DEFAULT_IDLE
+       def_bool y
  config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
  
@@@ -173,9 -176,12 +176,12 @@@ config GENERIC_PENDING_IR
  config X86_SMP
        bool
        depends on SMP && ((X86_32 && !X86_VOYAGER) || X86_64)
-       select USE_GENERIC_SMP_HELPERS
        default y
  
+ config USE_GENERIC_SMP_HELPERS
+       def_bool y
+       depends on SMP
  config X86_32_SMP
        def_bool y
        depends on X86_32 && SMP
@@@ -203,6 -209,7 +209,7 @@@ config X86_TRAMPOLIN
  config KTIME_SCALAR
        def_bool X86_32
  source "init/Kconfig"
+ source "kernel/Kconfig.freezer"
  
  menu "Processor type and features"
  
@@@ -236,25 -243,43 +243,43 @@@ config SM
  
          If you don't know what to do here, say N.
  
+ config X86_HAS_BOOT_CPU_ID
+       def_bool y
+       depends on X86_VOYAGER
+ config SPARSE_IRQ
+       bool "Support sparse irq numbering"
+       depends on PCI_MSI || HT_IRQ
+       help
+         This enables support for sparse irqs. This is useful for distro
+         kernels that want to define a high CONFIG_NR_CPUS value but still
+         want to have low kernel memory footprint on smaller machines.
+         ( Sparse IRQs can also be beneficial on NUMA boxes, as they spread
+           out the irq_desc[] array in a more NUMA-friendly way. )
+         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"
+       depends on SPARSE_IRQ && NUMA
+       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_FIND_SMP_CONFIG
        def_bool y
        depends on X86_MPPARSE || X86_VOYAGER
  
- if ACPI
  config X86_MPPARSE
-       def_bool y
-       bool "Enable MPS table"
+       bool "Enable MPS table" if ACPI
+       default y
        depends on X86_LOCAL_APIC
        help
          For old smp systems that do not have proper acpi support. Newer systems
          (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
- endif
- if !ACPI
- config X86_MPPARSE
-       def_bool y
-       depends on X86_LOCAL_APIC
- endif
  
  choice
        prompt "Subarchitecture Type"
@@@ -365,10 -390,10 +390,10 @@@ config X86_RDC321
          as R-8610-(G).
          If you don't have one of these chips, you should say N here.
  
- config SCHED_NO_NO_OMIT_FRAME_POINTER
+ config SCHED_OMIT_FRAME_POINTER
        def_bool y
        prompt "Single-depth WCHAN output"
-       depends on X86_32
+       depends on X86
        help
          Calculate simpler /proc/<PID>/wchan values. If this option
          is disabled then wchan values will recurse back to the
@@@ -463,10 -488,6 +488,6 @@@ config X86_CYCLONE_TIME
        def_bool y
        depends on X86_GENERICARCH
  
- config ES7000_CLUSTERED_APIC
-       def_bool y
-       depends on SMP && X86_ES7000 && MPENTIUMIII
  source "arch/x86/Kconfig.cpu"
  
  config HPET_TIMER
           The HPET provides a stable time base on SMP
           systems, unlike the TSC, but it is more expensive to access,
           as it is off-chip.  You can find the HPET spec at
-          <http://www.intel.com/hardwaredesign/hpetspec.htm>.
+          <http://www.intel.com/hardwaredesign/hpetspec_1.pdf>.
  
           You can safely choose Y here.  However, HPET will only be
           activated if the platform and the BIOS support this feature.
@@@ -567,7 -588,7 +588,7 @@@ config AMD_IOMM
  
  # need this always selected by IOMMU for the VIA workaround
  config SWIOTLB
-       bool
+       def_bool y if X86_64
        help
          Support for software bounce buffers used on x86-64 systems
          which don't have a hardware IOMMU (e.g. the current generation
@@@ -658,6 -679,30 +679,30 @@@ config X86_VISWS_API
        def_bool y
        depends on X86_32 && X86_VISWS
  
+ config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
+       bool "Reroute for broken boot IRQs"
+       default n
+       depends on X86_IO_APIC
+       help
+         This option enables a workaround that fixes a source of
+         spurious interrupts. This is recommended when threaded
+         interrupt handling is used on systems where the generation of
+         superfluous "boot interrupts" cannot be disabled.
+         Some chipsets generate a legacy INTx "boot IRQ" when the IRQ
+         entry in the chipset's IO-APIC is masked (as, e.g. the RT
+         kernel does during interrupt handling). On chipsets where this
+         boot IRQ generation cannot be disabled, this workaround keeps
+         the original IRQ line masked so that only the equivalent "boot
+         IRQ" is delivered to the CPUs. The workaround also tells the
+         kernel to set up the IRQ handler on the boot IRQ line. In this
+         way only one interrupt is delivered to the kernel. Otherwise
+         the spurious second interrupt may cause the kernel to bring
+         down (vital) interrupt lines.
+         Only affects "broken" chipsets. Interrupt sharing may be
+         increased on these systems.
  config X86_MCE
        bool "Machine Check Exception"
        depends on !X86_VOYAGER
@@@ -758,9 -803,8 +803,8 @@@ config I8
          Say N otherwise.
  
  config X86_REBOOTFIXUPS
-       def_bool n
-       prompt "Enable X86 board specific fixups for reboot"
-       depends on X86_32 && X86
+       bool "Enable X86 board specific fixups for reboot"
+       depends on X86_32
        ---help---
          This enables chipset and/or board specific fixups to be done
          in order to get reboot to work correctly. This is only needed on
@@@ -944,34 -988,48 +988,48 @@@ config HIGHME
        depends on X86_32 && (HIGHMEM64G || HIGHMEM4G)
  
  config X86_PAE
-       def_bool n
-       prompt "PAE (Physical Address Extension) Support"
+       bool "PAE (Physical Address Extension) Support"
        depends on X86_32 && !HIGHMEM4G
-       select RESOURCES_64BIT
        help
          PAE is required for NX support, and furthermore enables
          larger swapspace support for non-overcommit purposes. It
          has the cost of more pagetable lookup overhead, and also
          consumes more pagetable space per process.
  
+ config ARCH_PHYS_ADDR_T_64BIT
+        def_bool X86_64 || X86_PAE
+ config DIRECT_GBPAGES
+       bool "Enable 1GB pages for kernel pagetables" if EMBEDDED
+       default y
+       depends on X86_64
+       help
+         Allow the kernel linear mapping to use 1GB pages on CPUs that
+         support it. This can improve the kernel's performance a tiny bit by
+         reducing TLB pressure. If in doubt, say "Y".
  # Common NUMA Features
  config NUMA
-       bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)"
+       bool "Numa Memory Allocation and Scheduler Support"
        depends on SMP
        depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && EXPERIMENTAL)
        default n if X86_PC
        default y if (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP)
        help
          Enable NUMA (Non Uniform Memory Access) support.
          The kernel will try to allocate memory used by a CPU on the
          local memory controller of the CPU and add some more
          NUMA awareness to the kernel.
  
-         For 32-bit this is currently highly experimental and should be only
-         used for kernel development. It might also cause boot failures.
-         For 64-bit this is recommended on all multiprocessor Opteron systems.
-         If the system is EM64T, you should say N unless your system is
-         EM64T NUMA.
+         For 64-bit this is recommended if the system is Intel Core i7
+         (or later), AMD Opteron, or EM64T NUMA.
+         For 32-bit this is only needed on (rare) 32-bit-only platforms
+         that support NUMA topologies, such as NUMAQ / Summit, or if you
+         boot a 32-bit kernel on a 64-bit NUMA platform.
+         Otherwise, you should say N.
  
  comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
        depends on X86_32 && X86_SUMMIT && (!HIGHMEM64G || !ACPI)
@@@ -1238,8 -1296,7 +1296,7 @@@ config X86_PA
          If unsure, say Y.
  
  config EFI
-       def_bool n
-       prompt "EFI runtime service support"
+       bool "EFI runtime service support"
        depends on ACPI
        ---help---
        This enables the kernel to use EFI runtime services that are
        resultant kernel should continue to boot on existing non-EFI
        platforms.
  
- config IRQBALANCE
-       def_bool y
-       prompt "Enable kernel irq balancing"
-       depends on X86_32 && SMP && X86_IO_APIC
-       help
-         The default yes will allow the kernel to do irq load balancing.
-         Saying no will keep the kernel from doing irq load balancing.
  config SECCOMP
        def_bool y
        prompt "Enable seccomp to safely compute untrusted bytecode"
  
          If unsure, say Y. Only embedded should say N here.
  
 +config CC_STACKPROTECTOR_ALL
 +      bool
 +
  config CC_STACKPROTECTOR
        bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
 -      depends on X86_64 && EXPERIMENTAL && BROKEN
 +      depends on X86_64
 +      select CC_STACKPROTECTOR_ALL
        help
 -         This option turns on the -fstack-protector GCC feature. This
 -        feature puts, at the beginning of critical functions, a canary
 -        value on the stack just before the return address, and validates
 +          This option turns on the -fstack-protector GCC feature. This
 +        feature puts, at the beginning of functions, a canary value on
 +        the stack just before the return address, and validates
          the value just before actually returning.  Stack based buffer
          overflows (that need to overwrite this return address) now also
          overwrite the canary, which gets detected and the attack is then
  
          This feature requires gcc version 4.2 or above, or a distribution
          gcc with the feature backported. Older versions are automatically
 -        detected and for those versions, this configuration option is ignored.
 -
 -config CC_STACKPROTECTOR_ALL
 -      bool "Use stack-protector for all functions"
 -      depends on CC_STACKPROTECTOR
 -      help
 -        Normally, GCC only inserts the canary value protection for
 -        functions that use large-ish on-stack buffers. By enabling
 -        this option, GCC will be asked to do this for ALL functions.
 +        detected and for those versions, this configuration option is
 +        ignored. (and a warning is printed during bootup)
  
  source kernel/Kconfig.hz
  
@@@ -1497,11 -1549,15 +1546,15 @@@ config ARCH_ENABLE_MEMORY_HOTPLU
        def_bool y
        depends on X86_64 || (X86_32 && HIGHMEM)
  
+ config ARCH_ENABLE_MEMORY_HOTREMOVE
+       def_bool y
+       depends on MEMORY_HOTPLUG
  config HAVE_ARCH_EARLY_PFN_TO_NID
        def_bool X86_64
        depends on NUMA
  
- menu "Power management options"
+ menu "Power management and ACPI options"
        depends on !X86_VOYAGER
  
  config ARCH_HIBERNATION_HEADER
@@@ -1636,19 -1692,14 +1689,14 @@@ config APM_ALLOW_INT
          many of the newer IBM Thinkpads.  If you experience hangs when you
          suspend, try setting this to Y.  Otherwise, say N.
  
- config APM_REAL_MODE_POWER_OFF
-       bool "Use real mode APM BIOS call to power off"
-       help
-         Use real mode APM BIOS calls to switch off the computer. This is
-         a work-around for a number of buggy BIOSes. Switch this option on if
-         your computer crashes instead of powering off properly.
  endif # APM
  
  source "arch/x86/kernel/cpu/cpufreq/Kconfig"
  
  source "drivers/cpuidle/Kconfig"
  
+ source "drivers/idle/Kconfig"
  endmenu
  
  
@@@ -1899,6 -1950,10 +1947,10 @@@ config SYSVIPC_COMPA
  endmenu
  
  
+ config HAVE_ATOMIC_IOMAP
+       def_bool y
+       depends on X86_32
  source "net/Kconfig"
  
  source "drivers/Kconfig"
diff --combined arch/x86/Kconfig.debug
@@@ -114,22 -114,9 +114,10 @@@ config DEBUG_RODAT
          data. This is recommended so that we can catch kernel bugs sooner.
          If in doubt, say "Y".
  
  config DEBUG_RODATA_TEST
        bool "Testcase for the DEBUG_RODATA feature"
        depends on DEBUG_RODATA
 +      default y
        help
          This option enables a testcase for the DEBUG_RODATA
          feature as well as for the change_page_attr() infrastructure.
@@@ -187,14 -174,10 +175,10 @@@ config IOMMU_LEA
          Add a simple leak tracer to the IOMMU code. This is useful when you
          are debugging a buggy device driver that leaks IOMMU mappings.
  
- config MMIOTRACE_HOOKS
-       bool
  config MMIOTRACE
        bool "Memory mapped IO tracing"
        depends on DEBUG_KERNEL && PCI
        select TRACING
-       select MMIOTRACE_HOOKS
        help
          Mmiotrace traces Memory Mapped I/O access and is meant for
          debugging and reverse engineering. It is called from the ioremap
@@@ -308,10 -291,10 +292,10 @@@ config OPTIMIZE_INLININ
          developers have marked 'inline'. Doing so takes away freedom from gcc to
          do what it thinks is best, which is desirable for the gcc 3.x series of
          compilers. The gcc 4.x series have a rewritten inlining algorithm and
-         disabling this option will generate a smaller kernel there. Hopefully
-         this algorithm is so good that allowing gcc4 to make the decision can
-         become the default in the future, until then this option is there to
-         test gcc for this.
+         enabling this option will generate a smaller kernel there. Hopefully
+         this algorithm is so good that allowing gcc 4.x and above to make the
+         decision will become the default in the future. Until then this option
+         is there to test gcc for this.
  
          If unsure, say N.
  
diff --combined arch/x86/Makefile
@@@ -73,7 -73,7 +73,7 @@@ els
  
          stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh
          stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \
 -                "$(CC)" -fstack-protector )
 +                "$(CC)" "-fstack-protector -DGCC_HAS_SP" )
          stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \
                  "$(CC)" -fstack-protector-all )
  
@@@ -110,16 -110,16 +110,16 @@@ KBUILD_CFLAGS += $(call cc-option,-mno-
  mcore-y  := arch/x86/mach-default/
  
  # Voyager subarch support
- mflags-$(CONFIG_X86_VOYAGER)  := -Iinclude/asm-x86/mach-voyager
+ mflags-$(CONFIG_X86_VOYAGER)  := -Iarch/x86/include/asm/mach-voyager
  mcore-$(CONFIG_X86_VOYAGER)   := arch/x86/mach-voyager/
  
  # generic subarchitecture
- mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic
+ mflags-$(CONFIG_X86_GENERICARCH):= -Iarch/x86/include/asm/mach-generic
  fcore-$(CONFIG_X86_GENERICARCH)       += arch/x86/mach-generic/
  mcore-$(CONFIG_X86_GENERICARCH)       := arch/x86/mach-default/
  
  # default subarch .h files
- mflags-y += -Iinclude/asm-x86/mach-default
+ mflags-y += -Iarch/x86/include/asm/mach-default
  
  # 64 bit does not support subarch support - clear sub arch variables
  fcore-$(CONFIG_X86_64)  :=
index 0000000,2fbfff8..3fea2fd
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,137 +1,137 @@@
 -#ifdef CONFIG_CC_STACKPROTECTOR
+ #ifndef _ASM_X86_PDA_H
+ #define _ASM_X86_PDA_H
+ #ifndef __ASSEMBLY__
+ #include <linux/stddef.h>
+ #include <linux/types.h>
+ #include <linux/cache.h>
+ #include <asm/page.h>
+ /* Per processor datastructure. %gs points to it while the kernel runs */
+ struct x8664_pda {
+       struct task_struct *pcurrent;   /* 0  Current process */
+       unsigned long data_offset;      /* 8 Per cpu data offset from linker
+                                          address */
+       unsigned long kernelstack;      /* 16 top of kernel stack for current */
+       unsigned long oldrsp;           /* 24 user rsp for system call */
+       int irqcount;                   /* 32 Irq nesting counter. Starts -1 */
+       unsigned int cpunumber;         /* 36 Logical CPU number */
 -#endif
+       unsigned long stack_canary;     /* 40 stack canary value */
+                                       /* gcc-ABI: this canary MUST be at
+                                          offset 40!!! */
+       char *irqstackptr;
+       short nodenumber;               /* number of current node (32k max) */
+       short in_bootmem;               /* pda lives in bootmem */
+       unsigned int __softirq_pending;
+       unsigned int __nmi_count;       /* number of NMI on this CPUs */
+       short mmu_state;
+       short isidle;
+       struct mm_struct *active_mm;
+       unsigned apic_timer_irqs;
+       unsigned irq0_irqs;
+       unsigned irq_resched_count;
+       unsigned irq_call_count;
+       unsigned irq_tlb_count;
+       unsigned irq_thermal_count;
+       unsigned irq_threshold_count;
+       unsigned irq_spurious_count;
+ } ____cacheline_aligned_in_smp;
+ extern struct x8664_pda **_cpu_pda;
+ extern void pda_init(int);
+ #define cpu_pda(i) (_cpu_pda[i])
+ /*
+  * There is no fast way to get the base address of the PDA, all the accesses
+  * have to mention %fs/%gs.  So it needs to be done this Torvaldian way.
+  */
+ extern void __bad_pda_field(void) __attribute__((noreturn));
+ /*
+  * proxy_pda doesn't actually exist, but tell gcc it is accessed for
+  * all PDA accesses so it gets read/write dependencies right.
+  */
+ extern struct x8664_pda _proxy_pda;
+ #define pda_offset(field) offsetof(struct x8664_pda, field)
+ #define pda_to_op(op, field, val)                                     \
+ do {                                                                  \
+       typedef typeof(_proxy_pda.field) T__;                           \
+       if (0) { T__ tmp__; tmp__ = (val); }    /* type checking */     \
+       switch (sizeof(_proxy_pda.field)) {                             \
+       case 2:                                                         \
+               asm(op "w %1,%%gs:%c2" :                                \
+                   "+m" (_proxy_pda.field) :                           \
+                   "ri" ((T__)val),                                    \
+                   "i"(pda_offset(field)));                            \
+               break;                                                  \
+       case 4:                                                         \
+               asm(op "l %1,%%gs:%c2" :                                \
+                   "+m" (_proxy_pda.field) :                           \
+                   "ri" ((T__)val),                                    \
+                   "i" (pda_offset(field)));                           \
+               break;                                                  \
+       case 8:                                                         \
+               asm(op "q %1,%%gs:%c2":                                 \
+                   "+m" (_proxy_pda.field) :                           \
+                   "ri" ((T__)val),                                    \
+                   "i"(pda_offset(field)));                            \
+               break;                                                  \
+       default:                                                        \
+               __bad_pda_field();                                      \
+       }                                                               \
+ } while (0)
+ #define pda_from_op(op, field)                        \
+ ({                                            \
+       typeof(_proxy_pda.field) ret__;         \
+       switch (sizeof(_proxy_pda.field)) {     \
+       case 2:                                 \
+               asm(op "w %%gs:%c1,%0" :        \
+                   "=r" (ret__) :              \
+                   "i" (pda_offset(field)),    \
+                   "m" (_proxy_pda.field));    \
+               break;                          \
+       case 4:                                 \
+               asm(op "l %%gs:%c1,%0":         \
+                   "=r" (ret__):               \
+                   "i" (pda_offset(field)),    \
+                   "m" (_proxy_pda.field));    \
+               break;                          \
+       case 8:                                 \
+               asm(op "q %%gs:%c1,%0":         \
+                   "=r" (ret__) :              \
+                   "i" (pda_offset(field)),    \
+                   "m" (_proxy_pda.field));    \
+               break;                          \
+       default:                                \
+               __bad_pda_field();              \
+       }                                       \
+       ret__;                                  \
+ })
+ #define read_pda(field)               pda_from_op("mov", field)
+ #define write_pda(field, val) pda_to_op("mov", field, val)
+ #define add_pda(field, val)   pda_to_op("add", field, val)
+ #define sub_pda(field, val)   pda_to_op("sub", field, val)
+ #define or_pda(field, val)    pda_to_op("or", field, val)
+ /* This is not atomic against other CPUs -- CPU preemption needs to be off */
+ #define test_and_clear_bit_pda(bit, field)                            \
+ ({                                                                    \
+       int old__;                                                      \
+       asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0"                    \
+                    : "=r" (old__), "+m" (_proxy_pda.field)            \
+                    : "dIr" (bit), "i" (pda_offset(field)) : "memory");\
+       old__;                                                          \
+ })
+ #endif
+ #define PDA_STACKOFFSET (5*8)
++#define refresh_stack_canary() write_pda(stack_canary, current->stack_canary)
++
+ #endif /* _ASM_X86_PDA_H */
index 0000000,8e626ea..2f6340a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,427 +1,431 @@@
 -             [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))  \
+ #ifndef _ASM_X86_SYSTEM_H
+ #define _ASM_X86_SYSTEM_H
+ #include <asm/asm.h>
+ #include <asm/segment.h>
+ #include <asm/cpufeature.h>
+ #include <asm/cmpxchg.h>
+ #include <asm/nops.h>
+ #include <linux/kernel.h>
+ #include <linux/irqflags.h>
+ /* entries in ARCH_DLINFO: */
+ #ifdef CONFIG_IA32_EMULATION
+ # define AT_VECTOR_SIZE_ARCH 2
+ #else
+ # define AT_VECTOR_SIZE_ARCH 1
+ #endif
+ struct task_struct; /* one of the stranger aspects of C forward declarations */
+ struct task_struct *__switch_to(struct task_struct *prev,
+                               struct task_struct *next);
+ #ifdef CONFIG_X86_32
+ /*
+  * Saving eflags is important. It switches not only IOPL between tasks,
+  * it also protects other tasks from NT leaking through sysenter etc.
+  */
+ #define switch_to(prev, next, last)                                   \
+ do {                                                                  \
+       /*                                                              \
+        * Context-switching clobbers all registers, so we clobber      \
+        * them explicitly, via unused output variables.                \
+        * (EAX and EBP is not listed because EBP is saved/restored     \
+        * explicitly for wchan access and EAX is the return value of   \
+        * __switch_to())                                               \
+        */                                                             \
+       unsigned long ebx, ecx, edx, esi, edi;                          \
+                                                                       \
+       asm volatile("pushfl\n\t"               /* save    flags */     \
+                    "pushl %%ebp\n\t"          /* save    EBP   */     \
+                    "movl %%esp,%[prev_sp]\n\t"        /* save    ESP   */ \
+                    "movl %[next_sp],%%esp\n\t"        /* restore ESP   */ \
+                    "movl $1f,%[prev_ip]\n\t"  /* save    EIP   */     \
+                    "pushl %[next_ip]\n\t"     /* restore EIP   */     \
+                    "jmp __switch_to\n"        /* regparm call  */     \
+                    "1:\t"                                             \
+                    "popl %%ebp\n\t"           /* restore EBP   */     \
+                    "popfl\n"                  /* restore flags */     \
+                                                                       \
+                    /* output parameters */                            \
+                    : [prev_sp] "=m" (prev->thread.sp),                \
+                      [prev_ip] "=m" (prev->thread.ip),                \
+                      "=a" (last),                                     \
+                                                                       \
+                      /* clobbered output registers: */                \
+                      "=b" (ebx), "=c" (ecx), "=d" (edx),              \
+                      "=S" (esi), "=D" (edi)                           \
+                                                                       \
+                      /* input parameters: */                          \
+                    : [next_sp]  "m" (next->thread.sp),                \
+                      [next_ip]  "m" (next->thread.ip),                \
+                                                                       \
+                      /* regparm parameters for __switch_to(): */      \
+                      [prev]     "a" (prev),                           \
+                      [next]     "d" (next)                            \
+                                                                       \
+                    : /* reloaded segment registers */                 \
+                       "memory");                                      \
+ } while (0)
+ /*
+  * disable hlt during certain critical i/o operations
+  */
+ #define HAVE_DISABLE_HLT
+ #else
+ #define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
+ #define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
+ /* frame pointer must be last for get_wchan */
+ #define SAVE_CONTEXT    "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"
+ #define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t"
+ #define __EXTRA_CLOBBER  \
+       , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
+         "r12", "r13", "r14", "r15"
+ /* Save restore flags to clear handle leaking NT */
+ #define switch_to(prev, next, last) \
+       asm volatile(SAVE_CONTEXT                                                   \
+            "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */       \
+            "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \
+            "call __switch_to\n\t"                                       \
+            ".globl thread_return\n"                                     \
+            "thread_return:\n\t"                                         \
+            "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"                       \
++           "movq %P[task_canary](%%rsi),%%r8\n\t"                       \
++           "movq %%r8,%%gs:%P[pda_canary]\n\t"                          \
+            "movq %P[thread_info](%%rsi),%%r8\n\t"                       \
+            LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"        \
+            "movq %%rax,%%rdi\n\t"                                       \
+            "jc   ret_from_fork\n\t"                                     \
+            RESTORE_CONTEXT                                              \
+            : "=a" (last)                                                \
+            : [next] "S" (next), [prev] "D" (prev),                      \
+              [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \
+              [ti_flags] "i" (offsetof(struct thread_info, flags)),      \
+              [tif_fork] "i" (TIF_FORK),                                 \
+              [thread_info] "i" (offsetof(struct task_struct, stack)),   \
++             [task_canary] "i" (offsetof(struct task_struct, stack_canary)),\
++             [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
++             [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
+            : "memory", "cc" __EXTRA_CLOBBER)
+ #endif
+ #ifdef __KERNEL__
+ #define _set_base(addr, base) do { unsigned long __pr; \
+ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
+       "rorl $16,%%edx\n\t" \
+       "movb %%dl,%2\n\t" \
+       "movb %%dh,%3" \
+       :"=&d" (__pr) \
+       :"m" (*((addr)+2)), \
+        "m" (*((addr)+4)), \
+        "m" (*((addr)+7)), \
+        "0" (base) \
+       ); } while (0)
+ #define _set_limit(addr, limit) do { unsigned long __lr; \
+ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
+       "rorl $16,%%edx\n\t" \
+       "movb %2,%%dh\n\t" \
+       "andb $0xf0,%%dh\n\t" \
+       "orb %%dh,%%dl\n\t" \
+       "movb %%dl,%2" \
+       :"=&d" (__lr) \
+       :"m" (*(addr)), \
+        "m" (*((addr)+6)), \
+        "0" (limit) \
+       ); } while (0)
+ #define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base))
+ #define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1))
+ extern void native_load_gs_index(unsigned);
+ /*
+  * Load a segment. Fall back on loading the zero
+  * segment if something goes wrong..
+  */
+ #define loadsegment(seg, value)                       \
+       asm volatile("\n"                       \
+                    "1:\t"                     \
+                    "movl %k0,%%" #seg "\n"    \
+                    "2:\n"                     \
+                    ".section .fixup,\"ax\"\n" \
+                    "3:\t"                     \
+                    "movl %k1, %%" #seg "\n\t" \
+                    "jmp 2b\n"                 \
+                    ".previous\n"              \
+                    _ASM_EXTABLE(1b,3b)        \
+                    : :"r" (value), "r" (0) : "memory")
+ /*
+  * Save a segment register away
+  */
+ #define savesegment(seg, value)                               \
+       asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
+ static inline unsigned long get_limit(unsigned long segment)
+ {
+       unsigned long __limit;
+       asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
+       return __limit + 1;
+ }
+ static inline void native_clts(void)
+ {
+       asm volatile("clts");
+ }
+ /*
+  * Volatile isn't enough to prevent the compiler from reordering the
+  * read/write functions for the control registers and messing everything up.
+  * A memory clobber would solve the problem, but would prevent reordering of
+  * all loads stores around it, which can hurt performance. Solution is to
+  * use a variable and mimic reads and writes to it to enforce serialization
+  */
+ static unsigned long __force_order;
+ static inline unsigned long native_read_cr0(void)
+ {
+       unsigned long val;
+       asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
+       return val;
+ }
+ static inline void native_write_cr0(unsigned long val)
+ {
+       asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));
+ }
+ static inline unsigned long native_read_cr2(void)
+ {
+       unsigned long val;
+       asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
+       return val;
+ }
+ static inline void native_write_cr2(unsigned long val)
+ {
+       asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order));
+ }
+ static inline unsigned long native_read_cr3(void)
+ {
+       unsigned long val;
+       asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
+       return val;
+ }
+ static inline void native_write_cr3(unsigned long val)
+ {
+       asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));
+ }
+ static inline unsigned long native_read_cr4(void)
+ {
+       unsigned long val;
+       asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
+       return val;
+ }
+ static inline unsigned long native_read_cr4_safe(void)
+ {
+       unsigned long val;
+       /* This could fault if %cr4 does not exist. In x86_64, a cr4 always
+        * exists, so it will never fail. */
+ #ifdef CONFIG_X86_32
+       asm volatile("1: mov %%cr4, %0\n"
+                    "2:\n"
+                    _ASM_EXTABLE(1b, 2b)
+                    : "=r" (val), "=m" (__force_order) : "0" (0));
+ #else
+       val = native_read_cr4();
+ #endif
+       return val;
+ }
+ static inline void native_write_cr4(unsigned long val)
+ {
+       asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));
+ }
+ #ifdef CONFIG_X86_64
+ static inline unsigned long native_read_cr8(void)
+ {
+       unsigned long cr8;
+       asm volatile("movq %%cr8,%0" : "=r" (cr8));
+       return cr8;
+ }
+ static inline void native_write_cr8(unsigned long val)
+ {
+       asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
+ }
+ #endif
+ static inline void native_wbinvd(void)
+ {
+       asm volatile("wbinvd": : :"memory");
+ }
+ #ifdef CONFIG_PARAVIRT
+ #include <asm/paravirt.h>
+ #else
+ #define read_cr0()    (native_read_cr0())
+ #define write_cr0(x)  (native_write_cr0(x))
+ #define read_cr2()    (native_read_cr2())
+ #define write_cr2(x)  (native_write_cr2(x))
+ #define read_cr3()    (native_read_cr3())
+ #define write_cr3(x)  (native_write_cr3(x))
+ #define read_cr4()    (native_read_cr4())
+ #define read_cr4_safe()       (native_read_cr4_safe())
+ #define write_cr4(x)  (native_write_cr4(x))
+ #define wbinvd()      (native_wbinvd())
+ #ifdef CONFIG_X86_64
+ #define read_cr8()    (native_read_cr8())
+ #define write_cr8(x)  (native_write_cr8(x))
+ #define load_gs_index   native_load_gs_index
+ #endif
+ /* Clear the 'TS' bit */
+ #define clts()                (native_clts())
+ #endif/* CONFIG_PARAVIRT */
+ #define stts() write_cr0(read_cr0() | X86_CR0_TS)
+ #endif /* __KERNEL__ */
+ static inline void clflush(volatile void *__p)
+ {
+       asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
+ }
+ #define nop() asm volatile ("nop")
+ void disable_hlt(void);
+ void enable_hlt(void);
+ void cpu_idle_wait(void);
+ extern unsigned long arch_align_stack(unsigned long sp);
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
+ void default_idle(void);
+ void stop_this_cpu(void *dummy);
+ /*
+  * Force strict CPU ordering.
+  * And yes, this is required on UP too when we're talking
+  * to devices.
+  */
+ #ifdef CONFIG_X86_32
+ /*
+  * Some non-Intel clones support out of order store. wmb() ceases to be a
+  * nop for these.
+  */
+ #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
+ #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
+ #define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
+ #else
+ #define mb()  asm volatile("mfence":::"memory")
+ #define rmb() asm volatile("lfence":::"memory")
+ #define wmb() asm volatile("sfence" ::: "memory")
+ #endif
+ /**
+  * read_barrier_depends - Flush all pending reads that subsequents reads
+  * depend on.
+  *
+  * No data-dependent reads from memory-like regions are ever reordered
+  * over this barrier.  All reads preceding this primitive are guaranteed
+  * to access memory (but not necessarily other CPUs' caches) before any
+  * reads following this primitive that depend on the data return by
+  * any of the preceding reads.  This primitive is much lighter weight than
+  * rmb() on most CPUs, and is never heavier weight than is
+  * rmb().
+  *
+  * These ordering constraints are respected by both the local CPU
+  * and the compiler.
+  *
+  * Ordering is not guaranteed by anything other than these primitives,
+  * not even by data dependencies.  See the documentation for
+  * memory_barrier() for examples and URLs to more information.
+  *
+  * For example, the following code would force ordering (the initial
+  * value of "a" is zero, "b" is one, and "p" is "&a"):
+  *
+  * <programlisting>
+  *    CPU 0                           CPU 1
+  *
+  *    b = 2;
+  *    memory_barrier();
+  *    p = &b;                         q = p;
+  *                                    read_barrier_depends();
+  *                                    d = *q;
+  * </programlisting>
+  *
+  * because the read of "*q" depends on the read of "p" and these
+  * two reads are separated by a read_barrier_depends().  However,
+  * the following code, with the same initial values for "a" and "b":
+  *
+  * <programlisting>
+  *    CPU 0                           CPU 1
+  *
+  *    a = 2;
+  *    memory_barrier();
+  *    b = 3;                          y = b;
+  *                                    read_barrier_depends();
+  *                                    x = a;
+  * </programlisting>
+  *
+  * does not enforce ordering, since there is no data dependency between
+  * the read of "a" and the read of "b".  Therefore, on some CPUs, such
+  * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
+  * in cases like this where there are no data dependencies.
+  **/
+ #define read_barrier_depends()        do { } while (0)
+ #ifdef CONFIG_SMP
+ #define smp_mb()      mb()
+ #ifdef CONFIG_X86_PPRO_FENCE
+ # define smp_rmb()    rmb()
+ #else
+ # define smp_rmb()    barrier()
+ #endif
+ #ifdef CONFIG_X86_OOSTORE
+ # define smp_wmb()    wmb()
+ #else
+ # define smp_wmb()    barrier()
+ #endif
+ #define smp_read_barrier_depends()    read_barrier_depends()
+ #define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
+ #else
+ #define smp_mb()      barrier()
+ #define smp_rmb()     barrier()
+ #define smp_wmb()     barrier()
+ #define smp_read_barrier_depends()    do { } while (0)
+ #define set_mb(var, value) do { var = value; barrier(); } while (0)
+ #endif
+ /*
+  * Stop RDTSC speculation. This is needed when you need to use RDTSC
+  * (or get_cycles or vread that possibly accesses the TSC) in a defined
+  * code region.
+  *
+  * (Could use an alternative three way for this if there was one.)
+  */
+ static inline void rdtsc_barrier(void)
+ {
+       alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
+       alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
+ }
+ #endif /* _ASM_X86_SYSTEM_H */
diff --combined arch/x86/kernel/Makefile
@@@ -6,11 -6,13 +6,13 @@@ extra-y                := head_$(BITS).
  
  CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
  
- ifdef CONFIG_FTRACE
+ ifdef CONFIG_FUNCTION_TRACER
  # Do not profile debug and lowlevel utilities
  CFLAGS_REMOVE_tsc.o = -pg
  CFLAGS_REMOVE_rtc.o = -pg
  CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
+ CFLAGS_REMOVE_ftrace.o = -pg
+ CFLAGS_REMOVE_early_printk.o = -pg
  endif
  
  #
@@@ -21,11 -23,10 +23,11 @@@ nostackp := $(call cc-option, -fno-stac
  CFLAGS_vsyscall_64.o  := $(PROFILING) -g0 $(nostackp)
  CFLAGS_hpet.o         := $(nostackp)
  CFLAGS_tsc.o          := $(nostackp)
 +CFLAGS_paravirt.o     := $(nostackp)
  
- obj-y                 := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
- obj-y                 += traps.o irq_$(BITS).o dumpstack_$(BITS).o
- obj-y                 += time_$(BITS).o ioport.o ldt.o
+ 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 setup_percpu.o
  obj-$(CONFIG_X86_VISWS)       += visws_quirks.o
  obj-$(CONFIG_X86_32)  += probe_roms_32.o
@@@ -41,7 -42,7 +43,7 @@@ obj-$(CONFIG_X86_TRAMPOLINE)  += trampol
  obj-y                         += process.o
  obj-y                         += i387.o xsave.o
  obj-y                         += ptrace.o
- obj-y                         += ds.o
+ obj-$(CONFIG_X86_DS)          += ds.o
  obj-$(CONFIG_X86_32)          += tls.o
  obj-$(CONFIG_IA32_EMULATION)  += tls.o
  obj-y                         += step.o
@@@ -61,10 -62,11 +63,11 @@@ obj-$(CONFIG_X86_32_SMP)   += smpcommon.
  obj-$(CONFIG_X86_64_SMP)      += tsc_sync.o smpcommon.o
  obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline_$(BITS).o
  obj-$(CONFIG_X86_MPPARSE)     += mpparse.o
- obj-$(CONFIG_X86_LOCAL_APIC)  += apic_$(BITS).o nmi.o
- obj-$(CONFIG_X86_IO_APIC)     += io_apic_$(BITS).o
+ obj-$(CONFIG_X86_LOCAL_APIC)  += apic.o nmi.o
+ obj-$(CONFIG_X86_IO_APIC)     += io_apic.o
  obj-$(CONFIG_X86_REBOOTFIXUPS)        += reboot_fixups_32.o
  obj-$(CONFIG_DYNAMIC_FTRACE)  += ftrace.o
+ obj-$(CONFIG_FUNCTION_GRAPH_TRACER)   += ftrace.o
  obj-$(CONFIG_KEXEC)           += machine_kexec_$(BITS).o
  obj-$(CONFIG_KEXEC)           += relocate_kernel_$(BITS).o crash.o
  obj-$(CONFIG_CRASH_DUMP)      += crash_dump_$(BITS).o
@@@ -105,11 -107,15 +108,15 @@@ microcode-$(CONFIG_MICROCODE_INTEL)     += 
  microcode-$(CONFIG_MICROCODE_AMD)     += microcode_amd.o
  obj-$(CONFIG_MICROCODE)                       += microcode.o
  
+ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
+ obj-$(CONFIG_SWIOTLB)                 += pci-swiotlb_64.o # NB rename without _64
  ###
  # 64 bit specific files
  ifeq ($(CONFIG_X86_64),y)
          obj-y                         += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
-       obj-y                           += bios_uv.o
+       obj-y                           += bios_uv.o uv_irq.o uv_sysfs.o
          obj-y                         += genx2apic_cluster.o
          obj-y                         += genx2apic_phys.o
          obj-$(CONFIG_X86_PM_TIMER)    += pmtimer_64.o
          obj-$(CONFIG_GART_IOMMU)      += pci-gart_64.o aperture_64.o
          obj-$(CONFIG_CALGARY_IOMMU)   += pci-calgary_64.o tce_64.o
          obj-$(CONFIG_AMD_IOMMU)               += amd_iommu_init.o amd_iommu.o
-         obj-$(CONFIG_SWIOTLB)         += pci-swiotlb_64.o
  
          obj-$(CONFIG_PCI_MMCONFIG)    += mmconf-fam10h_64.o
  endif
@@@ -16,7 -16,6 +16,7 @@@
  
  #include <stdarg.h>
  
 +#include <linux/stackprotector.h>
  #include <linux/cpu.h>
  #include <linux/errno.h>
  #include <linux/sched.h>
@@@ -40,6 -39,7 +40,7 @@@
  #include <linux/prctl.h>
  #include <linux/uaccess.h>
  #include <linux/io.h>
+ #include <linux/ftrace.h>
  
  #include <asm/pgtable.h>
  #include <asm/system.h>
@@@ -53,6 -53,7 +54,7 @@@
  #include <asm/ia32.h>
  #include <asm/idle.h>
  #include <asm/syscalls.h>
+ #include <asm/ds.h>
  
  asmlinkage extern void ret_from_fork(void);
  
@@@ -64,6 -65,13 +66,13 @@@ void idle_notifier_register(struct noti
  {
        atomic_notifier_chain_register(&idle_notifier, n);
  }
+ EXPORT_SYMBOL_GPL(idle_notifier_register);
+ void idle_notifier_unregister(struct notifier_block *n)
+ {
+       atomic_notifier_chain_unregister(&idle_notifier, n);
+ }
+ EXPORT_SYMBOL_GPL(idle_notifier_unregister);
  
  void enter_idle(void)
  {
@@@ -103,17 -111,6 +112,17 @@@ static inline void play_dead(void
  void cpu_idle(void)
  {
        current_thread_info()->status |= TS_POLLING;
 +
 +      /*
 +       * If we're the non-boot CPU, nothing set the PDA stack
 +       * canary up for us - and if we are the boot CPU we have
 +       * a 0 stack canary. This is a good place for updating
 +       * it, as we wont ever return from this function (so the
 +       * invalid canaries already on the stack wont ever
 +       * trigger):
 +       */
 +      boot_init_stack_canary();
 +
        /* endless idle loop with no priority at all */
        while (1) {
                tick_nohz_stop_sched_tick(1);
@@@ -240,14 -237,8 +249,8 @@@ void exit_thread(void
                t->io_bitmap_max = 0;
                put_cpu();
        }
- #ifdef CONFIG_X86_DS
-       /* Free any DS contexts that have not been properly released. */
-       if (unlikely(t->ds_ctx)) {
-               /* we clear debugctl to make sure DS is not used. */
-               update_debugctlmsr(0);
-               ds_free(t->ds_ctx);
-       }
- #endif /* CONFIG_X86_DS */
+       ds_exit_thread(current);
  }
  
  void flush_thread(void)
@@@ -377,6 -368,12 +380,12 @@@ int copy_thread(int nr, unsigned long c
                if (err)
                        goto out;
        }
+       ds_copy_thread(p, me);
+       clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
+       p->thread.debugctlmsr = 0;
        err = 0;
  out:
        if (err && p->thread.io_bitmap_ptr) {
@@@ -475,35 -472,14 +484,14 @@@ static inline void __switch_to_xtra(str
                                    struct tss_struct *tss)
  {
        struct thread_struct *prev, *next;
-       unsigned long debugctl;
  
        prev = &prev_p->thread,
        next = &next_p->thread;
  
-       debugctl = prev->debugctlmsr;
- #ifdef CONFIG_X86_DS
-       {
-               unsigned long ds_prev = 0, ds_next = 0;
-               if (prev->ds_ctx)
-                       ds_prev = (unsigned long)prev->ds_ctx->ds;
-               if (next->ds_ctx)
-                       ds_next = (unsigned long)next->ds_ctx->ds;
-               if (ds_next != ds_prev) {
-                       /*
-                        * We clear debugctl to make sure DS
-                        * is not in use when we change it:
-                        */
-                       debugctl = 0;
-                       update_debugctlmsr(0);
-                       wrmsrl(MSR_IA32_DS_AREA, ds_next);
-               }
-       }
- #endif /* CONFIG_X86_DS */
-       if (next->debugctlmsr != debugctl)
+       if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
+           test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
+               ds_switch_to(prev_p, next_p);
+       else if (next->debugctlmsr != prev->debugctlmsr)
                update_debugctlmsr(next->debugctlmsr);
  
        if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
                 */
                memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
        }
- #ifdef CONFIG_X86_PTRACE_BTS
-       if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
-               ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
-       if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
-               ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
- #endif /* CONFIG_X86_PTRACE_BTS */
  }
  
  /*
   * - could test fs/gs bitsliced
   *
   * Kprobes not supported here. Set the probe on schedule instead.
+  * Function graph tracer not supported too.
   */
- struct task_struct *
__notrace_funcgraph struct task_struct *
  __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
  {
        struct thread_struct *prev = &prev_p->thread;
                  (unsigned long)task_stack_page(next_p) +
                  THREAD_SIZE - PDA_STACKOFFSET);
  #ifdef CONFIG_CC_STACKPROTECTOR
 -      write_pda(stack_canary, next_p->stack_canary);
        /*
         * Build time only check to make sure the stack_canary is at
         * offset 40 in the pda; this is a gcc ABI requirement
diff --combined arch/x86/mm/fault.c
@@@ -26,7 -26,6 +26,7 @@@
  #include <linux/kprobes.h>
  #include <linux/uaccess.h>
  #include <linux/kdebug.h>
 +#include <linux/magic.h>
  
  #include <asm/system.h>
  #include <asm/desc.h>
@@@ -54,7 -53,7 +54,7 @@@
  
  static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
  {
- #ifdef CONFIG_MMIOTRACE_HOOKS
+ #ifdef CONFIG_MMIOTRACE
        if (unlikely(is_kmmio_active()))
                if (kmmio_handler(regs, addr) == 1)
                        return -1;
@@@ -394,7 -393,7 +394,7 @@@ static void show_fault_oops(struct pt_r
                if (pte && pte_present(*pte) && !pte_exec(*pte))
                        printk(KERN_CRIT "kernel tried to execute "
                                "NX-protected page - exploit attempt? "
-                               "(uid: %d)\n", current->uid);
+                               "(uid: %d)\n", current_uid());
        }
  #endif
  
@@@ -414,6 -413,7 +414,7 @@@ static noinline void pgtable_bad(unsign
                                 unsigned long error_code)
  {
        unsigned long flags = oops_begin();
+       int sig = SIGKILL;
        struct task_struct *tsk;
  
        printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
        tsk->thread.trap_no = 14;
        tsk->thread.error_code = error_code;
        if (__die("Bad pagetable", regs, error_code))
-               regs = NULL;
-       oops_end(flags, regs, SIGKILL);
+               sig = 0;
+       oops_end(flags, regs, sig);
  }
  #endif
  
@@@ -589,10 -589,9 +590,11 @@@ void __kprobes do_page_fault(struct pt_
        unsigned long address;
        int write, si_code;
        int fault;
 +      unsigned long *stackend;
 +
  #ifdef CONFIG_X86_64
        unsigned long flags;
+       int sig;
  #endif
  
        tsk = current;
        }
  
  
- #ifdef CONFIG_X86_32
-       /* It's safe to allow irq's after cr2 has been saved and the vmalloc
-          fault has been handled. */
-       if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
-               local_irq_enable();
        /*
-        * If we're in an interrupt, have no user context or are running in an
-        * atomic region then we must not take the fault.
+        * It's safe to allow irq's after cr2 has been saved and the
+        * vmalloc fault has been handled.
+        *
+        * User-mode registers count as a user access even for any
+        * potential system fault or CPU buglet.
         */
-       if (in_atomic() || !mm)
-               goto bad_area_nosemaphore;
- #else /* CONFIG_X86_64 */
-       if (likely(regs->flags & X86_EFLAGS_IF))
+       if (user_mode_vm(regs)) {
+               local_irq_enable();
+               error_code |= PF_USER;
+       } else if (regs->flags & X86_EFLAGS_IF)
                local_irq_enable();
  
+ #ifdef CONFIG_X86_64
        if (unlikely(error_code & PF_RSVD))
                pgtable_bad(address, regs, error_code);
+ #endif
  
        /*
         * If we're in an interrupt, have no user context or are running in an
        if (unlikely(in_atomic() || !mm))
                goto bad_area_nosemaphore;
  
-       /*
-        * User-mode registers count as a user access even for any
-        * potential system fault or CPU buglet.
-        */
-       if (user_mode_vm(regs))
-               error_code |= PF_USER;
  again:
- #endif
-       /* When running in the kernel we expect faults to occur only to
+       /*
+        * When running in the kernel we expect faults to occur only to
         * addresses in user space.  All other faults represent errors in the
         * kernel and should generate an OOPS.  Unfortunately, in the case of an
         * erroneous fault occurring in a code path which already holds mmap_sem
@@@ -740,9 -732,6 +735,6 @@@ good_area
                        goto bad_area;
        }
  
- #ifdef CONFIG_X86_32
- survive:
- #endif
        /*
         * If for any reason at all we couldn't handle the fault,
         * make sure we exit gracefully rather than endlessly redo
@@@ -853,10 -842,6 +845,10 @@@ no_context
  
        show_fault_oops(regs, error_code, address);
  
 +      stackend = end_of_stack(tsk);
 +      if (*stackend != STACK_END_MAGIC)
 +              printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
 +
        tsk->thread.cr2 = address;
        tsk->thread.trap_no = 14;
        tsk->thread.error_code = error_code;
        bust_spinlocks(0);
        do_exit(SIGKILL);
  #else
+       sig = SIGKILL;
        if (__die("Oops", regs, error_code))
-               regs = NULL;
+               sig = 0;
        /* Executive summary in case the body of the oops scrolled away */
        printk(KERN_EMERG "CR2: %016lx\n", address);
-       oops_end(flags, regs, SIGKILL);
+       oops_end(flags, regs, sig);
  #endif
  
  /*
@@@ -881,12 -867,11 +874,11 @@@ out_of_memory
        up_read(&mm->mmap_sem);
        if (is_global_init(tsk)) {
                yield();
- #ifdef CONFIG_X86_32
-               down_read(&mm->mmap_sem);
-               goto survive;
- #else
+               /*
+                * Re-lookup the vma - in theory the vma tree might
+                * have changed:
+                */
                goto again;
- #endif
        }
  
        printk("VM: killing process %s\n", tsk->comm);
diff --combined include/linux/sched.h
@@@ -96,6 -96,7 +96,7 @@@ struct exec_domain
  struct futex_pi_state;
  struct robust_list_head;
  struct bio;
+ struct bts_tracer;
  
  /*
   * List of flags we want to share for kernel threads,
@@@ -247,6 -248,7 +248,7 @@@ extern void init_idle(struct task_struc
  extern void init_idle_bootup_task(struct task_struct *idle);
  
  extern int runqueue_is_locked(void);
+ extern void task_rq_unlock_wait(struct task_struct *p);
  
  extern cpumask_t nohz_cpu_mask;
  #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
@@@ -258,8 -260,6 +260,6 @@@ static inline int select_nohz_load_bala
  }
  #endif
  
- extern unsigned long rt_needs_cpu(int cpu);
  /*
   * Only dump TASK_* tasks. (0 for all tasks)
   */
@@@ -287,7 -287,6 +287,6 @@@ extern void trap_init(void)
  extern void account_process_tick(struct task_struct *task, int user);
  extern void update_process_times(int user);
  extern void scheduler_tick(void);
- extern void hrtick_resched(void);
  
  extern void sched_show_task(struct task_struct *p);
  
@@@ -403,12 -402,21 +402,21 @@@ extern int get_dumpable(struct mm_struc
  #define MMF_DUMP_MAPPED_PRIVATE       4
  #define MMF_DUMP_MAPPED_SHARED        5
  #define MMF_DUMP_ELF_HEADERS  6
+ #define MMF_DUMP_HUGETLB_PRIVATE 7
+ #define MMF_DUMP_HUGETLB_SHARED  8
  #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS
- #define MMF_DUMP_FILTER_BITS  5
+ #define MMF_DUMP_FILTER_BITS  7
  #define MMF_DUMP_FILTER_MASK \
        (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT)
  #define MMF_DUMP_FILTER_DEFAULT \
-       ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED))
+       ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\
+        (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF)
+ #ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS
+ # define MMF_DUMP_MASK_DEFAULT_ELF    (1 << MMF_DUMP_ELF_HEADERS)
+ #else
+ # define MMF_DUMP_MASK_DEFAULT_ELF    0
+ #endif
  
  struct sighand_struct {
        atomic_t                count;
@@@ -425,6 -433,39 +433,39 @@@ struct pacct_struct 
        unsigned long           ac_minflt, ac_majflt;
  };
  
+ /**
+  * struct task_cputime - collected CPU time counts
+  * @utime:            time spent in user mode, in &cputime_t units
+  * @stime:            time spent in kernel mode, in &cputime_t units
+  * @sum_exec_runtime: total time spent on the CPU, in nanoseconds
+  *
+  * This structure groups together three kinds of CPU time that are
+  * tracked for threads and thread groups.  Most things considering
+  * CPU time want to group these counts together and treat all three
+  * of them in parallel.
+  */
+ struct task_cputime {
+       cputime_t utime;
+       cputime_t stime;
+       unsigned long long sum_exec_runtime;
+ };
+ /* Alternate field names when used to cache expirations. */
+ #define prof_exp      stime
+ #define virt_exp      utime
+ #define sched_exp     sum_exec_runtime
+ /**
+  * struct thread_group_cputime - thread group interval timer counts
+  * @totals:           thread group interval timers; substructure for
+  *                    uniprocessor kernel, per-cpu for SMP kernel.
+  *
+  * This structure contains the version of task_cputime, above, that is
+  * used for thread group CPU clock calculations.
+  */
+ struct thread_group_cputime {
+       struct task_cputime *totals;
+ };
  /*
   * NOTE! "signal_struct" does not have it's own
   * locking, because a shared signal_struct always
@@@ -470,6 -511,17 +511,17 @@@ struct signal_struct 
        cputime_t it_prof_expires, it_virt_expires;
        cputime_t it_prof_incr, it_virt_incr;
  
+       /*
+        * Thread group totals for process CPU clocks.
+        * See thread_group_cputime(), et al, for details.
+        */
+       struct thread_group_cputime cputime;
+       /* Earliest-expiration cache. */
+       struct task_cputime cputime_expires;
+       struct list_head cpu_timers[3];
        /* job control IDs */
  
        /*
         * Live threads maintain their own counters and add to these
         * in __exit_signal, except for the group leader.
         */
-       cputime_t utime, stime, cutime, cstime;
+       cputime_t cutime, cstime;
        cputime_t gtime;
        cputime_t cgtime;
        unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
        struct task_io_accounting ioac;
  
        /*
-        * Cumulative ns of scheduled CPU time for dead threads in the
-        * group, not including a zombie group leader.  (This only differs
-        * from jiffies_to_ns(utime + stime) if sched_clock uses something
-        * other than jiffies.)
-        */
-       unsigned long long sum_sched_runtime;
-       /*
         * We don't bother to synchronize most readers of this at all,
         * because there is no reader checking a limit that actually needs
         * to get both rlim_cur and rlim_max atomically, and either one
         */
        struct rlimit rlim[RLIM_NLIMITS];
  
-       struct list_head cpu_timers[3];
-       /* keep the process-shared keyrings here so that they do the right
-        * thing in threads created with CLONE_THREAD */
- #ifdef CONFIG_KEYS
-       struct key *session_keyring;    /* keyring inherited over fork */
-       struct key *process_keyring;    /* keyring private to this process */
- #endif
  #ifdef CONFIG_BSD_PROCESS_ACCT
        struct pacct_struct pacct;      /* per-process accounting information */
  #endif
@@@ -587,6 -623,10 +623,10 @@@ struct user_struct 
        atomic_t inotify_watches; /* How many inotify watches does this user have? */
        atomic_t inotify_devs;  /* How many inotify devs does this user have opened? */
  #endif
+ #ifdef CONFIG_EPOLL
+       atomic_t epoll_devs;    /* The number of epoll descriptors currently open */
+       atomic_t epoll_watches; /* The number of file descriptors currently watched */
+ #endif
  #ifdef CONFIG_POSIX_MQUEUE
        /* protected by mq_lock */
        unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
        /* Hash table maintenance information */
        struct hlist_node uidhash_node;
        uid_t uid;
+       struct user_namespace *user_ns;
  
  #ifdef CONFIG_USER_SCHED
        struct task_group *tg;
@@@ -618,6 -659,7 +659,7 @@@ extern struct user_struct *find_user(ui
  extern struct user_struct root_user;
  #define INIT_USER (&root_user)
  
  struct backing_dev_info;
  struct reclaim_state;
  
  struct sched_info {
        /* cumulative counters */
        unsigned long pcount;         /* # of times run on this cpu */
-       unsigned long long cpu_time,  /* time spent on the cpu */
-                          run_delay; /* time spent waiting on a runqueue */
+       unsigned long long run_delay; /* time spent waiting on a runqueue */
  
        /* timestamps */
        unsigned long long last_arrival,/* when we last ran on a cpu */
  };
  #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
  
- #ifdef CONFIG_SCHEDSTATS
- extern const struct file_operations proc_schedstat_operations;
- #endif /* CONFIG_SCHEDSTATS */
  #ifdef CONFIG_TASK_DELAY_ACCT
  struct task_delay_info {
        spinlock_t      lock;
@@@ -845,38 -882,7 +882,7 @@@ partition_sched_domains(int ndoms_new, 
  #endif        /* !CONFIG_SMP */
  
  struct io_context;                    /* See blkdev.h */
- #define NGROUPS_SMALL         32
- #define NGROUPS_PER_BLOCK     ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
- struct group_info {
-       int ngroups;
-       atomic_t usage;
-       gid_t small_block[NGROUPS_SMALL];
-       int nblocks;
-       gid_t *blocks[0];
- };
- /*
-  * get_group_info() must be called with the owning task locked (via task_lock())
-  * when task != current.  The reason being that the vast majority of callers are
-  * looking at current->group_info, which can not be changed except by the
-  * current task.  Changing current->group_info requires the task lock, too.
-  */
- #define get_group_info(group_info) do { \
-       atomic_inc(&(group_info)->usage); \
- } while (0)
  
- #define put_group_info(group_info) do { \
-       if (atomic_dec_and_test(&(group_info)->usage)) \
-               groups_free(group_info); \
- } while (0)
- extern struct group_info *groups_alloc(int gidsetsize);
- extern void groups_free(struct group_info *group_info);
- extern int set_current_groups(struct group_info *group_info);
- extern int groups_search(struct group_info *group_info, gid_t grp);
- /* access the groups "array" with this macro */
- #define GROUP_AT(gi, i) \
-     ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
  
  #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK
  extern void prefetch_stack(struct task_struct *t);
@@@ -898,7 -904,6 +904,6 @@@ struct sched_class 
        void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup);
        void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
        void (*yield_task) (struct rq *rq);
-       int  (*select_task_rq)(struct task_struct *p, int sync);
  
        void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync);
  
        void (*put_prev_task) (struct rq *rq, struct task_struct *p);
  
  #ifdef CONFIG_SMP
+       int  (*select_task_rq)(struct task_struct *p, int sync);
        unsigned long (*load_balance) (struct rq *this_rq, int this_cpu,
                        struct rq *busiest, unsigned long max_load_move,
                        struct sched_domain *sd, enum cpu_idle_type idle,
        void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
        void (*post_schedule) (struct rq *this_rq);
        void (*task_wake_up) (struct rq *this_rq, struct task_struct *task);
- #endif
  
-       void (*set_curr_task) (struct rq *rq);
-       void (*task_tick) (struct rq *rq, struct task_struct *p, int queued);
-       void (*task_new) (struct rq *rq, struct task_struct *p);
        void (*set_cpus_allowed)(struct task_struct *p,
                                 const cpumask_t *newmask);
  
        void (*rq_online)(struct rq *rq);
        void (*rq_offline)(struct rq *rq);
+ #endif
+       void (*set_curr_task) (struct rq *rq);
+       void (*task_tick) (struct rq *rq, struct task_struct *p, int queued);
+       void (*task_new) (struct rq *rq, struct task_struct *p);
  
        void (*switched_from) (struct rq *this_rq, struct task_struct *task,
                               int running);
@@@ -1094,9 -1102,10 +1102,9 @@@ struct task_struct 
        pid_t pid;
        pid_t tgid;
  
 -#ifdef CONFIG_CC_STACKPROTECTOR
        /* Canary value for the -fstack-protector gcc feature */
        unsigned long stack_canary;
 -#endif
 +
        /* 
         * pointers to (original) parent process, youngest child, younger sibling,
         * older sibling, respectively.  (p->father can be replaced with 
        struct list_head ptraced;
        struct list_head ptrace_entry;
  
+ #ifdef CONFIG_X86_PTRACE_BTS
+       /*
+        * This is the tracer handle for the ptrace BTS extension.
+        * This field actually belongs to the ptracer task.
+        */
+       struct bts_tracer *bts;
+       /*
+        * The buffer to hold the BTS data.
+        */
+       void *bts_buffer;
+       size_t bts_size;
+ #endif /* CONFIG_X86_PTRACE_BTS */
        /* PID/PID hash table linkage. */
        struct pid_link pids[PIDTYPE_MAX];
        struct list_head thread_group;
  /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
        unsigned long min_flt, maj_flt;
  
-       cputime_t it_prof_expires, it_virt_expires;
-       unsigned long long it_sched_expires;
+       struct task_cputime cputime_expires;
        struct list_head cpu_timers[3];
  
  /* process credentials */
-       uid_t uid,euid,suid,fsuid;
-       gid_t gid,egid,sgid,fsgid;
-       struct group_info *group_info;
-       kernel_cap_t   cap_effective, cap_inheritable, cap_permitted, cap_bset;
-       struct user_struct *user;
-       unsigned securebits;
- #ifdef CONFIG_KEYS
-       unsigned char jit_keyring;      /* default keyring to attach requested keys to */
-       struct key *request_key_auth;   /* assumed request_key authority */
-       struct key *thread_keyring;     /* keyring private to this thread */
- #endif
+       const struct cred *real_cred;   /* objective and real subjective task
+                                        * credentials (COW) */
+       const struct cred *cred;        /* effective (overridable) subjective task
+                                        * credentials (COW) */
+       struct mutex cred_exec_mutex;   /* execve vs ptrace cred calculation mutex */
        char comm[TASK_COMM_LEN]; /* executable name excluding path
                                     - access with [gs]et_task_comm (which lock
                                       it with task_lock())
        int (*notifier)(void *priv);
        void *notifier_data;
        sigset_t *notifier_mask;
- #ifdef CONFIG_SECURITY
-       void *security;
- #endif
        struct audit_context *audit_context;
  #ifdef CONFIG_AUDITSYSCALL
        uid_t loginuid;
        int latency_record_count;
        struct latency_record latency_record[LT_SAVECOUNT];
  #endif
+       /*
+        * time slack values; these are used to round up poll() and
+        * select() etc timeout values. These are in nanoseconds.
+        */
+       unsigned long timer_slack_ns;
+       unsigned long default_timer_slack_ns;
+       struct list_head        *scm_work_list;
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       /* Index of current stored adress in ret_stack */
+       int curr_ret_stack;
+       /* Stack of return addresses for return function tracing */
+       struct ftrace_ret_stack *ret_stack;
+       /*
+        * Number of functions that haven't been traced
+        * because of depth overrun.
+        */
+       atomic_t trace_overrun;
+       /* Pause for the tracing */
+       atomic_t tracing_graph_pause;
+ #endif
+ #ifdef CONFIG_TRACING
+       /* state flags for use by tracers */
+       unsigned long trace;
+ #endif
  };
  
  /*
@@@ -1587,6 -1625,7 +1624,7 @@@ extern unsigned long long cpu_clock(in
  
  extern unsigned long long
  task_sched_runtime(struct task_struct *task);
+ extern unsigned long long thread_group_sched_runtime(struct task_struct *task);
  
  /* sched_exec is called by processes performing an exec */
  #ifdef CONFIG_SMP
@@@ -1621,6 -1660,7 +1659,7 @@@ extern unsigned int sysctl_sched_featur
  extern unsigned int sysctl_sched_migration_cost;
  extern unsigned int sysctl_sched_nr_migrate;
  extern unsigned int sysctl_sched_shares_ratelimit;
+ extern unsigned int sysctl_sched_shares_thresh;
  
  int sched_nr_latency_handler(struct ctl_table *table, int write,
                struct file *file, void __user *buffer, size_t *length,
@@@ -1720,7 -1760,6 +1759,6 @@@ static inline struct user_struct *get_u
        return u;
  }
  extern void free_uid(struct user_struct *);
- extern void switch_uid(struct user_struct *);
  extern void release_uids(struct user_namespace *ns);
  
  #include <asm/current.h>
@@@ -1739,9 -1778,6 +1777,6 @@@ extern void wake_up_new_task(struct tas
  extern void sched_fork(struct task_struct *p, int clone_flags);
  extern void sched_dead(struct task_struct *p);
  
- extern int in_group_p(gid_t);
- extern int in_egroup_p(gid_t);
  extern void proc_caches_init(void);
  extern void flush_signals(struct task_struct *);
  extern void ignore_signals(struct task_struct *);
@@@ -1873,6 -1909,8 +1908,8 @@@ static inline unsigned long wait_task_i
  #define for_each_process(p) \
        for (p = &init_task ; (p = next_task(p)) != &init_task ; )
  
+ extern bool is_single_threaded(struct task_struct *);
  /*
   * Careful: do_each_thread/while_each_thread is a double loop so
   *          'break' will not work as expected - use goto instead.
@@@ -1973,19 -2011,6 +2010,19 @@@ static inline int object_is_on_stack(vo
  
  extern void thread_info_cache_init(void);
  
 +#ifdef CONFIG_DEBUG_STACK_USAGE
 +static inline unsigned long stack_not_used(struct task_struct *p)
 +{
 +      unsigned long *n = end_of_stack(p);
 +
 +      do {    /* Skip over canary */
 +              n++;
 +      } while (!*n);
 +
 +      return (unsigned long)n - (unsigned long)end_of_stack(p);
 +}
 +#endif
 +
  /* set thread flags in other task's structures
   * - see asm/thread_info.h for TIF_xxxx flags available
   */
@@@ -2097,6 -2122,30 +2134,30 @@@ static inline int spin_needbreak(spinlo
  }
  
  /*
+  * Thread group CPU time accounting.
+  */
+ extern int thread_group_cputime_alloc(struct task_struct *);
+ extern void thread_group_cputime(struct task_struct *, struct task_cputime *);
+ static inline void thread_group_cputime_init(struct signal_struct *sig)
+ {
+       sig->cputime.totals = NULL;
+ }
+ static inline int thread_group_cputime_clone_thread(struct task_struct *curr)
+ {
+       if (curr->signal->cputime.totals)
+               return 0;
+       return thread_group_cputime_alloc(curr);
+ }
+ static inline void thread_group_cputime_free(struct signal_struct *sig)
+ {
+       free_percpu(sig->cputime.totals);
+ }
+ /*
   * Reevaluate whether the task has signals pending delivery.
   * Wake the task if so.
   * This is required every time the blocked sigset_t changes.
@@@ -2158,6 -2207,7 +2219,7 @@@ extern void normalize_rt_tasks(void)
  extern struct task_group init_task_group;
  #ifdef CONFIG_USER_SCHED
  extern struct task_group root_task_group;
+ extern void set_tg_uid(struct user_struct *user);
  #endif
  
  extern struct task_group *sched_create_group(struct task_group *parent);
diff --combined init/main.c
@@@ -14,7 -14,6 +14,7 @@@
  #include <linux/proc_fs.h>
  #include <linux/kernel.h>
  #include <linux/syscalls.h>
 +#include <linux/stackprotector.h>
  #include <linux/string.h>
  #include <linux/ctype.h>
  #include <linux/delay.h>
@@@ -28,6 -27,7 +28,7 @@@
  #include <linux/gfp.h>
  #include <linux/percpu.h>
  #include <linux/kmod.h>
+ #include <linux/vmalloc.h>
  #include <linux/kernel_stat.h>
  #include <linux/start_kernel.h>
  #include <linux/security.h>
@@@ -52,6 -52,7 +53,7 @@@
  #include <linux/key.h>
  #include <linux/unwind.h>
  #include <linux/buffer_head.h>
+ #include <linux/page_cgroup.h>
  #include <linux/debug_locks.h>
  #include <linux/debugobjects.h>
  #include <linux/lockdep.h>
@@@ -61,6 -62,8 +63,8 @@@
  #include <linux/sched.h>
  #include <linux/signal.h>
  #include <linux/idr.h>
+ #include <linux/ftrace.h>
+ #include <trace/boot.h>
  
  #include <asm/io.h>
  #include <asm/bugs.h>
@@@ -537,6 -540,15 +541,15 @@@ void __init __weak thread_info_cache_in
  {
  }
  
+ void __init __weak arch_early_irq_init(void)
+ {
+ }
+ void __init __weak early_irq_init(void)
+ {
+       arch_early_irq_init();
+ }
  asmlinkage void __init start_kernel(void)
  {
        char * command_line;
        unwind_init();
        lockdep_init();
        debug_objects_early_init();
 +
 +      /*
 +       * Set up the the initial canary ASAP:
 +       */
 +      boot_init_stack_canary();
 +
        cgroup_init_early();
  
        local_irq_disable();
        sort_main_extable();
        trap_init();
        rcu_init();
+       /* init some links before init_ISA_irqs() */
+       early_irq_init();
        init_IRQ();
        pidhash_init();
        init_timers();
                initrd_start = 0;
        }
  #endif
+       vmalloc_init();
        vfs_caches_init_early();
        cpuset_init_early();
+       page_cgroup_init();
        mem_init();
        enable_debug_pagealloc();
        cpu_hotplug_init();
                efi_enter_virtual_mode();
  #endif
        thread_info_cache_init();
+       cred_init();
        fork_init(num_physpages);
        proc_caches_init();
        buffer_init();
-       unnamed_dev_init();
        key_init();
        security_init();
        vfs_caches_init(num_physpages);
  
        acpi_early_init(); /* before LAPIC and SMP init */
  
+       ftrace_init();
        /* Do the rest non-__init'ed, we're now alive */
        rest_init();
  }
  
  static int initcall_debug;
- static int __init initcall_debug_setup(char *str)
- {
-       initcall_debug = 1;
-       return 1;
- }
- __setup("initcall_debug", initcall_debug_setup);
+ core_param(initcall_debug, initcall_debug, bool, 0644);
  
  int do_one_initcall(initcall_t fn)
  {
        int count = preempt_count();
-       ktime_t t0, t1, delta;
+       ktime_t calltime, delta, rettime;
        char msgbuf[64];
-       int result;
+       struct boot_trace_call call;
+       struct boot_trace_ret ret;
  
        if (initcall_debug) {
-               printk("calling  %pF @ %i\n", fn, task_pid_nr(current));
-               t0 = ktime_get();
+               call.caller = task_pid_nr(current);
+               printk("calling  %pF @ %i\n", fn, call.caller);
+               calltime = ktime_get();
+               trace_boot_call(&call, fn);
+               enable_boot_trace();
        }
  
-       result = fn();
+       ret.result = fn();
  
        if (initcall_debug) {
-               t1 = ktime_get();
-               delta = ktime_sub(t1, t0);
-               printk("initcall %pF returned %d after %Ld msecs\n",
-                       fn, result,
-                       (unsigned long long) delta.tv64 >> 20);
+               disable_boot_trace();
+               rettime = ktime_get();
+               delta = ktime_sub(rettime, calltime);
+               ret.duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+               trace_boot_ret(&ret, fn);
+               printk("initcall %pF returned %d after %Ld usecs\n", fn,
+                       ret.result, ret.duration);
        }
  
        msgbuf[0] = 0;
  
-       if (result && result != -ENODEV && initcall_debug)
-               sprintf(msgbuf, "error code %d ", result);
+       if (ret.result && ret.result != -ENODEV && initcall_debug)
+               sprintf(msgbuf, "error code %d ", ret.result);
  
        if (preempt_count() != count) {
                strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
                printk("initcall %pF returned with %s\n", fn, msgbuf);
        }
  
-       return result;
+       return ret.result;
  }
  
  
@@@ -774,7 -785,6 +792,6 @@@ static void __init do_initcalls(void
  static void __init do_basic_setup(void)
  {
        rcu_init_sched(); /* needed by module_init stage. */
-       /* drivers will send hotplug events */
        init_workqueues();
        usermodehelper_init();
        driver_init();
@@@ -862,6 -872,7 +879,7 @@@ static int __init kernel_init(void * un
        smp_prepare_cpus(setup_max_cpus);
  
        do_pre_smp_initcalls();
+       start_boot_trace();
  
        smp_init();
        sched_init_smp();
         * we're essentially up and running. Get rid of the
         * initmem segments and start the user-mode stuff..
         */
        init_post();
        return 0;
  }
diff --combined kernel/exit.c
  #include <linux/cn_proc.h>
  #include <linux/mutex.h>
  #include <linux/futex.h>
- #include <linux/compat.h>
  #include <linux/pipe_fs_i.h>
  #include <linux/audit.h> /* for audit_free() */
  #include <linux/resource.h>
  #include <linux/blkdev.h>
  #include <linux/task_io_accounting_ops.h>
  #include <linux/tracehook.h>
+ #include <linux/init_task.h>
+ #include <trace/sched.h>
  
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
  #include <asm/pgtable.h>
  #include <asm/mmu_context.h>
+ #include "cred-internals.h"
+ DEFINE_TRACE(sched_process_free);
+ DEFINE_TRACE(sched_process_exit);
+ DEFINE_TRACE(sched_process_wait);
  
  static void exit_mm(struct task_struct * tsk);
  
@@@ -112,8 -118,6 +118,6 @@@ static void __exit_signal(struct task_s
                 * We won't ever get here for the group leader, since it
                 * will have been the last reference on the signal_struct.
                 */
-               sig->utime = cputime_add(sig->utime, task_utime(tsk));
-               sig->stime = cputime_add(sig->stime, task_stime(tsk));
                sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
                sig->min_flt += tsk->min_flt;
                sig->maj_flt += tsk->maj_flt;
                sig->inblock += task_io_get_inblock(tsk);
                sig->oublock += task_io_get_oublock(tsk);
                task_io_accounting_add(&sig->ioac, &tsk->ioac);
-               sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
                sig = NULL; /* Marker for below. */
        }
  
        if (sig) {
                flush_sigqueue(&sig->shared_pending);
                taskstats_tgid_free(sig);
+               /*
+                * Make sure ->signal can't go away under rq->lock,
+                * see account_group_exec_runtime().
+                */
+               task_rq_unlock_wait(tsk);
                __cleanup_signal(sig);
        }
  }
  
  static void delayed_put_task_struct(struct rcu_head *rhp)
  {
-       put_task_struct(container_of(rhp, struct task_struct, rcu));
+       struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
+       trace_sched_process_free(tsk);
+       put_task_struct(tsk);
  }
  
  
@@@ -159,7 -170,10 +170,10 @@@ void release_task(struct task_struct * 
        int zap_leader;
  repeat:
        tracehook_prepare_release_task(p);
-       atomic_dec(&p->user->processes);
+       /* don't need to get the RCU readlock here - the process is dead and
+        * can't be modifying its own credentials */
+       atomic_dec(&__task_cred(p)->user->processes);
        proc_flush_task(p);
        write_lock_irq(&tasklist_lock);
        tracehook_finish_release_task(p);
@@@ -334,12 -348,12 +348,12 @@@ static void reparent_to_kthreadd(void
        /* cpus_allowed? */
        /* rt_priority? */
        /* signals? */
-       security_task_reparent_to_init(current);
        memcpy(current->signal->rlim, init_task.signal->rlim,
               sizeof(current->signal->rlim));
-       atomic_inc(&(INIT_USER->__count));
+       atomic_inc(&init_cred.usage);
+       commit_creds(&init_cred);
        write_unlock_irq(&tasklist_lock);
-       switch_uid(INIT_USER);
  }
  
  void __set_special_pids(struct pid *pid)
@@@ -640,24 -654,23 +654,23 @@@ retry
  assign_new_owner:
        BUG_ON(c == p);
        get_task_struct(c);
+       read_unlock(&tasklist_lock);
+       down_write(&mm->mmap_sem);
        /*
         * The task_lock protects c->mm from changing.
         * We always want mm->owner->mm == mm
         */
        task_lock(c);
-       /*
-        * Delay read_unlock() till we have the task_lock()
-        * to ensure that c does not slip away underneath us
-        */
-       read_unlock(&tasklist_lock);
        if (c->mm != mm) {
                task_unlock(c);
+               up_write(&mm->mmap_sem);
                put_task_struct(c);
                goto retry;
        }
        cgroup_mm_owner_callbacks(mm->owner, c);
        mm->owner = c;
        task_unlock(c);
+       up_write(&mm->mmap_sem);
        put_task_struct(c);
  }
  #endif /* CONFIG_MM_OWNER */
@@@ -968,9 -981,12 +981,9 @@@ static void check_stack_usage(void
  {
        static DEFINE_SPINLOCK(low_water_lock);
        static int lowest_to_date = THREAD_SIZE;
 -      unsigned long *n = end_of_stack(current);
        unsigned long free;
  
 -      while (*n == 0)
 -              n++;
 -      free = (unsigned long)n - (unsigned long)end_of_stack(current);
 +      free = stack_not_used(current);
  
        if (free >= lowest_to_date)
                return;
@@@ -1021,8 -1037,6 +1034,6 @@@ NORET_TYPE void do_exit(long code
                 * task into the wait for ever nirwana as well.
                 */
                tsk->flags |= PF_EXITPIDONE;
-               if (tsk->io_context)
-                       exit_io_context();
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule();
        }
                exit_itimers(tsk->signal);
        }
        acct_collect(code, group_dead);
- #ifdef CONFIG_FUTEX
-       if (unlikely(tsk->robust_list))
-               exit_robust_list(tsk);
- #ifdef CONFIG_COMPAT
-       if (unlikely(tsk->compat_robust_list))
-               compat_exit_robust_list(tsk);
- #endif
- #endif
        if (group_dead)
                tty_audit_exit();
        if (unlikely(tsk->audit_context))
  
        if (group_dead)
                acct_process();
+       trace_sched_process_exit(tsk);
        exit_sem(tsk);
        exit_files(tsk);
        exit_fs(tsk);
        check_stack_usage();
        exit_thread();
        cgroup_exit(tsk, 1);
-       exit_keys(tsk);
  
        if (group_dead && tsk->signal->leader)
                disassociate_ctty(1);
        preempt_disable();
        /* causes final put_task_struct in finish_task_switch(). */
        tsk->state = TASK_DEAD;
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
@@@ -1262,12 -1268,12 +1265,12 @@@ static int wait_task_zombie(struct task
        unsigned long state;
        int retval, status, traced;
        pid_t pid = task_pid_vnr(p);
+       uid_t uid = __task_cred(p)->uid;
  
        if (!likely(options & WEXITED))
                return 0;
  
        if (unlikely(options & WNOWAIT)) {
-               uid_t uid = p->uid;
                int exit_code = p->exit_code;
                int why, status;
  
        if (likely(!traced)) {
                struct signal_struct *psig;
                struct signal_struct *sig;
+               struct task_cputime cputime;
  
                /*
                 * The resource counters for the group leader are in its
                 * need to protect the access to p->parent->signal fields,
                 * as other threads in the parent group can be right
                 * here reaping other children at the same time.
+                *
+                * We use thread_group_cputime() to get times for the thread
+                * group, which consolidates times for all threads in the
+                * group including the group leader.
                 */
+               thread_group_cputime(p, &cputime);
                spin_lock_irq(&p->parent->sighand->siglock);
                psig = p->parent->signal;
                sig = p->signal;
                psig->cutime =
                        cputime_add(psig->cutime,
-                       cputime_add(p->utime,
-                       cputime_add(sig->utime,
-                                   sig->cutime)));
+                       cputime_add(cputime.utime,
+                                   sig->cutime));
                psig->cstime =
                        cputime_add(psig->cstime,
-                       cputime_add(p->stime,
-                       cputime_add(sig->stime,
-                                   sig->cstime)));
+                       cputime_add(cputime.stime,
+                                   sig->cstime));
                psig->cgtime =
                        cputime_add(psig->cgtime,
                        cputime_add(p->gtime,
        if (!retval && infop)
                retval = put_user(pid, &infop->si_pid);
        if (!retval && infop)
-               retval = put_user(p->uid, &infop->si_uid);
+               retval = put_user(uid, &infop->si_uid);
        if (!retval)
                retval = pid;
  
@@@ -1449,7 -1459,8 +1456,8 @@@ static int wait_task_stopped(int ptrace
        if (!unlikely(options & WNOWAIT))
                p->exit_code = 0;
  
-       uid = p->uid;
+       /* don't need the RCU readlock here as we're holding a spinlock */
+       uid = __task_cred(p)->uid;
  unlock_sig:
        spin_unlock_irq(&p->sighand->siglock);
        if (!exit_code)
@@@ -1523,10 -1534,10 +1531,10 @@@ static int wait_task_continued(struct t
        }
        if (!unlikely(options & WNOWAIT))
                p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
+       uid = __task_cred(p)->uid;
        spin_unlock_irq(&p->sighand->siglock);
  
        pid = task_pid_vnr(p);
-       uid = p->uid;
        get_task_struct(p);
        read_unlock(&tasklist_lock);
  
@@@ -1672,6 -1683,8 +1680,8 @@@ static long do_wait(enum pid_type type
        struct task_struct *tsk;
        int retval;
  
+       trace_sched_process_wait(pid);
        add_wait_queue(&current->signal->wait_chldexit,&wait);
  repeat:
        /*
diff --combined kernel/fork.c
  #include <linux/jiffies.h>
  #include <linux/tracehook.h>
  #include <linux/futex.h>
+ #include <linux/compat.h>
  #include <linux/task_io_accounting_ops.h>
  #include <linux/rcupdate.h>
  #include <linux/ptrace.h>
  #include <linux/mount.h>
  #include <linux/audit.h>
  #include <linux/memcontrol.h>
+ #include <linux/ftrace.h>
  #include <linux/profile.h>
  #include <linux/rmap.h>
  #include <linux/acct.h>
@@@ -58,7 -60,7 +60,8 @@@
  #include <linux/tty.h>
  #include <linux/proc_fs.h>
  #include <linux/blkdev.h>
+ #include <trace/sched.h>
 +#include <linux/magic.h>
  
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
@@@ -79,6 -81,8 +82,8 @@@ DEFINE_PER_CPU(unsigned long, process_c
  
  __cacheline_aligned DEFINE_RWLOCK(tasklist_lock);  /* outer */
  
+ DEFINE_TRACE(sched_process_fork);
  int nr_processes(void)
  {
        int cpu;
@@@ -136,6 -140,7 +141,7 @@@ void free_task(struct task_struct *tsk
        prop_local_destroy_single(&tsk->dirties);
        free_thread_info(tsk->stack);
        rt_mutex_debug_task_free(tsk);
+       ftrace_graph_exit_task(tsk);
        free_task_struct(tsk);
  }
  EXPORT_SYMBOL(free_task);
@@@ -146,9 -151,8 +152,8 @@@ void __put_task_struct(struct task_stru
        WARN_ON(atomic_read(&tsk->usage));
        WARN_ON(tsk == current);
  
-       security_task_free(tsk);
-       free_uid(tsk->user);
-       put_group_info(tsk->group_info);
+       put_cred(tsk->real_cred);
+       put_cred(tsk->cred);
        delayacct_tsk_free(tsk);
  
        if (!profile_handoff_task(tsk))
@@@ -208,8 -212,6 +213,8 @@@ static struct task_struct *dup_task_str
  {
        struct task_struct *tsk;
        struct thread_info *ti;
 +      unsigned long *stackend;
 +
        int err;
  
        prepare_to_copy(orig);
                goto out;
  
        setup_thread_stack(tsk, orig);
 +      stackend = end_of_stack(tsk);
 +      *stackend = STACK_END_MAGIC;    /* for overflow detection */
  
  #ifdef CONFIG_CC_STACKPROTECTOR
        tsk->stack_canary = get_random_int();
@@@ -318,17 -318,20 +323,20 @@@ static int dup_mmap(struct mm_struct *m
                file = tmp->vm_file;
                if (file) {
                        struct inode *inode = file->f_path.dentry->d_inode;
+                       struct address_space *mapping = file->f_mapping;
                        get_file(file);
                        if (tmp->vm_flags & VM_DENYWRITE)
                                atomic_dec(&inode->i_writecount);
-                       /* insert tmp into the share list, just after mpnt */
-                       spin_lock(&file->f_mapping->i_mmap_lock);
+                       spin_lock(&mapping->i_mmap_lock);
+                       if (tmp->vm_flags & VM_SHARED)
+                               mapping->i_mmap_writable++;
                        tmp->vm_truncate_count = mpnt->vm_truncate_count;
-                       flush_dcache_mmap_lock(file->f_mapping);
+                       flush_dcache_mmap_lock(mapping);
+                       /* insert tmp into the share list, just after mpnt */
                        vma_prio_tree_add(tmp, mpnt);
-                       flush_dcache_mmap_unlock(file->f_mapping);
-                       spin_unlock(&file->f_mapping->i_mmap_lock);
+                       flush_dcache_mmap_unlock(mapping);
+                       spin_unlock(&mapping->i_mmap_lock);
                }
  
                /*
@@@ -412,8 -415,8 +420,8 @@@ static struct mm_struct * mm_init(struc
        set_mm_counter(mm, file_rss, 0);
        set_mm_counter(mm, anon_rss, 0);
        spin_lock_init(&mm->page_table_lock);
-       rwlock_init(&mm->ioctx_list_lock);
-       mm->ioctx_list = NULL;
+       spin_lock_init(&mm->ioctx_lock);
+       INIT_HLIST_HEAD(&mm->ioctx_list);
        mm->free_area_cache = TASK_UNMAPPED_BASE;
        mm->cached_hole_size = ~0UL;
        mm_init_owner(mm, p);
@@@ -523,6 -526,16 +531,16 @@@ void mm_release(struct task_struct *tsk
  {
        struct completion *vfork_done = tsk->vfork_done;
  
+       /* Get rid of any futexes when releasing the mm */
+ #ifdef CONFIG_FUTEX
+       if (unlikely(tsk->robust_list))
+               exit_robust_list(tsk);
+ #ifdef CONFIG_COMPAT
+       if (unlikely(tsk->compat_robust_list))
+               compat_exit_robust_list(tsk);
+ #endif
+ #endif
        /* Get rid of any cached register state */
        deactivate_mm(tsk, mm);
  
@@@ -764,27 -777,50 +782,50 @@@ void __cleanup_sighand(struct sighand_s
                kmem_cache_free(sighand_cachep, sighand);
  }
  
+ /*
+  * Initialize POSIX timer handling for a thread group.
+  */
+ static void posix_cpu_timers_init_group(struct signal_struct *sig)
+ {
+       /* Thread group counters. */
+       thread_group_cputime_init(sig);
+       /* Expiration times and increments. */
+       sig->it_virt_expires = cputime_zero;
+       sig->it_virt_incr = cputime_zero;
+       sig->it_prof_expires = cputime_zero;
+       sig->it_prof_incr = cputime_zero;
+       /* Cached expiration times. */
+       sig->cputime_expires.prof_exp = cputime_zero;
+       sig->cputime_expires.virt_exp = cputime_zero;
+       sig->cputime_expires.sched_exp = 0;
+       /* The timer lists. */
+       INIT_LIST_HEAD(&sig->cpu_timers[0]);
+       INIT_LIST_HEAD(&sig->cpu_timers[1]);
+       INIT_LIST_HEAD(&sig->cpu_timers[2]);
+ }
  static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
  {
        struct signal_struct *sig;
        int ret;
  
        if (clone_flags & CLONE_THREAD) {
-               atomic_inc(&current->signal->count);
-               atomic_inc(&current->signal->live);
-               return 0;
+               ret = thread_group_cputime_clone_thread(current);
+               if (likely(!ret)) {
+                       atomic_inc(&current->signal->count);
+                       atomic_inc(&current->signal->live);
+               }
+               return ret;
        }
        sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
        tsk->signal = sig;
        if (!sig)
                return -ENOMEM;
  
-       ret = copy_thread_group_keys(tsk);
-       if (ret < 0) {
-               kmem_cache_free(signal_cachep, sig);
-               return ret;
-       }
        atomic_set(&sig->count, 1);
        atomic_set(&sig->live, 1);
        init_waitqueue_head(&sig->wait_chldexit);
        sig->it_real_incr.tv64 = 0;
        sig->real_timer.function = it_real_fn;
  
-       sig->it_virt_expires = cputime_zero;
-       sig->it_virt_incr = cputime_zero;
-       sig->it_prof_expires = cputime_zero;
-       sig->it_prof_incr = cputime_zero;
        sig->leader = 0;        /* session leadership doesn't inherit */
        sig->tty_old_pgrp = NULL;
        sig->tty = NULL;
  
-       sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
+       sig->cutime = sig->cstime = cputime_zero;
        sig->gtime = cputime_zero;
        sig->cgtime = cputime_zero;
        sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
        sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
        sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
        task_io_accounting_init(&sig->ioac);
-       sig->sum_sched_runtime = 0;
-       INIT_LIST_HEAD(&sig->cpu_timers[0]);
-       INIT_LIST_HEAD(&sig->cpu_timers[1]);
-       INIT_LIST_HEAD(&sig->cpu_timers[2]);
        taskstats_tgid_init(sig);
  
        task_lock(current->group_leader);
        memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
        task_unlock(current->group_leader);
  
-       if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
-               /*
-                * New sole thread in the process gets an expiry time
-                * of the whole CPU time limit.
-                */
-               tsk->it_prof_expires =
-                       secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
-       }
+       posix_cpu_timers_init_group(sig);
        acct_init_pacct(&sig->pacct);
  
        tty_audit_fork(sig);
  
  void __cleanup_signal(struct signal_struct *sig)
  {
-       exit_thread_group_keys(sig);
+       thread_group_cputime_free(sig);
        tty_kref_put(sig->tty);
        kmem_cache_free(signal_cachep, sig);
  }
@@@ -893,6 -914,19 +919,19 @@@ void mm_init_owner(struct mm_struct *mm
  #endif /* CONFIG_MM_OWNER */
  
  /*
+  * Initialize POSIX timer handling for a single task.
+  */
+ static void posix_cpu_timers_init(struct task_struct *tsk)
+ {
+       tsk->cputime_expires.prof_exp = cputime_zero;
+       tsk->cputime_expires.virt_exp = cputime_zero;
+       tsk->cputime_expires.sched_exp = 0;
+       INIT_LIST_HEAD(&tsk->cpu_timers[0]);
+       INIT_LIST_HEAD(&tsk->cpu_timers[1]);
+       INIT_LIST_HEAD(&tsk->cpu_timers[2]);
+ }
+ /*
   * This creates a new process as a copy of the old one,
   * but does not actually start it yet.
   *
@@@ -946,16 -980,16 +985,16 @@@ static struct task_struct *copy_process
        DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
  #endif
        retval = -EAGAIN;
-       if (atomic_read(&p->user->processes) >=
+       if (atomic_read(&p->real_cred->user->processes) >=
                        p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
                if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-                   p->user != current->nsproxy->user_ns->root_user)
+                   p->real_cred->user != INIT_USER)
                        goto bad_fork_free;
        }
  
-       atomic_inc(&p->user->__count);
-       atomic_inc(&p->user->processes);
-       get_group_info(p->group_info);
+       retval = copy_creds(p, clone_flags);
+       if (retval < 0)
+               goto bad_fork_free;
  
        /*
         * If multiple threads are within copy_process(), then this check
        p->prev_utime = cputime_zero;
        p->prev_stime = cputime_zero;
  
+       p->default_timer_slack_ns = current->timer_slack_ns;
  #ifdef CONFIG_DETECT_SOFTLOCKUP
        p->last_switch_count = 0;
        p->last_switch_timestamp = 0;
        task_io_accounting_init(&p->ioac);
        acct_clear_integrals(p);
  
-       p->it_virt_expires = cputime_zero;
-       p->it_prof_expires = cputime_zero;
-       p->it_sched_expires = 0;
-       INIT_LIST_HEAD(&p->cpu_timers[0]);
-       INIT_LIST_HEAD(&p->cpu_timers[1]);
-       INIT_LIST_HEAD(&p->cpu_timers[2]);
+       posix_cpu_timers_init(p);
  
        p->lock_depth = -1;             /* -1 = no lock */
        do_posix_clock_monotonic_gettime(&p->start_time);
        p->real_start_time = p->start_time;
        monotonic_to_bootbased(&p->real_start_time);
- #ifdef CONFIG_SECURITY
-       p->security = NULL;
- #endif
-       p->cap_bset = current->cap_bset;
        p->io_context = NULL;
        p->audit_context = NULL;
        cgroup_fork(p);
  #ifdef CONFIG_DEBUG_MUTEXES
        p->blocked_on = NULL; /* not blocked yet */
  #endif
+       if (unlikely(ptrace_reparented(current)))
+               ptrace_fork(p, clone_flags);
  
        /* Perform scheduler related setup. Assign this task to a CPU. */
        sched_fork(p, clone_flags);
  
-       if ((retval = security_task_alloc(p)))
-               goto bad_fork_cleanup_policy;
        if ((retval = audit_alloc(p)))
-               goto bad_fork_cleanup_security;
+               goto bad_fork_cleanup_policy;
        /* copy all the process information */
        if ((retval = copy_semundo(clone_flags, p)))
                goto bad_fork_cleanup_audit;
                goto bad_fork_cleanup_sighand;
        if ((retval = copy_mm(clone_flags, p)))
                goto bad_fork_cleanup_signal;
-       if ((retval = copy_keys(clone_flags, p)))
-               goto bad_fork_cleanup_mm;
        if ((retval = copy_namespaces(clone_flags, p)))
-               goto bad_fork_cleanup_keys;
+               goto bad_fork_cleanup_mm;
        if ((retval = copy_io(clone_flags, p)))
                goto bad_fork_cleanup_namespaces;
        retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
                }
        }
  
+       ftrace_graph_init_task(p);
        p->pid = pid_nr(pid);
        p->tgid = p->pid;
        if (clone_flags & CLONE_THREAD)
        if (current->nsproxy != p->nsproxy) {
                retval = ns_cgroup_clone(p, pid);
                if (retval)
-                       goto bad_fork_free_pid;
+                       goto bad_fork_free_graph;
        }
  
        p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
                spin_unlock(&current->sighand->siglock);
                write_unlock_irq(&tasklist_lock);
                retval = -ERESTARTNOINTR;
-               goto bad_fork_free_pid;
+               goto bad_fork_free_graph;
        }
  
        if (clone_flags & CLONE_THREAD) {
                p->group_leader = current->group_leader;
                list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
-               if (!cputime_eq(current->signal->it_virt_expires,
-                               cputime_zero) ||
-                   !cputime_eq(current->signal->it_prof_expires,
-                               cputime_zero) ||
-                   current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY ||
-                   !list_empty(&current->signal->cpu_timers[0]) ||
-                   !list_empty(&current->signal->cpu_timers[1]) ||
-                   !list_empty(&current->signal->cpu_timers[2])) {
-                       /*
-                        * Have child wake up on its first tick to check
-                        * for process CPU timers.
-                        */
-                       p->it_prof_expires = jiffies_to_cputime(1);
-               }
        }
  
        if (likely(p->pid)) {
        cgroup_post_fork(p);
        return p;
  
+ bad_fork_free_graph:
+       ftrace_graph_exit_task(p);
  bad_fork_free_pid:
        if (pid != &init_struct_pid)
                free_pid(pid);
@@@ -1261,8 -1275,6 +1280,6 @@@ bad_fork_cleanup_io
        put_io_context(p->io_context);
  bad_fork_cleanup_namespaces:
        exit_task_namespaces(p);
- bad_fork_cleanup_keys:
-       exit_keys(p);
  bad_fork_cleanup_mm:
        if (p->mm)
                mmput(p->mm);
@@@ -1278,8 -1290,6 +1295,6 @@@ bad_fork_cleanup_semundo
        exit_sem(p);
  bad_fork_cleanup_audit:
        audit_free(p);
- bad_fork_cleanup_security:
-       security_task_free(p);
  bad_fork_cleanup_policy:
  #ifdef CONFIG_NUMA
        mpol_put(p->mempolicy);
@@@ -1292,9 -1302,9 +1307,9 @@@ bad_fork_cleanup_cgroup
  bad_fork_cleanup_put_domain:
        module_put(task_thread_info(p)->exec_domain->module);
  bad_fork_cleanup_count:
-       put_group_info(p->group_info);
-       atomic_dec(&p->user->processes);
-       free_uid(p->user);
+       atomic_dec(&p->cred->user->processes);
+       put_cred(p->real_cred);
+       put_cred(p->cred);
  bad_fork_free:
        free_task(p);
  fork_out:
@@@ -1338,6 -1348,21 +1353,21 @@@ long do_fork(unsigned long clone_flags
        long nr;
  
        /*
+        * Do some preliminary argument and permissions checking before we
+        * actually start allocating stuff
+        */
+       if (clone_flags & CLONE_NEWUSER) {
+               if (clone_flags & CLONE_THREAD)
+                       return -EINVAL;
+               /* hopefully this check will go away when userns support is
+                * complete
+                */
+               if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) ||
+                               !capable(CAP_SETGID))
+                       return -EPERM;
+       }
+       /*
         * We hope to recycle these flags after 2.6.26
         */
        if (unlikely(clone_flags & CLONE_STOPPED)) {
        if (!IS_ERR(p)) {
                struct completion vfork;
  
+               trace_sched_process_fork(current, p);
                nr = task_pid_vnr(p);
  
                if (clone_flags & CLONE_PARENT_SETTID)
                        init_completion(&vfork);
                }
  
+               audit_finish_fork(p);
                tracehook_report_clone(trace, regs, clone_flags, nr, p);
  
                /*
@@@ -1582,8 -1610,7 +1615,7 @@@ asmlinkage long sys_unshare(unsigned lo
        err = -EINVAL;
        if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
                                CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
-                               CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER|
-                               CLONE_NEWNET))
+                               CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET))
                goto bad_unshare_out;
  
        /*
diff --combined kernel/panic.c
  #include <linux/debug_locks.h>
  #include <linux/random.h>
  #include <linux/kallsyms.h>
+ #include <linux/dmi.h>
  
  int panic_on_oops;
int tainted;
static unsigned long tainted_mask;
  static int pause_on_oops;
  static int pause_on_oops_flag;
  static DEFINE_SPINLOCK(pause_on_oops_lock);
@@@ -34,13 -35,6 +35,6 @@@ ATOMIC_NOTIFIER_HEAD(panic_notifier_lis
  
  EXPORT_SYMBOL(panic_notifier_list);
  
- static int __init panic_setup(char *str)
- {
-       panic_timeout = simple_strtoul(str, NULL, 0);
-       return 1;
- }
- __setup("panic=", panic_setup);
  static long no_blink(long time)
  {
        return 0;
@@@ -80,9 -74,6 +74,9 @@@ NORET_TYPE void panic(const char * fmt
        vsnprintf(buf, sizeof(buf), fmt, args);
        va_end(args);
        printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
 +#ifdef CONFIG_DEBUG_BUGVERBOSE
 +      dump_stack();
 +#endif
        bust_spinlocks(0);
  
        /*
  
  EXPORT_SYMBOL(panic);
  
+ struct tnt {
+       u8 bit;
+       char true;
+       char false;
+ };
+ static const struct tnt tnts[] = {
+       { TAINT_PROPRIETARY_MODULE, 'P', 'G' },
+       { TAINT_FORCED_MODULE, 'F', ' ' },
+       { TAINT_UNSAFE_SMP, 'S', ' ' },
+       { TAINT_FORCED_RMMOD, 'R', ' ' },
+       { TAINT_MACHINE_CHECK, 'M', ' ' },
+       { TAINT_BAD_PAGE, 'B', ' ' },
+       { TAINT_USER, 'U', ' ' },
+       { TAINT_DIE, 'D', ' ' },
+       { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
+       { TAINT_WARN, 'W', ' ' },
+       { TAINT_CRAP, 'C', ' ' },
+ };
  /**
   *    print_tainted - return a string to represent the kernel taint state.
   *
   *  'M' - System experienced a machine check exception.
   *  'B' - System has hit bad_page.
   *  'U' - Userspace-defined naughtiness.
+  *  'D' - Kernel has oopsed before
   *  'A' - ACPI table overridden.
   *  'W' - Taint on warning.
+  *  'C' - modules from drivers/staging are loaded.
   *
   *    The string is overwritten by the next call to print_taint().
   */
  const char *print_tainted(void)
  {
-       static char buf[20];
-       if (tainted) {
-               snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c",
-                       tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
-                       tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
-                       tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
-                       tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
-                       tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
-                       tainted & TAINT_BAD_PAGE ? 'B' : ' ',
-                       tainted & TAINT_USER ? 'U' : ' ',
-                       tainted & TAINT_DIE ? 'D' : ' ',
-                       tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ',
-                       tainted & TAINT_WARN ? 'W' : ' ');
-       }
-       else
+       static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1];
+       if (tainted_mask) {
+               char *s;
+               int i;
+               s = buf + sprintf(buf, "Tainted: ");
+               for (i = 0; i < ARRAY_SIZE(tnts); i++) {
+                       const struct tnt *t = &tnts[i];
+                       *s++ = test_bit(t->bit, &tainted_mask) ?
+                                       t->true : t->false;
+               }
+               *s = 0;
+       } else
                snprintf(buf, sizeof(buf), "Not tainted");
        return(buf);
  }
  
void add_taint(unsigned flag)
int test_taint(unsigned flag)
  {
-       debug_locks = 0; /* can't trust the integrity of the kernel anymore */
-       tainted |= flag;
+       return test_bit(flag, &tainted_mask);
+ }
+ EXPORT_SYMBOL(test_taint);
+ unsigned long get_taint(void)
+ {
+       return tainted_mask;
  }
- EXPORT_SYMBOL(add_taint);
  
static int __init pause_on_oops_setup(char *str)
void add_taint(unsigned flag)
  {
-       pause_on_oops = simple_strtoul(str, NULL, 0);
-       return 1;
+       debug_locks = 0; /* can't trust the integrity of the kernel anymore */
+       set_bit(flag, &tainted_mask);
  }
__setup("pause_on_oops=", pause_on_oops_setup);
EXPORT_SYMBOL(add_taint);
  
  static void spin_msec(int msecs)
  {
@@@ -306,36 -322,27 +325,27 @@@ void oops_exit(void
  }
  
  #ifdef WANT_WARN_ON_SLOWPATH
- void warn_on_slowpath(const char *file, int line)
- {
-       char function[KSYM_SYMBOL_LEN];
-       unsigned long caller = (unsigned long) __builtin_return_address(0);
-       sprint_symbol(function, caller);
-       printk(KERN_WARNING "------------[ cut here ]------------\n");
-       printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
-               line, function);
-       print_modules();
-       dump_stack();
-       print_oops_end_marker();
-       add_taint(TAINT_WARN);
- }
- EXPORT_SYMBOL(warn_on_slowpath);
  void warn_slowpath(const char *file, int line, const char *fmt, ...)
  {
        va_list args;
        char function[KSYM_SYMBOL_LEN];
        unsigned long caller = (unsigned long)__builtin_return_address(0);
+       const char *board;
        sprint_symbol(function, caller);
  
        printk(KERN_WARNING "------------[ cut here ]------------\n");
        printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file,
                line, function);
-       va_start(args, fmt);
-       vprintk(fmt, args);
-       va_end(args);
+       board = dmi_get_system_info(DMI_PRODUCT_NAME);
+       if (board)
+               printk(KERN_WARNING "Hardware name: %s\n", board);
+       if (fmt) {
+               va_start(args, fmt);
+               vprintk(fmt, args);
+               va_end(args);
+       }
  
        print_modules();
        dump_stack();
@@@ -346,20 -353,16 +356,23 @@@ EXPORT_SYMBOL(warn_slowpath)
  #endif
  
  #ifdef CONFIG_CC_STACKPROTECTOR
 +
 +#ifndef GCC_HAS_SP
 +#warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this.
 +#endif
 +
  /*
   * Called when gcc's -fstack-protector feature is used, and
   * gcc detects corruption of the on-stack canary value
   */
  void __stack_chk_fail(void)
  {
 -      panic("stack-protector: Kernel stack is corrupted");
 +      panic("stack-protector: Kernel stack is corrupted in: %p\n",
 +              __builtin_return_address(0));
  }
  EXPORT_SYMBOL(__stack_chk_fail);
 +
  #endif
+ core_param(panic, panic_timeout, int, 0644);
+ core_param(pause_on_oops, pause_on_oops, int, 0644);
diff --combined kernel/sched.c
@@@ -55,6 -55,7 +55,7 @@@
  #include <linux/cpuset.h>
  #include <linux/percpu.h>
  #include <linux/kthread.h>
+ #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  #include <linux/sysctl.h>
  #include <linux/syscalls.h>
@@@ -71,6 -72,7 +72,7 @@@
  #include <linux/debugfs.h>
  #include <linux/ctype.h>
  #include <linux/ftrace.h>
+ #include <trace/sched.h>
  
  #include <asm/tlb.h>
  #include <asm/irq_regs.h>
   */
  #define RUNTIME_INF   ((u64)~0ULL)
  
+ DEFINE_TRACE(sched_wait_task);
+ DEFINE_TRACE(sched_wakeup);
+ DEFINE_TRACE(sched_wakeup_new);
+ DEFINE_TRACE(sched_switch);
+ DEFINE_TRACE(sched_migrate_task);
  #ifdef CONFIG_SMP
  /*
   * Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
@@@ -201,7 -209,6 +209,6 @@@ void init_rt_bandwidth(struct rt_bandwi
        hrtimer_init(&rt_b->rt_period_timer,
                        CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        rt_b->rt_period_timer.function = sched_rt_period_timer;
-       rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
  }
  
  static inline int rt_bandwidth_enabled(void)
@@@ -226,9 -233,8 +233,8 @@@ static void start_rt_bandwidth(struct r
  
                now = hrtimer_cb_get_time(&rt_b->rt_period_timer);
                hrtimer_forward(&rt_b->rt_period_timer, now, rt_b->rt_period);
-               hrtimer_start(&rt_b->rt_period_timer,
-                             rt_b->rt_period_timer.expires,
-                             HRTIMER_MODE_ABS);
+               hrtimer_start_expires(&rt_b->rt_period_timer,
+                               HRTIMER_MODE_ABS);
        }
        spin_unlock(&rt_b->rt_runtime_lock);
  }
@@@ -260,6 -266,10 +266,10 @@@ struct task_group 
        struct cgroup_subsys_state css;
  #endif
  
+ #ifdef CONFIG_USER_SCHED
+       uid_t uid;
+ #endif
  #ifdef CONFIG_FAIR_GROUP_SCHED
        /* schedulable entities of this group on each cpu */
        struct sched_entity **se;
  
  #ifdef CONFIG_USER_SCHED
  
+ /* Helper function to pass uid information to create_sched_user() */
+ void set_tg_uid(struct user_struct *user)
+ {
+       user->tg->uid = user->uid;
+ }
  /*
   * Root task group.
   *    Every UID task group (including init_task_group aka UID-0) will
@@@ -344,7 -360,9 +360,9 @@@ static inline struct task_group *task_g
        struct task_group *tg;
  
  #ifdef CONFIG_USER_SCHED
-       tg = p->user->tg;
+       rcu_read_lock();
+       tg = __task_cred(p)->user->tg;
+       rcu_read_unlock();
  #elif defined(CONFIG_CGROUP_SCHED)
        tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
                                struct task_group, css);
@@@ -385,7 -403,6 +403,6 @@@ struct cfs_rq 
  
        u64 exec_clock;
        u64 min_vruntime;
-       u64 pair_start;
  
        struct rb_root tasks_timeline;
        struct rb_node *rb_leftmost;
         * 'curr' points to currently running entity on this cfs_rq.
         * It is set to NULL otherwise (i.e when none are currently running).
         */
-       struct sched_entity *curr, *next;
+       struct sched_entity *curr, *next, *last;
  
-       unsigned long nr_spread_over;
+       unsigned int nr_spread_over;
  
  #ifdef CONFIG_FAIR_GROUP_SCHED
        struct rq *rq;  /* cpu runqueue to which this cfs_rq is attached */
@@@ -586,6 -603,8 +603,8 @@@ struct rq 
  #ifdef CONFIG_SCHEDSTATS
        /* latency stats */
        struct sched_info rq_sched_info;
+       unsigned long long rq_cpu_time;
+       /* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */
  
        /* sys_sched_yield() stats */
        unsigned int yld_exp_empty;
@@@ -703,45 -722,18 +722,18 @@@ static __read_mostly char *sched_feat_n
  
  #undef SCHED_FEAT
  
- static int sched_feat_open(struct inode *inode, struct file *filp)
+ static int sched_feat_show(struct seq_file *m, void *v)
  {
        int i;
  
        for (i = 0; sched_feat_names[i]; i++) {
-               len += strlen(sched_feat_names[i]);
-               len += 4;
+               if (!(sysctl_sched_features & (1UL << i)))
+                       seq_puts(m, "NO_");
+               seq_printf(m, "%s ", sched_feat_names[i]);
        }
+       seq_puts(m, "\n");
  
-       buf = kmalloc(len + 2, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-       for (i = 0; sched_feat_names[i]; i++) {
-               if (sysctl_sched_features & (1UL << i))
-                       r += sprintf(buf + r, "%s ", sched_feat_names[i]);
-               else
-                       r += sprintf(buf + r, "NO_%s ", sched_feat_names[i]);
-       }
-       r += sprintf(buf + r, "\n");
-       WARN_ON(r >= len + 2);
-       r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
-       kfree(buf);
-       return r;
+       return 0;
  }
  
  static ssize_t
@@@ -786,10 -778,17 +778,17 @@@ sched_feat_write(struct file *filp, con
        return cnt;
  }
  
+ static int sched_feat_open(struct inode *inode, struct file *filp)
+ {
+       return single_open(filp, sched_feat_show, NULL);
+ }
  static struct file_operations sched_feat_fops = {
-       .open   = sched_feat_open,
-       .read   = sched_feat_read,
-       .write  = sched_feat_write,
+       .open           = sched_feat_open,
+       .write          = sched_feat_write,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
  };
  
  static __init int sched_init_debug(void)
@@@ -818,6 -817,13 +817,13 @@@ const_debug unsigned int sysctl_sched_n
  unsigned int sysctl_sched_shares_ratelimit = 250000;
  
  /*
+  * Inject some fuzzyness into changing the per-cpu group shares
+  * this avoids remote rq-locks at the expense of fairness.
+  * default: 4
+  */
+ unsigned int sysctl_sched_shares_thresh = 4;
+ /*
   * period over which we measure -rt task cpu usage in us.
   * default: 1s
   */
@@@ -962,6 -968,14 +968,14 @@@ static struct rq *task_rq_lock(struct t
        }
  }
  
+ void task_rq_unlock_wait(struct task_struct *p)
+ {
+       struct rq *rq = task_rq(p);
+       smp_mb(); /* spin-unlock-wait is not a full memory barrier */
+       spin_unlock_wait(&rq->lock);
+ }
  static void __task_rq_unlock(struct rq *rq)
        __releases(rq->lock)
  {
@@@ -1063,7 -1077,7 +1077,7 @@@ static void hrtick_start(struct rq *rq
        struct hrtimer *timer = &rq->hrtick_timer;
        ktime_t time = ktime_add_ns(timer->base->get_time(), delay);
  
-       timer->expires = time;
+       hrtimer_set_expires(timer, time);
  
        if (rq == this_rq()) {
                hrtimer_restart(timer);
@@@ -1124,7 -1138,6 +1138,6 @@@ static void init_rq_hrtick(struct rq *r
  
        hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        rq->hrtick_timer.function = hrtick;
-       rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU;
  }
  #else /* CONFIG_SCHED_HRTICK */
  static inline void hrtick_clear(struct rq *rq)
@@@ -1438,9 -1451,12 +1451,12 @@@ static int task_hot(struct task_struct 
  static unsigned long cpu_avg_load_per_task(int cpu)
  {
        struct rq *rq = cpu_rq(cpu);
+       unsigned long nr_running = ACCESS_ONCE(rq->nr_running);
  
-       if (rq->nr_running)
-               rq->avg_load_per_task = rq->load.weight / rq->nr_running;
+       if (nr_running)
+               rq->avg_load_per_task = rq->load.weight / nr_running;
+       else
+               rq->avg_load_per_task = 0;
  
        return rq->avg_load_per_task;
  }
@@@ -1453,30 -1469,16 +1469,16 @@@ static void __set_se_shares(struct sche
   * Calculate and set the cpu's group shares.
   */
  static void
__update_group_shares_cpu(struct task_group *tg, int cpu,
-                         unsigned long sd_shares, unsigned long sd_rq_weight)
+ update_group_shares_cpu(struct task_group *tg, int cpu,
+                       unsigned long sd_shares, unsigned long sd_rq_weight)
  {
-       int boost = 0;
        unsigned long shares;
        unsigned long rq_weight;
  
        if (!tg->se[cpu])
                return;
  
-       rq_weight = tg->cfs_rq[cpu]->load.weight;
-       /*
-        * If there are currently no tasks on the cpu pretend there is one of
-        * average load so that when a new task gets to run here it will not
-        * get delayed by group starvation.
-        */
-       if (!rq_weight) {
-               boost = 1;
-               rq_weight = NICE_0_LOAD;
-       }
-       if (unlikely(rq_weight > sd_rq_weight))
-               rq_weight = sd_rq_weight;
+       rq_weight = tg->cfs_rq[cpu]->rq_weight;
  
        /*
         *           \Sum shares * rq_weight
         *               \Sum rq_weight
         *
         */
-       shares = (sd_shares * rq_weight) / (sd_rq_weight + 1);
+       shares = (sd_shares * rq_weight) / sd_rq_weight;
+       shares = clamp_t(unsigned long, shares, MIN_SHARES, MAX_SHARES);
  
-       /*
-        * record the actual number of shares, not the boosted amount.
-        */
-       tg->cfs_rq[cpu]->shares = boost ? 0 : shares;
-       tg->cfs_rq[cpu]->rq_weight = rq_weight;
+       if (abs(shares - tg->se[cpu]->load.weight) >
+                       sysctl_sched_shares_thresh) {
+               struct rq *rq = cpu_rq(cpu);
+               unsigned long flags;
  
-       if (shares < MIN_SHARES)
-               shares = MIN_SHARES;
-       else if (shares > MAX_SHARES)
-               shares = MAX_SHARES;
+               spin_lock_irqsave(&rq->lock, flags);
+               tg->cfs_rq[cpu]->shares = shares;
  
-       __set_se_shares(tg->se[cpu], shares);
+               __set_se_shares(tg->se[cpu], shares);
+               spin_unlock_irqrestore(&rq->lock, flags);
+       }
  }
  
  /*
   */
  static int tg_shares_up(struct task_group *tg, void *data)
  {
-       unsigned long rq_weight = 0;
+       unsigned long weight, rq_weight = 0;
        unsigned long shares = 0;
        struct sched_domain *sd = data;
        int i;
  
        for_each_cpu_mask(i, sd->span) {
-               rq_weight += tg->cfs_rq[i]->load.weight;
+               /*
+                * If there are currently no tasks on the cpu pretend there
+                * is one of average load so that when a new task gets to
+                * run here it will not get delayed by group starvation.
+                */
+               weight = tg->cfs_rq[i]->load.weight;
+               if (!weight)
+                       weight = NICE_0_LOAD;
+               tg->cfs_rq[i]->rq_weight = weight;
+               rq_weight += weight;
                shares += tg->cfs_rq[i]->shares;
        }
  
        if (!sd->parent || !(sd->parent->flags & SD_LOAD_BALANCE))
                shares = tg->shares;
  
-       if (!rq_weight)
-               rq_weight = cpus_weight(sd->span) * NICE_0_LOAD;
-       for_each_cpu_mask(i, sd->span) {
-               struct rq *rq = cpu_rq(i);
-               unsigned long flags;
-               spin_lock_irqsave(&rq->lock, flags);
-               __update_group_shares_cpu(tg, i, shares, rq_weight);
-               spin_unlock_irqrestore(&rq->lock, flags);
-       }
+       for_each_cpu_mask(i, sd->span)
+               update_group_shares_cpu(tg, i, shares, rq_weight);
  
        return 0;
  }
@@@ -1596,6 -1599,39 +1599,39 @@@ static inline void update_shares_locked
  
  #endif
  
+ /*
+  * double_lock_balance - lock the busiest runqueue, this_rq is locked already.
+  */
+ static int double_lock_balance(struct rq *this_rq, struct rq *busiest)
+       __releases(this_rq->lock)
+       __acquires(busiest->lock)
+       __acquires(this_rq->lock)
+ {
+       int ret = 0;
+       if (unlikely(!irqs_disabled())) {
+               /* printk() doesn't work good under rq->lock */
+               spin_unlock(&this_rq->lock);
+               BUG_ON(1);
+       }
+       if (unlikely(!spin_trylock(&busiest->lock))) {
+               if (busiest < this_rq) {
+                       spin_unlock(&this_rq->lock);
+                       spin_lock(&busiest->lock);
+                       spin_lock_nested(&this_rq->lock, SINGLE_DEPTH_NESTING);
+                       ret = 1;
+               } else
+                       spin_lock_nested(&busiest->lock, SINGLE_DEPTH_NESTING);
+       }
+       return ret;
+ }
+ static inline void double_unlock_balance(struct rq *this_rq, struct rq *busiest)
+       __releases(busiest->lock)
+ {
+       spin_unlock(&busiest->lock);
+       lock_set_subclass(&this_rq->lock.dep_map, 0, _RET_IP_);
+ }
  #endif
  
  #ifdef CONFIG_FAIR_GROUP_SCHED
@@@ -1800,7 -1836,9 +1836,9 @@@ task_hot(struct task_struct *p, u64 now
        /*
         * Buddy candidates are cache hot:
         */
-       if (sched_feat(CACHE_HOT_BUDDY) && (&p->se == cfs_rq_of(&p->se)->next))
+       if (sched_feat(CACHE_HOT_BUDDY) &&
+                       (&p->se == cfs_rq_of(&p->se)->next ||
+                        &p->se == cfs_rq_of(&p->se)->last))
                return 1;
  
        if (p->sched_class != &fair_sched_class)
@@@ -1827,6 -1865,8 +1865,8 @@@ void set_task_cpu(struct task_struct *p
  
        clock_offset = old_rq->clock - new_rq->clock;
  
+       trace_sched_migrate_task(p, task_cpu(p), new_cpu);
  #ifdef CONFIG_SCHEDSTATS
        if (p->se.wait_start)
                p->se.wait_start -= clock_offset;
@@@ -1936,6 -1976,7 +1976,7 @@@ unsigned long wait_task_inactive(struc
                 * just go back and repeat.
                 */
                rq = task_rq_lock(p, &flags);
+               trace_sched_wait_task(rq, p);
                running = task_running(rq, p);
                on_rq = p->se.on_rq;
                ncsw = 0;
@@@ -2235,6 -2276,7 +2276,7 @@@ static int try_to_wake_up(struct task_s
  
        smp_wmb();
        rq = task_rq_lock(p, &flags);
+       update_rq_clock(rq);
        old_state = p->state;
        if (!(old_state & state))
                goto out;
@@@ -2292,14 -2334,11 +2334,11 @@@ out_activate
                schedstat_inc(p, se.nr_wakeups_local);
        else
                schedstat_inc(p, se.nr_wakeups_remote);
-       update_rq_clock(rq);
        activate_task(rq, p, 1);
        success = 1;
  
  out_running:
-       trace_mark(kernel_sched_wakeup,
-               "pid %d state %ld ## rq %p task %p rq->curr %p",
-               p->pid, p->state, rq, p, rq->curr);
+       trace_sched_wakeup(rq, p, success);
        check_preempt_curr(rq, p, sync);
  
        p->state = TASK_RUNNING;
@@@ -2432,9 -2471,7 +2471,7 @@@ void wake_up_new_task(struct task_struc
                p->sched_class->task_new(rq, p);
                inc_nr_running(rq);
        }
-       trace_mark(kernel_sched_wakeup_new,
-               "pid %d state %ld ## rq %p task %p rq->curr %p",
-               p->pid, p->state, rq, p, rq->curr);
+       trace_sched_wakeup_new(rq, p, 1);
        check_preempt_curr(rq, p, 0);
  #ifdef CONFIG_SMP
        if (p->sched_class->task_wake_up)
@@@ -2607,11 -2644,7 +2644,7 @@@ context_switch(struct rq *rq, struct ta
        struct mm_struct *mm, *oldmm;
  
        prepare_task_switch(rq, prev, next);
-       trace_mark(kernel_sched_schedule,
-               "prev_pid %d next_pid %d prev_state %ld "
-               "## rq %p prev %p next %p",
-               prev->pid, next->pid, prev->state,
-               rq, prev, next);
+       trace_sched_switch(rq, prev, next);
        mm = next->mm;
        oldmm = prev->active_mm;
        /*
@@@ -2801,40 -2834,6 +2834,6 @@@ static void double_rq_unlock(struct rq 
  }
  
  /*
-  * double_lock_balance - lock the busiest runqueue, this_rq is locked already.
-  */
- static int double_lock_balance(struct rq *this_rq, struct rq *busiest)
-       __releases(this_rq->lock)
-       __acquires(busiest->lock)
-       __acquires(this_rq->lock)
- {
-       int ret = 0;
-       if (unlikely(!irqs_disabled())) {
-               /* printk() doesn't work good under rq->lock */
-               spin_unlock(&this_rq->lock);
-               BUG_ON(1);
-       }
-       if (unlikely(!spin_trylock(&busiest->lock))) {
-               if (busiest < this_rq) {
-                       spin_unlock(&this_rq->lock);
-                       spin_lock(&busiest->lock);
-                       spin_lock_nested(&this_rq->lock, SINGLE_DEPTH_NESTING);
-                       ret = 1;
-               } else
-                       spin_lock_nested(&busiest->lock, SINGLE_DEPTH_NESTING);
-       }
-       return ret;
- }
- static void double_unlock_balance(struct rq *this_rq, struct rq *busiest)
-       __releases(busiest->lock)
- {
-       spin_unlock(&busiest->lock);
-       lock_set_subclass(&this_rq->lock.dep_map, 0, _RET_IP_);
- }
- /*
   * If dest_cpu is allowed for this process, migrate the task to it.
   * This is accomplished by forcing the cpu_allowed mask to only
   * allow dest_cpu, which will force the cpu onto dest_cpu. Then
@@@ -3344,7 -3343,7 +3343,7 @@@ small_imbalance
                } else
                        this_load_per_task = cpu_avg_load_per_task(this_cpu);
  
-               if (max_load - this_load + 2*busiest_load_per_task >=
+               if (max_load - this_load + busiest_load_per_task >=
                                        busiest_load_per_task * imbn) {
                        *imbalance = busiest_load_per_task;
                        return busiest;
@@@ -3695,7 -3694,7 +3694,7 @@@ out_balanced
  static void idle_balance(int this_cpu, struct rq *this_rq)
  {
        struct sched_domain *sd;
-       int pulled_task = -1;
+       int pulled_task = 0;
        unsigned long next_balance = jiffies + HZ;
        cpumask_t tmpmask;
  
@@@ -4052,23 -4051,26 +4051,26 @@@ DEFINE_PER_CPU(struct kernel_stat, ksta
  EXPORT_PER_CPU_SYMBOL(kstat);
  
  /*
-  * Return p->sum_exec_runtime plus any more ns on the sched_clock
-  * that have not yet been banked in case the task is currently running.
+  * Return any ns on the sched_clock that have not yet been banked in
+  * @p in case that task is currently running.
   */
- unsigned long long task_sched_runtime(struct task_struct *p)
+ unsigned long long task_delta_exec(struct task_struct *p)
  {
        unsigned long flags;
-       u64 ns, delta_exec;
        struct rq *rq;
+       u64 ns = 0;
  
        rq = task_rq_lock(p, &flags);
-       ns = p->se.sum_exec_runtime;
        if (task_current(rq, p)) {
+               u64 delta_exec;
                update_rq_clock(rq);
                delta_exec = rq->clock - p->se.exec_start;
                if ((s64)delta_exec > 0)
-                       ns += delta_exec;
+                       ns = delta_exec;
        }
        task_rq_unlock(rq, &flags);
  
        return ns;
@@@ -4085,6 -4087,7 +4087,7 @@@ void account_user_time(struct task_stru
        cputime64_t tmp;
  
        p->utime = cputime_add(p->utime, cputime);
+       account_group_user_time(p, cputime);
  
        /* Add user time to cpustat. */
        tmp = cputime_to_cputime64(cputime);
@@@ -4109,6 -4112,7 +4112,7 @@@ static void account_guest_time(struct t
        tmp = cputime_to_cputime64(cputime);
  
        p->utime = cputime_add(p->utime, cputime);
+       account_group_user_time(p, cputime);
        p->gtime = cputime_add(p->gtime, cputime);
  
        cpustat->user = cputime64_add(cpustat->user, tmp);
@@@ -4144,6 -4148,7 +4148,7 @@@ void account_system_time(struct task_st
        }
  
        p->stime = cputime_add(p->stime, cputime);
+       account_group_system_time(p, cputime);
  
        /* Add system time to cpustat. */
        tmp = cputime_to_cputime64(cputime);
@@@ -4320,7 -4325,7 +4325,7 @@@ void __kprobes sub_preempt_count(int va
        /*
         * Underflow?
         */
-       if (DEBUG_LOCKS_WARN_ON(val > preempt_count()))
+        if (DEBUG_LOCKS_WARN_ON(val > preempt_count() - (!!kernel_locked())))
                return;
        /*
         * Is the spinlock portion underflowing?
@@@ -4441,12 -4446,8 +4446,8 @@@ need_resched_nonpreemptible
        if (sched_feat(HRTICK))
                hrtick_clear(rq);
  
-       /*
-        * Do the rq-clock update outside the rq lock:
-        */
-       local_irq_disable();
+       spin_lock_irq(&rq->lock);
        update_rq_clock(rq);
-       spin_lock(&rq->lock);
        clear_tsk_need_resched(prev);
  
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
@@@ -5119,6 -5120,22 +5120,22 @@@ __setscheduler(struct rq *rq, struct ta
        set_load_weight(p);
  }
  
+ /*
+  * check the target process has a UID that matches the current process's
+  */
+ static bool check_same_owner(struct task_struct *p)
+ {
+       const struct cred *cred = current_cred(), *pcred;
+       bool match;
+       rcu_read_lock();
+       pcred = __task_cred(p);
+       match = (cred->euid == pcred->euid ||
+                cred->euid == pcred->uid);
+       rcu_read_unlock();
+       return match;
+ }
  static int __sched_setscheduler(struct task_struct *p, int policy,
                                struct sched_param *param, bool user)
  {
@@@ -5178,8 -5195,7 +5195,7 @@@ recheck
                        return -EPERM;
  
                /* can't change other user's priorities */
-               if ((current->euid != p->euid) &&
-                   (current->euid != p->uid))
+               if (!check_same_owner(p))
                        return -EPERM;
        }
  
@@@ -5411,8 -5427,7 +5427,7 @@@ long sched_setaffinity(pid_t pid, cons
        read_unlock(&tasklist_lock);
  
        retval = -EPERM;
-       if ((current->euid != p->euid) && (current->euid != p->uid) &&
-                       !capable(CAP_SYS_NICE))
+       if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
                goto out_unlock;
  
        retval = security_task_setscheduler(p, 0, NULL);
@@@ -5790,7 -5805,12 +5805,7 @@@ void sched_show_task(struct task_struc
                printk(KERN_CONT " %016lx ", thread_saved_pc(p));
  #endif
  #ifdef CONFIG_DEBUG_STACK_USAGE
 -      {
 -              unsigned long *n = end_of_stack(p);
 -              while (!*n)
 -                      n++;
 -              free = (unsigned long)n - (unsigned long)end_of_stack(p);
 -      }
 +      free = stack_not_used(p);
  #endif
        printk(KERN_CONT "%5lu %5d %6d\n", free,
                task_pid_nr(p), task_pid_nr(p->real_parent));
@@@ -5851,6 -5871,8 +5866,8 @@@ void __cpuinit init_idle(struct task_st
        struct rq *rq = cpu_rq(cpu);
        unsigned long flags;
  
+       spin_lock_irqsave(&rq->lock, flags);
        __sched_fork(idle);
        idle->se.exec_start = sched_clock();
  
        idle->cpus_allowed = cpumask_of_cpu(cpu);
        __set_task_cpu(idle, cpu);
  
-       spin_lock_irqsave(&rq->lock, flags);
        rq->curr = rq->idle = idle;
  #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
        idle->oncpu = 1;
         * The idle tasks have their own, simple scheduling class:
         */
        idle->sched_class = &idle_sched_class;
+       ftrace_graph_init_task(idle);
  }
  
  /*
@@@ -6105,7 -6127,6 +6122,6 @@@ static int __migrate_task_irq(struct ta
  
  /*
   * Figure out where task on dead CPU should go, use force if necessary.
-  * NOTE: interrupts should be disabled by the caller
   */
  static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
  {
@@@ -6566,7 -6587,9 +6582,9 @@@ migration_call(struct notifier_block *n
                        req = list_entry(rq->migration_queue.next,
                                         struct migration_req, list);
                        list_del_init(&req->list);
+                       spin_unlock_irq(&rq->lock);
                        complete(&req->done);
+                       spin_lock_irq(&rq->lock);
                }
                spin_unlock_irq(&rq->lock);
                break;
@@@ -6615,28 -6638,6 +6633,6 @@@ early_initcall(migration_init)
  
  #ifdef CONFIG_SCHED_DEBUG
  
- static inline const char *sd_level_to_string(enum sched_domain_level lvl)
- {
-       switch (lvl) {
-       case SD_LV_NONE:
-                       return "NONE";
-       case SD_LV_SIBLING:
-                       return "SIBLING";
-       case SD_LV_MC:
-                       return "MC";
-       case SD_LV_CPU:
-                       return "CPU";
-       case SD_LV_NODE:
-                       return "NODE";
-       case SD_LV_ALLNODES:
-                       return "ALLNODES";
-       case SD_LV_MAX:
-                       return "MAX";
-       }
-       return "MAX";
- }
  static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level,
                                  cpumask_t *groupmask)
  {
                return -1;
        }
  
-       printk(KERN_CONT "span %s level %s\n",
-               str, sd_level_to_string(sd->level));
+       printk(KERN_CONT "span %s level %s\n", str, sd->name);
  
        if (!cpu_isset(cpu, sd->span)) {
                printk(KERN_ERR "ERROR: domain->span does not contain "
@@@ -6793,6 -6793,8 +6788,8 @@@ sd_parent_degenerate(struct sched_domai
                                SD_BALANCE_EXEC |
                                SD_SHARE_CPUPOWER |
                                SD_SHARE_PKG_RESOURCES);
+               if (nr_node_ids == 1)
+                       pflags &= ~SD_SERIALIZE;
        }
        if (~cflags & pflags)
                return 0;
@@@ -6868,15 -6870,17 +6865,17 @@@ cpu_attach_domain(struct sched_domain *
        struct sched_domain *tmp;
  
        /* Remove the sched domains which do not contribute to scheduling. */
-       for (tmp = sd; tmp; tmp = tmp->parent) {
+       for (tmp = sd; tmp; ) {
                struct sched_domain *parent = tmp->parent;
                if (!parent)
                        break;
                if (sd_parent_degenerate(tmp, parent)) {
                        tmp->parent = parent->parent;
                        if (parent->parent)
                                parent->parent->child = tmp;
-               }
+               } else
+                       tmp = tmp->parent;
        }
  
        if (sd && sd_degenerate(sd)) {
@@@ -7311,13 -7315,21 +7310,21 @@@ struct allmasks 
  };
  
  #if   NR_CPUS > 128
- #define       SCHED_CPUMASK_ALLOC             1
- #define       SCHED_CPUMASK_FREE(v)           kfree(v)
- #define       SCHED_CPUMASK_DECLARE(v)        struct allmasks *v
+ #define SCHED_CPUMASK_DECLARE(v)      struct allmasks *v
+ static inline void sched_cpumask_alloc(struct allmasks **masks)
+ {
+       *masks = kmalloc(sizeof(**masks), GFP_KERNEL);
+ }
+ static inline void sched_cpumask_free(struct allmasks *masks)
+ {
+       kfree(masks);
+ }
  #else
- #define       SCHED_CPUMASK_ALLOC             0
- #define       SCHED_CPUMASK_FREE(v)
- #define       SCHED_CPUMASK_DECLARE(v)        struct allmasks _v, *v = &_v
+ #define SCHED_CPUMASK_DECLARE(v)      struct allmasks _v, *v = &_v
+ static inline void sched_cpumask_alloc(struct allmasks **masks)
+ { }
+ static inline void sched_cpumask_free(struct allmasks *masks)
+ { }
  #endif
  
  #define       SCHED_CPUMASK_VAR(v, a)         cpumask_t *v = (cpumask_t *) \
@@@ -7393,9 -7405,8 +7400,8 @@@ static int __build_sched_domains(const 
                return -ENOMEM;
        }
  
- #if SCHED_CPUMASK_ALLOC
        /* get space for all scratch cpumask variables */
-       allmasks = kmalloc(sizeof(*allmasks), GFP_KERNEL);
+       sched_cpumask_alloc(&allmasks);
        if (!allmasks) {
                printk(KERN_WARNING "Cannot alloc cpumask array\n");
                kfree(rd);
  #endif
                return -ENOMEM;
        }
- #endif
        tmpmask = (cpumask_t *)allmasks;
  
  
                cpu_attach_domain(sd, rd, i);
        }
  
-       SCHED_CPUMASK_FREE((void *)allmasks);
+       sched_cpumask_free(allmasks);
        return 0;
  
  #ifdef CONFIG_NUMA
  error:
        free_sched_groups(cpu_map, tmpmask);
-       SCHED_CPUMASK_FREE((void *)allmasks);
+       sched_cpumask_free(allmasks);
+       kfree(rd);
        return -ENOMEM;
  #endif
  }
@@@ -7686,8 -7698,14 +7693,14 @@@ static struct sched_domain_attr *dattr_
   */
  static cpumask_t fallback_doms;
  
- void __attribute__((weak)) arch_update_cpu_topology(void)
+ /*
+  * arch_update_cpu_topology lets virtualized architectures update the
+  * cpu core maps. It is supposed to return 1 if the topology changed
+  * or 0 if it stayed the same.
+  */
+ int __attribute__((weak)) arch_update_cpu_topology(void)
  {
+       return 0;
  }
  
  /*
@@@ -7727,8 -7745,6 +7740,6 @@@ static void detach_destroy_domains(cons
        cpumask_t tmpmask;
        int i;
  
-       unregister_sched_domain_sysctl();
        for_each_cpu_mask_nr(i, *cpu_map)
                cpu_attach_domain(NULL, &def_root_domain, i);
        synchronize_sched();
@@@ -7766,13 -7782,14 +7777,14 @@@ static int dattrs_equal(struct sched_do
   *
   * The passed in 'doms_new' should be kmalloc'd. This routine takes
   * ownership of it and will kfree it when done with it. If the caller
-  * failed the kmalloc call, then it can pass in doms_new == NULL,
-  * and partition_sched_domains() will fallback to the single partition
-  * 'fallback_doms', it also forces the domains to be rebuilt.
+  * failed the kmalloc call, then it can pass in doms_new == NULL &&
+  * ndoms_new == 1, and partition_sched_domains() will fallback to
+  * the single partition 'fallback_doms', it also forces the domains
+  * to be rebuilt.
   *
-  * If doms_new==NULL it will be replaced with cpu_online_map.
-  * ndoms_new==0 is a special case for destroying existing domains.
-  * It will not create the default domain.
+  * If doms_new == NULL it will be replaced with cpu_online_map.
+  * ndoms_new == 0 is a special case for destroying existing domains,
+  * and it will not create the default domain.
   *
   * Call with hotplug lock held
   */
@@@ -7780,17 -7797,21 +7792,21 @@@ void partition_sched_domains(int ndoms_
                             struct sched_domain_attr *dattr_new)
  {
        int i, j, n;
+       int new_topology;
  
        mutex_lock(&sched_domains_mutex);
  
        /* always unregister in case we don't destroy any domains */
        unregister_sched_domain_sysctl();
  
+       /* Let architecture update cpu core mappings. */
+       new_topology = arch_update_cpu_topology();
        n = doms_new ? ndoms_new : 0;
  
        /* Destroy deleted domains */
        for (i = 0; i < ndoms_cur; i++) {
-               for (j = 0; j < n; j++) {
+               for (j = 0; j < n && !new_topology; j++) {
                        if (cpus_equal(doms_cur[i], doms_new[j])
                            && dattrs_equal(dattr_cur, i, dattr_new, j))
                                goto match1;
@@@ -7805,12 -7826,12 +7821,12 @@@ match1
                ndoms_cur = 0;
                doms_new = &fallback_doms;
                cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
-               dattr_new = NULL;
+               WARN_ON_ONCE(dattr_new);
        }
  
        /* Build new domains */
        for (i = 0; i < ndoms_new; i++) {
-               for (j = 0; j < ndoms_cur; j++) {
+               for (j = 0; j < ndoms_cur && !new_topology; j++) {
                        if (cpus_equal(doms_new[i], doms_cur[j])
                            && dattrs_equal(dattr_new, i, dattr_cur, j))
                                goto match2;
@@@ -8465,7 -8486,7 +8481,7 @@@ stati
  int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
  {
        struct cfs_rq *cfs_rq;
-       struct sched_entity *se, *parent_se;
+       struct sched_entity *se;
        struct rq *rq;
        int i;
  
        for_each_possible_cpu(i) {
                rq = cpu_rq(i);
  
-               cfs_rq = kmalloc_node(sizeof(struct cfs_rq),
-                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
+               cfs_rq = kzalloc_node(sizeof(struct cfs_rq),
+                                     GFP_KERNEL, cpu_to_node(i));
                if (!cfs_rq)
                        goto err;
  
-               se = kmalloc_node(sizeof(struct sched_entity),
-                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
+               se = kzalloc_node(sizeof(struct sched_entity),
+                                 GFP_KERNEL, cpu_to_node(i));
                if (!se)
                        goto err;
  
-               parent_se = parent ? parent->se[i] : NULL;
-               init_tg_cfs_entry(tg, cfs_rq, se, i, 0, parent_se);
+               init_tg_cfs_entry(tg, cfs_rq, se, i, 0, parent->se[i]);
        }
  
        return 1;
@@@ -8553,7 -8573,7 +8568,7 @@@ stati
  int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent)
  {
        struct rt_rq *rt_rq;
-       struct sched_rt_entity *rt_se, *parent_se;
+       struct sched_rt_entity *rt_se;
        struct rq *rq;
        int i;
  
        for_each_possible_cpu(i) {
                rq = cpu_rq(i);
  
-               rt_rq = kmalloc_node(sizeof(struct rt_rq),
-                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
+               rt_rq = kzalloc_node(sizeof(struct rt_rq),
+                                    GFP_KERNEL, cpu_to_node(i));
                if (!rt_rq)
                        goto err;
  
-               rt_se = kmalloc_node(sizeof(struct sched_rt_entity),
-                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
+               rt_se = kzalloc_node(sizeof(struct sched_rt_entity),
+                                    GFP_KERNEL, cpu_to_node(i));
                if (!rt_se)
                        goto err;
  
-               parent_se = parent ? parent->rt_se[i] : NULL;
-               init_tg_rt_entry(tg, rt_rq, rt_se, i, 0, parent_se);
+               init_tg_rt_entry(tg, rt_rq, rt_se, i, 0, parent->rt_se[i]);
        }
  
        return 1;
@@@ -9224,11 -9243,12 +9238,12 @@@ struct cgroup_subsys cpu_cgroup_subsys 
   * (balbir@in.ibm.com).
   */
  
- /* track cpu usage of a group of tasks */
+ /* track cpu usage of a group of tasks and its child groups */
  struct cpuacct {
        struct cgroup_subsys_state css;
        /* cpuusage holds pointer to a u64-type object on every cpu */
        u64 *cpuusage;
+       struct cpuacct *parent;
  };
  
  struct cgroup_subsys cpuacct_subsys;
@@@ -9262,6 -9282,9 +9277,9 @@@ static struct cgroup_subsys_state *cpua
                return ERR_PTR(-ENOMEM);
        }
  
+       if (cgrp->parent)
+               ca->parent = cgroup_ca(cgrp->parent);
        return &ca->css;
  }
  
@@@ -9275,6 -9298,41 +9293,41 @@@ cpuacct_destroy(struct cgroup_subsys *s
        kfree(ca);
  }
  
+ static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu)
+ {
+       u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu);
+       u64 data;
+ #ifndef CONFIG_64BIT
+       /*
+        * Take rq->lock to make 64-bit read safe on 32-bit platforms.
+        */
+       spin_lock_irq(&cpu_rq(cpu)->lock);
+       data = *cpuusage;
+       spin_unlock_irq(&cpu_rq(cpu)->lock);
+ #else
+       data = *cpuusage;
+ #endif
+       return data;
+ }
+ static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val)
+ {
+       u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu);
+ #ifndef CONFIG_64BIT
+       /*
+        * Take rq->lock to make 64-bit write safe on 32-bit platforms.
+        */
+       spin_lock_irq(&cpu_rq(cpu)->lock);
+       *cpuusage = val;
+       spin_unlock_irq(&cpu_rq(cpu)->lock);
+ #else
+       *cpuusage = val;
+ #endif
+ }
  /* return total cpu usage (in nanoseconds) of a group */
  static u64 cpuusage_read(struct cgroup *cgrp, struct cftype *cft)
  {
        u64 totalcpuusage = 0;
        int i;
  
-       for_each_possible_cpu(i) {
-               u64 *cpuusage = percpu_ptr(ca->cpuusage, i);
-               /*
-                * Take rq->lock to make 64-bit addition safe on 32-bit
-                * platforms.
-                */
-               spin_lock_irq(&cpu_rq(i)->lock);
-               totalcpuusage += *cpuusage;
-               spin_unlock_irq(&cpu_rq(i)->lock);
-       }
+       for_each_present_cpu(i)
+               totalcpuusage += cpuacct_cpuusage_read(ca, i);
  
        return totalcpuusage;
  }
@@@ -9309,23 -9358,39 +9353,39 @@@ static int cpuusage_write(struct cgrou
                goto out;
        }
  
-       for_each_possible_cpu(i) {
-               u64 *cpuusage = percpu_ptr(ca->cpuusage, i);
+       for_each_present_cpu(i)
+               cpuacct_cpuusage_write(ca, i, 0);
  
-               spin_lock_irq(&cpu_rq(i)->lock);
-               *cpuusage = 0;
-               spin_unlock_irq(&cpu_rq(i)->lock);
-       }
  out:
        return err;
  }
  
+ static int cpuacct_percpu_seq_read(struct cgroup *cgroup, struct cftype *cft,
+                                  struct seq_file *m)
+ {
+       struct cpuacct *ca = cgroup_ca(cgroup);
+       u64 percpu;
+       int i;
+       for_each_present_cpu(i) {
+               percpu = cpuacct_cpuusage_read(ca, i);
+               seq_printf(m, "%llu ", (unsigned long long) percpu);
+       }
+       seq_printf(m, "\n");
+       return 0;
+ }
  static struct cftype files[] = {
        {
                .name = "usage",
                .read_u64 = cpuusage_read,
                .write_u64 = cpuusage_write,
        },
+       {
+               .name = "usage_percpu",
+               .read_seq_string = cpuacct_percpu_seq_read,
+       },
  };
  
  static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
  static void cpuacct_charge(struct task_struct *tsk, u64 cputime)
  {
        struct cpuacct *ca;
+       int cpu;
  
        if (!cpuacct_subsys.active)
                return;
  
+       cpu = task_cpu(tsk);
        ca = task_ca(tsk);
-       if (ca) {
-               u64 *cpuusage = percpu_ptr(ca->cpuusage, task_cpu(tsk));
  
+       for (; ca; ca = ca->parent) {
+               u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu);
                *cpuusage += cputime;
        }
  }