]> Git Repo - linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
authorLinus Torvalds <[email protected]>
Wed, 10 Oct 2012 03:02:25 +0000 (12:02 +0900)
committerLinus Torvalds <[email protected]>
Wed, 10 Oct 2012 03:02:25 +0000 (12:02 +0900)
Pull generic execve() changes from Al Viro:
 "This introduces the generic kernel_thread() and kernel_execve()
  functions, and switches x86, arm, alpha, um and s390 over to them."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (26 commits)
  s390: convert to generic kernel_execve()
  s390: switch to generic kernel_thread()
  s390: fold kernel_thread_helper() into ret_from_fork()
  s390: fold execve_tail() into start_thread(), convert to generic sys_execve()
  um: switch to generic kernel_thread()
  x86, um/x86: switch to generic sys_execve and kernel_execve
  x86: split ret_from_fork
  alpha: introduce ret_from_kernel_execve(), switch to generic kernel_execve()
  alpha: switch to generic kernel_thread()
  alpha: switch to generic sys_execve()
  arm: get rid of execve wrapper, switch to generic execve() implementation
  arm: optimized current_pt_regs()
  arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve()
  arm: split ret_from_fork, simplify kernel_thread() [based on patch by rmk]
  generic sys_execve()
  generic kernel_execve()
  new helper: current_pt_regs()
  preparation for generic kernel_thread()
  um: kill thread->forking
  um: let signal_delivered() do SIGTRAP on singlestepping into handler
  ...

57 files changed:
1  2 
arch/Kconfig
arch/alpha/include/asm/Kbuild
arch/alpha/kernel/process.c
arch/arm/Kconfig
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/process.c
arch/avr32/include/asm/Kbuild
arch/c6x/include/asm/Kbuild
arch/cris/include/asm/Kbuild
arch/frv/include/asm/Kbuild
arch/h8300/include/asm/Kbuild
arch/ia64/include/asm/Kbuild
arch/m32r/include/asm/Kbuild
arch/m68k/include/asm/Kbuild
arch/microblaze/include/asm/Kbuild
arch/mn10300/include/asm/Kbuild
arch/parisc/include/asm/Kbuild
arch/s390/Kconfig
arch/s390/include/asm/processor.h
arch/s390/include/asm/unistd.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_linux.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/entry64.S
arch/s390/kernel/process.c
arch/sparc/include/asm/Kbuild
arch/tile/include/asm/Kbuild
arch/um/include/asm/processor-generic.h
arch/um/kernel/exec.c
arch/um/kernel/process.c
arch/um/kernel/syscall.c
arch/unicore32/include/asm/Kbuild
arch/x86/Kconfig
arch/x86/ia32/ia32entry.S
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/processor.h
arch/x86/include/asm/sys_ia32.h
arch/x86/include/asm/thread_info.h
arch/x86/kernel/Makefile
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/signal.c
arch/x86/um/Kconfig
arch/xtensa/include/asm/Kbuild
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/exec.c
include/linux/binfmts.h
include/linux/compat.h
include/linux/ptrace.h
include/linux/sched.h
kernel/fork.c

diff --combined arch/Kconfig
index 550cce4dd64840a2f0be048ffb046b6d4a2dafae,d397e11d167d9c9923e418dcb3599a3a14de6590..26a28419cafcc400afb7300c702687b8d2dc103e
@@@ -222,19 -222,6 +222,19 @@@ config HAVE_PERF_EVENTS_NM
          subsystem.  Also has support for calculating CPU cycle events
          to determine how many clock cycles in a given period.
  
 +config HAVE_PERF_REGS
 +      bool
 +      help
 +        Support selective register dumps for perf events. This includes
 +        bit-mapping of each registers and a unique architecture id.
 +
 +config HAVE_PERF_USER_STACK_DUMP
 +      bool
 +      help
 +        Support user stack dumps for perf event samples. This needs
 +        access to the user stack pointer which is not unified across
 +        architectures.
 +
  config HAVE_ARCH_JUMP_LABEL
        bool
  
@@@ -271,6 -258,9 +271,9 @@@ config ARCH_WANT_OLD_COMPAT_IP
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
        bool
  
+ config GENERIC_KERNEL_THREAD
+       bool
  config HAVE_ARCH_SECCOMP_FILTER
        bool
        help
@@@ -294,26 -284,4 +297,26 @@@ config SECCOMP_FILTE
  
          See Documentation/prctl/seccomp_filter.txt for details.
  
 +config HAVE_RCU_USER_QS
 +      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.
 +
 +config HAVE_VIRT_CPU_ACCOUNTING
 +      bool
 +
 +config HAVE_IRQ_TIME_ACCOUNTING
 +      bool
 +      help
 +        Archs need to ensure they use a high enough resolution clock to
 +        support irq time accounting and then call enable_sched_clock_irqtime().
 +
 +config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 +      bool
 +
  source "kernel/gcov/Kconfig"
index d97d66334e6f87fa4d3024e9a98e0517ccadc8a1,3bae7c9a0477cade57e125b628dcc324fff12600..64ffc9e9e5485a41b29e0836773389582dfac2fe
@@@ -1,7 -1,5 +1,7 @@@
  include include/asm-generic/Kbuild.asm
  
 +generic-y += clkdev.h
 +
  header-y += compiler.h
  header-y += console.h
  header-y += fpu.h
@@@ -10,3 -8,4 +10,4 @@@ header-y += pal.
  header-y += reg.h
  header-y += regdef.h
  header-y += sysinfo.h
+ generic-y += exec.h
index 83638aa096d562d803a8ffb3632dbb971db6da3d,f47d764eaa11f8f387ced58725fb8000e99bda39..4054e0ffe2b25a1055deb3946167755dc73fb201
@@@ -28,7 -28,6 +28,7 @@@
  #include <linux/tty.h>
  #include <linux/console.h>
  #include <linux/slab.h>
 +#include <linux/rcupdate.h>
  
  #include <asm/reg.h>
  #include <asm/uaccess.h>
@@@ -55,12 -54,9 +55,12 @@@ cpu_idle(void
                /* FIXME -- EV6 and LCA45 know how to power down
                   the CPU.  */
  
 +              rcu_idle_enter();
                while (!need_resched())
                        cpu_relax();
 -              schedule();
 +
 +              rcu_idle_exit();
 +              schedule_preempt_disabled();
        }
  }
  
@@@ -263,33 -259,35 +263,35 @@@ alpha_vfork(struct pt_regs *regs
  
  /*
   * Copy an alpha thread..
-  *
-  * Note the "stack_offset" stuff: when returning to kernel mode, we need
-  * to have some extra stack-space for the kernel stack that still exists
-  * after the "ret_from_fork".  When returning to user mode, we only want
-  * the space needed by the syscall stack frame (ie "struct pt_regs").
-  * Use the passed "regs" pointer to determine how much space we need
-  * for a kernel fork().
   */
  
  int
  copy_thread(unsigned long clone_flags, unsigned long usp,
-           unsigned long unused,
+           unsigned long arg,
            struct task_struct * p, struct pt_regs * regs)
  {
        extern void ret_from_fork(void);
+       extern void ret_from_kernel_thread(void);
  
        struct thread_info *childti = task_thread_info(p);
-       struct pt_regs * childregs;
-       struct switch_stack * childstack, *stack;
-       unsigned long stack_offset, settls;
-       stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
-       if (!(regs->ps & 8))
-               stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
-       childregs = (struct pt_regs *)
-         (stack_offset + PAGE_SIZE + task_stack_page(p));
-               
+       struct pt_regs *childregs = task_pt_regs(p);
+       struct switch_stack *childstack, *stack;
+       unsigned long settls;
+       childstack = ((struct switch_stack *) childregs) - 1;
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childstack, 0,
+                       sizeof(struct switch_stack) + sizeof(struct pt_regs));
+               childstack->r26 = (unsigned long) ret_from_kernel_thread;
+               childstack->r9 = usp;   /* function */
+               childstack->r10 = arg;
+               childregs->hae = alpha_mv.hae_cache,
+               childti->pcb.usp = 0;
+               childti->pcb.ksp = (unsigned long) childstack;
+               childti->pcb.flags = 1; /* set FEN, clear everything else */
+               return 0;
+       }
        *childregs = *regs;
        settls = regs->r20;
        childregs->r0 = 0;
        childregs->r20 = 1;     /* OSF/1 has some strange fork() semantics.  */
        regs->r20 = 0;
        stack = ((struct switch_stack *) regs) - 1;
-       childstack = ((struct switch_stack *) childregs) - 1;
        *childstack = *stack;
        childstack->r26 = (unsigned long) ret_from_fork;
        childti->pcb.usp = usp;
@@@ -385,27 -382,6 +386,6 @@@ dump_elf_task_fp(elf_fpreg_t *dest, str
  }
  EXPORT_SYMBOL(dump_elf_task_fp);
  
- /*
-  * sys_execve() executes a new program.
-  */
- asmlinkage int
- do_sys_execve(const char __user *ufilename,
-             const char __user *const __user *argv,
-             const char __user *const __user *envp, struct pt_regs *regs)
- {
-       int error;
-       char *filename;
-       filename = getname(ufilename);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               goto out;
-       error = do_execve(filename, argv, envp, regs);
-       putname(filename);
- out:
-       return error;
- }
  /*
   * Return saved PC of a blocked thread.  This assumes the frame
   * pointer is the 6th saved long on the kernel stack and that the
@@@ -459,22 -435,3 +439,3 @@@ get_wchan(struct task_struct *p
        }
        return pc;
  }
- int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
- {
-       /* Avoid the HAE being gratuitously wrong, which would cause us
-          to do the whole turn off interrupts thing and restore it.  */
-       struct pt_regs regs = {.hae = alpha_mv.hae_cache};
-       int err = do_execve(path, argv, envp, &regs);
-       if (!err) {
-               struct pt_regs *p = current_pt_regs();
-               /* copy regs to normal position and off to userland we go... */
-               *p = regs;
-               __asm__ __volatile__ (
-                       "mov    %0, $sp;"
-                       "br     $31, ret_from_sys_call"
-                       : : "r"(p));
-       }
-       return err;
- }
- EXPORT_SYMBOL(kernel_execve);
diff --combined arch/arm/Kconfig
index 2867a7742306c3b9d3de7edbfd3d4f546e9c8cca,a949eec2286190c8739e60017165f2e50381b917..e40eefb5d32d805c0d8ed5f6d212a754a515fe76
@@@ -16,7 -16,6 +16,7 @@@ config AR
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
 +      select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_KPROBES if !XIP_KERNEL
        select HAVE_KRETPROBES if (HAVE_KPROBES)
        select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
@@@ -25,7 -24,6 +25,7 @@@
        select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
        select ARCH_BINFMT_ELF_RANDOMIZE_PIE
        select HAVE_GENERIC_DMA_COHERENT
 +      select HAVE_DEBUG_KMEMLEAK
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_LZMA
@@@ -40,7 -38,6 +40,7 @@@
        select HARDIRQS_SW_RESEND
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
 +      select HAVE_UID16
        select ARCH_WANT_IPC_PARSE_VERSION
        select HARDIRQS_SW_RESEND
        select CPU_PM if (SUSPEND || CPU_IDLE)
@@@ -52,6 -49,7 +52,7 @@@
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
+       select GENERIC_KERNEL_THREAD
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
@@@ -205,13 -203,6 +206,13 @@@ config ARM_PATCH_PHYS_VIR
          this feature (eg, building a kernel for a single machine) and
          you need to shrink the kernel to the minimal size.
  
 +config NEED_MACH_GPIO_H
 +      bool
 +      help
 +        Select this when mach/gpio.h is required to provide special
 +        definitions for this platform. The need for mach/gpio.h should
 +        be avoided when possible.
 +
  config NEED_MACH_IO_H
        bool
        help
@@@ -257,29 -248,39 +258,29 @@@ config MM
  #
  choice
        prompt "ARM system type"
 -      default ARCH_VERSATILE
 +      default ARCH_MULTIPLATFORM
  
 -config ARCH_SOCFPGA
 -      bool "Altera SOCFPGA family"
 -      select ARCH_WANT_OPTIONAL_GPIOLIB
 -      select ARM_AMBA
 -      select ARM_GIC
 -      select CACHE_L2X0
 -      select CLKDEV_LOOKUP
 +config ARCH_MULTIPLATFORM
 +      bool "Allow multiple platforms to be selected"
 +      select ARM_PATCH_PHYS_VIRT
 +      select AUTO_ZRELADDR
        select COMMON_CLK
 -      select CPU_V7
 -      select DW_APB_TIMER
 -      select DW_APB_TIMER_OF
 -      select GENERIC_CLOCKEVENTS
 -      select GPIO_PL061 if GPIOLIB
 -      select HAVE_ARM_SCU
 +      select MULTI_IRQ_HANDLER
        select SPARSE_IRQ
        select USE_OF
 -      help
 -        This enables support for Altera SOCFPGA Cyclone V platform
 +      depends on MMU
  
  config ARCH_INTEGRATOR
        bool "ARM Ltd. Integrator family"
        select ARM_AMBA
        select ARCH_HAS_CPUFREQ
        select COMMON_CLK
 -      select CLK_VERSATILE
 +      select COMMON_CLK_VERSATILE
        select HAVE_TCM
        select ICST
        select GENERIC_CLOCKEVENTS
        select PLAT_VERSATILE
        select PLAT_VERSATILE_FPGA_IRQ
 -      select NEED_MACH_IO_H
        select NEED_MACH_MEMORY_H
        select SPARSE_IRQ
        select MULTI_IRQ_HANDLER
  config ARCH_REALVIEW
        bool "ARM Ltd. RealView family"
        select ARM_AMBA
 -      select CLKDEV_LOOKUP
 -      select HAVE_MACH_CLKDEV
 +      select COMMON_CLK
 +      select COMMON_CLK_VERSATILE
        select ICST
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select PLAT_VERSATILE
 -      select PLAT_VERSATILE_CLOCK
        select PLAT_VERSATILE_CLCD
        select ARM_TIMER_SP804
        select GPIO_PL061 if GPIOLIB
@@@ -311,6 -313,7 +312,6 @@@ config ARCH_VERSATIL
        select ICST
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
 -      select NEED_MACH_IO_H if PCI
        select PLAT_VERSATILE
        select PLAT_VERSATILE_CLOCK
        select PLAT_VERSATILE_CLCD
        help
          This enables support for ARM Ltd Versatile board.
  
 -config ARCH_VEXPRESS
 -      bool "ARM Ltd. Versatile Express family"
 -      select ARCH_WANT_OPTIONAL_GPIOLIB
 -      select ARM_AMBA
 -      select ARM_TIMER_SP804
 -      select CLKDEV_LOOKUP
 -      select COMMON_CLK
 -      select GENERIC_CLOCKEVENTS
 -      select HAVE_CLK
 -      select HAVE_PATA_PLATFORM
 -      select ICST
 -      select NO_IOPORT
 -      select PLAT_VERSATILE
 -      select PLAT_VERSATILE_CLCD
 -      select REGULATOR_FIXED_VOLTAGE if REGULATOR
 -      help
 -        This enables support for the ARM Ltd Versatile Express boards.
 -
  config ARCH_AT91
        bool "Atmel AT91"
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
        select CLKDEV_LOOKUP
        select IRQ_DOMAIN
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_IO_H if PCCARD
        help
          This enables support for systems based on Atmel
          AT91RM9200 and AT91SAM9* processors.
  
 -config ARCH_BCMRING
 -      bool "Broadcom BCMRING"
 -      depends on MMU
 -      select CPU_V6
 -      select ARM_AMBA
 -      select ARM_TIMER_SP804
 -      select CLKDEV_LOOKUP
 -      select GENERIC_CLOCKEVENTS
 -      select ARCH_WANT_OPTIONAL_GPIOLIB
 -      help
 -        Support for Broadcom's BCMRing platform.
 -
 -config ARCH_HIGHBANK
 -      bool "Calxeda Highbank-based"
 +config ARCH_BCM2835
 +      bool "Broadcom BCM2835 family"
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_AMBA
 -      select ARM_GIC
 +      select ARM_ERRATA_411920
        select ARM_TIMER_SP804
 -      select CACHE_L2X0
        select CLKDEV_LOOKUP
        select COMMON_CLK
 -      select CPU_V7
 +      select CPU_V6
        select GENERIC_CLOCKEVENTS
 -      select HAVE_ARM_SCU
 -      select HAVE_SMP
 +      select MULTI_IRQ_HANDLER
        select SPARSE_IRQ
        select USE_OF
        help
 -        Support for the Calxeda Highbank SoC based boards.
 +        This enables support for the Broadcom BCM2835 SoC. This SoC is
 +        use in the Raspberry Pi, and Roku 2 devices.
  
  config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
        select CPU_ARM720T
        select ARCH_USES_GETTIMEOFFSET
 +      select COMMON_CLK
 +      select CLKDEV_LOOKUP
        select NEED_MACH_MEMORY_H
        help
          Support for Cirrus Logic 711x/721x/731x based boards.
@@@ -377,19 -408,21 +378,19 @@@ config ARCH_GEMIN
        help
          Support for the Cortina Systems Gemini family SoCs
  
 -config ARCH_PRIMA2
 -      bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
 -      select CPU_V7
 +config ARCH_SIRF
 +      bool "CSR SiRF"
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_CLOCKEVENTS
 -      select CLKDEV_LOOKUP
 +      select COMMON_CLK
        select GENERIC_IRQ_CHIP
        select MIGHT_HAVE_CACHE_L2X0
        select PINCTRL
        select PINCTRL_SIRF
        select USE_OF
 -      select ZONE_DMA
        help
 -          Support for CSR SiRFSoC ARM Cortex A9 Platform
 +        Support for CSR SiRFprimaII/Marco/Polo platforms
  
  config ARCH_EBSA110
        bool "EBSA-110"
@@@ -424,7 -457,7 +425,7 @@@ config ARCH_FOOTBRIDG
        select FOOTBRIDGE
        select GENERIC_CLOCKEVENTS
        select HAVE_IDE
 -      select NEED_MACH_IO_H
 +      select NEED_MACH_IO_H if !MMU
        select NEED_MACH_MEMORY_H
        help
          Support for systems based on the DC21285 companion chip
@@@ -451,9 -484,7 +452,9 @@@ config ARCH_MX
        select CLKSRC_MMIO
        select COMMON_CLK
        select HAVE_CLK_PREPARE
 +      select MULTI_IRQ_HANDLER
        select PINCTRL
 +      select SPARSE_IRQ
        select USE_OF
        help
          Support for Freescale MXS-based family of processors
@@@ -483,6 -514,7 +484,6 @@@ config ARCH_IOP13X
        select PCI
        select ARCH_SUPPORTS_MSI
        select VMSPLIT_1G
 -      select NEED_MACH_IO_H
        select NEED_MACH_MEMORY_H
        select NEED_RET_TO_USER
        help
@@@ -492,7 -524,6 +493,7 @@@ config ARCH_IOP32
        bool "IOP32x-based"
        depends on MMU
        select CPU_XSCALE
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_IO_H
        select NEED_RET_TO_USER
        select PLAT_IOP
@@@ -506,7 -537,6 +507,7 @@@ config ARCH_IOP33
        bool "IOP33x-based"
        depends on MMU
        select CPU_XSCALE
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_IO_H
        select NEED_RET_TO_USER
        select PLAT_IOP
@@@ -529,14 -559,26 +530,14 @@@ config ARCH_IXP4X
        help
          Support for Intel's IXP4XX (XScale) family of processors.
  
 -config ARCH_MVEBU
 -      bool "Marvell SOCs with Device Tree support"
 -      select GENERIC_CLOCKEVENTS
 -      select MULTI_IRQ_HANDLER
 -      select SPARSE_IRQ
 -      select CLKSRC_MMIO
 -      select GENERIC_IRQ_CHIP
 -      select IRQ_DOMAIN
 -      select COMMON_CLK
 -      help
 -        Support for the Marvell SoC Family with device tree support
 -
  config ARCH_DOVE
        bool "Marvell Dove"
        select CPU_V7
 -      select PCI
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_CLOCKEVENTS
 -      select NEED_MACH_IO_H
 -      select PLAT_ORION
 +      select MIGHT_HAVE_PCI
 +      select PLAT_ORION_LEGACY
 +      select USB_ARCH_HAS_EHCI
        help
          Support for the Marvell Dove SoC 88AP510
  
@@@ -546,7 -588,8 +547,7 @@@ config ARCH_KIRKWOO
        select PCI
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_CLOCKEVENTS
 -      select NEED_MACH_IO_H
 -      select PLAT_ORION
 +      select PLAT_ORION_LEGACY
        help
          Support for the following Marvell Kirkwood series SoCs:
          88F6180, 88F6192 and 88F6281.
@@@ -572,7 -615,8 +573,7 @@@ config ARCH_MV78XX
        select PCI
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_CLOCKEVENTS
 -      select NEED_MACH_IO_H
 -      select PLAT_ORION
 +      select PLAT_ORION_LEGACY
        help
          Support for the following Marvell MV78xx0 series SoCs:
          MV781x0, MV782x0.
@@@ -584,7 -628,8 +585,7 @@@ config ARCH_ORION5
        select PCI
        select ARCH_REQUIRE_GPIOLIB
        select GENERIC_CLOCKEVENTS
 -      select NEED_MACH_IO_H
 -      select PLAT_ORION
 +      select PLAT_ORION_LEGACY
        help
          Support for the following Marvell Orion 5x series SoCs:
          Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
@@@ -601,7 -646,6 +602,7 @@@ config ARCH_MM
        select PLAT_PXA
        select SPARSE_IRQ
        select GENERIC_ALLOCATOR
 +      select NEED_MACH_GPIO_H
        help
          Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
  
@@@ -609,9 -653,8 +610,9 @@@ config ARCH_KS869
        bool "Micrel/Kendin KS8695"
        select CPU_ARM922T
        select ARCH_REQUIRE_GPIOLIB
 -      select ARCH_USES_GETTIMEOFFSET
        select NEED_MACH_MEMORY_H
 +      select CLKSRC_MMIO
 +      select GENERIC_CLOCKEVENTS
        help
          Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
          System-on-Chip devices.
@@@ -641,13 -684,40 +642,13 @@@ config ARCH_TEGR
        select HAVE_CLK
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
 -      select NEED_MACH_IO_H if PCI
        select ARCH_HAS_CPUFREQ
        select USE_OF
 +      select COMMON_CLK
        help
          This enables support for NVIDIA Tegra based systems (Tegra APX,
          Tegra 6xx and Tegra 2 series).
  
 -config ARCH_PICOXCELL
 -      bool "Picochip picoXcell"
 -      select ARCH_REQUIRE_GPIOLIB
 -      select ARM_PATCH_PHYS_VIRT
 -      select ARM_VIC
 -      select CPU_V6K
 -      select DW_APB_TIMER
 -      select DW_APB_TIMER_OF
 -      select GENERIC_CLOCKEVENTS
 -      select GENERIC_GPIO
 -      select HAVE_TCM
 -      select NO_IOPORT
 -      select SPARSE_IRQ
 -      select USE_OF
 -      help
 -        This enables support for systems based on the Picochip picoXcell
 -        family of Femtocell devices.  The picoxcell support requires device tree
 -        for all boards.
 -
 -config ARCH_PNX4008
 -      bool "Philips Nexperia PNX4008 Mobile"
 -      select CPU_ARM926T
 -      select CLKDEV_LOOKUP
 -      select ARCH_USES_GETTIMEOFFSET
 -      help
 -        This enables support for Philips PNX4008 mobile platform.
 -
  config ARCH_PXA
        bool "PXA2xx/PXA3xx-based"
        depends on MMU
        select MULTI_IRQ_HANDLER
        select ARM_CPU_SUSPEND if PM
        select HAVE_IDE
 +      select NEED_MACH_GPIO_H
        help
          Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
  
@@@ -727,7 -796,6 +728,7 @@@ config ARCH_SA110
        select CLKDEV_LOOKUP
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_IDE
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_MEMORY_H
        select SPARSE_IRQ
        help
@@@ -743,7 -811,6 +744,7 @@@ config ARCH_S3C24X
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C_RTC if RTC_CLASS
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_IO_H
        help
          Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443
@@@ -771,7 -838,6 +772,7 @@@ config ARCH_S3C64X
        select SAMSUNG_GPIOLIB_4BIT
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
 +      select NEED_MACH_GPIO_H
        help
          Samsung S3C64XX series based systems
  
@@@ -786,7 -852,6 +787,7 @@@ config ARCH_S5P64X
        select GENERIC_CLOCKEVENTS
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C_RTC if RTC_CLASS
 +      select NEED_MACH_GPIO_H
        help
          Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
          SMDK6450.
@@@ -801,7 -866,6 +802,7 @@@ config ARCH_S5PC10
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C_RTC if RTC_CLASS
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
 +      select NEED_MACH_GPIO_H
        help
          Samsung S5PC100 series based systems
  
@@@ -819,7 -883,6 +820,7 @@@ config ARCH_S5PV21
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C_RTC if RTC_CLASS
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_MEMORY_H
        help
          Samsung S5PV210/S5PC110 series based systems
@@@ -837,7 -900,6 +838,7 @@@ config ARCH_EXYNO
        select HAVE_S3C_RTC if RTC_CLASS
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
 +      select NEED_MACH_GPIO_H
        select NEED_MACH_MEMORY_H
        help
          Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
@@@ -851,6 -913,7 +852,6 @@@ config ARCH_SHAR
        select PCI
        select ARCH_USES_GETTIMEOFFSET
        select NEED_MACH_MEMORY_H
 -      select NEED_MACH_IO_H
        help
          Support for the StrongARM based Digital DNARD machine, also known
          as "Shark" (<http://www.shark-linux.de/shark.html>).
@@@ -869,7 -932,6 +870,7 @@@ config ARCH_U30
        select COMMON_CLK
        select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
 +      select SPARSE_IRQ
        help
          Support for ST-Ericsson U300 series mobile platforms.
  
@@@ -895,7 -957,6 +896,7 @@@ config ARCH_NOMADI
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select PINCTRL
 +      select PINCTRL_STN8815
        select MIGHT_HAVE_CACHE_L2X0
        select ARCH_REQUIRE_GPIOLIB
        help
@@@ -911,7 -972,6 +912,7 @@@ config ARCH_DAVINC
        select GENERIC_ALLOCATOR
        select GENERIC_IRQ_CHIP
        select ARCH_HAS_HOLES_MEMORYMODEL
 +      select NEED_MACH_GPIO_H
        help
          Support for TI's DaVinci platform.
  
@@@ -924,7 -984,6 +925,7 @@@ config ARCH_OMA
        select CLKSRC_MMIO
        select GENERIC_CLOCKEVENTS
        select ARCH_HAS_HOLES_MEMORYMODEL
 +      select NEED_MACH_GPIO_H
        help
          Support for TI's OMAP platform (OMAP1/2/3/4).
  
@@@ -947,10 -1006,6 +948,10 @@@ config ARCH_VT850
        select ARCH_HAS_CPUFREQ
        select GENERIC_CLOCKEVENTS
        select ARCH_REQUIRE_GPIOLIB
 +      select USE_OF
 +      select COMMON_CLK
 +      select HAVE_CLK
 +      select CLKDEV_LOOKUP
        help
          Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
  
@@@ -968,50 -1023,6 +969,50 @@@ config ARCH_ZYN
          Support for Xilinx Zynq ARM Cortex A9 Platform
  endchoice
  
 +menu "Multiple platform selection"
 +      depends on ARCH_MULTIPLATFORM
 +
 +comment "CPU Core family selection"
 +
 +config ARCH_MULTI_V4
 +      bool "ARMv4 based platforms (FA526, StrongARM)"
 +      select ARCH_MULTI_V4_V5
 +      depends on !ARCH_MULTI_V6_V7
 +
 +config ARCH_MULTI_V4T
 +      bool "ARMv4T based platforms (ARM720T, ARM920T, ...)"
 +      select ARCH_MULTI_V4_V5
 +      depends on !ARCH_MULTI_V6_V7
 +
 +config ARCH_MULTI_V5
 +      bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)"
 +      select ARCH_MULTI_V4_V5
 +      depends on !ARCH_MULTI_V6_V7
 +
 +config ARCH_MULTI_V4_V5
 +      bool
 +
 +config ARCH_MULTI_V6
 +      bool "ARMv6 based platforms (ARM11, Scorpion, ...)"
 +      select CPU_V6
 +      select ARCH_MULTI_V6_V7
 +
 +config ARCH_MULTI_V7
 +      bool "ARMv7 based platforms (Cortex-A, PJ4, Krait)"
 +      select CPU_V7
 +      select ARCH_VEXPRESS
 +      default y
 +      select ARCH_MULTI_V6_V7
 +
 +config ARCH_MULTI_V6_V7
 +      bool
 +
 +config ARCH_MULTI_CPU_AUTO
 +      def_bool !(ARCH_MULTI_V4 || ARCH_MULTI_V4T || ARCH_MULTI_V6_V7)
 +      select ARCH_MULTI_V5
 +
 +endmenu
 +
  #
  # This is sorted alphabetically by mach-* pathname.  However, plat-*
  # Kconfigs may be included either alphabetically (according to the
