]> rtime.felk.cvut.cz Git - can-eth-gw-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>
Wed, 12 Dec 2012 20:22:13 +0000 (12:22 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Dec 2012 20:22:13 +0000 (12:22 -0800)
Pull big execve/kernel_thread/fork unification series from Al Viro:
 "All architectures are converted to new model.  Quite a bit of that
  stuff is actually shared with architecture trees; in such cases it's
  literally shared branch pulled by both, not a cherry-pick.

  A lot of ugliness and black magic is gone (-3KLoC total in this one):

   - kernel_thread()/kernel_execve()/sys_execve() redesign.

     We don't do syscalls from kernel anymore for either kernel_thread()
     or kernel_execve():

     kernel_thread() is essentially clone(2) with callback run before we
     return to userland, the callbacks either never return or do
     successful do_execve() before returning.

     kernel_execve() is a wrapper for do_execve() - it doesn't need to
     do transition to user mode anymore.

     As a result kernel_thread() and kernel_execve() are
     arch-independent now - they live in kernel/fork.c and fs/exec.c
     resp.  sys_execve() is also in fs/exec.c and it's completely
     architecture-independent.

   - daemonize() is gone, along with its parts in fs/*.c

   - struct pt_regs * is no longer passed to do_fork/copy_process/
     copy_thread/do_execve/search_binary_handler/->load_binary/do_coredump.

   - sys_fork()/sys_vfork()/sys_clone() unified; some architectures
     still need wrappers (ones with callee-saved registers not saved in
     pt_regs on syscall entry), but the main part of those suckers is in
     kernel/fork.c now."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (113 commits)
  do_coredump(): get rid of pt_regs argument
  print_fatal_signal(): get rid of pt_regs argument
  ptrace_signal(): get rid of unused arguments
  get rid of ptrace_signal_deliver() arguments
  new helper: signal_pt_regs()
  unify default ptrace_signal_deliver
  flagday: kill pt_regs argument of do_fork()
  death to idle_regs()
  don't pass regs to copy_process()
  flagday: don't pass regs to copy_thread()
  bfin: switch to generic vfork, get rid of pointless wrappers
  xtensa: switch to generic clone()
  openrisc: switch to use of generic fork and clone
  unicore32: switch to generic clone(2)
  score: switch to generic fork/vfork/clone
  c6x: sanitize copy_thread(), get rid of clone(2) wrapper, switch to generic clone()
  take sys_fork/sys_vfork/sys_clone prototypes to linux/syscalls.h
  mn10300: switch to generic fork/vfork/clone
  h8300: switch to generic fork/vfork/clone
  tile: switch to generic clone()
  ...

Conflicts:
arch/microblaze/include/asm/Kbuild

29 files changed:
1  2 
arch/Kconfig
arch/arm/Kconfig
arch/arm/kernel/entry-common.S
arch/arm/kernel/process.c
arch/arm64/Kconfig
arch/arm64/include/asm/unistd32.h
arch/avr32/Kconfig
arch/c6x/kernel/entry.S
arch/microblaze/include/asm/Kbuild
arch/mips/kernel/entry.S
arch/mips/kernel/scall64-n32.S
arch/parisc/kernel/syscall_table.S
arch/sparc/kernel/sys_sparc_32.c
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/kernel/syscalls.S
arch/sparc/kernel/systbls_64.S
arch/x86/Kconfig
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/process.c
arch/x86/um/Kconfig
drivers/staging/gdm72xx/gdm_usb.c
fs/file.c
include/linux/sched.h
kernel/auditsc.c
kernel/exit.c
kernel/fork.c
kernel/signal.c

diff --combined arch/Kconfig
index cc74aaea116c8cf7176725b937ee9e2cb2ce374b,8d698fb5ccc92f3a1065cdb2a350034a6e5f19bc..34884faf98cd26f3f24c6483dd98b10855387232
@@@ -300,16 -300,15 +300,16 @@@ config SECCOMP_FILTE
  
          See Documentation/prctl/seccomp_filter.txt for details.
  
 -config HAVE_RCU_USER_QS
 +config HAVE_CONTEXT_TRACKING
        bool
        help
 -        Provide kernel entry/exit hooks necessary for userspace
 -        RCU extended quiescent state. Syscalls need to be wrapped inside
 -        rcu_user_exit()-rcu_user_enter() through the slow path using
 -        TIF_NOHZ flag. Exceptions handlers must be wrapped as well. Irqs
 -        are already protected inside rcu_irq_enter/rcu_irq_exit() but
 -        preemption or signal handling on irq exit still need to be protected.
 +        Provide kernel/user boundaries probes necessary for subsystems
 +        that need it, such as userspace RCU extended quiescent state.
 +        Syscalls need to be wrapped inside user_exit()-user_enter() through
 +        the slow path using TIF_NOHZ flag. Exceptions handlers must be
 +        wrapped as well. Irqs are already protected inside
 +        rcu_irq_enter/rcu_irq_exit() but preemption or signal handling on
 +        irq exit still need to be protected.
  
  config HAVE_VIRT_CPU_ACCOUNTING
        bool
@@@ -342,4 -341,18 +342,18 @@@ config MODULES_USE_ELF_RE
          Modules only use ELF REL relocations.  Modules with ELF RELA
          relocations will give an error.
  
+ #
+ # ABI hall of shame
+ #
+ config CLONE_BACKWARDS
+       bool
+       help
+         Architecture has tls passed as the 4th argument of clone(2),
+         not the 5th one.
+ config CLONE_BACKWARDS2
+       bool
+       help
+         Architecture has the first two arguments of clone(2) swapped.
  source "kernel/gcov/Kconfig"
diff --combined arch/arm/Kconfig
index d7d7c2fc53884b00330ab3b4f1ea94799efad1b4,8918a2dd89b40fffcae39bcd5376163774a978ba..08330d9e6a9cffd37ad628fe28f992eb0250d37c
@@@ -5,9 -5,8 +5,9 @@@ config AR
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select ARCH_HAVE_CUSTOM_GPIO_H
        select ARCH_WANT_IPC_PARSE_VERSION
 +      select BUILDTIME_EXTABLE_SORT if MMU
        select CPU_PM if (SUSPEND || CPU_IDLE)
 -      select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
 +      select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU
        select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
        select GENERIC_IRQ_PROBE
@@@ -22,7 -21,6 +22,7 @@@
        select HAVE_AOUT
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
        select HAVE_ARCH_KGDB
 +      select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_BPF_JIT
        select HAVE_C_RECORDMCOUNT
@@@ -57,6 -55,7 +57,7 @@@
        select SYS_SUPPORTS_APM_EMULATION
        select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
        select MODULES_USE_ELF_REL
+       select CLONE_BACKWARDS
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
@@@ -286,8 -285,8 +287,8 @@@ config ARCH_INTEGRATO
        select MULTI_IRQ_HANDLER
        select NEED_MACH_MEMORY_H
        select PLAT_VERSATILE
 -      select PLAT_VERSATILE_FPGA_IRQ
        select SPARSE_IRQ
 +      select VERSATILE_FPGA_IRQ
        help
          Support for ARM's Integrator platform.
  
@@@ -320,7 -319,7 +321,7 @@@ config ARCH_VERSATIL
        select PLAT_VERSATILE
        select PLAT_VERSATILE_CLCD
        select PLAT_VERSATILE_CLOCK
 -      select PLAT_VERSATILE_FPGA_IRQ
 +      select VERSATILE_FPGA_IRQ
        help
          This enables support for ARM Ltd Versatile board.
  
@@@ -332,15 -331,13 +333,15 @@@ config ARCH_AT9
        select IRQ_DOMAIN
        select NEED_MACH_GPIO_H
        select NEED_MACH_IO_H if PCCARD
 +      select PINCTRL
 +      select PINCTRL_AT91 if USE_OF
        help
          This enables support for systems based on Atmel
          AT91RM9200 and AT91SAM9* processors.
  
  config ARCH_BCM2835
        bool "Broadcom BCM2835 family"
 -      select ARCH_WANT_OPTIONAL_GPIOLIB
 +      select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select ARM_ERRATA_411920
        select ARM_TIMER_SP804
        select COMMON_CLK
        select CPU_V6
        select GENERIC_CLOCKEVENTS
 +      select GENERIC_GPIO
        select MULTI_IRQ_HANDLER
 +      select PINCTRL
 +      select PINCTRL_BCM2835
        select SPARSE_IRQ
        select USE_OF
        help
@@@ -371,16 -365,11 +372,16 @@@ config ARCH_CNS3XX
  
  config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
 +      select ARCH_REQUIRE_GPIOLIB
        select ARCH_USES_GETTIMEOFFSET
 +      select AUTO_ZRELADDR
        select CLKDEV_LOOKUP
        select COMMON_CLK
        select CPU_ARM720T
 +      select GENERIC_CLOCKEVENTS
 +      select MULTI_IRQ_HANDLER
        select NEED_MACH_MEMORY_H
 +      select SPARSE_IRQ
        help
          Support for Cirrus Logic 711x/721x/731x based boards.
  
@@@ -445,6 -434,19 +446,6 @@@ config ARCH_FOOTBRIDG
          Support for systems based on the DC21285 companion chip
          ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
  
 -config ARCH_MXC
 -      bool "Freescale MXC/iMX-based"
 -      select ARCH_REQUIRE_GPIOLIB
 -      select CLKDEV_LOOKUP
 -      select CLKSRC_MMIO
 -      select GENERIC_CLOCKEVENTS
 -      select GENERIC_IRQ_CHIP
 -      select MULTI_IRQ_HANDLER
 -      select SPARSE_IRQ
 -      select USE_OF
 -      help
 -        Support for Freescale MXC/iMX-based family of processors
 -
  config ARCH_MXS
        bool "Freescale MXS-based"
        select ARCH_REQUIRE_GPIOLIB
@@@ -546,7 -548,6 +547,7 @@@ config ARCH_KIRKWOO
        select CPU_FEROCEON
        select GENERIC_CLOCKEVENTS
        select PCI
 +      select PCI_QUIRKS
        select PLAT_ORION_LEGACY
        help
          Support for the following Marvell Kirkwood series SoCs:
@@@ -586,7 -587,6 +587,7 @@@ config ARCH_MM
        select GPIO_PXA
        select IRQ_DOMAIN
        select NEED_MACH_GPIO_H
 +      select PINCTRL
        select PLAT_PXA
        select SPARSE_IRQ
        help
@@@ -905,7 -905,6 +906,7 @@@ config ARCH_NOMADI
  
  config PLAT_SPEAR
        bool "ST SPEAr"
 +      select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select CLKDEV_LOOKUP
@@@ -926,7 -925,6 +927,7 @@@ config ARCH_DAVINC
        select GENERIC_IRQ_CHIP
        select HAVE_IDE
        select NEED_MACH_GPIO_H
 +      select USE_OF
        select ZONE_DMA
        help
          Support for TI's DaVinci platform.
@@@ -940,6 -938,7 +941,6 @@@ config ARCH_OMA
        select CLKSRC_MMIO
        select GENERIC_CLOCKEVENTS
        select HAVE_CLK
 -      select NEED_MACH_GPIO_H
        help
          Support for TI's OMAP platform (OMAP1/2/3/4).
  
@@@ -961,6 -960,7 +962,6 @@@ config ARCH_ZYN
        bool "Xilinx Zynq ARM Cortex A9 Platform"
        select ARM_AMBA
        select ARM_GIC
 -      select CLKDEV_LOOKUP
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select ICST
@@@ -1023,8 -1023,6 +1024,8 @@@ source "arch/arm/mach-mvebu/Kconfig
  
  source "arch/arm/mach-at91/Kconfig"
  
 +source "arch/arm/mach-bcm/Kconfig"
 +
  source "arch/arm/mach-clps711x/Kconfig"
  
  source "arch/arm/mach-cns3xxx/Kconfig"
@@@ -1061,7 -1059,7 +1062,7 @@@ source "arch/arm/mach-msm/Kconfig
  
  source "arch/arm/mach-mv78xx0/Kconfig"
  
 -source "arch/arm/plat-mxc/Kconfig"
 +source "arch/arm/mach-imx/Kconfig"
  
  source "arch/arm/mach-mxs/Kconfig"
  
@@@ -1116,8 -1114,6 +1117,8 @@@ source "arch/arm/mach-exynos/Kconfig
  
  source "arch/arm/mach-shmobile/Kconfig"
  
 +source "arch/arm/mach-sunxi/Kconfig"
 +
  source "arch/arm/mach-prima2/Kconfig"
  
  source "arch/arm/mach-tegra/Kconfig"
@@@ -1173,7 -1169,7 +1174,7 @@@ config ARM_NR_BANK
  config IWMMXT
        bool "Enable iWMMXt support"
        depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
 -      default y if PXA27x || PXA3xx || PXA95x || ARCH_MMP
 +      default y if PXA27x || PXA3xx || ARCH_MMP
        help
          Enable support for iWMMXt context switching at run time if
          running on a CPU that supports it.
index 804153c0a9cf2050aadcf21007198100184b831d,88a07feaa05fb3283d1f8e765bed0dd9fd16566f..a6c301e90a3b3fd6cc43508b73d3710244395164
@@@ -417,6 -417,16 +417,6 @@@ local_restart
        ldr     r10, [tsk, #TI_FLAGS]           @ check for syscall tracing
        stmdb   sp!, {r4, r5}                   @ push fifth and sixth args
  
 -#ifdef CONFIG_SECCOMP
 -      tst     r10, #_TIF_SECCOMP
 -      beq     1f
 -      mov     r0, scno
 -      bl      __secure_computing      
 -      add     r0, sp, #S_R0 + S_OFF           @ pointer to regs
 -      ldmia   r0, {r0 - r3}                   @ have to reload r0 - r3
 -1:
 -#endif
 -
        tst     r10, #_TIF_SYSCALL_WORK         @ are we tracing syscalls?
        bne     __sys_trace
  
@@@ -448,13 -458,11 +448,13 @@@ __sys_trace
        ldmccia r1, {r0 - r6}                   @ have to reload r0 - r6
        stmccia sp, {r4, r5}                    @ and update the stack args
        ldrcc   pc, [tbl, scno, lsl #2]         @ call sys_* routine
 -      b       2b
 +      cmp     scno, #-1                       @ skip the syscall?
 +      bne     2b
 +      add     sp, sp, #S_OFF                  @ restore stack
 +      b       ret_slow_syscall
  
  __sys_trace_return:
        str     r0, [sp, #S_R0 + S_OFF]!        @ save returned r0
 -      mov     r1, scno
        mov     r0, sp
        bl      syscall_trace_exit
        b       ret_slow_syscall
@@@ -502,22 -510,6 +502,6 @@@ sys_syscall
                b       sys_ni_syscall
  ENDPROC(sys_syscall)
  
- sys_fork_wrapper:
-               add     r0, sp, #S_OFF
-               b       sys_fork
- ENDPROC(sys_fork_wrapper)
- sys_vfork_wrapper:
-               add     r0, sp, #S_OFF
-               b       sys_vfork
- ENDPROC(sys_vfork_wrapper)
- sys_clone_wrapper:
-               add     ip, sp, #S_OFF
-               str     ip, [sp, #4]
-               b       sys_clone
- ENDPROC(sys_clone_wrapper)
  sys_sigreturn_wrapper:
                add     r0, sp, #S_OFF
                mov     why, #0         @ prevent syscall restart handling
index 44bc0b327e2b62a2e13acf1713cf18a57b715e46,9800338c5d1b0e4df1b5e66ffe74f55de199637f..c6dec5fc20aa42440ce7267766f257449550550a
@@@ -34,7 -34,6 +34,7 @@@
  #include <linux/leds.h>
  
  #include <asm/cacheflush.h>
 +#include <asm/idmap.h>
  #include <asm/processor.h>
  #include <asm/thread_notify.h>
  #include <asm/stacktrace.h>
@@@ -57,6 -56,8 +57,6 @@@ static const char *isa_modes[] = 
    "ARM" , "Thumb" , "Jazelle", "ThumbEE"
  };
  
 -extern void setup_mm_for_reboot(void);
 -
  static volatile int hlt_counter;
  
  void disable_hlt(void)
@@@ -69,7 -70,6 +69,7 @@@ EXPORT_SYMBOL(disable_hlt)
  void enable_hlt(void)
  {
        hlt_counter--;
 +      BUG_ON(hlt_counter < 0);
  }
  
  EXPORT_SYMBOL(enable_hlt);
@@@ -376,17 -376,18 +376,18 @@@ asmlinkage void ret_from_fork(void) __a
  
  int
  copy_thread(unsigned long clone_flags, unsigned long stack_start,
-           unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
+           unsigned long stk_sz, struct task_struct *p)
  {
        struct thread_info *thread = task_thread_info(p);
        struct pt_regs *childregs = task_pt_regs(p);
  
        memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
  
-       if (likely(regs)) {
-               *childregs = *regs;
+       if (likely(!(p->flags & PF_KTHREAD))) {
+               *childregs = *current_pt_regs();
                childregs->ARM_r0 = 0;
-               childregs->ARM_sp = stack_start;
+               if (stack_start)
+                       childregs->ARM_sp = stack_start;
        } else {
                memset(childregs, 0, sizeof(struct pt_regs));
                thread->cpu_context.r4 = stk_sz;
        clear_ptrace_hw_breakpoint(p);
  
        if (clone_flags & CLONE_SETTLS)
-               thread->tp_value = regs->ARM_r3;
+               thread->tp_value = childregs->ARM_r3;
  
        thread_notify(THREAD_NOTIFY_COPY, thread);
  
diff --combined arch/arm64/Kconfig
index 2adf340b8589b945a0ee18739757038167b6568e,4b03c56ec3294e249f788a723b62827698cf9cf5..f9ccff915918fad21f622284e6f456747ac5143f
@@@ -2,7 -2,6 +2,7 @@@ config ARM6
        def_bool y
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 +      select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select GENERIC_HARDIRQS_NO_DEPRECATED
        select GENERIC_IOMAP
@@@ -24,6 -23,7 +24,6 @@@
        select HAVE_IRQ_WORK
        select HAVE_MEMBLOCK
        select HAVE_PERF_EVENTS
 -      select HAVE_SPARSE_IRQ
        select IRQ_DOMAIN
        select MODULES_USE_ELF_RELA
        select NO_BOOTMEM
@@@ -33,6 -33,7 +33,7 @@@
        select RTC_LIB
        select SPARSE_IRQ
        select SYSCTL_EXCEPTION_TRACE
+       select CLONE_BACKWARDS
        help
          ARM 64-bit (AArch64) Linux support.
  
index 50104e8ce55db7d63bfc62ac11d7b3ca1f6498cd,30127cb11adef08fabb85234cc6d8f2344e7a117..58432625fdb36922fa48831142e5bdf3a08d7875
@@@ -23,7 -23,7 +23,7 @@@
  
  __SYSCALL(0,   sys_restart_syscall)
  __SYSCALL(1,   sys_exit)
- __SYSCALL(2,   compat_sys_fork)
+ __SYSCALL(2,   sys_fork)
  __SYSCALL(3,   sys_read)
  __SYSCALL(4,   sys_write)
  __SYSCALL(5,   compat_sys_open)
@@@ -211,7 -211,7 +211,7 @@@ __SYSCALL(186, compat_sys_sigaltstack_w
  __SYSCALL(187, compat_sys_sendfile)
  __SYSCALL(188, sys_ni_syscall)                        /* 188 reserved */
  __SYSCALL(189, sys_ni_syscall)                        /* 189 reserved */
- __SYSCALL(190, compat_sys_vfork)
+ __SYSCALL(190, sys_vfork)
  __SYSCALL(191, compat_sys_getrlimit)          /* SuS compliant getrlimit */
  __SYSCALL(192, sys_mmap_pgoff)
  __SYSCALL(193, compat_sys_truncate64_wrapper)
@@@ -392,8 -392,8 +392,8 @@@ __SYSCALL(367, sys_fanotify_init
  __SYSCALL(368, compat_sys_fanotify_mark_wrapper)
  __SYSCALL(369, sys_prlimit64)
  __SYSCALL(370, sys_name_to_handle_at)
 -__SYSCALL(371, sys_open_by_handle_at)
 -__SYSCALL(372, sys_clock_adjtime)
 +__SYSCALL(371, compat_sys_open_by_handle_at)
 +__SYSCALL(372, compat_sys_clock_adjtime)
  __SYSCALL(373, sys_syncfs)
  
  #define __NR_compat_syscalls          374
diff --combined arch/avr32/Kconfig
index c2bbc9a722224b9d92f439ae9c6f9a612dee9b0a,649aeb9acecb4d0f3f5267038501e2822b10cf7e..202d71a15be1125109f560175a9137fa62064050
@@@ -17,6 -17,8 +17,8 @@@ config AVR3
        select GENERIC_CLOCKEVENTS
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
+       select GENERIC_KERNEL_THREAD
+       select GENERIC_KERNEL_EXECVE
        help
          AVR32 is a high-performance 32-bit RISC microprocessor core,
          designed for cost-sensitive embedded applications, with particular
@@@ -193,6 -195,9 +195,6 @@@ source "kernel/Kconfig.preempt
  config QUICKLIST
        def_bool y
  
 -config HAVE_ARCH_BOOTMEM
 -      def_bool n
 -
  config ARCH_HAVE_MEMORY_PRESENT
        def_bool n
  
diff --combined arch/c6x/kernel/entry.S
index 0ed6157dd256a81aeefc9e8de971f834f313a11d,1037b98953ca437009770e193ed34bcace91c737..5239057de4c4cdb4363b328a9ce820c2afd0f81e
@@@ -277,8 -277,6 +277,8 @@@ work_rescheduled
   [A1] BNOP    .S1     work_resched,5
  
  work_notifysig:
 +      ;; enable interrupts for do_notify_resume()
 +      UNMASK_INT B2
        B       .S2     do_notify_resume
        LDW     .D2T1   *+SP(REGS__END+8),A6 ; syscall flag
        ADDKPC  .S2     resume_userspace,B3,1
@@@ -415,21 -413,12 +415,11 @@@ ENTRY(ret_from_kernel_thread
  0:
        B       .S2     B10                /* call fn */
        LDW     .D2T1   *+SP(REGS_A1+8),A4 /* get arg */
-       MVKL    .S2     sys_exit,B11
-       MVKH    .S2     sys_exit,B11
-       ADDKPC  .S2     0f,B3,1
- 0:
-       BNOP    .S2     B11,5   /* jump to sys_exit */
+       ADDKPC  .S2     ret_from_fork_2,B3,3
  ENDPROC(ret_from_kernel_thread)
  
- ENTRY(ret_from_kernel_execve)
-       GET_THREAD_INFO A12
-       BNOP    .S2     syscall_exit,4
-       ADD     .D2X    A4,-8,SP
- ENDPROC(ret_from_kernel_execve)
        ;;
 -      ;; These are the interrupt handlers, responsible for calling __do_IRQ()
 -      ;; int6 is used for syscalls (see _system_call entry)
 +      ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ()
        ;;
        .macro SAVE_ALL_INT
        SAVE_ALL IRP,ITSR
@@@ -624,18 -613,6 +614,6 @@@ ENDPROC(sys_sigaltstack
        ;; Special system calls
        ;; return address is in B3
        ;;
- ENTRY(sys_clone)
-       ADD     .D1X    SP,8,A4
- #ifdef CONFIG_C6X_BIG_KERNEL
-  ||   MVKL    .S1     sys_c6x_clone,A0
-       MVKH    .S1     sys_c6x_clone,A0
-       BNOP    .S2X    A0,5
- #else
-  ||   B       .S2     sys_c6x_clone
-       NOP     5
- #endif
- ENDPROC(sys_clone)
  ENTRY(sys_rt_sigreturn)
        ADD     .D1X    SP,8,A4
  #ifdef CONFIG_C6X_BIG_KERNEL
index 2957fcc71764513e6c083a1f656efef1036a9678,88a758a679227ccd237aad7e35818361dc59b701..eb3a46c096fe57baf3075dfda129dd75187d4e43
@@@ -3,4 -3,4 +3,5 @@@ include include/asm-generic/Kbuild.as
  header-y  += elf.h
  generic-y += clkdev.h
  generic-y += exec.h
 +generic-y += trace_clock.h
+ generic-y += syscalls.h
diff --combined arch/mips/kernel/entry.S
index 9b00362f32f6d95d4577817bbd39757f880d0639,3320cb4ac1d485b1ab42bc3da9e6346a0f62b9ff..e5786858cdb6808f24993930c899d89f3ab3bfa5
@@@ -36,11 -36,6 +36,11 @@@ FEXPORT(ret_from_exception
  FEXPORT(ret_from_irq)
        LONG_S  s0, TI_REGS($28)
  FEXPORT(__ret_from_irq)
 +/*
 + * We can be coming here from a syscall done in the kernel space,
 + * e.g. a failed kernel_execve().
 + */
 +resume_userspace_check:
        LONG_L  t0, PT_STATUS(sp)               # returning to kernel mode?
        andi    t0, t0, KU_USER
        beqz    t0, resume_kernel
@@@ -70,6 -65,12 +70,12 @@@ need_resched
        b       need_resched
  #endif
  
+ FEXPORT(ret_from_kernel_thread)
+       jal     schedule_tail           # a0 = struct task_struct *prev
+       move    a0, s1
+       jal     s0
+       j       syscall_exit
  FEXPORT(ret_from_fork)
        jal     schedule_tail           # a0 = struct task_struct *prev
  
@@@ -167,7 -168,7 +173,7 @@@ work_notifysig:                            # deal with pending 
        move    a0, sp
        li      a1, 0
        jal     do_notify_resume        # a2 already loaded
 -      j       resume_userspace
 +      j       resume_userspace_check
  
  FEXPORT(syscall_exit_partial)
        local_irq_disable               # make sure need_resched doesn't
index 86ec03f0e00c48f966e428eb1a7844cfcf3eff1a,d27ca340d46dcbe6cb680f24b8c4e49e0bad1ebc..629719143763b081b8afd6ff2631870a02e9fddd
@@@ -167,7 -167,7 +167,7 @@@ EXPORT(sysn32_call_table
        PTR     sys_getsockopt
        PTR     sys_clone                       /* 6055 */
        PTR     sys_fork
-       PTR     sys32_execve
+       PTR     compat_sys_execve
        PTR     sys_exit
        PTR     compat_sys_wait4
        PTR     sys_kill                        /* 6060 */
        PTR     sys_timerfd_create
        PTR     compat_sys_timerfd_gettime      /* 6285 */
        PTR     compat_sys_timerfd_settime
 -      PTR     sys_signalfd4
 +      PTR     compat_sys_signalfd4
        PTR     sys_eventfd2
        PTR     sys_epoll_create1
        PTR     sys_dup3                        /* 6290 */
        PTR     sys_pipe2
        PTR     sys_inotify_init1
 -      PTR     sys_preadv
 -      PTR     sys_pwritev
 +      PTR     compat_sys_preadv
 +      PTR     compat_sys_pwritev
        PTR     compat_sys_rt_tgsigqueueinfo    /* 6295 */
        PTR     sys_perf_event_open
        PTR     sys_accept4
index cbf5d59d5d6a8943edd6c74a0f1e6013aa640c19,cb2da96d6ab99317f84edadbca2f0dd67884e887..54d950b067b7ff99845f1d4d67cdec88068b4b92
        ENTRY_SAME(fork_wrapper)
        ENTRY_SAME(read)
        ENTRY_SAME(write)
 -      ENTRY_SAME(open)                /* 5 */
 +      ENTRY_COMP(open)                /* 5 */
        ENTRY_SAME(close)
        ENTRY_SAME(waitpid)
        ENTRY_SAME(creat)
        ENTRY_SAME(link)
        ENTRY_SAME(unlink)              /* 10 */
-       ENTRY_DIFF(execve_wrapper)
+       ENTRY_COMP(execve)
        ENTRY_SAME(chdir)
        /* See comments in kernel/time.c!!! Maybe we don't need this? */
        ENTRY_COMP(time)
index 57277c8301518db33d49dfb5cd326d49212a62da,a8e6eb0a11d503b2c611e69243f8edb9981dfae8..2da0bdcae52f765e0e7e021082064bc99e6e0ace
@@@ -34,9 -34,11 +34,9 @@@ asmlinkage unsigned long sys_getpagesiz
        return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */
  }
  
 -#define COLOUR_ALIGN(addr)      (((addr)+SHMLBA-1)&~(SHMLBA-1))
 -
  unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
  {
 -      struct vm_area_struct * vmm;
 +      struct vm_unmapped_area_info info;
  
        if (flags & MAP_FIXED) {
                /* We do not accept a shared mapping if it would violate
        if (!addr)
                addr = TASK_UNMAPPED_BASE;
  
 -      if (flags & MAP_SHARED)
 -              addr = COLOUR_ALIGN(addr);
 -      else
 -              addr = PAGE_ALIGN(addr);
 -
 -      for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
 -              /* At this point:  (!vmm || addr < vmm->vm_end). */
 -              if (TASK_SIZE - PAGE_SIZE - len < addr)
 -                      return -ENOMEM;
 -              if (!vmm || addr + len <= vmm->vm_start)
 -                      return addr;
 -              addr = vmm->vm_end;
 -              if (flags & MAP_SHARED)
 -                      addr = COLOUR_ALIGN(addr);
 -      }
 +      info.flags = 0;
 +      info.length = len;
 +      info.low_limit = addr;
 +      info.high_limit = TASK_SIZE;
 +      info.align_mask = (flags & MAP_SHARED) ?
 +              (PAGE_MASK & (SHMLBA - 1)) : 0;
 +      info.align_offset = pgoff << PAGE_SHIFT;
 +      return vm_unmapped_area(&info);
  }
  
  /*
@@@ -249,27 -258,3 +249,3 @@@ out
        up_read(&uts_sem);
        return err;
  }
- /*
-  * Do a system call from kernel instead of calling sys_execve so we
-  * end up with proper pt_regs.
-  */
- int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
- {
-       long __res;
-       register long __g1 __asm__ ("g1") = __NR_execve;
-       register long __o0 __asm__ ("o0") = (long)(filename);
-       register long __o1 __asm__ ("o1") = (long)(argv);
-       register long __o2 __asm__ ("o2") = (long)(envp);
-       asm volatile ("t 0x10\n\t"
-                     "bcc 1f\n\t"
-                     "mov %%o0, %0\n\t"
-                     "sub %%g0, %%o0, %0\n\t"
-                     "1:\n\t"
-                     : "=r" (__res), "=&r" (__o0)
-                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
-                     : "cc");
-       return __res;
- }
index 97309c0ec5336caf4006cb952850957c42c22a4e,51b85feb8b973a0cbfaf8f8e35ae347227f0e12a..708bc29d36a8ff7cd8fe78ee7e02e91645d0f461
@@@ -75,7 -75,7 +75,7 @@@ static inline int invalid_64bit_range(u
   *    the spitfire/niagara VA-hole.
   */
  
 -static inline unsigned long COLOUR_ALIGN(unsigned long addr,
 +static inline unsigned long COLOR_ALIGN(unsigned long addr,
                                         unsigned long pgoff)
  {
        unsigned long base = (addr+SHMLBA-1)&~(SHMLBA-1);
        return base + off;
  }
  
 -static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
 -                                            unsigned long pgoff)
 -{
 -      unsigned long base = addr & ~(SHMLBA-1);
 -      unsigned long off = (pgoff<<PAGE_SHIFT) & (SHMLBA-1);
 -
 -      if (base + off <= addr)
 -              return base + off;
 -      return base - off;
 -}
 -
  unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
  {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct * vma;
        unsigned long task_size = TASK_SIZE;
 -      unsigned long start_addr;
        int do_color_align;
 +      struct vm_unmapped_area_info info;
  
        if (flags & MAP_FIXED) {
                /* We do not accept a shared mapping if it would violate
  
        if (addr) {
                if (do_color_align)
 -                      addr = COLOUR_ALIGN(addr, pgoff);
 +                      addr = COLOR_ALIGN(addr, pgoff);
                else
                        addr = PAGE_ALIGN(addr);
  
                        return addr;
        }
  
 -      if (len > mm->cached_hole_size) {
 -              start_addr = addr = mm->free_area_cache;
 -      } else {
 -              start_addr = addr = TASK_UNMAPPED_BASE;
 -              mm->cached_hole_size = 0;
 +      info.flags = 0;
 +      info.length = len;
 +      info.low_limit = TASK_UNMAPPED_BASE;
 +      info.high_limit = min(task_size, VA_EXCLUDE_START);
 +      info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
 +      info.align_offset = pgoff << PAGE_SHIFT;
 +      addr = vm_unmapped_area(&info);
 +
 +      if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
 +              VM_BUG_ON(addr != -ENOMEM);
 +              info.low_limit = VA_EXCLUDE_END;
 +              info.high_limit = task_size;
 +              addr = vm_unmapped_area(&info);
        }
  
 -      task_size -= len;
 -
 -full_search:
 -      if (do_color_align)
 -              addr = COLOUR_ALIGN(addr, pgoff);
 -      else
 -              addr = PAGE_ALIGN(addr);
 -
 -      for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
 -              /* At this point:  (!vma || addr < vma->vm_end). */
 -              if (addr < VA_EXCLUDE_START &&
 -                  (addr + len) >= VA_EXCLUDE_START) {
 -                      addr = VA_EXCLUDE_END;
 -                      vma = find_vma(mm, VA_EXCLUDE_END);
 -              }
 -              if (unlikely(task_size < addr)) {
 -                      if (start_addr != TASK_UNMAPPED_BASE) {
 -                              start_addr = addr = TASK_UNMAPPED_BASE;
 -                              mm->cached_hole_size = 0;
 -                              goto full_search;
 -                      }
 -                      return -ENOMEM;
 -              }
 -              if (likely(!vma || addr + len <= vma->vm_start)) {
 -                      /*
 -                       * Remember the place where we stopped the search:
 -                       */
 -                      mm->free_area_cache = addr + len;
 -                      return addr;
 -              }
 -              if (addr + mm->cached_hole_size < vma->vm_start)
 -                      mm->cached_hole_size = vma->vm_start - addr;
 -
 -              addr = vma->vm_end;
 -              if (do_color_align)
 -                      addr = COLOUR_ALIGN(addr, pgoff);
 -      }
 +      return addr;
  }
  
  unsigned long
@@@ -151,7 -190,6 +151,7 @@@ arch_get_unmapped_area_topdown(struct f
        unsigned long task_size = STACK_TOP32;
        unsigned long addr = addr0;
        int do_color_align;
 +      struct vm_unmapped_area_info info;
  
        /* This should only ever run for 32-bit processes.  */
        BUG_ON(!test_thread_flag(TIF_32BIT));
        /* requesting a specific address */
        if (addr) {
                if (do_color_align)
 -                      addr = COLOUR_ALIGN(addr, pgoff);
 +                      addr = COLOR_ALIGN(addr, pgoff);
                else
                        addr = PAGE_ALIGN(addr);
  
                        return addr;
        }
  
 -      /* check if free_area_cache is useful for us */
 -      if (len <= mm->cached_hole_size) {
 -              mm->cached_hole_size = 0;
 -              mm->free_area_cache = mm->mmap_base;
 -      }
 -
 -      /* either no address requested or can't fit in requested address hole */
 -      addr = mm->free_area_cache;
 -      if (do_color_align) {
 -              unsigned long base = COLOUR_ALIGN_DOWN(addr-len, pgoff);
 -
 -              addr = base + len;
 -      }
 -
 -      /* make sure it can fit in the remaining address space */
 -      if (likely(addr > len)) {
 -              vma = find_vma(mm, addr-len);
 -              if (!vma || addr <= vma->vm_start) {
 -                      /* remember the address as a hint for next time */
 -                      return (mm->free_area_cache = addr-len);
 -              }
 -      }
 -
 -      if (unlikely(mm->mmap_base < len))
 -              goto bottomup;
 -
 -      addr = mm->mmap_base-len;
 -      if (do_color_align)
 -              addr = COLOUR_ALIGN_DOWN(addr, pgoff);
 -
 -      do {
 -              /*
 -               * Lookup failure means no vma is above this address,
 -               * else if new region fits below vma->vm_start,
 -               * return with success:
 -               */
 -              vma = find_vma(mm, addr);
 -              if (likely(!vma || addr+len <= vma->vm_start)) {
 -                      /* remember the address as a hint for next time */
 -                      return (mm->free_area_cache = addr);
 -              }
 +      info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 +      info.length = len;
 +      info.low_limit = PAGE_SIZE;
 +      info.high_limit = mm->mmap_base;
 +      info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
 +      info.align_offset = pgoff << PAGE_SHIFT;
 +      addr = vm_unmapped_area(&info);
  
 -              /* remember the largest hole we saw so far */
 -              if (addr + mm->cached_hole_size < vma->vm_start)
 -                      mm->cached_hole_size = vma->vm_start - addr;
 -
 -              /* try just below the current vma->vm_start */
 -              addr = vma->vm_start-len;
 -              if (do_color_align)
 -                      addr = COLOUR_ALIGN_DOWN(addr, pgoff);
 -      } while (likely(len < vma->vm_start));
 -
 -bottomup:
        /*
         * A failed mmap() very likely causes application failure,
         * so fall back to the bottom-up function here. This scenario
         * can happen with large stack limits and large mmap()
         * allocations.
         */
 -      mm->cached_hole_size = ~0UL;
 -      mm->free_area_cache = TASK_UNMAPPED_BASE;
 -      addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
 -      /*
 -       * Restore the topdown base:
 -       */
 -      mm->free_area_cache = mm->mmap_base;
 -      mm->cached_hole_size = ~0UL;
 +      if (addr & ~PAGE_MASK) {
 +              VM_BUG_ON(addr != -ENOMEM);
 +              info.flags = 0;
 +              info.low_limit = TASK_UNMAPPED_BASE;
 +              info.high_limit = STACK_TOP32;
 +              addr = vm_unmapped_area(&info);
 +      }
  
        return addr;
  }
@@@ -646,28 -730,6 +646,6 @@@ SYSCALL_DEFINE5(rt_sigaction, int, sig
        return ret;
  }
  
- /*
-  * Do a system call from kernel instead of calling sys_execve so we
-  * end up with proper pt_regs.
-  */
- int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
- {
-       long __res;
-       register long __g1 __asm__ ("g1") = __NR_execve;
-       register long __o0 __asm__ ("o0") = (long)(filename);
-       register long __o1 __asm__ ("o1") = (long)(argv);
-       register long __o2 __asm__ ("o2") = (long)(envp);
-       asm volatile ("t 0x6d\n\t"
-                     "sub %%g0, %%o0, %0\n\t"
-                     "movcc %%xcc, %%o0, %0\n\t"
-                     : "=r" (__res), "=&r" (__o0)
-                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
-                     : "cc");
-       return __res;
- }
  asmlinkage long sys_kern_features(void)
  {
        return KERN_FEATURE_MIXED_MODE_STACK;
index bf2347794e3323c3220c92e4a96849d8c89d5fbf,2ef41e67f0bef3e4ffce7e5bd7d4f6426ebeb765..e0fed7711a940b6ec991ad11da63d0356556b5cd
@@@ -1,23 -1,19 +1,19 @@@
        /* SunOS's execv() call only specifies the argv argument, the
         * environment settings are the same as the calling processes.
         */
- sys_execve:
-       sethi   %hi(sparc_execve), %g1
-       ba,pt   %xcc, execve_merge
-        or     %g1, %lo(sparc_execve), %g1
+ sys64_execve:
+       set     sys_execve, %g1
+       jmpl    %g1, %g0
+        flushw
  
  #ifdef CONFIG_COMPAT
  sunos_execv:
-       stx     %g0, [%sp + PTREGS_OFF + PT_V9_I2]
+       mov     %g0, %o2
  sys32_execve:
-       sethi   %hi(sparc32_execve), %g1
-       or      %g1, %lo(sparc32_execve), %g1
- #endif
- execve_merge:
-       flushw
+       set     compat_sys_execve, %g1
        jmpl    %g1, %g0
-        add    %sp, PTREGS_OFF, %o0
+        flushw
+ #endif
  
        .align  32
  sys_sparc_pipe:
@@@ -112,26 -108,21 +108,31 @@@ sys_clone
  ret_from_syscall:
        /* Clear current_thread_info()->new_child. */
        stb     %g0, [%g6 + TI_NEW_CHILD]
-       ldx     [%g6 + TI_FLAGS], %l0
        call    schedule_tail
         mov    %g7, %o0
+       ldx     [%sp + PTREGS_OFF + PT_V9_I0], %o0
+       brnz,pt %o0, ret_sys_call
+        ldx    [%g6 + TI_FLAGS], %l0
+       ldx     [%sp + PTREGS_OFF + PT_V9_G1], %l1
+       call    %l1
+        ldx    [%sp + PTREGS_OFF + PT_V9_G2], %o0
        ba,pt   %xcc, ret_sys_call
-        ldx    [%sp + PTREGS_OFF + PT_V9_I0], %o0
+        mov    0, %o0
  
 +      .globl  sparc_exit_group
 +      .type   sparc_exit_group,#function
 +sparc_exit_group:
 +      sethi   %hi(sys_exit_group), %g7
 +      ba,pt   %xcc, 1f
 +       or     %g7, %lo(sys_exit_group), %g7
 +      .size   sparc_exit_group,.-sparc_exit_group
 +
        .globl  sparc_exit
        .type   sparc_exit,#function
  sparc_exit:
 -      rdpr    %pstate, %g2
 +      sethi   %hi(sys_exit), %g7
 +      or      %g7, %lo(sys_exit), %g7
 +1:    rdpr    %pstate, %g2
        wrpr    %g2, PSTATE_IE, %pstate
        rdpr    %otherwin, %g1
        rdpr    %cansave, %g3
        wrpr    %g3, 0x0, %cansave
        wrpr    %g0, 0x0, %otherwin
        wrpr    %g2, 0x0, %pstate
 -      ba,pt   %xcc, sys_exit
 +      jmpl    %g7, %g0
         stb    %g0, [%g6 + TI_WSAVED]
        .size   sparc_exit,.-sparc_exit
  
@@@ -232,7 -223,6 +233,6 @@@ ret_sys_call
        ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
  
  2:
-       stb     %g0, [%g6 + TI_SYS_NOERROR]
        /* System call success, clear Carry condition code. */
        andn    %g3, %g2, %g3
  3:
index 017b74a63dcb995dd9c18049bd1a1604d329fea5,ebb7f5fc58fb5c952582968230656a9cf9b0128b..cdbd9b817751472200246245e85830b504478a0f
@@@ -107,7 -107,7 +107,7 @@@ sys_call_table
  /*40*/        .word sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_nis_syscall
        .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
  /*50*/        .word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl
-       .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve
+       .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys64_execve
  /*60*/        .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize
        .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall
  /*70*/        .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_64_munmap, sys_mprotect
  /*170*/       .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
        .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
  /*180*/       .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
 -      .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
 +      .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname
  /*190*/       .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
        .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
  /*200*/       .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
diff --combined arch/x86/Kconfig
index 037c4e30c27165d9edbe3b2dfb40c8ddc96780d8,0df6e7d845398549317502cecc2a411084edb6aa..9195fd80e11ed7efa2e030704eab0b22e161c7cc
@@@ -69,8 -69,8 +69,8 @@@ config X8
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_DEBUG_KMEMLEAK
        select ANON_INODES
 -      select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
 -      select HAVE_CMPXCHG_LOCAL if !M386
 +      select HAVE_ALIGNED_STRUCT_PAGE if SLUB
 +      select HAVE_CMPXCHG_LOCAL
        select HAVE_CMPXCHG_DOUBLE
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
        select KTIME_SCALAR if X86_32
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
 -      select HAVE_RCU_USER_QS if X86_64
 +      select HAVE_CONTEXT_TRACKING if X86_64
        select HAVE_IRQ_TIME_ACCOUNTING
        select GENERIC_KERNEL_THREAD
        select GENERIC_KERNEL_EXECVE
        select MODULES_USE_ELF_REL if X86_32
        select MODULES_USE_ELF_RELA if X86_64
+       select CLONE_BACKWARDS if X86_32
  
  config INSTRUCTION_DECODER
        def_bool y
@@@ -171,8 -172,13 +172,8 @@@ config ARCH_MAY_HAVE_PC_FD
        def_bool y
        depends on ISA_DMA_API
  
 -config RWSEM_GENERIC_SPINLOCK
 -      def_bool y
 -      depends on !X86_XADD
 -
  config RWSEM_XCHGADD_ALGORITHM
        def_bool y
 -      depends on X86_XADD
  
  config GENERIC_CALIBRATE_DELAY
        def_bool y
@@@ -305,7 -311,7 +306,7 @@@ config X86_X2API
          If you don't know what to do here, say N.
  
  config X86_MPPARSE
 -      bool "Enable MPS table" if ACPI
 +      bool "Enable MPS table" if ACPI || SFI
        default y
        depends on X86_LOCAL_APIC
        ---help---
@@@ -1095,7 -1101,7 +1096,7 @@@ config HIGHMEM4
  
  config HIGHMEM64G
        bool "64GB"
 -      depends on !M386 && !M486
 +      depends on !M486
        select X86_PAE
        ---help---
          Select this if you have a 32-bit processor and more than 4
@@@ -1693,50 -1699,6 +1694,50 @@@ config HOTPLUG_CP
            automatically on SMP systems. )
          Say N if you want to disable CPU hotplug.
  
 +config BOOTPARAM_HOTPLUG_CPU0
 +      bool "Set default setting of cpu0_hotpluggable"
 +      default n
 +      depends on HOTPLUG_CPU && EXPERIMENTAL
 +      ---help---
 +        Set whether default state of cpu0_hotpluggable is on or off.
 +
 +        Say Y here to enable CPU0 hotplug by default. If this switch
 +        is turned on, there is no need to give cpu0_hotplug kernel
 +        parameter and the CPU0 hotplug feature is enabled by default.
 +
 +        Please note: there are two known CPU0 dependencies if you want
 +        to enable the CPU0 hotplug feature either by this switch or by
 +        cpu0_hotplug kernel parameter.
 +
 +        First, resume from hibernate or suspend always starts from CPU0.
 +        So hibernate and suspend are prevented if CPU0 is offline.
 +
 +        Second dependency is PIC interrupts always go to CPU0. CPU0 can not
 +        offline if any interrupt can not migrate out of CPU0. There may
 +        be other CPU0 dependencies.
 +
 +        Please make sure the dependencies are under your control before
 +        you enable this feature.
 +
 +        Say N if you don't want to enable CPU0 hotplug feature by default.
 +        You still can enable the CPU0 hotplug feature at boot by kernel
 +        parameter cpu0_hotplug.
 +
 +config DEBUG_HOTPLUG_CPU0
 +      def_bool n
 +      prompt "Debug CPU0 hotplug"
 +      depends on HOTPLUG_CPU && EXPERIMENTAL
 +      ---help---
 +        Enabling this option offlines CPU0 (if CPU0 can be offlined) as
 +        soon as possible and boots up userspace with CPU0 offlined. User
 +        can online CPU0 back after boot time.
 +
 +        To debug CPU0 hotplug, you need to enable CPU0 offline/online
 +        feature by either turning on CONFIG_BOOTPARAM_HOTPLUG_CPU0 during
 +        compilation or giving cpu0_hotplug kernel parameter at boot.
 +
 +        If unsure, say N.
 +
  config COMPAT_VDSO
        def_bool y
        prompt "Compat VDSO support"
index e101b38912dee08e40857def7676bc119233724b,92f48a5a6b2e1bf5b1fedddf947c458dbdddfd63..888184b2fc85c7987a63d365e9bfd1d334eb9372
@@@ -178,8 -178,6 +178,6 @@@ static inline int hlt_works(int cpu
  
  extern void cpu_detect(struct cpuinfo_x86 *c);
  
- extern struct pt_regs *idle_regs(struct pt_regs *);
  extern void early_cpu_init(void);
  extern void identify_boot_cpu(void);
  extern void identify_secondary_cpu(struct cpuinfo_x86 *);
@@@ -187,7 -185,7 +185,7 @@@ extern void print_cpu_info(struct cpuin
  void print_cpu_msr(struct cpuinfo_x86 *);
  extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
  extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 -extern unsigned short num_cache_leaves;
 +extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
  
  extern void detect_extended_topology(struct cpuinfo_x86 *c);
  extern void detect_ht(struct cpuinfo_x86 *c);
@@@ -672,29 -670,18 +670,29 @@@ static inline void sync_core(void
  {
        int tmp;
  
 -#if defined(CONFIG_M386) || defined(CONFIG_M486)
 -      if (boot_cpu_data.x86 < 5)
 -              /* There is no speculative execution.
 -               * jmp is a barrier to prefetching. */
 -              asm volatile("jmp 1f\n1:\n" ::: "memory");
 -      else
 +#ifdef CONFIG_M486
 +      /*
 +       * Do a CPUID if available, otherwise do a jump.  The jump
 +       * can conveniently enough be the jump around CPUID.
 +       */
 +      asm volatile("cmpl %2,%1\n\t"
 +                   "jl 1f\n\t"
 +                   "cpuid\n"
 +                   "1:"
 +                   : "=a" (tmp)
 +                   : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
 +                   : "ebx", "ecx", "edx", "memory");
 +#else
 +      /*
 +       * CPUID is a barrier to speculative execution.
 +       * Prefetched instructions are automatically
 +       * invalidated when modified.
 +       */
 +      asm volatile("cpuid"
 +                   : "=a" (tmp)
 +                   : "0" (1)
 +                   : "ebx", "ecx", "edx", "memory");
  #endif
 -              /* cpuid is a barrier to speculative execution.
 -               * Prefetched instructions are automatically
 -               * invalidated when modified. */
 -              asm volatile("cpuid" : "=a" (tmp) : "0" (1)
 -                           : "ebx", "ecx", "edx", "memory");
  }
  
  static inline void __monitor(const void *eax, unsigned long ecx,
index ca165ac6793b9c3524bd21103c920848f4bef336,6a6432cf89de26519aa8ef20f95cddf841d8b8a8..9c3ab43a6954d7217f390ae1f4f54527de82d09b
@@@ -1173,15 -1173,6 +1173,6 @@@ DEFINE_PER_CPU(struct task_struct *, fp
  DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
  #endif
  
- /* Make sure %fs and %gs are initialized properly in idle threads */
- struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
- {
-       memset(regs, 0, sizeof(struct pt_regs));
-       regs->fs = __KERNEL_PERCPU;
-       regs->gs = __KERNEL_STACK_CANARY;
-       return regs;
- }
  #endif        /* CONFIG_X86_64 */
  
  /*
@@@ -1237,7 -1228,7 +1228,7 @@@ void __cpuinit cpu_init(void
        oist = &per_cpu(orig_ist, cpu);
  
  #ifdef CONFIG_NUMA
 -      if (cpu != 0 && this_cpu_read(numa_node) == 0 &&
 +      if (this_cpu_read(numa_node) == 0 &&
            early_cpu_to_node(cpu) != NUMA_NO_NODE)
                set_numa_node(early_cpu_to_node(cpu));
  #endif
        barrier();
  
        x86_configure_nx();
 -      if (cpu != 0)
 -              enable_x2apic();
 +      enable_x2apic();
  
        /*
         * set up and load the per-CPU TSS
index 31b46128a63d49800f8a7b9d6e2b34171edbb961,2363e820ed68c49ba64361c63e1ba1dd7a01097b..70641aff0c258227185b7584dfa579a9c1b4e4df
@@@ -56,7 -56,7 +56,7 @@@
  #include <asm/ftrace.h>
  #include <asm/percpu.h>
  #include <asm/asm.h>
 -#include <asm/rcu.h>
 +#include <asm/context_tracking.h>
  #include <asm/smap.h>
  #include <linux/err.h>
  
@@@ -845,9 -845,25 +845,25 @@@ ENTRY(\label
  END(\label)
        .endm
  
-       PTREGSCALL stub_clone, sys_clone, %r8
-       PTREGSCALL stub_fork, sys_fork, %rdi
-       PTREGSCALL stub_vfork, sys_vfork, %rdi
+       .macro FORK_LIKE func
+ ENTRY(stub_\func)
+       CFI_STARTPROC
+       popq    %r11                    /* save return address */
+       PARTIAL_FRAME 0
+       SAVE_REST
+       pushq   %r11                    /* put it back on stack */
+       FIXUP_TOP_OF_STACK %r11, 8
+       DEFAULT_FRAME 0 8               /* offset 8: return address */
+       call sys_\func
+       RESTORE_TOP_OF_STACK %r11, 8
+       ret $REST_SKIP          /* pop extended registers */
+       CFI_ENDPROC
+ END(stub_\func)
+       .endm
+       FORK_LIKE  clone
+       FORK_LIKE  fork
+       FORK_LIKE  vfork
        PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
        PTREGSCALL stub_iopl, sys_iopl, %rsi
  
@@@ -1699,10 -1715,9 +1715,10 @@@ nested_nmi
  
  1:
        /* Set up the interrupted NMIs stack to jump to repeat_nmi */
 -      leaq -6*8(%rsp), %rdx
 +      leaq -1*8(%rsp), %rdx
        movq %rdx, %rsp
 -      CFI_ADJUST_CFA_OFFSET 6*8
 +      CFI_ADJUST_CFA_OFFSET 1*8
 +      leaq -10*8(%rsp), %rdx
        pushq_cfi $__KERNEL_DS
        pushq_cfi %rdx
        pushfq_cfi
        pushq_cfi $repeat_nmi
  
        /* Put stack back */
 -      addq $(11*8), %rsp
 -      CFI_ADJUST_CFA_OFFSET -11*8
 +      addq $(6*8), %rsp
 +      CFI_ADJUST_CFA_OFFSET -6*8
  
  nested_nmi_out:
        popq_cfi %rdx
@@@ -1737,18 -1752,18 +1753,18 @@@ first_nmi
         * +-------------------------+
         * | NMI executing variable  |
         * +-------------------------+
 -       * | Saved SS                |
 -       * | Saved Return RSP        |
 -       * | Saved RFLAGS            |
 -       * | Saved CS                |
 -       * | Saved RIP               |
 -       * +-------------------------+
         * | copied SS               |
         * | copied Return RSP       |
         * | copied RFLAGS           |
         * | copied CS               |
         * | copied RIP              |
         * +-------------------------+
 +       * | Saved SS                |
 +       * | Saved Return RSP        |
 +       * | Saved RFLAGS            |
 +       * | Saved CS                |
 +       * | Saved RIP               |
 +       * +-------------------------+
         * | pt_regs                 |
         * +-------------------------+
         *
        /* Set the NMI executing variable on the stack. */
        pushq_cfi $1
  
 +      /*
 +       * Leave room for the "copied" frame
 +       */
 +      subq $(5*8), %rsp
 +
        /* Copy the stack frame to the Saved frame */
        .rept 5
 -      pushq_cfi 6*8(%rsp)
 +      pushq_cfi 11*8(%rsp)
        .endr
        CFI_DEF_CFA_OFFSET SS+8-RIP
  
@@@ -1792,15 -1802,12 +1808,15 @@@ repeat_nmi
         * is benign for the non-repeat case, where 1 was pushed just above
         * to this very stack slot).
         */
 -      movq $1, 5*8(%rsp)
 +      movq $1, 10*8(%rsp)
  
        /* Make another copy, this one may be modified by nested NMIs */
 +      addq $(10*8), %rsp
 +      CFI_ADJUST_CFA_OFFSET -10*8
        .rept 5
 -      pushq_cfi 4*8(%rsp)
 +      pushq_cfi -6*8(%rsp)
        .endr
 +      subq $(5*8), %rsp
        CFI_DEF_CFA_OFFSET SS+8-RIP
  end_repeat_nmi:
  
@@@ -1851,12 -1858,8 +1867,12 @@@ nmi_swapgs
        SWAPGS_UNSAFE_STACK
  nmi_restore:
        RESTORE_ALL 8
 +
 +      /* Pop the extra iret frame */
 +      addq $(5*8), %rsp
 +
        /* Clear the NMI executing stack variable */
 -      movq $0, 10*8(%rsp)
 +      movq $0, 5*8(%rsp)
        jmp irq_return
        CFI_ENDPROC
  END(nmi)
index 2f99e31218759b8b5c2ab27fca66391d66caeff8,fe94595932572af84317ef2cb3f0762915a55938..2ed787f15bf0cf397d6515c429d50544e04e9e34
@@@ -262,36 -262,6 +262,6 @@@ void __switch_to_xtra(struct task_struc
        propagate_user_return_notify(prev_p, next_p);
  }
  
- int sys_fork(struct pt_regs *regs)
- {
-       return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
- }
- /*
-  * This is trivial, and on the face of it looks like it
-  * could equally well be done in user mode.
-  *
-  * Not so, for quite unobvious reasons - register pressure.
-  * In user mode vfork() cannot have a stack frame, and if
-  * done by calling the "clone()" system call directly, you
-  * do not have enough call-clobbered registers to hold all
-  * the information you need.
-  */
- int sys_vfork(struct pt_regs *regs)
- {
-       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
-                      NULL, NULL);
- }
- long
- sys_clone(unsigned long clone_flags, unsigned long newsp,
-         void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
- {
-       if (!newsp)
-               newsp = regs->sp;
-       return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
- }
  /*
   * Idle related variables and functions
   */
@@@ -306,6 -276,11 +276,6 @@@ void (*pm_idle)(void)
  EXPORT_SYMBOL(pm_idle);
  #endif
  
 -static inline int hlt_use_halt(void)
 -{
 -      return 1;
 -}
 -
  #ifndef CONFIG_SMP
  static inline void play_dead(void)
  {
@@@ -405,22 -380,28 +375,22 @@@ void cpu_idle(void
   */
  void default_idle(void)
  {
 -      if (hlt_use_halt()) {
 -              trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
 -              trace_cpu_idle_rcuidle(1, smp_processor_id());
 -              current_thread_info()->status &= ~TS_POLLING;
 -              /*
 -               * TS_POLLING-cleared state must be visible before we
 -               * test NEED_RESCHED:
 -               */
 -              smp_mb();
 +      trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
 +      trace_cpu_idle_rcuidle(1, smp_processor_id());
 +      current_thread_info()->status &= ~TS_POLLING;
 +      /*
 +       * TS_POLLING-cleared state must be visible before we
 +       * test NEED_RESCHED:
 +       */
 +      smp_mb();
  
 -              if (!need_resched())
 -                      safe_halt();    /* enables interrupts racelessly */
 -              else
 -                      local_irq_enable();
 -              current_thread_info()->status |= TS_POLLING;
 -              trace_power_end_rcuidle(smp_processor_id());
 -              trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
 -      } else {
 +      if (!need_resched())
 +              safe_halt();    /* enables interrupts racelessly */
 +      else
                local_irq_enable();
 -              /* loop is done by the caller */
 -              cpu_relax();
 -      }
 +      current_thread_info()->status |= TS_POLLING;
 +      trace_power_end_rcuidle(smp_processor_id());
 +      trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
  }
  #ifdef CONFIG_APM_MODULE
  EXPORT_SYMBOL(default_idle);
diff --combined arch/x86/um/Kconfig
index b0c30dae9f559a0103fa15f85d33d479955ac2e6,8f51c39750d19c42700397506df03869d8f8dd43..983997041963840039ec12a076e9b879cfdae0c7
@@@ -25,13 -25,14 +25,14 @@@ config X86_3
        select HAVE_AOUT
        select ARCH_WANT_IPC_PARSE_VERSION
        select MODULES_USE_ELF_REL
+       select CLONE_BACKWARDS
  
  config X86_64
        def_bool 64BIT
        select MODULES_USE_ELF_RELA
  
  config RWSEM_XCHGADD_ALGORITHM
 -      def_bool X86_XADD && 64BIT
 +      def_bool 64BIT
  
  config RWSEM_GENERIC_SPINLOCK
        def_bool !RWSEM_XCHGADD_ALGORITHM
index bce6104bbab8762c64ef620620bae65539d844fd,39db582ab1a687c6a16c797ad025ea64c6877222..e0cb2ffb41beac080a07dcb2d476a9043cd37634
@@@ -186,7 -186,6 +186,7 @@@ static int init_usb(struct usbwm_dev *u
        struct rx_cxt   *rx = &udev->rx;
        struct usb_tx   *t;
        struct usb_rx   *r;
 +      unsigned long flags;
  
        INIT_LIST_HEAD(&tx->free_list);
        INIT_LIST_HEAD(&tx->sdu_list);
        spin_lock_init(&tx->lock);
        spin_lock_init(&rx->lock);
  
 +      spin_lock_irqsave(&tx->lock, flags);
        for (i = 0; i < MAX_NR_SDU_BUF; i++) {
                t = alloc_tx_struct(tx);
                if (t == NULL) {
 +                      spin_unlock_irqrestore(&tx->lock, flags);
                        ret = -ENOMEM;
                        goto fail;
                }
                list_add(&t->list, &tx->free_list);
        }
 +      spin_unlock_irqrestore(&tx->lock, flags);
  
        r = alloc_rx_struct(rx);
        if (r == NULL) {
                goto fail;
        }
  
 +      spin_lock_irqsave(&rx->lock, flags);
        list_add(&r->list, &rx->free_list);
 +      spin_unlock_irqrestore(&rx->lock, flags);
        return ret;
  
  fail:
@@@ -235,9 -229,6 +235,9 @@@ static void release_usb(struct usbwm_de
        struct rx_cxt   *rx = &udev->rx;
        struct usb_tx   *t, *t_next;
        struct usb_rx   *r, *r_next;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&tx->lock, flags);
  
        list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
                list_del(&t->list);
                free_tx_struct(t);
        }
  
 +      spin_unlock_irqrestore(&tx->lock, flags);
 +
 +      spin_lock_irqsave(&rx->lock, flags);
 +
        list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
                list_del(&r->list);
                free_rx_struct(r);
                list_del(&r->list);
                free_rx_struct(r);
        }
 +
 +      spin_unlock_irqrestore(&rx->lock, flags);
  }
  
  static void __gdm_usb_send_complete(struct urb *urb)
@@@ -318,12 -303,9 +318,12 @@@ static int gdm_usb_send(void *priv_dev
        u8 *pkt = data;
        u16 cmd_evt;
        unsigned long flags;
 +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE
 +      unsigned long flags2;
 +#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
  
        if (!udev->usbdev) {
 -              printk(KERN_ERR "%s: No such device\n", __func__);
 +              dev_err(&usbdev->dev, "%s: No such device\n", __func__);
                return -ENODEV;
        }
  
  
                rx = &udev->rx;
  
 +              spin_lock_irqsave(&rx->lock, flags2);
                list_for_each_entry(r, &rx->used_list, list)
                        usb_unlink_urb(r->urb);
 +              spin_unlock_irqrestore(&rx->lock, flags2);
 +
                udev->bw_switch = 1;
  
 -              spin_lock(&k_lock);
 +              spin_lock_irqsave(&k_lock, flags2);
                list_add_tail(&udev->list, &k_list);
 -              spin_unlock(&k_lock);
 +              spin_unlock_irqrestore(&k_lock, flags2);
  
                wake_up(&k_wait);
        }
@@@ -437,7 -416,7 +437,7 @@@ static void gdm_usb_rcv_complete(struc
        struct tx_cxt *tx = &udev->tx;
        struct usb_tx *t;
        u16 cmd_evt;
 -      unsigned long flags;
 +      unsigned long flags, flags2;
  
  #ifdef CONFIG_WIMAX_GDM72XX_USB_PM
        struct usb_device *dev = urb->dev;
        if (!urb->status && r->callback)
                r->callback(r->cb_data, r->buf, urb->actual_length);
  
 -      spin_lock(&rx->lock);
 +      spin_lock_irqsave(&rx->lock, flags2);
        put_rx_struct(rx, r);
 -      spin_unlock(&rx->lock);
 +      spin_unlock_irqrestore(&rx->lock, flags2);
  
        spin_unlock_irqrestore(&tx->lock, flags);
  
@@@ -505,7 -484,7 +505,7 @@@ static int gdm_usb_receive(void *priv_d
        unsigned long flags;
  
        if (!udev->usbdev) {
 -              printk(KERN_ERR "%s: No such device\n", __func__);
 +              dev_err(&usbdev->dev, "%s: No such device\n", __func__);
                return -ENODEV;
        }
  
@@@ -580,9 -559,9 +580,9 @@@ static int gdm_usb_probe(struct usb_int
        idProduct = L2H(usbdev->descriptor.idProduct);
        bcdDevice = L2H(usbdev->descriptor.bcdDevice);
  
 -      printk(KERN_INFO "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
 -              idVendor, idProduct);
 -      printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION);
 +      dev_info(&intf->dev, "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
 +               idVendor, idProduct);
 +      dev_info(&intf->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION);
  
  
        if (idProduct == EMERGENCY_PID) {
@@@ -640,9 -619,8 +640,9 @@@ out
        if (ret) {
                kfree(phy_dev);
                kfree(udev);
 +      } else {
 +              usb_set_intfdata(intf, phy_dev);
        }
 -      usb_set_intfdata(intf, phy_dev);
        return ret;
  }
  
@@@ -682,22 -660,14 +682,22 @@@ static int gdm_suspend(struct usb_inter
        struct usbwm_dev *udev;
        struct rx_cxt *rx;
        struct usb_rx *r;
 +      unsigned long flags;
  
        phy_dev = usb_get_intfdata(intf);
 +      if (!phy_dev)
 +              return 0;
 +
        udev = phy_dev->priv_dev;
        rx = &udev->rx;
  
 +      spin_lock_irqsave(&rx->lock, flags);
 +
        list_for_each_entry(r, &rx->used_list, list)
                usb_unlink_urb(r->urb);
  
 +      spin_unlock_irqrestore(&rx->lock, flags);
 +
        return 0;
  }
  
@@@ -707,22 -677,14 +707,22 @@@ static int gdm_resume(struct usb_interf
        struct usbwm_dev *udev;
        struct rx_cxt *rx;
        struct usb_rx *r;
 +      unsigned long flags;
  
        phy_dev = usb_get_intfdata(intf);
 +      if (!phy_dev)
 +              return 0;
 +
        udev = phy_dev->priv_dev;
        rx = &udev->rx;
  
 +      spin_lock_irqsave(&rx->lock, flags);
 +
        list_for_each_entry(r, &rx->used_list, list)
                usb_submit_urb(r->urb, GFP_ATOMIC);
  
 +      spin_unlock_irqrestore(&rx->lock, flags);
 +
        return 0;
  }
  
@@@ -739,8 -701,6 +739,6 @@@ static int k_mode_thread(void *arg
        unsigned long flags, flags2, expire;
        int ret;
  
-       daemonize("k_mode_wimax");
        while (!k_mode_stop) {
  
                spin_lock_irqsave(&k_lock, flags2);
                        while (jiffies < expire)
                                schedule_timeout(K_WAIT_TIME);
  
 +                      spin_lock_irqsave(&rx->lock, flags);
 +
                        list_for_each_entry(r, &rx->used_list, list)
                                usb_submit_urb(r->urb, GFP_ATOMIC);
  
 +                      spin_unlock_irqrestore(&rx->lock, flags);
 +
                        spin_lock_irqsave(&tx->lock, flags);
  
                        list_for_each_entry_safe(t, temp, &tx->pending_list,
@@@ -806,7 -762,7 +804,7 @@@ static struct usb_driver gdm_usb_drive
  static int __init usb_gdm_wimax_init(void)
  {
  #ifdef CONFIG_WIMAX_GDM72XX_K_MODE
-       kthread_run(k_mode_thread, NULL, "WiMax_thread");
+       kthread_run(k_mode_thread, NULL, "k_mode_wimax");
  #endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
        return usb_register(&gdm_usb_driver);
  }
diff --combined fs/file.c
index eff23162485f93176255199b3ed74176534ae489,7272a1c5831d87f710f379d76afda17ecafdfbd4..15cb8618e95d0cf6568e8e9dd68b37008ea4d435
+++ b/fs/file.c
@@@ -519,12 -519,6 +519,6 @@@ struct files_struct init_files = 
        .file_lock      = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
  };
  
- void daemonize_descriptors(void)
- {
-       atomic_inc(&init_files.count);
-       reset_files_struct(&init_files);
- }
  /*
   * allocate a file descriptor, mark it busy.
   */
@@@ -994,18 -988,16 +988,18 @@@ int iterate_fd(struct files_struct *fil
                const void *p)
  {
        struct fdtable *fdt;
 -      struct file *file;
        int res = 0;
        if (!files)
                return 0;
        spin_lock(&files->file_lock);
 -      fdt = files_fdtable(files);
 -      while (!res && n < fdt->max_fds) {
 -              file = rcu_dereference_check_fdtable(files, fdt->fd[n++]);
 -              if (file)
 -                      res = f(p, file, n);
 +      for (fdt = files_fdtable(files); n < fdt->max_fds; n++) {
 +              struct file *file;
 +              file = rcu_dereference_check_fdtable(files, fdt->fd[n]);
 +              if (!file)
 +                      continue;
 +              res = f(p, file, n);
 +              if (res)
 +                      break;
        }
        spin_unlock(&files->file_lock);
        return res;
diff --combined include/linux/sched.h
index b96ff1e43ada3dbd30c66272af02b081614e4280,1162258bcaf0a939d7bd3993c42e01008a88a743..651b51a36711103162ff9a9dc13eaca1c93bddc3
@@@ -109,8 -109,6 +109,8 @@@ extern void update_cpu_load_nohz(void)
  
  extern unsigned long get_parent_ip(unsigned long addr);
  
 +extern void dump_cpu_task(int cpu);
 +
  struct seq_file;
  struct cfs_rq;
  struct task_group;
@@@ -435,29 -433,14 +435,29 @@@ struct cpu_itimer 
        u32 incr_error;
  };
  
 +/**
 + * struct cputime - snaphsot of system and user cputime
 + * @utime: time spent in user mode
 + * @stime: time spent in system mode
 + *
 + * Gathers a generic snapshot of user and system time.
 + */
 +struct cputime {
 +      cputime_t utime;
 +      cputime_t stime;
 +};
 +
  /**
   * 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
 + * This is an extension of struct cputime that includes the total runtime
 + * spent by the task from the scheduler point of view.
 + *
 + * As a result, 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.
   */
@@@ -598,7 -581,7 +598,7 @@@ struct signal_struct 
        cputime_t gtime;
        cputime_t cgtime;
  #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 -      cputime_t prev_utime, prev_stime;
 +      struct cputime prev_cputime;
  #endif
        unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
        unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
        struct rw_semaphore group_rwsem;
  #endif
  
 -      int oom_score_adj;      /* OOM kill score adjustment */
 -      int oom_score_adj_min;  /* OOM kill score adjustment minimum value.
 -                               * Only settable by CAP_SYS_RESOURCE. */
 +      oom_flags_t oom_flags;
 +      short oom_score_adj;            /* OOM kill score adjustment */
 +      short oom_score_adj_min;        /* OOM kill score adjustment min value.
 +                                       * Only settable by CAP_SYS_RESOURCE. */
  
        struct mutex cred_guard_mutex;  /* guard against foreign influences on
                                         * credential calculations
@@@ -1079,7 -1061,6 +1079,7 @@@ struct sched_class 
  
  #ifdef CONFIG_SMP
        int  (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
 +      void (*migrate_task_rq)(struct task_struct *p, int next_cpu);
  
        void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
        void (*post_schedule) (struct rq *this_rq);
@@@ -1114,18 -1095,6 +1114,18 @@@ struct load_weight 
        unsigned long weight, inv_weight;
  };
  
 +struct sched_avg {
 +      /*
 +       * These sums represent an infinite geometric series and so are bound
 +       * above by 1024/(1-y).  Thus we only need a u32 to store them for for all
 +       * choices of y < 1-2^(-32)*1024.
 +       */
 +      u32 runnable_avg_sum, runnable_avg_period;
 +      u64 last_runnable_update;
 +      s64 decay_count;
 +      unsigned long load_avg_contrib;
 +};
 +
  #ifdef CONFIG_SCHEDSTATS
  struct sched_statistics {
        u64                     wait_start;
@@@ -1186,15 -1155,6 +1186,15 @@@ struct sched_entity 
        /* rq "owned" by this entity/group: */
        struct cfs_rq           *my_q;
  #endif
 +/*
 + * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be
 + * removed when useful for applications beyond shares distribution (e.g.
 + * load-balance).
 + */
 +#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED)
 +      /* Per-entity load-tracking */
 +      struct sched_avg        avg;
 +#endif
  };
  
  struct sched_rt_entity {
@@@ -1358,7 -1318,7 +1358,7 @@@ struct task_struct 
        cputime_t utime, stime, utimescaled, stimescaled;
        cputime_t gtime;
  #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 -      cputime_t prev_utime, prev_stime;
 +      struct cputime prev_cputime;
  #endif
        unsigned long nvcsw, nivcsw; /* context switch counts */
        struct timespec start_time;             /* monotonic time */
@@@ -1769,8 -1729,8 +1769,8 @@@ static inline void put_task_struct(stru
                __put_task_struct(t);
  }
  
 -extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
 -extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
 +extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
 +extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);
  
  /*
   * Per process flags
@@@ -1884,6 -1844,14 +1884,6 @@@ static inline void rcu_copy_process(str
  
  #endif
  
 -static inline void rcu_switch(struct task_struct *prev,
 -                            struct task_struct *next)
 -{
 -#ifdef CONFIG_RCU_USER_QS
 -      rcu_user_hooks_switch(prev, next);
 -#endif
 -}
 -
  static inline void tsk_restore_flags(struct task_struct *task,
                                unsigned long orig_flags, unsigned long flags)
  {
@@@ -2303,7 -2271,7 +2303,7 @@@ extern void mm_release(struct task_stru
  extern struct mm_struct *dup_mm(struct task_struct *tsk);
  
  extern int copy_thread(unsigned long, unsigned long, unsigned long,
-                       struct task_struct *, struct pt_regs *);
+                       struct task_struct *);
  extern void flush_thread(void);
  extern void exit_thread(void);
  
@@@ -2315,14 -2283,13 +2315,13 @@@ extern void flush_itimer_signals(void)
  
  extern void do_group_exit(int);
  
- extern void daemonize(const char *, ...);
  extern int allow_signal(int);
  extern int disallow_signal(int);
  
  extern int do_execve(const char *,
                     const char __user * const __user *,
-                    const char __user * const __user *, struct pt_regs *);
- extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
+                    const char __user * const __user *);
+ extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *);
  struct task_struct *fork_idle(int);
  #ifdef CONFIG_GENERIC_KERNEL_THREAD
  extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
diff --combined kernel/auditsc.c
index fc7376bf86ea8133e44677e6ede62fc9581dc6e6,c8ca7fafbcc9ddb2637793946e4dcdb748659c4f..e37e6a12c5e32c204ca93b4422c52ffaee72aad3
@@@ -200,7 -200,6 +200,6 @@@ struct audit_context 
        struct list_head    names_list; /* anchor for struct audit_names->list */
        char *              filterkey;  /* key for rule that triggered record */
        struct path         pwd;
-       struct audit_context *previous; /* For nested syscalls */
        struct audit_aux_data *aux;
        struct audit_aux_data *aux_pids;
        struct sockaddr_storage *sockaddr;
@@@ -1091,29 -1090,13 +1090,13 @@@ int audit_alloc(struct task_struct *tsk
  
  static inline void audit_free_context(struct audit_context *context)
  {
-       struct audit_context *previous;
-       int                  count = 0;
-       do {
-               previous = context->previous;
-               if (previous || (count &&  count < 10)) {
-                       ++count;
-                       printk(KERN_ERR "audit(:%d): major=%d name_count=%d:"
-                              " freeing multiple contexts (%d)\n",
-                              context->serial, context->major,
-                              context->name_count, count);
-               }
-               audit_free_names(context);
-               unroll_tree_refs(context, NULL, 0);
-               free_tree_refs(context);
-               audit_free_aux(context);
-               kfree(context->filterkey);
-               kfree(context->sockaddr);
-               kfree(context);
-               context  = previous;
-       } while (context);
-       if (count >= 10)
-               printk(KERN_ERR "audit: freed %d contexts\n", count);
+       audit_free_names(context);
+       unroll_tree_refs(context, NULL, 0);
+       free_tree_refs(context);
+       audit_free_aux(context);
+       kfree(context->filterkey);
+       kfree(context->sockaddr);
+       kfree(context);
  }
  
  void audit_log_task_context(struct audit_buffer *ab)
@@@ -1159,7 -1142,7 +1142,7 @@@ void audit_log_task_info(struct audit_b
        cred = current_cred();
  
        spin_lock_irq(&tsk->sighand->siglock);
 -      if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
 +      if (tsk->signal && tsk->signal->tty)
                tty = tsk->signal->tty->name;
        else
                tty = "(none)";
@@@ -1783,42 -1766,6 +1766,6 @@@ void __audit_syscall_entry(int arch, in
        if (!context)
                return;
  
-       /*
-        * This happens only on certain architectures that make system
-        * calls in kernel_thread via the entry.S interface, instead of
-        * with direct calls.  (If you are porting to a new
-        * architecture, hitting this condition can indicate that you
-        * got the _exit/_leave calls backward in entry.S.)
-        *
-        * i386     no
-        * x86_64   no
-        * ppc64    yes (see arch/powerpc/platforms/iseries/misc.S)
-        *
-        * This also happens with vm86 emulation in a non-nested manner
-        * (entries without exits), so this case must be caught.
-        */
-       if (context->in_syscall) {
-               struct audit_context *newctx;
- #if AUDIT_DEBUG
-               printk(KERN_ERR
-                      "audit(:%d) pid=%d in syscall=%d;"
-                      " entering syscall=%d\n",
-                      context->serial, tsk->pid, context->major, major);
- #endif
-               newctx = audit_alloc_context(context->state);
-               if (newctx) {
-                       newctx->previous   = context;
-                       context            = newctx;
-                       tsk->audit_context = newctx;
-               } else  {
-                       /* If we can't alloc a new context, the best we
-                        * can do is to leak memory (any pending putname
-                        * will be lost).  The only other alternative is
-                        * to abandon auditing. */
-                       audit_zero_context(context, context->state);
-               }
-       }
        BUG_ON(context->in_syscall || context->name_count);
  
        if (!audit_enabled)
@@@ -1881,28 -1828,21 +1828,21 @@@ void __audit_syscall_exit(int success, 
        if (!list_empty(&context->killed_trees))
                audit_kill_trees(&context->killed_trees);
  
-       if (context->previous) {
-               struct audit_context *new_context = context->previous;
-               context->previous  = NULL;
-               audit_free_context(context);
-               tsk->audit_context = new_context;
-       } else {
-               audit_free_names(context);
-               unroll_tree_refs(context, NULL, 0);
-               audit_free_aux(context);
-               context->aux = NULL;
-               context->aux_pids = NULL;
-               context->target_pid = 0;
-               context->target_sid = 0;
-               context->sockaddr_len = 0;
-               context->type = 0;
-               context->fds[0] = -1;
-               if (context->state != AUDIT_RECORD_CONTEXT) {
-                       kfree(context->filterkey);
-                       context->filterkey = NULL;
-               }
-               tsk->audit_context = context;
+       audit_free_names(context);
+       unroll_tree_refs(context, NULL, 0);
+       audit_free_aux(context);
+       context->aux = NULL;
+       context->aux_pids = NULL;
+       context->target_pid = 0;
+       context->target_sid = 0;
+       context->sockaddr_len = 0;
+       context->type = 0;
+       context->fds[0] = -1;
+       if (context->state != AUDIT_RECORD_CONTEXT) {
+               kfree(context->filterkey);
+               context->filterkey = NULL;
        }
+       tsk->audit_context = context;
  }
  
  static inline void handle_one(const struct inode *inode)
diff --combined kernel/exit.c
index 618f7ee560034a71faf2757c02858a3095358a00,f9275e2c7c2cf90ad94c517ed09f7d6eb36fc82b..50d2e93c36ea6ff421192e7fb0f92a3cb0df6e63
@@@ -322,43 -322,6 +322,6 @@@ kill_orphaned_pgrp(struct task_struct *
        }
  }
  
- /**
-  * reparent_to_kthreadd - Reparent the calling kernel thread to kthreadd
-  *
-  * If a kernel thread is launched as a result of a system call, or if
-  * it ever exits, it should generally reparent itself to kthreadd so it
-  * isn't in the way of other processes and is correctly cleaned up on exit.
-  *
-  * The various task state such as scheduling policy and priority may have
-  * been inherited from a user process, so we reset them to sane values here.
-  *
-  * NOTE that reparent_to_kthreadd() gives the caller full capabilities.
-  */
- static void reparent_to_kthreadd(void)
- {
-       write_lock_irq(&tasklist_lock);
-       ptrace_unlink(current);
-       /* Reparent to init */
-       current->real_parent = current->parent = kthreadd_task;
-       list_move_tail(&current->sibling, &current->real_parent->children);
-       /* Set the exit signal to SIGCHLD so we signal init on exit */
-       current->exit_signal = SIGCHLD;
-       if (task_nice(current) < 0)
-               set_user_nice(current, 0);
-       /* cpus_allowed? */
-       /* rt_priority? */
-       /* signals? */
-       memcpy(current->signal->rlim, init_task.signal->rlim,
-              sizeof(current->signal->rlim));
-       atomic_inc(&init_cred.usage);
-       commit_creds(&init_cred);
-       write_unlock_irq(&tasklist_lock);
- }
  void __set_special_pids(struct pid *pid)
  {
        struct task_struct *curr = current->group_leader;
                change_pid(curr, PIDTYPE_PGID, pid);
  }
  
- static void set_special_pids(struct pid *pid)
- {
-       write_lock_irq(&tasklist_lock);
-       __set_special_pids(pid);
-       write_unlock_irq(&tasklist_lock);
- }
  /*
   * Let kernel threads use this to say that they allow a certain signal.
   * Must not be used if kthread was cloned with CLONE_SIGHAND.
@@@ -416,54 -372,6 +372,6 @@@ int disallow_signal(int sig
  
  EXPORT_SYMBOL(disallow_signal);
  
- /*
-  *    Put all the gunge required to become a kernel thread without
-  *    attached user resources in one place where it belongs.
-  */
- void daemonize(const char *name, ...)
- {
-       va_list args;
-       sigset_t blocked;
-       va_start(args, name);
-       vsnprintf(current->comm, sizeof(current->comm), name, args);
-       va_end(args);
-       /*
-        * If we were started as result of loading a module, close all of the
-        * user space pages.  We don't need them, and if we didn't close them
-        * they would be locked into memory.
-        */
-       exit_mm(current);
-       /*
-        * We don't want to get frozen, in case system-wide hibernation
-        * or suspend transition begins right now.
-        */
-       current->flags |= (PF_NOFREEZE | PF_KTHREAD);
-       if (current->nsproxy != &init_nsproxy) {
-               get_nsproxy(&init_nsproxy);
-               switch_task_namespaces(current, &init_nsproxy);
-       }
-       set_special_pids(&init_struct_pid);
-       proc_clear_tty(current);
-       /* Block and flush all signals */
-       sigfillset(&blocked);
-       sigprocmask(SIG_BLOCK, &blocked, NULL);
-       flush_signals(current);
-       /* Become as one with the init task */
-       daemonize_fs_struct();
-       daemonize_descriptors();
-       reparent_to_kthreadd();
- }
- EXPORT_SYMBOL(daemonize);
  #ifdef CONFIG_MM_OWNER
  /*
   * A task is exiting.   If it owned this mm, find a new owner for the mm.
@@@ -1186,11 -1094,11 +1094,11 @@@ static int wait_task_zombie(struct wait
                 * as other threads in the parent group can be right
                 * here reaping other children at the same time.
                 *
 -               * We use thread_group_times() to get times for the thread
 +               * We use thread_group_cputime_adjusted() to get times for the thread
                 * group, which consolidates times for all threads in the
                 * group including the group leader.
                 */
 -              thread_group_times(p, &tgutime, &tgstime);
 +              thread_group_cputime_adjusted(p, &tgutime, &tgstime);
                spin_lock_irq(&p->real_parent->sighand->siglock);
                psig = p->real_parent->signal;
                sig = p->signal;
diff --combined kernel/fork.c
index 79de9f99a48dba7abf4ecfc54fa89209ac36a907,540730783433ccc87d8a6104a68b5a708c065414..3c31e874afad647bef83205fb7d2d0787207bb62
@@@ -352,7 -352,6 +352,7 @@@ static int dup_mmap(struct mm_struct *m
        unsigned long charge;
        struct mempolicy *pol;
  
 +      uprobe_start_dup_mmap();
        down_write(&oldmm->mmap_sem);
        flush_cache_dup_mm(oldmm);
        uprobe_dup_mmap(oldmm, mm);
@@@ -470,7 -469,6 +470,7 @@@ out
        up_write(&mm->mmap_sem);
        flush_tlb_mm(oldmm);
        up_write(&oldmm->mmap_sem);
 +      uprobe_end_dup_mmap();
        return retval;
  fail_nomem_anon_vma_fork:
        mpol_put(pol);
@@@ -1129,7 -1127,6 +1129,6 @@@ static void posix_cpu_timers_init(struc
   */
  static struct task_struct *copy_process(unsigned long clone_flags,
                                        unsigned long stack_start,
-                                       struct pt_regs *regs,
                                        unsigned long stack_size,
                                        int __user *child_tidptr,
                                        struct pid *pid,
  {
        int retval;
        struct task_struct *p;
 -      int cgroup_callbacks_done = 0;
  
        if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
                return ERR_PTR(-EINVAL);
        p->utime = p->stime = p->gtime = 0;
        p->utimescaled = p->stimescaled = 0;
  #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 -      p->prev_utime = p->prev_stime = 0;
 +      p->prev_cputime.utime = p->prev_cputime.stime = 0;
  #endif
  #if defined(SPLIT_RSS_COUNTING)
        memset(&p->rss_stat, 0, sizeof(p->rss_stat));
        retval = copy_io(clone_flags, p);
        if (retval)
                goto bad_fork_cleanup_namespaces;
-       retval = copy_thread(clone_flags, stack_start, stack_size, p, regs);
+       retval = copy_thread(clone_flags, stack_start, stack_size, p);
        if (retval)
                goto bad_fork_cleanup_io;
  
        INIT_LIST_HEAD(&p->thread_group);
        p->task_works = NULL;
  
 -      /* Now that the task is set up, run cgroup callbacks if
 -       * necessary. We need to run them before the task is visible
 -       * on the tasklist. */
 -      cgroup_fork_callbacks(p);
 -      cgroup_callbacks_done = 1;
 -
        /* Need tasklist lock for parent etc handling! */
        write_lock_irq(&tasklist_lock);
  
@@@ -1498,7 -1502,7 +1497,7 @@@ bad_fork_cleanup_cgroup
  #endif
        if (clone_flags & CLONE_THREAD)
                threadgroup_change_end(current);
 -      cgroup_exit(p, cgroup_callbacks_done);
 +      cgroup_exit(p, 0);
        delayacct_tsk_free(p);
        module_put(task_thread_info(p)->exec_domain->module);
  bad_fork_cleanup_count:
@@@ -1510,12 -1514,6 +1509,6 @@@ fork_out
        return ERR_PTR(retval);
  }
  
- noinline struct pt_regs * __cpuinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
- {
-       memset(regs, 0, sizeof(struct pt_regs));
-       return regs;
- }
  static inline void init_idle_pids(struct pid_link *links)
  {
        enum pid_type type;
  struct task_struct * __cpuinit fork_idle(int cpu)
  {
        struct task_struct *task;
-       struct pt_regs regs;
-       task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
-                           &init_struct_pid, 0);
+       task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0);
        if (!IS_ERR(task)) {
                init_idle_pids(task->pids);
                init_idle(task, cpu);
   */
  long do_fork(unsigned long clone_flags,
              unsigned long stack_start,
-             struct pt_regs *regs,
              unsigned long stack_size,
              int __user *parent_tidptr,
              int __user *child_tidptr)
         * requested, no event is reported; otherwise, report if the event
         * for the type of forking is enabled.
         */
-       if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) {
+       if (!(clone_flags & CLONE_UNTRACED)) {
                if (clone_flags & CLONE_VFORK)
                        trace = PTRACE_EVENT_VFORK;
                else if ((clone_flags & CSIGNAL) != SIGCHLD)
                        trace = 0;
        }
  
-       p = copy_process(clone_flags, stack_start, regs, stack_size,
+       p = copy_process(clone_flags, stack_start, stack_size,
                         child_tidptr, NULL, trace);
        /*
         * Do this prior waking up the new thread - the thread pointer
   */
  pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
  {
-       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, NULL,
+       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
                (unsigned long)arg, NULL, NULL);
  }
  #endif
  
+ #ifdef __ARCH_WANT_SYS_FORK
+ SYSCALL_DEFINE0(fork)
+ {
+ #ifdef CONFIG_MMU
+       return do_fork(SIGCHLD, 0, 0, NULL, NULL);
+ #else
+       /* can not support in nommu mode */
+       return(-EINVAL);
+ #endif
+ }
+ #endif
+ #ifdef __ARCH_WANT_SYS_VFORK
+ SYSCALL_DEFINE0(vfork)
+ {
+       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 
+                       0, NULL, NULL);
+ }
+ #endif
+ #ifdef __ARCH_WANT_SYS_CLONE
+ #ifdef CONFIG_CLONE_BACKWARDS
+ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
+                int __user *, parent_tidptr,
+                int, tls_val,
+                int __user *, child_tidptr)
+ #elif defined(CONFIG_CLONE_BACKWARDS2)
+ SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
+                int __user *, parent_tidptr,
+                int __user *, child_tidptr,
+                int, tls_val)
+ #else
+ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
+                int __user *, parent_tidptr,
+                int __user *, child_tidptr,
+                int, tls_val)
+ #endif
+ {
+       return do_fork(clone_flags, newsp, 0,
+               parent_tidptr, child_tidptr);
+ }
+ #endif
  #ifndef ARCH_MIN_MMSTRUCT_ALIGN
  #define ARCH_MIN_MMSTRUCT_ALIGN 0
  #endif
diff --combined kernel/signal.c
index 5ffb5626e0721d52e7230e02a809d904fb2c2666,e75e4bd2839bba251306bcfa7c1eb2e05afb944e..a49c7f36ceb3e595d98a437f0b3031a51cab305d
@@@ -1159,8 -1159,9 +1159,9 @@@ static int send_signal(int sig, struct 
        return __send_signal(sig, info, t, group, from_ancestor_ns);
  }
  
- static void print_fatal_signal(struct pt_regs *regs, int signr)
+ static void print_fatal_signal(int signr)
  {
+       struct pt_regs *regs = signal_pt_regs();
        printk("%s/%d: potentially unexpected fatal signal %d.\n",
                current->comm, task_pid_nr(current), signr);
  
@@@ -1908,7 -1909,7 +1909,7 @@@ static void ptrace_stop(int exit_code, 
                preempt_disable();
                read_unlock(&tasklist_lock);
                preempt_enable_no_resched();
 -              schedule();
 +              freezable_schedule();
        } else {
                /*
                 * By the time we got the lock, our tracer went away.
                read_unlock(&tasklist_lock);
        }
  
 -      /*
 -       * While in TASK_TRACED, we were considered "frozen enough".
 -       * Now that we woke up, it's crucial if we're supposed to be
 -       * frozen that we freeze now before running anything substantial.
 -       */
 -      try_to_freeze();
 -
        /*
         * We are back.  Now reacquire the siglock before touching
         * last_siginfo, so that we are sure to have synchronized with
@@@ -2085,7 -2093,7 +2086,7 @@@ static bool do_signal_stop(int signr
                }
  
                /* Now we don't run again until woken by SIGCONT or SIGKILL */
 -              schedule();
 +              freezable_schedule();
                return true;
        } else {
                /*
@@@ -2131,10 -2139,9 +2132,9 @@@ static void do_jobctl_trap(void
        }
  }
  
- static int ptrace_signal(int signr, siginfo_t *info,
-                        struct pt_regs *regs, void *cookie)
+ static int ptrace_signal(int signr, siginfo_t *info)
  {
-       ptrace_signal_deliver(regs, cookie);
+       ptrace_signal_deliver();
        /*
         * We do not check sig_kernel_stop(signr) but set this marker
         * unconditionally because we do not know whether debugger will
@@@ -2193,14 -2200,15 +2193,14 @@@ int get_signal_to_deliver(siginfo_t *in
        if (unlikely(uprobe_deny_signal()))
                return 0;
  
 -relock:
        /*
 -       * We'll jump back here after any time we were stopped in TASK_STOPPED.
 -       * While in TASK_STOPPED, we were considered "frozen enough".
 -       * Now that we woke up, it's crucial if we're supposed to be
 -       * frozen that we freeze now before running anything substantial.
 +       * Do this once, we can't return to user-mode if freezing() == T.
 +       * do_signal_stop() and ptrace_stop() do freezable_schedule() and
 +       * thus do not need another check after return.
         */
        try_to_freeze();
  
 +relock:
        spin_lock_irq(&sighand->siglock);
        /*
         * Every stopped thread goes here after wakeup. Check to see if
                        break; /* will return 0 */
  
                if (unlikely(current->ptrace) && signr != SIGKILL) {
-                       signr = ptrace_signal(signr, info,
-                                             regs, cookie);
+                       signr = ptrace_signal(signr, info);
                        if (!signr)
                                continue;
                }
  
                if (sig_kernel_coredump(signr)) {
                        if (print_fatal_signals)
-                               print_fatal_signal(regs, info->si_signo);
+                               print_fatal_signal(info->si_signo);
                        /*
                         * If it was able to dump core, this kills all
                         * other threads in the group and synchronizes with
                         * first and our do_group_exit call below will use
                         * that value and ignore the one we pass it.
                         */
-                       do_coredump(info, regs);
+                       do_coredump(info);
                }
  
                /*