]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Oct 2012 01:49:08 +0000 (10:49 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Oct 2012 01:49:08 +0000 (10:49 +0900)
Pull pile 2 of execve and kernel_thread unification work from Al Viro:
 "Stuff in there: kernel_thread/kernel_execve/sys_execve conversions for
  several more architectures plus assorted signal fixes and cleanups.

  There'll be more (in particular, real fixes for the alpha
  do_notify_resume() irq mess)..."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (43 commits)
  alpha: don't open-code trace_report_syscall_{enter,exit}
  Uninclude linux/freezer.h
  m32r: trim masks
  avr32: trim masks
  tile: don't bother with SIGTRAP in setup_frame
  microblaze: don't bother with SIGTRAP in setup_rt_frame()
  mn10300: don't bother with SIGTRAP in setup_frame()
  frv: no need to raise SIGTRAP in setup_frame()
  x86: get rid of duplicate code in case of CONFIG_VM86
  unicore32: remove pointless test
  h8300: trim _TIF_WORK_MASK
  parisc: decide whether to go to slow path (tracesys) based on thread flags
  parisc: don't bother looping in do_signal()
  parisc: fix double restarts
  bury the rest of TIF_IRET
  sanitize tsk_is_polling()
  bury _TIF_RESTORE_SIGMASK
  unicore32: unobfuscate _TIF_WORK_MASK
  mips: NOTIFY_RESUME is not needed in TIF masks
  mips: merge the identical "return from syscall" per-ABI code
  ...

Conflicts:
arch/arm/include/asm/thread_info.h

20 files changed:
1  2 
arch/arm/include/asm/thread_info.h
arch/c6x/include/asm/unistd.h
arch/frv/Kconfig
arch/frv/kernel/process.c
arch/ia64/kernel/signal.c
arch/m68k/Kconfig
arch/m68k/kernel/process.c
arch/microblaze/kernel/signal.c
arch/mn10300/kernel/process.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/thread_info.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/process.c
arch/powerpc/kernel/sys_ppc32.c
arch/tile/kernel/compat_signal.c
arch/x86/kernel/entry_32.S
kernel/sched/core.c

index f71cdab18b87589beb5d4df33bcae80483e71536,b2d6b412172d1990cedd5d873a4fdae07bbade67..8477b4c1d39fb3fe43c21691d1ad46846a947e89
@@@ -59,9 -59,7 +59,9 @@@ struct thread_info 
        __u32                   syscall;        /* syscall number */
        __u8                    used_cp[16];    /* thread used copro */
        unsigned long           tp_value;
 +#ifdef CONFIG_CRUNCH
        struct crunch_state     crunchstate;
 +#endif
        union fp_state          fpstate __attribute__((aligned(8)));
        union vfp_state         vfpstate;
  #ifdef CONFIG_ARM_THUMBEE
