]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Mar 2012 01:12:23 +0000 (18:12 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Mar 2012 01:12:23 +0000 (18:12 -0700)
Pull x32 support for x86-64 from Ingo Molnar:
 "This tree introduces the X32 binary format and execution mode for x86:
  32-bit data space binaries using 64-bit instructions and 64-bit kernel
  syscalls.

  This allows applications whose working set fits into a 32 bits address
  space to make use of 64-bit instructions while using a 32-bit address
  space with shorter pointers, more compressed data structures, etc."

Fix up trivial context conflicts in arch/x86/{Kconfig,vdso/vma.c}

* 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (71 commits)
  x32: Fix alignment fail in struct compat_siginfo
  x32: Fix stupid ia32/x32 inversion in the siginfo format
  x32: Add ptrace for x32
  x32: Switch to a 64-bit clock_t
  x32: Provide separate is_ia32_task() and is_x32_task() predicates
  x86, mtrr: Use explicit sizing and padding for the 64-bit ioctls
  x86/x32: Fix the binutils auto-detect
  x32: Warn and disable rather than error if binutils too old
  x32: Only clear TIF_X32 flag once
  x32: Make sure TS_COMPAT is cleared for x32 tasks
  fs: Remove missed ->fds_bits from cessation use of fd_set structs internally
  fs: Fix close_on_exec pointer in alloc_fdtable
  x32: Drop non-__vdso weak symbols from the x32 VDSO
  x32: Fix coding style violations in the x32 VDSO code
  x32: Add x32 VDSO support
  x32: Allow x32 to be configured
  x32: If configured, add x32 system calls to system call tables
  x32: Handle process creation
  x32: Signal-related system calls
  x86: Add #ifdef CONFIG_COMPAT to <asm/sys_ia32.h>
  ...

32 files changed:
1  2 
arch/x86/Kconfig
arch/x86/ia32/ia32_signal.c
arch/x86/include/asm/elf.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/thread_info.h
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/process_64.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/signal.c
arch/x86/kernel/sys_x86_64.c
arch/x86/syscalls/syscall_32.tbl
arch/x86/vdso/vdso32-setup.c
arch/x86/vdso/vma.c
drivers/char/lp.c
drivers/staging/android/binder.c
fs/autofs4/dev-ioctl.c
fs/binfmt_elf.c
fs/compat.c
fs/exec.c
fs/file.c
fs/proc/base.c
fs/select.c
include/linux/Kbuild
include/linux/compat.h
include/linux/kernel.h
include/linux/time.h
kernel/exit.c
net/bluetooth/hci_sock.c
net/compat.c
net/socket.c
security/selinux/hooks.c

diff --combined arch/x86/Kconfig
index abfb953c131d7fe833b535a68927decd8bdb03e2,e2b38b4bffdce8f0576efb241a0b2bd13026ba23..1d14cc6b79ad399d1ad293030c9f2271d9e5df1d
@@@ -69,6 -69,7 +69,6 @@@ config X8
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_TEXT_POKE_SMP
        select HAVE_GENERIC_HARDIRQS
 -      select HAVE_SPARSE_IRQ
        select SPARSE_IRQ
        select GENERIC_FIND_FIRST_BIT
        select GENERIC_IRQ_PROBE
@@@ -81,7 -82,6 +81,7 @@@
        select CLKEVT_I8253
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_IOMAP
 +      select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
  
  config INSTRUCTION_DECODER
        def_bool (KPROBES || PERF_EVENTS)
@@@ -179,9 -179,6 +179,9 @@@ config ARCH_HAS_DEFAULT_IDL
  config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
  
 +config ARCH_HAS_CPU_AUTOPROBE
 +      def_bool y
 +
  config HAVE_SETUP_PER_CPU_AREA
        def_bool y
  
@@@ -401,7 -398,6 +401,7 @@@ config X86_INTEL_C
        select X86_REBOOTFIXUPS
        select OF
        select OF_EARLY_FLATTREE
 +      select IRQ_DOMAIN
        ---help---
          Select for the Intel CE media processor (CE4100) SOC.
          This option compiles in support for the CE4100 SOC for settop
@@@ -421,6 -417,27 +421,6 @@@ if X86_WANT_INTEL_MI
  config X86_INTEL_MID
        bool
  
 -config X86_MRST
 -       bool "Moorestown MID platform"
 -      depends on PCI
 -      depends on PCI_GOANY
 -      depends on X86_IO_APIC
 -      select X86_INTEL_MID
 -      select SFI
 -      select DW_APB_TIMER
 -      select APB_TIMER
 -      select I2C
 -      select SPI
 -      select INTEL_SCU_IPC
 -      select X86_PLATFORM_DEVICES
 -      ---help---
 -        Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
 -        Internet Device(MID) platform. Moorestown consists of two chips:
 -        Lincroft (CPU core, graphics, and memory controller) and Langwell IOH.
 -        Unlike standard x86 PCs, Moorestown does not have many legacy devices
 -        nor standard legacy replacement devices/features. e.g. Moorestown does
 -        not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
 -
  config X86_MDFLD
         bool "Medfield MID platform"
        depends on PCI
        select SPI
        select INTEL_SCU_IPC
        select X86_PLATFORM_DEVICES
 +      select MFD_INTEL_MSIC
        ---help---
          Medfield is Intel's Low Power Intel Architecture (LPIA) based Moblin
          Internet Device(MID) platform. 
@@@ -2060,7 -2076,6 +2060,7 @@@ config OLP
        select GPIOLIB
        select OF
        select OF_PROMTREE
 +      select IRQ_DOMAIN
        ---help---
          Add support for detecting the unique features of the OLPC
          XO hardware.
@@@ -2118,19 -2133,6 +2118,19 @@@ config ALI
  
          Note: You have to set alix.force=1 for boards with Award BIOS.
  
 +config NET5501
 +      bool "Soekris Engineering net5501 System Support (LEDS, GPIO, etc)"
 +      select GPIOLIB
 +      ---help---
 +        This option enables system support for the Soekris Engineering net5501.
 +
 +config GEOS
 +      bool "Traverse Technologies GEOS System Support (LEDS, GPIO, etc)"
 +      select GPIOLIB
 +      depends on DMI
 +      ---help---
 +        This option enables system support for the Traverse Technologies GEOS.
 +
  endif # X86_32
  
  config AMD_NB
@@@ -2163,9 -2165,9 +2163,9 @@@ config IA32_EMULATIO
        depends on X86_64
        select COMPAT_BINFMT_ELF
        ---help---
-         Include code to run 32-bit programs under a 64-bit kernel. You should
-         likely turn this on, unless you're 100% sure that you don't have any
-         32-bit programs left.
+         Include code to run legacy 32-bit programs under a
+         64-bit kernel. You should likely turn this on, unless you're
+         100% sure that you don't have any 32-bit programs left.
  
  config IA32_AOUT
        tristate "IA32 a.out support"
        ---help---
          Support old a.out binaries in the 32bit emulation.
  
+ config X86_X32
+       bool "x32 ABI for 64-bit mode (EXPERIMENTAL)"
+       depends on X86_64 && IA32_EMULATION && EXPERIMENTAL
+       ---help---
+         Include code to run binaries for the x32 native 32-bit ABI
+         for 64-bit processors.  An x32 process gets access to the
+         full 64-bit register file and wide data path while leaving
+         pointers at 32 bits for smaller memory footprint.
+         You will need a recent binutils (2.22 or later) with
+         elf32_x86_64 support enabled to compile a kernel with this
+         option set.
  config COMPAT
        def_bool y
-       depends on IA32_EMULATION
+       depends on IA32_EMULATION || X86_X32
 +      select ARCH_WANT_OLD_COMPAT_IPC
  
  config COMPAT_FOR_U64_ALIGNMENT
        def_bool COMPAT
index 5563ba1cf5136556a618ae345abd0194dc58e75f,ef026aa19d639808eaeee3b45bdec7dcb7048a49..8ff8e7ddfc55ec65542783979cdb2bcd0bc64c8b
  #include <linux/mm.h>
  #include <linux/smp.h>
  #include <linux/kernel.h>
- #include <linux/signal.h>
  #include <linux/errno.h>
  #include <linux/wait.h>
- #include <linux/ptrace.h>
  #include <linux/unistd.h>
  #include <linux/stddef.h>
  #include <linux/personality.h>
@@@ -24,7 -22,6 +22,7 @@@
  #include <asm/ucontext.h>
  #include <asm/uaccess.h>
  #include <asm/i387.h>
 +#include <asm/fpu-internal.h>
  #include <asm/ptrace.h>
  #include <asm/ia32_unistd.h>
  #include <asm/user32.h>
  #include <asm/proto.h>
  #include <asm/vdso.h>
  #include <asm/sigframe.h>
+ #include <asm/sighandling.h>
  #include <asm/sys_ia32.h>
  
- #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
- #define FIX_EFLAGS    (X86_EFLAGS_AC | X86_EFLAGS_OF | \
-                        X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
-                        X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
-                        X86_EFLAGS_CF)
- void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
+ #define FIX_EFLAGS    __FIX_EFLAGS
  
  int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
  {
        int err = 0;
+       bool ia32 = is_ia32_task();
  
        if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
                return -EFAULT;
                        case __SI_FAULT >> 16:
                                break;
                        case __SI_CHLD >> 16:
-                               put_user_ex(from->si_utime, &to->si_utime);
-                               put_user_ex(from->si_stime, &to->si_stime);
+                               if (ia32) {
+                                       put_user_ex(from->si_utime, &to->si_utime);
+                                       put_user_ex(from->si_stime, &to->si_stime);
+                               } else {
+                                       put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
+                                       put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
+                               }
                                put_user_ex(from->si_status, &to->si_status);
                                /* FALL THROUGH */
                        default:
index f27f79abe0215545ae4eccb796adbb920b6ce6ce,1e40634591a4c48c01aefc2f97a0244227a0fdde..5939f44fe0c0dfdce7fc8a88452e03871be35882
@@@ -84,6 -84,7 +84,6 @@@ extern unsigned int vdso_enabled
        (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
  
  #include <asm/processor.h>
 -#include <asm/system.h>
  
  #ifdef CONFIG_X86_32
  #include <asm/desc.h>
@@@ -155,7 -156,12 +155,12 @@@ do {                                             
  #define elf_check_arch(x)                     \
        ((x)->e_machine == EM_X86_64)
  
- #define compat_elf_check_arch(x)      elf_check_arch_ia32(x)
+ #define compat_elf_check_arch(x)              \
+       (elf_check_arch_ia32(x) || (x)->e_machine == EM_X86_64)
+ #if __USER32_DS != __USER_DS
+ # error "The following code assumes __USER32_DS == __USER_DS"
+ #endif
  
  static inline void elf_common_init(struct thread_struct *t,
                                   struct pt_regs *regs, const u16 ds)
  void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp);
  #define compat_start_thread start_thread_ia32
  
- void set_personality_ia32(void);
- #define COMPAT_SET_PERSONALITY(ex) set_personality_ia32()
+ void set_personality_ia32(bool);
+ #define COMPAT_SET_PERSONALITY(ex)                    \
+       set_personality_ia32((ex).e_machine == EM_X86_64)
  
  #define COMPAT_ELF_PLATFORM                   ("i686")
  
@@@ -286,7 -293,7 +292,7 @@@ do {                                                                       
  #define VDSO_HIGH_BASE                0xffffe000U /* CONFIG_COMPAT_VDSO address */
  
  /* 1GB for 64bit, 8MB for 32bit */
- #define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff)
+ #define STACK_RND_MASK (test_thread_flag(TIF_ADDR32) ? 0x7ff : 0x3fffff)
  
  #define ARCH_DLINFO                                                   \
  do {                                                                  \
                            (unsigned long)current->mm->context.vdso);  \
  } while (0)
  
+ #define ARCH_DLINFO_X32                                                       \
+ do {                                                                  \
+       if (vdso_enabled)                                               \
+               NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
+                           (unsigned long)current->mm->context.vdso);  \
+ } while (0)
  #define AT_SYSINFO            32
  
- #define COMPAT_ARCH_DLINFO    ARCH_DLINFO_IA32(sysctl_vsyscall32)
+ #define COMPAT_ARCH_DLINFO                                            \
+ if (test_thread_flag(TIF_X32))                                                \
+       ARCH_DLINFO_X32;                                                \
+ else                                                                  \
+       ARCH_DLINFO_IA32(sysctl_vsyscall32)
  
  #define COMPAT_ELF_ET_DYN_BASE        (TASK_UNMAPPED_BASE + 0x1000000)
  
@@@ -313,6 -331,8 +330,8 @@@ struct linux_binprm
  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
  extern int arch_setup_additional_pages(struct linux_binprm *bprm,
                                       int uses_interp);
+ extern int x32_setup_additional_pages(struct linux_binprm *bprm,
+                                     int uses_interp);
  
  extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
  #define compat_arch_setup_additional_pages    syscall32_setup_pages
@@@ -329,7 -349,7 +348,7 @@@ static inline int mmap_is_ia32(void
        return 1;
  #endif
  #ifdef CONFIG_IA32_EMULATION
-       if (test_thread_flag(TIF_IA32))
+       if (test_thread_flag(TIF_ADDR32))
                return 1;
  #endif
        return 0;
index a19542c1685e1b47433839fd8c6a08ffba23e2b2,e34f95129f1642e615eca34a150f813b3a8f9b81..f302ef6bb200fe01635acd700f174364daa263d5
@@@ -14,13 -14,13 +14,13 @@@ struct mm_struct
  #include <asm/sigcontext.h>
  #include <asm/current.h>
  #include <asm/cpufeature.h>
 -#include <asm/system.h>
  #include <asm/page.h>
  #include <asm/pgtable_types.h>
  #include <asm/percpu.h>
  #include <asm/msr.h>
  #include <asm/desc_defs.h>
  #include <asm/nops.h>
 +#include <asm/special_insns.h>
  
  #include <linux/personality.h>
  #include <linux/cpumask.h>
  #include <linux/math64.h>
  #include <linux/init.h>
  #include <linux/err.h>
 +#include <linux/irqflags.h>
 +
 +/*
 + * We handle most unaligned accesses in hardware.  On the other hand
 + * unaligned DMA can be quite expensive on some Nehalem processors.
 + *
 + * Based on this we disable the IP header alignment in network drivers.
 + */
 +#define NET_IP_ALIGN  0
  
  #define HBP_NUM 4
  /*
@@@ -171,7 -162,6 +171,7 @@@ extern void early_cpu_init(void)
  extern void identify_boot_cpu(void);
  extern void identify_secondary_cpu(struct cpuinfo_x86 *);
  extern void print_cpu_info(struct cpuinfo_x86 *);
 +void print_cpu_msr(struct cpuinfo_x86 *);
  extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
  extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
  extern unsigned short num_cache_leaves;
@@@ -384,8 -374,6 +384,8 @@@ union thread_xstate 
  };
  
  struct fpu {
 +      unsigned int last_cpu;
 +      unsigned int has_fpu;
        union thread_xstate *state;
  };
  
@@@ -484,6 -472,61 +484,6 @@@ struct thread_struct 
        unsigned                io_bitmap_max;
  };
  
 -static inline unsigned long native_get_debugreg(int regno)
 -{
 -      unsigned long val = 0;  /* Damn you, gcc! */
 -
 -      switch (regno) {
 -      case 0:
 -              asm("mov %%db0, %0" :"=r" (val));
 -              break;
 -      case 1:
 -              asm("mov %%db1, %0" :"=r" (val));
 -              break;
 -      case 2:
 -              asm("mov %%db2, %0" :"=r" (val));
 -              break;
 -      case 3:
 -              asm("mov %%db3, %0" :"=r" (val));
 -              break;
 -      case 6:
 -              asm("mov %%db6, %0" :"=r" (val));
 -              break;
 -      case 7:
 -              asm("mov %%db7, %0" :"=r" (val));
 -              break;
 -      default:
 -              BUG();
 -      }
 -      return val;
 -}
 -
 -static inline void native_set_debugreg(int regno, unsigned long value)
 -{
 -      switch (regno) {
 -      case 0:
 -              asm("mov %0, %%db0"     ::"r" (value));
 -              break;
 -      case 1:
 -              asm("mov %0, %%db1"     ::"r" (value));
 -              break;
 -      case 2:
 -              asm("mov %0, %%db2"     ::"r" (value));
 -              break;
 -      case 3:
 -              asm("mov %0, %%db3"     ::"r" (value));
 -              break;
 -      case 6:
 -              asm("mov %0, %%db6"     ::"r" (value));
 -              break;
 -      case 7:
 -              asm("mov %0, %%db7"     ::"r" (value));
 -              break;
 -      default:
 -              BUG();
 -      }
 -}
 -
  /*
   * Set IOPL bits in EFLAGS from given mask
   */
@@@ -529,6 -572,14 +529,6 @@@ static inline void native_swapgs(void
  #define __cpuid                       native_cpuid
  #define paravirt_enabled()    0
  
 -/*
 - * These special macros can be used to get or set a debugging register
 - */
 -#define get_debugreg(var, register)                           \
 -      (var) = native_get_debugreg(register)
 -#define set_debugreg(value, register)                         \
 -      native_set_debugreg(register, value)
 -
  static inline void load_sp0(struct tss_struct *tss,
                            struct thread_struct *thread)
  {
@@@ -873,9 -924,9 +873,9 @@@ extern unsigned long thread_saved_pc(st
  #define IA32_PAGE_OFFSET      ((current->personality & ADDR_LIMIT_3GB) ? \
                                        0xc0000000 : 0xFFFFe000)
  
- #define TASK_SIZE             (test_thread_flag(TIF_IA32) ? \
+ #define TASK_SIZE             (test_thread_flag(TIF_ADDR32) ? \
                                        IA32_PAGE_OFFSET : TASK_SIZE_MAX)
- #define TASK_SIZE_OF(child)   ((test_tsk_thread_flag(child, TIF_IA32)) ? \
+ #define TASK_SIZE_OF(child)   ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \
                                        IA32_PAGE_OFFSET : TASK_SIZE_MAX)
  
  #define STACK_TOP             TASK_SIZE
  
  #define task_pt_regs(tsk)     ((struct pt_regs *)(tsk)->thread.sp0 - 1)
  extern unsigned long KSTK_ESP(struct task_struct *task);
+ /*
+  * User space RSP while inside the SYSCALL fast path
+  */
+ DECLARE_PER_CPU(unsigned long, old_rsp);
  #endif /* CONFIG_X86_64 */
  
  extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
@@@ -968,24 -1025,4 +974,24 @@@ extern bool cpu_has_amd_erratum(const i
  #define cpu_has_amd_erratum(x)        (false)
  #endif /* CONFIG_CPU_SUP_AMD */
  
 +#ifdef CONFIG_X86_32
 +/*
 + * disable hlt during certain critical i/o operations
 + */
 +#define HAVE_DISABLE_HLT
 +#endif
 +
 +void disable_hlt(void);
 +void enable_hlt(void);
 +
 +void cpu_idle_wait(void);
 +
 +extern unsigned long arch_align_stack(unsigned long sp);
 +extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 +
 +void default_idle(void);
 +bool set_pm_idle_to_default(void);
 +
 +void stop_this_cpu(void *dummy);
 +
  #endif /* _ASM_X86_PROCESSOR_H */
index cfd8144d552742bcd12ac1b42f0d7b45adc5c2fb,912e93511466ff3b59b6c32e552b821fb2fb0e4d..af1db7e722f48d8fc982cb7f154e830b012f85b5
@@@ -86,7 -86,7 +86,7 @@@ struct thread_info 
  #define TIF_MCE_NOTIFY                10      /* notify userspace of an MCE */
  #define TIF_USER_RETURN_NOTIFY        11      /* notify kernel of userspace return */
  #define TIF_NOTSC             16      /* TSC is not accessible in userland */
- #define TIF_IA32              17      /* 32bit process */
+ #define TIF_IA32              17      /* IA32 compatibility process */
  #define TIF_FORK              18      /* ret_from_fork */
  #define TIF_MEMDIE            20      /* is terminating due to OOM killer */
  #define TIF_DEBUG             21      /* uses debug registers */
@@@ -95,6 -95,8 +95,8 @@@
  #define TIF_BLOCKSTEP         25      /* set when we want DEBUGCTLMSR_BTF */
  #define TIF_LAZY_MMU_UPDATES  27      /* task is updating the mmu lazily */
  #define TIF_SYSCALL_TRACEPOINT        28      /* syscall tracepoint instrumentation */
+ #define TIF_ADDR32            29      /* 32-bit address space on 64 bits */
+ #define TIF_X32                       30      /* 32-bit native x86-64 binary */
  
  #define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
  #define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
  #define _TIF_BLOCKSTEP                (1 << TIF_BLOCKSTEP)
  #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
  #define _TIF_SYSCALL_TRACEPOINT       (1 << TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_ADDR32           (1 << TIF_ADDR32)
+ #define _TIF_X32              (1 << TIF_X32)
  
  /* work to do in syscall_trace_enter() */
  #define _TIF_WORK_SYSCALL_ENTRY       \
@@@ -247,6 -251,8 +251,6 @@@ static inline struct thread_info *curre
   * ever touches our thread-synchronous status, so we don't
   * have to worry about atomic accesses.
   */
 -#define TS_USEDFPU            0x0001  /* FPU was used by this task
 -                                         this quantum (SMP) */
  #define TS_COMPAT             0x0002  /* 32bit syscall active (64BIT)*/
  #define TS_POLLING            0x0004  /* idle task polling need_resched,
                                           skip sending interrupt */
index fa2900c0e3984debf8370b3fc72cdf8a295d34b9,63c0e058a40503f6a7d8f60a0b50471e7b6e437f..40883ffe2da9261b4f34c2997d2b5e533df25648
  #include <linux/slab.h>
  #include <linux/cpu.h>
  #include <linux/bitops.h>
 +#include <linux/device.h>
  
  #include <asm/apic.h>
  #include <asm/stacktrace.h>
  #include <asm/nmi.h>
- #include <asm/compat.h>
  #include <asm/smp.h>
  #include <asm/alternative.h>
 +#include <asm/timer.h>
  
  #include "perf_event.h"
  
@@@ -353,36 -350,6 +352,36 @@@ int x86_setup_perfctr(struct perf_even
        return 0;
  }
  
 +/*
 + * check that branch_sample_type is compatible with
 + * settings needed for precise_ip > 1 which implies
 + * using the LBR to capture ALL taken branches at the
 + * priv levels of the measurement
 + */
 +static inline int precise_br_compat(struct perf_event *event)
 +{
 +      u64 m = event->attr.branch_sample_type;
 +      u64 b = 0;
 +
 +      /* must capture all branches */
 +      if (!(m & PERF_SAMPLE_BRANCH_ANY))
 +              return 0;
 +
 +      m &= PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_USER;
 +
 +      if (!event->attr.exclude_user)
 +              b |= PERF_SAMPLE_BRANCH_USER;
 +
 +      if (!event->attr.exclude_kernel)
 +              b |= PERF_SAMPLE_BRANCH_KERNEL;
 +
 +      /*
 +       * ignore PERF_SAMPLE_BRANCH_HV, not supported on x86
 +       */
 +
 +      return m == b;
 +}
 +
  int x86_pmu_hw_config(struct perf_event *event)
  {
        if (event->attr.precise_ip) {
  
                if (event->attr.precise_ip > precise)
                        return -EOPNOTSUPP;
 +              /*
 +               * check that PEBS LBR correction does not conflict with
 +               * whatever the user is asking with attr->branch_sample_type
 +               */
 +              if (event->attr.precise_ip > 1) {
 +                      u64 *br_type = &event->attr.branch_sample_type;
 +
 +                      if (has_branch_stack(event)) {
 +                              if (!precise_br_compat(event))
 +                                      return -EOPNOTSUPP;
 +
 +                              /* branch_sample_type is compatible */
 +
 +                      } else {
 +                              /*
 +                               * user did not specify  branch_sample_type
 +                               *
 +                               * For PEBS fixups, we capture all
 +                               * the branches at the priv level of the
 +                               * event.
 +                               */
 +                              *br_type = PERF_SAMPLE_BRANCH_ANY;
 +
 +                              if (!event->attr.exclude_user)
 +                                      *br_type |= PERF_SAMPLE_BRANCH_USER;
 +
 +                              if (!event->attr.exclude_kernel)
 +                                      *br_type |= PERF_SAMPLE_BRANCH_KERNEL;
 +                      }
 +              }
        }
  
        /*
@@@ -486,10 -423,6 +485,10 @@@ static int __x86_pmu_event_init(struct 
        /* mark unused */
        event->hw.extra_reg.idx = EXTRA_REG_NONE;
  
 +      /* mark not used */
 +      event->hw.extra_reg.idx = EXTRA_REG_NONE;
 +      event->hw.branch_reg.idx = EXTRA_REG_NONE;
 +
        return x86_pmu.hw_config(event);
  }
  
@@@ -643,14 -576,14 +642,14 @@@ static bool __perf_sched_find_counter(s
        /* Prefer fixed purpose counters */
        if (x86_pmu.num_counters_fixed) {
                idx = X86_PMC_IDX_FIXED;
 -              for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) {
 +              for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
                        if (!__test_and_set_bit(idx, sched->state.used))
                                goto done;
                }
        }
        /* Grab the first unused counter starting with idx */
        idx = sched->state.counter;
 -      for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
 +      for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
                if (!__test_and_set_bit(idx, sched->state.used))
                        goto done;
        }
@@@ -1276,8 -1209,6 +1275,8 @@@ x86_pmu_notifier(struct notifier_block 
                break;
  
        case CPU_STARTING:
 +              if (x86_pmu.attr_rdpmc)
 +                      set_in_cr4(X86_CR4_PCE);
                if (x86_pmu.cpu_starting)
                        x86_pmu.cpu_starting(cpu);
                break;
@@@ -1387,8 -1318,6 +1386,8 @@@ static int __init init_hw_perf_events(v
                }
        }
  
 +      x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
 +
        pr_info("... version:                %d\n",     x86_pmu.version);
        pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
        pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
@@@ -1612,106 -1541,23 +1611,106 @@@ static int x86_pmu_event_init(struct pe
        return err;
  }
  
 +static int x86_pmu_event_idx(struct perf_event *event)
 +{
 +      int idx = event->hw.idx;
 +
 +      if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) {
 +              idx -= X86_PMC_IDX_FIXED;
 +              idx |= 1 << 30;
 +      }
 +
 +      return idx + 1;
 +}
 +
 +static ssize_t get_attr_rdpmc(struct device *cdev,
 +                            struct device_attribute *attr,
 +                            char *buf)
 +{
 +      return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
 +}
 +
 +static void change_rdpmc(void *info)
 +{
 +      bool enable = !!(unsigned long)info;
 +
 +      if (enable)
 +              set_in_cr4(X86_CR4_PCE);
 +      else
 +              clear_in_cr4(X86_CR4_PCE);
 +}
 +
 +static ssize_t set_attr_rdpmc(struct device *cdev,
 +                            struct device_attribute *attr,
 +                            const char *buf, size_t count)
 +{
 +      unsigned long val = simple_strtoul(buf, NULL, 0);
 +
 +      if (!!val != !!x86_pmu.attr_rdpmc) {
 +              x86_pmu.attr_rdpmc = !!val;
 +              smp_call_function(change_rdpmc, (void *)val, 1);
 +      }
 +
 +      return count;
 +}
 +
 +static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
 +
 +static struct attribute *x86_pmu_attrs[] = {
 +      &dev_attr_rdpmc.attr,
 +      NULL,
 +};
 +
 +static struct attribute_group x86_pmu_attr_group = {
 +      .attrs = x86_pmu_attrs,
 +};
 +
 +static const struct attribute_group *x86_pmu_attr_groups[] = {
 +      &x86_pmu_attr_group,
 +      NULL,
 +};
 +
 +static void x86_pmu_flush_branch_stack(void)
 +{
 +      if (x86_pmu.flush_branch_stack)
 +              x86_pmu.flush_branch_stack();
 +}
 +
  static struct pmu pmu = {
 -      .pmu_enable     = x86_pmu_enable,
 -      .pmu_disable    = x86_pmu_disable,
 +      .pmu_enable             = x86_pmu_enable,
 +      .pmu_disable            = x86_pmu_disable,
 +
 +      .attr_groups    = x86_pmu_attr_groups,
  
        .event_init     = x86_pmu_event_init,
  
 -      .add            = x86_pmu_add,
 -      .del            = x86_pmu_del,
 -      .start          = x86_pmu_start,
 -      .stop           = x86_pmu_stop,
 -      .read           = x86_pmu_read,
 +      .add                    = x86_pmu_add,
 +      .del                    = x86_pmu_del,
 +      .start                  = x86_pmu_start,
 +      .stop                   = x86_pmu_stop,
 +      .read                   = x86_pmu_read,
  
        .start_txn      = x86_pmu_start_txn,
        .cancel_txn     = x86_pmu_cancel_txn,
        .commit_txn     = x86_pmu_commit_txn,
 +
 +      .event_idx      = x86_pmu_event_idx,
 +      .flush_branch_stack     = x86_pmu_flush_branch_stack,
  };
  
 +void perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now)
 +{
 +      if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
 +              return;
 +
 +      if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
 +              return;
 +
 +      userpg->time_mult = this_cpu_read(cyc2ns);
 +      userpg->time_shift = CYC2NS_SCALE_FACTOR;
 +      userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
 +}
 +
  /*
   * callchain support
   */