@@@ -1021,6 -1032,8 +1022,6 @@@ source "arch/arm/mach-mvebu/Kconfig
  
  source "arch/arm/mach-at91/Kconfig"
  
 -source "arch/arm/mach-bcmring/Kconfig"
 -
  source "arch/arm/mach-clps711x/Kconfig"
  
  source "arch/arm/mach-cns3xxx/Kconfig"
@@@ -1037,8 -1050,6 +1038,8 @@@ source "arch/arm/mach-gemini/Kconfig
  
  source "arch/arm/mach-h720x/Kconfig"
  
 +source "arch/arm/mach-highbank/Kconfig"
 +
  source "arch/arm/mach-integrator/Kconfig"
  
  source "arch/arm/mach-iop32x/Kconfig"
@@@ -1074,8 -1085,6 +1075,8 @@@ source "arch/arm/mach-omap2/Kconfig
  
  source "arch/arm/mach-orion5x/Kconfig"
  
 +source "arch/arm/mach-picoxcell/Kconfig"
 +
  source "arch/arm/mach-pxa/Kconfig"
  source "arch/arm/plat-pxa/Kconfig"
  
@@@ -1088,8 -1097,6 +1089,8 @@@ source "arch/arm/mach-sa1100/Kconfig
  source "arch/arm/plat-samsung/Kconfig"
  source "arch/arm/plat-s3c24xx/Kconfig"
  
 +source "arch/arm/mach-socfpga/Kconfig"
 +
  source "arch/arm/plat-spear/Kconfig"
  
  source "arch/arm/mach-s3c24xx/Kconfig"
@@@ -1112,8 -1119,6 +1113,8 @@@ source "arch/arm/mach-exynos/Kconfig
  
  source "arch/arm/mach-shmobile/Kconfig"
  
 +source "arch/arm/mach-prima2/Kconfig"
 +
  source "arch/arm/mach-tegra/Kconfig"
  
  source "arch/arm/mach-u300/Kconfig"
@@@ -1125,6 -1130,8 +1126,6 @@@ source "arch/arm/mach-versatile/Kconfig
  source "arch/arm/mach-vexpress/Kconfig"
  source "arch/arm/plat-versatile/Kconfig"
  
 -source "arch/arm/mach-vt8500/Kconfig"
 -
  source "arch/arm/mach-w90x900/Kconfig"
  
  # Definitions to make life easier
@@@ -1142,10 -1149,6 +1143,10 @@@ config PLAT_ORIO
        select IRQ_DOMAIN
        select COMMON_CLK
  
 +config PLAT_ORION_LEGACY
 +      bool
 +      select PLAT_ORION
 +
  config PLAT_PXA
        bool
  
@@@ -1177,6 -1180,12 +1178,6 @@@ config XSCALE_PM
        depends on CPU_XSCALE
        default y
  
 -config CPU_HAS_PMU
 -      depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
 -                 (!ARCH_OMAP3 || OMAP3_EMU)
 -      default y
 -      bool
 -
  config MULTI_IRQ_HANDLER
        bool
        help
@@@ -1405,16 -1414,6 +1406,16 @@@ config PL310_ERRATA_76941
          on systems with an outer cache, the store buffer is drained
          explicitly.
  
 +config ARM_ERRATA_775420
 +       bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
 +       depends on CPU_V7
 +       help
 +       This option enables the workaround for the 775420 Cortex-A9 (r2p2,
 +       r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance
 +       operation aborts with MMU exception, it might cause the processor
 +       to deadlock. This workaround puts DSB before executing ISB if
 +       an abort may occur on cache maintenance.
 +
  endmenu
  
  source "arch/arm/common/Kconfig"
@@@ -1625,7 -1624,6 +1626,7 @@@ config ARCH_NR_GPI
        default 355 if ARCH_U8500
        default 264 if MACH_H4700
        default 512 if SOC_OMAP5
 +      default 288 if ARCH_VT8500
        default 0
        help
          Maximum number of GPIOs in the system.
@@@ -1760,7 -1758,7 +1761,7 @@@ config HIGHPT
  
  config HW_PERF_EVENTS
        bool "Enable hardware performance counter support for perf events"
 -      depends on PERF_EVENTS && CPU_HAS_PMU
 +      depends on PERF_EVENTS
        default y
        help
          Enable hardware performance counter support for perf events. If
@@@ -1784,6 -1782,59 +1785,6 @@@ config FORCE_MAX_ZONEORDE
          This config option is actually maximum order plus one. For example,
          a value of 11 means that the largest free memory block is 2^10 pages.
  
 -config LEDS
 -      bool "Timer and CPU usage LEDs"
 -      depends on ARCH_CDB89712 || ARCH_EBSA110 || \
 -                 ARCH_EBSA285 || ARCH_INTEGRATOR || \
 -                 ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
 -                 ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
 -                 ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
 -                 ARCH_AT91 || ARCH_DAVINCI || \
 -                 ARCH_KS8695 || MACH_RD88F5182 || ARCH_REALVIEW
 -      help
 -        If you say Y here, the LEDs on your machine will be used
 -        to provide useful information about your current system status.
 -
 -        If you are compiling a kernel for a NetWinder or EBSA-285, you will
 -        be able to select which LEDs are active using the options below. If
 -        you are compiling a kernel for the EBSA-110 or the LART however, the
 -        red LED will simply flash regularly to indicate that the system is
 -        still functional. It is safe to say Y here if you have a CATS
 -        system, but the driver will do nothing.
 -
 -config LEDS_TIMER
 -      bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
 -                          OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
 -                          || MACH_OMAP_PERSEUS2
 -      depends on LEDS
 -      depends on !GENERIC_CLOCKEVENTS
 -      default y if ARCH_EBSA110
 -      help
 -        If you say Y here, one of the system LEDs (the green one on the
 -        NetWinder, the amber one on the EBSA285, or the red one on the LART)
 -        will flash regularly to indicate that the system is still
 -        operational. This is mainly useful to kernel hackers who are
 -        debugging unstable kernels.
 -
 -        The LART uses the same LED for both Timer LED and CPU usage LED
 -        functions. You may choose to use both, but the Timer LED function
 -        will overrule the CPU usage LED.
 -
 -config LEDS_CPU
 -      bool "CPU usage LED" if (!ARCH_CDB89712 && !ARCH_EBSA110 && \
 -                      !ARCH_OMAP) \
 -                      || OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
 -                      || MACH_OMAP_PERSEUS2
 -      depends on LEDS
 -      help
 -        If you say Y here, the red LED will be used to give a good real
 -        time indication of CPU usage, by lighting whenever the idle task
 -        is not currently executing.
 -
 -        The LART uses the same LED for both Timer LED and CPU usage LED
 -        functions. You may choose to use both, but the Timer LED function
 -        will overrule the CPU usage LED.
 -
  config ALIGNMENT_TRAP
        bool
        depends on CPU_CP15_MMU
          configuration it is safe to say N, otherwise say Y.
  
  config UACCESS_WITH_MEMCPY
 -      bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)"
 -      depends on MMU && EXPERIMENTAL
 +      bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()"
 +      depends on MMU
        default y if CPU_FEROCEON
        help
          Implement faster copy_to_user and clear_user methods for CPU
@@@ -1841,15 -1892,11 +1842,15 @@@ config CC_STACKPROTECTO
          neutralized via a kernel panic.
          This feature requires gcc version 4.2 or above.
  
 -config DEPRECATED_PARAM_STRUCT
 -      bool "Provide old way to pass kernel parameters"
 +config XEN_DOM0
 +      def_bool y
 +      depends on XEN
 +
 +config XEN
 +      bool "Xen guest support on ARM (EXPERIMENTAL)"
 +      depends on EXPERIMENTAL && ARM && OF
        help
 -        This was deprecated in 2001 and announced to live on for 5 years.
 -        Some old boot loaders still use this way.
 +        Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
  
  endmenu
  
@@@ -1863,23 -1910,6 +1864,23 @@@ config USE_O
        help
          Include support for flattened device tree machine descriptions.
  
 +config ATAGS
 +      bool "Support for the traditional ATAGS boot data passing" if USE_OF
 +      default y
 +      help
 +        This is the traditional way of passing data to the kernel at boot
 +        time. If you are solely relying on the flattened device tree (or
 +        the ARM_ATAG_DTB_COMPAT option) then you may unselect this option
 +        to remove ATAGS support from your kernel binary.  If unsure,
 +        leave this to y.
 +
 +config DEPRECATED_PARAM_STRUCT
 +      bool "Provide old way to pass kernel parameters"
 +      depends on ATAGS
 +      help
 +        This was deprecated in 2001 and announced to live on for 5 years.
 +        Some old boot loaders still use this way.
 +
  # Compressed boot loader in ROM.  Yes, we really want to ask about
  # TEXT and BSS so we preserve their values in the config files.
  config ZBOOT_ROM_TEXT
@@@ -2006,7 -2036,6 +2007,7 @@@ config CMDLIN
  choice
        prompt "Kernel command line type" if CMDLINE != ""
        default CMDLINE_FROM_BOOTLOADER
 +      depends on ATAGS
  
  config CMDLINE_FROM_BOOTLOADER
        bool "Use bootloader kernel arguments if available"
@@@ -2032,7 -2061,7 +2033,7 @@@ endchoic
  
  config XIP_KERNEL
        bool "Kernel Execute-In-Place from ROM"
 -      depends on !ZBOOT_ROM && !ARM_LPAE
 +      depends on !ZBOOT_ROM && !ARM_LPAE && !ARCH_MULTIPLATFORM
        help
          Execute-In-Place allows the kernel to run from non-volatile storage
          directly addressable by the CPU, such as NOR flash. This saves RAM
@@@ -2076,7 -2105,7 +2077,7 @@@ config KEXE
  
  config ATAGS_PROC
        bool "Export atags in procfs"
 -      depends on KEXEC
 +      depends on ATAGS && KEXEC
        default y
        help
          Should the atags used to boot the kernel be exported in an "atags"
@@@ -2285,7 -2314,7 +2286,7 @@@ menu "Power management options
  source "kernel/power/Kconfig"
  
  config ARCH_SUSPEND_POSSIBLE
 -      depends on !ARCH_S5PC100 && !ARCH_TEGRA
 +      depends on !ARCH_S5PC100
        depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
                CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
        def_bool y
index d9ff5cc3a5060177be581772cf22ead601ad4f65,6a70aa42debb1ab738eef726c98f84ad7c0c72ab..f259921edfe9a124ee68169a3455f35b45cdde8f
  #define __NR_setns                    (__NR_SYSCALL_BASE+375)
  #define __NR_process_vm_readv         (__NR_SYSCALL_BASE+376)
  #define __NR_process_vm_writev                (__NR_SYSCALL_BASE+377)
 +                                      /* 378 for kcmp */
 +
 +/*
 + * This may need to be greater than __NR_last_syscall+1 in order to
 + * account for the padding in the syscall table
 + */
 +#ifdef __KERNEL__
 +#define __NR_syscalls  (380)
 +#endif /* __KERNEL__ */
  
  /*
   * The following SWIs are ARM private.
  #define __ARCH_WANT_OLD_READDIR
  #define __ARCH_WANT_SYS_SOCKETCALL
  #endif
+ #define __ARCH_WANT_SYS_EXECVE
+ #define __ARCH_WANT_KERNEL_EXECVE
  
  /*
   * "Conditional" syscalls
   */
  #define __IGNORE_fadvise64_64
  #define __IGNORE_migrate_pages
 +#define __IGNORE_kcmp
  
  #endif /* __KERNEL__ */
  #endif /* __ASM_ARM_UNISTD_H */
diff --combined arch/arm/kernel/calls.S
index e337879595e565e5666cbd8ac0c40a4a72908c0e,b287b3580a9f8b9d902aba2f2595eddbed57bace..831cd38c8d997b32f895fa077f3745c08879d99d
@@@ -20,7 -20,7 +20,7 @@@
                CALL(sys_creat)
                CALL(sys_link)
  /* 10 */      CALL(sys_unlink)
-               CALL(sys_execve_wrapper)
+               CALL(sys_execve)
                CALL(sys_chdir)
                CALL(OBSOLETE(sys_time))        /* used by libc4 */
                CALL(sys_mknod)
  /* 375 */     CALL(sys_setns)
                CALL(sys_process_vm_readv)
                CALL(sys_process_vm_writev)
 +              CALL(sys_ni_syscall)    /* reserved for sys_kcmp */
  #ifndef syscalls_counted
  .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
  #define syscalls_counted