@@@ -150,8 -148,6 +150,7 @@@ extern int vfp_restore_user_hwstate(str
  #define TIF_NOTIFY_RESUME     2       /* callback before returning to user */
  #define TIF_SYSCALL_TRACE     8
  #define TIF_SYSCALL_AUDIT     9
- #define TIF_POLLING_NRFLAG    16
 +#define TIF_SYSCALL_TRACEPOINT        10
  #define TIF_USING_IWMMXT      17
  #define TIF_MEMDIE            18      /* is terminating due to OOM killer */
  #define TIF_RESTORE_SIGMASK   20
  #define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
  #define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
  #define _TIF_SYSCALL_AUDIT    (1 << TIF_SYSCALL_AUDIT)
- #define _TIF_POLLING_NRFLAG   (1 << TIF_POLLING_NRFLAG)
 +#define _TIF_SYSCALL_TRACEPOINT       (1 << TIF_SYSCALL_TRACEPOINT)
  #define _TIF_USING_IWMMXT     (1 << TIF_USING_IWMMXT)
  #define _TIF_SECCOMP          (1 << TIF_SECCOMP)
  
  /* Checks for any syscall work in entry-common.S */
 -#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
 +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
  
  /*
   * Change these and you break ASM code in entry-common.S
index ed2259043eec278b5a792b0660a326e66e292142,3c131d5888c11253cabb21cce01edbc2df28e25c..4ff747d12dad317e408c86bf8df6285bb31d980b
   *   NON INFRINGEMENT.        See the GNU General Public License for
   *   more details.
   */
 -#if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL)
 -#define _ASM_C6X_UNISTD_H
  
+ #define __ARCH_WANT_KERNEL_EXECVE
+ #define __ARCH_WANT_SYS_EXECVE
  /* Use the standard ABI for syscalls. */
  #include <asm-generic/unistd.h>
  
  /* C6X-specific syscalls. */
  #define __NR_cache_sync       (__NR_arch_specific_syscall + 0)
  __SYSCALL(__NR_cache_sync, sys_cache_sync)
 -
 -#endif /* _ASM_C6X_UNISTD_H */
diff --combined arch/frv/Kconfig
index 9d262645f6675275c9e2c7adca9a66b114d03b88,a27a1c6f84573257d99b019b087c37825767881e..b7412504f08a2c91635c6f75da624a59b6a6a953
@@@ -5,13 -5,12 +5,14 @@@ config FR
        select HAVE_ARCH_TRACEHOOK
        select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
 +      select HAVE_UID16
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_SHOW
 +      select HAVE_DEBUG_BUGVERBOSE
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_CPU_DEVICES
        select ARCH_WANT_IPC_PARSE_VERSION
+       select GENERIC_KERNEL_THREAD
  
  config ZONE_DMA
        bool
index 2eb7fa5bf9d8d48386ea7583dd1731dd92eff7a8,014f855362b9634a38c9cb8cdbc42d64c866cd46..655d90d20bb0cad25df015e7bdc9dee6dbf4e37b
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/reboot.h>
  #include <linux/interrupt.h>
  #include <linux/pagemap.h>
 +#include <linux/rcupdate.h>
  
  #include <asm/asm-offsets.h>
  #include <asm/uaccess.h>
@@@ -38,6 -37,7 +38,7 @@@
  #include "local.h"
  
  asmlinkage void ret_from_fork(void);
+ asmlinkage void ret_from_kernel_thread(void);
  
  #include <asm/pgalloc.h>
  
@@@ -70,14 -70,12 +71,14 @@@ void cpu_idle(void
  {
        /* endless idle loop with no priority at all */
        while (1) {
 +              rcu_idle_enter();
                while (!need_resched()) {
                        check_pgt_cache();
  
                        if (!frv_dma_inprogress && idle)
                                idle();
                }
 +              rcu_idle_exit();
  
                schedule_preempt_disabled();
        }
@@@ -172,32 -170,13 +173,13 @@@ asmlinkage int sys_clone(unsigned long 
   * set up the kernel stack and exception frames for a new process
   */
  int copy_thread(unsigned long clone_flags,
-               unsigned long usp, unsigned long topstk,
+               unsigned long usp, unsigned long arg,
                struct task_struct *p, struct pt_regs *regs)
  {
-       struct pt_regs *childregs0, *childregs, *regs0;
+       struct pt_regs *childregs;
  
-       regs0 = __kernel_frame0_ptr;
-       childregs0 = (struct pt_regs *)
+       childregs = (struct pt_regs *)
                (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
-       childregs = childregs0;
-       /* set up the userspace frame (the only place that the USP is stored) */
-       *childregs0 = *regs0;
-       childregs0->gr8         = 0;
-       childregs0->sp          = usp;
-       childregs0->next_frame  = NULL;
-       /* set up the return kernel frame if called from kernel_thread() */
-       if (regs != regs0) {
-               childregs--;
-               *childregs = *regs;
-               childregs->sp = (unsigned long) childregs0;
-               childregs->next_frame = childregs0;
-               childregs->gr15 = (unsigned long) task_thread_info(p);
-               childregs->gr29 = (unsigned long) p;
-       }
  
        p->set_child_tid = p->clear_child_tid = NULL;
  
        p->thread.sp     = (unsigned long) childregs;
        p->thread.fp     = 0;
        p->thread.lr     = 0;
-       p->thread.pc     = (unsigned long) ret_from_fork;
-       p->thread.frame0 = childregs0;
+       p->thread.frame0 = childregs;
+       if (unlikely(!regs)) {
+               memset(childregs, 0, sizeof(struct pt_regs));
+               childregs->gr9 = usp; /* function */
+               childregs->gr8 = arg;
+               chilregs->psr = PSR_S;
+               p->thread.pc = (unsigned long) ret_from_kernel_thread;
+               save_user_regs(p->thread.user);
+               return 0;
+       }
+       /* set up the userspace frame (the only place that the USP is stored) */
+       *childregs = *regs;
+       childregs->sp           = usp;
+       childregs->next_frame   = NULL;
+       p->thread.pc = (unsigned long) ret_from_fork;
  
        /* the new TLS pointer is passed in as arg #5 to sys_clone() */
        if (clone_flags & CLONE_SETTLS)
        return 0;
  } /* end copy_thread() */
  
- /*
-  * sys_execve() executes a new program.
-  */
- asmlinkage int sys_execve(const char __user *name,
-                         const char __user *const __user *argv,
-                         const char __user *const __user *envp)
- {
-       int error;
-       char * filename;
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, __frame);
-       putname(filename);
-       return error;
- }
  unsigned long get_wchan(struct task_struct *p)
  {
        struct pt_regs *regs0;
index 37dd79511cbeb548c67b4f255ff0b1fcb2c69196,19f89c09d40d756fe52a67978ab228c79e285f2d..680b73786be85077fe2a2424e3ecfd00ebe6ea43
@@@ -220,7 -220,7 +220,7 @@@ ia64_rt_sigreturn (struct sigscratch *s
        si.si_errno = 0;
        si.si_code = SI_KERNEL;
        si.si_pid = task_pid_vnr(current);
 -      si.si_uid = current_uid();
 +      si.si_uid = from_kuid_munged(current_user_ns(), current_uid());
        si.si_addr = sc;
        force_sig_info(SIGSEGV, &si, current);
        return retval;
@@@ -317,7 -317,7 +317,7 @@@ force_sigsegv_info (int sig, void __use
        si.si_errno = 0;
        si.si_code = SI_KERNEL;
        si.si_pid = task_pid_vnr(current);
 -      si.si_uid = current_uid();
 +      si.si_uid = from_kuid_munged(current_user_ns(), current_uid());
        si.si_addr = addr;
        force_sig_info(SIGSEGV, &si, current);
        return 0;
@@@ -437,14 -437,6 +437,6 @@@ ia64_do_signal (struct sigscratch *scr
        long restart = in_syscall;
        long errno = scr->pt.r8;
  
-       /*
-        * In the ia64_leave_kernel code path, we want the common case to go fast, which
-        * is why we may in certain cases get here from kernel mode. Just return without
-        * doing anything if so.
-        */
-       if (!user_mode(&scr->pt))
-               return;
        /*
         * This only loops in the rare cases of handle_signal() failing, in which case we
         * need to push through a forced SIGSEGV.
diff --combined arch/m68k/Kconfig
index dae1e7e16a374d3e100c2f86115181ea2b0006ca,ccda007ba40fae0e0d0fb7e8b18febabb368cc27..76fd6e2f71da1d4c7138f06dfca8a76633eb4336
@@@ -3,11 -3,9 +3,11 @@@ config M68
        default y
        select HAVE_IDE
        select HAVE_AOUT if MMU
 +      select HAVE_DEBUG_BUGVERBOSE
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_SHOW
        select GENERIC_ATOMIC64
 +      select HAVE_UID16
        select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
        select GENERIC_CPU_DEVICES
        select GENERIC_STRNCPY_FROM_USER if MMU
@@@ -15,6 -13,7 +15,7 @@@
        select FPU if MMU
        select ARCH_WANT_IPC_PARSE_VERSION
        select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
+       select GENERIC_KERNEL_THREAD
  
  config RWSEM_GENERIC_SPINLOCK
        bool
index ac2892e49c7c9107734044925caad596e56988bc,4e54b4c0308180bfe14d3de847578fcce9895889..c51bb172e14d774a4dcbea235fc22618de198aba
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/reboot.h>
  #include <linux/init_task.h>
  #include <linux/mqueue.h>
 +#include <linux/rcupdate.h>
  
  #include <asm/uaccess.h>
  #include <asm/traps.h>
@@@ -35,6 -34,7 +35,7 @@@
  
  
  asmlinkage void ret_from_fork(void);
+ asmlinkage void ret_from_kernel_thread(void);
  
  
  /*
@@@ -76,10 -76,8 +77,10 @@@ void cpu_idle(void
  {
        /* endless idle loop with no priority at all */
        while (1) {
 +              rcu_idle_enter();
                while (!need_resched())
                        idle();
 +              rcu_idle_exit();
                schedule_preempt_disabled();
        }
  }
@@@ -123,51 -121,6 +124,6 @@@ void show_regs(struct pt_regs * regs
                printk("USP: %08lx\n", rdusp());
  }
  
- /*
-  * Create a kernel thread
-  */
- int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
-       int pid;
-       mm_segment_t fs;
-       fs = get_fs();
-       set_fs (KERNEL_DS);
-       {
-       register long retval __asm__ ("d0");
-       register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
-       retval = __NR_clone;
-       __asm__ __volatile__
-         ("clrl %%d2\n\t"
-          "trap #0\n\t"                /* Linux/m68k system call */
-          "tstl %0\n\t"                /* child or parent */
-          "jne 1f\n\t"                 /* parent - jump */
- #ifdef CONFIG_MMU
-          "lea %%sp@(%c7),%6\n\t"      /* reload current */
-          "movel %6@,%6\n\t"
- #endif
-          "movel %3,%%sp@-\n\t"        /* push argument */
-          "jsr %4@\n\t"                /* call fn */
-          "movel %0,%%d1\n\t"          /* pass exit value */
-          "movel %2,%%d0\n\t"          /* exit */
-          "trap #0\n"
-          "1:"
-          : "+d" (retval)
-          : "i" (__NR_clone), "i" (__NR_exit),
-            "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
-            "i" (-THREAD_SIZE)
-          : "d2");
-       pid = retval;
-       }
-       set_fs (fs);
-       return pid;
- }
- EXPORT_SYMBOL(kernel_thread);
  void flush_thread(void)
  {
        current->thread.fs = __USER_DS;
@@@ -219,30 -172,18 +175,18 @@@ asmlinkage int m68k_clone(struct pt_reg
  }
  
  int copy_thread(unsigned long clone_flags, unsigned long usp,
-                unsigned long unused,
+                unsigned long arg,
                 struct task_struct * p, struct pt_regs * regs)
  {
        struct pt_regs * childregs;
-       struct switch_stack * childstack, *stack;
-       unsigned long *retp;
+       struct switch_stack *childstack;
  
        childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-       *childregs = *regs;
-       childregs->d0 = 0;
-       retp = ((unsigned long *) regs);
-       stack = ((struct switch_stack *) retp) - 1;
        childstack = ((struct switch_stack *) childregs) - 1;
-       *childstack = *stack;
-       childstack->retpc = (unsigned long)ret_from_fork;
  
        p->thread.usp = usp;
        p->thread.ksp = (unsigned long)childstack;
-       if (clone_flags & CLONE_SETTLS)
-               task_thread_info(p)->tp_value = regs->d5;
+       p->thread.esp0 = (unsigned long)childregs;
  
        /*
         * Must save the current SFC/DFC value, NOT the value when
         */
        p->thread.fs = get_fs().seg;
  
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childstack, 0,
+                       sizeof(struct switch_stack) + sizeof(struct pt_regs));
+               childregs->sr = PS_S;
+               childstack->a3 = usp; /* function */
+               childstack->d7 = arg;
+               childstack->retpc = (unsigned long)ret_from_kernel_thread;
+               p->thread.usp = 0;
+               return 0;
+       }
+       *childregs = *regs;
+       childregs->d0 = 0;
+       *childstack = ((struct switch_stack *) regs)[-1];
+       childstack->retpc = (unsigned long)ret_from_fork;
+       if (clone_flags & CLONE_SETTLS)
+               task_thread_info(p)->tp_value = regs->d5;
  #ifdef CONFIG_FPU
        if (!FPU_IS_EMU) {
                /* Copy the current fpu state */
@@@ -337,26 -298,6 +301,6 @@@ int dump_fpu (struct pt_regs *regs, str
  EXPORT_SYMBOL(dump_fpu);
  #endif /* CONFIG_FPU */
  
- /*
-  * sys_execve() executes a new program.
-  */
- asmlinkage int sys_execve(const char __user *name,
-                         const char __user *const __user *argv,
-                         const char __user *const __user *envp)
- {
-       int error;
-       char * filename;
-       struct pt_regs *regs = (struct pt_regs *) &name;
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, regs);
-       putname(filename);
-       return error;
- }
  unsigned long get_wchan(struct task_struct *p)
  {
        unsigned long fp, pc;
index c1220dbf87cd2726520d9713a6024c1a2fff80c5,0d27fdbb30fdde8ed6ff5407c72561173d718f22..3847e5b9c601f68e189ca21749300b6b7e416415
@@@ -254,10 -254,6 +254,6 @@@ static int setup_rt_frame(int sig, stru
  
        set_fs(USER_DS);
  
-       /* the tracer may want to single-step inside the handler */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
  #ifdef DEBUG_SIG
        printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
                current->comm, current->pid, frame, regs->pc);
@@@ -290,7 -286,15 +286,7 @@@ handle_restart(struct pt_regs *regs, st
        case -ERESTARTNOINTR:
  do_restart:
                /* offset of 4 bytes to re-execute trap (brki) instruction */
 -#ifndef CONFIG_MMU
                regs->pc -= 4;
 -#else
 -              /* offset of 8 bytes required = 4 for rtbd
 -                 offset, plus 4 for size of
 -                      "brki r14,8"
 -                 instruction. */
 -              regs->pc -= 8;
 -#endif
                break;
        }
  }
@@@ -315,7 -319,8 +311,8 @@@ handle_signal(unsigned long sig, struc
        if (ret)
                return;
  
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_delivered(sig, info, ka, regs,
+                       test_thread_flag(TIF_SINGLESTEP));
  }
  
  /*
index e9cceba193b6510f50acd8419a4a2498f82ff64f,8ee09d828c43c58a9168bbbbcc2963f034fa46d4..d0c671b6d9ffc18f687b5d45b99697f891686583
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/err.h>
  #include <linux/fs.h>
  #include <linux/slab.h>
 +#include <linux/rcupdate.h>
  #include <asm/uaccess.h>
  #include <asm/pgtable.h>
  #include <asm/io.h>
@@@ -108,7 -107,6 +108,7 @@@ void cpu_idle(void
  {
        /* endless idle loop with no priority at all */
        for (;;) {
 +              rcu_idle_enter();
                while (!need_resched()) {
                        void (*idle)(void);
  
                        }
                        idle();
                }
 +              rcu_idle_exit();
  
                schedule_preempt_disabled();
        }
@@@ -164,27 -161,6 +164,6 @@@ void show_regs(struct pt_regs *regs
  {
  }
  
- /*
-  * create a kernel thread
-  */
- int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
- {
-       struct pt_regs regs;
-       memset(&regs, 0, sizeof(regs));
-       regs.a2 = (unsigned long) fn;
-       regs.d2 = (unsigned long) arg;
-       regs.pc = (unsigned long) kernel_thread_helper;
-       local_save_flags(regs.epsw);
-       regs.epsw |= EPSW_IE | EPSW_IM_7;
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
-                      NULL, NULL);
- }
- EXPORT_SYMBOL(kernel_thread);
  /*
   * free current thread data structures etc..
   */
@@@ -230,50 -206,42 +209,42 @@@ int copy_thread(unsigned long clone_fla
                struct task_struct *p, struct pt_regs *kregs)
  {
        struct thread_info *ti = task_thread_info(p);
-       struct pt_regs *c_uregs, *c_kregs, *uregs;
+       struct pt_regs *c_regs;
        unsigned long c_ksp;
  
-       uregs = current->thread.uregs;
        c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
  
        /* allocate the userspace exception frame and set it up */
        c_ksp -= sizeof(struct pt_regs);
-       c_uregs = (struct pt_regs *) c_ksp;
+       c_regs = (struct pt_regs *) c_ksp;
+       c_ksp -= 12; /* allocate function call ABI slack */
  
-       p->thread.uregs = c_uregs;
-       *c_uregs = *uregs;
-       c_uregs->sp = c_usp;
-       c_uregs->epsw &= ~EPSW_FE; /* my FPU */
+       /* set up things up so the scheduler can start the new task */
+       p->thread.uregs = c_regs;
+       ti->frame       = c_regs;
+       p->thread.a3    = (unsigned long) c_regs;
+       p->thread.sp    = c_ksp;
+       p->thread.wchan = p->thread.pc;
+       p->thread.usp   = c_usp;
  
-       c_ksp -= 12; /* allocate function call ABI slack */
+       if (unlikely(!kregs)) {
+               memset(c_regs, 0, sizeof(struct pt_regs));
+               c_regs->a0 = c_usp; /* function */
+               c_regs->d0 = ustk_size; /* argument */
+               local_save_flags(c_regs->epsw);
+               c_regs->epsw |= EPSW_IE | EPSW_IM_7;
+               p->thread.pc    = (unsigned long) ret_from_kernel_thread;
+               return 0;
+       }
+       *c_regs = *kregs;
+       c_regs->sp = c_usp;
+       c_regs->epsw &= ~EPSW_FE; /* my FPU */
  
        /* the new TLS pointer is passed in as arg #5 to sys_clone() */
        if (clone_flags & CLONE_SETTLS)
-               c_uregs->e2 = current_frame()->d3;
-       /* set up the return kernel frame if called from kernel_thread() */
-       c_kregs = c_uregs;
-       if (kregs != uregs) {
-               c_ksp -= sizeof(struct pt_regs);
-               c_kregs = (struct pt_regs *) c_ksp;
-               *c_kregs = *kregs;
-               c_kregs->sp = c_usp;
-               c_kregs->next = c_uregs;
- #ifdef CONFIG_MN10300_CURRENT_IN_E2
-               c_kregs->e2 = (unsigned long) p; /* current */
- #endif
-               c_ksp -= 12; /* allocate function call ABI slack */
-       }
+               c_regs->e2 = current_frame()->d3;
  
-       /* set up things up so the scheduler can start the new task */
-       ti->frame       = c_kregs;
-       p->thread.a3    = (unsigned long) c_kregs;
-       p->thread.sp    = c_ksp;
        p->thread.pc    = (unsigned long) ret_from_fork;
-       p->thread.wchan = (unsigned long) ret_from_fork;
-       p->thread.usp   = c_usp;
  
        return 0;
  }
@@@ -302,22 -270,6 +273,6 @@@ asmlinkage long sys_vfork(void
                       current_frame(), 0, NULL, NULL);
  }
  
- asmlinkage long sys_execve(const char __user *name,
-                          const char __user *const __user *argv,
-                          const char __user *const __user *envp)
- {
-       char *filename;
-       int error;
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, current_frame());
-       putname(filename);
-       return error;
- }
  unsigned long get_wchan(struct task_struct *p)
  {
        return p->thread.wchan;
diff --combined arch/powerpc/Kconfig
index df7edb887a04c85be2c53ec9c12540f2a6440b29,6e5a0979c085b9947e395a8a06dd7d3cae15d554..78d6588b6e8622efd2860627b7deb8f0af389be0
@@@ -99,7 -99,6 +99,7 @@@ config PP
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_GRAPH_TRACER
 +      select SYSCTL_EXCEPTION_TRACE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_IDE
        select HAVE_IOREMAP_PROT
        select HAVE_DMA_API_DEBUG
        select USE_GENERIC_SMP_HELPERS if SMP
        select HAVE_OPROFILE
 +      select HAVE_DEBUG_KMEMLEAK
        select HAVE_SYSCALL_WRAPPERS if PPC64
        select GENERIC_ATOMIC64 if PPC32
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select GENERIC_CLOCKEVENTS
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
+       select GENERIC_KERNEL_THREAD
  
  config EARLY_PRINTK
        bool
@@@ -217,8 -216,7 +218,8 @@@ config ARCH_HIBERNATION_POSSIBL
  config ARCH_SUSPEND_POSSIBLE
        def_bool y
        depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
 -                 (PPC_85xx && !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x
 +                 (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \
 +                 || 44x || 40x
  
  config PPC_DCR_NATIVE
        bool
@@@ -242,9 -240,6 +243,9 @@@ config PPC_OF_PLATFORM_PC
  config ARCH_SUPPORTS_DEBUG_PAGEALLOC
        def_bool y
  
 +config ARCH_SUPPORTS_UPROBES
 +      def_bool y
 +
  config PPC_ADV_DEBUG_REGS
        bool
        depends on 40x || BOOKE
@@@ -331,8 -326,7 +332,8 @@@ config SWIOTL
  
  config HOTPLUG_CPU
        bool "Support for enabling/disabling CPUs"
 -      depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV)
 +      depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \
 +      PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
        ---help---
          Say Y here to be able to disable and re-enable individual
          CPUs at runtime on SMP machines.
@@@ -564,14 -558,6 +565,14 @@@ config SCHED_SM
          when dealing with POWER5 cpus at a cost of slightly increased
          overhead in some places. If unsure say N here.
  
 +config PPC_DENORMALISATION
 +      bool "PowerPC denormalisation exception handling"
 +      depends on PPC_BOOK3S_64
 +      default "n"
 +      ---help---
 +        Add support for handling denormalisation of single precision
 +        values.  Useful for bare metal only.  If unsure say Y here.
 +
  config CMDLINE_BOOL
        bool "Default bootloader kernel arguments"
  
index 9dc5cd1fde1a9107614709d1082270361ac71882,5376453d90cc295f216e3db17b17264c22c2d0ce..8734b3855272b3583aa9ba7c723f5e6df01772b1
@@@ -74,9 -74,6 +74,6 @@@ struct task_struct
  void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
  void release_thread(struct task_struct *);
  
- /* Create a new kernel thread. */
- extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
  /* Lazy FPU handling on uni-processor */
  extern struct task_struct *last_task_used_math;
  extern struct task_struct *last_task_used_altivec;
@@@ -97,8 -94,8 +94,8 @@@ extern struct task_struct *last_task_us
  #endif
  
  #ifdef CONFIG_PPC64
 -/* 64-bit user address space is 44-bits (16TB user VM) */
 -#define TASK_SIZE_USER64 (0x0000100000000000UL)
 +/* 64-bit user address space is 46-bits (64TB user VM) */
 +#define TASK_SIZE_USER64 (0x0000400000000000UL)
  
  /* 
   * 32-bit user address space is 4GB - 1 page 
@@@ -219,8 -216,6 +216,8 @@@ struct thread_struct 
  #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  #endif
        unsigned long   dabr;           /* Data address breakpoint register */
 +      unsigned long   dabrx;          /*      ... extension  */
 +      unsigned long   trap_nr;        /* last trap # on this thread */
  #ifdef CONFIG_ALTIVEC
        /* Complete AltiVec register set */
        vector128       vr[32] __attribute__((aligned(16)));
index 8ceea14d6fe44a20d0d807e28a4ca63477f18863,5b1974f651c002c4653d57392364ff56d883f326..406b7b9a13412f3736c369f500a5022e4955a928
@@@ -102,10 -102,7 +102,10 @@@ static inline struct thread_info *curre
  #define TIF_RESTOREALL                11      /* Restore all regs (implies NOERROR) */
  #define TIF_NOERROR           12      /* Force successful syscall return */
  #define TIF_NOTIFY_RESUME     13      /* callback before returning to user */
 +#define TIF_UPROBE            14      /* breakpointed or single-stepping */
  #define TIF_SYSCALL_TRACEPOINT        15      /* syscall tracepoint instrumentation */
 +#define TIF_EMULATE_STACK_STORE       16      /* Is an instruction emulation
 +                                              for stack store? */
  
  /* as above, but as bit values */
  #define _TIF_SYSCALL_TRACE    (1<<TIF_SYSCALL_TRACE)
  #define _TIF_RESTOREALL               (1<<TIF_RESTOREALL)
  #define _TIF_NOERROR          (1<<TIF_NOERROR)
  #define _TIF_NOTIFY_RESUME    (1<<TIF_NOTIFY_RESUME)
 +#define _TIF_UPROBE           (1<<TIF_UPROBE)
  #define _TIF_SYSCALL_TRACEPOINT       (1<<TIF_SYSCALL_TRACEPOINT)
 +#define _TIF_EMULATE_STACK_STORE      (1<<TIF_EMULATE_STACK_STORE)
  #define _TIF_SYSCALL_T_OR_A   (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
                                 _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
  
  #define _TIF_USER_WORK_MASK   (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
 -                               _TIF_NOTIFY_RESUME)
 +                               _TIF_NOTIFY_RESUME | _TIF_UPROBE)
  #define _TIF_PERSYSCALL_MASK  (_TIF_RESTOREALL|_TIF_NOERROR)
  
  /* Bits in local_flags */
@@@ -182,6 -177,8 +182,8 @@@ static inline bool test_thread_local_fl
  #define is_32bit_task()       (1)
  #endif
  
+ #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
  #endif        /* !__ASSEMBLY__ */
  
  #endif /* __KERNEL__ */
index c683fa350add7f5f34547ff88f58233f1724c338,26a6825909b6de44ded64ddb78b4c4e96b0c75c0..2533752af30f75dc63e333e48e7939e40ee85cb0
  #define __ARCH_WANT_COMPAT_SYS_TIME
  #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
  #define __ARCH_WANT_SYS_NEWFSTATAT
 +#define __ARCH_WANT_COMPAT_SYS_SENDFILE
  #endif
+ #define __ARCH_WANT_SYS_EXECVE
+ #define __ARCH_WANT_KERNEL_EXECVE
  
  /*
   * "Conditional" syscalls
index af37528da49fff06ef7b47fb2e9add01dd6b1caa,e6be75fc491aaee5cb91a5caf74075637f79a3db..9499385676e784362c20eade975ae396aaff144d
@@@ -434,6 -434,22 +434,22 @@@ ret_from_fork
        bl      schedule_tail
        li      r3,0
        b       ret_from_syscall
+       .globl  ret_from_kernel_thread
+ ret_from_kernel_thread:
+       REST_NVGPRS(r1)
+       bl      schedule_tail
+       mtlr    r14
+       mr      r3,r15
+       PPC440EP_ERR42
+       blrl
+       li      r3,0
+       b       do_exit         # no return
+       .globl  __ret_from_kernel_execve
+ __ret_from_kernel_execve:
+       addi    r1,r3,-STACK_FRAME_OVERHEAD
+       b       ret_from_syscall
  
  /* Traced system call support */
  syscall_dotrace:
@@@ -831,56 -847,19 +847,56 @@@ restore_user
        bnel-   load_dbcr0
  #endif
  
 -#ifdef CONFIG_PREEMPT
        b       restore
  
  /* N.B. the only way to get here is from the beq following ret_from_except. */
  resume_kernel:
 -      /* check current_thread_info->preempt_count */
 +      /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
        CURRENT_THREAD_INFO(r9, r1)
 +      lwz     r8,TI_FLAGS(r9)
 +      andis.  r8,r8,_TIF_EMULATE_STACK_STORE@h
 +      beq+    1f
 +
 +      addi    r8,r1,INT_FRAME_SIZE    /* Get the kprobed function entry */
 +
 +      lwz     r3,GPR1(r1)
 +      subi    r3,r3,INT_FRAME_SIZE    /* dst: Allocate a trampoline exception frame */
 +      mr      r4,r1                   /* src:  current exception frame */
 +      mr      r1,r3                   /* Reroute the trampoline frame to r1 */
 +
 +      /* Copy from the original to the trampoline. */
 +      li      r5,INT_FRAME_SIZE/4     /* size: INT_FRAME_SIZE */
 +      li      r6,0                    /* start offset: 0 */
 +      mtctr   r5
 +2:    lwzx    r0,r6,r4
 +      stwx    r0,r6,r3
 +      addi    r6,r6,4
 +      bdnz    2b
 +
 +      /* Do real store operation to complete stwu */
 +      lwz     r5,GPR1(r1)
 +      stw     r8,0(r5)
 +
 +      /* Clear _TIF_EMULATE_STACK_STORE flag */
 +      lis     r11,_TIF_EMULATE_STACK_STORE@h
 +      addi    r5,r9,TI_FLAGS
 +0:    lwarx   r8,0,r5
 +      andc    r8,r8,r11
 +#ifdef CONFIG_IBM405_ERR77
 +      dcbt    0,r5
 +#endif
 +      stwcx.  r8,0,r5
 +      bne-    0b
 +1:
 +
 +#ifdef CONFIG_PREEMPT
 +      /* check current_thread_info->preempt_count */
        lwz     r0,TI_PREEMPT(r9)
        cmpwi   0,r0,0          /* if non-zero, just restore regs and return */
        bne     restore
 -      lwz     r0,TI_FLAGS(r9)
 -      andi.   r0,r0,_TIF_NEED_RESCHED
 +      andi.   r8,r8,_TIF_NEED_RESCHED
        beq+    restore
 +      lwz     r3,_MSR(r1)
        andi.   r0,r3,MSR_EE    /* interrupts off? */
        beq     restore         /* don't schedule if so */
  #ifdef CONFIG_TRACE_IRQFLAGS
         */
        bl      trace_hardirqs_on
  #endif
 -#else
 -resume_kernel:
  #endif /* CONFIG_PREEMPT */
  
        /* interrupts are hard-disabled at this point */
index 0e931aaffca20ad2213c1fb0dd2923e409cf75c9,1ca3d9fa48c470b927186b044a5de1abb7d7d10e..56e0ff0878b5534c76b8c93818f7536498ce52df
@@@ -370,6 -370,22 +370,22 @@@ _GLOBAL(ret_from_fork
        li      r3,0
        b       syscall_exit
  
+ _GLOBAL(ret_from_kernel_thread)
+       bl      .schedule_tail
+       REST_NVGPRS(r1)
+       REST_GPR(2,r1)
+       mtlr    r14
+       mr      r3,r15
+       blrl
+       li      r3,0
+       b       .do_exit        # no return
+ _GLOBAL(__ret_from_kernel_execve)
+       addi    r1,r3,-STACK_FRAME_OVERHEAD
+       li      r10,1
+       std     r10,SOFTE(r1)
+       b       syscall_exit
        .section        ".toc","aw"
  DSCR_DEFAULT:
        .tc dscr_default[TC],dscr_default
@@@ -593,41 -609,6 +609,41 @@@ _GLOBAL(ret_from_except_lite
        b       .ret_from_except
  
  resume_kernel:
 +      /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
 +      CURRENT_THREAD_INFO(r9, r1)
 +      ld      r8,TI_FLAGS(r9)
 +      andis.  r8,r8,_TIF_EMULATE_STACK_STORE@h
 +      beq+    1f
 +
 +      addi    r8,r1,INT_FRAME_SIZE    /* Get the kprobed function entry */
 +
 +      lwz     r3,GPR1(r1)
 +      subi    r3,r3,INT_FRAME_SIZE    /* dst: Allocate a trampoline exception frame */
 +      mr      r4,r1                   /* src:  current exception frame */
 +      mr      r1,r3                   /* Reroute the trampoline frame to r1 */
 +
 +      /* Copy from the original to the trampoline. */
 +      li      r5,INT_FRAME_SIZE/8     /* size: INT_FRAME_SIZE */
 +      li      r6,0                    /* start offset: 0 */
 +      mtctr   r5
 +2:    ldx     r0,r6,r4
 +      stdx    r0,r6,r3
 +      addi    r6,r6,8
 +      bdnz    2b
 +
 +      /* Do real store operation to complete stwu */
 +      lwz     r5,GPR1(r1)
 +      std     r8,0(r5)
 +
 +      /* Clear _TIF_EMULATE_STACK_STORE flag */
 +      lis     r11,_TIF_EMULATE_STACK_STORE@h
 +      addi    r5,r9,TI_FLAGS
 +      ldarx   r4,0,r5
 +      andc    r4,r4,r11
 +      stdcx.  r4,0,r5
 +      bne-    0b
 +1:
 +
  #ifdef CONFIG_PREEMPT
        /* Check if we need to preempt */
        andi.   r0,r4,_TIF_NEED_RESCHED
index d5ad666efd8b9a5fde3b93541fb774ae8459881f,6fdf044f475c4f25e9a11b1580e15c05a0c12b30..ba48233500f6d47d7f2a554f5023f23060b5cff2
@@@ -258,7 -258,6 +258,7 @@@ void do_send_trap(struct pt_regs *regs
  {
        siginfo_t info;
  
 +      current->thread.trap_nr = signal_code;
        if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
                        11, SIGSEGV) == NOTIFY_STOP)
                return;
@@@ -276,7 -275,6 +276,7 @@@ void do_dabr(struct pt_regs *regs, unsi
  {
        siginfo_t info;
  
 +      current->thread.trap_nr = TRAP_HWBKPT;
        if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
                        11, SIGSEGV) == NOTIFY_STOP)
                return;
                return;
  
        /* Clear the DABR */
 -      set_dabr(0);
 +      set_dabr(0, 0);
  
        /* Deliver the signal to userspace */
        info.si_signo = SIGTRAP;
@@@ -366,19 -364,18 +366,19 @@@ static void set_debug_reg_defaults(stru
  {
        if (thread->dabr) {
                thread->dabr = 0;
 -              set_dabr(0);
 +              thread->dabrx = 0;
 +              set_dabr(0, 0);
        }
  }
  #endif /* !CONFIG_HAVE_HW_BREAKPOINT */
  #endif        /* CONFIG_PPC_ADV_DEBUG_REGS */
  
 -int set_dabr(unsigned long dabr)
 +int set_dabr(unsigned long dabr, unsigned long dabrx)
  {
        __get_cpu_var(current_dabr) = dabr;
  
        if (ppc_md.set_dabr)
 -              return ppc_md.set_dabr(dabr);
 +              return ppc_md.set_dabr(dabr, dabrx);
  
        /* XXX should we have a CPU_FTR_HAS_DABR ? */
  #ifdef CONFIG_PPC_ADV_DEBUG_REGS
  #endif
  #elif defined(CONFIG_PPC_BOOK3S)
        mtspr(SPRN_DABR, dabr);
 +      mtspr(SPRN_DABRX, dabrx);
  #endif
 -
 -
        return 0;
  }
  
@@@ -482,7 -480,7 +482,7 @@@ struct task_struct *__switch_to(struct 
   */
  #ifndef CONFIG_HAVE_HW_BREAKPOINT
        if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
 -              set_dabr(new->thread.dabr);
 +              set_dabr(new->thread.dabr, new->thread.dabrx);
  #endif /* CONFIG_HAVE_HW_BREAKPOINT */
  #endif
  
  
        local_irq_save(flags);
  
 -      account_system_vtime(current);
 -      account_process_vtime(current);
 -
        /*
         * We can't take a PMU exception inside _switch() since there is a
         * window where the kernel stack SLB and the kernel stack are out
@@@ -733,30 -734,39 +733,39 @@@ int arch_dup_task_struct(struct task_st
  extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
  
  int copy_thread(unsigned long clone_flags, unsigned long usp,
-               unsigned long unused, struct task_struct *p,
+               unsigned long arg, struct task_struct *p,
                struct pt_regs *regs)
  {
        struct pt_regs *childregs, *kregs;
        extern void ret_from_fork(void);
+       extern void ret_from_kernel_thread(void);
+       void (*f)(void);
        unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
  
-       CHECK_FULL_REGS(regs);
        /* Copy registers */
        sp -= sizeof(struct pt_regs);
        childregs = (struct pt_regs *) sp;
-       *childregs = *regs;
-       if ((childregs->msr & MSR_PR) == 0) {
+       if (!regs) {
                /* for kernel thread, set `current' and stackptr in new task */
+               memset(childregs, 0, sizeof(struct pt_regs));
                childregs->gpr[1] = sp + sizeof(struct pt_regs);
- #ifdef CONFIG_PPC32
-               childregs->gpr[2] = (unsigned long) p;
- #else
+ #ifdef CONFIG_PPC64
+               childregs->gpr[14] = *(unsigned long *)usp;
+               childregs->gpr[2] = ((unsigned long *)usp)[1],
                clear_tsk_thread_flag(p, TIF_32BIT);
+ #else
+               childregs->gpr[14] = usp;       /* function */
+               childregs->gpr[2] = (unsigned long) p;
  #endif
+               childregs->gpr[15] = arg;
                p->thread.regs = NULL;  /* no user register state */
+               f = ret_from_kernel_thread;
        } else {
+               CHECK_FULL_REGS(regs);
+               *childregs = *regs;
                childregs->gpr[1] = usp;
                p->thread.regs = childregs;
+               childregs->gpr[3] = 0;  /* Result from fork() */
                if (clone_flags & CLONE_SETTLS) {
  #ifdef CONFIG_PPC64
                        if (!is_32bit_task())
  #endif
                                childregs->gpr[2] = childregs->gpr[6];
                }
+               f = ret_from_fork;
        }
-       childregs->gpr[3] = 0;  /* Result from fork() */
        sp -= STACK_FRAME_OVERHEAD;
  
        /*
                p->thread.dscr = current->thread.dscr;
        }
  #endif
        /*
         * The PPC64 ABI makes use of a TOC to contain function 
         * pointers.  The function (ret_from_except) is actually a pointer
         * to the TOC entry.  The first entry is a pointer to the actual
         * function.
-        */
+        */
  #ifdef CONFIG_PPC64
-       kregs->nip = *((unsigned long *)ret_from_fork);
+       kregs->nip = *((unsigned long *)f);
  #else
-       kregs->nip = (unsigned long)ret_from_fork;
+       kregs->nip = (unsigned long)f;
  #endif
        return 0;
  }
  
@@@ -1055,26 -1064,13 +1063,13 @@@ int sys_vfork(unsigned long p1, unsigne
                        regs, 0, NULL, NULL);
  }
  
- int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-              unsigned long a3, unsigned long a4, unsigned long a5,
-              struct pt_regs *regs)
+ void __ret_from_kernel_execve(struct pt_regs *normal)
+ __noreturn;
+ void ret_from_kernel_execve(struct pt_regs *normal)
  {
-       int error;
-       char *filename;
-       filename = getname((const char __user *) a0);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       flush_fp_to_thread(current);
-       flush_altivec_to_thread(current);
-       flush_spe_to_thread(current);
-       error = do_execve(filename,
-                         (const char __user *const __user *) a1,
-                         (const char __user *const __user *) a2, regs);
-       putname(filename);
- out:
-       return error;
+       set_thread_flag(TIF_RESTOREALL);
+       __ret_from_kernel_execve(normal);
  }
  
  static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
index abd1112da54f40b1b24a08a6a0732373ad95ef0e,a1ae73a0f352857407b38811e62161217cd14e70..9c2ed90ece8f4cdb93b75456f70376b944d52703
@@@ -143,41 -143,50 +143,19 @@@ long compat_sys_ipc(u32 call, u32 first
   * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
   * and the register representation of a signed int (msr in 64-bit mode) is performed.
   */
 -asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
 +asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd,
 +                                          compat_off_t __user *offset, u32 count)
  {
 -      mm_segment_t old_fs = get_fs();
 -      int ret;
 -      off_t of;
 -      off_t __user *up;
 -
 -      if (offset && get_user(of, offset))
 -              return -EFAULT;
 -
 -      /* The __user pointer cast is valid because of the set_fs() */          
 -      set_fs(KERNEL_DS);
 -      up = offset ? (off_t __user *) &of : NULL;
 -      ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
 -      set_fs(old_fs);
 -      
 -      if (offset && put_user(of, offset))
 -              return -EFAULT;
 -              
 -      return ret;
 +      return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
  }
  
 -asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
 +asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
 +                                            compat_loff_t __user *offset, u32 count)
  {
 -      mm_segment_t old_fs = get_fs();
 -      int ret;
 -      loff_t lof;
 -      loff_t __user *up;
 -      
 -      if (offset && get_user(lof, offset))
 -              return -EFAULT;
 -              
 -      /* The __user pointer cast is valid because of the set_fs() */          
 -      set_fs(KERNEL_DS);
 -      up = offset ? (loff_t __user *) &lof : NULL;
 -      ret = sys_sendfile64(out_fd, in_fd, up, count);
 -      set_fs(old_fs);
 -      
 -      if (offset && put_user(lof, offset))
 -              return -EFAULT;
 -              
 -      return ret;
 +      return sys_sendfile((int)out_fd, (int)in_fd,
 +                          (off_t __user *)offset, count);
  }
  
- long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-                 unsigned long a3, unsigned long a4, unsigned long a5,
-                 struct pt_regs *regs)
- {
-       int error;
-       char * filename;
-       
-       filename = getname((char __user *) a0);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       flush_fp_to_thread(current);
-       flush_altivec_to_thread(current);
-       error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
-       putname(filename);
- out:
-       return error;
- }
  /* Note: it is necessary to treat option as an unsigned int, 
   * with the corresponding cast to a signed int to insure that the 
   * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
index 7bc0859a9f5ea688779266c10b967ad9f9a554ed,3690f0199f09af6629f2ed3dd1c18b7805da1725..08b4fe1717bb975aa6edff118fa79f641e77b237
@@@ -55,6 -55,63 +55,6 @@@ struct compat_ucontext 
        sigset_t          uc_sigmask;   /* mask last for extensibility */
  };
  
 -#define COMPAT_SI_PAD_SIZE    ((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int))
 -
 -struct compat_siginfo {
 -      int si_signo;
 -      int si_errno;
 -      int si_code;
 -
 -      union {
 -              int _pad[COMPAT_SI_PAD_SIZE];
 -
 -              /* kill() */
 -              struct {
 -                      unsigned int _pid;      /* sender's pid */
 -                      unsigned int _uid;      /* sender's uid */
 -              } _kill;
 -
 -              /* POSIX.1b timers */
 -              struct {
 -                      compat_timer_t _tid;    /* timer id */
 -                      int _overrun;           /* overrun count */
 -                      compat_sigval_t _sigval;        /* same as below */
 -                      int _sys_private;       /* not to be passed to user */
 -                      int _overrun_incr;      /* amount to add to overrun */
 -              } _timer;
 -
 -              /* POSIX.1b signals */
 -              struct {
 -                      unsigned int _pid;      /* sender's pid */
 -                      unsigned int _uid;      /* sender's uid */
 -                      compat_sigval_t _sigval;
 -              } _rt;
 -
 -              /* SIGCHLD */
 -              struct {
 -                      unsigned int _pid;      /* which child */
 -                      unsigned int _uid;      /* sender's uid */
 -                      int _status;            /* exit code */
 -                      compat_clock_t _utime;
 -                      compat_clock_t _stime;
 -              } _sigchld;
 -
 -              /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 -              struct {
 -                      unsigned int _addr;     /* faulting insn/memory ref. */
 -#ifdef __ARCH_SI_TRAPNO
 -                      int _trapno;    /* TRAP # which caused the signal */
 -#endif
 -              } _sigfault;
 -
 -              /* SIGPOLL */
 -              struct {
 -                      int _band;      /* POLL_IN, POLL_OUT, POLL_MSG */
 -                      int _fd;
 -              } _sigpoll;
 -      } _sifields;
 -};
 -
  struct compat_rt_sigframe {
        unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
        struct compat_siginfo info;
@@@ -354,15 -411,6 +354,6 @@@ int compat_setup_rt_frame(int sig, stru
        regs->regs[1] = ptr_to_compat_reg(&frame->info);
        regs->regs[2] = ptr_to_compat_reg(&frame->uc);
        regs->flags |= PT_FLAGS_CALLER_SAVES;
-       /*
-        * Notify any tracer that was single-stepping it.
-        * The tracer may want to single-step inside the
-        * handler too.
-        */
-       if (test_thread_flag(TIF_SINGLESTEP))
-               ptrace_notify(SIGTRAP);
        return 0;
  
  give_sigsegv:
index 8f9ed1afde8f28565a9e9325e4ecc3f61a3fc089,fe4cc305d8da959885762c46997a174f55c2718b..2c6340796fe99b7374b545649e89cbc96996bd44
@@@ -57,7 -57,6 +57,7 @@@
  #include <asm/cpufeature.h>
  #include <asm/alternative-asm.h>
  #include <asm/asm.h>
 +#include <asm/smap.h>
  
  /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
  #include <linux/elf-em.h>
@@@ -414,9 -413,7 +414,9 @@@ sysenter_past_esp
   */
        cmpl $__PAGE_OFFSET-3,%ebp
        jae syscall_fault
 +      ASM_STAC
  1:    movl (%ebp),%ebp
 +      ASM_CLAC
        movl %ebp,PT_EBP(%esp)
        _ASM_EXTABLE(1b,syscall_fault)
  
@@@ -497,7 -494,6 +497,7 @@@ ENDPROC(ia32_sysenter_target
        # system call handler stub
  ENTRY(system_call)
        RING0_INT_FRAME                 # can't unwind into user space anyway
 +      ASM_CLAC
        pushl_cfi %eax                  # save orig_eax
        SAVE_ALL
        GET_THREAD_INFO(%ebp)
@@@ -622,6 -618,10 +622,10 @@@ work_notifysig:                          # deal with pending 
        movl %esp, %eax
        jne work_notifysig_v86          # returning to kernel-space or
                                        # vm86-space
+ 1:
+ #else
+       movl %esp, %eax
+ #endif
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
        movb PT_CS(%esp), %bl
        call do_notify_resume
        jmp resume_userspace
  
+ #ifdef CONFIG_VM86
        ALIGN
  work_notifysig_v86:
        pushl_cfi %ecx                  # save ti_flags for do_notify_resume
        call save_v86_state             # %eax contains pt_regs pointer
        popl_cfi %ecx
        movl %eax, %esp
- #else
-       movl %esp, %eax
+       jmp 1b
  #endif
-       TRACE_IRQS_ON
-       ENABLE_INTERRUPTS(CLBR_NONE)
-       movb PT_CS(%esp), %bl
-       andb $SEGMENT_RPL_MASK, %bl
-       cmpb $USER_RPL, %bl
-       jb resume_kernel
-       xorl %edx, %edx
-       call do_notify_resume
-       jmp resume_userspace
  END(work_pending)
  
        # perform syscall exit tracing
@@@ -680,7 -671,6 +675,7 @@@ END(syscall_exit_work
  
        RING0_INT_FRAME                 # can't unwind into user space anyway
  syscall_fault:
 +      ASM_CLAC
        GET_THREAD_INFO(%ebp)
        movl $-EFAULT,PT_EAX(%esp)
        jmp resume_userspace
@@@ -835,7 -825,6 +830,7 @@@ END(interrupt
   */
        .p2align CONFIG_X86_L1_CACHE_SHIFT
  common_interrupt:
 +      ASM_CLAC
        addl $-0x80,(%esp)      /* Adjust vector into the [-256,-1] range */
        SAVE_ALL
        TRACE_IRQS_OFF
@@@ -852,7 -841,6 +847,7 @@@ ENDPROC(common_interrupt
  #define BUILD_INTERRUPT3(name, nr, fn)        \
  ENTRY(name)                           \
        RING0_INT_FRAME;                \
 +      ASM_CLAC;                       \
        pushl_cfi $~(nr);               \
        SAVE_ALL;                       \
        TRACE_IRQS_OFF                  \
@@@ -869,7 -857,6 +864,7 @@@ ENDPROC(name
  
  ENTRY(coprocessor_error)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_coprocessor_error
        jmp error_code
@@@ -878,7 -865,6 +873,7 @@@ END(coprocessor_error
  
  ENTRY(simd_coprocessor_error)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
  #ifdef CONFIG_X86_INVD_BUG
        /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
@@@ -900,7 -886,6 +895,7 @@@ END(simd_coprocessor_error
  
  ENTRY(device_not_available)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $-1                   # mark this as an int
        pushl_cfi $do_device_not_available
        jmp error_code
@@@ -921,7 -906,6 +916,7 @@@ END(native_irq_enable_sysexit
  
  ENTRY(overflow)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_overflow
        jmp error_code
@@@ -930,7 -914,6 +925,7 @@@ END(overflow
  
  ENTRY(bounds)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_bounds
        jmp error_code
@@@ -939,7 -922,6 +934,7 @@@ END(bounds
  
  ENTRY(invalid_op)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_invalid_op
        jmp error_code
@@@ -948,7 -930,6 +943,7 @@@ END(invalid_op
  
  ENTRY(coprocessor_segment_overrun)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_coprocessor_segment_overrun
        jmp error_code
@@@ -957,7 -938,6 +952,7 @@@ END(coprocessor_segment_overrun
  
  ENTRY(invalid_TSS)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_invalid_TSS
        jmp error_code
        CFI_ENDPROC
@@@ -965,7 -945,6 +960,7 @@@ END(invalid_TSS
  
  ENTRY(segment_not_present)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_segment_not_present
        jmp error_code
        CFI_ENDPROC
@@@ -973,7 -952,6 +968,7 @@@ END(segment_not_present
  
  ENTRY(stack_segment)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_stack_segment
        jmp error_code
        CFI_ENDPROC
@@@ -981,7 -959,6 +976,7 @@@ END(stack_segment
  
  ENTRY(alignment_check)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_alignment_check
        jmp error_code
        CFI_ENDPROC
@@@ -989,7 -966,6 +984,7 @@@ END(alignment_check
  
  ENTRY(divide_error)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0                    # no error code
        pushl_cfi $do_divide_error
        jmp error_code
@@@ -999,7 -975,6 +994,7 @@@ END(divide_error
  #ifdef CONFIG_X86_MCE
  ENTRY(machine_check)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi machine_check_vector
        jmp error_code
@@@ -1009,7 -984,6 +1004,7 @@@ END(machine_check
  
  ENTRY(spurious_interrupt_bug)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_spurious_interrupt_bug
        jmp error_code
@@@ -1140,21 -1114,17 +1135,21 @@@ ENTRY(ftrace_caller
        pushl %eax
        pushl %ecx
        pushl %edx
 -      movl 0xc(%esp), %eax
 +      pushl $0        /* Pass NULL as regs pointer */
 +      movl 4*4(%esp), %eax
        movl 0x4(%ebp), %edx
 +      leal function_trace_op, %ecx
        subl $MCOUNT_INSN_SIZE, %eax
  
  .globl ftrace_call
  ftrace_call:
        call ftrace_stub
  
 +      addl $4,%esp    /* skip NULL pointer */
        popl %edx
        popl %ecx
        popl %eax
 +ftrace_ret:
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  .globl ftrace_graph_call
  ftrace_graph_call:
@@@ -1166,71 -1136,6 +1161,71 @@@ ftrace_stub
        ret
  END(ftrace_caller)
  
 +ENTRY(ftrace_regs_caller)
 +      pushf   /* push flags before compare (in cs location) */
 +      cmpl $0, function_trace_stop
 +      jne ftrace_restore_flags
 +
 +      /*
 +       * i386 does not save SS and ESP when coming from kernel.
 +       * Instead, to get sp, &regs->sp is used (see ptrace.h).
 +       * Unfortunately, that means eflags must be at the same location
 +       * as the current return ip is. We move the return ip into the
 +       * ip location, and move flags into the return ip location.
 +       */
 +      pushl 4(%esp)   /* save return ip into ip slot */
 +
 +      pushl $0        /* Load 0 into orig_ax */
 +      pushl %gs
 +      pushl %fs
 +      pushl %es
 +      pushl %ds
 +      pushl %eax
 +      pushl %ebp
 +      pushl %edi
 +      pushl %esi
 +      pushl %edx
 +      pushl %ecx
 +      pushl %ebx
 +
 +      movl 13*4(%esp), %eax   /* Get the saved flags */
 +      movl %eax, 14*4(%esp)   /* Move saved flags into regs->flags location */
 +                              /* clobbering return ip */
 +      movl $__KERNEL_CS,13*4(%esp)
 +
 +      movl 12*4(%esp), %eax   /* Load ip (1st parameter) */
 +      subl $MCOUNT_INSN_SIZE, %eax    /* Adjust ip */
 +      movl 0x4(%ebp), %edx    /* Load parent ip (2nd parameter) */
 +      leal function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */
 +      pushl %esp              /* Save pt_regs as 4th parameter */
 +
 +GLOBAL(ftrace_regs_call)
 +      call ftrace_stub
 +
 +      addl $4, %esp           /* Skip pt_regs */
 +      movl 14*4(%esp), %eax   /* Move flags back into cs */
 +      movl %eax, 13*4(%esp)   /* Needed to keep addl from modifying flags */
 +      movl 12*4(%esp), %eax   /* Get return ip from regs->ip */
 +      movl %eax, 14*4(%esp)   /* Put return ip back for ret */
 +
 +      popl %ebx
 +      popl %ecx
 +      popl %edx
 +      popl %esi
 +      popl %edi
 +      popl %ebp
 +      popl %eax
 +      popl %ds
 +      popl %es
 +      popl %fs
 +      popl %gs
 +      addl $8, %esp           /* Skip orig_ax and ip */
 +      popf                    /* Pop flags at end (no addl to corrupt flags) */
 +      jmp ftrace_ret
 +
 +ftrace_restore_flags:
 +      popf
 +      jmp  ftrace_stub
  #else /* ! CONFIG_DYNAMIC_FTRACE */
  
  ENTRY(mcount)
@@@ -1271,6 -1176,9 +1266,6 @@@ END(mcount
  
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  ENTRY(ftrace_graph_caller)
 -      cmpl $0, function_trace_stop
 -      jne ftrace_stub
 -
        pushl %eax
        pushl %ecx
        pushl %edx
@@@ -1304,7 -1212,6 +1299,7 @@@ return_to_handler
  
  ENTRY(page_fault)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_page_fault
        ALIGN
  error_code:
@@@ -1377,7 -1284,6 +1372,7 @@@ END(page_fault
  
  ENTRY(debug)
        RING0_INT_FRAME
 +      ASM_CLAC
        cmpl $ia32_sysenter_target,(%esp)
        jne debug_stack_correct
        FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
@@@ -1402,7 -1308,6 +1397,7 @@@ END(debug
   */
  ENTRY(nmi)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi %eax
        movl %ss, %eax
        cmpw $__ESPFIX_SS, %ax
@@@ -1473,7 -1378,6 +1468,7 @@@ END(nmi
  
  ENTRY(int3)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $-1                   # mark this as an int
        SAVE_ALL
        TRACE_IRQS_OFF
@@@ -1494,7 -1398,6 +1489,7 @@@ END(general_protection
  #ifdef CONFIG_KVM_GUEST
  ENTRY(async_page_fault)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_async_page_fault
        jmp error_code
        CFI_ENDPROC
diff --combined kernel/sched/core.c
index c1774723643838ea565a9419838bc0509ee48353,9dcf93c24d10758715f6755b9e470cdbcb91510d..bd7c39450b1b160714e9abc2f690a7ac3e086739
@@@ -505,7 -505,7 +505,7 @@@ static inline void init_hrtick(void
  #ifdef CONFIG_SMP
  
  #ifndef tsk_is_polling
- #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+ #define tsk_is_polling(t) 0
  #endif
  
  void resched_task(struct task_struct *p)
@@@ -740,6 -740,126 +740,6 @@@ void deactivate_task(struct rq *rq, str
        dequeue_task(rq, p, flags);
  }
  
 -#ifdef CONFIG_IRQ_TIME_ACCOUNTING
 -
 -/*
 - * There are no locks covering percpu hardirq/softirq time.
 - * They are only modified in account_system_vtime, on corresponding CPU
 - * with interrupts disabled. So, writes are safe.
 - * They are read and saved off onto struct rq in update_rq_clock().
 - * This may result in other CPU reading this CPU's irq time and can
 - * race with irq/account_system_vtime on this CPU. We would either get old
 - * or new value with a side effect of accounting a slice of irq time to wrong
 - * task when irq is in progress while we read rq->clock. That is a worthy
 - * compromise in place of having locks on each irq in account_system_time.
 - */
 -static DEFINE_PER_CPU(u64, cpu_hardirq_time);
 -static DEFINE_PER_CPU(u64, cpu_softirq_time);
 -
 -static DEFINE_PER_CPU(u64, irq_start_time);
 -static int sched_clock_irqtime;
 -
 -void enable_sched_clock_irqtime(void)
 -{
 -      sched_clock_irqtime = 1;
 -}
 -
 -void disable_sched_clock_irqtime(void)
 -{
 -      sched_clock_irqtime = 0;
 -}
 -
 -#ifndef CONFIG_64BIT
 -static DEFINE_PER_CPU(seqcount_t, irq_time_seq);
 -
 -static inline void irq_time_write_begin(void)
 -{
 -      __this_cpu_inc(irq_time_seq.sequence);
 -      smp_wmb();
 -}
 -
 -static inline void irq_time_write_end(void)
 -{
 -      smp_wmb();
 -      __this_cpu_inc(irq_time_seq.sequence);
 -}
 -
 -static inline u64 irq_time_read(int cpu)
 -{
 -      u64 irq_time;
 -      unsigned seq;
 -
 -      do {
 -              seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu));
 -              irq_time = per_cpu(cpu_softirq_time, cpu) +
 -                         per_cpu(cpu_hardirq_time, cpu);
 -      } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq));
 -
 -      return irq_time;
 -}
 -#else /* CONFIG_64BIT */
 -static inline void irq_time_write_begin(void)
 -{
 -}
 -
 -static inline void irq_time_write_end(void)
 -{
 -}
 -
 -static inline u64 irq_time_read(int cpu)
 -{
 -      return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu);
 -}
 -#endif /* CONFIG_64BIT */
 -
 -/*
 - * Called before incrementing preempt_count on {soft,}irq_enter
 - * and before decrementing preempt_count on {soft,}irq_exit.
 - */
 -void account_system_vtime(struct task_struct *curr)
 -{
 -      unsigned long flags;
 -      s64 delta;
 -      int cpu;
 -
 -      if (!sched_clock_irqtime)
 -              return;
 -
 -      local_irq_save(flags);
 -
 -      cpu = smp_processor_id();
 -      delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time);
 -      __this_cpu_add(irq_start_time, delta);
 -
 -      irq_time_write_begin();
 -      /*
 -       * We do not account for softirq time from ksoftirqd here.
 -       * We want to continue accounting softirq time to ksoftirqd thread
 -       * in that case, so as not to confuse scheduler with a special task
 -       * that do not consume any time, but still wants to run.
 -       */
 -      if (hardirq_count())
 -              __this_cpu_add(cpu_hardirq_time, delta);
 -      else if (in_serving_softirq() && curr != this_cpu_ksoftirqd())
 -              __this_cpu_add(cpu_softirq_time, delta);
 -
 -      irq_time_write_end();
 -      local_irq_restore(flags);
 -}
 -EXPORT_SYMBOL_GPL(account_system_vtime);
 -
 -#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 -
 -#ifdef CONFIG_PARAVIRT
 -static inline u64 steal_ticks(u64 steal)
 -{
 -      if (unlikely(steal > NSEC_PER_SEC))
 -              return div_u64(steal, TICK_NSEC);
 -
 -      return __iter_div_u64_rem(steal, TICK_NSEC, &steal);
 -}
 -#endif
 -
  static void update_rq_clock_task(struct rq *rq, s64 delta)
  {
  /*
  #endif
  }
  
 -#ifdef CONFIG_IRQ_TIME_ACCOUNTING
 -static int irqtime_account_hi_update(void)
 -{
 -      u64 *cpustat = kcpustat_this_cpu->cpustat;
 -      unsigned long flags;
 -      u64 latest_ns;
 -      int ret = 0;
 -
 -      local_irq_save(flags);
 -      latest_ns = this_cpu_read(cpu_hardirq_time);
 -      if (nsecs_to_cputime64(latest_ns) > cpustat[CPUTIME_IRQ])
 -              ret = 1;
 -      local_irq_restore(flags);
 -      return ret;
 -}
 -
 -static int irqtime_account_si_update(void)
 -{
 -      u64 *cpustat = kcpustat_this_cpu->cpustat;
 -      unsigned long flags;
 -      u64 latest_ns;
 -      int ret = 0;
 -
 -      local_irq_save(flags);
 -      latest_ns = this_cpu_read(cpu_softirq_time);
 -      if (nsecs_to_cputime64(latest_ns) > cpustat[CPUTIME_SOFTIRQ])
 -              ret = 1;
 -      local_irq_restore(flags);
 -      return ret;
 -}
 -
 -#else /* CONFIG_IRQ_TIME_ACCOUNTING */
 -
 -#define sched_clock_irqtime   (0)
 -
 -#endif
 -
  void sched_set_stop_task(int cpu, struct task_struct *stop)
  {
        struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
@@@ -1361,6 -1518,25 +1361,6 @@@ static void ttwu_queue_remote(struct ta
                smp_send_reschedule(cpu);
  }
  
 -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
 -static int ttwu_activate_remote(struct task_struct *p, int wake_flags)
 -{
 -      struct rq *rq;
 -      int ret = 0;
 -
 -      rq = __task_rq_lock(p);
 -      if (p->on_cpu) {
 -              ttwu_activate(rq, p, ENQUEUE_WAKEUP);
 -              ttwu_do_wakeup(rq, p, wake_flags);
 -              ret = 1;
 -      }
 -      __task_rq_unlock(rq);
 -
 -      return ret;
 -
 -}
 -#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
 -
  bool cpus_share_cache(int this_cpu, int that_cpu)
  {
        return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
@@@ -1421,8 -1597,21 +1421,8 @@@ try_to_wake_up(struct task_struct *p, u
         * If the owning (remote) cpu is still in the middle of schedule() with
         * this task as prev, wait until its done referencing the task.
         */
 -      while (p->on_cpu) {
 -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
 -              /*
 -               * In case the architecture enables interrupts in
 -               * context_switch(), we cannot busy wait, since that
 -               * would lead to deadlocks when an interrupt hits and
 -               * tries to wake up @prev. So bail and do a complete
 -               * remote wakeup.
 -               */
 -              if (ttwu_activate_remote(p, wake_flags))
 -                      goto stat;
 -#else
 +      while (p->on_cpu)
                cpu_relax();
 -#endif
 -      }
        /*
         * Pairs with the smp_wmb() in finish_lock_switch().
         */
@@@ -1764,9 -1953,14 +1764,9 @@@ static void finish_task_switch(struct r
         *              Manfred Spraul <manfred@colorfullife.com>
         */
        prev_state = prev->state;
 +      vtime_task_switch(prev);
        finish_arch_switch(prev);
 -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
 -      local_irq_disable();
 -#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
        perf_event_task_sched_in(prev, current);
 -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
 -      local_irq_enable();
 -#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
        finish_lock_switch(rq, prev);
        finish_arch_post_lock_switch();
  
@@@ -1887,7 -2081,6 +1887,7 @@@ context_switch(struct rq *rq, struct ta
  #endif
  
        /* Here we just switch the register state and the stack. */
 +      rcu_switch(prev, next);
        switch_to(prev, next, prev);
  
        barrier();
@@@ -2616,6 -2809,404 +2616,6 @@@ unsigned long long task_sched_runtime(s
        return ns;
  }
  
 -#ifdef CONFIG_CGROUP_CPUACCT
 -struct cgroup_subsys cpuacct_subsys;
 -struct cpuacct root_cpuacct;
 -#endif
 -
 -static inline void task_group_account_field(struct task_struct *p, int index,
 -                                          u64 tmp)
 -{
 -#ifdef CONFIG_CGROUP_CPUACCT
 -      struct kernel_cpustat *kcpustat;
 -      struct cpuacct *ca;
 -#endif
 -      /*
 -       * Since all updates are sure to touch the root cgroup, we
 -       * get ourselves ahead and touch it first. If the root cgroup
 -       * is the only cgroup, then nothing else should be necessary.
 -       *
 -       */
 -      __get_cpu_var(kernel_cpustat).cpustat[index] += tmp;
 -
 -#ifdef CONFIG_CGROUP_CPUACCT
 -      if (unlikely(!cpuacct_subsys.active))
 -              return;
 -
 -      rcu_read_lock();
 -      ca = task_ca(p);
 -      while (ca && (ca != &root_cpuacct)) {
 -              kcpustat = this_cpu_ptr(ca->cpustat);
 -              kcpustat->cpustat[index] += tmp;
 -              ca = parent_ca(ca);
 -      }
 -      rcu_read_unlock();
 -#endif
 -}
 -
 -
 -/*
 - * Account user cpu time to a process.
 - * @p: the process that the cpu time gets accounted to
 - * @cputime: the cpu time spent in user space since the last update
 - * @cputime_scaled: cputime scaled by cpu frequency
 - */
 -void account_user_time(struct task_struct *p, cputime_t cputime,
 -                     cputime_t cputime_scaled)
 -{
 -      int index;
 -
 -      /* Add user time to process. */
 -      p->utime += cputime;
 -      p->utimescaled += cputime_scaled;
 -      account_group_user_time(p, cputime);
 -
 -      index = (TASK_NICE(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
 -
 -      /* Add user time to cpustat. */
 -      task_group_account_field(p, index, (__force u64) cputime);
 -
 -      /* Account for user time used */
 -      acct_update_integrals(p);
 -}
 -
 -/*
 - * Account guest cpu time to a process.
 - * @p: the process that the cpu time gets accounted to
 - * @cputime: the cpu time spent in virtual machine since the last update
 - * @cputime_scaled: cputime scaled by cpu frequency
 - */
 -static void account_guest_time(struct task_struct *p, cputime_t cputime,
 -                             cputime_t cputime_scaled)
 -{
 -      u64 *cpustat = kcpustat_this_cpu->cpustat;
 -
 -      /* Add guest time to process. */
 -      p->utime += cputime;
 -      p->utimescaled += cputime_scaled;
 -      account_group_user_time(p, cputime);
 -      p->gtime += cputime;
 -
 -      /* Add guest time to cpustat. */
 -      if (TASK_NICE(p) > 0) {
 -              cpustat[CPUTIME_NICE] += (__force u64) cputime;
 -              cpustat[CPUTIME_GUEST_NICE] += (__force u64) cputime;
 -      } else {
 -              cpustat[CPUTIME_USER] += (__force u64) cputime;
 -              cpustat[CPUTIME_GUEST] += (__force u64) cputime;
 -      }
 -}
 -
 -/*
 - * Account system cpu time to a process and desired cpustat field
 - * @p: the process that the cpu time gets accounted to
 - * @cputime: the cpu time spent in kernel space since the last update
 - * @cputime_scaled: cputime scaled by cpu frequency
 - * @target_cputime64: pointer to cpustat field that has to be updated
 - */
 -static inline
 -void __account_system_time(struct task_struct *p, cputime_t cputime,
 -                      cputime_t cputime_scaled, int index)
 -{
 -      /* Add system time to process. */
 -      p->stime += cputime;
 -      p->stimescaled += cputime_scaled;
 -      account_group_system_time(p, cputime);
 -
 -      /* Add system time to cpustat. */
 -      task_group_account_field(p, index, (__force u64) cputime);
 -
 -      /* Account for system time used */
 -      acct_update_integrals(p);
 -}
 -
 -/*
 - * Account system cpu time to a process.
 - * @p: the process that the cpu time gets accounted to
 - * @hardirq_offset: the offset to subtract from hardirq_count()
 - * @cputime: the cpu time spent in kernel space since the last update
 - * @cputime_scaled: cputime scaled by cpu frequency
 - */
 -void account_system_time(struct task_struct *p, int hardirq_offset,
 -                       cputime_t cputime, cputime_t cputime_scaled)
 -{
 -      int index;
 -
 -      if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
 -              account_guest_time(p, cputime, cputime_scaled);
 -              return;
 -      }
 -
 -      if (hardirq_count() - hardirq_offset)
 -              index = CPUTIME_IRQ;
 -      else if (in_serving_softirq())
 -              index = CPUTIME_SOFTIRQ;
 -      else
 -              index = CPUTIME_SYSTEM;
 -
 -      __account_system_time(p, cputime, cputime_scaled, index);
 -}
 -
 -/*
 - * Account for involuntary wait time.
 - * @cputime: the cpu time spent in involuntary wait
 - */
 -void account_steal_time(cputime_t cputime)
 -{
 -      u64 *cpustat = kcpustat_this_cpu->cpustat;
 -
 -      cpustat[CPUTIME_STEAL] += (__force u64) cputime;
 -}
 -
 -/*
 - * Account for idle time.
 - * @cputime: the cpu time spent in idle wait
 - */
 -void account_idle_time(cputime_t cputime)
 -{
 -      u64 *cpustat = kcpustat_this_cpu->cpustat;
 -      struct rq *rq = this_rq();
 -
 -      if (atomic_read(&rq->nr_iowait) > 0)
 -              cpustat[CPUTIME_IOWAIT] += (__force u64) cputime;
 -      else
 -              cpustat[CPUTIME_IDLE] += (__force u64) cputime;
 -}
 -
 -static __always_inline bool steal_account_process_tick(void)
 -{
 -#ifdef CONFIG_PARAVIRT
 -      if (static_key_false(&paravirt_steal_enabled)) {
 -              u64 steal, st = 0;
 -
 -              steal = paravirt_steal_clock(smp_processor_id());
 -              steal -= this_rq()->prev_steal_time;
 -
 -              st = steal_ticks(steal);
 -              this_rq()->prev_steal_time += st * TICK_NSEC;
 -
 -              account_steal_time(st);
 -              return st;
 -      }
 -#endif
 -      return false;
 -}
 -
 -#ifndef CONFIG_VIRT_CPU_ACCOUNTING
 -
 -#ifdef CONFIG_IRQ_TIME_ACCOUNTING
 -/*
 - * Account a tick to a process and cpustat
 - * @p: the process that the cpu time gets accounted to
 - * @user_tick: is the tick from userspace
 - * @rq: the pointer to rq
 - *
 - * Tick demultiplexing follows the order
 - * - pending hardirq update
 - * - pending softirq update
 - * - user_time
 - * - idle_time
 - * - system time
 - *   - check for guest_time
 - *   - else account as system_time
 - *
 - * Check for hardirq is done both for system and user time as there is
 - * no timer going off while we are on hardirq and hence we may never get an
 - * opportunity to update it solely in system time.
 - * p->stime and friends are only updated on system time and not on irq
 - * softirq as those do not count in task exec_runtime any more.
 - */
 -static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
 -                                              struct rq *rq)
 -{
 -      cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy);
 -      u64 *cpustat = kcpustat_this_cpu->cpustat;
 -
 -      if (steal_account_process_tick())
 -              return;
 -
 -      if (irqtime_account_hi_update()) {
 -              cpustat[CPUTIME_IRQ] += (__force u64) cputime_one_jiffy;
 -      } else if (irqtime_account_si_update()) {
 -              cpustat[CPUTIME_SOFTIRQ] += (__force u64) cputime_one_jiffy;
 -      } else if (this_cpu_ksoftirqd() == p) {
 -              /*
 -               * ksoftirqd time do not get accounted in cpu_softirq_time.
 -               * So, we have to handle it separately here.
 -               * Also, p->stime needs to be updated for ksoftirqd.
 -               */
 -              __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled,
 -                                      CPUTIME_SOFTIRQ);
 -      } else if (user_tick) {
 -              account_user_time(p, cputime_one_jiffy, one_jiffy_scaled);
 -      } else if (p == rq->idle) {
 -              account_idle_time(cputime_one_jiffy);
 -      } else if (p->flags & PF_VCPU) { /* System time or guest time */
 -              account_guest_time(p, cputime_one_jiffy, one_jiffy_scaled);
 -      } else {
 -              __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled,
 -                                      CPUTIME_SYSTEM);
 -      }
 -}
 -
 -static void irqtime_account_idle_ticks(int ticks)
 -{
 -      int i;
 -      struct rq *rq = this_rq();
 -
 -      for (i = 0; i < ticks; i++)
 -              irqtime_account_process_tick(current, 0, rq);
 -}
 -#else /* CONFIG_IRQ_TIME_ACCOUNTING */
 -static void irqtime_account_idle_ticks(int ticks) {}
 -static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
 -                                              struct rq *rq) {}
 -#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 -
 -/*
 - * Account a single tick of cpu time.
 - * @p: the process that the cpu time gets accounted to
 - * @user_tick: indicates if the tick is a user or a system tick
 - */
 -void account_process_tick(struct task_struct *p, int user_tick)
 -{
 -      cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy);
 -      struct rq *rq = this_rq();
 -
 -      if (sched_clock_irqtime) {
 -              irqtime_account_process_tick(p, user_tick, rq);
 -              return;
 -      }
 -
 -      if (steal_account_process_tick())
 -              return;
 -
 -      if (user_tick)
 -              account_user_time(p, cputime_one_jiffy, one_jiffy_scaled);
 -      else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET))
 -              account_system_time(p, HARDIRQ_OFFSET, cputime_one_jiffy,
 -                                  one_jiffy_scaled);
 -      else
 -              account_idle_time(cputime_one_jiffy);
 -}
 -
 -/*
 - * Account multiple ticks of steal time.
 - * @p: the process from which the cpu time has been stolen
 - * @ticks: number of stolen ticks
 - */
 -void account_steal_ticks(unsigned long ticks)
 -{
 -      account_steal_time(jiffies_to_cputime(ticks));
 -}
 -
 -/*
 - * Account multiple ticks of idle time.
 - * @ticks: number of stolen ticks
 - */
 -void account_idle_ticks(unsigned long ticks)
 -{
 -
 -      if (sched_clock_irqtime) {
 -              irqtime_account_idle_ticks(ticks);
 -              return;
 -      }
 -
 -      account_idle_time(jiffies_to_cputime(ticks));
 -}
 -
 -#endif
 -
 -/*
 - * Use precise platform statistics if available:
 - */
 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING
 -void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 -{
 -      *ut = p->utime;
 -      *st = p->stime;
 -}
 -
 -void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 -{
 -      struct task_cputime cputime;
 -
 -      thread_group_cputime(p, &cputime);
 -
 -      *ut = cputime.utime;
 -      *st = cputime.stime;
 -}
 -#else
 -
 -#ifndef nsecs_to_cputime
 -# define nsecs_to_cputime(__nsecs)    nsecs_to_jiffies(__nsecs)
 -#endif
 -
 -static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total)
 -{
 -      u64 temp = (__force u64) rtime;
 -
 -      temp *= (__force u64) utime;
 -
 -      if (sizeof(cputime_t) == 4)
 -              temp = div_u64(temp, (__force u32) total);
 -      else
 -              temp = div64_u64(temp, (__force u64) total);
 -
 -      return (__force cputime_t) temp;
 -}
 -
 -void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 -{
 -      cputime_t rtime, utime = p->utime, total = utime + p->stime;
 -
 -      /*
 -       * Use CFS's precise accounting:
 -       */
 -      rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
 -
 -      if (total)
 -              utime = scale_utime(utime, rtime, total);
 -      else
 -              utime = rtime;
 -
 -      /*
 -       * Compare with previous values, to keep monotonicity:
 -       */
 -      p->prev_utime = max(p->prev_utime, utime);
 -      p->prev_stime = max(p->prev_stime, rtime - p->prev_utime);
 -
 -      *ut = p->prev_utime;
 -      *st = p->prev_stime;
 -}
 -
 -/*
 - * Must be called with siglock held.
 - */
 -void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 -{
 -      struct signal_struct *sig = p->signal;
 -      struct task_cputime cputime;
 -      cputime_t rtime, utime, total;
 -
 -      thread_group_cputime(p, &cputime);
 -
 -      total = cputime.utime + cputime.stime;
 -      rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
 -
 -      if (total)
 -              utime = scale_utime(cputime.utime, rtime, total);
 -      else
 -              utime = rtime;
 -
 -      sig->prev_utime = max(sig->prev_utime, utime);
 -      sig->prev_stime = max(sig->prev_stime, rtime - sig->prev_utime);
 -
 -      *ut = sig->prev_utime;
 -      *st = sig->prev_stime;
 -}
 -#endif
 -
  /*
   * This function gets called by the timer code, with HZ frequency.
   * We call it with interrupts disabled.
@@@ -2776,40 -3367,6 +2776,40 @@@ pick_next_task(struct rq *rq
  
  /*
   * __schedule() is the main scheduler function.
 + *
 + * The main means of driving the scheduler and thus entering this function are:
 + *
 + *   1. Explicit blocking: mutex, semaphore, waitqueue, etc.
 + *
 + *   2. TIF_NEED_RESCHED flag is checked on interrupt and userspace return
 + *      paths. For example, see arch/x86/entry_64.S.
 + *
 + *      To drive preemption between tasks, the scheduler sets the flag in timer
 + *      interrupt handler scheduler_tick().
 + *
 + *   3. Wakeups don't really cause entry into schedule(). They add a
 + *      task to the run-queue and that's it.
 + *
 + *      Now, if the new task added to the run-queue preempts the current
 + *      task, then the wakeup sets TIF_NEED_RESCHED and schedule() gets
 + *      called on the nearest possible occasion:
 + *
 + *       - If the kernel is preemptible (CONFIG_PREEMPT=y):
 + *
 + *         - in syscall or exception context, at the next outmost
 + *           preempt_enable(). (this might be as soon as the wake_up()'s
 + *           spin_unlock()!)
 + *
 + *         - in IRQ context, return from interrupt-handler to
 + *           preemptible context
 + *
 + *       - If the kernel is not preemptible (CONFIG_PREEMPT is not set)
 + *         then at the next:
 + *
 + *          - cond_resched() call
 + *          - explicit schedule() call
 + *          - return from syscall or exception to user-space
 + *          - return from interrupt-handler to user-space
   */
  static void __sched __schedule(void)
  {
@@@ -2911,21 -3468,6 +2911,21 @@@ asmlinkage void __sched schedule(void
  }
  EXPORT_SYMBOL(schedule);
  
 +#ifdef CONFIG_RCU_USER_QS
 +asmlinkage void __sched schedule_user(void)
 +{
 +      /*
 +       * If we come here after a random call to set_need_resched(),
 +       * or we have been woken up remotely but the IPI has not yet arrived,
 +       * we haven't yet exited the RCU idle mode. Do it here manually until
 +       * we find a better solution.
 +       */
 +      rcu_user_exit();
 +      schedule();
 +      rcu_user_enter();
 +}
 +#endif
 +
  /**
   * schedule_preempt_disabled - called with preemption disabled
   *
@@@ -3027,7 -3569,6 +3027,7 @@@ asmlinkage void __sched preempt_schedul
        /* Catch callers which need to be fixed */
        BUG_ON(ti->preempt_count || !irqs_disabled());
  
 +      rcu_user_exit();
        do {
                add_preempt_count(PREEMPT_ACTIVE);
                local_irq_enable();
@@@ -4327,6 -4868,13 +4327,6 @@@ again
                 */
                if (preempt && rq != p_rq)
                        resched_task(p_rq->curr);
 -      } else {
 -              /*
 -               * We might have set it in task_yield_fair(), but are
 -               * not going to schedule(), so don't want to skip
 -               * the next update.
 -               */
 -              rq->skip_clock_update = 0;
        }
  
  out:
@@@ -4868,25 -5416,16 +4868,25 @@@ static void sd_free_ctl_entry(struct ct
        *tablep = NULL;
  }
  
 +static int min_load_idx = 0;
 +static int max_load_idx = CPU_LOAD_IDX_MAX;
 +
  static void
  set_table_entry(struct ctl_table *entry,
                const char *procname, void *data, int maxlen,
 -              umode_t mode, proc_handler *proc_handler)
 +              umode_t mode, proc_handler *proc_handler,
 +              bool load_idx)
  {
        entry->procname = procname;
        entry->data = data;
        entry->maxlen = maxlen;
        entry->mode = mode;
        entry->proc_handler = proc_handler;
 +
 +      if (load_idx) {
 +              entry->extra1 = &min_load_idx;
 +              entry->extra2 = &max_load_idx;
 +      }
  }
  
  static struct ctl_table *
@@@ -4898,30 -5437,30 +4898,30 @@@ sd_alloc_ctl_domain_table(struct sched_
                return NULL;
  
        set_table_entry(&table[0], "min_interval", &sd->min_interval,
 -              sizeof(long), 0644, proc_doulongvec_minmax);
 +              sizeof(long), 0644, proc_doulongvec_minmax, false);
        set_table_entry(&table[1], "max_interval", &sd->max_interval,
 -              sizeof(long), 0644, proc_doulongvec_minmax);
 +              sizeof(long), 0644, proc_doulongvec_minmax, false);
        set_table_entry(&table[2], "busy_idx", &sd->busy_idx,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, true);
        set_table_entry(&table[3], "idle_idx", &sd->idle_idx,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, true);
        set_table_entry(&table[4], "newidle_idx", &sd->newidle_idx,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, true);
        set_table_entry(&table[5], "wake_idx", &sd->wake_idx,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, true);
        set_table_entry(&table[6], "forkexec_idx", &sd->forkexec_idx,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, true);
        set_table_entry(&table[7], "busy_factor", &sd->busy_factor,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, false);
        set_table_entry(&table[8], "imbalance_pct", &sd->imbalance_pct,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, false);
        set_table_entry(&table[9], "cache_nice_tries",
                &sd->cache_nice_tries,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, false);
        set_table_entry(&table[10], "flags", &sd->flags,
 -              sizeof(int), 0644, proc_dointvec_minmax);
 +              sizeof(int), 0644, proc_dointvec_minmax, false);
        set_table_entry(&table[11], "name", sd->name,
 -              CORENAME_MAX_SIZE, 0444, proc_dostring);
 +              CORENAME_MAX_SIZE, 0444, proc_dostring, false);
        /* &table[12] is terminator */
  
        return table;
@@@ -5065,9 -5604,7 +5065,9 @@@ migration_call(struct notifier_block *n
                migrate_tasks(cpu);
                BUG_ON(rq->nr_running != 1); /* the migration thread */
                raw_spin_unlock_irqrestore(&rq->lock, flags);
 +              break;
  
 +      case CPU_DEAD:
                calc_load_migrate(rq);
                break;
  #endif
@@@ -6000,6 -6537,7 +6000,6 @@@ sd_numa_init(struct sched_domain_topolo
                                        | 0*SD_BALANCE_FORK
                                        | 0*SD_BALANCE_WAKE
                                        | 0*SD_WAKE_AFFINE
 -                                      | 0*SD_PREFER_LOCAL
                                        | 0*SD_SHARE_CPUPOWER
                                        | 0*SD_SHARE_PKG_RESOURCES
                                        | 1*SD_SERIALIZE
@@@ -7797,8 -8335,6 +7797,8 @@@ struct cgroup_subsys cpu_cgroup_subsys 
   * (balbir@in.ibm.com).
   */
  
 +struct cpuacct root_cpuacct;
 +
  /* create a new cpu accounting group */
  static struct cgroup_subsys_state *cpuacct_create(struct cgroup *cgrp)
  {