@@@ -1748,6 -1594,9 +1747,9 @@@ perf_callchain_kernel(struct perf_callc
  }
  
  #ifdef CONFIG_COMPAT
+ #include <asm/compat.h>
  static inline int
  perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
  {
index 734ebd1d3caabf0e0b058a1f8ed6aa947c1caf95,9e036f0ce5e0dc458fae8a62c782f7664bd10a78..cdc79b5cfcd925c014010a3fe60723a14143616a
@@@ -320,7 -320,7 +320,7 @@@ ENDPROC(native_usergs_sysret64
        movq %rsp, %rsi
  
        leaq -RBP(%rsp),%rdi    /* arg1 for handler */
 -      testl $3, CS(%rdi)
 +      testl $3, CS-RBP(%rsi)
        je 1f
        SWAPGS
        /*
         * moving irq_enter into assembly, which would be too much work)
         */
  1:    incl PER_CPU_VAR(irq_count)
 -      jne 2f
 -      mov PER_CPU_VAR(irq_stack_ptr),%rsp
 +      cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp
        CFI_DEF_CFA_REGISTER    rsi
  
 -2:    /* Store previous stack value */
 +      /* Store previous stack value */
        pushq %rsi
        CFI_ESCAPE      0x0f /* DW_CFA_def_cfa_expression */, 6, \
                        0x77 /* DW_OP_breg7 */, 0, \
@@@ -481,7 -482,12 +481,12 @@@ GLOBAL(system_call_after_swapgs
        testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
        jnz tracesys
  system_call_fastpath:
+ #if __SYSCALL_MASK == ~0
        cmpq $__NR_syscall_max,%rax
+ #else
+       andl $__SYSCALL_MASK,%eax
+       cmpl $__NR_syscall_max,%eax
+ #endif
        ja badsys
        movq %r10,%rcx
        call *sys_call_table(,%rax,8)  # XXX:    rip relative
@@@ -595,7 -601,12 +600,12 @@@ tracesys
         */
        LOAD_ARGS ARGOFFSET, 1
        RESTORE_REST
+ #if __SYSCALL_MASK == ~0
        cmpq $__NR_syscall_max,%rax
+ #else
+       andl $__SYSCALL_MASK,%eax
+       cmpl $__NR_syscall_max,%eax
+ #endif
        ja   int_ret_from_sys_call      /* RAX(%rsp) set to -ENOSYS above */
        movq %r10,%rcx  /* fixup for C */
        call *sys_call_table(,%rax,8)
@@@ -735,6 -746,40 +745,40 @@@ ENTRY(stub_rt_sigreturn
        CFI_ENDPROC
  END(stub_rt_sigreturn)
  
+ #ifdef CONFIG_X86_X32_ABI
+       PTREGSCALL stub_x32_sigaltstack, sys32_sigaltstack, %rdx
+ ENTRY(stub_x32_rt_sigreturn)
+       CFI_STARTPROC
+       addq $8, %rsp
+       PARTIAL_FRAME 0
+       SAVE_REST
+       movq %rsp,%rdi
+       FIXUP_TOP_OF_STACK %r11
+       call sys32_x32_rt_sigreturn
+       movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
+       RESTORE_REST
+       jmp int_ret_from_sys_call
+       CFI_ENDPROC
+ END(stub_x32_rt_sigreturn)
+ ENTRY(stub_x32_execve)
+       CFI_STARTPROC
+       addq $8, %rsp
+       PARTIAL_FRAME 0
+       SAVE_REST
+       FIXUP_TOP_OF_STACK %r11
+       movq %rsp, %rcx
+       call sys32_execve
+       RESTORE_TOP_OF_STACK %r11
+       movq %rax,RAX(%rsp)
+       RESTORE_REST
+       jmp int_ret_from_sys_call
+       CFI_ENDPROC
+ END(stub_x32_execve)
+ #endif
  /*
   * Build the entry stubs and pointer table with some assembler magic.
   * We pack 7 stubs into a single 32-byte chunk, which will fit in a
@@@ -812,7 -857,7 +856,7 @@@ ret_from_intr
  
        /* Restore saved previous stack */
        popq %rsi
 -      CFI_DEF_CFA_REGISTER    rsi
 +      CFI_DEF_CFA rsi,SS+8-RBP        /* reg/off reset after def_cfa_expr */
        leaq ARGOFFSET-RBP(%rsi), %rsp
        CFI_DEF_CFA_REGISTER    rsp
        CFI_ADJUST_CFA_OFFSET   RBP-ARGOFFSET
@@@ -1529,20 -1574,12 +1573,20 @@@ ENTRY(nmi
  
        /* Use %rdx as out temp variable throughout */
        pushq_cfi %rdx
 +      CFI_REL_OFFSET rdx, 0
 +
 +      /*
 +       * If %cs was not the kernel segment, then the NMI triggered in user
 +       * space, which means it is definitely not nested.
 +       */
 +      cmpl $__KERNEL_CS, 16(%rsp)
 +      jne first_nmi
  
        /*
         * Check the special variable on the stack to see if NMIs are
         * executing.
         */
 -      cmp $1, -8(%rsp)
 +      cmpl $1, -8(%rsp)
        je nested_nmi
  
        /*
         */
        lea 6*8(%rsp), %rdx
        test_in_nmi rdx, 4*8(%rsp), nested_nmi, first_nmi
 +      CFI_REMEMBER_STATE
  
  nested_nmi:
        /*
  
  nested_nmi_out:
        popq_cfi %rdx
 +      CFI_RESTORE rdx
  
        /* No need to check faults here */
        INTERRUPT_RETURN
  
 +      CFI_RESTORE_STATE
  first_nmi:
        /*
         * Because nested NMIs will use the pushed location that we
         * | pt_regs                 |
         * +-------------------------+
         *
 -       * The saved RIP is used to fix up the copied RIP that a nested
 -       * NMI may zero out. The original stack frame and the temp storage
 +       * The saved stack frame is used to fix up the copied stack frame
 +       * that a nested NMI may change to make the interrupted NMI iret jump
 +       * to the repeat_nmi. The original stack frame and the temp storage
         * is also used by nested NMIs and can not be trusted on exit.
         */
 +      /* Do not pop rdx, nested NMIs will corrupt that part of the stack */
 +      movq (%rsp), %rdx
 +      CFI_RESTORE rdx
 +
        /* Set the NMI executing variable on the stack. */
        pushq_cfi $1
  
        .rept 5
        pushq_cfi 6*8(%rsp)
        .endr
 +      CFI_DEF_CFA_OFFSET SS+8-RIP
 +
 +      /* Everything up to here is safe from nested NMIs */
 +
 +      /*
 +       * If there was a nested NMI, the first NMI's iret will return
 +       * here. But NMIs are still enabled and we can take another
 +       * nested NMI. The nested NMI checks the interrupted RIP to see
 +       * if it is between repeat_nmi and end_repeat_nmi, and if so
 +       * it will just return, as we are about to repeat an NMI anyway.
 +       * This makes it safe to copy to the stack frame that a nested
 +       * NMI will update.
 +       */
 +repeat_nmi:
 +      /*
 +       * Update the stack variable to say we are still in NMI (the update
 +       * is benign for the non-repeat case, where 1 was pushed just above
 +       * to this very stack slot).
 +       */
 +      movq $1, 5*8(%rsp)
  
        /* Make another copy, this one may be modified by nested NMIs */
        .rept 5
        pushq_cfi 4*8(%rsp)
        .endr
 -
 -      /* Do not pop rdx, nested NMIs will corrupt it */
 -      movq 11*8(%rsp), %rdx
 +      CFI_DEF_CFA_OFFSET SS+8-RIP
 +end_repeat_nmi:
  
        /*
         * Everything below this point can be preempted by a nested
 -       * NMI if the first NMI took an exception. Repeated NMIs
 -       * caused by an exception and nested NMI will start here, and
 -       * can still be preempted by another NMI.
 +       * NMI if the first NMI took an exception and reset our iret stack
 +       * so that we repeat another NMI.
         */
 -restart_nmi:
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
        CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
@@@ -1700,6 -1712,26 +1744,6 @@@ nmi_restore
        CFI_ENDPROC
  END(nmi)
  
 -      /*
 -       * If an NMI hit an iret because of an exception or breakpoint,
 -       * it can lose its NMI context, and a nested NMI may come in.
 -       * In that case, the nested NMI will change the preempted NMI's
 -       * stack to jump to here when it does the final iret.
 -       */
 -repeat_nmi:
 -      INTR_FRAME
 -      /* Update the stack variable to say we are still in NMI */
 -      movq $1, 5*8(%rsp)
 -
 -      /* copy the saved stack back to copy stack */
 -      .rept 5
 -      pushq_cfi 4*8(%rsp)
 -      .endr
 -
 -      jmp restart_nmi
 -      CFI_ENDPROC
 -end_repeat_nmi:
 -
  ENTRY(ignore_sysret)
        CFI_STARTPROC
        mov $-ENOSYS,%eax
index 2b154da0b6d35a342008ae9a0accada9a4880a9a,a4659739e202203ac9c26a32a57ebf72c0a79acc..733ca39f367ebcc222eaca07b87eb170f2831e1e
@@@ -14,6 -14,7 +14,6 @@@
   * This file handles the architecture-dependent parts of process handling..
   */
  
 -#include <linux/stackprotector.h>
  #include <linux/cpu.h>
  #include <linux/errno.h>
  #include <linux/sched.h>
  #include <linux/notifier.h>
  #include <linux/kprobes.h>
  #include <linux/kdebug.h>
 -#include <linux/tick.h>
  #include <linux/prctl.h>
  #include <linux/uaccess.h>
  #include <linux/io.h>
  #include <linux/ftrace.h>
 -#include <linux/cpuidle.h>
  
  #include <asm/pgtable.h>
 -#include <asm/system.h>
  #include <asm/processor.h>
  #include <asm/i387.h>
 +#include <asm/fpu-internal.h>
  #include <asm/mmu_context.h>
  #include <asm/prctl.h>
  #include <asm/desc.h>
  #include <asm/idle.h>
  #include <asm/syscalls.h>
  #include <asm/debugreg.h>
 -#include <asm/nmi.h>
 +#include <asm/switch_to.h>
  
  asmlinkage extern void ret_from_fork(void);
  
  DEFINE_PER_CPU(unsigned long, old_rsp);
 -static DEFINE_PER_CPU(unsigned char, is_idle);
 -
 -static ATOMIC_NOTIFIER_HEAD(idle_notifier);
 -
 -void idle_notifier_register(struct notifier_block *n)
 -{
 -      atomic_notifier_chain_register(&idle_notifier, n);
 -}
 -EXPORT_SYMBOL_GPL(idle_notifier_register);
 -
 -void idle_notifier_unregister(struct notifier_block *n)
 -{
 -      atomic_notifier_chain_unregister(&idle_notifier, n);
 -}
 -EXPORT_SYMBOL_GPL(idle_notifier_unregister);
 -
 -void enter_idle(void)
 -{
 -      percpu_write(is_idle, 1);
 -      atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
 -}
 -
 -static void __exit_idle(void)
 -{
 -      if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
 -              return;
 -      atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
 -}
 -
 -/* Called from interrupts to signify idle end */
 -void exit_idle(void)
 -{
 -      /* idle loop has pid 0 */
 -      if (current->pid)
 -              return;
 -      __exit_idle();
 -}
 -
 -#ifndef CONFIG_SMP
 -static inline void play_dead(void)
 -{
 -      BUG();
 -}
 -#endif
 -
 -/*
 - * The idle thread. There's no useful work to be
 - * done, so just try to conserve power and have a
 - * low exit latency (ie sit in a loop waiting for
 - * somebody to say that they'd like to reschedule)
 - */
 -void cpu_idle(void)
 -{
 -      current_thread_info()->status |= TS_POLLING;
 -
 -      /*
 -       * If we're the non-boot CPU, nothing set the stack canary up
 -       * for us.  CPU0 already has it initialized but no harm in
 -       * doing it again.  This is a good place for updating it, as
 -       * we wont ever return from this function (so the invalid
 -       * canaries already on the stack wont ever trigger).
 -       */
 -      boot_init_stack_canary();
 -
 -      /* endless idle loop with no priority at all */
 -      while (1) {
 -              tick_nohz_idle_enter();
 -              while (!need_resched()) {
 -
 -                      rmb();
 -
 -                      if (cpu_is_offline(smp_processor_id()))
 -                              play_dead();
 -                      /*
 -                       * Idle routines should keep interrupts disabled
 -                       * from here on, until they go to idle.
 -                       * Otherwise, idle callbacks can misfire.
 -                       */
 -                      local_touch_nmi();
 -                      local_irq_disable();
 -                      enter_idle();
 -                      /* Don't trace irqs off for idle */
 -                      stop_critical_timings();
 -
 -                      /* enter_idle() needs rcu for notifiers */
 -                      rcu_idle_enter();
 -
 -                      if (cpuidle_idle_call())
 -                              pm_idle();
 -
 -                      rcu_idle_exit();
 -                      start_critical_timings();
 -
 -                      /* In many cases the interrupt that ended idle
 -                         has already called exit_idle. But some idle
 -                         loops can be woken up without interrupt. */
 -                      __exit_idle();
 -              }
 -
 -              tick_nohz_idle_exit();
 -              preempt_enable_no_resched();
 -              schedule();
 -              preempt_disable();
 -      }
 -}
  
  /* Prints also some state that isn't saved in the pt_regs */
  void __show_regs(struct pt_regs *regs, int all)
@@@ -178,7 -286,6 +178,7 @@@ int copy_thread(unsigned long clone_fla
  
        set_tsk_thread_flag(p, TIF_FORK);
  
 +      p->fpu_counter = 0;
        p->thread.io_bitmap_ptr = NULL;
  
        savesegment(gs, p->thread.gsindex);
@@@ -234,7 -341,6 +234,7 @@@ start_thread_common(struct pt_regs *reg
        loadsegment(es, _ds);
        loadsegment(ds, _ds);
        load_gs_index(0);
 +      current->thread.usersp  = new_sp;
        regs->ip                = new_ip;
        regs->sp                = new_sp;
        percpu_write(old_rsp, new_sp);
@@@ -258,7 -364,9 +258,9 @@@ start_thread(struct pt_regs *regs, unsi
  void start_thread_ia32(struct pt_regs *regs, u32 new_ip, u32 new_sp)
  {
        start_thread_common(regs, new_ip, new_sp,
-                           __USER32_CS, __USER32_DS, __USER32_DS);
+                           test_thread_flag(TIF_X32)
+                           ? __USER_CS : __USER32_CS,
+                           __USER_DS, __USER_DS);
  }
  #endif
  
@@@ -280,9 -388,18 +282,9 @@@ __switch_to(struct task_struct *prev_p
        int cpu = smp_processor_id();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
        unsigned fsindex, gsindex;
 -      bool preload_fpu;
 +      fpu_switch_t fpu;
  
 -      /*
 -       * If the task has used fpu the last 5 timeslices, just do a full
 -       * restore of the math state immediately to avoid the trap; the
 -       * chances of needing FPU soon are obviously high now
 -       */
 -      preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
 -
 -      /* we're going to use this soon, after a few expensive things */
 -      if (preload_fpu)
 -              prefetch(next->fpu.state);
 +      fpu = switch_fpu_prepare(prev_p, next_p, cpu);
  
        /*
         * Reload esp0, LDT and the page table pointer:
  
        load_TLS(next, cpu);
  
 -      /* Must be after DS reload */
 -      __unlazy_fpu(prev_p);
 -
 -      /* Make sure cpu is ready for new context */
 -      if (preload_fpu)
 -              clts();
 -
        /*
         * Leave lazy mode, flushing any hypercalls made here.
         * This must be done before restoring TLS segments so
                wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
        prev->gsindex = gsindex;
  
 +      switch_fpu_finish(next_p, fpu);
 +
        /*
         * Switch the PDA and FPU contexts.
         */
                     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
                __switch_to_xtra(prev_p, next_p, tss);
  
 -      /*
 -       * Preload the FPU context, now that we've determined that the
 -       * task is likely to be using it. 
 -       */
 -      if (preload_fpu)
 -              __math_state_restore();
 -
        return prev_p;
  }
  
@@@ -381,6 -510,8 +383,8 @@@ void set_personality_64bit(void
  
        /* Make sure to be in 64bit mode */
        clear_thread_flag(TIF_IA32);
+       clear_thread_flag(TIF_ADDR32);
+       clear_thread_flag(TIF_X32);
  
        /* Ensure the corresponding mm is not marked. */
        if (current->mm)
        current->personality &= ~READ_IMPLIES_EXEC;
  }
  
- void set_personality_ia32(void)
+ void set_personality_ia32(bool x32)
  {
        /* inherit personality from parent */
  
        /* Make sure to be in 32bit mode */
-       set_thread_flag(TIF_IA32);
-       current->personality |= force_personality32;
+       set_thread_flag(TIF_ADDR32);
  
        /* Mark the associated mm as containing 32-bit tasks. */
        if (current->mm)
                current->mm->context.ia32_compat = 1;
  
-       /* Prepare the first "return" to user space */
-       current_thread_info()->status |= TS_COMPAT;
+       if (x32) {
+               clear_thread_flag(TIF_IA32);
+               set_thread_flag(TIF_X32);
+               current->personality &= ~READ_IMPLIES_EXEC;
+               /* is_compat_task() uses the presence of the x32
+                  syscall bit flag to determine compat status */
+               current_thread_info()->status &= ~TS_COMPAT;
+       } else {
+               set_thread_flag(TIF_IA32);
+               clear_thread_flag(TIF_X32);
+               current->personality |= force_personality32;
+               /* Prepare the first "return" to user space */
+               current_thread_info()->status |= TS_COMPAT;
+       }
  }
  
  unsigned long get_wchan(struct task_struct *p)
diff --combined arch/x86/kernel/ptrace.c
index 8a634c8876521df889915f3bb5462ac05bf0ab6c,93e7877a19c46efebd674059ed03fc9667627cef..284c35ae60e43a0380af94195612b58799280bd8
@@@ -24,9 -24,9 +24,9 @@@
  
  #include <asm/uaccess.h>
  #include <asm/pgtable.h>
 -#include <asm/system.h>
  #include <asm/processor.h>
  #include <asm/i387.h>
 +#include <asm/fpu-internal.h>
  #include <asm/debugreg.h>
  #include <asm/ldt.h>
  #include <asm/desc.h>
@@@ -1130,6 -1130,100 +1130,100 @@@ static int genregs32_set(struct task_st
        return ret;
  }
  
+ #ifdef CONFIG_X86_X32_ABI
+ static long x32_arch_ptrace(struct task_struct *child,
+                           compat_long_t request, compat_ulong_t caddr,
+                           compat_ulong_t cdata)
+ {
+       unsigned long addr = caddr;
+       unsigned long data = cdata;
+       void __user *datap = compat_ptr(data);
+       int ret;
+       switch (request) {
+       /* Read 32bits at location addr in the USER area.  Only allow
+          to return the lower 32bits of segment and debug registers.  */
+       case PTRACE_PEEKUSR: {
+               u32 tmp;
+               ret = -EIO;
+               if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user) ||
+                   addr < offsetof(struct user_regs_struct, cs))
+                       break;
+               tmp = 0;  /* Default return condition */
+               if (addr < sizeof(struct user_regs_struct))
+                       tmp = getreg(child, addr);
+               else if (addr >= offsetof(struct user, u_debugreg[0]) &&
+                        addr <= offsetof(struct user, u_debugreg[7])) {
+                       addr -= offsetof(struct user, u_debugreg[0]);
+                       tmp = ptrace_get_debugreg(child, addr / sizeof(data));
+               }
+               ret = put_user(tmp, (__u32 __user *)datap);
+               break;
+       }
+       /* Write the word at location addr in the USER area.  Only allow
+          to update segment and debug registers with the upper 32bits
+          zero-extended. */
+       case PTRACE_POKEUSR:
+               ret = -EIO;
+               if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user) ||
+                   addr < offsetof(struct user_regs_struct, cs))
+                       break;
+               if (addr < sizeof(struct user_regs_struct))
+                       ret = putreg(child, addr, data);
+               else if (addr >= offsetof(struct user, u_debugreg[0]) &&
+                        addr <= offsetof(struct user, u_debugreg[7])) {
+                       addr -= offsetof(struct user, u_debugreg[0]);
+                       ret = ptrace_set_debugreg(child,
+                                                 addr / sizeof(data), data);
+               }
+               break;
+       case PTRACE_GETREGS:    /* Get all gp regs from the child. */
+               return copy_regset_to_user(child,
+                                          task_user_regset_view(current),
+                                          REGSET_GENERAL,
+                                          0, sizeof(struct user_regs_struct),
+                                          datap);
+       case PTRACE_SETREGS:    /* Set all gp regs in the child. */
+               return copy_regset_from_user(child,
+                                            task_user_regset_view(current),
+                                            REGSET_GENERAL,
+                                            0, sizeof(struct user_regs_struct),
+                                            datap);
+       case PTRACE_GETFPREGS:  /* Get the child FPU state. */
+               return copy_regset_to_user(child,
+                                          task_user_regset_view(current),
+                                          REGSET_FP,
+                                          0, sizeof(struct user_i387_struct),
+                                          datap);
+       case PTRACE_SETFPREGS:  /* Set the child FPU state. */
+               return copy_regset_from_user(child,
+                                            task_user_regset_view(current),
+                                            REGSET_FP,
+                                            0, sizeof(struct user_i387_struct),
+                                            datap);
+               /* normal 64bit interface to access TLS data.
+                  Works just like arch_prctl, except that the arguments
+                  are reversed. */
+       case PTRACE_ARCH_PRCTL:
+               return do_arch_prctl(child, data, addr);
+       default:
+               return compat_ptrace_request(child, request, addr, data);
+       }
+       return ret;
+ }
+ #endif
  long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        compat_ulong_t caddr, compat_ulong_t cdata)
  {
        int ret;
        __u32 val;
  
+ #ifdef CONFIG_X86_X32_ABI
+       if (!is_ia32_task())
+               return x32_arch_ptrace(child, request, caddr, cdata);
+ #endif
        switch (request) {
        case PTRACE_PEEKUSR:
                ret = getreg32(child, addr, &val);
diff --combined arch/x86/kernel/signal.c
index 25edcfc9ba5b8587d06f613481dfa2436f972bdb,c3846b6fb7264f6b24e25252e2fc398ee9a61b25..5134e17855f05ffabe448cdecd663875c0183b06
  #include <linux/mm.h>
  #include <linux/smp.h>
  #include <linux/kernel.h>
- #include <linux/signal.h>
  #include <linux/errno.h>
  #include <linux/wait.h>
- #include <linux/ptrace.h>
  #include <linux/tracehook.h>
  #include <linux/unistd.h>
  #include <linux/stddef.h>
  #include <asm/processor.h>
  #include <asm/ucontext.h>
  #include <asm/i387.h>
 +#include <asm/fpu-internal.h>
  #include <asm/vdso.h>
  #include <asm/mce.h>
+ #include <asm/sighandling.h>
  
  #ifdef CONFIG_X86_64
  #include <asm/proto.h>
  #include <asm/ia32_unistd.h>
+ #include <asm/sys_ia32.h>
  #endif /* CONFIG_X86_64 */
  
  #include <asm/syscall.h>
  
  #include <asm/sigframe.h>
  
- #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
- #define __FIX_EFLAGS  (X86_EFLAGS_AC | X86_EFLAGS_OF | \
-                        X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
-                        X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
-                        X86_EFLAGS_CF)
  #ifdef CONFIG_X86_32
  # define FIX_EFLAGS   (__FIX_EFLAGS | X86_EFLAGS_RF)
  #else
@@@ -69,9 -61,8 +62,8 @@@
        regs->seg = GET_SEG(seg) | 3;                   \
  } while (0)
  
- static int
- restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
-                  unsigned long *pax)
+ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
+                      unsigned long *pax)
  {
        void __user *buf;
        unsigned int tmpflags;
        return err;
  }
  