index f45987037bf1c4467396799a117245cfede3d0d1,ed7941277ca2b467ee1771a3e45dfe0a5d793715..e340fa1db203ea0dd5d78ca9a2e19e7cacf2395e
@@@ -91,18 -91,33 +91,42 @@@ ENTRY(ret_from_fork
        b       ret_slow_syscall
  ENDPROC(ret_from_fork)
  
+ ENTRY(ret_from_kernel_thread)
+  UNWIND(.fnstart)
+  UNWIND(.cantunwind)
+       bl      schedule_tail
+       mov     r0, r4
+       adr     lr, BSYM(1f)    @ kernel threads should not exit
+       mov     pc, r5
+ 1:    bl      do_exit
+       nop
+  UNWIND(.fnend)
+ ENDPROC(ret_from_kernel_thread)
+ /*
+  * turn a kernel thread into userland process
+  * use: ret_from_kernel_execve(struct pt_regs *normal)
+  */
+ ENTRY(ret_from_kernel_execve)
+       mov     why, #0                 @ not a syscall
+       str     why, [r0, #S_R0]        @ ... and we want 0 in ->ARM_r0 as well
+       get_thread_info tsk             @ thread structure
+       mov     sp, r0                  @ stack pointer just under pt_regs
+       b       ret_slow_syscall
+ ENDPROC(ret_from_kernel_execve)
        .equ NR_syscalls,0
  #define CALL(x) .equ NR_syscalls,NR_syscalls+1
  #include "calls.S"
 +
 +/*
 + * Ensure that the system call table is equal to __NR_syscalls,
 + * which is the value the rest of the system sees
 + */
 +.ifne NR_syscalls - __NR_syscalls
 +.error "__NR_syscalls is not equal to the size of the syscall table"
 +.endif
 +
  #undef CALL
  #define CALL(x) .long x
  
@@@ -517,11 -532,6 +541,6 @@@ sys_vfork_wrapper
                b       sys_vfork
  ENDPROC(sys_vfork_wrapper)
  
- sys_execve_wrapper:
-               add     r3, sp, #S_OFF
-               b       sys_execve
- ENDPROC(sys_execve_wrapper)
  sys_clone_wrapper:
                add     ip, sp, #S_OFF
                str     ip, [sp, #4]
index 04eea22d7958637f17456c7e2f37ac7b71e8e182,c10e4395bc47c20b14ae09dd6e212d6c027849b9..f98c17ff1957cc921c1e7a7459802f03e539a8de
@@@ -31,9 -31,9 +31,9 @@@
  #include <linux/random.h>
  #include <linux/hw_breakpoint.h>
  #include <linux/cpuidle.h>
 +#include <linux/leds.h>
  
  #include <asm/cacheflush.h>
 -#include <asm/leds.h>
  #include <asm/processor.h>
  #include <asm/thread_notify.h>
  #include <asm/stacktrace.h>
@@@ -189,7 -189,7 +189,7 @@@ void cpu_idle(void
        while (1) {
                tick_nohz_idle_enter();
                rcu_idle_enter();
 -              leds_event(led_idle_start);
 +              ledtrig_cpu(CPU_LED_IDLE_START);
                while (!need_resched()) {
  #ifdef CONFIG_HOTPLUG_CPU
                        if (cpu_is_offline(smp_processor_id()))
                        } else
                                local_irq_enable();
                }
 -              leds_event(led_idle_end);
 +              ledtrig_cpu(CPU_LED_IDLE_END);
                rcu_idle_exit();
                tick_nohz_idle_exit();
                schedule_preempt_disabled();
@@@ -373,6 -373,7 +373,7 @@@ void release_thread(struct task_struct 
  }
  
  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+ asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
  
  int
  copy_thread(unsigned long clone_flags, unsigned long stack_start,
        struct thread_info *thread = task_thread_info(p);
        struct pt_regs *childregs = task_pt_regs(p);
  
-       *childregs = *regs;
-       childregs->ARM_r0 = 0;
-       childregs->ARM_sp = stack_start;
        memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+       if (likely(regs)) {
+               *childregs = *regs;
+               childregs->ARM_r0 = 0;
+               childregs->ARM_sp = stack_start;
+               thread->cpu_context.pc = (unsigned long)ret_from_fork;
+       } else {
+               thread->cpu_context.r4 = stk_sz;
+               thread->cpu_context.r5 = stack_start;
+               thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+               childregs->ARM_cpsr = SVC_MODE;
+       }
        thread->cpu_context.sp = (unsigned long)childregs;
-       thread->cpu_context.pc = (unsigned long)ret_from_fork;
  
        clear_ptrace_hw_breakpoint(p);
  
@@@ -423,63 -431,6 +431,6 @@@ int dump_fpu (struct pt_regs *regs, str
  }
  EXPORT_SYMBOL(dump_fpu);
  
- /*
-  * Shuffle the argument into the correct register before calling the
-  * thread function.  r4 is the thread argument, r5 is the pointer to
-  * the thread function, and r6 points to the exit function.
-  */
- extern void kernel_thread_helper(void);
- asm(  ".pushsection .text\n"
- "     .align\n"
- "     .type   kernel_thread_helper, #function\n"
- "kernel_thread_helper:\n"
- #ifdef CONFIG_TRACE_IRQFLAGS
- "     bl      trace_hardirqs_on\n"
- #endif
- "     msr     cpsr_c, r7\n"
- "     mov     r0, r4\n"
- "     mov     lr, r6\n"
- "     mov     pc, r5\n"
- "     .size   kernel_thread_helper, . - kernel_thread_helper\n"
- "     .popsection");
- #ifdef CONFIG_ARM_UNWIND
- extern void kernel_thread_exit(long code);
- asm(  ".pushsection .text\n"
- "     .align\n"
- "     .type   kernel_thread_exit, #function\n"
- "kernel_thread_exit:\n"
- "     .fnstart\n"
- "     .cantunwind\n"
- "     bl      do_exit\n"
- "     nop\n"
- "     .fnend\n"
- "     .size   kernel_thread_exit, . - kernel_thread_exit\n"
- "     .popsection");
- #else
- #define kernel_thread_exit    do_exit
- #endif
- /*
-  * Create a kernel thread.
-  */
- pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
- {
-       struct pt_regs regs;
-       memset(&regs, 0, sizeof(regs));
-       regs.ARM_r4 = (unsigned long)arg;
-       regs.ARM_r5 = (unsigned long)fn;
-       regs.ARM_r6 = (unsigned long)kernel_thread_exit;
-       regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
-       regs.ARM_pc = (unsigned long)kernel_thread_helper;
-       regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
-       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
- }
- EXPORT_SYMBOL(kernel_thread);
  unsigned long get_wchan(struct task_struct *p)
  {
        struct stackframe frame;
index e3ba7bca06fae732929e28a4b00be0374883de17,aa47fff70760b4fd0e4a2cf21521483fb4a00a13..be0433ee5a8ec79c86a1d049cca58a6890df3230
@@@ -1,5 -1,4 +1,6 @@@
  include include/asm-generic/Kbuild.asm
  
 +generic-y     += clkdev.h
+ generic-y     += exec.h
 +
  header-y      += cachectl.h
index 277f1a4ecb0954ca63c5c64e1314973d0a9dddd3,e59c9f027523d36bfa3a875c62f66d6db52111a5..4e4e98da8192f375207203e29774b1bbc3c5dd8b
@@@ -2,7 -2,6 +2,7 @@@ include include/asm-generic/Kbuild.as
  
  generic-y += atomic.h
  generic-y += auxvec.h
 +generic-y += barrier.h
  generic-y += bitsperlong.h
  generic-y += bugs.h
  generic-y += cputime.h
@@@ -12,6 -11,7 +12,7 @@@ generic-y += div64.
  generic-y += dma.h
  generic-y += emergency-restart.h
  generic-y += errno.h
+ generic-y += exec.h
  generic-y += fb.h
  generic-y += fcntl.h
  generic-y += futex.h
@@@ -40,7 -40,6 +41,7 @@@ generic-y += sembuf.
  generic-y += shmbuf.h
  generic-y += shmparam.h
  generic-y += siginfo.h
 +generic-y += signal.h
  generic-y += socket.h
  generic-y += sockios.h
  generic-y += stat.h
index a8eab26a1ec752e38d794c767bd96d5aac5373ae,b68ad4bfa088cffd5293fc4c3cfad53e6b060c45..ff1bf7fcae8e116d86f23a7c05d825fd4ebc60b5
@@@ -8,4 -8,4 +8,5 @@@ header-y += etraxgpio.
  header-y += rs485.h
  header-y += sync_serial.h
  
 +generic-y += clkdev.h
+ generic-y += exec.h
index 13cd044aabdfe43ece5b8345f291e1291e86c6e7,32c16468cf5e74e677edd6e014b9bd1f40b29ce8..251bd7125576861ca09380768a0279dae258f753
@@@ -2,4 -2,4 +2,5 @@@ include include/asm-generic/Kbuild.as
  
  header-y += registers.h
  header-y += termios.h
 +generic-y += clkdev.h
+ generic-y += exec.h
index 0e152a93c1259a551ffa65b327ae5f9b013be3dd,3a2af1a2974fc49e21586455c608d3b192f613f4..fccd81eddff1f6de89b07cc13c362809364c9507
@@@ -1,3 -1,2 +1,4 @@@
  include include/asm-generic/Kbuild.asm
- generic-y     += clkdev.h
 +
++generic-y += clkdev.h
+ generic-y += exec.h
index 58f3d14a6cd4029b18531bcd1d0224d8337f7d3e,98efd48d7da4dfbeefa23a55022d893165d483c2..562f59315847cae6de4782e3f1bed6cc0e1883eb
@@@ -13,4 -13,4 +13,5 @@@ header-y += ptrace_offsets.
  header-y += rse.h
  header-y += ucontext.h
  header-y += ustack.h
 +generic-y += clkdev.h
+ generic-y += exec.h
index 0e152a93c1259a551ffa65b327ae5f9b013be3dd,708340339b057e16c4accba616fd5d37ffa53838..fccd81eddff1f6de89b07cc13c362809364c9507
@@@ -1,3 -1,3 +1,4 @@@
  include include/asm-generic/Kbuild.asm
  
- generic-y     += clkdev.h
++generic-y += clkdev.h
+ generic-y += exec.h
index bfe675f0faee5a1b6bda67ecf9bc4ac006f63f87,a9d1bf1400f8496a5fa0cb5446b969cb103ba823..ecb540810ab3ace200ae66368d700d97b4abf0d2
@@@ -2,11 -2,11 +2,12 @@@ include include/asm-generic/Kbuild.as
  header-y += cachectl.h
  
  generic-y += bitsperlong.h
 +generic-y += clkdev.h
  generic-y += cputime.h
  generic-y += device.h
  generic-y += emergency-restart.h
  generic-y += errno.h
+ generic-y += exec.h
  generic-y += futex.h
  generic-y += ioctl.h
  generic-y += ipcbuf.h
index 48510f6cec8f23f924c9bdc1781540282bcb0a7b,5a0e72bf998d90516f3acbd5a3275093b4dd0dd7..8653072d7e9f061479c5b11c5de056337cfdac7a
@@@ -1,4 -1,4 +1,5 @@@
  include include/asm-generic/Kbuild.asm
  
  header-y  += elf.h
 +generic-y += clkdev.h
+ generic-y += exec.h
index 0d20f5526dd8e99b7ba770d677bc17480f4bdb40,708340339b057e16c4accba616fd5d37ffa53838..fccd81eddff1f6de89b07cc13c362809364c9507
@@@ -1,3 -1,3 +1,4 @@@
  include include/asm-generic/Kbuild.asm
  
 +generic-y += clkdev.h
+ generic-y += exec.h
index 0587f62e5b76027291cea9dd62954d230cc38c06,818d6516567864cb0a4f52361ee863774e01dece..458371a1565aa2fdcbaa75e27ab398d8741019a9
@@@ -1,5 -1,5 +1,6 @@@
  include include/asm-generic/Kbuild.asm
  
  header-y += pdc.h
 +generic-y += clkdev.h
  generic-y += word-at-a-time.h
+ generic-y += exec.h
diff --combined arch/s390/Kconfig
index ceff7aef2477ad5ff896db12886204e773475d28,57442393bac72783270ccce346f3972b1aa8bea5..99d2d790d1528c256c2fe6c2099fdc0809988382
@@@ -49,13 -49,10 +49,13 @@@ config GENERIC_LOCKBREA
  config PGSTE
        def_bool y if KVM
  
 -config VIRT_CPU_ACCOUNTING
 +config ARCH_SUPPORTS_DEBUG_PAGEALLOC
        def_bool y
  
 -config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 +config KEXEC
 +      def_bool y
 +
 +config AUDIT_ARCH
        def_bool y
  
  config S390
@@@ -68,7 -65,6 +68,7 @@@
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_C_RECORDMCOUNT
        select HAVE_SYSCALL_TRACEPOINTS
 +      select SYSCTL_EXCEPTION_TRACE
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_REGS_AND_STACK_ACCESS_API
@@@ -81,7 -77,6 +81,7 @@@
        select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
 +      select HAVE_DEBUG_KMEMLEAK
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_XZ
        select HAVE_ARCH_MUTEX_CPU_RELAX
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
 +      select HAVE_BPF_JIT if 64BIT && PACK_STACK
        select ARCH_SAVE_PAGE_KEYS if HIBERNATION
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_CMPXCHG_LOCAL
 +      select HAVE_CMPXCHG_DOUBLE
 +      select HAVE_VIRT_CPU_ACCOUNTING
 +      select VIRT_CPU_ACCOUNTING
        select ARCH_DISCARD_MEMBLOCK
        select BUILDTIME_EXTABLE_SORT
        select ARCH_INLINE_SPIN_TRYLOCK
        select ARCH_INLINE_WRITE_UNLOCK_BH
        select ARCH_INLINE_WRITE_UNLOCK_IRQ
        select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
 +      select HAVE_UID16 if 32BIT
        select ARCH_WANT_IPC_PARSE_VERSION
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL
        select GENERIC_CLOCKEVENTS
        select KTIME_SCALAR if 32BIT
        select HAVE_ARCH_SECCOMP_FILTER
+       select GENERIC_KERNEL_THREAD
  
  config SCHED_OMIT_FRAME_POINTER
        def_bool y
@@@ -143,79 -134,9 +144,79 @@@ source "init/Kconfig
  
  source "kernel/Kconfig.freezer"
  
 -menu "Base setup"
 +menu "Processor type and features"
 +
 +config HAVE_MARCH_Z900_FEATURES
 +      def_bool n
 +
 +config HAVE_MARCH_Z990_FEATURES
 +      def_bool n
 +      select HAVE_MARCH_Z900_FEATURES
 +
 +config HAVE_MARCH_Z9_109_FEATURES
 +      def_bool n
 +      select HAVE_MARCH_Z990_FEATURES
 +
 +config HAVE_MARCH_Z10_FEATURES
 +      def_bool n
 +      select HAVE_MARCH_Z9_109_FEATURES
 +
 +config HAVE_MARCH_Z196_FEATURES
 +      def_bool n
 +      select HAVE_MARCH_Z10_FEATURES
 +
 +choice
 +      prompt "Processor type"
 +      default MARCH_G5
 +
 +config MARCH_G5
 +      bool "System/390 model G5 and G6"
 +      depends on !64BIT
 +      help
 +        Select this to build a 31 bit kernel that works
 +        on all ESA/390 and z/Architecture machines.
  
 -comment "Processor type and features"
 +config MARCH_Z900
 +      bool "IBM zSeries model z800 and z900"
 +      select HAVE_MARCH_Z900_FEATURES if 64BIT
 +      help
 +        Select this to enable optimizations for model z800/z900 (2064 and
 +        2066 series). This will enable some optimizations that are not
 +        available on older ESA/390 (31 Bit) only CPUs.
 +
 +config MARCH_Z990
 +      bool "IBM zSeries model z890 and z990"
 +      select HAVE_MARCH_Z990_FEATURES if 64BIT
 +      help
 +        Select this to enable optimizations for model z890/z990 (2084 and
 +        2086 series). The kernel will be slightly faster but will not work
 +        on older machines.
 +
 +config MARCH_Z9_109
 +      bool "IBM System z9"
 +      select HAVE_MARCH_Z9_109_FEATURES if 64BIT
 +      help
 +        Select this to enable optimizations for IBM System z9 (2094 and
 +        2096 series). The kernel will be slightly faster but will not work
 +        on older machines.
 +
 +config MARCH_Z10
 +      bool "IBM System z10"
 +      select HAVE_MARCH_Z10_FEATURES if 64BIT
 +      help
 +        Select this to enable optimizations for IBM System z10 (2097 and
 +        2098 series). The kernel will be slightly faster but will not work
 +        on older machines.
 +
 +config MARCH_Z196
 +      bool "IBM zEnterprise 114 and 196"
 +      select HAVE_MARCH_Z196_FEATURES if 64BIT
 +      help
 +        Select this to enable optimizations for IBM zEnterprise 114 and 196
 +        (2818 and 2817 series). The kernel will be slightly faster but will
 +        not work on older machines.
 +
 +endchoice
  
  config 64BIT
        def_bool y
  config 32BIT
        def_bool y if !64BIT
  
 +config COMPAT
 +      def_bool y
 +      prompt "Kernel support for 31 bit emulation"
 +      depends on 64BIT
 +      select COMPAT_BINFMT_ELF if BINFMT_ELF
 +      select ARCH_WANT_OLD_COMPAT_IPC
 +      help
 +        Select this option if you want to enable your system kernel to
 +        handle system-calls from ELF binaries for 31 bit ESA.  This option
 +        (and some other stuff like libraries and such) is needed for
 +        executing 31 bit applications.  It is safe to say "Y".
 +
 +config SYSVIPC_COMPAT
 +      def_bool y if COMPAT && SYSVIPC
 +
 +config KEYS_COMPAT
 +      def_bool y if COMPAT && KEYS
 +
  config SMP
        def_bool y
        prompt "Symmetric multi-processing support"
@@@ -300,8 -203,6 +301,8 @@@ config SCHED_BOO
          Book scheduler support improves the CPU scheduler's decision making
          when dealing with machines that have several books.
  
 +source kernel/Kconfig.preempt
 +
  config MATHEMU
        def_bool y
        prompt "IEEE FPU emulation"
          on older ESA/390 machines. Say Y unless you know your machine doesn't
          need this.
  
 -config COMPAT
 -      def_bool y
 -      prompt "Kernel support for 31 bit emulation"
 -      depends on 64BIT
 -      select COMPAT_BINFMT_ELF if BINFMT_ELF
 -      select ARCH_WANT_OLD_COMPAT_IPC
 -      help
 -        Select this option if you want to enable your system kernel to
 -        handle system-calls from ELF binaries for 31 bit ESA.  This option
 -        (and some other stuff like libraries and such) is needed for
 -        executing 31 bit applications.  It is safe to say "Y".
 +source kernel/Kconfig.hz
  
 -config SYSVIPC_COMPAT
 -      def_bool y if COMPAT && SYSVIPC
 +endmenu
  
 -config KEYS_COMPAT
 -      def_bool y if COMPAT && KEYS
 +menu "Memory setup"
  
 -config AUDIT_ARCH
 +config ARCH_SPARSEMEM_ENABLE
        def_bool y
 +      select SPARSEMEM_VMEMMAP_ENABLE
 +      select SPARSEMEM_VMEMMAP
 +      select SPARSEMEM_STATIC if !64BIT
  
 -config HAVE_MARCH_Z900_FEATURES
 -      def_bool n
 -
 -config HAVE_MARCH_Z990_FEATURES
 -      def_bool n
 -      select HAVE_MARCH_Z900_FEATURES
 -
 -config HAVE_MARCH_Z9_109_FEATURES
 -      def_bool n
 -      select HAVE_MARCH_Z990_FEATURES
 -
 -config HAVE_MARCH_Z10_FEATURES
 -      def_bool n
 -      select HAVE_MARCH_Z9_109_FEATURES
 -
 -config HAVE_MARCH_Z196_FEATURES
 -      def_bool n
 -      select HAVE_MARCH_Z10_FEATURES
 -
 -comment "Code generation options"
 -
 -choice
 -      prompt "Processor type"
 -      default MARCH_G5
 -
 -config MARCH_G5
 -      bool "System/390 model G5 and G6"
 -      depends on !64BIT
 -      help
 -        Select this to build a 31 bit kernel that works
 -        on all ESA/390 and z/Architecture machines.
 -
 -config MARCH_Z900
 -      bool "IBM zSeries model z800 and z900"
 -      select HAVE_MARCH_Z900_FEATURES if 64BIT
 -      help
 -        Select this to enable optimizations for model z800/z900 (2064 and
 -        2066 series). This will enable some optimizations that are not
 -        available on older ESA/390 (31 Bit) only CPUs.
 +config ARCH_SPARSEMEM_DEFAULT
 +      def_bool y
  
 -config MARCH_Z990
 -      bool "IBM zSeries model z890 and z990"
 -      select HAVE_MARCH_Z990_FEATURES if 64BIT
 -      help
 -        Select this to enable optimizations for model z890/z990 (2084 and
 -        2086 series). The kernel will be slightly faster but will not work
 -        on older machines.
 +config ARCH_SELECT_MEMORY_MODEL
 +      def_bool y
  
 -config MARCH_Z9_109
 -      bool "IBM System z9"
 -      select HAVE_MARCH_Z9_109_FEATURES if 64BIT
 -      help
 -        Select this to enable optimizations for IBM System z9 (2094 and
 -        2096 series). The kernel will be slightly faster but will not work
 -        on older machines.
 +config ARCH_ENABLE_MEMORY_HOTPLUG
 +      def_bool y if SPARSEMEM
  
 -config MARCH_Z10
 -      bool "IBM System z10"
 -      select HAVE_MARCH_Z10_FEATURES if 64BIT
 -      help
 -        Select this to enable optimizations for IBM System z10 (2097 and
 -        2098 series). The kernel will be slightly faster but will not work
 -        on older machines.
 +config ARCH_ENABLE_MEMORY_HOTREMOVE
 +      def_bool y
  
 -config MARCH_Z196
 -      bool "IBM zEnterprise 114 and 196"
 -      select HAVE_MARCH_Z196_FEATURES if 64BIT
 -      help
 -        Select this to enable optimizations for IBM zEnterprise 114 and 196
 -        (2818 and 2817 series). The kernel will be slightly faster but will
 -        not work on older machines.
 +config FORCE_MAX_ZONEORDER
 +      int
 +      default "9"
  
 -endchoice
 +source "mm/Kconfig"
  
  config PACK_STACK
        def_bool y
@@@ -403,9 -369,34 +404,9 @@@ config WARN_DYNAMIC_STAC
  
          Say N if you are unsure.
  
 -comment "Kernel preemption"
 -
 -source "kernel/Kconfig.preempt"
 -
 -config ARCH_SPARSEMEM_ENABLE
 -      def_bool y
 -      select SPARSEMEM_VMEMMAP_ENABLE
 -      select SPARSEMEM_VMEMMAP
 -      select SPARSEMEM_STATIC if !64BIT
 -
 -config ARCH_SPARSEMEM_DEFAULT
 -      def_bool y
 -
 -config ARCH_SELECT_MEMORY_MODEL
 -      def_bool y
 -
 -config ARCH_ENABLE_MEMORY_HOTPLUG
 -      def_bool y if SPARSEMEM
 -
 -config ARCH_ENABLE_MEMORY_HOTREMOVE
 -      def_bool y
 -
 -config ARCH_HIBERNATION_POSSIBLE
 -      def_bool y if 64BIT
 -
 -source "mm/Kconfig"
 +endmenu
  
 -comment "I/O subsystem configuration"
 +menu "I/O subsystem"
  
  config QDIO
        def_tristate y
@@@ -436,102 -427,13 +437,102 @@@ config CHSC_SC
  
          If unsure, say N.
  
 -comment "Misc"
 +config SCM_BUS
 +      def_bool y
 +      depends on 64BIT
 +      prompt "SCM bus driver"
 +      help
 +        Bus driver for Storage Class Memory.
 +
 +config EADM_SCH
 +      def_tristate m
 +      prompt "Support for EADM subchannels"
 +      depends on SCM_BUS
 +      help
 +        This driver allows usage of EADM subchannels. EADM subchannels act
 +        as a communication vehicle for SCM increments.
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called eadm_sch.
 +
 +endmenu
 +
 +menu "Dump support"
 +
 +config CRASH_DUMP
 +      bool "kernel crash dumps"
 +      depends on 64BIT && SMP
 +      select KEXEC
 +      help
 +        Generate crash dump after being started by kexec.
 +        Crash dump kernels are loaded in the main kernel with kexec-tools
 +        into a specially reserved region and then later executed after
 +        a crash by kdump/kexec.
 +        For more details see Documentation/kdump/kdump.txt
 +
 +config ZFCPDUMP
 +      def_bool n
 +      prompt "zfcpdump support"
 +      select SMP
 +      help
 +        Select this option if you want to build an zfcpdump enabled kernel.
 +        Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
 +
 +endmenu
 +
 +menu "Executable file formats / Emulations"
  
  source "fs/Kconfig.binfmt"
  
 -config FORCE_MAX_ZONEORDER
 -      int
 -      default "9"
 +config SECCOMP
 +      def_bool y
 +      prompt "Enable seccomp to safely compute untrusted bytecode"
 +      depends on PROC_FS
 +      help
 +        This kernel feature is useful for number crunching applications
 +        that may need to compute untrusted bytecode during their
 +        execution. By using pipes or other transports made available to
 +        the process as file descriptors supporting the read/write
 +        syscalls, it's possible to isolate those applications in
 +        their own address space using seccomp. Once seccomp is
 +        enabled via /proc/<pid>/seccomp, it cannot be disabled
 +        and the task is only allowed to execute a few safe syscalls
 +        defined by each seccomp mode.
 +
 +        If unsure, say Y.
 +
 +endmenu
 +
 +menu "Power Management"
 +
 +config ARCH_HIBERNATION_POSSIBLE
 +      def_bool y if 64BIT
 +
 +source "kernel/power/Kconfig"
 +
 +endmenu
 +
 +source "net/Kconfig"
 +
 +config PCMCIA
 +      def_bool n
 +
 +config CCW
 +      def_bool y
 +
 +source "drivers/Kconfig"
 +
 +source "fs/Kconfig"
 +
 +source "arch/s390/Kconfig.debug"
 +
 +source "security/Kconfig"
 +
 +source "crypto/Kconfig"
 +
 +source "lib/Kconfig"
 +
 +menu "Virtualization"
  
  config PFAULT
        def_bool y
          this option.
  
  config SHARED_KERNEL
 -      def_bool y
 -      prompt "VM shared kernel support"
 +      bool "VM shared kernel support"
 +      depends on !JUMP_LABEL
        help
          Select this option, if you want to share the text segment of the
          Linux kernel between different VM guests. This reduces memory
@@@ -643,6 -545,8 +644,6 @@@ config APPLDATA_NET_SU
          This can also be compiled as a module, which will be called
          appldata_net_sum.o.
  
 -source kernel/Kconfig.hz
 -
  config S390_HYPFS_FS
        def_bool y
        prompt "s390 hypervisor file system support"
          This is a virtual file system intended to provide accounting
          information in an s390 hypervisor environment.
  
 -config KEXEC
 -      def_bool n
 -      prompt "kexec system call"
 -      help
 -        kexec is a system call that implements the ability to shutdown your
 -        current kernel, and to start another kernel.  It is like a reboot
 -        but is independent of hardware/microcode support.
 -
 -config CRASH_DUMP
 -      bool "kernel crash dumps"
 -      depends on 64BIT && SMP
 -      select KEXEC
 -      help
 -        Generate crash dump after being started by kexec.
 -        Crash dump kernels are loaded in the main kernel with kexec-tools
 -        into a specially reserved region and then later executed after
 -        a crash by kdump/kexec.
 -        For more details see Documentation/kdump/kdump.txt
 -
 -config ZFCPDUMP
 -      def_bool n
 -      prompt "zfcpdump support"
 -      select SMP
 -      help
 -        Select this option if you want to build an zfcpdump enabled kernel.
 -        Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
 +source "arch/s390/kvm/Kconfig"
  
  config S390_GUEST
        def_bool y
 -      prompt "s390 guest support for KVM (EXPERIMENTAL)"
 +      prompt "s390 support for virtio devices (EXPERIMENTAL)"
        depends on 64BIT && EXPERIMENTAL
        select VIRTUALIZATION
        select VIRTIO
 -      select VIRTIO_RING
        select VIRTIO_CONSOLE
        help
 -        Select this option if you want to run the kernel as a guest under
 -        the KVM hypervisor. This will add detection for KVM as well  as a
 -        virtio transport. If KVM is detected, the virtio console will be
 -        the default console.
 -
 -config SECCOMP
 -      def_bool y
 -      prompt "Enable seccomp to safely compute untrusted bytecode"
 -      depends on PROC_FS
 -      help
 -        This kernel feature is useful for number crunching applications
 -        that may need to compute untrusted bytecode during their
 -        execution. By using pipes or other transports made available to
 -        the process as file descriptors supporting the read/write
 -        syscalls, it's possible to isolate those applications in
 -        their own address space using seccomp. Once seccomp is
 -        enabled via /proc/<pid>/seccomp, it cannot be disabled
 -        and the task is only allowed to execute a few safe syscalls
 -        defined by each seccomp mode.
 -
 -        If unsure, say Y.
 -
 -endmenu
 +        Enabling this option adds support for virtio based paravirtual device
 +        drivers on s390.
  
 -menu "Power Management"
 -
 -source "kernel/power/Kconfig"
 +        Select this option if you want to run the kernel as a guest under
 +        the KVM hypervisor.
  
  endmenu
 -
 -source "net/Kconfig"
 -
 -config PCMCIA
 -      def_bool n
 -
 -config CCW
 -      def_bool y
 -
 -source "drivers/Kconfig"
 -
 -source "fs/Kconfig"
 -
 -source "arch/s390/Kconfig.debug"
 -
 -source "security/Kconfig"
 -
 -source "crypto/Kconfig"
 -
 -source "lib/Kconfig"
 -
 -source "arch/s390/kvm/Kconfig"
index 56831dfa9198c6e2192605fd5ee9d68c538d8b17,da6f5baeee5c20925d82a648690fa12c14ea8044..94e749c90230d9f824949429d505625f90f7b4e7
  #ifndef __ASM_S390_PROCESSOR_H
  #define __ASM_S390_PROCESSOR_H
  
 +#ifndef __ASSEMBLY__
 +
  #include <linux/linkage.h>
  #include <linux/irqflags.h>
  #include <asm/cpu.h>
  #include <asm/page.h>
  #include <asm/ptrace.h>
  #include <asm/setup.h>
 +#include <asm/runtime_instr.h>
  
  /*
   * Default implementation of macro that returns current
@@@ -35,6 -32,7 +35,7 @@@ static inline void get_cpu_id(struct cp
  extern void s390_adjust_jiffies(void);
  extern const struct seq_operations cpuinfo_op;
  extern int sysctl_ieee_emulation_warnings;
+ extern void execve_tail(void);
  
  /*
   * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
@@@ -78,20 -76,11 +79,20 @@@ struct thread_struct 
        unsigned long gmap_addr;        /* address of last gmap fault. */
        struct per_regs per_user;       /* User specified PER registers */
        struct per_event per_event;     /* Cause of the last PER trap */
 +      unsigned long per_flags;        /* Flags to control debug behavior */
          /* pfault_wait is used to block the process on a pfault event */
        unsigned long pfault_wait;
        struct list_head list;
 +      /* cpu runtime instrumentation */
 +      struct runtime_instr_cb *ri_cb;
 +      int ri_signum;
 +#ifdef CONFIG_64BIT
 +      unsigned char trap_tdb[256];    /* Transaction abort diagnose block */
 +#endif
  };
  
 +#define PER_FLAG_NO_TE                1UL     /* Flag to disable transactions. */
 +
  typedef struct thread_struct thread_struct;
  
  /*
@@@ -126,6 -115,7 +127,7 @@@ struct stack_frame 
        regs->psw.mask  = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;    \
        regs->psw.addr  = new_psw | PSW_ADDR_AMODE;                     \
        regs->gprs[15]  = new_stackp;                                   \
+       execve_tail();                                                  \
  } while (0)
  
  #define start_thread31(regs, new_psw, new_stackp) do {                        \
        __tlb_flush_mm(current->mm);                                    \
        crst_table_downgrade(current->mm, 1UL << 31);                   \
        update_mm(current->mm, current);                                \
+       execve_tail();                                                  \
  } while (0)
  
  /* Forward declaration, a strange C thing */
@@@ -142,15 -133,8 +145,14 @@@ struct task_struct
  struct mm_struct;
  struct seq_file;
  
 +#ifdef CONFIG_64BIT
 +extern void show_cacheinfo(struct seq_file *m);
 +#else
 +static inline void show_cacheinfo(struct seq_file *m) { }
 +#endif
 +
  /* Free all resources held by a thread. */
  extern void release_thread(struct task_struct *);
- extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
  
  /*
   * Return saved PC of a blocked thread.
  extern unsigned long thread_saved_pc(struct task_struct *t);
  
  extern void show_code(struct pt_regs *regs);
 +extern void print_fn_code(unsigned char *code, unsigned long len);
 +extern int insn_to_mnemonic(unsigned char *instruction, char buf[8]);
  
  unsigned long get_wchan(struct task_struct *p);
  #define task_pt_regs(tsk) ((struct pt_regs *) \
@@@ -351,6 -333,23 +353,6 @@@ extern void (*s390_base_ext_handler_fn)
  
  #define ARCH_LOW_ADDRESS_LIMIT        0x7fffffffUL
  
 -/*
 - * Helper macro for exception table entries
 - */
 -#ifndef CONFIG_64BIT
 -#define EX_TABLE(_fault,_target)                      \
 -      ".section __ex_table,\"a\"\n"                   \
 -      "       .align 4\n"                             \
 -      "       .long  " #_fault "," #_target "\n"      \
 -      ".previous\n"
 -#else
 -#define EX_TABLE(_fault,_target)                      \
 -      ".section __ex_table,\"a\"\n"                   \
 -      "       .align 8\n"                             \
 -      "       .quad  " #_fault "," #_target "\n"      \
 -      ".previous\n"
 -#endif
 -
  extern int memcpy_real(void *, void *, size_t);
  extern void memcpy_absolute(void *, void *, size_t);
  
        memcpy_absolute(&(dest), &__tmp, sizeof(__tmp));        \
  }
  
 -#endif                                 /* __ASM_S390_PROCESSOR_H           */
 +/*
 + * Helper macro for exception table entries
 + */
 +#define EX_TABLE(_fault, _target)     \
 +      ".section __ex_table,\"a\"\n"   \
 +      ".align 4\n"                    \
 +      ".long  (" #_fault ") - .\n"    \
 +      ".long  (" #_target ") - .\n"   \
 +      ".previous\n"
 +
 +#else /* __ASSEMBLY__ */
 +
 +#define EX_TABLE(_fault, _target)     \
 +      .section __ex_table,"a" ;       \
 +      .align  4 ;                     \
 +      .long   (_fault) - . ;          \
 +      .long   (_target) - . ;         \
 +      .previous
 +
 +#endif /* __ASSEMBLY__ */
 +
 +#endif /* __ASM_S390_PROCESSOR_H */
index 4e64b5cd1558762016ef166b1a73022f9ccfc084,3c500174459a9d4d5793474729d0217b0c077f7e..8192e292753ac7c45713a41886e29c98bf98db08
  #define __NR_setns            339
  #define __NR_process_vm_readv 340
  #define __NR_process_vm_writev        341
 -#define NR_syscalls 342
 +#define __NR_s390_runtime_instr 342
 +#define __NR_kcmp             343
 +#define NR_syscalls 344
  
  /* 
   * There are some system calls that are not present on 64 bit, some
  #   define __ARCH_WANT_COMPAT_SYS_TIME
  #   define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
  # endif
+ #define __ARCH_WANT_SYS_EXECVE
+ #define __ARCH_WANT_KERNEL_EXECVE
  
  /*
   * "Conditional" syscalls
index 189963c90c6eb09deb498947f057ae6ad3450f12,d03d733dadfe5ba1e50a09e87c538c7da246433f..65cca95843e112d170c40535a95030a087614adb
@@@ -131,19 -131,13 +131,19 @@@ asmlinkage long sys32_setresuid16(u16 r
                low2highuid(suid));
  }
  
 -asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid)
 +asmlinkage long sys32_getresuid16(u16 __user *ruidp, u16 __user *euidp, u16 __user *suidp)
  {
 +      const struct cred *cred = current_cred();
        int retval;
 +      u16 ruid, euid, suid;
  
 -      if (!(retval = put_user(high2lowuid(current->cred->uid), ruid)) &&
 -          !(retval = put_user(high2lowuid(current->cred->euid), euid)))
 -              retval = put_user(high2lowuid(current->cred->suid), suid);
 +      ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid));
 +      euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid));
 +      suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid));
 +
 +      if (!(retval   = put_user(ruid, ruidp)) &&
 +          !(retval   = put_user(euid, euidp)))
 +              retval = put_user(suid, suidp);
  
        return retval;
  }
@@@ -154,19 -148,13 +154,19 @@@ asmlinkage long sys32_setresgid16(u16 r
                low2highgid(sgid));
  }
  
 -asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
 +asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __user *sgidp)
  {
 +      const struct cred *cred = current_cred();
        int retval;
 +      u16 rgid, egid, sgid;
 +
 +      rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid));
 +      egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid));
 +      sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid));
  
 -      if (!(retval = put_user(high2lowgid(current->cred->gid), rgid)) &&
 -          !(retval = put_user(high2lowgid(current->cred->egid), egid)))
 -              retval = put_user(high2lowgid(current->cred->sgid), sgid);
 +      if (!(retval   = put_user(rgid, rgidp)) &&
 +          !(retval   = put_user(egid, egidp)))
 +              retval = put_user(sgid, sgidp);
  
        return retval;
  }
@@@ -270,22 -258,22 +270,22 @@@ asmlinkage long sys32_setgroups16(int g
  
  asmlinkage long sys32_getuid16(void)
  {
 -      return high2lowuid(current->cred->uid);
 +      return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));
  }
  
  asmlinkage long sys32_geteuid16(void)
  {
 -      return high2lowuid(current->cred->euid);
 +      return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));
  }
  
  asmlinkage long sys32_getgid16(void)
  {
 -      return high2lowgid(current->cred->gid);
 +      return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));
  }
  
  asmlinkage long sys32_getegid16(void)
  {
 -      return high2lowgid(current->cred->egid);
 +      return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));
  }
  
  /*
@@@ -432,32 -420,6 +432,6 @@@ sys32_rt_sigqueueinfo(int pid, int sig
        return ret;
  }
  
- /*
-  * sys32_execve() executes a new program after the asm stub has set
-  * things up for us.  This should basically do what I want it to.
-  */
- asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-                            compat_uptr_t __user *envp)
- {
-       struct pt_regs *regs = task_pt_regs(current);
-       char *filename;
-       long rc;
-       filename = getname(name);
-       rc = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return rc;
-       rc = compat_do_execve(filename, argv, envp, regs);
-       if (rc)
-               goto out;
-       current->thread.fp_regs.fpc=0;
-       asm volatile("sfpc %0,0" : : "d" (0));
-       rc = regs->gprs[2];
- out:
-       putname(filename);
-       return rc;
- }
  asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
  {
index 90887bd98cf0b384ce91d2f1bc1ce7187e51498f,5daff1d34b8e502919c62a2ad4a38a25fc216894..d4d0239970ac1f9b3953a38f62fc6a2f6f2b23b7
@@@ -23,6 -23,74 +23,6 @@@ struct old_sigaction32 
         __u32                  sa_flags;
         __u32                  sa_restorer;    /* Another 32 bit pointer */
  };
 - 
 -typedef struct compat_siginfo {
 -      int     si_signo;
 -      int     si_errno;
 -      int     si_code;
 -
 -      union {
 -              int _pad[((128/sizeof(int)) - 3)];
 -
 -              /* kill() */
 -              struct {
 -                      pid_t   _pid;   /* sender's pid */
 -                      uid_t   _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 */
 -              } _timer;
 -
 -              /* POSIX.1b signals */
 -              struct {
 -                      pid_t                   _pid;   /* sender's pid */
 -                      uid_t                   _uid;   /* sender's uid */
 -                      compat_sigval_t         _sigval;
 -              } _rt;
 -
 -              /* SIGCHLD */
 -              struct {
 -                      pid_t                   _pid;   /* which child */
 -                      uid_t                   _uid;   /* sender's uid */
 -                      int                     _status;/* exit code */
 -                      compat_clock_t          _utime;
 -                      compat_clock_t          _stime;
 -              } _sigchld;
 -
 -              /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 -              struct {
 -                      __u32   _addr;  /* faulting insn/memory ref. - pointer */
 -              } _sigfault;
 -                          
 -              /* SIGPOLL */
 -              struct {
 -                      int     _band;  /* POLL_IN, POLL_OUT, POLL_MSG */
 -                      int     _fd;
 -              } _sigpoll;
 -      } _sifields;
 -} compat_siginfo_t;
 -
 -/*
 - * How these fields are to be accessed.
 - */
 -#define si_pid                _sifields._kill._pid
 -#define si_uid                _sifields._kill._uid
 -#define si_status     _sifields._sigchld._status
 -#define si_utime      _sifields._sigchld._utime
 -#define si_stime      _sifields._sigchld._stime
 -#define si_value      _sifields._rt._sigval
 -#define si_int                _sifields._rt._sigval.sival_int
 -#define si_ptr                _sifields._rt._sigval.sival_ptr
 -#define si_addr               _sifields._sigfault._addr
 -#define si_band               _sifields._sigpoll._band
 -#define si_fd         _sifields._sigpoll._fd    
 -#define si_tid                _sifields._timer._tid
 -#define si_overrun    _sifields._timer._overrun
  
  /* asm/sigcontext.h */
  typedef union
@@@ -125,8 -193,6 +125,6 @@@ long sys32_rt_sigprocmask(int how, comp
                          compat_sigset_t __user *oset, size_t sigsetsize);
  long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize);
  long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo);
- long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-                 compat_uptr_t __user *envp);
  long sys32_init_module(void __user *umod, unsigned long len,
                       const char __user *uargs);
  long sys32_delete_module(const char __user *name_user, unsigned int flags);