- static int
- setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
-                struct pt_regs *regs, unsigned long mask)
+ int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
+                    struct pt_regs *regs, unsigned long mask)
  {
        int err = 0;
  
@@@ -643,6 -633,16 +634,16 @@@ static int signr_convert(int sig
  #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,
@@@ -667,8 -667,14 +668,14 @@@ setup_rt_frame(int sig, struct k_sigact
                        ret = ia32_setup_rt_frame(usig, ka, info, set, regs);
                else
                        ret = ia32_setup_frame(usig, ka, set, regs);
-       } else
+ #ifdef CONFIG_X86_X32_ABI
+       } else if (is_x32) {
+               ret = x32_setup_rt_frame(usig, ka, info,
+                                        (compat_sigset_t *)set, regs);
+ #endif
+       } else {
                ret = __setup_rt_frame(sig, ka, info, set, regs);
+       }
  
        if (ret) {
                force_sigsegv(sig, current);
@@@ -851,3 -857,102 +858,102 @@@ void signal_fault(struct pt_regs *regs
  
        force_sig(SIGSEGV, me);
  }
+ #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;
+       sigset_t set;
+       unsigned long ax;
+       struct pt_regs tregs;
+       frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8);
+       if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+               goto badframe;
+       if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+               goto badframe;
+       sigdelsetmask(&set, ~_BLOCKABLE);
+       set_current_blocked(&set);
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
+               goto badframe;
+       tregs = *regs;
+       if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
+               goto badframe;
+       return ax;
+ badframe:
+       signal_fault(regs, frame, "x32 rt_sigreturn");
+       return 0;
+ }
+ #endif
index ef59642ff1bf9e719ae1674668dece0a22787d7c,f921df8c2099133002372199a2c73978bef2d174..b4d3c3927dd8c4106c840f494ba3fd157d98e554
@@@ -98,7 -98,7 +98,7 @@@ out
  static void find_start_end(unsigned long flags, unsigned long *begin,
                           unsigned long *end)
  {
-       if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
+       if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT)) {
                unsigned long new_begin;
                /* This is usually used needed to map code in small
                   model, so it needs to be in the first 31bit. Limit
@@@ -144,7 -144,7 +144,7 @@@ arch_get_unmapped_area(struct file *fil
                    (!vma || addr + len <= vma->vm_start))
                        return addr;
        }
-       if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
+       if (((flags & MAP_32BIT) || test_thread_flag(TIF_ADDR32))
            && len <= mm->cached_hole_size) {
                mm->cached_hole_size = 0;
                mm->free_area_cache = begin;
@@@ -195,7 -195,7 +195,7 @@@ arch_get_unmapped_area_topdown(struct f
  {
        struct vm_area_struct *vma;
        struct mm_struct *mm = current->mm;
 -      unsigned long addr = addr0;
 +      unsigned long addr = addr0, start_addr;
  
        /* requested length too big for entire address space */
        if (len > TASK_SIZE)
                return addr;
  
        /* for MAP_32BIT mappings we force the legact mmap base */
-       if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
+       if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT))
                goto bottomup;
  
        /* requesting a specific address */
                mm->free_area_cache = mm->mmap_base;
        }
  
 +try_again:
        /* either no address requested or can't fit in requested address hole */
 -      addr = mm->free_area_cache;
 -
 -      /* make sure it can fit in the remaining address space */
 -      if (addr > len) {
 -              unsigned long tmp_addr = align_addr(addr - len, filp,
 -                                                  ALIGN_TOPDOWN);
 -
 -              vma = find_vma(mm, tmp_addr);
 -              if (!vma || tmp_addr + len <= vma->vm_start)
 -                      /* remember the address as a hint for next time */
 -                      return mm->free_area_cache = tmp_addr;
 -      }
 -
 -      if (mm->mmap_base < len)
 -              goto bottomup;
 +      start_addr = addr = mm->free_area_cache;
  
 -      addr = mm->mmap_base-len;
 +      if (addr < len)
 +              goto fail;
  
 +      addr -= len;
        do {
                addr = align_addr(addr, filp, ALIGN_TOPDOWN);
  
                addr = vma->vm_start-len;
        } while (len < vma->vm_start);
  
 +fail:
 +      /*
 +       * if hint left us with no space for the requested
 +       * mapping then try again:
 +       */
 +      if (start_addr != mm->mmap_base) {
 +              mm->free_area_cache = mm->mmap_base;
 +              mm->cached_hole_size = 0;
 +              goto try_again;
 +      }
 +
  bottomup:
        /*
         * A failed mmap() very likely causes application failure,
index e7e67cc3c14b82857438b62a85c670e1b31a874c,031cef84fe43c8596ca7ce029c5373b0a863ae08..29f9f0554f7de0244e7120ea69fec26640bf7dce
  172   i386    prctl                   sys_prctl
  173   i386    rt_sigreturn            ptregs_rt_sigreturn             stub32_rt_sigreturn
  174   i386    rt_sigaction            sys_rt_sigaction                sys32_rt_sigaction
- 175   i386    rt_sigprocmask          sys_rt_sigprocmask              sys32_rt_sigprocmask
+ 175   i386    rt_sigprocmask          sys_rt_sigprocmask
  176   i386    rt_sigpending           sys_rt_sigpending               sys32_rt_sigpending
  177   i386    rt_sigtimedwait         sys_rt_sigtimedwait             compat_sys_rt_sigtimedwait
  178   i386    rt_sigqueueinfo         sys_rt_sigqueueinfo             sys32_rt_sigqueueinfo
  279   i386    mq_timedsend            sys_mq_timedsend                compat_sys_mq_timedsend
  280   i386    mq_timedreceive         sys_mq_timedreceive             compat_sys_mq_timedreceive
  281   i386    mq_notify               sys_mq_notify                   compat_sys_mq_notify
 -282   i386    mq_getsetaddr           sys_mq_getsetattr               compat_sys_mq_getsetattr
 +282   i386    mq_getsetattr           sys_mq_getsetattr               compat_sys_mq_getsetattr
  283   i386    kexec_load              sys_kexec_load                  compat_sys_kexec_load
  284   i386    waitid                  sys_waitid                      compat_sys_waitid
  # 285 sys_setaltroot
index a944020fa8593f634b3c81ad28d26c6c1de1241b,10f9f59477db71cb9e27f4cbaa8e7ca989d06984..66e6d93598262a2877666f1d1163125207f9c89a
@@@ -250,7 -250,13 +250,7 @@@ static int __init gate_vma_init(void
        gate_vma.vm_end = FIXADDR_USER_END;
        gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
        gate_vma.vm_page_prot = __P101;
 -      /*
 -       * Make sure the vDSO gets into every core dump.
 -       * Dumping its contents makes post-mortem fully interpretable later
 -       * without matching up the same kernel and hardware config to see
 -       * what PC values meant.
 -       */
 -      gate_vma.vm_flags |= VM_ALWAYSDUMP;
 +
        return 0;
  }
  