index 3afba804fe97e9e9eb19ee9f2040cf3466f23361,cf1d60f46922e1552a9533b1978b03413c6d3de3..ad79b846535c4d9345e884341f40481e9d38c492
@@@ -1576,7 -1576,7 +1576,7 @@@ ENTRY(sys32_execve_wrapper
        llgtr   %r2,%r2                 # char *
        llgtr   %r3,%r3                 # compat_uptr_t *
        llgtr   %r4,%r4                 # compat_uptr_t *
-       jg      sys32_execve            # branch to system call
+       jg      compat_sys_execve       # branch to system call
  
  ENTRY(sys_fanotify_init_wrapper)
        llgfr   %r2,%r2                 # unsigned int
@@@ -1646,16 -1646,3 +1646,16 @@@ ENTRY(compat_sys_process_vm_writev_wrap
        llgf    %r0,164(%r15)           # unsigned long
        stg     %r0,160(%r15)
        jg      compat_sys_process_vm_writev
 +
 +ENTRY(sys_s390_runtime_instr_wrapper)
 +      lgfr    %r2,%r2                 # int
 +      lgfr    %r3,%r3                 # int
 +      jg      sys_s390_runtime_instr
 +
 +ENTRY(sys_kcmp_wrapper)
 +      lgfr    %r2,%r2                 # pid_t
 +      lgfr    %r3,%r3                 # pid_t
 +      lgfr    %r4,%r4                 # int
 +      llgfr   %r5,%r5                 # unsigned long
 +      llgfr   %r6,%r6                 # unsigned long
 +      jg      sys_kcmp
index 7549985402f726515e49694708957e710c50e17e,3d188f74d4c05c4d11b2f60704c9e789bb1b0592..f9761f806c9e52cee8b4d3270055198cab63845c
@@@ -10,7 -10,6 +10,7 @@@
  
  #include <linux/init.h>
  #include <linux/linkage.h>
 +#include <asm/processor.h>
  #include <asm/cache.h>
  #include <asm/errno.h>
  #include <asm/ptrace.h>
@@@ -353,41 -352,31 +353,31 @@@ ENTRY(ret_from_fork
        la      %r11,STACK_FRAME_OVERHEAD(%r15)
        lg      %r12,__LC_THREAD_INFO
        tm      __PT_PSW+1(%r11),0x01   # forking a kernel thread ?
-       jo      0f
-       stg     %r15,__PT_R15(%r11)     # store stack pointer for new kthread
- 0:    brasl   %r14,schedule_tail
+       je      1f
+       brasl   %r14,schedule_tail
        TRACE_IRQS_ON
        ssm     __LC_SVC_NEW_PSW        # reenable interrupts
        j       sysc_tracenogo
- #
- # kernel_execve function needs to deal with pt_regs that is not
- # at the usual place
- #
- ENTRY(kernel_execve)
-       stmg    %r12,%r15,96(%r15)
-       lgr     %r14,%r15
-       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       stg     %r14,__SF_BACKCHAIN(%r15)
-       la      %r12,STACK_FRAME_OVERHEAD(%r15)
-       xc      0(__PT_SIZE,%r12),0(%r12)
-       lgr     %r5,%r12
-       brasl   %r14,do_execve
-       ltgfr   %r2,%r2
-       je      0f
-       aghi    %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       lmg     %r12,%r15,96(%r15)
-       br      %r14
-       # execve succeeded.
- 0:    ssm     __LC_PGM_NEW_PSW        # disable I/O and ext. interrupts
-       lg      %r15,__LC_KERNEL_STACK  # load ksp
-       aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-       la      %r11,STACK_FRAME_OVERHEAD(%r15)
-       mvc     0(__PT_SIZE,%r11),0(%r12)       # copy pt_regs
-       lg      %r12,__LC_THREAD_INFO
+ 1:    # it's a kernel thread
+       stg     %r15,__PT_R15(%r11)     # store stack pointer for new kthread
+       brasl   %r14,schedule_tail
+       TRACE_IRQS_ON
+       ssm     __LC_SVC_NEW_PSW        # reenable interrupts
+       lmg     %r9,%r11,__PT_R9(%r11)  # load gprs
+ ENTRY(kernel_thread_starter)
+       la      %r2,0(%r10)
+       basr    %r14,%r9
+       la      %r2,0
+       br      %r11                    # do_exit
+ ENTRY(ret_from_kernel_execve)
+       ssm     __LC_PGM_NEW_PSW        # disable I/O and ext. interrupts
+       lgr     %r15,%r2
+       lgr     %r11,%r2
+       aghi    %r15,-STACK_FRAME_OVERHEAD
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+       lg      %r12,__LC_THREAD_INFO
        ssm     __LC_SVC_NEW_PSW        # reenable interrupts
-       brasl   %r14,execve_tail
        j       sysc_return
  
  /*
@@@ -413,11 -402,6 +403,11 @@@ ENTRY(pgm_check_handler
  1:    UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
        LAST_BREAK %r14
        lg      %r15,__LC_KERNEL_STACK
 +      lg      %r14,__TI_task(%r12)
 +      lghi    %r13,__LC_PGM_TDB
 +      tm      __LC_PGM_ILC+2,0x02     # check for transaction abort
 +      jz      2f
 +      mvc     __THREAD_trap_tdb(256,%r14),0(%r13)
  2:    aghi    %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
        la      %r11,STACK_FRAME_OVERHEAD(%r15)
        stmg    %r0,%r7,__PT_R0(%r11)
        stg     %r10,__PT_ARGS(%r11)
        tm      __LC_PGM_ILC+3,0x80     # check for per exception
        jz      0f
 -      lg      %r1,__TI_task(%r12)
        tmhh    %r8,0x0001              # kernel per event ?
        jz      pgm_kprobe
        oi      __TI_flags+7(%r12),_TIF_PER_TRAP
 -      mvc     __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
 -      mvc     __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
 -      mvc     __THREAD_per_paid(1,%r1),__LC_PER_PAID
 +      mvc     __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
 +      mvc     __THREAD_per_cause(2,%r14),__LC_PER_CAUSE
 +      mvc     __THREAD_per_paid(1,%r14),__LC_PER_PAID
  0:    REENABLE_IRQS
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
        larl    %r1,pgm_check_table
@@@ -1009,7 -994,9 +999,7 @@@ sie_fault
  .Lhost_id:
        .quad   0
  
 -      .section __ex_table,"a"
 -      .quad   sie_loop,sie_fault
 -      .previous
 +      EX_TABLE(sie_loop,sie_fault)
  #endif
  
                .section .rodata, "a"
index 5024be27df444b3dedc669f823734404fcb0fe4c,bab088de45697b4772d26e76638554b5f688420a..cd31ad457a9bdb7890a0ff7eae840a63f5f0f48f
  #include <asm/io.h>
  #include <asm/processor.h>
  #include <asm/vtimer.h>
 +#include <asm/exec.h>
  #include <asm/irq.h>
  #include <asm/nmi.h>
  #include <asm/smp.h>
  #include <asm/switch_to.h>
 +#include <asm/runtime_instr.h>
  #include "entry.h"
  
  asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@@ -100,41 -98,11 +100,12 @@@ void cpu_idle(void
  
  extern void __kprobes kernel_thread_starter(void);
  
- asm(
-       ".section .kprobes.text, \"ax\"\n"
-       ".global kernel_thread_starter\n"
-       "kernel_thread_starter:\n"
-       "    la    2,0(10)\n"
-       "    basr  14,9\n"
-       "    la    2,0\n"
-       "    br    11\n"
-       ".previous\n");
- int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
-       struct pt_regs regs;
-       memset(&regs, 0, sizeof(regs));
-       regs.psw.mask = psw_kernel_bits |
-               PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
-       regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
-       regs.gprs[9] = (unsigned long) fn;
-       regs.gprs[10] = (unsigned long) arg;
-       regs.gprs[11] = (unsigned long) do_exit;
-       regs.orig_gpr2 = -1;
-       /* 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..
   */
  void exit_thread(void)
  {
 +      exit_thread_runtime_instr();
  }
  
  void flush_thread(void)
@@@ -146,7 -114,7 +117,7 @@@ void release_thread(struct task_struct 
  }
  
  int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
-               unsigned long unused,
+               unsigned long arg,
                struct task_struct *p, struct pt_regs *regs)
  {
        struct thread_info *ti;
  
        frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
        p->thread.ksp = (unsigned long) frame;
-       /* Store access registers to kernel stack of new process. */
-       frame->childregs = *regs;
-       frame->childregs.gprs[2] = 0;   /* child returns 0 on fork. */
-       frame->childregs.gprs[15] = new_stackp;
-       frame->sf.back_chain = 0;
+       /* Save access registers to new thread structure. */
+       save_access_regs(&p->thread.acrs[0]);
+       /* start new process with ar4 pointing to the correct address space */
+       p->thread.mm_segment = get_fs();
+       /* Don't copy debug registers */
+       memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
+       memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
+       clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
+       clear_tsk_thread_flag(p, TIF_PER_TRAP);
+       /* Initialize per thread user and system timer values */
+       ti = task_thread_info(p);
+       ti->user_timer = 0;
+       ti->system_timer = 0;
  
+       frame->sf.back_chain = 0;
        /* new return point is ret_from_fork */
        frame->sf.gprs[8] = (unsigned long) ret_from_fork;
        /* fake return stack for resume(), don't go back to schedule */
        frame->sf.gprs[9] = (unsigned long) frame;
  
-       /* Save access registers to new thread structure. */
-       save_access_regs(&p->thread.acrs[0]);
+       /* Store access registers to kernel stack of new process. */
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(&frame->childregs, 0, sizeof(struct pt_regs));
+               frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
+                               PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
+               frame->childregs.psw.addr = PSW_ADDR_AMODE |
+                               (unsigned long) kernel_thread_starter;
+               frame->childregs.gprs[9] = new_stackp; /* function */
+               frame->childregs.gprs[10] = arg;
+               frame->childregs.gprs[11] = (unsigned long) do_exit;
+               frame->childregs.orig_gpr2 = -1;
+               return 0;
+       }
+       frame->childregs = *regs;
+       frame->childregs.gprs[2] = 0;   /* child returns 0 on fork. */
+       frame->childregs.gprs[15] = new_stackp;
  
 +      /* Don't copy runtime instrumentation info */
 +      p->thread.ri_cb = NULL;
 +      p->thread.ri_signum = 0;
 +      frame->childregs.psw.mask &= ~PSW_MASK_RI;
 +
  #ifndef CONFIG_64BIT
        /*
         * save fprs to current->thread.fp_regs to merge them with
                }
        }
  #endif /* CONFIG_64BIT */
-       /* start new process with ar4 pointing to the correct address space */
-       p->thread.mm_segment = get_fs();
-       /* Don't copy debug registers */
-       memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
-       memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
-       clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
-       clear_tsk_thread_flag(p, TIF_PER_TRAP);
-       /* Initialize per thread user and system timer values */
-       ti = task_thread_info(p);
-       ti->user_timer = 0;
-       ti->system_timer = 0;
        return 0;
  }
  
@@@ -257,31 -233,6 +241,6 @@@ asmlinkage void execve_tail(void
                asm volatile("sfpc %0,%0" : : "d" (0));
  }
  
- /*
-  * sys_execve() executes a new program.
-  */
- SYSCALL_DEFINE3(execve, const char __user *, name,
-               const char __user *const __user *, argv,
-               const char __user *const __user *, envp)
- {
-       struct pt_regs *regs = task_pt_regs(current);
-       char *filename;
-       long rc;
-       filename = getname(name);
-       rc = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return rc;
-       rc = do_execve(filename, argv, envp, regs);
-       if (rc)
-               goto out;
-       execve_tail();
-       rc = regs->gprs[2];
- out:
-       putname(filename);
-       return rc;
- }
  /*
   * fill in the FPU structure for a core dump.
   */
index 61d41c11ee0ab7b0289fce60e0bc27597518ee2a,cf1e85782703600bef492ba2f23cf6bb988e4ec7..10d54e5e37f5c01d51b68218710fa0b062932b59
@@@ -1,8 -1,24 +1,9 @@@
  # User exported sparc header files
 -include include/asm-generic/Kbuild.asm
  
 -header-y += apc.h
 -header-y += asi.h
 -header-y += display7seg.h
 -header-y += envctrl.h
 -header-y += fbio.h
 -header-y += jsflash.h
 -header-y += openpromio.h
 -header-y += perfctr.h
 -header-y += psrcompat.h
 -header-y += psr.h
 -header-y += pstate.h
 -header-y += traps.h
 -header-y += uctx.h
 -header-y += utrap.h
 -header-y += watchdog.h
  
 +generic-y += clkdev.h
  generic-y += div64.h
+ generic-y += exec.h
  generic-y += local64.h
  generic-y += irq_regs.h
  generic-y += local.h
index ea2e8ea3eb6135e181f6fd15b95e8c47701bf3b0,5a5e6796a312c89a6a480b05bc7e6b280c1da3b2..5cd98fac98993147207b0c75055fa31b1dabc717
@@@ -8,11 -8,11 +8,12 @@@ header-y += hardwall.
  
  generic-y += bug.h
  generic-y += bugs.h
 +generic-y += clkdev.h
  generic-y += cputime.h
  generic-y += div64.h
  generic-y += emergency-restart.h
  generic-y += errno.h
+ generic-y += exec.h
  generic-y += fb.h
  generic-y += fcntl.h
  generic-y += ioctl.h
index 24e97be814bcc793f24d41d282388e4bc3d62937,5d9ab0c4f4887594989273a5bd8fac1a5eb35140..1e82e954e97877994d77697ad621ccdc0ea168b2
@@@ -10,9 -10,9 +10,9 @@@ struct pt_regs
  
  struct task_struct;
  
 -#include "asm/ptrace.h"
 -#include "registers.h"
 -#include "sysdep/archsetjmp.h"
 +#include <asm/ptrace.h>
 +#include <registers.h>
 +#include <sysdep/archsetjmp.h>
  
  #include <linux/prefetch.h>
  
@@@ -63,8 -63,6 +63,6 @@@ static inline void release_thread(struc
  {
  }
  
- extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
  extern unsigned long thread_saved_pc(struct task_struct *t);
  
  static inline void mm_copy_segments(struct mm_struct *from_mm,
diff --combined arch/um/kernel/exec.c
index de66c421ae9d2a153620ecd70619359c11d427fe,e427301f55d6b789639d3948b48b9c50447f248b..ab019c7f0b57fdc06f9a70c974d44d80cbd9f1b8
  #include <asm/current.h>
  #include <asm/processor.h>
  #include <asm/uaccess.h>
 -#include "as-layout.h"
 -#include "mem_user.h"
 -#include "skas.h"
 -#include "os.h"
 +#include <as-layout.h>
 +#include <mem_user.h>
 +#include <skas.h>
 +#include <os.h>
- #include "internal.h"
  
  void flush_thread(void)
  {
@@@ -49,27 -48,7 +48,7 @@@ void start_thread(struct pt_regs *regs
  }
  EXPORT_SYMBOL(start_thread);
  
long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
void __noreturn ret_from_kernel_execve(struct pt_regs *unused)
  {
-       long err;
-       err = do_execve(file, argv, env, &current->thread.regs);
-       if (!err)
-               UML_LONGJMP(current->thread.exec_buf, 1);
-       return err;
- }
- long sys_execve(const char __user *file, const char __user *const __user *argv,
-               const char __user *const __user *env)
- {
-       long error;
-       char *filename;
-       filename = getname(file);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename)) goto out;
-       error = do_execve(filename, argv, env, &current->thread.regs);
-       putname(filename);
-  out:
-       return error;
+       UML_LONGJMP(current->thread.exec_buf, 1);
  }
diff --combined arch/um/kernel/process.c
index 41f53240e794b37524b3eef3f381363bcf50359c,a1b50add48a299feb1b3c88b8a2d1c73ce477c85..30629783b3e081f30e5e016e94018cd1591efafa
  #include <asm/pgtable.h>
  #include <asm/mmu_context.h>
  #include <asm/uaccess.h>
 -#include "as-layout.h"
 -#include "kern_util.h"
 -#include "os.h"
 -#include "skas.h"
 +#include <as-layout.h>
 +#include <kern_util.h>
 +#include <os.h>
 +#include <skas.h>
  
  /*
   * This is a per-cpu array.  A processor only modifies its entry and it only
@@@ -69,18 -69,6 +69,6 @@@ unsigned long alloc_stack(int order, in
        return page;
  }
  
- int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
-       int pid;
-       current->thread.request.u.thread.proc = fn;
-       current->thread.request.u.thread.arg = arg;
-       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
-                     &current->thread.regs, 0, NULL, NULL);
-       return pid;
- }
- EXPORT_SYMBOL(kernel_thread);
  static inline void set_current(struct task_struct *task)
  {
        cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
@@@ -177,7 -165,7 +165,7 @@@ void fork_handler(void
  }
  
  int copy_thread(unsigned long clone_flags, unsigned long sp,
-               unsigned long stack_top, struct task_struct * p,
+               unsigned long arg, struct task_struct * p,
                struct pt_regs *regs)
  {
        void (*handler)(void);
                arch_copy_thread(&current->thread.arch, &p->thread.arch);
        } else {
                get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
-               p->thread.request.u.thread = current->thread.request.u.thread;
+               p->thread.request.u.thread.proc = (int (*)(void *))sp;
+               p->thread.request.u.thread.arg = (void *)arg;
                handler = new_thread_handler;
        }
  
diff --combined arch/um/kernel/syscall.c
index 10808bda36718048f87f5fa1a710e254dbb4495a,a5639c4727729562f74728e5c93d5d3517bbfb1d..a81f3705e90f6e23448ab827c5e980fa8306d9e6
@@@ -3,17 -3,16 +3,16 @@@
   * Licensed under the GPL
   */
  
 -#include "linux/file.h"
 -#include "linux/fs.h"
 -#include "linux/mm.h"
 -#include "linux/sched.h"
 -#include "linux/utsname.h"
 -#include "linux/syscalls.h"
 -#include "asm/current.h"
 -#include "asm/mman.h"
 -#include "asm/uaccess.h"
 -#include "asm/unistd.h"
 +#include <linux/file.h>
 +#include <linux/fs.h>
 +#include <linux/mm.h>
 +#include <linux/sched.h>
 +#include <linux/utsname.h>
 +#include <linux/syscalls.h>
 +#include <asm/current.h>
 +#include <asm/mman.h>
 +#include <asm/uaccess.h>
 +#include <asm/unistd.h>
- #include "internal.h"
  
  long sys_fork(void)
  {
@@@ -50,19 -49,3 +49,3 @@@ long old_mmap(unsigned long addr, unsig
   out:
        return err;
  }
- int kernel_execve(const char *filename,
-                 const char *const argv[],
-                 const char *const envp[])
- {
-       mm_segment_t fs;
-       int ret;
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = um_execve(filename, (const char __user *const __user *)argv,
-                       (const char __user *const __user *) envp);
-       set_fs(fs);
-       return ret;
- }
index 123c59a06c14d8dd78ca2cfd5101acec34429f9a,90a01c83a036e7298e332f90b8a0380fa6af0086..c910c9857e114316991b2e9c711819a3939cdad5
@@@ -4,13 -4,13 +4,14 @@@ generic-y += atomic.
  generic-y += auxvec.h
  generic-y += bitsperlong.h
  generic-y += bugs.h
 +generic-y += clkdev.h
  generic-y += cputime.h
  generic-y += current.h
  generic-y += device.h
  generic-y += div64.h
  generic-y += emergency-restart.h
  generic-y += errno.h
+ generic-y += exec.h
  generic-y += fb.h
  generic-y += fcntl.h
  generic-y += ftrace.h
diff --combined arch/x86/Kconfig
index 1ae94bcae5d9ba7fb92f739c6d433b244ad09ae0,d93eb9d1bb974bab77fb37045bf2a11f199303c0..42d2c35a5bbdd61b594ee5e2b9431532ad02a59f
@@@ -7,14 -7,11 +7,14 @@@ config 64BI
          Say no to build a 32-bit kernel - formerly known as i386
  
  config X86_32
 -      def_bool !64BIT
 +      def_bool y
 +      depends on !64BIT
        select CLKSRC_I8253
 +      select HAVE_UID16
  
  config X86_64
 -      def_bool 64BIT
 +      def_bool y
 +      depends on 64BIT
        select X86_DEV_DMA_OPS
  
  ### Arch settings
@@@ -39,7 -36,6 +39,7 @@@ config X8
        select HAVE_KRETPROBES
        select HAVE_OPTPROBES
        select HAVE_FTRACE_MCOUNT_RECORD
 +      select HAVE_FENTRY if X86_64
        select HAVE_C_RECORDMCOUNT
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_TRACER
@@@ -47,7 -43,6 +47,7 @@@
        select HAVE_FUNCTION_GRAPH_FP_TEST
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_SYSCALL_TRACEPOINTS
 +      select SYSCTL_EXCEPTION_TRACE
        select HAVE_KVM
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
@@@ -65,9 -60,6 +65,9 @@@
        select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS
        select HAVE_PERF_EVENTS_NMI
 +      select HAVE_PERF_REGS
 +      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
@@@ -88,7 -80,6 +88,7 @@@
        select IRQ_FORCED_THREADING
        select USE_GENERIC_SMP_HELPERS if SMP
        select HAVE_BPF_JIT if X86_64
 +      select HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select CLKEVT_I8253
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_IOMAP
        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_IRQ_TIME_ACCOUNTING
+       select GENERIC_KERNEL_THREAD
  
  config INSTRUCTION_DECODER
 -      def_bool (KPROBES || PERF_EVENTS || UPROBES)
 +      def_bool y
 +      depends on KPROBES || PERF_EVENTS || UPROBES
  
  config OUTPUT_FORMAT
        string
@@@ -139,15 -128,13 +140,15 @@@ config SBU
        bool
  
  config NEED_DMA_MAP_STATE
 -       def_bool (X86_64 || INTEL_IOMMU || DMA_API_DEBUG)
 +      def_bool y
 +      depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG
  
  config NEED_SG_DMA_LENGTH
        def_bool y
  
  config GENERIC_ISA_DMA
 -      def_bool ISA_DMA_API
 +      def_bool y
 +      depends on ISA_DMA_API
  
  config GENERIC_BUG
        def_bool y
@@@ -164,16 -151,13 +165,16 @@@ config GENERIC_GPI
        bool
  
  config ARCH_MAY_HAVE_PC_FDC
 -      def_bool ISA_DMA_API
 +      def_bool y
 +      depends on ISA_DMA_API
  
  config RWSEM_GENERIC_SPINLOCK
 -      def_bool !X86_XADD
 +      def_bool y
 +      depends on !X86_XADD
  
  config RWSEM_XCHGADD_ALGORITHM
 -      def_bool X86_XADD
 +      def_bool y
 +      depends on X86_XADD
  
  config GENERIC_CALIBRATE_DELAY
        def_bool y
@@@ -590,18 -574,23 +591,18 @@@ config PARAVIRT_TIME_ACCOUNTIN
  
  source "arch/x86/xen/Kconfig"
  
 -config KVM_CLOCK
 -      bool "KVM paravirtualized clock"
 -      select PARAVIRT
 -      select PARAVIRT_CLOCK
 -      ---help---
 -        Turning on this option will allow you to run a paravirtualized clock
 -        when running over the KVM hypervisor. Instead of relying on a PIT
 -        (or probably other) emulation by the underlying device model, the host
 -        provides the guest with timing infrastructure such as time of day, and
 -        system time
 -
  config KVM_GUEST
 -      bool "KVM Guest support"
 +      bool "KVM Guest support (including kvmclock)"
 +      select PARAVIRT
        select PARAVIRT
 +      select PARAVIRT_CLOCK
 +      default y if PARAVIRT_GUEST
        ---help---
          This option enables various optimizations for running under the KVM
 -        hypervisor.
 +        hypervisor. It includes a paravirtualized clock, so that instead
 +        of relying on a PIT (or probably other) emulation by the
 +        underlying device model, the host provides the guest with
 +        timing infrastructure such as time of day, and system time
  
  source "arch/x86/lguest/Kconfig"
  
@@@ -758,14 -747,13 +759,14 @@@ config SWIOTL
        def_bool y if X86_64
        ---help---
          Support for software bounce buffers used on x86-64 systems
 -        which don't have a hardware IOMMU (e.g. the current generation
 -        of Intel's x86-64 CPUs). Using this PCI devices which can only
 -        access 32-bits of memory can be used on systems with more than
 -        3 GB of memory. If unsure, say Y.
 +        which don't have a hardware IOMMU. Using this PCI devices
 +        which can only access 32-bits of memory can be used on systems
 +        with more than 3 GB of memory.
 +        If unsure, say Y.
  
  config IOMMU_HELPER
 -      def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)
 +      def_bool y
 +      depends on CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU
  
  config MAXSMP
        bool "Enable Maximum number of SMP Processors and NUMA Nodes"
@@@ -809,6 -797,17 +810,6 @@@ config SCHED_M
          making when dealing with multi-core CPU chips at a cost of slightly
          increased overhead in some places. If unsure say N here.
  
 -config IRQ_TIME_ACCOUNTING
 -      bool "Fine granularity task level IRQ time accounting"
 -      default n
 -      ---help---
 -        Select this option to enable fine granularity task irq time
 -        accounting. This is done by reading a timestamp on each
 -        transitions between softirq and hardirq state, so there can be a
 -        small performance impact.
 -
 -        If in doubt, say N here.
 -
  source "kernel/Kconfig.preempt"
  
  config X86_UP_APIC
@@@ -873,7 -872,6 +874,7 @@@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQ
  
  config X86_MCE
        bool "Machine Check / overheating reporting"
 +      default y
        ---help---
          Machine Check support allows the processor to notify the
          kernel if it detects a problem (e.g. overheating, data corruption).
@@@ -985,25 -983,25 +986,25 @@@ config X86_REBOOTFIXUP
          Say N otherwise.
  
  config MICROCODE
 -      tristate "/dev/cpu/microcode - microcode support"
 +      tristate "CPU microcode loading support"
        select FW_LOADER
        ---help---
 +
          If you say Y here, you will be able to update the microcode on
          certain Intel and AMD processors. The Intel support is for the
 -        IA32 family, e.g. Pentium Pro, Pentium II, Pentium III,
 -        Pentium 4, Xeon etc. The AMD support is for family 0x10 and
 -        0x11 processors, e.g. Opteron, Phenom and Turion 64 Ultra.
 -        You will obviously need the actual microcode binary data itself
 -        which is not shipped with the Linux kernel.
 +        IA32 family, e.g. Pentium Pro, Pentium II, Pentium III, Pentium 4,
 +        Xeon etc. The AMD support is for families 0x10 and later. You will
 +        obviously need the actual microcode binary data itself which is not
 +        shipped with the Linux kernel.
  
          This option selects the general module only, you need to select
          at least one vendor specific module as well.
  
 -        To compile this driver as a module, choose M here: the
 -        module will be called microcode.
 +        To compile this driver as a module, choose M here: the module
 +        will be called microcode.
  
  config MICROCODE_INTEL
 -      bool "Intel microcode patch loading support"
 +      bool "Intel microcode loading support"
        depends on MICROCODE
        default MICROCODE
        select FW_LOADER
          <http://www.urbanmyth.org/microcode/>.
  
  config MICROCODE_AMD
 -      bool "AMD microcode patch loading support"
 +      bool "AMD microcode loading support"
        depends on MICROCODE
        select FW_LOADER
        ---help---
@@@ -1162,12 -1160,10 +1163,12 @@@ config X86_PA
          consumes more pagetable space per process.
  
  config ARCH_PHYS_ADDR_T_64BIT
 -      def_bool X86_64 || X86_PAE
 +      def_bool y
 +      depends on X86_64 || X86_PAE
  
  config ARCH_DMA_ADDR_T_64BIT
 -      def_bool X86_64 || HIGHMEM64G
 +      def_bool y
 +      depends on X86_64 || HIGHMEM64G
  
  config DIRECT_GBPAGES
        bool "Enable 1GB pages for kernel pagetables" if EXPERT
@@@ -1290,8 -1286,8 +1291,8 @@@ config ARCH_SELECT_MEMORY_MODE
        depends on ARCH_SPARSEMEM_ENABLE
  
  config ARCH_MEMORY_PROBE
 -      def_bool X86_64
 -      depends on MEMORY_HOTPLUG
 +      def_bool y
 +      depends on X86_64 && MEMORY_HOTPLUG
  
  config ARCH_PROC_KCORE_TEXT
        def_bool y
@@@ -1492,17 -1488,6 +1493,17 @@@ config ARCH_RANDO
          If supported, this is a high bandwidth, cryptographically
          secure hardware random number generator.
  
 +config X86_SMAP
 +      def_bool y
 +      prompt "Supervisor Mode Access Prevention" if EXPERT
 +      ---help---
 +        Supervisor Mode Access Prevention (SMAP) is a security
 +        feature in newer Intel processors.  There is a small
 +        performance cost if this enabled and turned on; there is
 +        also a small increase in the kernel size if this is enabled.
 +
 +        If unsure, say Y.
 +
  config EFI
        bool "EFI runtime service support"
        depends on ACPI
@@@ -1991,6 -1976,7 +1992,6 @@@ config PCI_MMCONFI
  
  config PCI_CNB20LE_QUIRK
        bool "Read CNB20LE Host Bridge Windows" if EXPERT
 -      default n
        depends on PCI && EXPERIMENTAL
        help
          Read the PCI windows out of the CNB20LE host bridge. This allows
@@@ -2172,7 -2158,6 +2173,7 @@@ config IA32_EMULATIO
        bool "IA32 Emulation"
        depends on X86_64
        select COMPAT_BINFMT_ELF
 +      select HAVE_UID16
        ---help---
          Include code to run legacy 32-bit programs under a
          64-bit kernel. You should likely turn this on, unless you're
@@@ -2202,18 -2187,18 +2203,18 @@@ config COMPA
        depends on IA32_EMULATION || X86_X32
        select ARCH_WANT_OLD_COMPAT_IPC
  
 +if COMPAT
  config COMPAT_FOR_U64_ALIGNMENT
 -      def_bool COMPAT
 -      depends on X86_64
 +      def_bool y
  
  config SYSVIPC_COMPAT
        def_bool y
 -      depends on COMPAT && SYSVIPC
 +      depends on SYSVIPC
  
  config KEYS_COMPAT
 -      bool
 -      depends on COMPAT && KEYS
 -      default y
 +      def_bool y
 +      depends on KEYS
 +endif
  
  endmenu
  
index 9c289504e680303a2bdfed3308eb40eb35135176,e75f941bd2b2cb6c4ddd361125a738639a77cacc..076745fc8045a8c35d1df646ede41d3c191c52e6
@@@ -14,7 -14,6 +14,7 @@@
  #include <asm/segment.h>
  #include <asm/irqflags.h>
  #include <asm/asm.h>
 +#include <asm/smap.h>
  #include <linux/linkage.h>
  #include <linux/err.h>
  
@@@ -147,10 -146,8 +147,10 @@@ ENTRY(ia32_sysenter_target
        SAVE_ARGS 0,1,0
        /* no need to do an access_ok check here because rbp has been
           32bit zero extended */ 
 +      ASM_STAC
  1:    movl    (%rbp),%ebp
        _ASM_EXTABLE(1b,ia32_badarg)
 +      ASM_CLAC
        orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        CFI_REMEMBER_STATE
@@@ -304,10 -301,8 +304,10 @@@ ENTRY(ia32_cstar_target
        /* no need to do an access_ok check here because r8 has been
           32bit zero extended */ 
        /* hardware stack frame is complete now */      
 +      ASM_STAC
  1:    movl    (%r8),%r9d
        _ASM_EXTABLE(1b,ia32_badarg)
 +      ASM_CLAC
        orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        CFI_REMEMBER_STATE
@@@ -370,7 -365,6 +370,7 @@@ cstar_tracesys
  END(ia32_cstar_target)
                                
  ia32_badarg:
 +      ASM_CLAC
        movq $-EFAULT,%rax
        jmp ia32_sysret
        CFI_ENDPROC
@@@ -465,7 -459,7 +465,7 @@@ GLOBAL(\label
        PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
        PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
        PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
-       PTREGSCALL stub32_execve, sys32_execve, %rcx
+       PTREGSCALL stub32_execve, compat_sys_execve, %rcx
        PTREGSCALL stub32_fork, sys_fork, %rdi
        PTREGSCALL stub32_clone, sys32_clone, %rdx
        PTREGSCALL stub32_vfork, sys_vfork, %rdi
diff --combined arch/x86/ia32/sys_ia32.c
index c5b938d92eab3c3eb07294fdc425b8e756f776b6,6b31144589d04ed559a5ceb809aaccd1c3685ddd..86d68d1c8806b27fdf5506d0807d6fe874b48438
@@@ -287,7 -287,7 +287,7 @@@ asmlinkage long sys32_sigaction(int sig
        return ret;
  }
  
 -asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr,
 +asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int __user *stat_addr,
                              int options)
  {
        return compat_sys_wait4(pid, stat_addr, options, NULL);
@@@ -385,21 -385,6 +385,6 @@@ asmlinkage long sys32_sendfile(int out_
        return ret;
  }
  
- asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-                            compat_uptr_t __user *envp, struct pt_regs *regs)
- {
-       long error;
-       char *filename;
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = compat_do_execve(filename, argv, envp, regs);
-       putname(filename);
-       return error;
- }
  asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
                            struct pt_regs *regs)
  {
index b98c0d958ebbdf830536ad42e3d166c198c1d29e,078f3fdedf95ad0696092613bff725e3058280c1..ad1fc85116743d677ff5b050e7226c2988a5e559
@@@ -423,6 -423,7 +423,6 @@@ DECLARE_INIT_PER_CPU(irq_stack_union)
  
  DECLARE_PER_CPU(char *, irq_stack_ptr);
  DECLARE_PER_CPU(unsigned int, irq_count);
 -extern unsigned long kernel_eflags;
  extern asmlinkage void ignore_sysret(void);
  #else /* X86_64 */
  #ifdef CONFIG_CC_STACKPROTECTOR
@@@ -588,11 -589,6 +588,6 @@@ typedef struct 
  } mm_segment_t;
  
  
- /*
-  * create a kernel thread without removing it from tasklists
-  */
- extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
  /* Free all resources held by a thread. */
  extern void release_thread(struct task_struct *);
  
@@@ -758,8 -754,6 +753,8 @@@ static inline void update_debugctlmsr(u
        wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
  }
  
 +extern void set_task_blockstep(struct task_struct *task, bool on);
 +
  /*
   * from system description table in BIOS. Mostly for MCA use, but
   * others may find it useful:
index 4ca1c611b55202cfa6df55c37032cce27eca86b8,1ac127f41fe6668fe6a64c6667b3b56c16eab7a5..a9a8cf3da49d72ae78eb3e98af8ad3e0523ce6e3
@@@ -40,7 -40,7 +40,7 @@@ asmlinkage long sys32_sigaction(int, st
                                struct old_sigaction32 __user *);
  asmlinkage long sys32_alarm(unsigned int);
  
 -asmlinkage long sys32_waitpid(compat_pid_t, unsigned int *, int);
 +asmlinkage long sys32_waitpid(compat_pid_t, unsigned int __user *, int);
  asmlinkage long sys32_sysfs(int, u32, u32);
  
  asmlinkage long sys32_sched_rr_get_interval(compat_pid_t,
@@@ -54,8 -54,6 +54,6 @@@ asmlinkage long sys32_pwrite(unsigned i
  asmlinkage long sys32_personality(unsigned long);
  asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
  
- asmlinkage long sys32_execve(const char __user *, compat_uptr_t __user *,
-                            compat_uptr_t __user *, struct pt_regs *);
  asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
  
  long sys32_lseek(unsigned int, int, unsigned int);
index c535d847e3b5f75dff0d8d2dd7988935fc35b63f,c509d07bdbd72b15d425f1a445eaf42dd4f6ae83..2d946e63ee82bceca34043aff29958b5e0e34127
@@@ -79,7 -79,6 +79,6 @@@ struct thread_info 
  #define TIF_SIGPENDING                2       /* signal pending */
  #define TIF_NEED_RESCHED      3       /* rescheduling necessary */
  #define TIF_SINGLESTEP                4       /* reenable singlestep on user return*/
- #define TIF_IRET              5       /* force IRET */
  #define TIF_SYSCALL_EMU               6       /* syscall emulation active */
  #define TIF_SYSCALL_AUDIT     7       /* syscall auditing active */
  #define TIF_SECCOMP           8       /* secure computing */
@@@ -89,7 -88,6 +88,7 @@@
  #define TIF_NOTSC             16      /* TSC is not accessible in userland */
  #define TIF_IA32              17      /* IA32 compatibility process */
  #define TIF_FORK              18      /* ret_from_fork */
 +#define TIF_NOHZ              19      /* in adaptive nohz mode */
  #define TIF_MEMDIE            20      /* is terminating due to OOM killer */
  #define TIF_DEBUG             21      /* uses debug registers */
  #define TIF_IO_BITMAP         22      /* uses I/O bitmap */
  #define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
  #define _TIF_SINGLESTEP               (1 << TIF_SINGLESTEP)
  #define _TIF_NEED_RESCHED     (1 << TIF_NEED_RESCHED)
- #define _TIF_IRET             (1 << TIF_IRET)
  #define _TIF_SYSCALL_EMU      (1 << TIF_SYSCALL_EMU)
  #define _TIF_SYSCALL_AUDIT    (1 << TIF_SYSCALL_AUDIT)
  #define _TIF_SECCOMP          (1 << TIF_SECCOMP)
  #define _TIF_NOTSC            (1 << TIF_NOTSC)
  #define _TIF_IA32             (1 << TIF_IA32)
  #define _TIF_FORK             (1 << TIF_FORK)
 +#define _TIF_NOHZ             (1 << TIF_NOHZ)
  #define _TIF_DEBUG            (1 << TIF_DEBUG)
  #define _TIF_IO_BITMAP                (1 << TIF_IO_BITMAP)
  #define _TIF_FORCED_TF                (1 << TIF_FORCED_TF)
  /* work to do in syscall_trace_enter() */
  #define _TIF_WORK_SYSCALL_ENTRY       \
        (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT |   \
 -       _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT)
 +       _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT |     \
 +       _TIF_NOHZ)
  
  /* work to do in syscall_trace_leave() */
  #define _TIF_WORK_SYSCALL_EXIT        \
        (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP |    \
 -       _TIF_SYSCALL_TRACEPOINT)
 +       _TIF_SYSCALL_TRACEPOINT | _TIF_NOHZ)
  
  /* work to do on interrupt/exception return */
  #define _TIF_WORK_MASK                                                        \
  
  /* work to do on any return to user space */
  #define _TIF_ALLWORK_MASK                                             \
 -      ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT)
 +      ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT |       \
 +      _TIF_NOHZ)
  
  /* Only used for 64 bit */
  #define _TIF_DO_NOTIFY_MASK                                           \