@@@ -311,6 -317,11 +311,11 @@@ int arch_setup_additional_pages(struct 
        int ret = 0;
        bool compat;
  
+ #ifdef CONFIG_X86_X32_ABI
+       if (test_thread_flag(TIF_X32))
+               return x32_setup_additional_pages(bprm, uses_interp);
+ #endif
        if (vdso_enabled == VDSO_DISABLED)
                return 0;
  
        if (compat_uses_vma || !compat) {
                /*
                 * MAYWRITE to allow gdb to COW and set breakpoints
 -               *
 -               * Make sure the vDSO gets into every core dump.
 -               * Dumping its contents makes post-mortem fully
 -               * interpretable later without matching up the same
 -               * kernel and hardware config to see what PC values
 -               * meant.
                 */
                ret = install_special_mapping(mm, addr, PAGE_SIZE,
                                              VM_READ|VM_EXEC|
 -                                            VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
 -                                            VM_ALWAYSDUMP,
 +                                            VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                              vdso32_pages);
  
                if (ret)
diff --combined arch/x86/vdso/vma.c
index 17e18279649f7029d7c2b10881ad155e6a022e00,d7dce1dbf8c90a118d026bb294c20b35c0347aa2..00aaf047b39f9ac948e0fdd3ccdbf1e4d80e9fb7
@@@ -24,7 -24,44 +24,44 @@@ extern unsigned short vdso_sync_cpuid
  extern struct page *vdso_pages[];
  static unsigned vdso_size;
  
- static void __init patch_vdso(void *vdso, size_t len)
+ #ifdef CONFIG_X86_X32_ABI
+ extern char vdsox32_start[], vdsox32_end[];
+ extern struct page *vdsox32_pages[];
+ static unsigned vdsox32_size;
+ static void __init patch_vdsox32(void *vdso, size_t len)
+ {
+       Elf32_Ehdr *hdr = vdso;
+       Elf32_Shdr *sechdrs, *alt_sec = 0;
+       char *secstrings;
+       void *alt_data;
+       int i;
+       BUG_ON(len < sizeof(Elf32_Ehdr));
+       BUG_ON(memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0);
+       sechdrs = (void *)hdr + hdr->e_shoff;
+       secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+       for (i = 1; i < hdr->e_shnum; i++) {
+               Elf32_Shdr *shdr = &sechdrs[i];
+               if (!strcmp(secstrings + shdr->sh_name, ".altinstructions")) {
+                       alt_sec = shdr;
+                       goto found;
+               }
+       }
+       /* If we get here, it's probably a bug. */
+       pr_warning("patch_vdsox32: .altinstructions not found\n");
+       return;  /* nothing to patch */
+ found:
+       alt_data = (void *)hdr + alt_sec->sh_offset;
+       apply_alternatives(alt_data, alt_data + alt_sec->sh_size);
+ }
+ #endif
+ static void __init patch_vdso64(void *vdso, size_t len)
  {
        Elf64_Ehdr *hdr = vdso;
        Elf64_Shdr *sechdrs, *alt_sec = 0;
@@@ -47,7 -84,7 +84,7 @@@
        }
  
        /* If we get here, it's probably a bug. */
-       pr_warning("patch_vdso: .altinstructions not found\n");
+       pr_warning("patch_vdso64: .altinstructions not found\n");
        return;  /* nothing to patch */
  
  found:
@@@ -60,12 -97,20 +97,20 @@@ static int __init init_vdso(void
        int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE;
        int i;
  
-       patch_vdso(vdso_start, vdso_end - vdso_start);
+       patch_vdso64(vdso_start, vdso_end - vdso_start);
  
        vdso_size = npages << PAGE_SHIFT;
        for (i = 0; i < npages; i++)
                vdso_pages[i] = virt_to_page(vdso_start + i*PAGE_SIZE);
  
+ #ifdef CONFIG_X86_X32_ABI
+       patch_vdsox32(vdsox32_start, vdsox32_end - vdsox32_start);
+       npages = (vdsox32_end - vdsox32_start + PAGE_SIZE - 1) / PAGE_SIZE;
+       vdsox32_size = npages << PAGE_SHIFT;
+       for (i = 0; i < npages; i++)
+               vdsox32_pages[i] = virt_to_page(vdsox32_start + i*PAGE_SIZE);
+ #endif
        return 0;
  }
  subsys_initcall(init_vdso);
@@@ -103,7 -148,10 +148,10 @@@ static unsigned long vdso_addr(unsigne
  
  /* Setup a VMA at program startup for the vsyscall page.
     Not called for compat tasks */
- int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ static int setup_additional_pages(struct linux_binprm *bprm,
+                                 int uses_interp,
+                                 struct page **pages,
+                                 unsigned size)
  {
        struct mm_struct *mm = current->mm;
        unsigned long addr;
                return 0;
  
        down_write(&mm->mmap_sem);
-       addr = vdso_addr(mm->start_stack, vdso_size);
-       addr = get_unmapped_area(NULL, addr, vdso_size, 0, 0);
+       addr = vdso_addr(mm->start_stack, size);
+       addr = get_unmapped_area(NULL, addr, size, 0, 0);
        if (IS_ERR_VALUE(addr)) {
                ret = addr;
                goto up_fail;
  
        current->mm->context.vdso = (void *)addr;
  
-       ret = install_special_mapping(mm, addr, vdso_size,
+       ret = install_special_mapping(mm, addr, size,
                                      VM_READ|VM_EXEC|
 -                                    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
 -                                    VM_ALWAYSDUMP,
 +                                    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-                                     vdso_pages);
+                                     pages);
        if (ret) {
                current->mm->context.vdso = NULL;
                goto up_fail;
@@@ -136,6 -185,20 +184,20 @@@ up_fail
        return ret;
  }
  
+ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+       return setup_additional_pages(bprm, uses_interp, vdso_pages,
+                                     vdso_size);
+ }
+ #ifdef CONFIG_X86_X32_ABI
+ int x32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+       return setup_additional_pages(bprm, uses_interp, vdsox32_pages,
+                                     vdsox32_size);
+ }
+ #endif
  static __init int vdso_setup(char *s)
  {
        vdso_enabled = simple_strtoul(s, NULL, 0);
diff --combined drivers/char/lp.c
index 0fbf1a776b521024c1dd45c39ac56bfa306b40e4,a27097173b3ac1f4e9f2990fe8893c3514dbfecf..a741e418b456d2fe966fda9b7175fc67d35c221c
  
  #include <asm/irq.h>
  #include <asm/uaccess.h>
 -#include <asm/system.h>
  
  /* if you have more than 8 printers, remember to increase LP_NO */
  #define LP_NO 8
@@@ -705,16 -706,13 +705,13 @@@ static long lp_compat_ioctl(struct fil
  {
        unsigned int minor;
        struct timeval par_timeout;
-       struct compat_timeval __user *tc;
        int ret;
  
        minor = iminor(file->f_path.dentry->d_inode);
        mutex_lock(&lp_mutex);
        switch (cmd) {
        case LPSETTIMEOUT:
-               tc = compat_ptr(arg);
-               if (get_user(par_timeout.tv_sec, &tc->tv_sec) ||
-                   get_user(par_timeout.tv_usec, &tc->tv_usec)) {
+               if (compat_get_timeval(&par_timeout, compat_ptr(arg))) {
                        ret = -EFAULT;
                        break;
                }
index 59e095362c81cd1ddfed2d5087bc5048a09a2b15,9446f0185f5e8335a486ea37cdf92c61b969e23a..c2832124bb3e7ade105ef66d82471d2d509d2110
@@@ -38,7 -38,6 +38,7 @@@
  
  static DEFINE_MUTEX(binder_lock);
  static DEFINE_MUTEX(binder_deferred_lock);
 +static DEFINE_MUTEX(binder_mmap_lock);
  
  static HLIST_HEAD(binder_procs);
  static HLIST_HEAD(binder_deferred_list);
@@@ -103,7 -102,7 +103,7 @@@ static uint32_t binder_debug_mask = BIN
        BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
  module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
  
 -static int binder_debug_no_lock;
 +static bool binder_debug_no_lock;
  module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
  
  static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
@@@ -258,7 -257,7 +258,7 @@@ struct binder_ref 
  };
  
  struct binder_buffer {
 -      struct list_head entry; /* free and allocated entries by addesss */
 +      struct list_head entry; /* free and allocated entries by address */
        struct rb_node rb_node; /* free entry by size or allocated entry */
                                /* by address */
        unsigned free:1;
@@@ -288,7 -287,6 +288,7 @@@ struct binder_proc 
        struct rb_root refs_by_node;
        int pid;
        struct vm_area_struct *vma;
 +      struct mm_struct *vma_vm_mm;
        struct task_struct *tsk;
        struct files_struct *files;
        struct hlist_node deferred_work_node;
@@@ -381,8 -379,7 +381,7 @@@ int task_get_unused_fd_flags(struct bin
  
  repeat:
        fdt = files_fdtable(files);
-       fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds,
-                               files->next_fd);
+       fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, files->next_fd);
  
        /*
         * N.B. For clone tasks sharing a files structure, this test
                goto repeat;
        }
  
-       FD_SET(fd, fdt->open_fds);
+       __set_open_fd(fd, fdt);
        if (flags & O_CLOEXEC)
-               FD_SET(fd, fdt->close_on_exec);
+               __set_close_on_exec(fd, fdt);
        else
-               FD_CLR(fd, fdt->close_on_exec);
+               __clear_close_on_exec(fd, fdt);
        files->next_fd = fd + 1;
  #if 1
        /* Sanity check */
@@@ -455,7 -452,7 +454,7 @@@ static void task_fd_install
  static void __put_unused_fd(struct files_struct *files, unsigned int fd)
  {
        struct fdtable *fdt = files_fdtable(files);
-       __FD_CLR(fd, fdt->open_fds);
+       __clear_open_fd(fd, fdt);
        if (fd < files->next_fd)
                files->next_fd = fd;
  }
@@@ -481,7 -478,7 +480,7 @@@ static long task_close_fd(struct binder
        if (!filp)
                goto out_unlock;
        rcu_assign_pointer(fdt->fd[fd], NULL);
-       FD_CLR(fd, fdt->close_on_exec);
+       __clear_close_on_exec(fd, fdt);
        __put_unused_fd(files, fd);
        spin_unlock(&files->file_lock);
        retval = filp_close(filp, files);
@@@ -634,11 -631,6 +633,11 @@@ static int binder_update_page_range(str
        if (mm) {
                down_write(&mm->mmap_sem);
                vma = proc->vma;
 +              if (vma && mm != proc->vma_vm_mm) {
 +                      pr_err("binder: %d: vma mm and task mm mismatch\n",
 +                              proc->pid);
 +                      vma = NULL;
 +              }
        }
  
        if (allocate == 0)
@@@ -2766,6 -2758,7 +2765,6 @@@ static void binder_vma_open(struct vm_a
                     proc->pid, vma->vm_start, vma->vm_end,
                     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
                     (unsigned long)pgprot_val(vma->vm_page_prot));
 -      dump_stack();
  }
  
  static void binder_vma_close(struct vm_area_struct *vma)
                     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
                     (unsigned long)pgprot_val(vma->vm_page_prot));
        proc->vma = NULL;
 +      proc->vma_vm_mm = NULL;
        binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
  }
  
@@@ -2810,7 -2802,6 +2809,7 @@@ static int binder_mmap(struct file *fil
        }
        vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
  
 +      mutex_lock(&binder_mmap_lock);
        if (proc->buffer) {
                ret = -EBUSY;
                failure_string = "already mapped";
        }
        proc->buffer = area->addr;
        proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
 +      mutex_unlock(&binder_mmap_lock);
  
  #ifdef CONFIG_CPU_CACHE_VIPT
        if (cache_is_vipt_aliasing()) {
        binder_insert_free_buffer(proc, buffer);
        proc->free_async_space = proc->buffer_size / 2;
        barrier();
 -      proc->files = get_files_struct(current);
 +      proc->files = get_files_struct(proc->tsk);
        proc->vma = vma;
 +      proc->vma_vm_mm = vma->vm_mm;
  
        /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
                 proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
@@@ -2870,12 -2859,10 +2869,12 @@@ err_alloc_small_buf_failed
        kfree(proc->pages);
        proc->pages = NULL;
  err_alloc_pages_failed:
 +      mutex_lock(&binder_mmap_lock);
        vfree(proc->buffer);
        proc->buffer = NULL;
  err_get_vm_area_failed:
  err_already_mapped:
 +      mutex_unlock(&binder_mmap_lock);
  err_bad_arg:
        printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
               proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
diff --combined fs/autofs4/dev-ioctl.c
index 85f1fcdb30e75b4ad2da3d2dd8c1286664b6a3dd,3dfd615afb6b5442c0685392fdafb0adbf902343..9dacb858670107bab207d4378e77d79dd3f25605
@@@ -230,7 -230,7 +230,7 @@@ static void autofs_dev_ioctl_fd_install
        fdt = files_fdtable(files);
        BUG_ON(fdt->fd[fd] != NULL);
        rcu_assign_pointer(fdt->fd[fd], file);
-       FD_SET(fd, fdt->close_on_exec);
+       __set_close_on_exec(fd, fdt);
        spin_unlock(&files->file_lock);
  }
  
@@@ -385,7 -385,6 +385,7 @@@ static int autofs_dev_ioctl_setpipefd(s
                sbi->pipefd = pipefd;
                sbi->pipe = pipe;
                sbi->catatonic = 0;
 +              sbi->compat_daemon = is_compat_task();
        }
  out:
        mutex_unlock(&sbi->wq_mutex);
diff --combined fs/binfmt_elf.c
index 7d7ff206cdcba2b8c2b73c4831d864aa41c0cbcd,43ba478c3386ba302c59731087b0765c510680ba..48ffb3dc610a7c9d6ea4428dd441666b4605b2c4
@@@ -35,7 -35,6 +35,7 @@@
  #include <asm/uaccess.h>
  #include <asm/param.h>
  #include <asm/page.h>
 +#include <asm/exec.h>
  
  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
  static int load_elf_library(struct file *);
@@@ -713,6 -712,7 +713,6 @@@ static int load_elf_binary(struct linux
                goto out_free_dentry;
  
        /* OK, This is the point of no return */
 -      current->flags &= ~PF_FORKNOEXEC;
        current->mm->def_flags = def_flags;
  
        /* Do this immediately, since STACK_TOP as used in setup_arg_pages
  #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
  
        install_exec_creds(bprm);
 -      current->flags &= ~PF_FORKNOEXEC;
        retval = create_elf_tables(bprm, &loc->elf_ex,
                          load_addr, interp_load_addr);
        if (retval < 0) {
   * Jeremy Fitzhardinge <jeremy@sw.oz.au>
   */
  
 +/*
 + * The purpose of always_dump_vma() is to make sure that special kernel mappings
 + * that are useful for post-mortem analysis are included in every core dump.
 + * In that way we ensure that the core dump is fully interpretable later
 + * without matching up the same kernel and hardware config to see what PC values
 + * meant. These special mappings include - vDSO, vsyscall, and other
 + * architecture specific mappings
 + */
 +static bool always_dump_vma(struct vm_area_struct *vma)
 +{
 +      /* Any vsyscall mappings? */
 +      if (vma == get_gate_vma(vma->vm_mm))
 +              return true;
 +      /*
 +       * arch_vma_name() returns non-NULL for special architecture mappings,
 +       * such as vDSO sections.
 +       */
 +      if (arch_vma_name(vma))
 +              return true;
 +
 +      return false;
 +}
 +
  /*
   * Decide what to dump of a segment, part, all or none.
   */
@@@ -1124,13 -1102,10 +1124,13 @@@ static unsigned long vma_dump_size(stru
  {
  #define FILTER(type)  (mm_flags & (1UL << MMF_DUMP_##type))
  
 -      /* The vma can be set up to tell us the answer directly.  */
 -      if (vma->vm_flags & VM_ALWAYSDUMP)
 +      /* always dump the vdso and vsyscall sections */
 +      if (always_dump_vma(vma))
                goto whole;
  
 +      if (vma->vm_flags & VM_NODUMP)
 +              return 0;
 +
        /* Hugetlb memory check */
        if (vma->vm_flags & VM_HUGETLB) {
                if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
@@@ -1415,6 -1390,22 +1415,22 @@@ static void do_thread_regset_writeback(
                regset->writeback(task, regset, 1);
  }
  
+ #ifndef PR_REG_SIZE
+ #define PR_REG_SIZE(S) sizeof(S)
+ #endif
+ #ifndef PRSTATUS_SIZE
+ #define PRSTATUS_SIZE(S) sizeof(S)
+ #endif
+ #ifndef PR_REG_PTR
+ #define PR_REG_PTR(S) (&((S)->pr_reg))
+ #endif
+ #ifndef SET_PR_FPVALID
+ #define SET_PR_FPVALID(S, V) ((S)->pr_fpvalid = (V))
+ #endif
  static int fill_thread_core_info(struct elf_thread_core_info *t,
                                 const struct user_regset_view *view,
                                 long signr, size_t *total)
         */
        fill_prstatus(&t->prstatus, t->task, signr);
        (void) view->regsets[0].get(t->task, &view->regsets[0],
-                                   0, sizeof(t->prstatus.pr_reg),
-                                   &t->prstatus.pr_reg, NULL);
+                                   0, PR_REG_SIZE(t->prstatus.pr_reg),
+                                   PR_REG_PTR(&t->prstatus), NULL);
  
        fill_note(&t->notes[0], "CORE", NT_PRSTATUS,
-                 sizeof(t->prstatus), &t->prstatus);
+                 PRSTATUS_SIZE(t->prstatus), &t->prstatus);
        *total += notesize(&t->notes[0]);
  
        do_thread_regset_writeback(t->task, &view->regsets[0]);
        for (i = 1; i < view->n; ++i) {
                const struct user_regset *regset = &view->regsets[i];
                do_thread_regset_writeback(t->task, regset);
 -              if (regset->core_note_type &&
 +              if (regset->core_note_type && regset->get &&
                    (!regset->active || regset->active(t->task, regset))) {
                        int ret;
                        size_t size = regset->n * regset->size;
                                                  regset->core_note_type,
                                                  size, data);
                                else {
-                                       t->prstatus.pr_fpvalid = 1;
+                                       SET_PR_FPVALID(&t->prstatus, 1);
                                        fill_note(&t->notes[i], "CORE",
                                                  NT_PRFPREG, size, data);
                                }
@@@ -2102,8 -2093,7 +2118,8 @@@ out
  
  static int __init init_elf_binfmt(void)
  {
 -      return register_binfmt(&elf_format);
 +      register_binfmt(&elf_format);
 +      return 0;
  }
  
  static void __exit exit_elf_binfmt(void)
diff --combined fs/compat.c
index 14483a715bbb304e988a10afb41b7decc3cd63ad,83d751c788854afbc155f7c5a8ece756c29a2a81..f2944ace7a7b4a06a29880ed8c55cdd2cccb1ada
@@@ -33,6 -33,7 +33,6 @@@
  #include <linux/nfs4_mount.h>
  #include <linux/syscalls.h>
  #include <linux/ctype.h>
 -#include <linux/module.h>
  #include <linux/dirent.h>
  #include <linux/fsnotify.h>
  #include <linux/highuid.h>
@@@ -130,35 -131,41 +130,35 @@@ asmlinkage long compat_sys_utimes(cons
  
  static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
  {
 -      compat_ino_t ino = stat->ino;
 -      typeof(ubuf->st_uid) uid = 0;
 -      typeof(ubuf->st_gid) gid = 0;
 -      int err;
 +      struct compat_stat tmp;
  
 -      SET_UID(uid, stat->uid);
 -      SET_GID(gid, stat->gid);
 +      if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
 +              return -EOVERFLOW;
  
 -      if ((u64) stat->size > MAX_NON_LFS ||
 -          !old_valid_dev(stat->dev) ||
 -          !old_valid_dev(stat->rdev))
 +      memset(&tmp, 0, sizeof(tmp));
 +      tmp.st_dev = old_encode_dev(stat->dev);
 +      tmp.st_ino = stat->ino;
 +      if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
                return -EOVERFLOW;
 -      if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
 +      tmp.st_mode = stat->mode;
 +      tmp.st_nlink = stat->nlink;
 +      if (tmp.st_nlink != stat->nlink)
                return -EOVERFLOW;
 -
 -      if (clear_user(ubuf, sizeof(*ubuf)))
 -              return -EFAULT;
 -
 -      err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
 -      err |= __put_user(ino, &ubuf->st_ino);
 -      err |= __put_user(stat->mode, &ubuf->st_mode);
 -      err |= __put_user(stat->nlink, &ubuf->st_nlink);
 -      err |= __put_user(uid, &ubuf->st_uid);
 -      err |= __put_user(gid, &ubuf->st_gid);
 -      err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
 -      err |= __put_user(stat->size, &ubuf->st_size);
 -      err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
 -      err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
 -      err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
 -      err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
 -      err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
 -      err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
 -      err |= __put_user(stat->blksize, &ubuf->st_blksize);
 -      err |= __put_user(stat->blocks, &ubuf->st_blocks);
 -      return err;
 +      SET_UID(tmp.st_uid, stat->uid);
 +      SET_GID(tmp.st_gid, stat->gid);
 +      tmp.st_rdev = old_encode_dev(stat->rdev);
 +      if ((u64) stat->size > MAX_NON_LFS)
 +              return -EOVERFLOW;
 +      tmp.st_size = stat->size;
 +      tmp.st_atime = stat->atime.tv_sec;
 +      tmp.st_atime_nsec = stat->atime.tv_nsec;
 +      tmp.st_mtime = stat->mtime.tv_sec;
 +      tmp.st_mtime_nsec = stat->mtime.tv_nsec;
 +      tmp.st_ctime = stat->ctime.tv_sec;
 +      tmp.st_ctime_nsec = stat->ctime.tv_nsec;
 +      tmp.st_blocks = stat->blocks;
 +      tmp.st_blksize = stat->blksize;
 +      return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
  }
  
  asmlinkage long compat_sys_newstat(const char __user * filename,
@@@ -1170,10 -1177,9 +1170,9 @@@ compat_sys_readv(unsigned long fd, cons
  }
  
  asmlinkage ssize_t
- compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
-                 unsigned long vlen, u32 pos_low, u32 pos_high)
+ compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
+                   unsigned long vlen, loff_t pos)
  {
-       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
        struct file *file;
        int fput_needed;
        ssize_t ret;
        return ret;
  }
  
+ asmlinkage ssize_t
+ compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
+                 unsigned long vlen, u32 pos_low, u32 pos_high)
+ {
+       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+       return compat_sys_preadv64(fd, vec, vlen, pos);
+ }
  static size_t compat_writev(struct file *file,
                            const struct compat_iovec __user *vec,
                            unsigned long vlen, loff_t *pos)
@@@ -1229,10 -1243,9 +1236,9 @@@ compat_sys_writev(unsigned long fd, con
  }
  
  asmlinkage ssize_t
- compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
-                  unsigned long vlen, u32 pos_low, u32 pos_high)
+ compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
+                    unsigned long vlen, loff_t pos)
  {
-       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
        struct file *file;
        int fput_needed;
        ssize_t ret;
        return ret;
  }
  
+ asmlinkage ssize_t
+ compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
+                  unsigned long vlen, u32 pos_low, u32 pos_high)
+ {
+       loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+       return compat_sys_pwritev64(fd, vec, vlen, pos);
+ }
  asmlinkage long
  compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
                    unsigned int nr_segs, unsigned int flags)
diff --combined fs/exec.c
index c8b63d14da8540040545e458bf32188655050310,cfd5e3047bd8ab93fb10b1e47e14ef438c867992..9a1d9f0a60abf77a55df5bef051047a23ef853d0
+++ 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 <trace/events/sched.h>
 +
  int core_uses_pid;
  char core_pattern[CORENAME_MAX_SIZE] = "core";
  unsigned int core_pipe_limit;
@@@ -82,13 -79,15 +82,13 @@@ static atomic_t call_count = ATOMIC_INI
  static LIST_HEAD(formats);
  static DEFINE_RWLOCK(binfmt_lock);
  
 -int __register_binfmt(struct linux_binfmt * fmt, int insert)
 +void __register_binfmt(struct linux_binfmt * fmt, int insert)
  {
 -      if (!fmt)
 -              return -EINVAL;
 +      BUG_ON(!fmt);
        write_lock(&binfmt_lock);
        insert ? list_add(&fmt->lh, &formats) :
                 list_add_tail(&fmt->lh, &formats);
        write_unlock(&binfmt_lock);
 -      return 0;       
  }
  
  EXPORT_SYMBOL(__register_binfmt);
@@@ -823,7 -822,7 +823,7 @@@ static int exec_mmap(struct mm_struct *
        /* Notify parent that we're no longer interested in the old VM */
        tsk = current;
        old_mm = current->mm;
 -      sync_mm_rss(tsk, old_mm);
 +      sync_mm_rss(old_mm);
        mm_release(tsk, old_mm);
  
        if (old_mm) {
        if (old_mm) {
                up_read(&old_mm->mmap_sem);
                BUG_ON(active_mm != old_mm);
 +              setmax_mm_hiwater_rss(&tsk->signal->maxrss, old_mm);
                mm_update_next_owner(old_mm);
                mmput(old_mm);
                return 0;
@@@ -977,8 -975,8 +977,8 @@@ static int de_thread(struct task_struc
        sig->notify_count = 0;
  
  no_thread_group:
 -      if (current->mm)
 -              setmax_mm_hiwater_rss(&sig->maxrss, current->mm);
 +      /* we have changed execution domain */
 +      tsk->exit_signal = SIGCHLD;
  
        exit_itimers(sig);
        flush_itimer_signals();
@@@ -1028,10 -1026,10 +1028,10 @@@ static void flush_old_files(struct file
                fdt = files_fdtable(files);
                if (i >= fdt->max_fds)
                        break;
-               set = fdt->close_on_exec->fds_bits[j];
+               set = fdt->close_on_exec[j];
                if (!set)
                        continue;
-               fdt->close_on_exec->fds_bits[j] = 0;
+               fdt->close_on_exec[j] = 0;
                spin_unlock(&files->file_lock);
                for ( ; set ; i++,set >>= 1) {
                        if (set & 1) {
@@@ -1114,7 -1112,7 +1114,7 @@@ int flush_old_exec(struct linux_binprm 
        bprm->mm = NULL;                /* We're using it now */
  
        set_fs(USER_DS);
 -      current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD);
 +      current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD);
        flush_thread();
        current->personality &= ~bprm->per_clear;
  
@@@ -1341,13 -1339,13 +1341,13 @@@ int remove_arg_zero(struct linux_binpr
                        ret = -EFAULT;
                        goto out;
                }
 -              kaddr = kmap_atomic(page, KM_USER0);
 +              kaddr = kmap_atomic(page);
  
                for (; offset < PAGE_SIZE && kaddr[offset];
                                offset++, bprm->p++)
                        ;
  
 -              kunmap_atomic(kaddr, KM_USER0);
 +              kunmap_atomic(kaddr);
                put_arg_page(page);
  
                if (offset == PAGE_SIZE)
@@@ -1404,10 -1402,9 +1404,10 @@@ int search_binary_handler(struct linux_
                         */
                        bprm->recursion_depth = depth;
                        if (retval >= 0) {
 -                              if (depth == 0)
 -                                      ptrace_event(PTRACE_EVENT_EXEC,
 -                                                      old_pid);
 +                              if (depth == 0) {
 +                                      trace_sched_process_exec(current, old_pid, bprm);
 +                                      ptrace_event(PTRACE_EVENT_EXEC, old_pid);
 +                              }
                                put_binfmt(fmt);
                                allow_write_access(bprm->file);
                                if (bprm->file)
@@@ -1918,6 -1915,7 +1918,6 @@@ static int coredump_wait(int exit_code
  {
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
 -      struct completion *vfork_done;
        int core_waiters = -EBUSY;
  
        init_completion(&core_state->startup);
                core_waiters = zap_threads(tsk, mm, core_state, exit_code);
        up_write(&mm->mmap_sem);
  
 -      if (unlikely(core_waiters < 0))
 -              goto fail;
 -
 -      /*
 -       * Make sure nobody is waiting for us to release the VM,
 -       * otherwise we can deadlock when we wait on each other
 -       */
 -      vfork_done = tsk->vfork_done;
 -      if (vfork_done) {
 -              tsk->vfork_done = NULL;
 -              complete(vfork_done);
 -      }
 -
 -      if (core_waiters)
 +      if (core_waiters > 0)
                wait_for_completion(&core_state->startup);
 -fail:
 +
        return core_waiters;
  }
  
@@@ -2067,8 -2078,8 +2067,8 @@@ static int umh_pipe_setup(struct subpro
        fd_install(0, rp);
        spin_lock(&cf->file_lock);
        fdt = files_fdtable(cf);
-       FD_SET(0, fdt->open_fds);
-       FD_CLR(0, fdt->close_on_exec);
+       __set_open_fd(0, fdt);
+       __clear_close_on_exec(0, fdt);
        spin_unlock(&cf->file_lock);
  
        /* and disallow core files too */
diff --combined fs/file.c
index 3c426de7203a831ba3e107b10eac1a8f8849b72d,171f6b41b4cdf94310eccaeb87781ef36663e0be..ba3f6053025cf44915ebd5ca42605d3281429d33
+++ b/fs/file.c
@@@ -6,7 -6,7 +6,7 @@@
   *  Manage the dynamic fd arrays in the process files_struct.
   */
  
 -#include <linux/module.h>
 +#include <linux/export.h>
  #include <linux/fs.h>
  #include <linux/mm.h>
  #include <linux/mmzone.h>
@@@ -40,7 -40,7 +40,7 @@@ int sysctl_nr_open_max = 1024 * 1024; /
   */
  static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list);
  
- static void *alloc_fdmem(unsigned int size)
+ static void *alloc_fdmem(size_t size)
  {
        /*
         * Very large allocations can stress page reclaim, so fall back to
@@@ -142,7 -142,7 +142,7 @@@ static void copy_fdtable(struct fdtabl
  static struct fdtable * alloc_fdtable(unsigned int nr)
  {
        struct fdtable *fdt;
-       char *data;
+       void *data;
  
        /*
         * Figure out how many fds we actually want to support in this fdtable.
        data = alloc_fdmem(nr * sizeof(struct file *));
        if (!data)
                goto out_fdt;
-       fdt->fd = (struct file **)data;
-       data = alloc_fdmem(max_t(unsigned int,
+       fdt->fd = data;
+       data = alloc_fdmem(max_t(size_t,
                                 2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES));
        if (!data)
                goto out_arr;
-       fdt->open_fds = (fd_set *)data;
+       fdt->open_fds = data;
        data += nr / BITS_PER_BYTE;
-       fdt->close_on_exec = (fd_set *)data;
+       fdt->close_on_exec = data;
        fdt->next = NULL;
  
        return fdt;
@@@ -275,11 -276,11 +276,11 @@@ static int count_open_files(struct fdta
        int i;
  
        /* Find the last open fd */
-       for (i = size/(8*sizeof(long)); i > 0; ) {
-               if (fdt->open_fds->fds_bits[--i])
+       for (i = size / BITS_PER_LONG; i > 0; ) {
+               if (fdt->open_fds[--i])
                        break;
        }
-       i = (i+1) * 8 * sizeof(long);
+       i = (i + 1) * BITS_PER_LONG;
        return i;
  }
  
@@@ -306,8 -307,8 +307,8 @@@ struct files_struct *dup_fd(struct file
        newf->next_fd = 0;
        new_fdt = &newf->fdtab;
        new_fdt->max_fds = NR_OPEN_DEFAULT;
-       new_fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
-       new_fdt->open_fds = (fd_set *)&newf->open_fds_init;
+       new_fdt->close_on_exec = newf->close_on_exec_init;
+       new_fdt->open_fds = newf->open_fds_init;
        new_fdt->fd = &newf->fd_array[0];
        new_fdt->next = NULL;
  
        old_fds = old_fdt->fd;
        new_fds = new_fdt->fd;
  
-       memcpy(new_fdt->open_fds->fds_bits,
-               old_fdt->open_fds->fds_bits, open_files/8);
-       memcpy(new_fdt->close_on_exec->fds_bits,
-               old_fdt->close_on_exec->fds_bits, open_files/8);
+       memcpy(new_fdt->open_fds, old_fdt->open_fds, open_files / 8);
+       memcpy(new_fdt->close_on_exec, old_fdt->close_on_exec, open_files / 8);
  
        for (i = open_files; i != 0; i--) {
                struct file *f = *old_fds++;
                         * is partway through open().  So make sure that this
                         * fd is available to the new process.
                         */
-                       FD_CLR(open_files - i, new_fdt->open_fds);
+                       __clear_open_fd(open_files - i, new_fdt);
                }
                rcu_assign_pointer(*new_fds++, f);
        }
        memset(new_fds, 0, size);
  
        if (new_fdt->max_fds > open_files) {
-               int left = (new_fdt->max_fds-open_files)/8;
-               int start = open_files / (8 * sizeof(unsigned long));
+               int left = (new_fdt->max_fds - open_files) / 8;
+               int start = open_files / BITS_PER_LONG;
  
-               memset(&new_fdt->open_fds->fds_bits[start], 0, left);
-               memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
+               memset(&new_fdt->open_fds[start], 0, left);
+               memset(&new_fdt->close_on_exec[start], 0, left);
        }
  
        rcu_assign_pointer(newf->fdt, new_fdt);
@@@ -419,8 -418,8 +418,8 @@@ struct files_struct init_files = 
        .fdtab          = {
                .max_fds        = NR_OPEN_DEFAULT,
                .fd             = &init_files.fd_array[0],
-               .close_on_exec  = (fd_set *)&init_files.close_on_exec_init,
-               .open_fds       = (fd_set *)&init_files.open_fds_init,
+               .close_on_exec  = init_files.close_on_exec_init,
+               .open_fds       = init_files.open_fds_init,
        },
        .file_lock      = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
  };
@@@ -443,8 -442,7 +442,7 @@@ repeat
                fd = files->next_fd;
  
        if (fd < fdt->max_fds)
-               fd = find_next_zero_bit(fdt->open_fds->fds_bits,
-                                          fdt->max_fds, fd);
+               fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, fd);
  
        error = expand_files(files, fd);
        if (error < 0)
        if (start <= files->next_fd)
                files->next_fd = fd + 1;
  
-       FD_SET(fd, fdt->open_fds);
+       __set_open_fd(fd, fdt);
        if (flags & O_CLOEXEC)
-               FD_SET(fd, fdt->close_on_exec);
+               __set_close_on_exec(fd, fdt);
        else
-               FD_CLR(fd, fdt->close_on_exec);
+               __clear_close_on_exec(fd, fdt);
        error = fd;
  #if 1
        /* Sanity check */
diff --combined fs/proc/base.c
index 3b42c1418f3118871d93275848f633217419129f,db6ab4b36a0b10bf92f6de4f838b2f37708f5546..1c8b280146d7a0956dddd1f06e431f49671bd269
@@@ -1310,7 -1310,8 +1310,7 @@@ sched_autogroup_write(struct file *file
        if (!p)
                return -ESRCH;
  
 -      err = nice;
 -      err = proc_sched_autogroup_set_nice(p, &err);
 +      err = proc_sched_autogroup_set_nice(p, nice);
        if (err)
                count = err;
  
@@@ -1753,7 -1754,7 +1753,7 @@@ static int proc_fd_info(struct inode *i
  
                        fdt = files_fdtable(files);
                        f_flags = file->f_flags & ~O_CLOEXEC;
-                       if (FD_ISSET(fd, fdt->close_on_exec))
+                       if (close_on_exec(fd, fdt))
                                f_flags |= O_CLOEXEC;
  
                        if (path) {
@@@ -2989,9 -2990,9 +2989,9 @@@ static const struct pid_entry tgid_base
        INF("cmdline",    S_IRUGO, proc_pid_cmdline),
        ONE("stat",       S_IRUGO, proc_tgid_stat),
        ONE("statm",      S_IRUGO, proc_pid_statm),
 -      REG("maps",       S_IRUGO, proc_maps_operations),
 +      REG("maps",       S_IRUGO, proc_pid_maps_operations),
  #ifdef CONFIG_NUMA
 -      REG("numa_maps",  S_IRUGO, proc_numa_maps_operations),
 +      REG("numa_maps",  S_IRUGO, proc_pid_numa_maps_operations),
  #endif
        REG("mem",        S_IRUSR|S_IWUSR, proc_mem_operations),
        LNK("cwd",        proc_cwd_link),
        REG("mountstats", S_IRUSR, proc_mountstats_operations),
  #ifdef CONFIG_PROC_PAGE_MONITOR
        REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
 -      REG("smaps",      S_IRUGO, proc_smaps_operations),
 +      REG("smaps",      S_IRUGO, proc_pid_smaps_operations),
        REG("pagemap",    S_IRUGO, proc_pagemap_operations),
  #endif
  #ifdef CONFIG_SECURITY
@@@ -3348,9 -3349,9 +3348,9 @@@ static const struct pid_entry tid_base_
        INF("cmdline",   S_IRUGO, proc_pid_cmdline),
        ONE("stat",      S_IRUGO, proc_tid_stat),
        ONE("statm",     S_IRUGO, proc_pid_statm),
 -      REG("maps",      S_IRUGO, proc_maps_operations),
 +      REG("maps",      S_IRUGO, proc_tid_maps_operations),
  #ifdef CONFIG_NUMA
 -      REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
 +      REG("numa_maps", S_IRUGO, proc_tid_numa_maps_operations),
  #endif
        REG("mem",       S_IRUSR|S_IWUSR, proc_mem_operations),
        LNK("cwd",       proc_cwd_link),
        REG("mountinfo",  S_IRUGO, proc_mountinfo_operations),
  #ifdef CONFIG_PROC_PAGE_MONITOR
        REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
 -      REG("smaps",     S_IRUGO, proc_smaps_operations),
 +      REG("smaps",     S_IRUGO, proc_tid_smaps_operations),
        REG("pagemap",    S_IRUGO, proc_pagemap_operations),
  #endif
  #ifdef CONFIG_SECURITY
diff --combined fs/select.c
index 6fb8943d580bb178c35b900cff675e39c72ec259,2e7fbe8a092c901cc4fb37984f7a95ad01735233..17d33d09fc16f4843c72f9c7444dfdb3fb738952
@@@ -17,7 -17,7 +17,7 @@@
  #include <linux/kernel.h>
  #include <linux/sched.h>
  #include <linux/syscalls.h>
 -#include <linux/module.h>
 +#include <linux/export.h>
  #include <linux/slab.h>
  #include <linux/poll.h>
  #include <linux/personality.h> /* for STICKY_TIMEOUTS */
@@@ -223,7 -223,7 +223,7 @@@ static void __pollwait(struct file *fil
        get_file(filp);
        entry->filp = filp;
        entry->wait_address = wait_address;
 -      entry->key = p->key;
 +      entry->key = p->_key;
        init_waitqueue_func_entry(&entry->wait, pollwake);
        entry->wait.private = pwq;
        add_wait_queue(wait_address, &entry->wait);
@@@ -348,7 -348,7 +348,7 @@@ static int max_select_fd(unsigned long 
        set = ~(~0UL << (n & (__NFDBITS-1)));
        n /= __NFDBITS;
        fdt = files_fdtable(current->files);
-       open_fds = fdt->open_fds->fds_bits+n;
+       open_fds = fdt->open_fds + n;
        max = 0;
        if (set) {
                set &= BITS(fds, n);
@@@ -386,11 -386,13 +386,11 @@@ get_max
  static inline void wait_key_set(poll_table *wait, unsigned long in,
                                unsigned long out, unsigned long bit)
  {
 -      if (wait) {
 -              wait->key = POLLEX_SET;
 -              if (in & bit)
 -                      wait->key |= POLLIN_SET;
 -              if (out & bit)
 -                      wait->key |= POLLOUT_SET;
 -      }
 +      wait->_key = POLLEX_SET;
 +      if (in & bit)
 +              wait->_key |= POLLIN_SET;
 +      if (out & bit)
 +              wait->_key |= POLLOUT_SET;
  }
  
  int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
        poll_initwait(&table);
        wait = &table.pt;
        if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
 -              wait = NULL;
 +              wait->_qproc = NULL;
                timed_out = 1;
        }
  
                                        if ((mask & POLLIN_SET) && (in & bit)) {
                                                res_in |= bit;
                                                retval++;
 -                                              wait = NULL;
 +                                              wait->_qproc = NULL;
                                        }
                                        if ((mask & POLLOUT_SET) && (out & bit)) {
                                                res_out |= bit;
                                                retval++;
 -                                              wait = NULL;
 +                                              wait->_qproc = NULL;
                                        }
                                        if ((mask & POLLEX_SET) && (ex & bit)) {
                                                res_ex |= bit;
                                                retval++;
 -                                              wait = NULL;
 +                                              wait->_qproc = NULL;
                                        }
                                }
                        }
                                *rexp = res_ex;
                        cond_resched();
                }
 -              wait = NULL;
 +              wait->_qproc = NULL;
                if (retval || timed_out || signal_pending(current))
                        break;
                if (table.error) {
@@@ -718,7 -720,7 +718,7 @@@ struct poll_list 
   * interested in events matching the pollfd->events mask, and the result
   * matching that mask is both recorded in pollfd->revents and returned. The
   * pwait poll_table will be used by the fd-provided poll handler for waiting,
 - * if non-NULL.
 + * if pwait->_qproc is non-NULL.
   */
  static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
  {
                if (file != NULL) {
                        mask = DEFAULT_POLLMASK;
                        if (file->f_op && file->f_op->poll) {
 -                              if (pwait)
 -                                      pwait->key = pollfd->events |
 -                                                      POLLERR | POLLHUP;
 +                              pwait->_key = pollfd->events|POLLERR|POLLHUP;
                                mask = file->f_op->poll(file, pwait);
                        }
                        /* Mask out unneeded events. */
@@@ -759,7 -763,7 +759,7 @@@ static int do_poll(unsigned int nfds,  
  
        /* Optimise the no-wait case */
        if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
 -              pt = NULL;
 +              pt->_qproc = NULL;
                timed_out = 1;
        }
  
                        for (; pfd != pfd_end; pfd++) {
                                /*
                                 * Fish for events. If we found one, record it
 -                               * and kill the poll_table, so we don't
 +                               * and kill poll_table->_qproc, so we don't
                                 * needlessly register any other waiters after
                                 * this. They'll get immediately deregistered
                                 * when we break out and return.
                                 */
                                if (do_pollfd(pfd, pt)) {
                                        count++;
 -                                      pt = NULL;
 +                                      pt->_qproc = NULL;
                                }
                        }
                }
                /*
                 * All waiters have already been registered, so don't provide
 -               * a poll_table to them on the next loop iteration.
 +               * a poll_table->_qproc to them on the next loop iteration.
                 */
 -              pt = NULL;
 +              pt->_qproc = NULL;
                if (!count) {
                        count = wait->error;
                        if (signal_pending(current))
@@@ -908,7 -912,7 +908,7 @@@ static long do_restart_poll(struct rest
  }
  
  SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
 -              long, timeout_msecs)
 +              int, timeout_msecs)
  {
        struct timespec end_time, *to = NULL;
        int ret;
diff --combined include/linux/Kbuild
index a2555538109733da56f3feffd523cf2cdef58ca9,8446086776656f0825f77fd1cde1c62bd1a50484..a4b5da2b83f543ff4e503d2c15fd24aa6e04881f
@@@ -238,7 -238,6 +238,7 @@@ header-y += magic.
  header-y += major.h
  header-y += map_to_7segment.h
  header-y += matroxfb.h
 +header-y += mdio.h
  header-y += media.h
  header-y += mempolicy.h
  header-y += meye.h
@@@ -305,7 -304,6 +305,7 @@@ header-y += poll.
  header-y += posix_types.h
  header-y += ppdev.h
  header-y += ppp-comp.h
 +header-y += ppp-ioctl.h
  header-y += ppp_defs.h
  header-y += pps.h
  header-y += prctl.h
@@@ -357,6 -355,7 +357,7 @@@ header-y += suspend_ioctls.
  header-y += swab.h
  header-y += synclink.h
  header-y += sysctl.h
+ header-y += sysinfo.h
  header-y += taskstats.h
  header-y += tcp.h
  header-y += telephony.h
diff --combined include/linux/compat.h
index 35c2dbf2448abe5085c8242bff22eb10698d4f62,a82e452bbdb98e114f05fcc716771e1fdfd44502..5d46217f84adfaab0dbe679a7612da7062bb72c6
  #include <asm/siginfo.h>
  #include <asm/signal.h>
  
+ #ifndef COMPAT_USE_64BIT_TIME
+ #define COMPAT_USE_64BIT_TIME 0
+ #endif
  #define compat_jiffies_to_clock_t(x)  \
                (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
  
@@@ -83,10 -87,26 +87,26 @@@ typedef struct 
        compat_sigset_word      sig[_COMPAT_NSIG_WORDS];
  } compat_sigset_t;
  
+ /*
+  * These functions operate strictly on struct compat_time*
+  */
  extern int get_compat_timespec(struct timespec *,
                               const struct compat_timespec __user *);
  extern int put_compat_timespec(const struct timespec *,
                               struct compat_timespec __user *);
+ extern int get_compat_timeval(struct timeval *,
+                             const struct compat_timeval __user *);
+ extern int put_compat_timeval(const struct timeval *,
+                             struct compat_timeval __user *);
+ /*
+  * These functions operate on 32- or 64-bit specs depending on
+  * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments and the
+  * naming as compat_get/put_ rather than get/put_compat_.
+  */
+ extern int compat_get_timespec(struct timespec *, const void __user *);
+ extern int compat_put_timespec(const struct timespec *, void __user *);
+ extern int compat_get_timeval(struct timeval *, const void __user *);
+ extern int compat_put_timeval(const struct timeval *, void __user *);
  
  struct compat_iovec {
        compat_uptr_t   iov_base;
@@@ -224,7 -244,6 +244,7 @@@ struct compat_sysinfo
  struct compat_sysctl_args;
  struct compat_kexec_segment;
  struct compat_mq_attr;
 +struct compat_msgbuf;
  
  extern void compat_exit_robust_list(struct task_struct *curr);
  
@@@ -235,22 -254,13 +255,22 @@@ asmlinkage lon
  compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
                           compat_size_t __user *len_ptr);
  
 +#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
  long compat_sys_semctl(int first, int second, int third, void __user *uptr);
  long compat_sys_msgsnd(int first, int second, int third, void __user *uptr);
  long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
                int version, void __user *uptr);
 -long compat_sys_msgctl(int first, int second, void __user *uptr);
  long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
                void __user *uptr);
 +#else
 +long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
 +long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
 +              size_t msgsz, int msgflg);
 +long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
 +              size_t msgsz, long msgtyp, int msgflg);
 +long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg);
 +#endif
 +long compat_sys_msgctl(int first, int second, void __user *uptr);
  long compat_sys_shmctl(int first, int second, void __user *uptr);
  long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
                unsigned nsems, const struct compat_timespec __user *timeout);
@@@ -571,9 -581,5 +591,9 @@@ asmlinkage ssize_t compat_sys_process_v
                unsigned long liovcnt, const struct compat_iovec __user *rvec,
                unsigned long riovcnt, unsigned long flags);
  
 +#else
 +
 +#define is_compat_task() (0)
 +
  #endif /* CONFIG_COMPAT */
  #endif /* _LINUX_COMPAT_H */
diff --combined include/linux/kernel.h
index 5db52d0ff1d44ab240de7f0892e241c0c3b0922f,dc6a50f88ca7ba1deb18fe9a47bff3dad9af1977..a5375e7f3feac423fa6325280276e17dcf5351f6
@@@ -1,6 -1,8 +1,8 @@@
  #ifndef _LINUX_KERNEL_H
  #define _LINUX_KERNEL_H
  
+ #include <linux/sysinfo.h>
  /*
   * 'kernel.h' contains some often-used function prototypes etc
   */
@@@ -20,6 -22,7 +22,6 @@@
  #include <linux/printk.h>
  #include <linux/dynamic_debug.h>
  #include <asm/byteorder.h>
 -#include <asm/bug.h>
  
  #define USHRT_MAX     ((u16)(~0U))
  #define SHRT_MAX      ((s16)(USHRT_MAX>>1))
  }                                                     \
  )
  
 +/*
 + * Multiplies an integer by a fraction, while avoiding unnecessary
 + * overflow or loss of precision.
 + */
 +#define mult_frac(x, numer, denom)(                   \
 +{                                                     \
 +      typeof(x) quot = (x) / (denom);                 \
 +      typeof(x) rem  = (x) % (denom);                 \
 +      (quot * (numer)) + ((rem * (numer)) / (denom)); \
 +}                                                     \
 +)
 +
 +
  #define _RET_IP_              (unsigned long)__builtin_return_address(0)
  #define _THIS_IP_  ({ __label__ __here; __here: (unsigned long)&&__here; })
  
@@@ -311,8 -301,6 +313,8 @@@ extern long long simple_strtoll(const c
  #define strict_strtoull       kstrtoull
  #define strict_strtoll        kstrtoll
  
 +extern int num_to_str(char *buf, int size, unsigned long long num);
 +
  /* lib/printf utilities */
  
  extern __printf(2, 3) int sprintf(char *buf, const char * fmt, ...);
@@@ -329,10 -317,10 +331,10 @@@ extern __printf(2, 3
  char *kasprintf(gfp_t gfp, const char *fmt, ...);
  extern char *kvasprintf(gfp_t gfp, const char *fmt, va_list args);
  
 -extern int sscanf(const char *, const char *, ...)
 -      __attribute__ ((format (scanf, 2, 3)));
 -extern int vsscanf(const char *, const char *, va_list)
 -      __attribute__ ((format (scanf, 2, 0)));
 +extern __scanf(2, 3)
 +int sscanf(const char *, const char *, ...);
 +extern __scanf(2, 0)
 +int vsscanf(const char *, const char *, va_list);
  
  extern int get_option(char **str, int *pint);
  extern char *get_options(const char *str, int nints, int *ints);
@@@ -676,6 -664,67 +678,6 @@@ static inline void ftrace_dump(enum ftr
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})
  
 -#ifdef __CHECKER__
 -#define BUILD_BUG_ON_NOT_POWER_OF_2(n)
 -#define BUILD_BUG_ON_ZERO(e) (0)
 -#define BUILD_BUG_ON_NULL(e) ((void*)0)
 -#define BUILD_BUG_ON(condition)
 -#define BUILD_BUG() (0)
 -#else /* __CHECKER__ */
 -
 -/* Force a compilation error if a constant expression is not a power of 2 */
 -#define BUILD_BUG_ON_NOT_POWER_OF_2(n)                        \
 -      BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
 -
 -/* Force a compilation error if condition is true, but also produce a
 -   result (of value 0 and type size_t), so the expression can be used
 -   e.g. in a structure initializer (or where-ever else comma expressions
 -   aren't permitted). */
 -#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
 -#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
 -
 -/**
 - * BUILD_BUG_ON - break compile if a condition is true.
 - * @condition: the condition which the compiler should know is false.
 - *
 - * If you have some code which relies on certain constants being equal, or
 - * other compile-time-evaluated condition, you should use BUILD_BUG_ON to
 - * detect if someone changes it.
 - *
 - * The implementation uses gcc's reluctance to create a negative array, but
 - * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
 - * to inline functions).  So as a fallback we use the optimizer; if it can't
 - * prove the condition is false, it will cause a link error on the undefined
 - * "__build_bug_on_failed".  This error message can be harder to track down
 - * though, hence the two different methods.
 - */
 -#ifndef __OPTIMIZE__
 -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 -#else
 -extern int __build_bug_on_failed;
 -#define BUILD_BUG_ON(condition)                                       \
 -      do {                                                    \
 -              ((void)sizeof(char[1 - 2*!!(condition)]));      \
 -              if (condition) __build_bug_on_failed = 1;       \
 -      } while(0)
 -#endif
 -
 -/**
 - * BUILD_BUG - break compile if used.
 - *
 - * If you have some code that you expect the compiler to eliminate at
 - * build time, you should use BUILD_BUG to detect if it is
 - * unexpectedly used.
 - */
 -#define BUILD_BUG()                                           \
 -      do {                                                    \
 -              extern void __build_bug_failed(void)            \
 -                      __linktime_error("BUILD_BUG failed");   \
 -              __build_bug_failed();                           \
 -      } while (0)
 -
 -#endif        /* __CHECKER__ */
 -
  /* Trap pasters of __FUNCTION__ at compile-time */
  #define __FUNCTION__ (__func__)
  
  # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
  #endif
  
- struct sysinfo;
  extern int do_sysinfo(struct sysinfo *info);
  
  #endif /* __KERNEL__ */
  
- #define SI_LOAD_SHIFT 16
- struct sysinfo {
-       long uptime;                    /* Seconds since boot */
-       unsigned long loads[3];         /* 1, 5, and 15 minute load averages */
-       unsigned long totalram;         /* Total usable main memory size */
-       unsigned long freeram;          /* Available memory size */
-       unsigned long sharedram;        /* Amount of shared memory */
-       unsigned long bufferram;        /* Memory used by buffers */
-       unsigned long totalswap;        /* Total swap space size */
-       unsigned long freeswap;         /* swap space still available */
-       unsigned short procs;           /* Number of current processes */
-       unsigned short pad;             /* explicit padding for m68k */
-       unsigned long totalhigh;        /* Total high memory size */
-       unsigned long freehigh;         /* Available high memory size */
-       unsigned int mem_unit;          /* Memory unit size in bytes */
-       char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
- };
  #endif
diff --combined include/linux/time.h
index 97734e9409c65e222ff56201bcc84810799f11d0,9f43487facdf99ca46d9514853d148352fa3effb..33a92ead4d88163fce7b12d236c56dfd1772d379
@@@ -116,6 -116,7 +116,6 @@@ static inline struct timespec timespec_
  extern void read_persistent_clock(struct timespec *ts);
  extern void read_boot_clock(struct timespec *ts);
  extern int update_persistent_clock(struct timespec now);
 -extern int no_sync_cmos_clock __read_mostly;
  void timekeeping_init(void);
  extern int timekeeping_suspended;
  
@@@ -255,6 -256,7 +255,7 @@@ static __always_inline void timespec_ad
        a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
        a->tv_nsec = ns;
  }
  #endif /* __KERNEL__ */
  
  #define NFDBITS                       __NFDBITS
diff --combined kernel/exit.c
index 3db1909faed9331488cecad09e10359db175a746,4db020015f14aa90c5217846924200ac51d1e172..d8bd3b425fa78413f94c9278f481672faebb999c
@@@ -52,7 -52,6 +52,7 @@@
  #include <linux/hw_breakpoint.h>
  #include <linux/oom.h>
  #include <linux/writeback.h>
 +#include <linux/shm.h>
  
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
@@@ -425,7 -424,7 +425,7 @@@ void daemonize(const char *name, ...
         */
        exit_mm(current);
        /*
 -       * We don't want to have TIF_FREEZE set if the system-wide hibernation
 +       * We don't want to get frozen, in case system-wide hibernation
         * or suspend transition begins right now.
         */
        current->flags |= (PF_NOFREEZE | PF_KTHREAD);
@@@ -474,7 -473,7 +474,7 @@@ static void close_files(struct files_st
                i = j * __NFDBITS;
                if (i >= fdt->max_fds)
                        break;
-               set = fdt->open_fds->fds_bits[j++];
+               set = fdt->open_fds[j++];
                while (set) {
                        if (set & 1) {
                                struct file * file = xchg(&fdt->fd[i], NULL);
@@@ -687,11 -686,11 +687,11 @@@ static void exit_mm(struct task_struct 
  }
  
  /*
 - * When we die, we re-parent all our children.
 - * Try to give them to another thread in our thread
 - * group, and if no such member exists, give it to
 - * the child reaper process (ie "init") in our pid
 - * space.
 + * When we die, we re-parent all our children, and try to:
 + * 1. give them to another thread in our thread group, if such a member exists
 + * 2. give it to the first ancestor process which prctl'd itself as a
 + *    child_subreaper for its children (like a service manager)
 + * 3. give it to the init process (PID 1) in our pid namespace
   */
  static struct task_struct *find_new_reaper(struct task_struct *father)
        __releases(&tasklist_lock)
  
        if (unlikely(pid_ns->child_reaper == father)) {
                write_unlock_irq(&tasklist_lock);
 -              if (unlikely(pid_ns == &init_pid_ns))
 -                      panic("Attempted to kill init!");
 +              if (unlikely(pid_ns == &init_pid_ns)) {
 +                      panic("Attempted to kill init! exitcode=0x%08x\n",
 +                              father->signal->group_exit_code ?:
 +                                      father->exit_code);
 +              }
  
                zap_pid_ns_processes(pid_ns);
                write_lock_irq(&tasklist_lock);
                 * forget_original_parent() must move them somewhere.
                 */
                pid_ns->child_reaper = init_pid_ns.child_reaper;
 +      } else if (father->signal->has_child_subreaper) {
 +              struct task_struct *reaper;
 +
 +              /*
 +               * Find the first ancestor marked as child_subreaper.
 +               * Note that the code below checks same_thread_group(reaper,
 +               * pid_ns->child_reaper).  This is what we need to DTRT in a
 +               * PID namespace. However we still need the check above, see
 +               * http://marc.info/?l=linux-kernel&m=131385460420380
 +               */
 +              for (reaper = father->real_parent;
 +                   reaper != &init_task;
 +                   reaper = reaper->real_parent) {
 +                      if (same_thread_group(reaper, pid_ns->child_reaper))
 +                              break;
 +                      if (!reaper->signal->is_child_subreaper)
 +                              continue;
 +                      thread = reaper;
 +                      do {
 +                              if (!(thread->flags & PF_EXITING))
 +                                      return reaper;
 +                      } while_each_thread(reaper, thread);
 +              }
        }
  
        return pid_ns->child_reaper;
@@@ -845,6 -818,25 +845,6 @@@ static void exit_notify(struct task_str
        if (group_dead)
                kill_orphaned_pgrp(tsk->group_leader, NULL);
  
 -      /* Let father know we died
 -       *
 -       * Thread signals are configurable, but you aren't going to use
 -       * that to send signals to arbitrary processes.
 -       * That stops right now.
 -       *
 -       * If the parent exec id doesn't match the exec id we saved
 -       * when we started then we know the parent has changed security
 -       * domain.
 -       *
 -       * If our self_exec id doesn't match our parent_exec_id then
 -       * we have changed execution domain as these two values started
 -       * the same after a fork.
 -       */
 -      if (thread_group_leader(tsk) && tsk->exit_signal != SIGCHLD &&
 -          (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
 -           tsk->self_exec_id != tsk->parent_exec_id))
 -              tsk->exit_signal = SIGCHLD;
 -
        if (unlikely(tsk->ptrace)) {
                int sig = thread_group_leader(tsk) &&
                                thread_group_empty(tsk) &&
@@@ -943,6 -935,8 +943,6 @@@ void do_exit(long code
                schedule();
        }
  
 -      exit_irq_thread();
 -
        exit_signals(tsk);  /* sets PF_EXITING */
        /*
         * tsk->flags are checked in the futex code to protect against
        smp_mb();
        raw_spin_unlock_wait(&tsk->pi_lock);
  
 +      exit_irq_thread();
 +
        if (unlikely(in_atomic()))
                printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
                                current->comm, task_pid_nr(current),
        acct_update_integrals(tsk);
        /* sync mm's RSS info before statistics gathering */
        if (tsk->mm)
 -              sync_mm_rss(tsk, tsk->mm);
 +              sync_mm_rss(tsk->mm);
        group_dead = atomic_dec_and_test(&tsk->signal->live);
        if (group_dead) {
                hrtimer_cancel(&tsk->signal->real_timer);
diff --combined net/bluetooth/hci_sock.c
index 49142612916eaaace215c5c4715c2b8798c6d157,b2eb2b93580ff56ed8d4898e8501c24451f66786..5914623f426aa835aadee48c6ec8eb8400ab7728
  #include <linux/ioctl.h>
  #include <net/sock.h>
  
 -#include <asm/system.h>
  #include <linux/uaccess.h>
  #include <asm/unaligned.h>
  
  #include <net/bluetooth/bluetooth.h>
  #include <net/bluetooth/hci_core.h>
 +#include <net/bluetooth/hci_mon.h>
  
 -static bool enable_mgmt;
 +static atomic_t monitor_promisc = ATOMIC_INIT(0);
  
  /* ----- HCI socket interface ----- */
  
@@@ -85,20 -85,22 +85,20 @@@ static struct bt_sock_list hci_sk_list 
  };
  
  /* Send frame to RAW socket */
 -void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
 -                                                      struct sock *skip_sk)
 +void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
  {
        struct sock *sk;
        struct hlist_node *node;
 +      struct sk_buff *skb_copy = NULL;
  
        BT_DBG("hdev %p len %d", hdev, skb->len);
  
        read_lock(&hci_sk_list.lock);
 +
        sk_for_each(sk, node, &hci_sk_list.head) {
                struct hci_filter *flt;
                struct sk_buff *nskb;
  
 -              if (sk == skip_sk)
 -                      continue;
 -
                if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
                        continue;
  
                if (skb->sk == sk)
                        continue;
  
 -              if (bt_cb(skb)->channel != hci_pi(sk)->channel)
 +              if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
                        continue;
  
 -              if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
 -                      goto clone;
 -
                /* Apply filter */
                flt = &hci_pi(sk)->filter;
  
                                continue;
                }
  
 -clone:
 +              if (!skb_copy) {
 +                      /* Create a private copy with headroom */
 +                      skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
 +                      if (!skb_copy)
 +                              continue;
 +
 +                      /* Put type byte before the data */
 +                      memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
 +              }
 +
 +              nskb = skb_clone(skb_copy, GFP_ATOMIC);
 +              if (!nskb)
 +                      continue;
 +
 +              if (sock_queue_rcv_skb(sk, nskb))
 +                      kfree_skb(nskb);
 +      }
 +
 +      read_unlock(&hci_sk_list.lock);
 +
 +      kfree_skb(skb_copy);
 +}
 +
 +/* Send frame to control socket */
 +void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
 +{
 +      struct sock *sk;
 +      struct hlist_node *node;
 +
 +      BT_DBG("len %d", skb->len);
 +
 +      read_lock(&hci_sk_list.lock);
 +
 +      sk_for_each(sk, node, &hci_sk_list.head) {
 +              struct sk_buff *nskb;
 +
 +              /* Skip the original socket */
 +              if (sk == skip_sk)
 +                      continue;
 +
 +              if (sk->sk_state != BT_BOUND)
 +                      continue;
 +
 +              if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
 +                      continue;
 +
                nskb = skb_clone(skb, GFP_ATOMIC);
                if (!nskb)
                        continue;
  
 -              /* Put type byte before the data */
 -              if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
 -                      memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
 +              if (sock_queue_rcv_skb(sk, nskb))
 +                      kfree_skb(nskb);
 +      }
 +
 +      read_unlock(&hci_sk_list.lock);
 +}
 +
 +/* Send frame to monitor socket */
 +void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
 +{
 +      struct sock *sk;
 +      struct hlist_node *node;
 +      struct sk_buff *skb_copy = NULL;
 +      __le16 opcode;
 +
 +      if (!atomic_read(&monitor_promisc))
 +              return;
 +
 +      BT_DBG("hdev %p len %d", hdev, skb->len);
 +
 +      switch (bt_cb(skb)->pkt_type) {
 +      case HCI_COMMAND_PKT:
 +              opcode = __constant_cpu_to_le16(HCI_MON_COMMAND_PKT);
 +              break;
 +      case HCI_EVENT_PKT:
 +              opcode = __constant_cpu_to_le16(HCI_MON_EVENT_PKT);
 +              break;
 +      case HCI_ACLDATA_PKT:
 +              if (bt_cb(skb)->incoming)
 +                      opcode = __constant_cpu_to_le16(HCI_MON_ACL_RX_PKT);
 +              else
 +                      opcode = __constant_cpu_to_le16(HCI_MON_ACL_TX_PKT);
 +              break;
 +      case HCI_SCODATA_PKT:
 +              if (bt_cb(skb)->incoming)
 +                      opcode = __constant_cpu_to_le16(HCI_MON_SCO_RX_PKT);
 +              else
 +                      opcode = __constant_cpu_to_le16(HCI_MON_SCO_TX_PKT);
 +              break;
 +      default:
 +              return;
 +      }
 +
 +      read_lock(&hci_sk_list.lock);
 +
 +      sk_for_each(sk, node, &hci_sk_list.head) {
 +              struct sk_buff *nskb;
 +
 +              if (sk->sk_state != BT_BOUND)
 +                      continue;
 +
 +              if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
 +                      continue;
 +
 +              if (!skb_copy) {
 +                      struct hci_mon_hdr *hdr;
 +
 +                      /* Create a private copy with headroom */
 +                      skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC);
 +                      if (!skb_copy)
 +                              continue;
 +
 +                      /* Put header before the data */
 +                      hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
 +                      hdr->opcode = opcode;
 +                      hdr->index = cpu_to_le16(hdev->id);
 +                      hdr->len = cpu_to_le16(skb->len);
 +              }
 +
 +              nskb = skb_clone(skb_copy, GFP_ATOMIC);
 +              if (!nskb)
 +                      continue;
 +
 +              if (sock_queue_rcv_skb(sk, nskb))
 +                      kfree_skb(nskb);
 +      }
 +
 +      read_unlock(&hci_sk_list.lock);
 +
 +      kfree_skb(skb_copy);
 +}
 +
 +static void send_monitor_event(struct sk_buff *skb)
 +{
 +      struct sock *sk;
 +      struct hlist_node *node;
 +
 +      BT_DBG("len %d", skb->len);
 +
 +      read_lock(&hci_sk_list.lock);
 +
 +      sk_for_each(sk, node, &hci_sk_list.head) {
 +              struct sk_buff *nskb;
 +
 +              if (sk->sk_state != BT_BOUND)
 +                      continue;
 +
 +              if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
 +                      continue;
 +
 +              nskb = skb_clone(skb, GFP_ATOMIC);
 +              if (!nskb)
 +                      continue;
  
                if (sock_queue_rcv_skb(sk, nskb))
                        kfree_skb(nskb);
        }
 +
        read_unlock(&hci_sk_list.lock);
  }
  
 +static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
 +{
 +      struct hci_mon_hdr *hdr;
 +      struct hci_mon_new_index *ni;
 +      struct sk_buff *skb;
 +      __le16 opcode;
 +
 +      switch (event) {
 +      case HCI_DEV_REG:
 +              skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
 +              if (!skb)
 +                      return NULL;
 +
 +              ni = (void *) skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
 +              ni->type = hdev->dev_type;
 +              ni->bus = hdev->bus;
 +              bacpy(&ni->bdaddr, &hdev->bdaddr);
 +              memcpy(ni->name, hdev->name, 8);
 +
 +              opcode = __constant_cpu_to_le16(HCI_MON_NEW_INDEX);
 +              break;
 +
 +      case HCI_DEV_UNREG:
 +              skb = bt_skb_alloc(0, GFP_ATOMIC);
 +              if (!skb)
 +                      return NULL;
 +
 +              opcode = __constant_cpu_to_le16(HCI_MON_DEL_INDEX);
 +              break;
 +
 +      default:
 +              return NULL;
 +      }
 +
 +      __net_timestamp(skb);
 +
 +      hdr = (void *) skb_push(skb, HCI_MON_HDR_SIZE);
 +      hdr->opcode = opcode;
 +      hdr->index = cpu_to_le16(hdev->id);
 +      hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
 +
 +      return skb;
 +}
 +
 +static void send_monitor_replay(struct sock *sk)
 +{
 +      struct hci_dev *hdev;
 +
 +      read_lock(&hci_dev_list_lock);
 +
 +      list_for_each_entry(hdev, &hci_dev_list, list) {
 +              struct sk_buff *skb;
 +
 +              skb = create_monitor_event(hdev, HCI_DEV_REG);
 +              if (!skb)
 +                      continue;
 +
 +              if (sock_queue_rcv_skb(sk, skb))
 +                      kfree_skb(skb);
 +      }
 +
 +      read_unlock(&hci_dev_list_lock);
 +}
 +
 +/* Generate internal stack event */
 +static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
 +{
 +      struct hci_event_hdr *hdr;
 +      struct hci_ev_stack_internal *ev;
 +      struct sk_buff *skb;
 +
 +      skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
 +      if (!skb)
 +              return;
 +
 +      hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
 +      hdr->evt  = HCI_EV_STACK_INTERNAL;
 +      hdr->plen = sizeof(*ev) + dlen;
 +
 +      ev  = (void *) skb_put(skb, sizeof(*ev) + dlen);
 +      ev->type = type;
 +      memcpy(ev->data, data, dlen);
 +
 +      bt_cb(skb)->incoming = 1;
 +      __net_timestamp(skb);
 +
 +      bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
 +      skb->dev = (void *) hdev;
 +      hci_send_to_sock(hdev, skb);
 +      kfree_skb(skb);
 +}
 +
 +void hci_sock_dev_event(struct hci_dev *hdev, int event)
 +{
 +      struct hci_ev_si_device ev;
 +
 +      BT_DBG("hdev %s event %d", hdev->name, event);
 +
 +      /* Send event to monitor */
 +      if (atomic_read(&monitor_promisc)) {
 +              struct sk_buff *skb;
 +
 +              skb = create_monitor_event(hdev, event);
 +              if (skb) {
 +                      send_monitor_event(skb);
 +                      kfree_skb(skb);
 +              }
 +      }
 +
 +      /* Send event to sockets */
 +      ev.event  = event;
 +      ev.dev_id = hdev->id;
 +      hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
 +
 +      if (event == HCI_DEV_UNREG) {
 +              struct sock *sk;
 +              struct hlist_node *node;
 +
 +              /* Detach sockets from device */
 +              read_lock(&hci_sk_list.lock);
 +              sk_for_each(sk, node, &hci_sk_list.head) {
 +                      bh_lock_sock_nested(sk);
 +                      if (hci_pi(sk)->hdev == hdev) {
 +                              hci_pi(sk)->hdev = NULL;
 +                              sk->sk_err = EPIPE;
 +                              sk->sk_state = BT_OPEN;
 +                              sk->sk_state_change(sk);
 +
 +                              hci_dev_put(hdev);
 +                      }
 +                      bh_unlock_sock(sk);
 +              }
 +              read_unlock(&hci_sk_list.lock);
 +      }
 +}
 +
  static int hci_sock_release(struct socket *sock)
  {
        struct sock *sk = sock->sk;
  
        hdev = hci_pi(sk)->hdev;
  
 +      if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
 +              atomic_dec(&monitor_promisc);
 +
        bt_sock_unlink(&hci_sk_list, sk);
  
        if (hdev) {
@@@ -470,7 -190,7 +470,7 @@@ static int hci_sock_blacklist_add(struc
  
        hci_dev_lock(hdev);
  
 -      err = hci_blacklist_add(hdev, &bdaddr);
 +      err = hci_blacklist_add(hdev, &bdaddr, 0);
  
        hci_dev_unlock(hdev);
  
@@@ -487,7 -207,7 +487,7 @@@ static int hci_sock_blacklist_del(struc
  
        hci_dev_lock(hdev);
  
 -      err = hci_blacklist_del(hdev, &bdaddr);
 +      err = hci_blacklist_del(hdev, &bdaddr, 0);
  
        hci_dev_unlock(hdev);
  
@@@ -620,69 -340,34 +620,69 @@@ static int hci_sock_bind(struct socket 
        if (haddr.hci_family != AF_BLUETOOTH)
                return -EINVAL;
  
 -      if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
 -              return -EINVAL;
 -
 -      if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
 -              if (!enable_mgmt)
 -                      return -EINVAL;
 -              set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
 -      }
 -
        lock_sock(sk);
  
 -      if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
 +      if (sk->sk_state == BT_BOUND) {
                err = -EALREADY;
                goto done;
        }
  
 -      if (haddr.hci_dev != HCI_DEV_NONE) {
 -              hdev = hci_dev_get(haddr.hci_dev);
 -              if (!hdev) {
 -                      err = -ENODEV;
 +      switch (haddr.hci_channel) {
 +      case HCI_CHANNEL_RAW:
 +              if (hci_pi(sk)->hdev) {
 +                      err = -EALREADY;
                        goto done;
                }
  
 -              atomic_inc(&hdev->promisc);
 +              if (haddr.hci_dev != HCI_DEV_NONE) {
 +                      hdev = hci_dev_get(haddr.hci_dev);
 +                      if (!hdev) {
 +                              err = -ENODEV;
 +                              goto done;
 +                      }
 +
 +                      atomic_inc(&hdev->promisc);
 +              }
 +
 +              hci_pi(sk)->hdev = hdev;
 +              break;
 +
 +      case HCI_CHANNEL_CONTROL:
 +              if (haddr.hci_dev != HCI_DEV_NONE) {
 +                      err = -EINVAL;
 +                      goto done;
 +              }
 +
 +              if (!capable(CAP_NET_ADMIN)) {
 +                      err = -EPERM;
 +                      goto done;
 +              }
 +
 +              break;
 +
 +      case HCI_CHANNEL_MONITOR:
 +              if (haddr.hci_dev != HCI_DEV_NONE) {
 +                      err = -EINVAL;
 +                      goto done;
 +              }
 +
 +              if (!capable(CAP_NET_RAW)) {
 +                      err = -EPERM;
 +                      goto done;
 +              }
 +
 +              send_monitor_replay(sk);
 +
 +              atomic_inc(&monitor_promisc);
 +              break;
 +
 +      default:
 +              err = -EINVAL;
 +              goto done;
        }
  
 +
        hci_pi(sk)->channel = haddr.hci_channel;
 -      hci_pi(sk)->hdev = hdev;
        sk->sk_state = BT_BOUND;
  
  done:
@@@ -733,7 -418,8 +733,8 @@@ static inline void hci_sock_cmsg(struc
                data = &tv;
                len = sizeof(tv);
  #ifdef CONFIG_COMPAT
-               if (msg->msg_flags & MSG_CMSG_COMPAT) {
+               if (!COMPAT_USE_64BIT_TIME &&
+                   (msg->msg_flags & MSG_CMSG_COMPAT)) {
                        ctv.tv_sec = tv.tv_sec;
                        ctv.tv_usec = tv.tv_usec;
                        data = &ctv;
@@@ -776,15 -462,7 +777,15 @@@ static int hci_sock_recvmsg(struct kioc
        skb_reset_transport_header(skb);
        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
  
 -      hci_sock_cmsg(sk, msg, skb);
 +      switch (hci_pi(sk)->channel) {
 +      case HCI_CHANNEL_RAW:
 +              hci_sock_cmsg(sk, msg, skb);
 +              break;
 +      case HCI_CHANNEL_CONTROL:
 +      case HCI_CHANNEL_MONITOR:
 +              sock_recv_timestamp(msg, sk, skb);
 +              break;
 +      }
  
        skb_free_datagram(sk, skb);
  
@@@ -818,9 -496,6 +819,9 @@@ static int hci_sock_sendmsg(struct kioc
        case HCI_CHANNEL_CONTROL:
                err = mgmt_control(sk, msg, len);
                goto done;
 +      case HCI_CHANNEL_MONITOR:
 +              err = -EOPNOTSUPP;
 +              goto done;
        default:
                err = -EINVAL;
                goto done;
@@@ -900,11 -575,6 +901,11 @@@ static int hci_sock_setsockopt(struct s
  
        lock_sock(sk);
  
 +      if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
 +              err = -EINVAL;
 +              goto done;
 +      }
 +
        switch (optname) {
        case HCI_DATA_DIR:
                if (get_user(opt, (int __user *)optval)) {
                break;
        }
  
 +done:
        release_sock(sk);
        return err;
  }
@@@ -976,20 -645,11 +977,20 @@@ static int hci_sock_getsockopt(struct s
  {
        struct hci_ufilter uf;
        struct sock *sk = sock->sk;
 -      int len, opt;
 +      int len, opt, err = 0;
 +
 +      BT_DBG("sk %p, opt %d", sk, optname);
  
        if (get_user(len, optlen))
                return -EFAULT;
  
 +      lock_sock(sk);
 +
 +      if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
 +              err = -EINVAL;
 +              goto done;
 +      }
 +
        switch (optname) {
        case HCI_DATA_DIR:
                if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
                        opt = 0;
  
                if (put_user(opt, optval))
 -                      return -EFAULT;
 +                      err = -EFAULT;
                break;
  
        case HCI_TIME_STAMP:
                        opt = 0;
  
                if (put_user(opt, optval))
 -                      return -EFAULT;
 +                      err = -EFAULT;
                break;
  
        case HCI_FILTER:
  
                len = min_t(unsigned int, len, sizeof(uf));
                if (copy_to_user(optval, &uf, len))
 -                      return -EFAULT;
 +                      err = -EFAULT;
                break;
  
        default:
 -              return -ENOPROTOOPT;
 +              err = -ENOPROTOOPT;
                break;
        }
  
 -      return 0;
 +done:
 +      release_sock(sk);
 +      return err;
  }
  
  static const struct proto_ops hci_sock_ops = {
@@@ -1091,12 -749,52 +1092,12 @@@ static int hci_sock_create(struct net *
        return 0;
  }
  
 -static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 -{
 -      struct hci_dev *hdev = (struct hci_dev *) ptr;
 -      struct hci_ev_si_device ev;
 -
 -      BT_DBG("hdev %s event %ld", hdev->name, event);
 -
 -      /* Send event to sockets */
 -      ev.event  = event;
 -      ev.dev_id = hdev->id;
 -      hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
 -
 -      if (event == HCI_DEV_UNREG) {
 -              struct sock *sk;
 -              struct hlist_node *node;
 -
 -              /* Detach sockets from device */
 -              read_lock(&hci_sk_list.lock);
 -              sk_for_each(sk, node, &hci_sk_list.head) {
 -                      bh_lock_sock_nested(sk);
 -                      if (hci_pi(sk)->hdev == hdev) {
 -                              hci_pi(sk)->hdev = NULL;
 -                              sk->sk_err = EPIPE;
 -                              sk->sk_state = BT_OPEN;
 -                              sk->sk_state_change(sk);
 -
 -                              hci_dev_put(hdev);
 -                      }
 -                      bh_unlock_sock(sk);
 -              }
 -              read_unlock(&hci_sk_list.lock);
 -      }
 -
 -      return NOTIFY_DONE;
 -}
 -
  static const struct net_proto_family hci_sock_family_ops = {
        .family = PF_BLUETOOTH,
        .owner  = THIS_MODULE,
        .create = hci_sock_create,
  };
  
 -static struct notifier_block hci_sock_nblock = {
 -      .notifier_call = hci_sock_dev_event
 -};
 -
  int __init hci_sock_init(void)
  {
        int err;
        if (err < 0)
                goto error;
  
 -      hci_register_notifier(&hci_sock_nblock);
 -
        BT_INFO("HCI socket layer initialized");
  
        return 0;
@@@ -1124,5 -824,10 +1125,5 @@@ void hci_sock_cleanup(void
        if (bt_sock_unregister(BTPROTO_HCI) < 0)
                BT_ERR("HCI socket unregistration failed");
  
 -      hci_unregister_notifier(&hci_sock_nblock);
 -
        proto_unregister(&hci_sk_proto);
  }
 -
 -module_param(enable_mgmt, bool, 0644);
 -MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");
diff --combined net/compat.c
index 64b4515a64e6e7e6002b0f923b8ef3902406854f,73bf0e06f3d7959b4bde708327d956bc52280860..e055708b8ec9dfaa894e8e5920b4c35fd38b2afe
@@@ -79,7 -79,7 +79,7 @@@ int get_compat_msghdr(struct msghdr *km
  
  /* I've named the args so it is easy to tell whose space the pointers are in. */
  int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
 -                 struct sockaddr *kern_address, int mode)
 +                 struct sockaddr_storage *kern_address, int mode)
  {
        int tot_len;
  
@@@ -219,8 -219,6 +219,6 @@@ Efault
  
  int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
  {
-       struct compat_timeval ctv;
-       struct compat_timespec cts[3];
        struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
        struct compat_cmsghdr cmhdr;
        int cmlen;
                return 0; /* XXX: return error? check spec. */
        }
  
-       if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
-               struct timeval *tv = (struct timeval *)data;
-               ctv.tv_sec = tv->tv_sec;
-               ctv.tv_usec = tv->tv_usec;
-               data = &ctv;
-               len = sizeof(ctv);
-       }
-       if (level == SOL_SOCKET &&
-           (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
-               int count = type == SCM_TIMESTAMPNS ? 1 : 3;
-               int i;
-               struct timespec *ts = (struct timespec *)data;
-               for (i = 0; i < count; i++) {
-                       cts[i].tv_sec = ts[i].tv_sec;
-                       cts[i].tv_nsec = ts[i].tv_nsec;
+       if (!COMPAT_USE_64BIT_TIME) {
+               struct compat_timeval ctv;
+               struct compat_timespec cts[3];
+               if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
+                       struct timeval *tv = (struct timeval *)data;
+                       ctv.tv_sec = tv->tv_sec;
+                       ctv.tv_usec = tv->tv_usec;
+                       data = &ctv;
+                       len = sizeof(ctv);
+               }
+               if (level == SOL_SOCKET &&
+                   (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
+                       int count = type == SCM_TIMESTAMPNS ? 1 : 3;
+                       int i;
+                       struct timespec *ts = (struct timespec *)data;
+                       for (i = 0; i < count; i++) {
+                               cts[i].tv_sec = ts[i].tv_sec;
+                               cts[i].tv_nsec = ts[i].tv_nsec;
+                       }
+                       data = &cts;
+                       len = sizeof(cts[0]) * count;
                }
-               data = &cts;
-               len = sizeof(cts[0]) * count;
        }
  
        cmlen = CMSG_COMPAT_LEN(len);
@@@ -454,11 -456,15 +456,15 @@@ static int compat_sock_getsockopt(struc
  
  int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
  {
-       struct compat_timeval __user *ctv =
-                       (struct compat_timeval __user *) userstamp;
-       int err = -ENOENT;
+       struct compat_timeval __user *ctv;
+       int err;
        struct timeval tv;
  
+       if (COMPAT_USE_64BIT_TIME)
+               return sock_get_timestamp(sk, userstamp);
+       ctv = (struct compat_timeval __user *) userstamp;
+       err = -ENOENT;
        if (!sock_flag(sk, SOCK_TIMESTAMP))
                sock_enable_timestamp(sk, SOCK_TIMESTAMP);
        tv = ktime_to_timeval(sk->sk_stamp);
@@@ -478,11 -484,15 +484,15 @@@ EXPORT_SYMBOL(compat_sock_get_timestamp
  
  int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
  {
-       struct compat_timespec __user *ctv =
-                       (struct compat_timespec __user *) userstamp;
-       int err = -ENOENT;
+       struct compat_timespec __user *ctv;
+       int err;
        struct timespec ts;
  
+       if (COMPAT_USE_64BIT_TIME)
+               return sock_get_timestampns (sk, userstamp);
+       ctv = (struct compat_timespec __user *) userstamp;
+       err = -ENOENT;
        if (!sock_flag(sk, SOCK_TIMESTAMP))
                sock_enable_timestamp(sk, SOCK_TIMESTAMP);
        ts = ktime_to_timespec(sk->sk_stamp);
@@@ -767,6 -777,11 +777,11 @@@ asmlinkage long compat_sys_recvmmsg(in
        int datagrams;
        struct timespec ktspec;
  
+       if (COMPAT_USE_64BIT_TIME)
+               return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
+                                     flags | MSG_CMSG_COMPAT,
+                                     (struct timespec *) timeout);
        if (timeout == NULL)
                return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
                                      flags | MSG_CMSG_COMPAT, NULL);
diff --combined net/socket.c
index 12a48d846223c5d2204e753fe9ae6298d55ff489,5325d4c797c90e9b625bc79a9c66ceb3e143a01d..484cc6953fc61ebcb049604e5dbdb57a4ffcd385
@@@ -181,7 -181,7 +181,7 @@@ static DEFINE_PER_CPU(int, sockets_in_u
   *    invalid addresses -EFAULT is returned. On a success 0 is returned.
   */
  
 -int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr)
 +int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
  {
        if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
                return -EINVAL;
   *    specified. Zero is returned for a success.
   */
  
 -static int move_addr_to_user(struct sockaddr *kaddr, int klen,
 +static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
                             void __user *uaddr, int __user *ulen)
  {
        int err;
@@@ -1449,7 -1449,7 +1449,7 @@@ SYSCALL_DEFINE3(bind, int, fd, struct s
  
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (sock) {
 -              err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
 +              err = move_addr_to_kernel(umyaddr, addrlen, &address);
                if (err >= 0) {
                        err = security_socket_bind(sock,
                                                   (struct sockaddr *)&address,
@@@ -1556,7 -1556,7 +1556,7 @@@ SYSCALL_DEFINE4(accept4, int, fd, struc
                        err = -ECONNABORTED;
                        goto out_fd;
                }
 -              err = move_addr_to_user((struct sockaddr *)&address,
 +              err = move_addr_to_user(&address,
                                        len, upeer_sockaddr, upeer_addrlen);
                if (err < 0)
                        goto out_fd;
@@@ -1605,7 -1605,7 +1605,7 @@@ SYSCALL_DEFINE3(connect, int, fd, struc
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 -      err = move_addr_to_kernel(uservaddr, addrlen, (struct sockaddr *)&address);
 +      err = move_addr_to_kernel(uservaddr, addrlen, &address);
        if (err < 0)
                goto out_put;
  
@@@ -1645,7 -1645,7 +1645,7 @@@ SYSCALL_DEFINE3(getsockname, int, fd, s
        err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
        if (err)
                goto out_put;
 -      err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr, usockaddr_len);
 +      err = move_addr_to_user(&address, len, usockaddr, usockaddr_len);
  
  out_put:
        fput_light(sock->file, fput_needed);
@@@ -1677,7 -1677,7 +1677,7 @@@ SYSCALL_DEFINE3(getpeername, int, fd, s
                    sock->ops->getname(sock, (struct sockaddr *)&address, &len,
                                       1);
                if (!err)
 -                      err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr,
 +                      err = move_addr_to_user(&address, len, usockaddr,
                                                usockaddr_len);
                fput_light(sock->file, fput_needed);
        }
@@@ -1716,7 -1716,7 +1716,7 @@@ SYSCALL_DEFINE6(sendto, int, fd, void _
        msg.msg_controllen = 0;
        msg.msg_namelen = 0;
        if (addr) {
 -              err = move_addr_to_kernel(addr, addr_len, (struct sockaddr *)&address);
 +              err = move_addr_to_kernel(addr, addr_len, &address);
                if (err < 0)
                        goto out_put;
                msg.msg_name = (struct sockaddr *)&address;
@@@ -1779,7 -1779,7 +1779,7 @@@ SYSCALL_DEFINE6(recvfrom, int, fd, voi
        err = sock_recvmsg(sock, &msg, size, flags);
  
        if (err >= 0 && addr != NULL) {
 -              err2 = move_addr_to_user((struct sockaddr *)&address,
 +              err2 = move_addr_to_user(&address,
                                         msg.msg_namelen, addr, addr_len);
                if (err2 < 0)
                        err = err2;
@@@ -1933,9 -1933,13 +1933,9 @@@ static int __sys_sendmsg(struct socket 
  
        /* This will also move the address data into kernel space */
        if (MSG_CMSG_COMPAT & flags) {
 -              err = verify_compat_iovec(msg_sys, iov,
 -                                        (struct sockaddr *)&address,
 -                                        VERIFY_READ);
 +              err = verify_compat_iovec(msg_sys, iov, &address, VERIFY_READ);
        } else
 -              err = verify_iovec(msg_sys, iov,
 -                                 (struct sockaddr *)&address,
 -                                 VERIFY_READ);
 +              err = verify_iovec(msg_sys, iov, &address, VERIFY_READ);
        if (err < 0)
                goto out_freeiov;
        total_len = err;
@@@ -2139,9 -2143,13 +2139,9 @@@ static int __sys_recvmsg(struct socket 
        uaddr = (__force void __user *)msg_sys->msg_name;
        uaddr_len = COMPAT_NAMELEN(msg);
        if (MSG_CMSG_COMPAT & flags) {
 -              err = verify_compat_iovec(msg_sys, iov,
 -                                        (struct sockaddr *)&addr,
 -                                        VERIFY_WRITE);
 +              err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
        } else
 -              err = verify_iovec(msg_sys, iov,
 -                                 (struct sockaddr *)&addr,
 -                                 VERIFY_WRITE);
 +              err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
        if (err < 0)
                goto out_freeiov;
        total_len = err;
        len = err;
  
        if (uaddr != NULL) {
 -              err = move_addr_to_user((struct sockaddr *)&addr,
 +              err = move_addr_to_user(&addr,
                                        msg_sys->msg_namelen, uaddr,
                                        uaddr_len);
                if (err < 0)
@@@ -2592,7 -2600,7 +2592,7 @@@ void socket_seq_show(struct seq_file *s
  
  #ifdef CONFIG_COMPAT
  static int do_siocgstamp(struct net *net, struct socket *sock,
-                        unsigned int cmd, struct compat_timeval __user *up)
+                        unsigned int cmd, void __user *up)
  {
        mm_segment_t old_fs = get_fs();
        struct timeval ktv;
        set_fs(KERNEL_DS);
        err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
        set_fs(old_fs);
-       if (!err) {
-               err = put_user(ktv.tv_sec, &up->tv_sec);
-               err |= __put_user(ktv.tv_usec, &up->tv_usec);
-       }
+       if (!err)
+               err = compat_put_timeval(up, &ktv);
        return err;
  }
  
  static int do_siocgstampns(struct net *net, struct socket *sock,
-                        unsigned int cmd, struct compat_timespec __user *up)
+                          unsigned int cmd, void __user *up)
  {
        mm_segment_t old_fs = get_fs();
        struct timespec kts;
        set_fs(KERNEL_DS);
        err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
        set_fs(old_fs);
-       if (!err) {
-               err = put_user(kts.tv_sec, &up->tv_sec);
-               err |= __put_user(kts.tv_nsec, &up->tv_nsec);
-       }
+       if (!err)
+               err = compat_put_timespec(up, &kts);
        return err;
  }
  
diff --combined security/selinux/hooks.c
index 30492990937595b420e3d01be4a6cc0f5448ff7f,421c990a20b280d6ff67c0cbfa33ad706cb71baf..15c6c567468b6f4a12d00b8a4f5756311ddbc532
@@@ -81,8 -81,6 +81,8 @@@
  #include <linux/syslog.h>
  #include <linux/user_namespace.h>
  #include <linux/export.h>
 +#include <linux/msg.h>
 +#include <linux/shm.h>
  
  #include "avc.h"
  #include "objsec.h"
@@@ -2147,7 -2145,7 +2147,7 @@@ static inline void flush_unauthorized_f
                fdt = files_fdtable(files);
                if (i >= fdt->max_fds)
                        break;
-               set = fdt->open_fds->fds_bits[j];
+               set = fdt->open_fds[j];
                if (!set)
                        continue;
                spin_unlock(&files->file_lock);