diff --combined arch/x86/kernel/Makefile
index a48ea05157d3bbcb8cb56c4a2f92bb45cad446e8,5661000022332d5190916bc76bab8c21f48ec300..91ce48f05f9f6d623beaa84029be5ff1cdf1cfc8
@@@ -23,7 -23,7 +23,7 @@@ obj-y                 += time.o ioport.o ldt.o dumpst
  obj-y                 += setup.o x86_init.o i8259.o irqinit.o jump_label.o
  obj-$(CONFIG_IRQ_WORK)  += irq_work.o
  obj-y                 += probe_roms.o
- obj-$(CONFIG_X86_32)  += sys_i386_32.o i386_ksyms_32.o
+ obj-$(CONFIG_X86_32)  += i386_ksyms_32.o
  obj-$(CONFIG_X86_64)  += sys_x86_64.o x8664_ksyms_64.o
  obj-y                 += syscall_$(BITS).o
  obj-$(CONFIG_X86_64)  += vsyscall_64.o
@@@ -81,7 -81,8 +81,7 @@@ obj-$(CONFIG_DEBUG_RODATA_TEST)       += test
  obj-$(CONFIG_DEBUG_NX_TEST)   += test_nx.o
  obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
  
 -obj-$(CONFIG_KVM_GUEST)               += kvm.o
 -obj-$(CONFIG_KVM_CLOCK)               += kvmclock.o
 +obj-$(CONFIG_KVM_GUEST)               += kvm.o kvmclock.o
  obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirt_patch_$(BITS).o
  obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
  obj-$(CONFIG_PARAVIRT_CLOCK)  += pvclock.o
@@@ -99,8 -100,6 +99,8 @@@ obj-$(CONFIG_SWIOTLB)                        += pci-swiotlb.
  obj-$(CONFIG_OF)                      += devicetree.o
  obj-$(CONFIG_UPROBES)                 += uprobes.o
  
 +obj-$(CONFIG_PERF_EVENTS)             += perf_regs.o
 +
  ###
  # 64 bit specific files
  ifeq ($(CONFIG_X86_64),y)
index 0750e3ba87c09447c7443112b0a1e5678538de91,b6bb6923929631106bf8562787b2daf396551b10..8f9ed1afde8f28565a9e9325e4ecc3f61a3fc089
@@@ -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>
@@@ -299,6 -298,13 +299,13 @@@ ENTRY(ret_from_fork
        CFI_ENDPROC
  END(ret_from_fork)
  
+ ENTRY(ret_from_kernel_execve)
+       movl %eax, %esp
+       movl $0,PT_EAX(%esp)
+       GET_THREAD_INFO(%ebp)
+       jmp syscall_exit
+ END(ret_from_kernel_execve)
  /*
   * Interrupt exit functions should be protected against kprobes
   */
@@@ -323,8 -329,7 +330,7 @@@ ret_from_intr
        andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
  #else
        /*
-        * We can be coming here from a syscall done in the kernel space,
-        * e.g. a failed kernel_execve().
+        * We can be coming here from child spawned by kernel_thread().
         */
        movl PT_CS(%esp), %eax
        andl $SEGMENT_RPL_MASK, %eax
@@@ -408,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)
  
@@@ -491,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)
@@@ -674,7 -676,6 +680,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
@@@ -732,7 -733,6 +738,6 @@@ ENDPROC(ptregs_##name
  PTREGSCALL1(iopl)
  PTREGSCALL0(fork)
  PTREGSCALL0(vfork)
- PTREGSCALL3(execve)
  PTREGSCALL2(sigaltstack)
  PTREGSCALL0(sigreturn)
  PTREGSCALL0(rt_sigreturn)
@@@ -830,7 -830,6 +835,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
@@@ -847,7 -846,6 +852,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                  \
@@@ -864,7 -862,6 +869,7 @@@ ENDPROC(name
  
  ENTRY(coprocessor_error)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_coprocessor_error
        jmp error_code
@@@ -873,7 -870,6 +878,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 */
@@@ -895,7 -891,6 +900,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
@@@ -916,7 -911,6 +921,7 @@@ END(native_irq_enable_sysexit
  
  ENTRY(overflow)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_overflow
        jmp error_code
@@@ -925,7 -919,6 +930,7 @@@ END(overflow
  
  ENTRY(bounds)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_bounds
        jmp error_code
@@@ -934,7 -927,6 +939,7 @@@ END(bounds
  
  ENTRY(invalid_op)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $0
        pushl_cfi $do_invalid_op
        jmp error_code
@@@ -943,7 -935,6 +948,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
@@@ -952,7 -943,6 +957,7 @@@ END(coprocessor_segment_overrun
  
  ENTRY(invalid_TSS)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_invalid_TSS
        jmp error_code
        CFI_ENDPROC
@@@ -960,7 -950,6 +965,7 @@@ END(invalid_TSS
  
  ENTRY(segment_not_present)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_segment_not_present
        jmp error_code
        CFI_ENDPROC
@@@ -968,7 -957,6 +973,7 @@@ END(segment_not_present
  
  ENTRY(stack_segment)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_stack_segment
        jmp error_code
        CFI_ENDPROC
@@@ -976,7 -964,6 +981,7 @@@ END(stack_segment
  
  ENTRY(alignment_check)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_alignment_check
        jmp error_code
        CFI_ENDPROC
@@@ -984,7 -971,6 +989,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
@@@ -994,7 -980,6 +999,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
@@@ -1004,7 -989,6 +1009,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
@@@ -1015,15 -999,20 +1020,20 @@@ END(spurious_interrupt_bug
   */
        .popsection
  
- ENTRY(kernel_thread_helper)
-       pushl $0                # fake return address for unwinder
+ ENTRY(ret_from_kernel_thread)
        CFI_STARTPROC
-       movl %edi,%eax
-       call *%esi
+       pushl_cfi %eax
+       call schedule_tail
+       GET_THREAD_INFO(%ebp)
+       popl_cfi %eax
+       pushl_cfi $0x0202               # Reset kernel eflags
+       popfl_cfi
+       movl PT_EBP(%esp),%eax
+       call *PT_EBX(%esp)
        call do_exit
        ud2                     # padding for call trace
        CFI_ENDPROC
- ENDPROC(kernel_thread_helper)
+ ENDPROC(ret_from_kernel_thread)
  
  #ifdef CONFIG_XEN
  /* Xen doesn't set %esp to be precisely what the normal sysenter
@@@ -1130,21 -1119,17 +1140,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:
@@@ -1156,71 -1141,6 +1166,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)
@@@ -1261,6 -1181,9 +1271,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
@@@ -1294,7 -1217,6 +1304,7 @@@ return_to_handler
  
  ENTRY(page_fault)
        RING0_EC_FRAME
 +      ASM_CLAC
        pushl_cfi $do_page_fault
        ALIGN
  error_code:
@@@ -1367,7 -1289,6 +1377,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
@@@ -1392,7 -1313,6 +1402,7 @@@ END(debug
   */
  ENTRY(nmi)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi %eax
        movl %ss, %eax
        cmpw $__ESPFIX_SS, %ax
@@@ -1463,7 -1383,6 +1473,7 @@@ END(nmi
  
  ENTRY(int3)
        RING0_INT_FRAME
 +      ASM_CLAC
        pushl_cfi $-1                   # mark this as an int
        SAVE_ALL
        TRACE_IRQS_OFF
@@@ -1484,7 -1403,6 +1494,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
index 44531acd9a81e83f932a34a409c028b24cdb9bce,053c9552ffd94c8bad8fab58be06ffab8dc55a09..cdc790c78f328ed0d9525c270ed9e4013db28bdb
@@@ -56,8 -56,6 +56,8 @@@
  #include <asm/ftrace.h>
  #include <asm/percpu.h>
  #include <asm/asm.h>
 +#include <asm/rcu.h>
 +#include <asm/smap.h>
  #include <linux/err.h>
  
  /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
        .section .entry.text, "ax"
  
  #ifdef CONFIG_FUNCTION_TRACER
 +
 +#ifdef CC_USING_FENTRY
 +# define function_hook        __fentry__
 +#else
 +# define function_hook        mcount
 +#endif
 +
  #ifdef CONFIG_DYNAMIC_FTRACE
 -ENTRY(mcount)
 +
 +ENTRY(function_hook)
        retq
 -END(mcount)
 +END(function_hook)
 +
 +/* skip is set if stack has been adjusted */
 +.macro ftrace_caller_setup skip=0
 +      MCOUNT_SAVE_FRAME \skip
 +
 +      /* Load the ftrace_ops into the 3rd parameter */
 +      leaq function_trace_op, %rdx
 +
 +      /* Load ip into the first parameter */
 +      movq RIP(%rsp), %rdi
 +      subq $MCOUNT_INSN_SIZE, %rdi
 +      /* Load the parent_ip into the second parameter */
 +#ifdef CC_USING_FENTRY
 +      movq SS+16(%rsp), %rsi
 +#else
 +      movq 8(%rbp), %rsi
 +#endif
 +.endm
  
  ENTRY(ftrace_caller)
 +      /* Check if tracing was disabled (quick check) */
        cmpl $0, function_trace_stop
        jne  ftrace_stub
  
 -      MCOUNT_SAVE_FRAME
 -
 -      movq 0x38(%rsp), %rdi
 -      movq 8(%rbp), %rsi
 -      subq $MCOUNT_INSN_SIZE, %rdi
 +      ftrace_caller_setup
 +      /* regs go into 4th parameter (but make it NULL) */
 +      movq $0, %rcx
  
  GLOBAL(ftrace_call)
        call ftrace_stub
  
        MCOUNT_RESTORE_FRAME
 +ftrace_return:
  
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  GLOBAL(ftrace_graph_call)
@@@ -125,78 -97,8 +125,78 @@@ GLOBAL(ftrace_stub
        retq
  END(ftrace_caller)
  
 +ENTRY(ftrace_regs_caller)
 +      /* Save the current flags before compare (in SS location)*/
 +      pushfq
 +
 +      /* Check if tracing was disabled (quick check) */
 +      cmpl $0, function_trace_stop
 +      jne  ftrace_restore_flags
 +
 +      /* skip=8 to skip flags saved in SS */
 +      ftrace_caller_setup 8
 +
 +      /* Save the rest of pt_regs */
 +      movq %r15, R15(%rsp)
 +      movq %r14, R14(%rsp)
 +      movq %r13, R13(%rsp)
 +      movq %r12, R12(%rsp)
 +      movq %r11, R11(%rsp)
 +      movq %r10, R10(%rsp)
 +      movq %rbp, RBP(%rsp)
 +      movq %rbx, RBX(%rsp)
 +      /* Copy saved flags */
 +      movq SS(%rsp), %rcx
 +      movq %rcx, EFLAGS(%rsp)
 +      /* Kernel segments */
 +      movq $__KERNEL_DS, %rcx
 +      movq %rcx, SS(%rsp)
 +      movq $__KERNEL_CS, %rcx
 +      movq %rcx, CS(%rsp)
 +      /* Stack - skipping return address */
 +      leaq SS+16(%rsp), %rcx
 +      movq %rcx, RSP(%rsp)
 +
 +      /* regs go into 4th parameter */
 +      leaq (%rsp), %rcx
 +
 +GLOBAL(ftrace_regs_call)
 +      call ftrace_stub
 +
 +      /* Copy flags back to SS, to restore them */
 +      movq EFLAGS(%rsp), %rax
 +      movq %rax, SS(%rsp)
 +
 +      /* Handlers can change the RIP */
 +      movq RIP(%rsp), %rax
 +      movq %rax, SS+8(%rsp)
 +
 +      /* restore the rest of pt_regs */
 +      movq R15(%rsp), %r15
 +      movq R14(%rsp), %r14
 +      movq R13(%rsp), %r13
 +      movq R12(%rsp), %r12
 +      movq R10(%rsp), %r10
 +      movq RBP(%rsp), %rbp
 +      movq RBX(%rsp), %rbx
 +
 +      /* skip=8 to skip flags saved in SS */
 +      MCOUNT_RESTORE_FRAME 8
 +
 +      /* Restore flags */
 +      popfq
 +
 +      jmp ftrace_return
 +ftrace_restore_flags:
 +      popfq
 +      jmp  ftrace_stub
 +
 +END(ftrace_regs_caller)
 +
 +
  #else /* ! CONFIG_DYNAMIC_FTRACE */
 -ENTRY(mcount)
 +
 +ENTRY(function_hook)
        cmpl $0, function_trace_stop
        jne  ftrace_stub
  
@@@ -217,12 -119,8 +217,12 @@@ GLOBAL(ftrace_stub
  trace:
        MCOUNT_SAVE_FRAME
  
 -      movq 0x38(%rsp), %rdi
 +      movq RIP(%rsp), %rdi
 +#ifdef CC_USING_FENTRY
 +      movq SS+16(%rsp), %rsi
 +#else
        movq 8(%rbp), %rsi
 +#endif
        subq $MCOUNT_INSN_SIZE, %rdi
  
        call   *ftrace_trace_function
        MCOUNT_RESTORE_FRAME
  
        jmp ftrace_stub
 -END(mcount)
 +END(function_hook)
  #endif /* CONFIG_DYNAMIC_FTRACE */
  #endif /* CONFIG_FUNCTION_TRACER */
  
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  ENTRY(ftrace_graph_caller)
 -      cmpl $0, function_trace_stop
 -      jne ftrace_stub
 -
        MCOUNT_SAVE_FRAME
  
 +#ifdef CC_USING_FENTRY
 +      leaq SS+16(%rsp), %rdi
 +      movq $0, %rdx   /* No framepointers needed */
 +#else
        leaq 8(%rbp), %rdi
 -      movq 0x38(%rsp), %rsi
        movq (%rbp), %rdx
 +#endif
 +      movq RIP(%rsp), %rsi
        subq $MCOUNT_INSN_SIZE, %rsi
  
        call    prepare_ftrace_return
@@@ -446,15 -342,15 +446,15 @@@ ENDPROC(native_usergs_sysret64
        .macro SAVE_ARGS_IRQ
        cld
        /* start from rbp in pt_regs and jump over */
 -      movq_cfi rdi, RDI-RBP
 -      movq_cfi rsi, RSI-RBP
 -      movq_cfi rdx, RDX-RBP
 -      movq_cfi rcx, RCX-RBP
 -      movq_cfi rax, RAX-RBP
 -      movq_cfi  r8,  R8-RBP
 -      movq_cfi  r9,  R9-RBP
 -      movq_cfi r10, R10-RBP
 -      movq_cfi r11, R11-RBP
 +      movq_cfi rdi, (RDI-RBP)
 +      movq_cfi rsi, (RSI-RBP)
 +      movq_cfi rdx, (RDX-RBP)
 +      movq_cfi rcx, (RCX-RBP)
 +      movq_cfi rax, (RAX-RBP)
 +      movq_cfi  r8,  (R8-RBP)
 +      movq_cfi  r9,  (R9-RBP)
 +      movq_cfi r10, (R10-RBP)
 +      movq_cfi r11, (R11-RBP)
  
        /* Save rbp so that we can unwind from get_irq_regs() */
        movq_cfi rbp, 0
        .endm
  
  ENTRY(save_rest)
 -      PARTIAL_FRAME 1 REST_SKIP+8
 +      PARTIAL_FRAME 1 (REST_SKIP+8)
        movq 5*8+16(%rsp), %r11 /* save return address */
        movq_cfi rbx, RBX+16
        movq_cfi rbp, RBP+16
@@@ -544,7 -440,7 +544,7 @@@ ENTRY(ret_from_fork
  
        LOCK ; btr $TIF_FORK,TI_flags(%r8)
  
 -      pushq_cfi kernel_eflags(%rip)
 +      pushq_cfi $0x0002
        popfq_cfi                               # reset kernel eflags
  
        call schedule_tail                      # rdi: 'prev' task parameter
        RESTORE_REST
  
        testl $3, CS-ARGOFFSET(%rsp)            # from kernel_thread?
-       jz   retint_restore_args
+       jz   1f
  
        testl $_TIF_IA32, TI_flags(%rcx)        # 32-bit compat task needs IRET
        jnz  int_ret_from_sys_call
        RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET
        jmp ret_from_sys_call                   # go to the SYSRET fastpath
  
+ 1:
+       subq $REST_SKIP, %rsp   # move the stack pointer back
+       CFI_ADJUST_CFA_OFFSET   REST_SKIP
+       movq %rbp, %rdi
+       call *%rbx
+       # exit
+       mov %eax, %edi
+       call do_exit
+       ud2                     # padding for call trace
        CFI_ENDPROC
  END(ret_from_fork)
  
   * System call entry. Up to 6 arguments in registers are supported.
   *
   * SYSCALL does not save anything on the stack and does not change the
 - * stack pointer.
 + * stack pointer.  However, it does mask the flags register for us, so
 + * CLD and CLAC are not needed.
   */
  
  /*
@@@ -670,7 -575,7 +680,7 @@@ sysret_careful
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
        pushq_cfi %rdi
 -      call schedule
 +      SCHEDULE_USER
        popq_cfi %rdi
        jmp sysret_check
  
@@@ -783,7 -688,7 +793,7 @@@ int_careful
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
        pushq_cfi %rdi
 -      call schedule
 +      SCHEDULE_USER
        popq_cfi %rdi
        DISABLE_INTERRUPTS(CLBR_NONE)
        TRACE_IRQS_OFF
@@@ -862,7 -767,6 +872,6 @@@ ENTRY(stub_execve
        PARTIAL_FRAME 0
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
-       movq %rsp, %rcx
        call sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
@@@ -912,8 -816,7 +921,7 @@@ ENTRY(stub_x32_execve
        PARTIAL_FRAME 0
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
-       movq %rsp, %rcx
-       call sys32_execve
+       call compat_sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
        RESTORE_REST
@@@ -989,7 -892,6 +997,7 @@@ END(interrupt
         */
        .p2align CONFIG_X86_L1_CACHE_SHIFT
  common_interrupt:
 +      ASM_CLAC
        XCPT_FRAME
        addq $-0x80,(%rsp)              /* Adjust vector to [-256,-1] range */
        interrupt do_IRQ
@@@ -1080,7 -982,7 +1088,7 @@@ retint_careful
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_NONE)
        pushq_cfi %rdi
 -      call  schedule
 +      SCHEDULE_USER
        popq_cfi %rdi
        GET_THREAD_INFO(%rcx)
        DISABLE_INTERRUPTS(CLBR_NONE)
@@@ -1129,7 -1031,6 +1137,7 @@@ END(common_interrupt
   */
  .macro apicinterrupt num sym do_sym
  ENTRY(\sym)
 +      ASM_CLAC
        INTR_FRAME
        pushq_cfi $~(\num)
  .Lcommon_\sym:
@@@ -1184,7 -1085,6 +1192,7 @@@ apicinterrupt IRQ_WORK_VECTOR 
   */
  .macro zeroentry sym do_sym
  ENTRY(\sym)
 +      ASM_CLAC
        INTR_FRAME
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
@@@ -1202,7 -1102,6 +1210,7 @@@ END(\sym
  
  .macro paranoidzeroentry sym do_sym
  ENTRY(\sym)
 +      ASM_CLAC
        INTR_FRAME
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
@@@ -1221,7 -1120,6 +1229,7 @@@ END(\sym
  #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
  .macro paranoidzeroentry_ist sym do_sym ist
  ENTRY(\sym)
 +      ASM_CLAC
        INTR_FRAME
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
@@@ -1241,7 -1139,6 +1249,7 @@@ END(\sym
  
  .macro errorentry sym do_sym
  ENTRY(\sym)
 +      ASM_CLAC
        XCPT_FRAME
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        subq $ORIG_RAX-R15, %rsp
@@@ -1260,7 -1157,6 +1268,7 @@@ END(\sym
        /* error code is on the stack already */
  .macro paranoiderrorentry sym do_sym
  ENTRY(\sym)
 +      ASM_CLAC
        XCPT_FRAME
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        subq $ORIG_RAX-R15, %rsp
@@@ -1318,51 -1214,19 +1326,19 @@@ bad_gs
        jmp  2b
        .previous
  
- ENTRY(kernel_thread_helper)
-       pushq $0                # fake return address
-       CFI_STARTPROC
-       /*
-        * Here we are in the child and the registers are set as they were
-        * at kernel_thread() invocation in the parent.
-        */
-       call *%rsi
-       # exit
-       mov %eax, %edi
-       call do_exit
-       ud2                     # padding for call trace
-       CFI_ENDPROC
- END(kernel_thread_helper)
- /*
-  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
-  *
-  * C extern interface:
-  *     extern long execve(const char *name, char **argv, char **envp)
-  *
-  * asm input arguments:
-  *    rdi: name, rsi: argv, rdx: envp
-  *
-  * We want to fallback into:
-  *    extern long sys_execve(const char *name, char **argv,char **envp, struct pt_regs *regs)
-  *
-  * do_sys_execve asm fallback arguments:
-  *    rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
-  */
- ENTRY(kernel_execve)
-       CFI_STARTPROC
-       FAKE_STACK_FRAME $0
-       SAVE_ALL
-       movq %rsp,%rcx
-       call sys_execve
-       movq %rax, RAX(%rsp)
-       RESTORE_REST
-       testq %rax,%rax
-       je int_ret_from_sys_call
-       RESTORE_ARGS
-       UNFAKE_STACK_FRAME
-       ret
-       CFI_ENDPROC
- END(kernel_execve)
+ ENTRY(ret_from_kernel_execve)
+       movq %rdi, %rsp
+       movl $0, RAX(%rsp)
+       // RESTORE_REST
+       movq 0*8(%rsp), %r15
+       movq 1*8(%rsp), %r14
+       movq 2*8(%rsp), %r13
+       movq 3*8(%rsp), %r12
+       movq 4*8(%rsp), %rbp
+       movq 5*8(%rsp), %rbx
+       addq $(6*8), %rsp
+       jmp int_ret_from_sys_call
+ END(ret_from_kernel_execve)
  
  /* Call softirq on interrupt stack. Interrupts are off. */
  ENTRY(call_softirq)
@@@ -1561,7 -1425,7 +1537,7 @@@ paranoid_userspace
  paranoid_schedule:
        TRACE_IRQS_ON
        ENABLE_INTERRUPTS(CLBR_ANY)
 -      call schedule
 +      SCHEDULE_USER
        DISABLE_INTERRUPTS(CLBR_ANY)
        TRACE_IRQS_OFF
        jmp paranoid_userspace
index dc3567e083f9f5ec3a9d524756d191b5125490cc,eae2dd5cd5a04935c7ff02758e74fd4736ab7f02..b644e1c765dc211dbb07b6ee7570081e5cd0e6c6
@@@ -66,13 -66,15 +66,13 @@@ int arch_dup_task_struct(struct task_st
  {
        int ret;
  
 -      unlazy_fpu(src);
 -
        *dst = *src;
        if (fpu_allocated(&src->thread.fpu)) {
                memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu));
                ret = fpu_alloc(&dst->thread.fpu);
                if (ret)
                        return ret;
 -              fpu_copy(&dst->thread.fpu, &src->thread.fpu);
 +              fpu_copy(dst, src);
        }
        return 0;
  }
@@@ -95,6 -97,16 +95,6 @@@ void arch_task_cache_init(void
                                  SLAB_PANIC | SLAB_NOTRACK, NULL);
  }
  
 -static inline void drop_fpu(struct task_struct *tsk)
 -{
 -      /*
 -       * Forget coprocessor state..
 -       */
 -      tsk->fpu_counter = 0;
 -      clear_fpu(tsk);
 -      clear_used_math();
 -}
 -
  /*
   * Free current thread data structures etc..
   */
@@@ -151,13 -163,7 +151,13 @@@ void flush_thread(void
  
        flush_ptrace_hw_breakpoint(tsk);
        memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
 -      drop_fpu(tsk);
 +      drop_init_fpu(tsk);
 +      /*
 +       * Free the FPU state for non xsave platforms. They get reallocated
 +       * lazily at the first use.
 +       */
 +      if (!use_eager_fpu())
 +              free_thread_xstate(tsk);
  }
  
  static void hard_disable_TSC(void)
@@@ -292,71 -298,6 +292,6 @@@ sys_clone(unsigned long clone_flags, un
        return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
  }
  
- /*
-  * This gets run with %si containing the
-  * function to call, and %di containing
-  * the "args".
-  */
- extern void kernel_thread_helper(void);
- /*
-  * 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.si = (unsigned long) fn;
-       regs.di = (unsigned long) arg;
- #ifdef CONFIG_X86_32
-       regs.ds = __USER_DS;
-       regs.es = __USER_DS;
-       regs.fs = __KERNEL_PERCPU;
-       regs.gs = __KERNEL_STACK_CANARY;
- #else
-       regs.ss = __KERNEL_DS;
- #endif
-       regs.orig_ax = -1;
-       regs.ip = (unsigned long) kernel_thread_helper;
-       regs.cs = __KERNEL_CS | get_kernel_rpl();
-       regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
-       /* Ok, create the new process.. */
-       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
- }
- EXPORT_SYMBOL(kernel_thread);
- /*
-  * sys_execve() executes a new program.
-  */
- long sys_execve(const char __user *name,
-               const char __user *const __user *argv,
-               const char __user *const __user *envp, struct pt_regs *regs)
- {
-       long error;
-       char *filename;
-       filename = getname(name);
-       error = PTR_ERR(filename);
-       if (IS_ERR(filename))
-               return error;
-       error = do_execve(filename, argv, envp, regs);
- #ifdef CONFIG_X86_32
-       if (error == 0) {
-               /* Make sure we don't return using sysenter.. */
-                 set_thread_flag(TIF_IRET);
-         }
- #endif
-       putname(filename);
-       return error;
- }
  /*
   * Idle related variables and functions
   */
index b9ff83c7135bad337d4e5d7e7554be6e833204a0,25e7e9390d26349208eabac5f19e36725682aa67..44e0bff38e724de5b9e02e5bd9581133999ad40e
@@@ -57,6 -57,7 +57,7 @@@
  #include <asm/switch_to.h>
  
  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+ asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
  
  /*
   * Return saved PC of a blocked thread.
@@@ -127,23 -128,39 +128,39 @@@ void release_thread(struct task_struct 
  }
  
  int copy_thread(unsigned long clone_flags, unsigned long sp,
-       unsigned long unused,
+       unsigned long arg,
        struct task_struct *p, struct pt_regs *regs)
  {
-       struct pt_regs *childregs;
+       struct pt_regs *childregs = task_pt_regs(p);
        struct task_struct *tsk;
        int err;
  
-       childregs = task_pt_regs(p);
+       p->thread.sp = (unsigned long) childregs;
+       p->thread.sp0 = (unsigned long) (childregs+1);
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childregs, 0, sizeof(struct pt_regs));
+               p->thread.ip = (unsigned long) ret_from_kernel_thread;
+               task_user_gs(p) = __KERNEL_STACK_CANARY;
+               childregs->ds = __USER_DS;
+               childregs->es = __USER_DS;
+               childregs->fs = __KERNEL_PERCPU;
+               childregs->bx = sp;     /* function */
+               childregs->bp = arg;
+               childregs->orig_ax = -1;
+               childregs->cs = __KERNEL_CS | get_kernel_rpl();
+               childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+               p->fpu_counter = 0;
+               p->thread.io_bitmap_ptr = NULL;
+               memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+               return 0;
+       }
        *childregs = *regs;
        childregs->ax = 0;
        childregs->sp = sp;
  
-       p->thread.sp = (unsigned long) childregs;
-       p->thread.sp0 = (unsigned long) (childregs+1);
        p->thread.ip = (unsigned long) ret_from_fork;
        task_user_gs(p) = get_user_gs(regs);
  
        p->fpu_counter = 0;
@@@ -190,6 -207,16 +207,12 @@@ start_thread(struct pt_regs *regs, unsi
        regs->cs                = __USER_CS;
        regs->ip                = new_ip;
        regs->sp                = new_sp;
 -      /*
 -       * Free the old FP and other extended state
 -       */
 -      free_thread_xstate(current);
+       regs->flags             = X86_EFLAGS_IF;
+       /*
+        * force it to the iret return path by making it look as if there was
+        * some work pending.
+        */
+       set_thread_flag(TIF_NOTIFY_RESUME);
  }
  EXPORT_SYMBOL_GPL(start_thread);
  
index 8a6d20ce19784ee96362cbaaa29c696497122a6a,937f2af6f2d4eeeb5f2d68466bd843c058d45a50..16c6365e2b867c883805061f533349751f9bfbf0
@@@ -146,29 -146,18 +146,18 @@@ static inline u32 read_32bit_tls(struc
  }
  
  int copy_thread(unsigned long clone_flags, unsigned long sp,
-               unsigned long unused,
+               unsigned long arg,
        struct task_struct *p, struct pt_regs *regs)
  {
        int err;
        struct pt_regs *childregs;
        struct task_struct *me = current;
  
-       childregs = ((struct pt_regs *)
-                       (THREAD_SIZE + task_stack_page(p))) - 1;
-       *childregs = *regs;
-       childregs->ax = 0;
-       if (user_mode(regs))
-               childregs->sp = sp;
-       else
-               childregs->sp = (unsigned long)childregs;
+       p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+       childregs = task_pt_regs(p);
        p->thread.sp = (unsigned long) childregs;
-       p->thread.sp0 = (unsigned long) (childregs+1);
        p->thread.usersp = me->thread.usersp;
        set_tsk_thread_flag(p, TIF_FORK);
        p->fpu_counter = 0;
        p->thread.io_bitmap_ptr = NULL;
  
        p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
        savesegment(es, p->thread.es);
        savesegment(ds, p->thread.ds);
+       memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+       if (unlikely(!regs)) {
+               /* kernel thread */
+               memset(childregs, 0, sizeof(struct pt_regs));
+               childregs->sp = (unsigned long)childregs;
+               childregs->ss = __KERNEL_DS;
+               childregs->bx = sp; /* function */
+               childregs->bp = arg;
+               childregs->orig_ax = -1;
+               childregs->cs = __KERNEL_CS | get_kernel_rpl();
+               childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+               return 0;
+       }
+       *childregs = *regs;
+       childregs->ax = 0;
+       childregs->sp = sp;
  
        err = -ENOMEM;
        memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
@@@ -232,6 -239,10 +239,6 @@@ start_thread_common(struct pt_regs *reg
        regs->cs                = _cs;
        regs->ss                = _ss;
        regs->flags             = X86_EFLAGS_IF;
 -      /*
 -       * Free the old FP and other extended state
 -       */
 -      free_thread_xstate(current);
  }
  
  void
diff --combined arch/x86/kernel/signal.c
index b33144c8b3098a10d956882f31e6ca1933770ce7,c648fc5298729b76e1ab677df263d7d3a1f3551e..29ad351804e9324d3aaf59c07c86d274958516b3
@@@ -114,12 -114,11 +114,12 @@@ int restore_sigcontext(struct pt_regs *
                regs->orig_ax = -1;             /* disable syscall checks */
  
                get_user_ex(buf, &sc->fpstate);
 -              err |= restore_i387_xstate(buf);
  
                get_user_ex(*pax, &sc->ax);
        } get_user_catch(err);
  
 +      err |= restore_xstate_sig(buf, config_enabled(CONFIG_X86_32));
 +
        return err;
  }
  
@@@ -207,32 -206,35 +207,32 @@@ get_sigframe(struct k_sigaction *ka, st
             void __user **fpstate)
  {
        /* Default to using normal stack */
 +      unsigned long math_size = 0;
        unsigned long sp = regs->sp;
 +      unsigned long buf_fx = 0;
        int onsigstack = on_sig_stack(sp);
  
 -#ifdef CONFIG_X86_64
        /* redzone */
 -      sp -= 128;
 -#endif /* CONFIG_X86_64 */
 +      if (config_enabled(CONFIG_X86_64))
 +              sp -= 128;
  
        if (!onsigstack) {
                /* This is the X/Open sanctioned signal stack switching.  */
                if (ka->sa.sa_flags & SA_ONSTACK) {
                        if (current->sas_ss_size)
                                sp = current->sas_ss_sp + current->sas_ss_size;
 -              } else {
 -#ifdef CONFIG_X86_32
 -                      /* This is the legacy signal stack switching. */
 -                      if ((regs->ss & 0xffff) != __USER_DS &&
 -                              !(ka->sa.sa_flags & SA_RESTORER) &&
 -                                      ka->sa.sa_restorer)
 +              } else if (config_enabled(CONFIG_X86_32) &&
 +                         (regs->ss & 0xffff) != __USER_DS &&
 +                         !(ka->sa.sa_flags & SA_RESTORER) &&
 +                         ka->sa.sa_restorer) {
 +                              /* This is the legacy signal stack switching. */
                                sp = (unsigned long) ka->sa.sa_restorer;
 -#endif /* CONFIG_X86_32 */
                }
        }
  
        if (used_math()) {
 -              sp -= sig_xstate_size;
 -#ifdef CONFIG_X86_64
 -              sp = round_down(sp, 64);
 -#endif /* CONFIG_X86_64 */
 +              sp = alloc_mathframe(sp, config_enabled(CONFIG_X86_32),
 +                                   &buf_fx, &math_size);
                *fpstate = (void __user *)sp;
        }
  
        if (onsigstack && !likely(on_sig_stack(sp)))
                return (void __user *)-1L;
  
 -      /* save i387 state */
 -      if (used_math() && save_i387_xstate(*fpstate) < 0)
 +      /* save i387 and extended state */
 +      if (used_math() &&
 +          save_xstate_sig(*fpstate, (void __user *)buf_fx, math_size) < 0)
                return (void __user *)-1L;
  
        return (void __user *)sp;
@@@ -356,6 -357,7 +356,6 @@@ static int __setup_rt_frame(int sig, st
                put_user_ex(sig, &frame->sig);
                put_user_ex(&frame->info, &frame->pinfo);
                put_user_ex(&frame->uc, &frame->puc);
 -              err |= copy_siginfo_to_user(&frame->info, info);
  
                /* Create the ucontext.  */
                if (cpu_has_xsave)
                put_user_ex(sas_ss_flags(regs->sp),
                            &frame->uc.uc_stack.ss_flags);
                put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 -              err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
 -                                      regs, set->sig[0]);
 -              err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  
                /* Set up to return from userspace.  */
                restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
                 */
                put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
        } put_user_catch(err);
 +      
 +      err |= copy_siginfo_to_user(&frame->info, info);
 +      err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
 +                              regs, set->sig[0]);
 +      err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  
        if (err)
                return -EFAULT;
@@@ -436,6 -436,8 +436,6 @@@ static int __setup_rt_frame(int sig, st
                put_user_ex(sas_ss_flags(regs->sp),
                            &frame->uc.uc_stack.ss_flags);
                put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
 -              err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
 -              err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  
                /* Set up to return from userspace.  If provided, use a stub
                   already in userspace.  */
                }
        } put_user_catch(err);
  
 +      err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
 +      err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 +
        if (err)
                return -EFAULT;
  
  }
  #endif /* CONFIG_X86_32 */
  
 +static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
 +                            siginfo_t *info, compat_sigset_t *set,
 +                            struct pt_regs *regs)
 +{
 +#ifdef CONFIG_X86_X32_ABI
 +      struct rt_sigframe_x32 __user *frame;
 +      void __user *restorer;
 +      int err = 0;
 +      void __user *fpstate = NULL;
 +
 +      frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 +
 +      if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 +              return -EFAULT;
 +
 +      if (ka->sa.sa_flags & SA_SIGINFO) {
 +              if (copy_siginfo_to_user32(&frame->info, info))
 +                      return -EFAULT;
 +      }
 +
 +      put_user_try {
 +              /* Create the ucontext.  */
 +              if (cpu_has_xsave)
 +                      put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
 +              else
 +                      put_user_ex(0, &frame->uc.uc_flags);
 +              put_user_ex(0, &frame->uc.uc_link);
 +              put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 +              put_user_ex(sas_ss_flags(regs->sp),
 +                          &frame->uc.uc_stack.ss_flags);
 +              put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 +              put_user_ex(0, &frame->uc.uc__pad0);
 +
 +              if (ka->sa.sa_flags & SA_RESTORER) {
 +                      restorer = ka->sa.sa_restorer;
 +              } else {
 +                      /* could use a vstub here */
 +                      restorer = NULL;
 +                      err |= -EFAULT;
 +              }
 +              put_user_ex(restorer, &frame->pretcode);
 +      } put_user_catch(err);
 +
 +      err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
 +                              regs, set->sig[0]);
 +      err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 +
 +      if (err)
 +              return -EFAULT;
 +
 +      /* Set up registers for signal handler */
 +      regs->sp = (unsigned long) frame;
 +      regs->ip = (unsigned long) ka->sa.sa_handler;
 +
 +      /* We use the x32 calling convention here... */
 +      regs->di = sig;
 +      regs->si = (unsigned long) &frame->info;
 +      regs->dx = (unsigned long) &frame->uc;
 +
 +      loadsegment(ds, __USER_DS);
 +      loadsegment(es, __USER_DS);
 +
 +      regs->cs = __USER_CS;
 +      regs->ss = __USER_DS;
 +#endif        /* CONFIG_X86_X32_ABI */
 +
 +      return 0;
 +}
 +
  #ifdef CONFIG_X86_32
  /*
   * Atomically swap in the new signal mask, and wait for a signal.
@@@ -682,22 -612,55 +682,22 @@@ static int signr_convert(int sig
        return sig;
  }
  
 -#ifdef CONFIG_X86_32
 -
 -#define is_ia32       1
 -#define ia32_setup_frame      __setup_frame
 -#define ia32_setup_rt_frame   __setup_rt_frame
 -
 -#else /* !CONFIG_X86_32 */
 -
 -#ifdef CONFIG_IA32_EMULATION
 -#define is_ia32       test_thread_flag(TIF_IA32)
 -#else /* !CONFIG_IA32_EMULATION */
 -#define is_ia32       0
 -#endif /* CONFIG_IA32_EMULATION */
 -
 -#ifdef CONFIG_X86_X32_ABI
 -#define is_x32        test_thread_flag(TIF_X32)
 -
 -static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
 -                            siginfo_t *info, compat_sigset_t *set,
 -                            struct pt_regs *regs);
 -#else /* !CONFIG_X86_X32_ABI */
 -#define is_x32        0
 -#endif /* CONFIG_X86_X32_ABI */
 -
 -int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 -              sigset_t *set, struct pt_regs *regs);
 -int ia32_setup_frame(int sig, struct k_sigaction *ka,
 -              sigset_t *set, struct pt_regs *regs);
 -
 -#endif /* CONFIG_X86_32 */
 -
  static int
  setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                struct pt_regs *regs)
  {
        int usig = signr_convert(sig);
        sigset_t *set = sigmask_to_save();
 +      compat_sigset_t *cset = (compat_sigset_t *) set;
  
        /* Set up the stack frame */
 -      if (is_ia32) {
 +      if (is_ia32_frame()) {
                if (ka->sa.sa_flags & SA_SIGINFO)
 -                      return ia32_setup_rt_frame(usig, ka, info, set, regs);
 +                      return ia32_setup_rt_frame(usig, ka, info, cset, regs);
                else
 -                      return ia32_setup_frame(usig, ka, set, regs);
 -#ifdef CONFIG_X86_X32_ABI
 -      } else if (is_x32) {
 -              return x32_setup_rt_frame(usig, ka, info,
 -                                       (compat_sigset_t *)set, regs);
 -#endif
 +                      return ia32_setup_frame(usig, ka, cset, regs);
 +      } else if (is_x32_frame()) {
 +              return x32_setup_rt_frame(usig, ka, info, cset, regs);
        } else {
                return __setup_rt_frame(sig, ka, info, set, regs);
        }
@@@ -816,8 -779,6 +816,8 @@@ static void do_signal(struct pt_regs *r
  void
  do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
  {
 +      rcu_user_exit();
 +
  #ifdef CONFIG_X86_MCE
        /* notify userspace of pending MCEs */
        if (thread_info_flags & _TIF_MCE_NOTIFY)
        }
        if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
                fire_user_return_notifiers();
- #ifdef CONFIG_X86_32
-       clear_thread_flag(TIF_IRET);
- #endif /* CONFIG_X86_32 */
 +
 +      rcu_user_enter();
  }
  
  void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
  }
  
  #ifdef CONFIG_X86_X32_ABI
 -static int x32_setup_rt_frame(int sig, struct k_sigaction *ka,
 -                            siginfo_t *info, compat_sigset_t *set,
 -                            struct pt_regs *regs)
 -{
 -      struct rt_sigframe_x32 __user *frame;
 -      void __user *restorer;
 -      int err = 0;
 -      void __user *fpstate = NULL;
 -
 -      frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 -
 -      if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 -              return -EFAULT;
 -
 -      if (ka->sa.sa_flags & SA_SIGINFO) {
 -              if (copy_siginfo_to_user32(&frame->info, info))
 -                      return -EFAULT;
 -      }
 -
 -      put_user_try {
 -              /* Create the ucontext.  */
 -              if (cpu_has_xsave)
 -                      put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
 -              else
 -                      put_user_ex(0, &frame->uc.uc_flags);
 -              put_user_ex(0, &frame->uc.uc_link);
 -              put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 -              put_user_ex(sas_ss_flags(regs->sp),
 -                          &frame->uc.uc_stack.ss_flags);
 -              put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 -              put_user_ex(0, &frame->uc.uc__pad0);
 -              err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
 -                                      regs, set->sig[0]);
 -              err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 -
 -              if (ka->sa.sa_flags & SA_RESTORER) {
 -                      restorer = ka->sa.sa_restorer;
 -              } else {
 -                      /* could use a vstub here */
 -                      restorer = NULL;
 -                      err |= -EFAULT;
 -              }
 -              put_user_ex(restorer, &frame->pretcode);
 -      } put_user_catch(err);
 -
 -      if (err)
 -              return -EFAULT;
 -
 -      /* Set up registers for signal handler */
 -      regs->sp = (unsigned long) frame;
 -      regs->ip = (unsigned long) ka->sa.sa_handler;
 -
 -      /* We use the x32 calling convention here... */
 -      regs->di = sig;
 -      regs->si = (unsigned long) &frame->info;
 -      regs->dx = (unsigned long) &frame->uc;
 -
 -      loadsegment(ds, __USER_DS);
 -      loadsegment(es, __USER_DS);
 -
 -      regs->cs = __USER_CS;
 -      regs->ss = __USER_DS;
 -
 -      return 0;
 -}
 -
  asmlinkage long sys32_x32_rt_sigreturn(struct pt_regs *regs)
  {
        struct rt_sigframe_x32 __user *frame;
diff --combined arch/x86/um/Kconfig
index aeaff8bef2f162642ef4ad31603a301384f4b1fe,da85b6fc8e8e085104a9f6f14228af4bde23b529..30c4eec033afa7e0a3cab735ac93e9281384af78
@@@ -13,6 -13,7 +13,7 @@@ endmen
  config UML_X86
        def_bool y
        select GENERIC_FIND_FIRST_BIT
+       select GENERIC_KERNEL_THREAD
  
  config 64BIT
        bool "64-bit kernel" if SUBARCH = "x86"
@@@ -21,7 -22,6 +22,7 @@@
  config X86_32
        def_bool !64BIT
        select HAVE_AOUT
 +      select ARCH_WANT_IPC_PARSE_VERSION
  
  config X86_64
        def_bool 64BIT
index 0d20f5526dd8e99b7ba770d677bc17480f4bdb40,708340339b057e16c4accba616fd5d37ffa53838..fccd81eddff1f6de89b07cc13c362809364c9507
@@@ -1,3 -1,3 +1,4 @@@
  include include/asm-generic/Kbuild.asm
  
 +generic-y += clkdev.h
+ generic-y += exec.h
diff --combined fs/binfmt_elf.c
index e800dec958c3273ea91aea2a865daa49d9874224,2ab91905b2e2ca848c1ebc02caa313b5602065cf..fbd9f60bd763310c452a08dbb34fc8bbf2515560
@@@ -27,7 -27,6 +27,7 @@@
  #include <linux/compiler.h>
  #include <linux/highmem.h>
  #include <linux/pagemap.h>
 +#include <linux/vmalloc.h>
  #include <linux/security.h>
  #include <linux/random.h>
  #include <linux/elf.h>
  #include <asm/uaccess.h>
  #include <asm/param.h>
  #include <asm/page.h>
- #include <asm/exec.h>
  
 +#ifndef user_long_t
 +#define user_long_t long
 +#endif
 +#ifndef user_siginfo_t
 +#define user_siginfo_t siginfo_t
 +#endif
 +
  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
  static int load_elf_library(struct file *);
  static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
@@@ -889,7 -880,7 +888,7 @@@ static int load_elf_binary(struct linux
        }
  
        if (elf_interpreter) {
 -              unsigned long uninitialized_var(interp_map_addr);
 +              unsigned long interp_map_addr = 0;
  
                elf_entry = load_elf_interp(&loc->interp_elf_ex,
                                            interpreter,
@@@ -1123,7 -1114,7 +1122,7 @@@ static unsigned long vma_dump_size(stru
        if (always_dump_vma(vma))
                goto whole;
  
 -      if (vma->vm_flags & VM_NODUMP)
 +      if (vma->vm_flags & VM_DONTDUMP)
                return 0;
  
        /* Hugetlb memory check */
        }
  
        /* Do not dump I/O mapped devices or special mappings */
 -      if (vma->vm_flags & (VM_IO | VM_RESERVED))
 +      if (vma->vm_flags & VM_IO)
                return 0;
  
        /* By default, dump shared memory if mapped from an anonymous file. */
@@@ -1380,103 -1371,6 +1379,103 @@@ static void fill_auxv_note(struct memel
        fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
  }
  
 +static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
 +              siginfo_t *siginfo)
 +{
 +      mm_segment_t old_fs = get_fs();
 +      set_fs(KERNEL_DS);
 +      copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo);
 +      set_fs(old_fs);
 +      fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
 +}
 +
 +#define MAX_FILE_NOTE_SIZE (4*1024*1024)
 +/*
 + * Format of NT_FILE note:
 + *
 + * long count     -- how many files are mapped
 + * long page_size -- units for file_ofs
 + * array of [COUNT] elements of
 + *   long start
 + *   long end
 + *   long file_ofs
 + * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL...
 + */
 +static void fill_files_note(struct memelfnote *note)
 +{
 +      struct vm_area_struct *vma;
 +      unsigned count, size, names_ofs, remaining, n;
 +      user_long_t *data;
 +      user_long_t *start_end_ofs;
 +      char *name_base, *name_curpos;
 +
 +      /* *Estimated* file count and total data size needed */
 +      count = current->mm->map_count;
 +      size = count * 64;
 +
 +      names_ofs = (2 + 3 * count) * sizeof(data[0]);
 + alloc:
 +      if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */
 +              goto err;
 +      size = round_up(size, PAGE_SIZE);
 +      data = vmalloc(size);
 +      if (!data)
 +              goto err;
 +
 +      start_end_ofs = data + 2;
 +      name_base = name_curpos = ((char *)data) + names_ofs;
 +      remaining = size - names_ofs;
 +      count = 0;
 +      for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
 +              struct file *file;
 +              const char *filename;
 +
 +              file = vma->vm_file;
 +              if (!file)
 +                      continue;
 +              filename = d_path(&file->f_path, name_curpos, remaining);
 +              if (IS_ERR(filename)) {
 +                      if (PTR_ERR(filename) == -ENAMETOOLONG) {
 +                              vfree(data);
 +                              size = size * 5 / 4;
 +                              goto alloc;
 +                      }
 +                      continue;
 +              }
 +
 +              /* d_path() fills at the end, move name down */
 +              /* n = strlen(filename) + 1: */
 +              n = (name_curpos + remaining) - filename;
 +              remaining = filename - name_curpos;
 +              memmove(name_curpos, filename, n);
 +              name_curpos += n;
 +
 +              *start_end_ofs++ = vma->vm_start;
 +              *start_end_ofs++ = vma->vm_end;
 +              *start_end_ofs++ = vma->vm_pgoff;
 +              count++;
 +      }
 +
 +      /* Now we know exact count of files, can store it */
 +      data[0] = count;
 +      data[1] = PAGE_SIZE;
 +      /*
 +       * Count usually is less than current->mm->map_count,
 +       * we need to move filenames down.
 +       */
 +      n = current->mm->map_count - count;
 +      if (n != 0) {
 +              unsigned shift_bytes = n * 3 * sizeof(data[0]);
 +              memmove(name_base - shift_bytes, name_base,
 +                      name_curpos - name_base);
 +              name_curpos -= shift_bytes;
 +      }
 +
 +      size = name_curpos - (char *)data;
 +      fill_note(note, "CORE", NT_FILE, size, data);
 + err: ;
 +}
 +
  #ifdef CORE_DUMP_USE_REGSET
  #include <linux/regset.h>
  
@@@ -1490,10 -1384,7 +1489,10 @@@ struct elf_thread_core_info 
  struct elf_note_info {
        struct elf_thread_core_info *thread;
        struct memelfnote psinfo;
 +      struct memelfnote signote;
        struct memelfnote auxv;
 +      struct memelfnote files;
 +      user_siginfo_t csigdata;
        size_t size;
        int thread_notes;
  };
@@@ -1588,7 -1479,7 +1587,7 @@@ static int fill_thread_core_info(struc
  
  static int fill_note_info(struct elfhdr *elf, int phdrs,
                          struct elf_note_info *info,
 -                        long signr, struct pt_regs *regs)
 +                        siginfo_t *siginfo, struct pt_regs *regs)
  {
        struct task_struct *dump_task = current;
        const struct user_regset_view *view = task_user_regset_view(dump_task);
         * Now fill in each thread's information.
         */
        for (t = info->thread; t != NULL; t = t->next)
 -              if (!fill_thread_core_info(t, view, signr, &info->size))
 +              if (!fill_thread_core_info(t, view, siginfo->si_signo, &info->size))
                        return 0;
  
        /*
        fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm);
        info->size += notesize(&info->psinfo);
  
 +      fill_siginfo_note(&info->signote, &info->csigdata, siginfo);
 +      info->size += notesize(&info->signote);
 +
        fill_auxv_note(&info->auxv, current->mm);
        info->size += notesize(&info->auxv);
  
 +      fill_files_note(&info->files);
 +      info->size += notesize(&info->files);
 +
        return 1;
  }
  
@@@ -1702,12 -1587,8 +1701,12 @@@ static int write_note_info(struct elf_n
  
                if (first && !writenote(&info->psinfo, file, foffset))
                        return 0;
 +              if (first && !writenote(&info->signote, file, foffset))
 +                      return 0;
                if (first && !writenote(&info->auxv, file, foffset))
                        return 0;
 +              if (first && !writenote(&info->files, file, foffset))
 +                      return 0;
  
                for (i = 1; i < info->thread_notes; ++i)
                        if (t->notes[i].data &&
@@@ -1734,7 -1615,6 +1733,7 @@@ static void free_note_info(struct elf_n
                kfree(t);
        }
        kfree(info->psinfo.data);
 +      vfree(info->files.data);
  }
  
  #else
@@@ -1800,7 -1680,6 +1799,7 @@@ struct elf_note_info 
  #ifdef ELF_CORE_COPY_XFPREGS
        elf_fpxregset_t *xfpu;
  #endif
 +      user_siginfo_t csigdata;
        int thread_status_size;
        int numnote;
  };
@@@ -1810,37 -1689,48 +1809,37 @@@ static int elf_note_info_init(struct el
        memset(info, 0, sizeof(*info));
        INIT_LIST_HEAD(&info->thread_list);
  
 -      /* Allocate space for six ELF notes */
 -      info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL);
 +      /* Allocate space for ELF notes */
 +      info->notes = kmalloc(8 * sizeof(struct memelfnote), GFP_KERNEL);
        if (!info->notes)
                return 0;
        info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
        if (!info->psinfo)
 -              goto notes_free;
 +              return 0;
        info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL);
        if (!info->prstatus)
 -              goto psinfo_free;
 +              return 0;
        info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL);
        if (!info->fpu)
 -              goto prstatus_free;
 +              return 0;
  #ifdef ELF_CORE_COPY_XFPREGS
        info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL);
        if (!info->xfpu)
 -              goto fpu_free;
 +              return 0;
  #endif
        return 1;
 -#ifdef ELF_CORE_COPY_XFPREGS
 - fpu_free:
 -      kfree(info->fpu);
 -#endif
 - prstatus_free:
 -      kfree(info->prstatus);
 - psinfo_free:
 -      kfree(info->psinfo);
 - notes_free:
 -      kfree(info->notes);
 -      return 0;
  }
  
  static int fill_note_info(struct elfhdr *elf, int phdrs,
                          struct elf_note_info *info,
 -                        long signr, struct pt_regs *regs)
 +                        siginfo_t *siginfo, struct pt_regs *regs)
  {
        struct list_head *t;
  
        if (!elf_note_info_init(info))
                return 0;
  
 -      if (signr) {
 +      if (siginfo->si_signo) {
                struct core_thread *ct;
                struct elf_thread_status *ets;
  
                        int sz;
  
                        ets = list_entry(t, struct elf_thread_status, list);
 -                      sz = elf_dump_thread_status(signr, ets);
 +                      sz = elf_dump_thread_status(siginfo->si_signo, ets);
                        info->thread_status_size += sz;
                }
        }
        /* now collect the dump for the current */
        memset(info->prstatus, 0, sizeof(*info->prstatus));
 -      fill_prstatus(info->prstatus, current, signr);
 +      fill_prstatus(info->prstatus, current, siginfo->si_signo);
        elf_core_copy_regs(&info->prstatus->pr_reg, regs);
  
        /* Set up header */
        fill_note(info->notes + 1, "CORE", NT_PRPSINFO,
                  sizeof(*info->psinfo), info->psinfo);
  
 -      info->numnote = 2;
 +      fill_siginfo_note(info->notes + 2, &info->csigdata, siginfo);
 +      fill_auxv_note(info->notes + 3, current->mm);
 +      fill_files_note(info->notes + 4);
  
 -      fill_auxv_note(&info->notes[info->numnote++], current->mm);
 +      info->numnote = 5;
  
        /* Try to dump the FPU. */
        info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs,
@@@ -1947,9 -1835,6 +1946,9 @@@ static void free_note_info(struct elf_n
                kfree(list_entry(tmp, struct elf_thread_status, list));
        }
  
 +      /* Free data allocated by fill_files_note(): */
 +      vfree(info->notes[4].data);
 +
        kfree(info->prstatus);
        kfree(info->psinfo);
        kfree(info->notes);
@@@ -2076,7 -1961,7 +2075,7 @@@ static int elf_core_dump(struct coredum
         * Collect all the non-memory information about the process for the
         * notes.  This also sets up the file header.
         */
 -      if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
 +      if (!fill_note_info(elf, e_phnum, &info, cprm->siginfo, cprm->regs))
                goto cleanup;
  
        has_dumped = 1;
diff --combined fs/binfmt_elf_fdpic.c
index 262db114ff0162dd24761c842af617a017e992ea,c298f2efc1bfcad428fbc0cd39b55831215276c6..a46049154107f549eaf3c987cab594db730116f4
@@@ -39,7 -39,6 +39,6 @@@
  #include <asm/uaccess.h>
  #include <asm/param.h>
  #include <asm/pgalloc.h>
- #include <asm/exec.h>
  
  typedef char *elf_caddr_t;
  
@@@ -1205,7 -1204,7 +1204,7 @@@ static int maydump(struct vm_area_struc
        int dump_ok;
  
        /* Do not dump I/O mapped devices or special mappings */
 -      if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
 +      if (vma->vm_flags & VM_IO) {
                kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
                return 0;
        }
@@@ -1642,7 -1641,7 +1641,7 @@@ static int elf_fdpic_core_dump(struct c
                goto cleanup;
  #endif
  
 -      if (cprm->signr) {
 +      if (cprm->siginfo->si_signo) {
                struct core_thread *ct;
                struct elf_thread_status *tmp;
  
                        int sz;
  
                        tmp = list_entry(t, struct elf_thread_status, list);
 -                      sz = elf_dump_thread_status(cprm->signr, tmp);
 +                      sz = elf_dump_thread_status(cprm->siginfo->si_signo, tmp);
                        thread_status_size += sz;
                }
        }
  
        /* now collect the dump for the current */
 -      fill_prstatus(prstatus, current, cprm->signr);
 +      fill_prstatus(prstatus, current, cprm->siginfo->si_signo);
        elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
  
        segs = current->mm->map_count;
diff --combined fs/exec.c
index 4f2bebc276c52f3ca60b75fbff9eeea8ea21bbe5,50a1270da95b4b08f91ddfa58d27ea4e13051cca..ca434534ae9abd43ee320e308b22199fb2d53849
+++ b/fs/exec.c
  #include <asm/uaccess.h>
  #include <asm/mmu_context.h>
  #include <asm/tlb.h>
- #include <asm/exec.h>
  
  #include <trace/events/task.h>
  #include "internal.h"
 +#include "coredump.h"
  
  #include <trace/events/sched.h>
  
 -int core_uses_pid;
 -char core_pattern[CORENAME_MAX_SIZE] = "core";
 -unsigned int core_pipe_limit;
  int suid_dumpable = 0;
  
 -struct core_name {
 -      char *corename;
 -      int used, size;
 -};
 -static atomic_t call_count = ATOMIC_INIT(1);
 -
 -/* The maximal length of core_pattern is also specified in sysctl.c */
 -
  static LIST_HEAD(formats);
  static DEFINE_RWLOCK(binfmt_lock);
  
@@@ -392,7 -401,7 +391,7 @@@ struct user_arg_ptr 
        union {
                const char __user *const __user *native;
  #ifdef CONFIG_COMPAT
-               compat_uptr_t __user *compat;
+               const compat_uptr_t __user *compat;
  #endif
        } ptr;
  };
@@@ -603,7 -612,7 +602,7 @@@ static int shift_arg_pages(struct vm_ar
         * process cleanup to remove whatever mess we made.
         */
        if (length != move_page_tables(vma, old_start,
 -                                     vma, new_start, length))
 +                                     vma, new_start, length, false))
                return -ENOMEM;
  
        lru_add_drain();
@@@ -878,11 -887,9 +877,11 @@@ static int de_thread(struct task_struc
                sig->notify_count--;
  
        while (sig->notify_count) {
 -              __set_current_state(TASK_UNINTERRUPTIBLE);
 +              __set_current_state(TASK_KILLABLE);
                spin_unlock_irq(lock);
                schedule();
 +              if (unlikely(__fatal_signal_pending(tsk)))
 +                      goto killed;
                spin_lock_irq(lock);
        }
        spin_unlock_irq(lock);
                        write_lock_irq(&tasklist_lock);
                        if (likely(leader->exit_state))
                                break;
 -                      __set_current_state(TASK_UNINTERRUPTIBLE);
 +                      __set_current_state(TASK_KILLABLE);
                        write_unlock_irq(&tasklist_lock);
                        schedule();
 +                      if (unlikely(__fatal_signal_pending(tsk)))
 +                              goto killed;
                }
  
                /*
@@@ -998,14 -1003,40 +997,14 @@@ no_thread_group
  
        BUG_ON(!thread_group_leader(tsk));
        return 0;
 -}
 -
 -/*
 - * These functions flushes out all traces of the currently running executable
 - * so that a new one can be started
 - */
 -static void flush_old_files(struct files_struct * files)
 -{
 -      long j = -1;
 -      struct fdtable *fdt;
 -
 -      spin_lock(&files->file_lock);
 -      for (;;) {
 -              unsigned long set, i;
  
 -              j++;
 -              i = j * BITS_PER_LONG;
 -              fdt = files_fdtable(files);
 -              if (i >= fdt->max_fds)
 -                      break;
 -              set = fdt->close_on_exec[j];
 -              if (!set)
 -                      continue;
 -              fdt->close_on_exec[j] = 0;
 -              spin_unlock(&files->file_lock);
 -              for ( ; set ; i++,set >>= 1) {
 -                      if (set & 1) {
 -                              sys_close(i);
 -                      }
 -              }
 -              spin_lock(&files->file_lock);
 -
 -      }
 -      spin_unlock(&files->file_lock);
 +killed:
 +      /* protects against exit_notify() and __exit_signal() */
 +      read_lock(&tasklist_lock);
 +      sig->group_exit_task = NULL;
 +      sig->notify_count = 0;
 +      read_unlock(&tasklist_lock);
 +      return -EAGAIN;
  }
  
  char *get_task_comm(char *buf, struct task_struct *tsk)
  }
  EXPORT_SYMBOL_GPL(get_task_comm);
  
 +/*
 + * These functions flushes out all traces of the currently running executable
 + * so that a new one can be started
 + */
 +
  void set_task_comm(struct task_struct *tsk, char *buf)
  {
        task_lock(tsk);
@@@ -1109,7 -1135,7 +1108,7 @@@ void setup_new_exec(struct linux_binpr
        current->sas_ss_sp = current->sas_ss_size = 0;
  
        if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid()))
 -              set_dumpable(current->mm, 1);
 +              set_dumpable(current->mm, SUID_DUMPABLE_ENABLED);
        else
                set_dumpable(current->mm, suid_dumpable);
  
        current->self_exec_id++;
                        
        flush_signal_handlers(current, 0);
 -      flush_old_files(current->files);
 +      do_close_on_exec(current->files);
  }
  EXPORT_SYMBOL(setup_new_exec);
  
@@@ -1574,9 -1600,9 +1573,9 @@@ int do_execve(const char *filename
  }
  
  #ifdef CONFIG_COMPAT
- int compat_do_execve(char *filename,
-       compat_uptr_t __user *__argv,
-       compat_uptr_t __user *__envp,
+ int compat_do_execve(const char *filename,
+       const compat_uptr_t __user *__argv,
+       const compat_uptr_t __user *__envp,
        struct pt_regs *regs)
  {
        struct user_arg_ptr argv = {
@@@ -1605,6 -1631,353 +1604,6 @@@ void set_binfmt(struct linux_binfmt *ne
  
  EXPORT_SYMBOL(set_binfmt);
  
 -static int expand_corename(struct core_name *cn)
 -{
 -      char *old_corename = cn->corename;
 -
 -      cn->size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count);
 -      cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL);
 -
 -      if (!cn->corename) {
 -              kfree(old_corename);
 -              return -ENOMEM;
 -      }
 -
 -      return 0;
 -}
 -
 -static int cn_printf(struct core_name *cn, const char *fmt, ...)
 -{
 -      char *cur;
 -      int need;
 -      int ret;
 -      va_list arg;
 -
 -      va_start(arg, fmt);
 -      need = vsnprintf(NULL, 0, fmt, arg);
 -      va_end(arg);
 -
 -      if (likely(need < cn->size - cn->used - 1))
 -              goto out_printf;
 -
 -      ret = expand_corename(cn);
 -      if (ret)
 -              goto expand_fail;
 -
 -out_printf:
 -      cur = cn->corename + cn->used;
 -      va_start(arg, fmt);
 -      vsnprintf(cur, need + 1, fmt, arg);
 -      va_end(arg);
 -      cn->used += need;
 -      return 0;
 -
 -expand_fail:
 -      return ret;
 -}
 -
 -static void cn_escape(char *str)
 -{
 -      for (; *str; str++)
 -              if (*str == '/')
 -                      *str = '!';
 -}
 -
 -static int cn_print_exe_file(struct core_name *cn)
 -{
 -      struct file *exe_file;
 -      char *pathbuf, *path;
 -      int ret;
 -
 -      exe_file = get_mm_exe_file(current->mm);
 -      if (!exe_file) {
 -              char *commstart = cn->corename + cn->used;
 -              ret = cn_printf(cn, "%s (path unknown)", current->comm);
 -              cn_escape(commstart);
 -              return ret;
 -      }
 -
 -      pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
 -      if (!pathbuf) {
 -              ret = -ENOMEM;
 -              goto put_exe_file;
 -      }
 -
 -      path = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
 -      if (IS_ERR(path)) {
 -              ret = PTR_ERR(path);
 -              goto free_buf;
 -      }
 -
 -      cn_escape(path);
 -
 -      ret = cn_printf(cn, "%s", path);
 -
 -free_buf:
 -      kfree(pathbuf);
 -put_exe_file:
 -      fput(exe_file);
 -      return ret;
 -}
 -
 -/* format_corename will inspect the pattern parameter, and output a
 - * name into corename, which must have space for at least
 - * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
 - */
 -static int format_corename(struct core_name *cn, long signr)
 -{
 -      const struct cred *cred = current_cred();
 -      const char *pat_ptr = core_pattern;
 -      int ispipe = (*pat_ptr == '|');
 -      int pid_in_pattern = 0;
 -      int err = 0;
 -
 -      cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count);
 -      cn->corename = kmalloc(cn->size, GFP_KERNEL);
 -      cn->used = 0;
 -
 -      if (!cn->corename)
 -              return -ENOMEM;
 -
 -      /* Repeat as long as we have more pattern to process and more output
 -         space */
 -      while (*pat_ptr) {
 -              if (*pat_ptr != '%') {
 -                      if (*pat_ptr == 0)
 -                              goto out;
 -                      err = cn_printf(cn, "%c", *pat_ptr++);
 -              } else {
 -                      switch (*++pat_ptr) {
 -                      /* single % at the end, drop that */
 -                      case 0:
 -                              goto out;
 -                      /* Double percent, output one percent */
 -                      case '%':
 -                              err = cn_printf(cn, "%c", '%');
 -                              break;
 -                      /* pid */
 -                      case 'p':
 -                              pid_in_pattern = 1;
 -                              err = cn_printf(cn, "%d",
 -                                            task_tgid_vnr(current));
 -                              break;
 -                      /* uid */
 -                      case 'u':
 -                              err = cn_printf(cn, "%d", cred->uid);
 -                              break;
 -                      /* gid */
 -                      case 'g':
 -                              err = cn_printf(cn, "%d", cred->gid);
 -                              break;
 -                      /* signal that caused the coredump */
 -                      case 's':
 -                              err = cn_printf(cn, "%ld", signr);
 -                              break;
 -                      /* UNIX time of coredump */
 -                      case 't': {
 -                              struct timeval tv;
 -                              do_gettimeofday(&tv);
 -                              err = cn_printf(cn, "%lu", tv.tv_sec);
 -                              break;
 -                      }
 -                      /* hostname */
 -                      case 'h': {
 -                              char *namestart = cn->corename + cn->used;
 -                              down_read(&uts_sem);
 -                              err = cn_printf(cn, "%s",
 -                                            utsname()->nodename);
 -                              up_read(&uts_sem);
 -                              cn_escape(namestart);
 -                              break;
 -                      }
 -                      /* executable */
 -                      case 'e': {
 -                              char *commstart = cn->corename + cn->used;
 -                              err = cn_printf(cn, "%s", current->comm);
 -                              cn_escape(commstart);
 -                              break;
 -                      }
 -                      case 'E':
 -                              err = cn_print_exe_file(cn);
 -                              break;
 -                      /* core limit size */
 -                      case 'c':
 -                              err = cn_printf(cn, "%lu",
 -                                            rlimit(RLIMIT_CORE));
 -                              break;
 -                      default:
 -                              break;
 -                      }
 -                      ++pat_ptr;
 -              }
 -
 -              if (err)
 -                      return err;
 -      }
 -
 -      /* Backward compatibility with core_uses_pid:
 -       *
 -       * If core_pattern does not include a %p (as is the default)
 -       * and core_uses_pid is set, then .%pid will be appended to
 -       * the filename. Do not do this for piped commands. */
 -      if (!ispipe && !pid_in_pattern && core_uses_pid) {
 -              err = cn_printf(cn, ".%d", task_tgid_vnr(current));
 -              if (err)
 -                      return err;
 -      }
 -out:
 -      return ispipe;
 -}
 -
 -static int zap_process(struct task_struct *start, int exit_code)
 -{
 -      struct task_struct *t;
 -      int nr = 0;
 -
 -      start->signal->flags = SIGNAL_GROUP_EXIT;
 -      start->signal->group_exit_code = exit_code;
 -      start->signal->group_stop_count = 0;
 -
 -      t = start;
 -      do {
 -              task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
 -              if (t != current && t->mm) {
 -                      sigaddset(&t->pending.signal, SIGKILL);
 -                      signal_wake_up(t, 1);
 -                      nr++;
 -              }
 -      } while_each_thread(start, t);
 -
 -      return nr;
 -}
 -
 -static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
 -                              struct core_state *core_state, int exit_code)
 -{
 -      struct task_struct *g, *p;
 -      unsigned long flags;
 -      int nr = -EAGAIN;
 -
 -      spin_lock_irq(&tsk->sighand->siglock);
 -      if (!signal_group_exit(tsk->signal)) {
 -              mm->core_state = core_state;
 -              nr = zap_process(tsk, exit_code);
 -      }
 -      spin_unlock_irq(&tsk->sighand->siglock);
 -      if (unlikely(nr < 0))
 -              return nr;
 -
 -      if (atomic_read(&mm->mm_users) == nr + 1)
 -              goto done;
 -      /*
 -       * We should find and kill all tasks which use this mm, and we should
 -       * count them correctly into ->nr_threads. We don't take tasklist
 -       * lock, but this is safe wrt:
 -       *
 -       * fork:
 -       *      None of sub-threads can fork after zap_process(leader). All
 -       *      processes which were created before this point should be
 -       *      visible to zap_threads() because copy_process() adds the new
 -       *      process to the tail of init_task.tasks list, and lock/unlock
 -       *      of ->siglock provides a memory barrier.
 -       *
 -       * do_exit:
 -       *      The caller holds mm->mmap_sem. This means that the task which
 -       *      uses this mm can't pass exit_mm(), so it can't exit or clear
 -       *      its ->mm.
 -       *
 -       * de_thread:
 -       *      It does list_replace_rcu(&leader->tasks, &current->tasks),
 -       *      we must see either old or new leader, this does not matter.
 -       *      However, it can change p->sighand, so lock_task_sighand(p)
 -       *      must be used. Since p->mm != NULL and we hold ->mmap_sem
 -       *      it can't fail.
 -       *
 -       *      Note also that "g" can be the old leader with ->mm == NULL
 -       *      and already unhashed and thus removed from ->thread_group.
 -       *      This is OK, __unhash_process()->list_del_rcu() does not
 -       *      clear the ->next pointer, we will find the new leader via
 -       *      next_thread().
 -       */
 -      rcu_read_lock();
 -      for_each_process(g) {
 -              if (g == tsk->group_leader)
 -                      continue;
 -              if (g->flags & PF_KTHREAD)
 -                      continue;
 -              p = g;
 -              do {
 -                      if (p->mm) {
 -                              if (unlikely(p->mm == mm)) {
 -                                      lock_task_sighand(p, &flags);
 -                                      nr += zap_process(p, exit_code);
 -                                      unlock_task_sighand(p, &flags);
 -                              }
 -                              break;
 -                      }
 -              } while_each_thread(g, p);
 -      }
 -      rcu_read_unlock();
 -done:
 -      atomic_set(&core_state->nr_threads, nr);
 -      return nr;
 -}
 -
 -static int coredump_wait(int exit_code, struct core_state *core_state)
 -{
 -      struct task_struct *tsk = current;
 -      struct mm_struct *mm = tsk->mm;
 -      int core_waiters = -EBUSY;
 -
 -      init_completion(&core_state->startup);
 -      core_state->dumper.task = tsk;
 -      core_state->dumper.next = NULL;
 -
 -      down_write(&mm->mmap_sem);
 -      if (!mm->core_state)
 -              core_waiters = zap_threads(tsk, mm, core_state, exit_code);
 -      up_write(&mm->mmap_sem);
 -
 -      if (core_waiters > 0) {
 -              struct core_thread *ptr;
 -
 -              wait_for_completion(&core_state->startup);
 -              /*
 -               * Wait for all the threads to become inactive, so that
 -               * all the thread context (extended register state, like
 -               * fpu etc) gets copied to the memory.
 -               */
 -              ptr = core_state->dumper.next;
 -              while (ptr != NULL) {
 -                      wait_task_inactive(ptr->task, 0);
 -                      ptr = ptr->next;
 -              }
 -      }
 -
 -      return core_waiters;
 -}
 -
 -static void coredump_finish(struct mm_struct *mm)
 -{
 -      struct core_thread *curr, *next;
 -      struct task_struct *task;
 -
 -      next = mm->core_state->dumper.next;
 -      while ((curr = next) != NULL) {
 -              next = curr->next;
 -              task = curr->task;
 -              /*
 -               * see exit_mm(), curr->task must not see
 -               * ->task == NULL before we read ->next.
 -               */
 -              smp_mb();
 -              curr->task = NULL;
 -              wake_up_process(task);
 -      }
 -
 -      mm->core_state = NULL;
 -}
 -
  /*
   * set_dumpable converts traditional three-value dumpable to two flags and
   * stores them into mm->flags.  It modifies lower two bits of mm->flags, but
@@@ -1646,7 -2019,7 +1645,7 @@@ void set_dumpable(struct mm_struct *mm
        }
  }
  
 -static int __get_dumpable(unsigned long mm_flags)
 +int __get_dumpable(unsigned long mm_flags)
  {
        int ret;
  
@@@ -1658,3 -2031,342 +1657,55 @@@ int get_dumpable(struct mm_struct *mm
  {
        return __get_dumpable(mm->flags);
  }
 -static void wait_for_dump_helpers(struct file *file)
 -{
 -      struct pipe_inode_info *pipe;
 -
 -      pipe = file->f_path.dentry->d_inode->i_pipe;
 -
 -      pipe_lock(pipe);
 -      pipe->readers++;
 -      pipe->writers--;
 -
 -      while ((pipe->readers > 1) && (!signal_pending(current))) {
 -              wake_up_interruptible_sync(&pipe->wait);
 -              kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 -              pipe_wait(pipe);
 -      }
 -
 -      pipe->readers--;
 -      pipe->writers++;
 -      pipe_unlock(pipe);
 -
 -}
 -
 -
 -/*
 - * umh_pipe_setup
 - * helper function to customize the process used
 - * to collect the core in userspace.  Specifically
 - * it sets up a pipe and installs it as fd 0 (stdin)
 - * for the process.  Returns 0 on success, or
 - * PTR_ERR on failure.
 - * Note that it also sets the core limit to 1.  This
 - * is a special value that we use to trap recursive
 - * core dumps
 - */
 -static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
 -{
 -      struct file *files[2];
 -      struct fdtable *fdt;
 -      struct coredump_params *cp = (struct coredump_params *)info->data;
 -      struct files_struct *cf = current->files;
 -      int err = create_pipe_files(files, 0);
 -      if (err)
 -              return err;
 -
 -      cp->file = files[1];
 -
 -      sys_close(0);
 -      fd_install(0, files[0]);
 -      spin_lock(&cf->file_lock);
 -      fdt = files_fdtable(cf);
 -      __set_open_fd(0, fdt);
 -      __clear_close_on_exec(0, fdt);
 -      spin_unlock(&cf->file_lock);
 -
 -      /* and disallow core files too */
 -      current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
 -
 -      return 0;
 -}
 -
 -void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 -{
 -      struct core_state core_state;
 -      struct core_name cn;
 -      struct mm_struct *mm = current->mm;
 -      struct linux_binfmt * binfmt;
 -      const struct cred *old_cred;
 -      struct cred *cred;
 -      int retval = 0;
 -      int flag = 0;
 -      int ispipe;
 -      bool need_nonrelative = false;
 -      static atomic_t core_dump_count = ATOMIC_INIT(0);
 -      struct coredump_params cprm = {
 -              .signr = signr,
 -              .regs = regs,
 -              .limit = rlimit(RLIMIT_CORE),
 -              /*
 -               * We must use the same mm->flags while dumping core to avoid
 -               * inconsistency of bit flags, since this flag is not protected
 -               * by any locks.
 -               */
 -              .mm_flags = mm->flags,
 -      };
 -
 -      audit_core_dumps(signr);
 -
 -      binfmt = mm->binfmt;
 -      if (!binfmt || !binfmt->core_dump)
 -              goto fail;
 -      if (!__get_dumpable(cprm.mm_flags))
 -              goto fail;
 -
 -      cred = prepare_creds();
 -      if (!cred)
 -              goto fail;
 -      /*
 -       * We cannot trust fsuid as being the "true" uid of the process
 -       * nor do we know its entire history. We only know it was tainted
 -       * so we dump it as root in mode 2, and only into a controlled
 -       * environment (pipe handler or fully qualified path).
 -       */
 -      if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) {
 -              /* Setuid core dump mode */
 -              flag = O_EXCL;          /* Stop rewrite attacks */
 -              cred->fsuid = GLOBAL_ROOT_UID;  /* Dump root private */
 -              need_nonrelative = true;
 -      }
 -
 -      retval = coredump_wait(exit_code, &core_state);
 -      if (retval < 0)
 -              goto fail_creds;
 -
 -      old_cred = override_creds(cred);
 -
 -      /*
 -       * Clear any false indication of pending signals that might
 -       * be seen by the filesystem code called to write the core file.
 -       */
 -      clear_thread_flag(TIF_SIGPENDING);
 -
 -      ispipe = format_corename(&cn, signr);
 -
 -      if (ispipe) {
 -              int dump_count;
 -              char **helper_argv;
 -
 -              if (ispipe < 0) {
 -                      printk(KERN_WARNING "format_corename failed\n");
 -                      printk(KERN_WARNING "Aborting core\n");
 -                      goto fail_corename;
 -              }
 -
 -              if (cprm.limit == 1) {
 -                      /* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
 -                       *
 -                       * Normally core limits are irrelevant to pipes, since
 -                       * we're not writing to the file system, but we use
 -                       * cprm.limit of 1 here as a speacial value, this is a
 -                       * consistent way to catch recursive crashes.
 -                       * We can still crash if the core_pattern binary sets
 -                       * RLIM_CORE = !1, but it runs as root, and can do
 -                       * lots of stupid things.
 -                       *
 -                       * Note that we use task_tgid_vnr here to grab the pid
 -                       * of the process group leader.  That way we get the
 -                       * right pid if a thread in a multi-threaded
 -                       * core_pattern process dies.
 -                       */
 -                      printk(KERN_WARNING
 -                              "Process %d(%s) has RLIMIT_CORE set to 1\n",
 -                              task_tgid_vnr(current), current->comm);
 -                      printk(KERN_WARNING "Aborting core\n");
 -                      goto fail_unlock;
 -              }
 -              cprm.limit = RLIM_INFINITY;
 -
 -              dump_count = atomic_inc_return(&core_dump_count);
 -              if (core_pipe_limit && (core_pipe_limit < dump_count)) {
 -                      printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
 -                             task_tgid_vnr(current), current->comm);
 -                      printk(KERN_WARNING "Skipping core dump\n");
 -                      goto fail_dropcount;
 -              }
 -
 -              helper_argv = argv_split(GFP_KERNEL, cn.corename+1, NULL);
 -              if (!helper_argv) {
 -                      printk(KERN_WARNING "%s failed to allocate memory\n",
 -                             __func__);
 -                      goto fail_dropcount;
 -              }
 -
 -              retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
 -                                      NULL, UMH_WAIT_EXEC, umh_pipe_setup,
 -                                      NULL, &cprm);
 -              argv_free(helper_argv);
 -              if (retval) {
 -                      printk(KERN_INFO "Core dump to %s pipe failed\n",
 -                             cn.corename);
 -                      goto close_fail;
 -              }
 -      } else {
 -              struct inode *inode;
 -
 -              if (cprm.limit < binfmt->min_coredump)
 -                      goto fail_unlock;
 -
 -              if (need_nonrelative && cn.corename[0] != '/') {
 -                      printk(KERN_WARNING "Pid %d(%s) can only dump core "\
 -                              "to fully qualified path!\n",
 -                              task_tgid_vnr(current), current->comm);
 -                      printk(KERN_WARNING "Skipping core dump\n");
 -                      goto fail_unlock;
 -              }
 -
 -              cprm.file = filp_open(cn.corename,
 -                               O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
 -                               0600);
 -              if (IS_ERR(cprm.file))
 -                      goto fail_unlock;
 -
 -              inode = cprm.file->f_path.dentry->d_inode;
 -              if (inode->i_nlink > 1)
 -                      goto close_fail;
 -              if (d_unhashed(cprm.file->f_path.dentry))
 -                      goto close_fail;
 -              /*
 -               * AK: actually i see no reason to not allow this for named
 -               * pipes etc, but keep the previous behaviour for now.
 -               */
 -              if (!S_ISREG(inode->i_mode))
 -                      goto close_fail;
 -              /*
 -               * Dont allow local users get cute and trick others to coredump
 -               * into their pre-created files.
 -               */
 -              if (!uid_eq(inode->i_uid, current_fsuid()))
 -                      goto close_fail;
 -              if (!cprm.file->f_op || !cprm.file->f_op->write)
 -                      goto close_fail;
 -              if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
 -                      goto close_fail;
 -      }
 -
 -      retval = binfmt->core_dump(&cprm);
 -      if (retval)
 -              current->signal->group_exit_code |= 0x80;
 -
 -      if (ispipe && core_pipe_limit)
 -              wait_for_dump_helpers(cprm.file);
 -close_fail:
 -      if (cprm.file)
 -              filp_close(cprm.file, NULL);
 -fail_dropcount:
 -      if (ispipe)
 -              atomic_dec(&core_dump_count);
 -fail_unlock:
 -      kfree(cn.corename);
 -fail_corename:
 -      coredump_finish(mm);
 -      revert_creds(old_cred);
 -fail_creds:
 -      put_cred(cred);
 -fail:
 -      return;
 -}
 -
 -/*
 - * Core dumping helper functions.  These are the only things you should
 - * do on a core-file: use only these functions to write out all the
 - * necessary info.
 - */
 -int dump_write(struct file *file, const void *addr, int nr)
 -{
 -      return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr;
 -}
 -EXPORT_SYMBOL(dump_write);
 -
 -int dump_seek(struct file *file, loff_t off)
 -{
 -      int ret = 1;
 -
 -      if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
 -              if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
 -                      return 0;
 -      } else {
 -              char *buf = (char *)get_zeroed_page(GFP_KERNEL);
 -
 -              if (!buf)
 -                      return 0;
 -              while (off > 0) {
 -                      unsigned long n = off;
 -
 -                      if (n > PAGE_SIZE)
 -                              n = PAGE_SIZE;
 -                      if (!dump_write(file, buf, n)) {
 -                              ret = 0;
 -                              break;
 -                      }
 -                      off -= n;
 -              }
 -              free_page((unsigned long)buf);
 -      }
 -      return ret;
 -}
 -EXPORT_SYMBOL(dump_seek);
 -
+ #ifdef __ARCH_WANT_SYS_EXECVE
+ SYSCALL_DEFINE3(execve,
+               const char __user *, filename,
+               const char __user *const __user *, argv,
+               const char __user *const __user *, envp)
+ {
+       const char *path = getname(filename);
+       int error = PTR_ERR(path);
+       if (!IS_ERR(path)) {
+               error = do_execve(path, argv, envp, current_pt_regs());
+               putname(path);
+       }
+       return error;
+ }
+ #ifdef CONFIG_COMPAT
+ asmlinkage long compat_sys_execve(const char __user * filename,
+       const compat_uptr_t __user * argv,
+       const compat_uptr_t __user * envp)
+ {
+       const char *path = getname(filename);
+       int error = PTR_ERR(path);
+       if (!IS_ERR(path)) {
+               error = compat_do_execve(path, argv, envp, current_pt_regs());
+               putname(path);
+       }
+       return error;
+ }
+ #endif
+ #endif
+ #ifdef __ARCH_WANT_KERNEL_EXECVE
+ int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
+ {
+       struct pt_regs *p = current_pt_regs();
+       int ret;
+       ret = do_execve(filename,
+                       (const char __user *const __user *)argv,
+                       (const char __user *const __user *)envp, p);
+       if (ret < 0)
+               return ret;
+       /*
+        * We were successful.  We won't be returning to our caller, but
+        * instead to user space by manipulating the kernel stack.
+        */
+       ret_from_kernel_execve(p);
+ }
+ #endif
diff --combined include/linux/binfmts.h
index 37935c2d2e8f1eb1a4b071a38e3af6fd14bb1296,f9c9d08f4f7c7bfe1712b8f04f993eb776244dc8..26531f32bbb2d29793979c1c240642f9463073e5
@@@ -19,6 -19,8 +19,8 @@@ struct pt_regs
  
  #ifdef __KERNEL__
  #include <linux/sched.h>
+ #include <linux/unistd.h>
+ #include <asm/exec.h>
  
  #define CORENAME_MAX_SIZE 128
  
@@@ -72,7 -74,7 +74,7 @@@ struct linux_binprm 
  
  /* Function parameter for binfmt->coredump */
  struct coredump_params {
 -      long signr;
 +      siginfo_t *siginfo;
        struct pt_regs *regs;
        struct file *file;
        unsigned long limit;
@@@ -132,8 -134,13 +134,12 @@@ extern int copy_strings_kernel(int argc
                               struct linux_binprm *bprm);
  extern int prepare_bprm_creds(struct linux_binprm *bprm);
  extern void install_exec_creds(struct linux_binprm *bprm);
 -extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
  extern void set_binfmt(struct linux_binfmt *new);
  extern void free_bprm(struct linux_binprm *);
  
+ #ifdef __ARCH_WANT_KERNEL_EXECVE
+ extern void ret_from_kernel_execve(struct pt_regs *normal) __noreturn;
+ #endif
  #endif /* __KERNEL__ */
  #endif /* _LINUX_BINFMTS_H */
diff --combined include/linux/compat.h
index 3f53d002c7c5c88521874e2e0085f0a083f2e7d1,c4be3f55511d65b2bda2dd9021bd3725c56eecc0..d0ced1011f2fa28cf96087880d6cddda011de13f
@@@ -160,6 -160,11 +160,6 @@@ struct compat_ustat 
        char                    f_fpack[6];
  };
  
 -typedef union compat_sigval {
 -      compat_int_t    sival_int;
 -      compat_uptr_t   sival_ptr;
 -} compat_sigval_t;
 -
  #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
  
  typedef struct compat_sigevent {
@@@ -284,8 -289,12 +284,12 @@@ asmlinkage ssize_t compat_sys_pwritev(u
                const struct compat_iovec __user *vec,
                unsigned long vlen, u32 pos_low, u32 pos_high);
  
- int compat_do_execve(char *filename, compat_uptr_t __user *argv,
-                    compat_uptr_t __user *envp, struct pt_regs *regs);
+ int compat_do_execve(const char *filename, const compat_uptr_t __user *argv,
+                    const compat_uptr_t __user *envp, struct pt_regs *regs);
+ #ifdef __ARCH_WANT_SYS_EXECVE
+ asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
+                    const compat_uptr_t __user *envp);
+ #endif
  
  asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
                compat_ulong_t __user *outp, compat_ulong_t __user *exp,
@@@ -585,9 -594,6 +589,9 @@@ asmlinkage ssize_t compat_sys_process_v
                unsigned long liovcnt, const struct compat_iovec __user *rvec,
                unsigned long riovcnt, unsigned long flags);
  
 +asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
 +                                  compat_off_t __user *offset, compat_size_t count);
 +
  #else
  
  #define is_compat_task() (0)
diff --combined include/linux/ptrace.h
index 3db698aee34cd9437f8f42823f17825796597f09,07fd922d69281de5b366603e5b7b6f447c669ef8..1d24ffad59c53c27a66bf7b4cced639f0a5f000a
@@@ -130,6 -130,8 +130,6 @@@ extern void exit_ptrace(struct task_str
  #define PTRACE_MODE_READ      0x01
  #define PTRACE_MODE_ATTACH    0x02
  #define PTRACE_MODE_NOAUDIT   0x04
 -/* Returns 0 on success, -errno on denial. */
 -extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
  /* Returns true on success, false on denial. */
  extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
  
@@@ -401,6 -403,10 +401,10 @@@ static inline void user_single_step_sig
  #define arch_ptrace_stop(code, info)          do { } while (0)
  #endif
  
+ #ifndef current_pt_regs
+ #define current_pt_regs() task_pt_regs(current)
+ #endif
  extern int task_current_syscall(struct task_struct *target, long *callno,
                                unsigned long args[6], unsigned int maxargs,
                                unsigned long *sp, unsigned long *pc);
diff --combined include/linux/sched.h
index c2070e92a9d6ef0acfb962b49f68167785093add,34da9340c6a43dacb0f67404a3efeb650084c006..a83ca5816ecbc1e2f41a958c3f6830a50f8931b9
@@@ -273,11 -273,11 +273,11 @@@ extern void init_idle_bootup_task(struc
  extern int runqueue_is_locked(int cpu);
  
  #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
 -extern void select_nohz_load_balancer(int stop_tick);
 +extern void nohz_balance_enter_idle(int cpu);
  extern void set_cpu_sd_state_idle(void);
  extern int get_nohz_timer_target(void);
  #else
 -static inline void select_nohz_load_balancer(int stop_tick) { }
 +static inline void nohz_balance_enter_idle(int cpu) { }
  static inline void set_cpu_sd_state_idle(void) { }
  #endif
  
@@@ -446,9 -446,6 +446,9 @@@ extern int get_dumpable(struct mm_struc
  #define MMF_VM_HUGEPAGE               17      /* set when VM_HUGEPAGE is set on vma */
  #define MMF_EXE_FILE_CHANGED  18      /* see prctl_set_mm_exe_file() */
  
 +#define MMF_HAS_UPROBES               19      /* has uprobes */
 +#define MMF_RECALC_UPROBES    20      /* MMF_HAS_UPROBES can be wrong */
 +
  #define MMF_INIT_MASK         (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
  
  struct sighand_struct {
@@@ -671,6 -668,7 +671,6 @@@ struct signal_struct 
        struct rw_semaphore group_rwsem;
  #endif
  
 -      int oom_adj;            /* OOM kill score adjustment (bit shift) */
        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. */
                                         * (notably. ptrace) */
  };
  
 -/* Context switch must be unlocked if interrupts are to be enabled */
 -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
 -# define __ARCH_WANT_UNLOCKED_CTXSW
 -#endif
 -
  /*
   * Bits in flags field of signal_struct.
   */
@@@ -857,6 -860,7 +857,6 @@@ enum cpu_idle_type 
  #define SD_BALANCE_FORK               0x0008  /* Balance on fork, clone */
  #define SD_BALANCE_WAKE               0x0010  /* Balance on wakeup */
  #define SD_WAKE_AFFINE                0x0020  /* Wake task to waking CPU */
 -#define SD_PREFER_LOCAL               0x0040  /* Prefer to keep tasks local to this domain */
  #define SD_SHARE_CPUPOWER     0x0080  /* Domain members share cpu power */
  #define SD_SHARE_PKG_RESOURCES        0x0200  /* Domain members share cpu pkg resources */
  #define SD_SERIALIZE          0x0400  /* Only a single load balancing instance */
@@@ -1413,7 -1417,7 +1413,7 @@@ struct task_struct 
  
        struct audit_context *audit_context;
  #ifdef CONFIG_AUDITSYSCALL
 -      uid_t loginuid;
 +      kuid_t loginuid;
        unsigned int sessionid;
  #endif
        struct seccomp seccomp;
         * cache last used pipe for splice
         */
        struct pipe_inode_info *splice_pipe;
 +
 +      struct page_frag task_frag;
 +
  #ifdef        CONFIG_TASK_DELAY_ACCT
        struct task_delay_info *delays;
  #endif
@@@ -1884,14 -1885,6 +1884,14 @@@ 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)
  {
@@@ -2332,6 -2325,9 +2332,9 @@@ extern int do_execve(const char *
                     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 *);
  struct task_struct *fork_idle(int);
+ #ifdef CONFIG_GENERIC_KERNEL_THREAD
+ extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+ #endif
  
  extern void set_task_comm(struct task_struct *tsk, char *from);
  extern char *get_task_comm(char *to, struct task_struct *tsk);
diff --combined kernel/fork.c
index 1cd7d581b3b2da32e07c57a8342d597ee7ceb73f,a42c62a8eb248b9540aa86298101055eb96562b9..8b20ab7d3aa2951eff91a4e09e0af23a90992747
@@@ -330,7 -330,6 +330,7 @@@ static struct task_struct *dup_task_str
        tsk->btrace_seq = 0;
  #endif
        tsk->splice_pipe = NULL;
 +      tsk->task_frag.page = NULL;
  
        account_kernel_stack(ti, 1);
  
@@@ -354,7 -353,6 +354,7 @@@ static int dup_mmap(struct mm_struct *m
  
        down_write(&oldmm->mmap_sem);
        flush_cache_dup_mm(oldmm);
 +      uprobe_dup_mmap(oldmm, mm);
        /*
         * Not linked in yet - no deadlock potential:
         */
                                mapping->i_mmap_writable++;
                        flush_dcache_mmap_lock(mapping);
                        /* insert tmp into the share list, just after mpnt */
 -                      vma_prio_tree_add(tmp, mpnt);
 +                      if (unlikely(tmp->vm_flags & VM_NONLINEAR))
 +                              vma_nonlinear_insert(tmp,
 +                                              &mapping->i_mmap_nonlinear);
 +                      else
 +                              vma_interval_tree_insert_after(tmp, mpnt,
 +                                                      &mapping->i_mmap);
                        flush_dcache_mmap_unlock(mapping);
                        mutex_unlock(&mapping->i_mmap_mutex);
                }
  
                if (retval)
                        goto out;
 -
 -              if (file)
 -                      uprobe_mmap(tmp);
        }
        /* a new mm has just been created */
        arch_dup_mmap(oldmm, mm);
@@@ -627,6 -623,26 +627,6 @@@ void mmput(struct mm_struct *mm
  }
  EXPORT_SYMBOL_GPL(mmput);
  
 -/*
 - * We added or removed a vma mapping the executable. The vmas are only mapped
 - * during exec and are not mapped with the mmap system call.
 - * Callers must hold down_write() on the mm's mmap_sem for these
 - */
 -void added_exe_file_vma(struct mm_struct *mm)
 -{
 -      mm->num_exe_file_vmas++;
 -}
 -
 -void removed_exe_file_vma(struct mm_struct *mm)
 -{
 -      mm->num_exe_file_vmas--;
 -      if ((mm->num_exe_file_vmas == 0) && mm->exe_file) {
 -              fput(mm->exe_file);
 -              mm->exe_file = NULL;
 -      }
 -
 -}
 -
  void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
  {
        if (new_exe_file)
        if (mm->exe_file)
                fput(mm->exe_file);
        mm->exe_file = new_exe_file;
 -      mm->num_exe_file_vmas = 0;
  }
  
  struct file *get_mm_exe_file(struct mm_struct *mm)
  {
        struct file *exe_file;
  
 -      /* We need mmap_sem to protect against races with removal of
 -       * VM_EXECUTABLE vmas */
 +      /* We need mmap_sem to protect against races with removal of exe_file */
        down_read(&mm->mmap_sem);
        exe_file = mm->exe_file;
        if (exe_file)
@@@ -821,6 -839,8 +821,6 @@@ struct mm_struct *dup_mm(struct task_st
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
        mm->pmd_huge_pte = NULL;
  #endif
 -      uprobe_reset_state(mm);
 -
        if (!mm_init(mm, tsk))
                goto fail_nomem;
  
@@@ -1061,6 -1081,7 +1061,6 @@@ static int copy_signal(unsigned long cl
        init_rwsem(&sig->group_rwsem);
  #endif
  
 -      sig->oom_adj = current->signal->oom_adj;
        sig->oom_score_adj = current->signal->oom_score_adj;
        sig->oom_score_adj_min = current->signal->oom_score_adj_min;
  
@@@ -1259,7 -1280,11 +1259,7 @@@ static struct task_struct *copy_process
  #endif
  #ifdef CONFIG_TRACE_IRQFLAGS
        p->irq_events = 0;
 -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
 -      p->hardirqs_enabled = 1;
 -#else
        p->hardirqs_enabled = 0;
 -#endif
        p->hardirq_enable_ip = 0;
        p->hardirq_enable_event = 0;
        p->hardirq_disable_ip = _THIS_IP_;
@@@ -1584,7 -1609,7 +1584,7 @@@ long do_fork(unsigned long clone_flags
         * requested, no event is reported; otherwise, report if the event
         * for the type of forking is enabled.
         */
-       if (likely(user_mode(regs)) && !(clone_flags & CLONE_UNTRACED)) {
+       if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) {
                if (clone_flags & CLONE_VFORK)
                        trace = PTRACE_EVENT_VFORK;
                else if ((clone_flags & CSIGNAL) != SIGCHLD)
        return nr;
  }
  
+ #ifdef CONFIG_GENERIC_KERNEL_THREAD
+ /*
+  * Create a kernel thread.
+  */
+ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+ {
+       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, NULL,
+               (unsigned long)arg, NULL, NULL);
+ }
+ #endif
  #ifndef ARCH_MIN_MMSTRUCT_ALIGN
  #define ARCH_MIN_MMSTRUCT_ALIGN 0
  #endif
This page took 0.419395 seconds and 4 git commands to generate.