From ab1a7a99b1ad883956dddf9b37fd677da293691d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 18 Jan 2010 22:50:09 +0000 Subject: [PATCH] Add stable release 2.6.32.4 Fix conflict between 2.6.32.4 and vserver in mm/mremap.c by making some cosmetic changes on top of 2.6.32.4. svn path=/dists/trunk/linux-2.6/; revision=14953 --- debian/changelog | 18 +- .../patches/bugfix/all/stable/2.6.32.4.patch | 4651 +++++++++++++++++ ...onflict-between-2.6.32.4-and-vserver.patch | 32 + debian/patches/series/6 | 7 +- 4 files changed, 4698 insertions(+), 10 deletions(-) create mode 100644 debian/patches/bugfix/all/stable/2.6.32.4.patch create mode 100644 debian/patches/debian/mremap-fix-conflict-between-2.6.32.4-and-vserver.patch diff --git a/debian/changelog b/debian/changelog index cfbd86500..f29763307 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,14 +13,22 @@ linux-2.6 (2.6.32-6) UNRELEASED; urgency=low * saa7134: Add device id and description for Asus Europa DVB-T card * x86/iTCO-wdt: Add device ids for Intel 'Ibex Peak' PCH * Documentation/3c509: document ethtool support (Closes: #564743) - * Fix DMA mapping for i915 driver (Closes: #558237) - - agp/intel-agp: Clear entire GTT on startup - - drm: remove address mask param for drm_pci_alloc() * Add MODULE_FIRMWARE declarations to several drivers that lacked them * [x86] Update rt2860sta/rt2870sta firmware loader patch - Accept 8K versions of rt2870.bin - Fix hang on resume * [x86] Enable rt3090sta using firmware loader + * Add stable release 2.6.32.4: + - fasync: split 'fasync_helper()' into separate add/remove functions + (CVE-2009-4141) + - netfilter: ebtables: enforce CAP_NET_ADMIN (CVE-2010-0007) + - audit: Fix memory management bugs (Closes: #562815) + + fix braindamage in audit_tree.c untag_chunk() + + fix more leaks in audit_tree.c tag_chunk() + - ipv6: skb_dst() can be NULL in ipv6_hop_jumbo(). (CVE-2010-0006) + - Fix DMA mapping for i915 driver (Closes: #558237) + + drm: remove address mask param for drm_pci_alloc() + + agp/intel-agp: Clear entire GTT on startup [ Ian Campbell ] * xen: Enable up to 32G of guest memory on i386. @@ -28,10 +36,6 @@ linux-2.6 (2.6.32-6) UNRELEASED; urgency=low [ Julien Cristau ] * drm/i915: disable powersave by default (closes: #564807) - [ dann frazier ] - * fasync: split 'fasync_helper()' into separate add/remove functions - (CVE-2009-4141) - -- Ben Hutchings Sun, 10 Jan 2010 17:38:50 +0000 linux-2.6 (2.6.32-5) unstable; urgency=low diff --git a/debian/patches/bugfix/all/stable/2.6.32.4.patch b/debian/patches/bugfix/all/stable/2.6.32.4.patch new file mode 100644 index 000000000..5d06a2a78 --- /dev/null +++ b/debian/patches/bugfix/all/stable/2.6.32.4.patch @@ -0,0 +1,4651 @@ +diff --git a/Makefile b/Makefile +index 482dcdd..6d13598 100644 +diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c +index 9a3334a..62619f2 100644 +--- a/arch/alpha/kernel/osf_sys.c ++++ b/arch/alpha/kernel/osf_sys.c +@@ -178,25 +178,18 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, off) + { +- struct file *file = NULL; +- unsigned long ret = -EBADF; ++ unsigned long ret = -EINVAL; + + #if 0 + if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED)) + printk("%s: unimplemented OSF mmap flags %04lx\n", + current->comm, flags); + #endif +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- down_write(¤t->mm->mmap_sem); +- ret = do_mmap(file, addr, len, prot, flags, off); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); ++ if ((off + PAGE_ALIGN(len)) < off) ++ goto out; ++ if (off & ~PAGE_MASK) ++ goto out; ++ ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + out: + return ret; + } +diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h +index 8eebf89..41f99c5 100644 +--- a/arch/arm/include/asm/mman.h ++++ b/arch/arm/include/asm/mman.h +@@ -1 +1,4 @@ + #include ++ ++#define arch_mmap_check(addr, len, flags) \ ++ (((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0) +diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S +index fafce1b..4f07168 100644 +--- a/arch/arm/kernel/calls.S ++++ b/arch/arm/kernel/calls.S +@@ -172,7 +172,7 @@ + /* 160 */ CALL(sys_sched_get_priority_min) + CALL(sys_sched_rr_get_interval) + CALL(sys_nanosleep) +- CALL(sys_arm_mremap) ++ CALL(sys_mremap) + CALL(sys_setresuid16) + /* 165 */ CALL(sys_getresuid16) + CALL(sys_ni_syscall) /* vm86 */ +diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S +index f0fe95b..2c1db77 100644 +--- a/arch/arm/kernel/entry-common.S ++++ b/arch/arm/kernel/entry-common.S +@@ -416,12 +416,12 @@ sys_mmap2: + tst r5, #PGOFF_MASK + moveq r5, r5, lsr #PAGE_SHIFT - 12 + streq r5, [sp, #4] +- beq do_mmap2 ++ beq sys_mmap_pgoff + mov r0, #-EINVAL + mov pc, lr + #else + str r5, [sp, #4] +- b do_mmap2 ++ b sys_mmap_pgoff + #endif + ENDPROC(sys_mmap2) + +diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c +index 78ecaac..ae4027b 100644 +--- a/arch/arm/kernel/sys_arm.c ++++ b/arch/arm/kernel/sys_arm.c +@@ -28,41 +28,6 @@ + #include + #include + +-extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, +- unsigned long new_len, unsigned long flags, +- unsigned long new_addr); +- +-/* common code for old and new mmaps */ +-inline long do_mmap2( +- unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EINVAL; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- if (flags & MAP_FIXED && addr < FIRST_USER_ADDRESS) +- goto out; +- +- error = -EBADF; +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + struct mmap_arg_struct { + unsigned long addr; + unsigned long len; +@@ -84,29 +49,11 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); + out: + return error; + } + +-asmlinkage unsigned long +-sys_arm_mremap(unsigned long addr, unsigned long old_len, +- unsigned long new_len, unsigned long flags, +- unsigned long new_addr) +-{ +- unsigned long ret = -EINVAL; +- +- if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS) +- goto out; +- +- down_write(¤t->mm->mmap_sem); +- ret = do_mremap(addr, old_len, new_len, flags, new_addr); +- up_write(¤t->mm->mmap_sem); +- +-out: +- return ret; +-} +- + /* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. +diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c +index 2b79964..f5abc51 100644 +--- a/arch/arm/mm/mmap.c ++++ b/arch/arm/mm/mmap.c +@@ -54,7 +54,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, + * We enforce the MAP_FIXED case. + */ + if (flags & MAP_FIXED) { +- if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1)) ++ if (aliasing && flags & MAP_SHARED && ++ (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) + return -EINVAL; + return addr; + } +diff --git a/arch/avr32/include/asm/syscalls.h b/arch/avr32/include/asm/syscalls.h +index 483d666..66a1972 100644 +--- a/arch/avr32/include/asm/syscalls.h ++++ b/arch/avr32/include/asm/syscalls.h +@@ -29,10 +29,6 @@ asmlinkage int sys_sigaltstack(const stack_t __user *, stack_t __user *, + struct pt_regs *); + asmlinkage int sys_rt_sigreturn(struct pt_regs *); + +-/* kernel/sys_avr32.c */ +-asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, +- unsigned long, unsigned long, off_t); +- + /* mm/cache.c */ + asmlinkage int sys_cacheflush(int, void __user *, size_t); + +diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c +index 5d2daea..459349b 100644 +--- a/arch/avr32/kernel/sys_avr32.c ++++ b/arch/avr32/kernel/sys_avr32.c +@@ -5,39 +5,8 @@ + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +-#include +-#include +-#include +-#include + #include + +-#include +-#include +-#include +- +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, off_t offset) +-{ +- int error = -EBADF; +- struct file *file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- return error; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, offset); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +- return error; +-} +- + int kernel_execve(const char *file, char **argv, char **envp) + { + register long scno asm("r8") = __NR_execve; +diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S +index f7244cd..0447a3e 100644 +--- a/arch/avr32/kernel/syscall-stubs.S ++++ b/arch/avr32/kernel/syscall-stubs.S +@@ -61,7 +61,7 @@ __sys_execve: + __sys_mmap2: + pushm lr + st.w --sp, ARG6 +- call sys_mmap2 ++ call sys_mmap_pgoff + sub sp, -4 + popm pc + +diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c +index afcef12..2e7f8e1 100644 +--- a/arch/blackfin/kernel/sys_bfin.c ++++ b/arch/blackfin/kernel/sys_bfin.c +@@ -22,39 +22,6 @@ + #include + #include + +-/* common code for old and new mmaps */ +-static inline long +-do_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file *file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +- out: +- return error; +-} +- +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- return do_mmap2(addr, len, prot, flags, fd, pgoff); +-} +- + asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) + { + return sram_alloc_with_lsl(size, flags); +diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S +index 94a0375..1d8f00a 100644 +--- a/arch/blackfin/mach-common/entry.S ++++ b/arch/blackfin/mach-common/entry.S +@@ -1422,7 +1422,7 @@ ENTRY(_sys_call_table) + .long _sys_ni_syscall /* streams2 */ + .long _sys_vfork /* 190 */ + .long _sys_getrlimit +- .long _sys_mmap2 ++ .long _sys_mmap_pgoff + .long _sys_truncate64 + .long _sys_ftruncate64 + .long _sys_stat64 /* 195 */ +diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c +index 2ad962c..c2bbb1a 100644 +--- a/arch/cris/kernel/sys_cris.c ++++ b/arch/cris/kernel/sys_cris.c +@@ -26,31 +26,6 @@ + #include + #include + +-/* common code for old and new mmaps */ +-static inline long +-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, +- unsigned long flags, unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + asmlinkage unsigned long old_mmap(unsigned long __user *args) + { + unsigned long buffer[6]; +@@ -63,7 +38,7 @@ asmlinkage unsigned long old_mmap(unsigned long __user *args) + if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */ + goto out; + +- err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3], ++ err = sys_mmap_pgoff(buffer[0], buffer[1], buffer[2], buffer[3], + buffer[4], buffer[5] >> PAGE_SHIFT); + out: + return err; +@@ -73,7 +48,8 @@ asmlinkage long + sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) + { +- return do_mmap2(addr, len, prot, flags, fd, pgoff); ++ /* bug(?): 8Kb pages here */ ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + } + + /* +diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c +index 2b6b528..1d3d4c9 100644 +--- a/arch/frv/kernel/sys_frv.c ++++ b/arch/frv/kernel/sys_frv.c +@@ -31,9 +31,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) + { +- int error = -EBADF; +- struct file * file = NULL; +- + /* As with sparc32, make sure the shift for mmap2 is constant + (12), no matter what PAGE_SIZE we have.... */ + +@@ -41,69 +38,10 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + trying to map something we can't */ + if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1)) + return -EINVAL; +- pgoff >>= PAGE_SHIFT - 12; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- +-#if 0 /* DAVIDM - do we want this */ +-struct mmap_arg_struct64 { +- __u32 addr; +- __u32 len; +- __u32 prot; +- __u32 flags; +- __u64 offset; /* 64 bits */ +- __u32 fd; +-}; +- +-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) +-{ +- int error = -EFAULT; +- struct file * file = NULL; +- struct mmap_arg_struct64 a; +- unsigned long pgoff; +- +- if (copy_from_user(&a, arg, sizeof(a))) +- return -EFAULT; +- +- if ((long)a.offset & ~PAGE_MASK) +- return -EINVAL; +- +- pgoff = a.offset >> PAGE_SHIFT; +- if ((a.offset >> PAGE_SHIFT) != pgoff) +- return -EINVAL; +- +- if (!(a.flags & MAP_ANONYMOUS)) { +- error = -EBADF; +- file = fget(a.fd); +- if (!file) +- goto out; +- } +- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); +-out: +- return error; ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, ++ pgoff >> (PAGE_SHIFT - 12)); + } +-#endif + + /* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. +diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c +index 8cb5d73..b5969db 100644 +--- a/arch/h8300/kernel/sys_h8300.c ++++ b/arch/h8300/kernel/sys_h8300.c +@@ -26,39 +26,6 @@ + #include + #include + +-/* common code for old and new mmaps */ +-static inline long do_mmap2( +- unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- return do_mmap2(addr, len, prot, flags, fd, pgoff); +-} +- + /* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to +@@ -87,57 +54,11 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); +-out: +- return error; +-} +- +-#if 0 /* DAVIDM - do we want this */ +-struct mmap_arg_struct64 { +- __u32 addr; +- __u32 len; +- __u32 prot; +- __u32 flags; +- __u64 offset; /* 64 bits */ +- __u32 fd; +-}; +- +-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) +-{ +- int error = -EFAULT; +- struct file * file = NULL; +- struct mmap_arg_struct64 a; +- unsigned long pgoff; +- +- if (copy_from_user(&a, arg, sizeof(a))) +- return -EFAULT; +- +- if ((long)a.offset & ~PAGE_MASK) +- return -EINVAL; +- +- pgoff = a.offset >> PAGE_SHIFT; +- if ((a.offset >> PAGE_SHIFT) != pgoff) +- return -EINVAL; +- +- if (!(a.flags & MAP_ANONYMOUS)) { +- error = -EBADF; +- file = fget(a.fd); +- if (!file) +- goto out; +- } +- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, ++ a.offset >> PAGE_SHIFT); + out: + return error; + } +-#endif + + struct sel_arg_struct { + unsigned long n; +diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S +index 4eb67fa..2d69881 100644 +--- a/arch/h8300/kernel/syscalls.S ++++ b/arch/h8300/kernel/syscalls.S +@@ -206,7 +206,7 @@ SYMBOL_NAME_LABEL(sys_call_table) + .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ + .long SYMBOL_NAME(sys_vfork) /* 190 */ + .long SYMBOL_NAME(sys_getrlimit) +- .long SYMBOL_NAME(sys_mmap2) ++ .long SYMBOL_NAME(sys_mmap_pgoff) + .long SYMBOL_NAME(sys_truncate64) + .long SYMBOL_NAME(sys_ftruncate64) + .long SYMBOL_NAME(sys_stat64) /* 195 */ +diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c +index 625ed8f..e031ee8 100644 +--- a/arch/ia64/ia32/sys_ia32.c ++++ b/arch/ia64/ia32/sys_ia32.c +@@ -858,6 +858,9 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot + + prot = get_prot32(prot); + ++ if (flags & MAP_HUGETLB) ++ return -ENOMEM; ++ + #if PAGE_SHIFT > IA32_PAGE_SHIFT + mutex_lock(&ia32_mmap_mutex); + { +diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c +index 92ed83f..609d500 100644 +--- a/arch/ia64/kernel/sys_ia64.c ++++ b/arch/ia64/kernel/sys_ia64.c +@@ -100,51 +100,7 @@ sys_getpagesize (void) + asmlinkage unsigned long + ia64_brk (unsigned long brk) + { +- unsigned long rlim, retval, newbrk, oldbrk; +- struct mm_struct *mm = current->mm; +- +- /* +- * Most of this replicates the code in sys_brk() except for an additional safety +- * check and the clearing of r8. However, we can't call sys_brk() because we need +- * to acquire the mmap_sem before we can do the test... +- */ +- down_write(&mm->mmap_sem); +- +- if (brk < mm->end_code) +- goto out; +- newbrk = PAGE_ALIGN(brk); +- oldbrk = PAGE_ALIGN(mm->brk); +- if (oldbrk == newbrk) +- goto set_brk; +- +- /* Always allow shrinking brk. */ +- if (brk <= mm->brk) { +- if (!do_munmap(mm, newbrk, oldbrk-newbrk)) +- goto set_brk; +- goto out; +- } +- +- /* Check against unimplemented/unmapped addresses: */ +- if ((newbrk - oldbrk) > RGN_MAP_LIMIT || REGION_OFFSET(newbrk) > RGN_MAP_LIMIT) +- goto out; +- +- /* Check against rlimit.. */ +- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; +- if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) +- goto out; +- +- /* Check against existing mmap mappings. */ +- if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) +- goto out; +- +- /* Ok, looks good - let it rip. */ +- if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) +- goto out; +-set_brk: +- mm->brk = brk; +-out: +- retval = mm->brk; +- up_write(&mm->mmap_sem); ++ unsigned long retval = sys_brk(brk); + force_successful_syscall_return(); + return retval; + } +@@ -185,39 +141,6 @@ int ia64_mmap_check(unsigned long addr, unsigned long len, + return 0; + } + +-static inline unsigned long +-do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff) +-{ +- struct file *file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- return -EBADF; +- +- if (!file->f_op || !file->f_op->mmap) { +- addr = -ENODEV; +- goto out; +- } +- } +- +- /* Careful about overflows.. */ +- len = PAGE_ALIGN(len); +- if (!len || len > TASK_SIZE) { +- addr = -EINVAL; +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +-out: if (file) +- fput(file); +- return addr; +-} +- + /* + * mmap2() is like mmap() except that the offset is expressed in units + * of PAGE_SIZE (instead of bytes). This allows to mmap2() (pieces +@@ -226,7 +149,7 @@ out: if (file) + asmlinkage unsigned long + sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) + { +- addr = do_mmap2(addr, len, prot, flags, fd, pgoff); ++ addr = sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + if (!IS_ERR((void *) addr)) + force_successful_syscall_return(); + return addr; +@@ -238,7 +161,7 @@ sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, lo + if (offset_in_page(off) != 0) + return -EINVAL; + +- addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); ++ addr = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + if (!IS_ERR((void *) addr)) + force_successful_syscall_return(); + return addr; +diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c +index 305ac85..d3c865c 100644 +--- a/arch/m32r/kernel/sys_m32r.c ++++ b/arch/m32r/kernel/sys_m32r.c +@@ -76,30 +76,6 @@ asmlinkage int sys_tas(int __user *addr) + return oldval; + } + +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file *file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + /* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * +diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S +index aa3bf4c..60536e2 100644 +--- a/arch/m32r/kernel/syscall_table.S ++++ b/arch/m32r/kernel/syscall_table.S +@@ -191,7 +191,7 @@ ENTRY(sys_call_table) + .long sys_ni_syscall /* streams2 */ + .long sys_vfork /* 190 */ + .long sys_getrlimit +- .long sys_mmap2 ++ .long sys_mmap_pgoff + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ +diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c +index 7deb402..218f441 100644 +--- a/arch/m68k/kernel/sys_m68k.c ++++ b/arch/m68k/kernel/sys_m68k.c +@@ -29,37 +29,16 @@ + #include + #include + +-/* common code for old and new mmaps */ +-static inline long do_mmap2( +- unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) + { +- return do_mmap2(addr, len, prot, flags, fd, pgoff); ++ /* ++ * This is wrong for sun3 - there PAGE_SIZE is 8Kb, ++ * so we need to shift the argument down by 1; m68k mmap64(3) ++ * (in libc) expects the last argument of mmap2 in 4Kb units. ++ */ ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + } + + /* +@@ -90,57 +69,11 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); +-out: +- return error; +-} +- +-#if 0 +-struct mmap_arg_struct64 { +- __u32 addr; +- __u32 len; +- __u32 prot; +- __u32 flags; +- __u64 offset; /* 64 bits */ +- __u32 fd; +-}; +- +-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg) +-{ +- int error = -EFAULT; +- struct file * file = NULL; +- struct mmap_arg_struct64 a; +- unsigned long pgoff; +- +- if (copy_from_user(&a, arg, sizeof(a))) +- return -EFAULT; +- +- if ((long)a.offset & ~PAGE_MASK) +- return -EINVAL; +- +- pgoff = a.offset >> PAGE_SHIFT; +- if ((a.offset >> PAGE_SHIFT) != pgoff) +- return -EINVAL; +- +- if (!(a.flags & MAP_ANONYMOUS)) { +- error = -EBADF; +- file = fget(a.fd); +- if (!file) +- goto out; +- } +- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, ++ a.offset >> PAGE_SHIFT); + out: + return error; + } +-#endif + + struct sel_arg_struct { + unsigned long n; +diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c +index efdd090..b67cbc7 100644 +--- a/arch/m68knommu/kernel/sys_m68k.c ++++ b/arch/m68knommu/kernel/sys_m68k.c +@@ -27,39 +27,6 @@ + #include + #include + +-/* common code for old and new mmaps */ +-static inline long do_mmap2( +- unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- return do_mmap2(addr, len, prot, flags, fd, pgoff); +-} +- + /* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to +@@ -88,9 +55,8 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, ++ a.offset >> PAGE_SHIFT); + out: + return error; + } +diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S +index 23535cc..486837e 100644 +--- a/arch/m68knommu/kernel/syscalltable.S ++++ b/arch/m68knommu/kernel/syscalltable.S +@@ -210,7 +210,7 @@ ENTRY(sys_call_table) + .long sys_ni_syscall /* streams2 */ + .long sys_vfork /* 190 */ + .long sys_getrlimit +- .long sys_mmap2 ++ .long sys_mmap_pgoff + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ +diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c +index 07cabed..9f3c205 100644 +--- a/arch/microblaze/kernel/sys_microblaze.c ++++ b/arch/microblaze/kernel/sys_microblaze.c +@@ -62,46 +62,14 @@ out: + return error; + } + +-asmlinkage long +-sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- struct file *file = NULL; +- int ret = -EBADF; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) { +- printk(KERN_INFO "no fd in mmap\r\n"); +- goto out; +- } +- } +- +- down_write(¤t->mm->mmap_sem); +- ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); +-out: +- return ret; +-} +- + asmlinkage long sys_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t pgoff) + { +- int err = -EINVAL; +- +- if (pgoff & ~PAGE_MASK) { +- printk(KERN_INFO "no pagemask in mmap\r\n"); +- goto out; +- } ++ if (pgoff & ~PAGE_MASK) ++ return -EINVAL; + +- err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); +-out: +- return err; ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); + } + + /* +diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S +index ecec191..eb50ce5 100644 +--- a/arch/microblaze/kernel/syscall_table.S ++++ b/arch/microblaze/kernel/syscall_table.S +@@ -196,7 +196,7 @@ ENTRY(sys_call_table) + .long sys_ni_syscall /* reserved for streams2 */ + .long sys_vfork /* 190 */ + .long sys_getrlimit +- .long sys_mmap2 /* mmap2 */ ++ .long sys_mmap_pgoff /* mmap2 */ + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ +diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c +index b77fefa..ea4a746 100644 +--- a/arch/mips/kernel/linux32.c ++++ b/arch/mips/kernel/linux32.c +@@ -67,28 +67,13 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, pgoff) + { +- struct file * file = NULL; + unsigned long error; + + error = -EINVAL; + if (pgoff & (~PAGE_MASK >> 12)) + goto out; +- pgoff >>= PAGE_SHIFT-12; +- +- if (!(flags & MAP_ANONYMOUS)) { +- error = -EBADF; +- file = fget(fd); +- if (!file) +- goto out; +- } +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); +- ++ error = sys_mmap_pgoff(addr, len, prot, flags, fd, ++ pgoff >> (PAGE_SHIFT-12)); + out: + return error; + } +diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c +index fe0d798..3f7f466 100644 +--- a/arch/mips/kernel/syscall.c ++++ b/arch/mips/kernel/syscall.c +@@ -93,7 +93,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + * We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ +- if ((flags & MAP_SHARED) && (addr & shm_align_mask)) ++ if ((flags & MAP_SHARED) && ++ ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) + return -EINVAL; + return addr; + } +@@ -129,31 +130,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + } + } + +-/* common code for old and new mmaps */ +-static inline unsigned long +-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, +- unsigned long flags, unsigned long fd, unsigned long pgoff) +-{ +- unsigned long error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, + fd, off_t, offset) +@@ -164,7 +140,7 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, + if (offset & ~PAGE_MASK) + goto out; + +- result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); ++ result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + + out: + return result; +@@ -177,7 +153,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, + if (pgoff & (~PAGE_MASK >> 12)) + return -EINVAL; + +- return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12)); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12)); + } + + save_static_function(sys_fork); +diff --git a/arch/mn10300/include/asm/mman.h b/arch/mn10300/include/asm/mman.h +index 8eebf89..db5c53d 100644 +--- a/arch/mn10300/include/asm/mman.h ++++ b/arch/mn10300/include/asm/mman.h +@@ -1 +1,6 @@ + #include ++ ++#define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */ ++ ++#define arch_mmap_check(addr, len, flags) \ ++ (((flags) & MAP_FIXED && (addr) < MIN_MAP_ADDR) ? -EINVAL : 0) +diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S +index a94e7ea..c9ee6c0 100644 +--- a/arch/mn10300/kernel/entry.S ++++ b/arch/mn10300/kernel/entry.S +@@ -578,7 +578,7 @@ ENTRY(sys_call_table) + .long sys_ni_syscall /* reserved for streams2 */ + .long sys_vfork /* 190 */ + .long sys_getrlimit +- .long sys_mmap2 ++ .long sys_mmap_pgoff + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ +diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c +index 8ca5af0..17cc6ce 100644 +--- a/arch/mn10300/kernel/sys_mn10300.c ++++ b/arch/mn10300/kernel/sys_mn10300.c +@@ -23,47 +23,13 @@ + + #include + +-#define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */ +- +-/* +- * memory mapping syscall +- */ +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- struct file *file = NULL; +- long error = -EINVAL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- if (flags & MAP_FIXED && addr < MIN_MAP_ADDR) +- goto out; +- +- error = -EBADF; +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + asmlinkage long old_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long offset) + { + if (offset & ~PAGE_MASK) + return -EINVAL; +- return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + } + + struct sel_arg_struct { +diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c +index 71b3195..9147391 100644 +--- a/arch/parisc/kernel/sys_parisc.c ++++ b/arch/parisc/kernel/sys_parisc.c +@@ -110,37 +110,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + return addr; + } + +-static unsigned long do_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, unsigned long fd, +- unsigned long pgoff) +-{ +- struct file * file = NULL; +- unsigned long error = -EBADF; +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file != NULL) +- fput(file); +-out: +- return error; +-} +- + asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, unsigned long fd, + unsigned long pgoff) + { + /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE + we have. */ +- return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12)); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, ++ pgoff >> (PAGE_SHIFT - 12)); + } + + asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, +@@ -148,7 +125,8 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, + unsigned long offset) + { + if (!(offset & ~PAGE_MASK)) { +- return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, ++ offset >> PAGE_SHIFT); + } else { + return -EINVAL; + } +diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h +index 0845488..0192a4e 100644 +--- a/arch/powerpc/include/asm/module.h ++++ b/arch/powerpc/include/asm/module.h +@@ -87,5 +87,10 @@ struct exception_table_entry; + void sort_ex_table(struct exception_table_entry *start, + struct exception_table_entry *finish); + ++#ifdef CONFIG_MODVERSIONS ++#define ARCH_RELOCATES_KCRCTAB ++ ++extern const unsigned long reloc_start[]; ++#endif + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_MODULE_H */ +diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c +index c04832c..3370e62 100644 +--- a/arch/powerpc/kernel/syscalls.c ++++ b/arch/powerpc/kernel/syscalls.c +@@ -140,7 +140,6 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long off, int shift) + { +- struct file * file = NULL; + unsigned long ret = -EINVAL; + + if (!arch_validate_prot(prot)) +@@ -151,20 +150,8 @@ static inline unsigned long do_mmap2(unsigned long addr, size_t len, + goto out; + off >>= shift; + } +- +- ret = -EBADF; +- if (!(flags & MAP_ANONYMOUS)) { +- if (!(file = fget(fd))) +- goto out; +- } +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + +- down_write(¤t->mm->mmap_sem); +- ret = do_mmap_pgoff(file, addr, len, prot, flags, off); +- up_write(¤t->mm->mmap_sem); +- if (file) +- fput(file); ++ ret = sys_mmap_pgoff(addr, len, prot, flags, fd, off); + out: + return ret; + } +diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S +index 27735a7..dcd01c8 100644 +--- a/arch/powerpc/kernel/vmlinux.lds.S ++++ b/arch/powerpc/kernel/vmlinux.lds.S +@@ -38,6 +38,9 @@ jiffies = jiffies_64 + 4; + #endif + SECTIONS + { ++ . = 0; ++ reloc_start = .; ++ + . = KERNELBASE; + + /* +diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c +index 0debcec..9c746c0 100644 +--- a/arch/s390/kernel/compat_linux.c ++++ b/arch/s390/kernel/compat_linux.c +@@ -683,38 +683,6 @@ struct mmap_arg_struct_emu31 { + u32 offset; + }; + +-/* common code for old and new mmaps */ +-static inline long do_mmap2( +- unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- struct file * file = NULL; +- unsigned long error = -EBADF; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) { +- /* Result is out of bounds. */ +- do_munmap(current->mm, addr, len); +- error = -ENOMEM; +- } +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- +- + asmlinkage unsigned long + old32_mmap(struct mmap_arg_struct_emu31 __user *arg) + { +@@ -728,7 +696,8 @@ old32_mmap(struct mmap_arg_struct_emu31 __user *arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, ++ a.offset >> PAGE_SHIFT); + out: + return error; + } +@@ -741,7 +710,7 @@ sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) + + if (copy_from_user(&a, arg, sizeof(a))) + goto out; +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); + out: + return error; + } +diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c +index e9d94f6..86a74c9 100644 +--- a/arch/s390/kernel/sys_s390.c ++++ b/arch/s390/kernel/sys_s390.c +@@ -32,32 +32,6 @@ + #include + #include "entry.h" + +-/* common code for old and new mmaps */ +-static inline long do_mmap2( +- unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- long error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + /* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. Linux for S/390 isn't able to handle more than 5 +@@ -81,7 +55,7 @@ SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg) + + if (copy_from_user(&a, arg, sizeof(a))) + goto out; +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); + out: + return error; + } +@@ -98,7 +72,7 @@ SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); ++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); + out: + return error; + } +diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c +index 0012494..856ed68 100644 +--- a/arch/score/kernel/sys_score.c ++++ b/arch/score/kernel/sys_score.c +@@ -36,34 +36,16 @@ asmlinkage long + sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) + { +- int error = -EBADF; +- struct file *file = NULL; +- +- if (pgoff & (~PAGE_MASK >> 12)) +- return -EINVAL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- return error; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +- +- return error; ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + } + + asmlinkage long + sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, +- unsigned long flags, unsigned long fd, off_t pgoff) ++ unsigned long flags, unsigned long fd, off_t offset) + { +- return sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); ++ if (unlikely(offset & ~PAGE_MASK)) ++ return -EINVAL; ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + } + + asmlinkage long +diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c +index 8aa5d1c..71399cd 100644 +--- a/arch/sh/kernel/sys_sh.c ++++ b/arch/sh/kernel/sys_sh.c +@@ -28,37 +28,13 @@ + #include + #include + +-static inline long +-do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, +- unsigned long flags, int fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file *file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + asmlinkage int old_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + int fd, unsigned long off) + { + if (off & ~PAGE_MASK) + return -EINVAL; +- return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT); + } + + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +@@ -74,7 +50,7 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + + pgoff >>= PAGE_SHIFT - 12; + +- return do_mmap2(addr, len, prot, flags, fd, pgoff); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); + } + + /* +diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c +index d2984fa..afeb710 100644 +--- a/arch/sh/mm/mmap.c ++++ b/arch/sh/mm/mmap.c +@@ -54,7 +54,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + /* We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ +- if ((flags & MAP_SHARED) && (addr & shm_align_mask)) ++ if ((flags & MAP_SHARED) && ++ ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask)) + return -EINVAL; + return addr; + } +diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c +index 03035c8..3a82e65 100644 +--- a/arch/sparc/kernel/sys_sparc_32.c ++++ b/arch/sparc/kernel/sys_sparc_32.c +@@ -45,7 +45,8 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi + /* We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ +- if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) ++ if ((flags & MAP_SHARED) && ++ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) + return -EINVAL; + return addr; + } +@@ -79,15 +80,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi + } + } + +-asmlinkage unsigned long sparc_brk(unsigned long brk) +-{ +- if(ARCH_SUN4C) { +- if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000)) +- return current->mm->brk; +- } +- return sys_brk(brk); +-} +- + /* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. +@@ -234,31 +226,6 @@ int sparc_mmap_check(unsigned long addr, unsigned long len) + } + + /* Linux version of mmap */ +-static unsigned long do_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, unsigned long fd, +- unsigned long pgoff) +-{ +- struct file * file = NULL; +- unsigned long retval = -EBADF; +- +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- len = PAGE_ALIGN(len); +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- +- down_write(¤t->mm->mmap_sem); +- retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return retval; +-} + + asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, unsigned long fd, +@@ -266,14 +233,16 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, + { + /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE + we have. */ +- return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12)); ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, ++ pgoff >> (PAGE_SHIFT - 12)); + } + + asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, unsigned long fd, + unsigned long off) + { +- return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); ++ /* no alignment check? */ ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + } + + long sparc_remap_file_pages(unsigned long start, unsigned long size, +@@ -287,27 +256,6 @@ long sparc_remap_file_pages(unsigned long start, unsigned long size, + (pgoff >> (PAGE_SHIFT - 12)), flags); + } + +-extern unsigned long do_mremap(unsigned long addr, +- unsigned long old_len, unsigned long new_len, +- unsigned long flags, unsigned long new_addr); +- +-asmlinkage unsigned long sparc_mremap(unsigned long addr, +- unsigned long old_len, unsigned long new_len, +- unsigned long flags, unsigned long new_addr) +-{ +- unsigned long ret = -EINVAL; +- +- if (unlikely(sparc_mmap_check(addr, old_len))) +- goto out; +- if (unlikely(sparc_mmap_check(new_addr, new_len))) +- goto out; +- down_write(¤t->mm->mmap_sem); +- ret = do_mremap(addr, old_len, new_len, flags, new_addr); +- up_write(¤t->mm->mmap_sem); +-out: +- return ret; +-} +- + /* we come to here via sys_nis_syscall so it can setup the regs argument */ + asmlinkage unsigned long + c_sys_nis_syscall (struct pt_regs *regs) +diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c +index e2d1024..cfa0e19 100644 +--- a/arch/sparc/kernel/sys_sparc_64.c ++++ b/arch/sparc/kernel/sys_sparc_64.c +@@ -317,10 +317,14 @@ bottomup: + unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) + { + unsigned long align_goal, addr = -ENOMEM; ++ unsigned long (*get_area)(struct file *, unsigned long, ++ unsigned long, unsigned long, unsigned long); ++ ++ get_area = current->mm->get_unmapped_area; + + if (flags & MAP_FIXED) { + /* Ok, don't mess with it. */ +- return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); ++ return get_area(NULL, orig_addr, len, pgoff, flags); + } + flags &= ~MAP_SHARED; + +@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u + align_goal = (64UL * 1024); + + do { +- addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); ++ addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); + if (!(addr & ~PAGE_MASK)) { + addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); + break; +@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u + * be obtained. + */ + if (addr & ~PAGE_MASK) +- addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); ++ addr = get_area(NULL, orig_addr, len, pgoff, flags); + + return addr; + } +@@ -399,18 +403,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm) + } + } + +-SYSCALL_DEFINE1(sparc_brk, unsigned long, brk) +-{ +- /* People could try to be nasty and use ta 0x6d in 32bit programs */ +- if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) +- return current->mm->brk; +- +- if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk))) +- return current->mm->brk; +- +- return sys_brk(brk); +-} +- + /* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. +@@ -568,23 +560,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, off) + { +- struct file * file = NULL; +- unsigned long retval = -EBADF; +- +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- len = PAGE_ALIGN(len); ++ unsigned long retval = -EINVAL; + +- down_write(¤t->mm->mmap_sem); +- retval = do_mmap(file, addr, len, prot, flags, off); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); ++ if ((off + PAGE_ALIGN(len)) < off) ++ goto out; ++ if (off & ~PAGE_MASK) ++ goto out; ++ retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + out: + return retval; + } +@@ -614,12 +596,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, + + if (test_thread_flag(TIF_32BIT)) + goto out; +- if (unlikely(new_len >= VA_EXCLUDE_START)) +- goto out; +- if (unlikely(sparc_mmap_check(addr, old_len))) +- goto out; +- if (unlikely(sparc_mmap_check(new_addr, new_len))) +- goto out; + + down_write(¤t->mm->mmap_sem); + ret = do_mremap(addr, old_len, new_len, flags, new_addr); +diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h +index a63c5d2..d2f999a 100644 +--- a/arch/sparc/kernel/systbls.h ++++ b/arch/sparc/kernel/systbls.h +@@ -9,7 +9,6 @@ + struct new_utsname; + + extern asmlinkage unsigned long sys_getpagesize(void); +-extern asmlinkage unsigned long sparc_brk(unsigned long brk); + extern asmlinkage long sparc_pipe(struct pt_regs *regs); + extern asmlinkage long sys_ipc(unsigned int call, int first, + unsigned long second, +diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S +index 0f1658d..14f950a 100644 +--- a/arch/sparc/kernel/systbls_32.S ++++ b/arch/sparc/kernel/systbls_32.S +@@ -19,7 +19,7 @@ sys_call_table: + /*0*/ .long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write + /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link + /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod +-/*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek ++/*15*/ .long sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys_lseek + /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 + /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause + /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice +@@ -67,7 +67,7 @@ sys_call_table: + /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall + /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler + /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep +-/*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl ++/*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl + /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep + /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun + /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy +diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S +index 009825f..f63c871 100644 +--- a/arch/sparc/kernel/systbls_64.S ++++ b/arch/sparc/kernel/systbls_64.S +@@ -21,7 +21,7 @@ sys_call_table32: + /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write + /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link + /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod +-/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek ++/*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys32_perfctr, sys32_lseek + /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 + /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause + /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice +@@ -96,7 +96,7 @@ sys_call_table: + /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write + /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link + /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod +-/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek ++/*15*/ .word sys_chmod, sys_lchown, sys_brk, sys_perfctr, sys_lseek + /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid + /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall + /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice +diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c +index a4625c7..cccab85 100644 +--- a/arch/um/kernel/syscall.c ++++ b/arch/um/kernel/syscall.c +@@ -8,6 +8,7 @@ + #include "linux/mm.h" + #include "linux/sched.h" + #include "linux/utsname.h" ++#include "linux/syscalls.h" + #include "asm/current.h" + #include "asm/mman.h" + #include "asm/uaccess.h" +@@ -37,31 +38,6 @@ long sys_vfork(void) + return ret; + } + +-/* common code for old and new mmaps */ +-long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- long error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +- out: +- return error; +-} +- + long old_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long offset) +@@ -70,7 +46,7 @@ long old_mmap(unsigned long addr, unsigned long len, + if (offset & ~PAGE_MASK) + goto out; + +- err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); ++ err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + out: + return err; + } +diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h +index 9056981..e778767 100644 +--- a/arch/um/sys-i386/shared/sysdep/syscalls.h ++++ b/arch/um/sys-i386/shared/sysdep/syscalls.h +@@ -20,7 +20,3 @@ extern syscall_handler_t *sys_call_table[]; + #define EXECUTE_SYSCALL(syscall, regs) \ + ((long (*)(struct syscall_args)) \ + (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) +- +-extern long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff); +diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu +index 2649840..f2824fb 100644 +--- a/arch/x86/Kconfig.cpu ++++ b/arch/x86/Kconfig.cpu +@@ -400,7 +400,7 @@ config X86_TSC + + config X86_CMPXCHG64 + def_bool y +- depends on !M386 && !M486 ++ depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM + + # this should be set for all -march=.. options where the compiler + # generates cmov. +diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S +index 581b056..5294d84 100644 +--- a/arch/x86/ia32/ia32entry.S ++++ b/arch/x86/ia32/ia32entry.S +@@ -696,7 +696,7 @@ ia32_sys_call_table: + .quad quiet_ni_syscall /* streams2 */ + .quad stub32_vfork /* 190 */ + .quad compat_sys_getrlimit +- .quad sys32_mmap2 ++ .quad sys_mmap_pgoff + .quad sys32_truncate64 + .quad sys32_ftruncate64 + .quad sys32_stat64 /* 195 */ +diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c +index 9f55271..016218c 100644 +--- a/arch/x86/ia32/sys_ia32.c ++++ b/arch/x86/ia32/sys_ia32.c +@@ -155,9 +155,6 @@ struct mmap_arg_struct { + asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg) + { + struct mmap_arg_struct a; +- struct file *file = NULL; +- unsigned long retval; +- struct mm_struct *mm ; + + if (copy_from_user(&a, arg, sizeof(a))) + return -EFAULT; +@@ -165,22 +162,8 @@ asmlinkage long sys32_mmap(struct mmap_arg_struct __user *arg) + if (a.offset & ~PAGE_MASK) + return -EINVAL; + +- if (!(a.flags & MAP_ANONYMOUS)) { +- file = fget(a.fd); +- if (!file) +- return -EBADF; +- } +- +- mm = current->mm; +- down_write(&mm->mmap_sem); +- retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, ++ return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, + a.offset>>PAGE_SHIFT); +- if (file) +- fput(file); +- +- up_write(&mm->mmap_sem); +- +- return retval; + } + + asmlinkage long sys32_mprotect(unsigned long start, size_t len, +@@ -539,30 +522,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, + return ret; + } + +-asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- struct mm_struct *mm = current->mm; +- unsigned long error; +- struct file *file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- return -EBADF; +- } +- +- down_write(&mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(&mm->mmap_sem); +- +- if (file) +- fput(file); +- return error; +-} +- + asmlinkage long sys32_olduname(struct oldold_utsname __user *name) + { + char *arch = "x86_64"; +diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h +index 72a6dcd..77c1184 100644 +--- a/arch/x86/include/asm/sys_ia32.h ++++ b/arch/x86/include/asm/sys_ia32.h +@@ -62,9 +62,6 @@ asmlinkage long sys32_pwrite(unsigned int, char __user *, u32, u32, u32); + asmlinkage long sys32_personality(unsigned long); + asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32); + +-asmlinkage long sys32_mmap2(unsigned long, unsigned long, unsigned long, +- unsigned long, unsigned long, unsigned long); +- + struct oldold_utsname; + struct old_utsname; + asmlinkage long sys32_olduname(struct oldold_utsname __user *); +diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h +index 372b76e..1bb6e39 100644 +--- a/arch/x86/include/asm/syscalls.h ++++ b/arch/x86/include/asm/syscalls.h +@@ -55,8 +55,6 @@ struct sel_arg_struct; + struct oldold_utsname; + struct old_utsname; + +-asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, +- unsigned long, unsigned long, unsigned long); + asmlinkage int old_mmap(struct mmap_arg_struct __user *); + asmlinkage int old_select(struct sel_arg_struct __user *); + asmlinkage int sys_ipc(uint, int, int, int, void __user *, long); +diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c +index 1884a8d..dee1ff7 100644 +--- a/arch/x86/kernel/sys_i386_32.c ++++ b/arch/x86/kernel/sys_i386_32.c +@@ -24,31 +24,6 @@ + + #include + +-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file *file = NULL; +- struct mm_struct *mm = current->mm; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(&mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(&mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + /* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. Linux/i386 didn't use to be able to handle more than +@@ -77,7 +52,7 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) + if (a.offset & ~PAGE_MASK) + goto out; + +- err = sys_mmap2(a.addr, a.len, a.prot, a.flags, ++ err = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, + a.fd, a.offset >> PAGE_SHIFT); + out: + return err; +diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c +index 45e00eb..8aa2057 100644 +--- a/arch/x86/kernel/sys_x86_64.c ++++ b/arch/x86/kernel/sys_x86_64.c +@@ -23,26 +23,11 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, fd, unsigned long, off) + { + long error; +- struct file *file; +- + error = -EINVAL; + if (off & ~PAGE_MASK) + goto out; + +- error = -EBADF; +- file = NULL; +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); ++ error = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); + out: + return error; + } +diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S +index 0157cd2..76d70a4 100644 +--- a/arch/x86/kernel/syscall_table_32.S ++++ b/arch/x86/kernel/syscall_table_32.S +@@ -191,7 +191,7 @@ ENTRY(sys_call_table) + .long sys_ni_syscall /* reserved for streams2 */ + .long ptregs_vfork /* 190 */ + .long sys_getrlimit +- .long sys_mmap2 ++ .long sys_mmap_pgoff + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ +diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h +index 05cebf8..4352dbe 100644 +--- a/arch/xtensa/include/asm/syscall.h ++++ b/arch/xtensa/include/asm/syscall.h +@@ -13,8 +13,6 @@ struct sigaction; + asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); + asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); + asmlinkage long xtensa_pipe(int __user *); +-asmlinkage long xtensa_mmap2(unsigned long, unsigned long, unsigned long, +- unsigned long, unsigned long, unsigned long); + asmlinkage long xtensa_ptrace(long, long, long, long); + asmlinkage long xtensa_sigreturn(struct pt_regs*); + asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); +diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h +index c092c8f..9a5c354 100644 +--- a/arch/xtensa/include/asm/unistd.h ++++ b/arch/xtensa/include/asm/unistd.h +@@ -189,7 +189,7 @@ __SYSCALL( 79, sys_fremovexattr, 2) + /* File Map / Shared Memory Operations */ + + #define __NR_mmap2 80 +-__SYSCALL( 80, xtensa_mmap2, 6) ++__SYSCALL( 80, sys_mmap_pgoff, 6) + #define __NR_munmap 81 + __SYSCALL( 81, sys_munmap, 2) + #define __NR_mprotect 82 +diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c +index ac15ecb..1e67bab 100644 +--- a/arch/xtensa/kernel/syscall.c ++++ b/arch/xtensa/kernel/syscall.c +@@ -57,31 +57,6 @@ asmlinkage long xtensa_pipe(int __user *userfds) + return error; + } + +- +-asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len, +- unsigned long prot, unsigned long flags, +- unsigned long fd, unsigned long pgoff) +-{ +- int error = -EBADF; +- struct file * file = NULL; +- +- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); +- if (!(flags & MAP_ANONYMOUS)) { +- file = fget(fd); +- if (!file) +- goto out; +- } +- +- down_write(¤t->mm->mmap_sem); +- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); +- up_write(¤t->mm->mmap_sem); +- +- if (file) +- fput(file); +-out: +- return error; +-} +- + asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) + { + unsigned long ret; +diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c +index 3cb56a0..4dcfef0 100644 +--- a/drivers/char/agp/intel-agp.c ++++ b/drivers/char/agp/intel-agp.c +@@ -178,6 +178,7 @@ static struct _intel_private { + * popup and for the GTT. + */ + int gtt_entries; /* i830+ */ ++ int gtt_total_size; + union { + void __iomem *i9xx_flush_page; + void *i8xx_flush_page; +@@ -1153,7 +1154,7 @@ static int intel_i915_configure(void) + readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ + + if (agp_bridge->driver->needs_scratch_page) { +- for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { ++ for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) { + writel(agp_bridge->scratch_page, intel_private.gtt+i); + } + readl(intel_private.gtt+i-1); /* PCI Posting. */ +@@ -1308,6 +1309,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) + if (!intel_private.gtt) + return -ENOMEM; + ++ intel_private.gtt_total_size = gtt_map_size / 4; ++ + temp &= 0xfff80000; + + intel_private.registers = ioremap(temp, 128 * 4096); +@@ -1395,6 +1398,8 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) + if (!intel_private.gtt) + return -ENOMEM; + ++ intel_private.gtt_total_size = gtt_size / 4; ++ + intel_private.registers = ioremap(temp, 128 * 4096); + if (!intel_private.registers) { + iounmap(intel_private.gtt); +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index 6810443..73655ae 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + + #define BUCKETS 12 + #define RESOLUTION 1024 +@@ -169,6 +170,12 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices); + + static void menu_update(struct cpuidle_device *dev); + ++/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ ++static u64 div_round64(u64 dividend, u32 divisor) ++{ ++ return div_u64(dividend + (divisor / 2), divisor); ++} ++ + /** + * menu_select - selects the next idle state to enter + * @dev: the CPU +@@ -209,9 +216,8 @@ static int menu_select(struct cpuidle_device *dev) + data->correction_factor[data->bucket] = RESOLUTION * DECAY; + + /* Make sure to round up for half microseconds */ +- data->predicted_us = DIV_ROUND_CLOSEST( +- data->expected_us * data->correction_factor[data->bucket], +- RESOLUTION * DECAY); ++ data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], ++ RESOLUTION * DECAY); + + /* + * We want to default to C1 (hlt), not to busy polling +diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c +index 628eae3..a1fce68 100644 +--- a/drivers/gpu/drm/ati_pcigart.c ++++ b/drivers/gpu/drm/ati_pcigart.c +@@ -39,8 +39,7 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev, + struct drm_ati_pcigart_info *gart_info) + { + gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, +- PAGE_SIZE, +- gart_info->table_mask); ++ PAGE_SIZE); + if (gart_info->table_handle == NULL) + return -ENOMEM; + +@@ -112,6 +111,13 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { + DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); + ++ if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { ++ DRM_ERROR("fail to set dma mask to 0x%Lx\n", ++ gart_info->table_mask); ++ ret = 1; ++ goto done; ++ } ++ + ret = drm_ati_alloc_pcigart_table(dev, gart_info); + if (ret) { + DRM_ERROR("cannot allocate PCI GART page!\n"); +diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c +index 3d09e30..8417cc4 100644 +--- a/drivers/gpu/drm/drm_bufs.c ++++ b/drivers/gpu/drm/drm_bufs.c +@@ -326,7 +326,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, + * As we're limiting the address to 2^32-1 (or less), + * casting it down to 32 bits is no problem, but we + * need to point to a 64bit variable first. */ +- dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); ++ dmah = drm_pci_alloc(dev, map->size, map->size); + if (!dmah) { + kfree(map); + return -ENOMEM; +@@ -885,7 +885,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) + + while (entry->buf_count < count) { + +- dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful); ++ dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000); + + if (!dmah) { + /* Set count correctly so we free the proper amount. */ +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index 577094f..e68ebf9 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -47,8 +47,7 @@ + /** + * \brief Allocate a PCI consistent memory block, for DMA. + */ +-drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align, +- dma_addr_t maxaddr) ++drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align) + { + drm_dma_handle_t *dmah; + #if 1 +@@ -63,11 +62,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali + if (align > size) + return NULL; + +- if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) { +- DRM_ERROR("Setting pci dma mask failed\n"); +- return NULL; +- } +- + dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); + if (!dmah) + return NULL; +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index e5b138b..bc2db7d 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -123,7 +123,7 @@ static int i915_init_phys_hws(struct drm_device *dev) + drm_i915_private_t *dev_priv = dev->dev_private; + /* Program Hardware Status Page */ + dev_priv->status_page_dmah = +- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); ++ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); + + if (!dev_priv->status_page_dmah) { + DRM_ERROR("Can not allocate hardware status page\n"); +@@ -1111,7 +1111,8 @@ static void i915_setup_compression(struct drm_device *dev, int size) + { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_mm_node *compressed_fb, *compressed_llb; +- unsigned long cfb_base, ll_base; ++ unsigned long cfb_base; ++ unsigned long ll_base = 0; + + /* Leave 1M for line length buffer & misc. */ + compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index ecbafd0..791fded 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -546,6 +546,7 @@ typedef struct drm_i915_private { + struct timer_list idle_timer; + bool busy; + u16 orig_clock; ++ struct drm_connector *int_lvds_connector; + } drm_i915_private_t; + + /** driver private structure attached to each drm_gem_object */ +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 5ddbd38..df2c625 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2010,9 +2010,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) + /* blow away mappings if mapped through GTT */ + i915_gem_release_mmap(obj); + +- if (obj_priv->fence_reg != I915_FENCE_REG_NONE) +- i915_gem_clear_fence_reg(obj); +- + /* Move the object to the CPU domain to ensure that + * any possible CPU writes while it's not in the GTT + * are flushed when we go to remap it. This will +@@ -2028,6 +2025,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj) + + BUG_ON(obj_priv->active); + ++ /* release the fence reg _after_ flushing */ ++ if (obj_priv->fence_reg != I915_FENCE_REG_NONE) ++ i915_gem_clear_fence_reg(obj); ++ + if (obj_priv->agp_mem != NULL) { + drm_unbind_agp(obj_priv->agp_mem); + drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); +@@ -2570,9 +2571,6 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + bool retry_alloc = false; + int ret; + +- if (dev_priv->mm.suspended) +- return -EBUSY; +- + if (obj_priv->madv != I915_MADV_WILLNEED) { + DRM_ERROR("Attempting to bind a purgeable object\n"); + return -EINVAL; +@@ -4639,7 +4637,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, + + phys_obj->id = id; + +- phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff); ++ phys_obj->handle = drm_pci_alloc(dev, size, 0); + if (!phys_obj->handle) { + ret = -ENOMEM; + goto kfree_obj; +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 1687edf..54e5907 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -968,6 +968,8 @@ + #define LVDS_PORT_EN (1 << 31) + /* Selects pipe B for LVDS data. Must be set on pre-965. */ + #define LVDS_PIPEB_SELECT (1 << 30) ++/* LVDS dithering flag on 965/g4x platform */ ++#define LVDS_ENABLE_DITHER (1 << 25) + /* Enable border for unscaled (or aspect-scaled) display */ + #define LVDS_BORDER_ENABLE (1 << 15) + /* +@@ -1737,6 +1739,8 @@ + + /* Display & cursor control */ + ++/* dithering flag on Ironlake */ ++#define PIPE_ENABLE_DITHER (1 << 4) + /* Pipe A */ + #define PIPEADSL 0x70000 + #define PIPEACONF 0x70008 +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f1de53b..121b92e 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -1473,6 +1473,10 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; + u32 temp; + int tries = 5, j, n; ++ u32 pipe_bpc; ++ ++ temp = I915_READ(pipeconf_reg); ++ pipe_bpc = temp & PIPE_BPC_MASK; + + /* XXX: When our outputs are all unaware of DPMS modes other than off + * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. +@@ -1504,6 +1508,12 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + + /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ + temp = I915_READ(fdi_rx_reg); ++ /* ++ * make the BPC in FDI Rx be consistent with that in ++ * pipeconf reg. ++ */ ++ temp &= ~(0x7 << 16); ++ temp |= (pipe_bpc << 11); + I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | + FDI_SEL_PCDCLK | + FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ +@@ -1644,6 +1654,12 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + + /* enable PCH transcoder */ + temp = I915_READ(transconf_reg); ++ /* ++ * make the BPC in transcoder be consistent with ++ * that in pipeconf reg. ++ */ ++ temp &= ~PIPE_BPC_MASK; ++ temp |= pipe_bpc; + I915_WRITE(transconf_reg, temp | TRANS_ENABLE); + I915_READ(transconf_reg); + +@@ -1722,6 +1738,9 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + I915_READ(fdi_tx_reg); + + temp = I915_READ(fdi_rx_reg); ++ /* BPC in FDI rx is consistent with that in pipeconf */ ++ temp &= ~(0x07 << 16); ++ temp |= (pipe_bpc << 11); + I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); + I915_READ(fdi_rx_reg); + +@@ -1765,7 +1784,12 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + } + } + } +- ++ temp = I915_READ(transconf_reg); ++ /* BPC in transcoder is consistent with that in pipeconf */ ++ temp &= ~PIPE_BPC_MASK; ++ temp |= pipe_bpc; ++ I915_WRITE(transconf_reg, temp); ++ I915_READ(transconf_reg); + udelay(100); + + /* disable PCH DPLL */ +@@ -2877,6 +2901,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + + /* determine panel color depth */ + temp = I915_READ(pipeconf_reg); ++ temp &= ~PIPE_BPC_MASK; ++ if (is_lvds) { ++ int lvds_reg = I915_READ(PCH_LVDS); ++ /* the BPC will be 6 if it is 18-bit LVDS panel */ ++ if ((lvds_reg & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) ++ temp |= PIPE_8BPC; ++ else ++ temp |= PIPE_6BPC; ++ } else ++ temp |= PIPE_8BPC; ++ I915_WRITE(pipeconf_reg, temp); ++ I915_READ(pipeconf_reg); + + switch (temp & PIPE_BPC_MASK) { + case PIPE_8BPC: +@@ -3104,7 +3140,20 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + * appropriately here, but we need to look more thoroughly into how + * panels behave in the two modes. + */ +- ++ /* set the dithering flag */ ++ if (IS_I965G(dev)) { ++ if (dev_priv->lvds_dither) { ++ if (IS_IGDNG(dev)) ++ pipeconf |= PIPE_ENABLE_DITHER; ++ else ++ lvds |= LVDS_ENABLE_DITHER; ++ } else { ++ if (IS_IGDNG(dev)) ++ pipeconf &= ~PIPE_ENABLE_DITHER; ++ else ++ lvds &= ~LVDS_ENABLE_DITHER; ++ } ++ } + I915_WRITE(lvds_reg, lvds); + I915_READ(lvds_reg); + } +@@ -3688,125 +3737,6 @@ static void intel_gpu_idle_timer(unsigned long arg) + queue_work(dev_priv->wq, &dev_priv->idle_work); + } + +-void intel_increase_renderclock(struct drm_device *dev, bool schedule) +-{ +- drm_i915_private_t *dev_priv = dev->dev_private; +- +- if (IS_IGDNG(dev)) +- return; +- +- if (!dev_priv->render_reclock_avail) { +- DRM_DEBUG("not reclocking render clock\n"); +- return; +- } +- +- /* Restore render clock frequency to original value */ +- if (IS_G4X(dev) || IS_I9XX(dev)) +- pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); +- else if (IS_I85X(dev)) +- pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); +- DRM_DEBUG("increasing render clock frequency\n"); +- +- /* Schedule downclock */ +- if (schedule) +- mod_timer(&dev_priv->idle_timer, jiffies + +- msecs_to_jiffies(GPU_IDLE_TIMEOUT)); +-} +- +-void intel_decrease_renderclock(struct drm_device *dev) +-{ +- drm_i915_private_t *dev_priv = dev->dev_private; +- +- if (IS_IGDNG(dev)) +- return; +- +- if (!dev_priv->render_reclock_avail) { +- DRM_DEBUG("not reclocking render clock\n"); +- return; +- } +- +- if (IS_G4X(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; +- gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I965G(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; +- gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I945G(dev) || IS_I945GM(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; +- gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I915G(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; +- gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I85X(dev)) { +- u16 hpllcc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); +- +- /* Up to maximum... */ +- hpllcc &= ~GC_CLOCK_CONTROL_MASK; +- hpllcc |= GC_CLOCK_133_200; +- +- pci_write_config_word(dev->pdev, HPLLCC, hpllcc); +- } +- DRM_DEBUG("decreasing render clock frequency\n"); +-} +- +-/* Note that no increase function is needed for this - increase_renderclock() +- * will also rewrite these bits +- */ +-void intel_decrease_displayclock(struct drm_device *dev) +-{ +- if (IS_IGDNG(dev)) +- return; +- +- if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || +- IS_I915GM(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~0xf0; +- gcfgc |= 0x80; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } +-} +- + #define CRTC_IDLE_TIMEOUT 1000 /* ms */ + + static void intel_crtc_idle_timer(unsigned long arg) +@@ -3920,12 +3850,6 @@ static void intel_idle_update(struct work_struct *work) + + mutex_lock(&dev->struct_mutex); + +- /* GPU isn't processing, downclock it. */ +- if (!dev_priv->busy) { +- intel_decrease_renderclock(dev); +- intel_decrease_displayclock(dev); +- } +- + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + /* Skip inactive CRTCs */ + if (!crtc->fb) +@@ -3960,7 +3884,6 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) + return; + + dev_priv->busy = true; +- intel_increase_renderclock(dev, true); + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (!crtc->fb) +@@ -4465,7 +4388,6 @@ void intel_modeset_cleanup(struct drm_device *dev) + del_timer_sync(&intel_crtc->idle_timer); + } + +- intel_increase_renderclock(dev, false); + del_timer_sync(&dev_priv->idle_timer); + + mutex_unlock(&dev->struct_mutex); +diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c +index 05598ae..0e0e4b4 100644 +--- a/drivers/gpu/drm/i915/intel_lvds.c ++++ b/drivers/gpu/drm/i915/intel_lvds.c +@@ -679,7 +679,14 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, + struct drm_i915_private *dev_priv = + container_of(nb, struct drm_i915_private, lid_notifier); + struct drm_device *dev = dev_priv->dev; ++ struct drm_connector *connector = dev_priv->int_lvds_connector; + ++ /* ++ * check and update the status of LVDS connector after receiving ++ * the LID nofication event. ++ */ ++ if (connector) ++ connector->status = connector->funcs->detect(connector); + if (!acpi_lid_open()) { + dev_priv->modeset_on_lid = 1; + return NOTIFY_OK; +@@ -1085,6 +1092,8 @@ out: + DRM_DEBUG("lid notifier registration failed\n"); + dev_priv->lid_notifier.notifier_call = NULL; + } ++ /* keep the LVDS connector */ ++ dev_priv->int_lvds_connector = connector; + drm_sysfs_connector_add(connector); + return; + +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index 700e93a..c1f7ea0 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -374,7 +374,7 @@ config SENSORS_GL520SM + + config SENSORS_CORETEMP + tristate "Intel Core/Core2/Atom temperature sensor" +- depends on X86 && EXPERIMENTAL ++ depends on X86 && PCI && EXPERIMENTAL + help + If you say yes here you get support for the temperature + sensor inside your CPU. Most of the family 6 CPUs +diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c +index 1852f27..262c133 100644 +--- a/drivers/hwmon/adt7462.c ++++ b/drivers/hwmon/adt7462.c +@@ -97,7 +97,7 @@ I2C_CLIENT_INSMOD_1(adt7462); + #define ADT7462_PIN24_SHIFT 6 + #define ADT7462_PIN26_VOLT_INPUT 0x08 + #define ADT7462_PIN25_VOLT_INPUT 0x20 +-#define ADT7462_PIN28_SHIFT 6 /* cfg3 */ ++#define ADT7462_PIN28_SHIFT 4 /* cfg3 */ + #define ADT7462_PIN28_VOLT 0x5 + + #define ADT7462_REG_ALARM1 0xB8 +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index caef39c..2d7bcee 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -161,6 +162,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * + int usemsr_ee = 1; + int err; + u32 eax, edx; ++ struct pci_dev *host_bridge; + + /* Early chips have no MSR for TjMax */ + +@@ -168,11 +170,21 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * + usemsr_ee = 0; + } + +- /* Atoms seems to have TjMax at 90C */ ++ /* Atom CPUs */ + + if (c->x86_model == 0x1c) { + usemsr_ee = 0; +- tjmax = 90000; ++ ++ host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); ++ ++ if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL ++ && (host_bridge->device == 0xa000 /* NM10 based nettop */ ++ || host_bridge->device == 0xa010)) /* NM10 based netbook */ ++ tjmax = 100000; ++ else ++ tjmax = 90000; ++ ++ pci_dev_put(host_bridge); + } + + if ((c->x86_model > 0xe) && (usemsr_ee)) { +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 85f0e8c..1f552c6 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -85,7 +85,14 @@ static void mmc_blk_put(struct mmc_blk_data *md) + mutex_lock(&open_lock); + md->usage--; + if (md->usage == 0) { ++ int devmaj = MAJOR(disk_devt(md->disk)); + int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; ++ ++ if (!devmaj) ++ devidx = md->disk->first_minor >> MMC_SHIFT; ++ ++ blk_cleanup_queue(md->queue.queue); ++ + __clear_bit(devidx, dev_use); + + put_disk(md->disk); +@@ -613,6 +620,7 @@ static int mmc_blk_probe(struct mmc_card *card) + return 0; + + out: ++ mmc_cleanup_queue(&md->queue); + mmc_blk_put(md); + + return err; +diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c +index 49e5823..c5a7a85 100644 +--- a/drivers/mmc/card/queue.c ++++ b/drivers/mmc/card/queue.c +@@ -90,9 +90,10 @@ static void mmc_request(struct request_queue *q) + struct request *req; + + if (!mq) { +- printk(KERN_ERR "MMC: killing requests for dead queue\n"); +- while ((req = blk_fetch_request(q)) != NULL) ++ while ((req = blk_fetch_request(q)) != NULL) { ++ req->cmd_flags |= REQ_QUIET; + __blk_end_request_all(req, -EIO); ++ } + return; + } + +@@ -223,17 +224,18 @@ void mmc_cleanup_queue(struct mmc_queue *mq) + struct request_queue *q = mq->queue; + unsigned long flags; + +- /* Mark that we should start throwing out stragglers */ +- spin_lock_irqsave(q->queue_lock, flags); +- q->queuedata = NULL; +- spin_unlock_irqrestore(q->queue_lock, flags); +- + /* Make sure the queue isn't suspended, as that will deadlock */ + mmc_queue_resume(mq); + + /* Then terminate our worker thread */ + kthread_stop(mq->thread); + ++ /* Empty the queue */ ++ spin_lock_irqsave(q->queue_lock, flags); ++ q->queuedata = NULL; ++ blk_start_queue(q); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ + if (mq->bounce_sg) + kfree(mq->bounce_sg); + mq->bounce_sg = NULL; +@@ -245,8 +247,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq) + kfree(mq->bounce_buf); + mq->bounce_buf = NULL; + +- blk_cleanup_queue(mq->queue); +- + mq->card = NULL; + } + EXPORT_SYMBOL(mmc_cleanup_queue); +diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c +index 7918852..9a96550 100644 +--- a/drivers/net/wireless/ath/ath5k/eeprom.c ++++ b/drivers/net/wireless/ath/ath5k/eeprom.c +@@ -97,7 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; + int ret; + u16 val; +- u32 cksum, offset; ++ u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; + + /* + * Read values from EEPROM and store them in the capability structure +@@ -116,12 +116,38 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) + * Validate the checksum of the EEPROM date. There are some + * devices with invalid EEPROMs. + */ +- for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { ++ AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); ++ if (val) { ++ eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << ++ AR5K_EEPROM_SIZE_ENDLOC_SHIFT; ++ AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); ++ eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; ++ ++ /* ++ * Fail safe check to prevent stupid loops due ++ * to busted EEPROMs. XXX: This value is likely too ++ * big still, waiting on a better value. ++ */ ++ if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { ++ ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " ++ "%d (0x%04x) max expected: %d (0x%04x)\n", ++ eep_max, eep_max, ++ 3 * AR5K_EEPROM_INFO_MAX, ++ 3 * AR5K_EEPROM_INFO_MAX); ++ return -EIO; ++ } ++ } ++ ++ for (cksum = 0, offset = 0; offset < eep_max; offset++) { + AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); + cksum ^= val; + } + if (cksum != AR5K_EEPROM_INFO_CKSUM) { +- ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); ++ ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " ++ "checksum: 0x%04x eep_max: 0x%04x (%s)\n", ++ cksum, eep_max, ++ eep_max == AR5K_EEPROM_INFO_MAX ? ++ "default size" : "custom size"); + return -EIO; + } + +diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h +index 0123f35..473a483 100644 +--- a/drivers/net/wireless/ath/ath5k/eeprom.h ++++ b/drivers/net/wireless/ath/ath5k/eeprom.h +@@ -37,6 +37,14 @@ + #define AR5K_EEPROM_RFKILL_POLARITY_S 1 + + #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ ++ ++/* FLASH(EEPROM) Defines for AR531X chips */ ++#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */ ++#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */ ++#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0 ++#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4 ++#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12 ++ + #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ + #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ + #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) +diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c +index f4e2e84..99331ed 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-4965.c ++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c +@@ -2087,7 +2087,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, + struct ieee80211_tx_info *info; + struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->u.status); +- int tid = MAX_TID_COUNT; ++ int tid = MAX_TID_COUNT - 1; + int sta_id; + int freed; + u8 *qc = NULL; +diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h +index c2d9b7a..cea2ee2 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-dev.h ++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h +@@ -703,7 +703,7 @@ extern void iwl_txq_ctx_stop(struct iwl_priv *priv); + extern int iwl_queue_space(const struct iwl_queue *q); + static inline int iwl_queue_used(const struct iwl_queue *q, int i) + { +- return q->write_ptr > q->read_ptr ? ++ return q->write_ptr >= q->read_ptr ? + (i >= q->read_ptr && i < q->write_ptr) : + !(i < q->read_ptr && i >= q->write_ptr); + } +diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c +index 6c95af3..06d66a1 100644 +--- a/drivers/net/wireless/libertas/scan.c ++++ b/drivers/net/wireless/libertas/scan.c +@@ -399,11 +399,8 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan) + chan_count = lbs_scan_create_channel_list(priv, chan_list); + + netif_stop_queue(priv->dev); +- netif_carrier_off(priv->dev); +- if (priv->mesh_dev) { ++ if (priv->mesh_dev) + netif_stop_queue(priv->mesh_dev); +- netif_carrier_off(priv->mesh_dev); +- } + + /* Prepare to continue an interrupted scan */ + lbs_deb_scan("chan_count %d, scan_channel %d\n", +@@ -467,16 +464,13 @@ out2: + priv->scan_channel = 0; + + out: +- if (priv->connect_status == LBS_CONNECTED) { +- netif_carrier_on(priv->dev); +- if (!priv->tx_pending_len) +- netif_wake_queue(priv->dev); +- } +- if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { +- netif_carrier_on(priv->mesh_dev); +- if (!priv->tx_pending_len) +- netif_wake_queue(priv->mesh_dev); +- } ++ if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) ++ netif_wake_queue(priv->dev); ++ ++ if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) && ++ !priv->tx_pending_len) ++ netif_wake_queue(priv->mesh_dev); ++ + kfree(chan_list); + + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); +diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c +index f7a4701..473e5f2 100644 +--- a/drivers/rtc/rtc-cmos.c ++++ b/drivers/rtc/rtc-cmos.c +@@ -1099,9 +1099,9 @@ static int cmos_pnp_resume(struct pnp_dev *pnp) + #define cmos_pnp_resume NULL + #endif + +-static void cmos_pnp_shutdown(struct device *pdev) ++static void cmos_pnp_shutdown(struct pnp_dev *pnp) + { +- if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev)) ++ if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev)) + return; + + cmos_do_shutdown(); +@@ -1120,15 +1120,12 @@ static struct pnp_driver cmos_pnp_driver = { + .id_table = rtc_ids, + .probe = cmos_pnp_probe, + .remove = __exit_p(cmos_pnp_remove), ++ .shutdown = cmos_pnp_shutdown, + + /* flag ensures resume() gets called, and stops syslog spam */ + .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, + .suspend = cmos_pnp_suspend, + .resume = cmos_pnp_resume, +- .driver = { +- .name = (char *)driver_name, +- .shutdown = cmos_pnp_shutdown, +- } + }; + + #endif /* CONFIG_PNP */ +diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c +index c499793..5d42d55 100644 +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -102,15 +102,15 @@ static void do_suspend(void) + goto out_thaw; + } + ++ printk(KERN_DEBUG "suspending xenstore...\n"); ++ xs_suspend(); ++ + err = dpm_suspend_noirq(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); + goto out_resume; + } + +- printk(KERN_DEBUG "suspending xenstore...\n"); +- xs_suspend(); +- + err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); + + dpm_resume_noirq(PMSG_RESUME); +@@ -120,13 +120,13 @@ static void do_suspend(void) + cancelled = 1; + } + ++out_resume: + if (!cancelled) { + xen_arch_resume(); + xs_resume(); + } else + xs_suspend_cancel(); + +-out_resume: + dpm_resume_end(PMSG_RESUME); + + /* Make sure timer events get retriggered on all CPUs */ +diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c +index 6c10f74..6f7df0f 100644 +--- a/fs/exofs/inode.c ++++ b/fs/exofs/inode.c +@@ -731,13 +731,28 @@ static int exofs_write_begin_export(struct file *file, + fsdata); + } + ++static int exofs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *page, void *fsdata) ++{ ++ struct inode *inode = mapping->host; ++ /* According to comment in simple_write_end i_mutex is held */ ++ loff_t i_size = inode->i_size; ++ int ret; ++ ++ ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata); ++ if (i_size != inode->i_size) ++ mark_inode_dirty(inode); ++ return ret; ++} ++ + const struct address_space_operations exofs_aops = { + .readpage = exofs_readpage, + .readpages = exofs_readpages, + .writepage = exofs_writepage, + .writepages = exofs_writepages, + .write_begin = exofs_write_begin_export, +- .write_end = simple_write_end, ++ .write_end = exofs_write_end, + }; + + /****************************************************************************** +diff --git a/fs/fcntl.c b/fs/fcntl.c +index 2cf93ec..97e01dc 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -618,60 +618,90 @@ static DEFINE_RWLOCK(fasync_lock); + static struct kmem_cache *fasync_cache __read_mostly; + + /* +- * fasync_helper() is used by almost all character device drivers +- * to set up the fasync queue. It returns negative on error, 0 if it did +- * no changes and positive if it added/deleted the entry. ++ * Remove a fasync entry. If successfully removed, return ++ * positive and clear the FASYNC flag. If no entry exists, ++ * do nothing and return 0. ++ * ++ * NOTE! It is very important that the FASYNC flag always ++ * match the state "is the filp on a fasync list". ++ * ++ * We always take the 'filp->f_lock', in since fasync_lock ++ * needs to be irq-safe. + */ +-int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) ++static int fasync_remove_entry(struct file *filp, struct fasync_struct **fapp) + { + struct fasync_struct *fa, **fp; +- struct fasync_struct *new = NULL; + int result = 0; + +- if (on) { +- new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); +- if (!new) +- return -ENOMEM; ++ spin_lock(&filp->f_lock); ++ write_lock_irq(&fasync_lock); ++ for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { ++ if (fa->fa_file != filp) ++ continue; ++ *fp = fa->fa_next; ++ kmem_cache_free(fasync_cache, fa); ++ filp->f_flags &= ~FASYNC; ++ result = 1; ++ break; + } ++ write_unlock_irq(&fasync_lock); ++ spin_unlock(&filp->f_lock); ++ return result; ++} ++ ++/* ++ * Add a fasync entry. Return negative on error, positive if ++ * added, and zero if did nothing but change an existing one. ++ * ++ * NOTE! It is very important that the FASYNC flag always ++ * match the state "is the filp on a fasync list". ++ */ ++static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp) ++{ ++ struct fasync_struct *new, *fa, **fp; ++ int result = 0; ++ ++ new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; + +- /* +- * We need to take f_lock first since it's not an IRQ-safe +- * lock. +- */ + spin_lock(&filp->f_lock); + write_lock_irq(&fasync_lock); + for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { +- if (fa->fa_file == filp) { +- if(on) { +- fa->fa_fd = fd; +- kmem_cache_free(fasync_cache, new); +- } else { +- *fp = fa->fa_next; +- kmem_cache_free(fasync_cache, fa); +- result = 1; +- } +- goto out; +- } ++ if (fa->fa_file != filp) ++ continue; ++ fa->fa_fd = fd; ++ kmem_cache_free(fasync_cache, new); ++ goto out; + } + +- if (on) { +- new->magic = FASYNC_MAGIC; +- new->fa_file = filp; +- new->fa_fd = fd; +- new->fa_next = *fapp; +- *fapp = new; +- result = 1; +- } ++ new->magic = FASYNC_MAGIC; ++ new->fa_file = filp; ++ new->fa_fd = fd; ++ new->fa_next = *fapp; ++ *fapp = new; ++ result = 1; ++ filp->f_flags |= FASYNC; ++ + out: +- if (on) +- filp->f_flags |= FASYNC; +- else +- filp->f_flags &= ~FASYNC; + write_unlock_irq(&fasync_lock); + spin_unlock(&filp->f_lock); + return result; + } + ++/* ++ * fasync_helper() is used by almost all character device drivers ++ * to set up the fasync queue, and for regular files by the file ++ * lease code. It returns negative on error, 0 if it did no changes ++ * and positive if it added/deleted the entry. ++ */ ++int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) ++{ ++ if (!on) ++ return fasync_remove_entry(filp, fapp); ++ return fasync_add_entry(fd, filp, fapp); ++} ++ + EXPORT_SYMBOL(fasync_helper); + + void __kill_fasync(struct fasync_struct *fa, int sig, int band) +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index a293f02..570dd1c 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -774,12 +774,9 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp, + int (*fsync) (struct file *, struct dentry *, int); + int err; + +- err = filemap_fdatawrite(inode->i_mapping); ++ err = filemap_write_and_wait(inode->i_mapping); + if (err == 0 && fop && (fsync = fop->fsync)) + err = fsync(filp, dp, 0); +- if (err == 0) +- err = filemap_fdatawait(inode->i_mapping); +- + return err; + } + +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index c4d07a8..2534987 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -1425,6 +1425,9 @@ static void inode_sub_rsv_space(struct inode *inode, qsize_t number) + static qsize_t inode_get_rsv_space(struct inode *inode) + { + qsize_t ret; ++ ++ if (!inode->i_sb->dq_op->get_reserved_space) ++ return 0; + spin_lock(&inode->i_lock); + ret = *inode_reserved_space(inode); + spin_unlock(&inode->i_lock); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 9d3d684..7ad3faa 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1402,7 +1402,7 @@ extern int drm_ati_pcigart_cleanup(struct drm_device *dev, + struct drm_ati_pcigart_info * gart_info); + + extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size, +- size_t align, dma_addr_t maxaddr); ++ size_t align); + extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); + extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); + +diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h +index a990ace..93515c6 100644 +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -879,4 +879,8 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]); + asmlinkage long sys_perf_event_open( + struct perf_event_attr __user *attr_uptr, + pid_t pid, int cpu, int group_fd, unsigned long flags); ++ ++asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, ++ unsigned long prot, unsigned long flags, ++ unsigned long fd, unsigned long pgoff); + #endif +diff --git a/ipc/shm.c b/ipc/shm.c +index 464694e..11bec62 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -290,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file, + unsigned long flags) + { + struct shm_file_data *sfd = shm_file_data(file); +- return get_unmapped_area(sfd->file, addr, len, pgoff, flags); +-} +- +-int is_file_shm_hugepages(struct file *file) +-{ +- int ret = 0; +- +- if (file->f_op == &shm_file_operations) { +- struct shm_file_data *sfd; +- sfd = shm_file_data(file); +- ret = is_file_hugepages(sfd->file); +- } +- return ret; ++ return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, ++ pgoff, flags); + } + + static const struct file_operations shm_file_operations = { + .mmap = shm_mmap, + .fsync = shm_fsync, + .release = shm_release, ++}; ++ ++static const struct file_operations shm_file_operations_huge = { ++ .mmap = shm_mmap, ++ .fsync = shm_fsync, ++ .release = shm_release, + .get_unmapped_area = shm_get_unmapped_area, + }; + ++int is_file_shm_hugepages(struct file *file) ++{ ++ return file->f_op == &shm_file_operations_huge; ++} ++ + static const struct vm_operations_struct shm_vm_ops = { + .open = shm_open, /* callback for a new vm-area open */ + .close = shm_close, /* callback for when the vm-area is released */ +@@ -889,7 +889,10 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) + if (!sfd) + goto out_put_dentry; + +- file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); ++ file = alloc_file(path.mnt, path.dentry, f_mode, ++ is_file_hugepages(shp->shm_file) ? ++ &shm_file_operations_huge : ++ &shm_file_operations); + if (!file) + goto out_free; + ima_counts_get(file); +diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c +index 2451dc6..4b05bd9 100644 +--- a/kernel/audit_tree.c ++++ b/kernel/audit_tree.c +@@ -277,7 +277,7 @@ static void untag_chunk(struct node *p) + owner->root = NULL; + } + +- for (i = j = 0; i < size; i++, j++) { ++ for (i = j = 0; j <= size; i++, j++) { + struct audit_tree *s; + if (&chunk->owners[j] == p) { + list_del_init(&p->list); +@@ -290,7 +290,7 @@ static void untag_chunk(struct node *p) + if (!s) /* result of earlier fallback */ + continue; + get_tree(s); +- list_replace_init(&chunk->owners[i].list, &new->owners[j].list); ++ list_replace_init(&chunk->owners[j].list, &new->owners[i].list); + } + + list_replace_rcu(&chunk->hash, &new->hash); +@@ -373,15 +373,17 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) + for (n = 0; n < old->count; n++) { + if (old->owners[n].owner == tree) { + spin_unlock(&hash_lock); +- put_inotify_watch(watch); ++ put_inotify_watch(&old->watch); + return 0; + } + } + spin_unlock(&hash_lock); + + chunk = alloc_chunk(old->count + 1); +- if (!chunk) ++ if (!chunk) { ++ put_inotify_watch(&old->watch); + return -ENOMEM; ++ } + + mutex_lock(&inode->inotify_mutex); + if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) { +@@ -425,7 +427,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) + spin_unlock(&hash_lock); + inotify_evict_watch(&old->watch); + mutex_unlock(&inode->inotify_mutex); +- put_inotify_watch(&old->watch); ++ put_inotify_watch(&old->watch); /* pair to inotify_find_watch */ ++ put_inotify_watch(&old->watch); /* and kill it */ + return 0; + } + +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index 0249f4b..1fbcc74 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -2468,7 +2468,6 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp, + /* make sure l doesn't vanish out from under us */ + down_write(&l->mutex); + mutex_unlock(&cgrp->pidlist_mutex); +- l->use_count++; + return l; + } + } +diff --git a/kernel/module.c b/kernel/module.c +index 5842a71..dfa33e8 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -1030,11 +1030,23 @@ static int try_to_force_load(struct module *mod, const char *reason) + } + + #ifdef CONFIG_MODVERSIONS ++/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */ ++static unsigned long maybe_relocated(unsigned long crc, ++ const struct module *crc_owner) ++{ ++#ifdef ARCH_RELOCATES_KCRCTAB ++ if (crc_owner == NULL) ++ return crc - (unsigned long)reloc_start; ++#endif ++ return crc; ++} ++ + static int check_version(Elf_Shdr *sechdrs, + unsigned int versindex, + const char *symname, + struct module *mod, +- const unsigned long *crc) ++ const unsigned long *crc, ++ const struct module *crc_owner) + { + unsigned int i, num_versions; + struct modversion_info *versions; +@@ -1055,10 +1067,10 @@ static int check_version(Elf_Shdr *sechdrs, + if (strcmp(versions[i].name, symname) != 0) + continue; + +- if (versions[i].crc == *crc) ++ if (versions[i].crc == maybe_relocated(*crc, crc_owner)) + return 1; + DEBUGP("Found checksum %lX vs module %lX\n", +- *crc, versions[i].crc); ++ maybe_relocated(*crc, crc_owner), versions[i].crc); + goto bad_version; + } + +@@ -1081,7 +1093,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, + if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, + &crc, true, false)) + BUG(); +- return check_version(sechdrs, versindex, "module_layout", mod, crc); ++ return check_version(sechdrs, versindex, "module_layout", mod, crc, ++ NULL); + } + + /* First part is kernel version, which we ignore if module has crcs. */ +@@ -1099,7 +1112,8 @@ static inline int check_version(Elf_Shdr *sechdrs, + unsigned int versindex, + const char *symname, + struct module *mod, +- const unsigned long *crc) ++ const unsigned long *crc, ++ const struct module *crc_owner) + { + return 1; + } +@@ -1134,8 +1148,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, + /* use_module can fail due to OOM, + or module initialization or unloading */ + if (sym) { +- if (!check_version(sechdrs, versindex, name, mod, crc) || +- !use_module(mod, owner)) ++ if (!check_version(sechdrs, versindex, name, mod, crc, owner) ++ || !use_module(mod, owner)) + sym = NULL; + } + return sym; +@@ -1146,6 +1160,12 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, + * J. Corbet + */ + #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) ++ ++static inline bool sect_empty(const Elf_Shdr *sect) ++{ ++ return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; ++} ++ + struct module_sect_attr + { + struct module_attribute mattr; +@@ -1187,8 +1207,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, + + /* Count loaded sections and allocate structures */ + for (i = 0; i < nsect; i++) +- if (sechdrs[i].sh_flags & SHF_ALLOC +- && sechdrs[i].sh_size) ++ if (!sect_empty(&sechdrs[i])) + nloaded++; + size[0] = ALIGN(sizeof(*sect_attrs) + + nloaded * sizeof(sect_attrs->attrs[0]), +@@ -1206,9 +1225,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, + sattr = §_attrs->attrs[0]; + gattr = §_attrs->grp.attrs[0]; + for (i = 0; i < nsect; i++) { +- if (! (sechdrs[i].sh_flags & SHF_ALLOC)) +- continue; +- if (!sechdrs[i].sh_size) ++ if (sect_empty(&sechdrs[i])) + continue; + sattr->address = sechdrs[i].sh_addr; + sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, +@@ -1292,7 +1309,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, + /* Count notes sections and allocate structures. */ + notes = 0; + for (i = 0; i < nsect; i++) +- if ((sechdrs[i].sh_flags & SHF_ALLOC) && ++ if (!sect_empty(&sechdrs[i]) && + (sechdrs[i].sh_type == SHT_NOTE)) + ++notes; + +@@ -1308,7 +1325,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, + notes_attrs->notes = notes; + nattr = ¬es_attrs->attrs[0]; + for (loaded = i = 0; i < nsect; ++i) { +- if (!(sechdrs[i].sh_flags & SHF_ALLOC)) ++ if (sect_empty(&sechdrs[i])) + continue; + if (sechdrs[i].sh_type == SHT_NOTE) { + nattr->attr.name = mod->sect_attrs->attrs[loaded].name; +diff --git a/kernel/signal.c b/kernel/signal.c +index 6705320..4d0658d 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -939,7 +939,8 @@ static void print_fatal_signal(struct pt_regs *regs, int signr) + for (i = 0; i < 16; i++) { + unsigned char insn; + +- __get_user(insn, (unsigned char *)(regs->ip + i)); ++ if (get_user(insn, (unsigned char *)(regs->ip + i))) ++ break; + printk("%02x ", insn); + } + } +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index dd84be9..b8bd058 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -1200,7 +1200,6 @@ static struct ctl_table vm_table[] = { + .extra2 = (void *)&hugetlb_infinity, + }, + #endif +-#ifdef CONFIG_MMU + { + .ctl_name = VM_LOWMEM_RESERVE_RATIO, + .procname = "lowmem_reserve_ratio", +@@ -1346,6 +1345,7 @@ static struct ctl_table vm_table[] = { + .strategy = &sysctl_jiffies, + }, + #endif ++#ifdef CONFIG_MMU + { + .ctl_name = CTL_UNNUMBERED, + .procname = "mmap_min_addr", +diff --git a/lib/dma-debug.c b/lib/dma-debug.c +index 5a77c7c..084e879 100644 +--- a/lib/dma-debug.c ++++ b/lib/dma-debug.c +@@ -913,6 +913,9 @@ static void check_sync(struct device *dev, + ref->size); + } + ++ if (entry->direction == DMA_BIDIRECTIONAL) ++ goto out; ++ + if (ref->direction != entry->direction) { + err_printk(dev, entry, "DMA-API: device driver syncs " + "DMA memory with different direction " +@@ -923,9 +926,6 @@ static void check_sync(struct device *dev, + dir2name[ref->direction]); + } + +- if (entry->direction == DMA_BIDIRECTIONAL) +- goto out; +- + if (to_cpu && !(entry->direction == DMA_FROM_DEVICE) && + !(ref->direction == DMA_TO_DEVICE)) + err_printk(dev, entry, "DMA-API: device driver syncs " +@@ -948,7 +948,6 @@ static void check_sync(struct device *dev, + + out: + put_hash_bucket(bucket, &flags); +- + } + + void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, +diff --git a/lib/rational.c b/lib/rational.c +index b3c099b..3ed247b 100644 +--- a/lib/rational.c ++++ b/lib/rational.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + + /* + * calculate best rational approximation for a given fraction +diff --git a/mm/mmap.c b/mm/mmap.c +index 73f5e4b..ae19746 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -932,13 +932,9 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, + if (!(flags & MAP_FIXED)) + addr = round_hint_to_min(addr); + +- error = arch_mmap_check(addr, len, flags); +- if (error) +- return error; +- + /* Careful about overflows.. */ + len = PAGE_ALIGN(len); +- if (!len || len > TASK_SIZE) ++ if (!len) + return -ENOMEM; + + /* offset overflow? */ +@@ -949,24 +945,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, + if (mm->map_count > sysctl_max_map_count) + return -ENOMEM; + +- if (flags & MAP_HUGETLB) { +- struct user_struct *user = NULL; +- if (file) +- return -EINVAL; +- +- /* +- * VM_NORESERVE is used because the reservations will be +- * taken when vm_ops->mmap() is called +- * A dummy user value is used because we are not locking +- * memory so no accounting is necessary +- */ +- len = ALIGN(len, huge_page_size(&default_hstate)); +- file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, +- &user, HUGETLB_ANONHUGE_INODE); +- if (IS_ERR(file)) +- return PTR_ERR(file); +- } +- + /* Obtain the address to map to. we verify (or select) it and ensure + * that it represents a valid section of the address space. + */ +@@ -1459,6 +1437,14 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, + unsigned long (*get_area)(struct file *, unsigned long, + unsigned long, unsigned long, unsigned long); + ++ unsigned long error = arch_mmap_check(addr, len, flags); ++ if (error) ++ return error; ++ ++ /* Careful about overflows.. */ ++ if (len > TASK_SIZE) ++ return -ENOMEM; ++ + get_area = current->mm->get_unmapped_area; + if (file && file->f_op && file->f_op->get_unmapped_area) + get_area = file->f_op->get_unmapped_area; +@@ -2003,20 +1989,14 @@ unsigned long do_brk(unsigned long addr, unsigned long len) + if (!len) + return addr; + +- if ((addr + len) > TASK_SIZE || (addr + len) < addr) +- return -EINVAL; +- +- if (is_hugepage_only_range(mm, addr, len)) +- return -EINVAL; +- + error = security_file_mmap(NULL, 0, 0, 0, addr, 1); + if (error) + return error; + + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; + +- error = arch_mmap_check(addr, len, flags); +- if (error) ++ error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED); ++ if (error & ~PAGE_MASK) + return error; + + /* +diff --git a/mm/mremap.c b/mm/mremap.c +index 97bff25..8451908 100644 +--- a/mm/mremap.c ++++ b/mm/mremap.c +@@ -261,6 +261,137 @@ static unsigned long move_vma(struct vm_area_struct *vma, + return new_addr; + } + ++static struct vm_area_struct *vma_to_resize(unsigned long addr, ++ unsigned long old_len, unsigned long new_len, unsigned long *p) ++{ ++ struct mm_struct *mm = current->mm; ++ struct vm_area_struct *vma = find_vma(mm, addr); ++ ++ if (!vma || vma->vm_start > addr) ++ goto Efault; ++ ++ if (is_vm_hugetlb_page(vma)) ++ goto Einval; ++ ++ /* We can't remap across vm area boundaries */ ++ if (old_len > vma->vm_end - addr) ++ goto Efault; ++ ++ if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) { ++ if (new_len > old_len) ++ goto Efault; ++ } ++ ++ if (vma->vm_flags & VM_LOCKED) { ++ unsigned long locked, lock_limit; ++ locked = mm->locked_vm << PAGE_SHIFT; ++ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; ++ locked += new_len - old_len; ++ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) ++ goto Eagain; ++ } ++ ++ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) ++ goto Enomem; ++ ++ if (vma->vm_flags & VM_ACCOUNT) { ++ unsigned long charged = (new_len - old_len) >> PAGE_SHIFT; ++ if (security_vm_enough_memory(charged)) ++ goto Efault; ++ *p = charged; ++ } ++ ++ return vma; ++ ++Efault: /* very odd choice for most of the cases, but... */ ++ return ERR_PTR(-EFAULT); ++Einval: ++ return ERR_PTR(-EINVAL); ++Enomem: ++ return ERR_PTR(-ENOMEM); ++Eagain: ++ return ERR_PTR(-EAGAIN); ++} ++ ++static unsigned long mremap_to(unsigned long addr, ++ unsigned long old_len, unsigned long new_addr, ++ unsigned long new_len) ++{ ++ struct mm_struct *mm = current->mm; ++ struct vm_area_struct *vma; ++ unsigned long ret = -EINVAL; ++ unsigned long charged = 0; ++ unsigned long map_flags; ++ ++ if (new_addr & ~PAGE_MASK) ++ goto out; ++ ++ if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) ++ goto out; ++ ++ /* Check if the location we're moving into overlaps the ++ * old location at all, and fail if it does. ++ */ ++ if ((new_addr <= addr) && (new_addr+new_len) > addr) ++ goto out; ++ ++ if ((addr <= new_addr) && (addr+old_len) > new_addr) ++ goto out; ++ ++ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); ++ if (ret) ++ goto out; ++ ++ ret = do_munmap(mm, new_addr, new_len); ++ if (ret) ++ goto out; ++ ++ if (old_len >= new_len) { ++ ret = do_munmap(mm, addr+new_len, old_len - new_len); ++ if (ret && old_len != new_len) ++ goto out; ++ old_len = new_len; ++ } ++ ++ vma = vma_to_resize(addr, old_len, new_len, &charged); ++ if (IS_ERR(vma)) { ++ ret = PTR_ERR(vma); ++ goto out; ++ } ++ ++ map_flags = MAP_FIXED; ++ if (vma->vm_flags & VM_MAYSHARE) ++ map_flags |= MAP_SHARED; ++ ++ ret = get_unmapped_area(vma->vm_file, new_addr, new_len, vma->vm_pgoff + ++ ((addr - vma->vm_start) >> PAGE_SHIFT), ++ map_flags); ++ if (ret & ~PAGE_MASK) ++ goto out1; ++ ++ ret = move_vma(vma, addr, old_len, new_len, new_addr); ++ if (!(ret & ~PAGE_MASK)) ++ goto out; ++out1: ++ vm_unacct_memory(charged); ++ ++out: ++ return ret; ++} ++ ++static int vma_expandable(struct vm_area_struct *vma, unsigned long delta) ++{ ++ unsigned long end = vma->vm_end + delta; ++ if (end < vma->vm_end) /* overflow */ ++ return 0; ++ if (vma->vm_next && vma->vm_next->vm_start < end) /* intersection */ ++ return 0; ++ if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start, ++ 0, MAP_FIXED) & ~PAGE_MASK) ++ return 0; ++ return 1; ++} ++ + /* + * Expand (or shrink) an existing mapping, potentially moving it at the + * same time (controlled by the MREMAP_MAYMOVE flag and available VM space) +@@ -294,32 +425,10 @@ unsigned long do_mremap(unsigned long addr, + if (!new_len) + goto out; + +- /* new_addr is only valid if MREMAP_FIXED is specified */ + if (flags & MREMAP_FIXED) { +- if (new_addr & ~PAGE_MASK) +- goto out; +- if (!(flags & MREMAP_MAYMOVE)) +- goto out; +- +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) +- goto out; +- +- /* Check if the location we're moving into overlaps the +- * old location at all, and fail if it does. +- */ +- if ((new_addr <= addr) && (new_addr+new_len) > addr) +- goto out; +- +- if ((addr <= new_addr) && (addr+old_len) > new_addr) +- goto out; +- +- ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); +- if (ret) +- goto out; +- +- ret = do_munmap(mm, new_addr, new_len); +- if (ret) +- goto out; ++ if (flags & MREMAP_MAYMOVE) ++ ret = mremap_to(addr, old_len, new_addr, new_len); ++ goto out; + } + + /* +@@ -332,60 +441,23 @@ unsigned long do_mremap(unsigned long addr, + if (ret && old_len != new_len) + goto out; + ret = addr; +- if (!(flags & MREMAP_FIXED) || (new_addr == addr)) +- goto out; +- old_len = new_len; ++ goto out; + } + + /* +- * Ok, we need to grow.. or relocate. ++ * Ok, we need to grow.. + */ +- ret = -EFAULT; +- vma = find_vma(mm, addr); +- if (!vma || vma->vm_start > addr) +- goto out; +- if (is_vm_hugetlb_page(vma)) { +- ret = -EINVAL; +- goto out; +- } +- /* We can't remap across vm area boundaries */ +- if (old_len > vma->vm_end - addr) +- goto out; +- if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) { +- if (new_len > old_len) +- goto out; +- } +- if (vma->vm_flags & VM_LOCKED) { +- unsigned long locked, lock_limit; +- locked = mm->locked_vm << PAGE_SHIFT; +- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; +- locked += new_len - old_len; +- ret = -EAGAIN; +- if (locked > lock_limit && !capable(CAP_IPC_LOCK)) +- goto out; +- } +- if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) { +- ret = -ENOMEM; ++ vma = vma_to_resize(addr, old_len, new_len, &charged); ++ if (IS_ERR(vma)) { ++ ret = PTR_ERR(vma); + goto out; + } + +- if (vma->vm_flags & VM_ACCOUNT) { +- charged = (new_len - old_len) >> PAGE_SHIFT; +- if (security_vm_enough_memory(charged)) +- goto out_nc; +- } +- + /* old_len exactly to the end of the area.. +- * And we're not relocating the area. + */ +- if (old_len == vma->vm_end - addr && +- !((flags & MREMAP_FIXED) && (addr != new_addr)) && +- (old_len != new_len || !(flags & MREMAP_MAYMOVE))) { +- unsigned long max_addr = TASK_SIZE; +- if (vma->vm_next) +- max_addr = vma->vm_next->vm_start; ++ if (old_len == vma->vm_end - addr) { + /* can we just expand the current mapping? */ +- if (max_addr - addr >= new_len) { ++ if (vma_expandable(vma, new_len - old_len)) { + int pages = (new_len - old_len) >> PAGE_SHIFT; + + vma_adjust(vma, vma->vm_start, +@@ -409,28 +481,27 @@ unsigned long do_mremap(unsigned long addr, + */ + ret = -ENOMEM; + if (flags & MREMAP_MAYMOVE) { +- if (!(flags & MREMAP_FIXED)) { +- unsigned long map_flags = 0; +- if (vma->vm_flags & VM_MAYSHARE) +- map_flags |= MAP_SHARED; +- +- new_addr = get_unmapped_area(vma->vm_file, 0, new_len, +- vma->vm_pgoff, map_flags); +- if (new_addr & ~PAGE_MASK) { +- ret = new_addr; +- goto out; +- } +- +- ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); +- if (ret) +- goto out; ++ unsigned long map_flags = 0; ++ if (vma->vm_flags & VM_MAYSHARE) ++ map_flags |= MAP_SHARED; ++ ++ new_addr = get_unmapped_area(vma->vm_file, 0, new_len, ++ vma->vm_pgoff + ++ ((addr - vma->vm_start) >> PAGE_SHIFT), ++ map_flags); ++ if (new_addr & ~PAGE_MASK) { ++ ret = new_addr; ++ goto out; + } ++ ++ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); ++ if (ret) ++ goto out; + ret = move_vma(vma, addr, old_len, new_len, new_addr); + } + out: + if (ret & ~PAGE_MASK) + vm_unacct_memory(charged); +-out_nc: + return ret; + } + +diff --git a/mm/util.c b/mm/util.c +index 7c35ad9..b377ce4 100644 +--- a/mm/util.c ++++ b/mm/util.c +@@ -4,6 +4,10 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + #include + + #define CREATE_TRACE_POINTS +@@ -268,6 +272,46 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start, + } + EXPORT_SYMBOL_GPL(get_user_pages_fast); + ++SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, ++ unsigned long, prot, unsigned long, flags, ++ unsigned long, fd, unsigned long, pgoff) ++{ ++ struct file * file = NULL; ++ unsigned long retval = -EBADF; ++ ++ if (!(flags & MAP_ANONYMOUS)) { ++ if (unlikely(flags & MAP_HUGETLB)) ++ return -EINVAL; ++ file = fget(fd); ++ if (!file) ++ goto out; ++ } else if (flags & MAP_HUGETLB) { ++ struct user_struct *user = NULL; ++ /* ++ * VM_NORESERVE is used because the reservations will be ++ * taken when vm_ops->mmap() is called ++ * A dummy user value is used because we are not locking ++ * memory so no accounting is necessary ++ */ ++ len = ALIGN(len, huge_page_size(&default_hstate)); ++ file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, ++ &user, HUGETLB_ANONHUGE_INODE); ++ if (IS_ERR(file)) ++ return PTR_ERR(file); ++ } ++ ++ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); ++ ++ down_write(¤t->mm->mmap_sem); ++ retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); ++ up_write(¤t->mm->mmap_sem); ++ ++ if (file) ++ fput(file); ++out: ++ return retval; ++} ++ + /* Tracepoints definitions. */ + EXPORT_TRACEPOINT_SYMBOL(kmalloc); + EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); +diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c +index bd1c654..0b7f262 100644 +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -1406,6 +1406,9 @@ static int do_ebt_set_ctl(struct sock *sk, + { + int ret; + ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ + switch(cmd) { + case EBT_SO_SET_ENTRIES: + ret = do_replace(sock_net(sk), user, len); +@@ -1425,6 +1428,9 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + struct ebt_replace tmp; + struct ebt_table *t; + ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ + if (copy_from_user(&tmp, user, sizeof(tmp))) + return -EFAULT; + +diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c +index df159ff..4bac362 100644 +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -559,6 +559,11 @@ static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb) + return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev); + } + ++static inline struct net *ipv6_skb_net(struct sk_buff *skb) ++{ ++ return skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev); ++} ++ + /* Router Alert as of RFC 2711 */ + + static int ipv6_hop_ra(struct sk_buff *skb, int optoff) +@@ -580,8 +585,8 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff) + static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) + { + const unsigned char *nh = skb_network_header(skb); ++ struct net *net = ipv6_skb_net(skb); + u32 pkt_len; +- struct net *net = dev_net(skb_dst(skb)->dev); + + if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { + LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index b8295cb..079c500 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -15,12 +15,14 @@ + #include + #include + #include ++#include + #include "ieee80211_i.h" + #include "sta_info.h" + #include "debugfs_netdev.h" + #include "mesh.h" + #include "led.h" + #include "driver-ops.h" ++#include "wme.h" + + /** + * DOC: Interface list locking +@@ -642,6 +644,12 @@ static void ieee80211_teardown_sdata(struct net_device *dev) + WARN_ON(flushed); + } + ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); ++} ++ + static const struct net_device_ops ieee80211_dataif_ops = { + .ndo_open = ieee80211_open, + .ndo_stop = ieee80211_stop, +@@ -650,8 +658,35 @@ static const struct net_device_ops ieee80211_dataif_ops = { + .ndo_set_multicast_list = ieee80211_set_multicast_list, + .ndo_change_mtu = ieee80211_change_mtu, + .ndo_set_mac_address = eth_mac_addr, ++ .ndo_select_queue = ieee80211_netdev_select_queue, + }; + ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hdr *hdr; ++ struct ieee80211_radiotap_header *rtap = (void *)skb->data; ++ ++ if (local->hw.queues < 4) ++ return 0; ++ ++ if (skb->len < 4 || ++ skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */) ++ return 0; /* doesn't matter, frame will be dropped */ ++ ++ hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); ++ ++ if (!ieee80211_is_data(hdr->frame_control)) { ++ skb->priority = 7; ++ return ieee802_1d_to_ac[skb->priority]; ++ } ++ ++ skb->priority = 0; ++ return ieee80211_downgrade_queue(local, skb); ++} ++ + static const struct net_device_ops ieee80211_monitorif_ops = { + .ndo_open = ieee80211_open, + .ndo_stop = ieee80211_stop, +@@ -660,6 +695,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { + .ndo_set_multicast_list = ieee80211_set_multicast_list, + .ndo_change_mtu = ieee80211_change_mtu, + .ndo_set_mac_address = eth_mac_addr, ++ .ndo_select_queue = ieee80211_monitor_select_queue, + }; + + static void ieee80211_if_setup(struct net_device *dev) +@@ -768,8 +804,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, + + ASSERT_RTNL(); + +- ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, +- name, ieee80211_if_setup); ++ ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size, ++ name, ieee80211_if_setup, local->hw.queues); + if (!ndev) + return -ENOMEM; + dev_net_set(ndev, wiphy_net(local->hw.wiphy)); +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index f13d181..6cae295 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1953,7 +1953,9 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, + rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); + break; + case IEEE80211_STYPE_ACTION: +- /* XXX: differentiate, can only happen for CSA now! */ ++ if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) ++ break; ++ + ieee80211_sta_process_chanswitch(sdata, + &mgmt->u.action.u.chan_switch.sw_elem, + ifmgd->associated); +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 4e14754..16c6cdc 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1548,7 +1548,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) + memset(info, 0, sizeof(*info)); + info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; + info->control.vif = &rx->sdata->vif; +- ieee80211_select_queue(local, fwd_skb); ++ skb_set_queue_mapping(skb, ++ ieee80211_select_queue(rx->sdata, fwd_skb)); ++ ieee80211_set_qos_hdr(local, skb); + if (is_multicast_ether_addr(fwd_hdr->addr1)) + IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, + fwded_mcast); +@@ -1808,6 +1810,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) + } + break; + default: ++ /* do not process rejected action frames */ ++ if (mgmt->u.action.category & 0x80) ++ return RX_DROP_MONITOR; ++ + return RX_CONTINUE; + } + +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index d398197..441f68e 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1482,7 +1482,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, + return; + } + +- ieee80211_select_queue(local, skb); ++ ieee80211_set_qos_hdr(local, skb); + ieee80211_tx(sdata, skb, false); + dev_put(sdata->dev); + } +@@ -2226,6 +2226,9 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, + if (!encrypt) + info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + ++ /* send all internal mgmt frames on VO */ ++ skb_set_queue_mapping(skb, 0); ++ + /* + * The other path calling ieee80211_xmit is from the tasklet, + * and while we can handle concurrent transmissions locking +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 51e0bd2..553cffe 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -269,6 +269,7 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, + enum queue_stop_reason reason) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct ieee80211_sub_if_data *sdata; + + if (WARN_ON(queue >= hw->queues)) + return; +@@ -281,6 +282,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, + + if (!skb_queue_empty(&local->pending[queue])) + tasklet_schedule(&local->tx_pending_tasklet); ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(sdata, &local->interfaces, list) ++ netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); ++ rcu_read_unlock(); + } + + void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, +@@ -305,11 +311,17 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, + enum queue_stop_reason reason) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct ieee80211_sub_if_data *sdata; + + if (WARN_ON(queue >= hw->queues)) + return; + + __set_bit(reason, &local->queue_stop_reasons[queue]); ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(sdata, &local->interfaces, list) ++ netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); ++ rcu_read_unlock(); + } + + void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, +diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c +index b19b769..6d32ebf 100644 +--- a/net/mac80211/wme.c ++++ b/net/mac80211/wme.c +@@ -44,22 +44,62 @@ static int wme_downgrade_ac(struct sk_buff *skb) + } + + +-/* Indicate which queue to use. */ +-static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb) ++/* Indicate which queue to use. */ ++u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; ++ struct ieee80211_local *local = sdata->local; ++ struct sta_info *sta = NULL; ++ u32 sta_flags = 0; ++ const u8 *ra = NULL; ++ bool qos = false; + +- if (!ieee80211_is_data(hdr->frame_control)) { +- /* management frames go on AC_VO queue, but are sent +- * without QoS control fields */ +- return 0; ++ if (local->hw.queues < 4 || skb->len < 6) { ++ skb->priority = 0; /* required for correct WPA/11i MIC */ ++ return min_t(u16, local->hw.queues - 1, ++ ieee802_1d_to_ac[skb->priority]); + } + +- if (0 /* injected */) { +- /* use AC from radiotap */ ++ rcu_read_lock(); ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP_VLAN: ++ case NL80211_IFTYPE_AP: ++ ra = skb->data; ++ break; ++ case NL80211_IFTYPE_WDS: ++ ra = sdata->u.wds.remote_addr; ++ break; ++#ifdef CONFIG_MAC80211_MESH ++ case NL80211_IFTYPE_MESH_POINT: ++ /* ++ * XXX: This is clearly broken ... but already was before, ++ * because ieee80211_fill_mesh_addresses() would clear A1 ++ * except for multicast addresses. ++ */ ++ break; ++#endif ++ case NL80211_IFTYPE_STATION: ++ ra = sdata->u.mgd.bssid; ++ break; ++ case NL80211_IFTYPE_ADHOC: ++ ra = skb->data; ++ break; ++ default: ++ break; + } + +- if (!ieee80211_is_data_qos(hdr->frame_control)) { ++ if (!sta && ra && !is_multicast_ether_addr(ra)) { ++ sta = sta_info_get(local, ra); ++ if (sta) ++ sta_flags = get_sta_flags(sta); ++ } ++ ++ if (sta_flags & WLAN_STA_WME) ++ qos = true; ++ ++ rcu_read_unlock(); ++ ++ if (!qos) { + skb->priority = 0; /* required for correct WPA/11i MIC */ + return ieee802_1d_to_ac[skb->priority]; + } +@@ -68,6 +108,12 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb) + * data frame has */ + skb->priority = cfg80211_classify8021d(skb); + ++ return ieee80211_downgrade_queue(local, skb); ++} ++ ++u16 ieee80211_downgrade_queue(struct ieee80211_local *local, ++ struct sk_buff *skb) ++{ + /* in case we are a client verify acm is not set for this ac */ + while (unlikely(local->wmm_acm & BIT(skb->priority))) { + if (wme_downgrade_ac(skb)) { +@@ -85,24 +131,17 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb) + return ieee802_1d_to_ac[skb->priority]; + } + +-void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb) ++void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +- u16 queue; +- u8 tid; +- +- queue = classify80211(local, skb); +- if (unlikely(queue >= local->hw.queues)) +- queue = local->hw.queues - 1; +- +- /* +- * Now we know the 1d priority, fill in the QoS header if +- * there is one (and we haven't done this before). +- */ ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ ++ /* Fill in the QoS header if there is one. */ + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *p = ieee80211_get_qos_ctl(hdr); +- u8 ack_policy = 0; ++ u8 ack_policy = 0, tid; ++ + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ + if (unlikely(local->wifi_wme_noack_test)) + ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << + QOS_CONTROL_ACK_POLICY_SHIFT; +@@ -110,6 +149,4 @@ void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb) + *p++ = ack_policy | tid; + *p = 0; + } +- +- skb_set_queue_mapping(skb, queue); + } +diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h +index d4fd87c..6053b1c 100644 +--- a/net/mac80211/wme.h ++++ b/net/mac80211/wme.h +@@ -20,7 +20,11 @@ + + extern const int ieee802_1d_to_ac[8]; + +-void ieee80211_select_queue(struct ieee80211_local *local, +- struct sk_buff *skb); ++u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb); ++void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb); ++u16 ieee80211_downgrade_queue(struct ieee80211_local *local, ++ struct sk_buff *skb); ++ + + #endif /* _WME_H */ +diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c +index 5509dd1..7dfd469 100644 +--- a/net/netfilter/nf_conntrack_ftp.c ++++ b/net/netfilter/nf_conntrack_ftp.c +@@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq, + struct nf_ct_ftp_master *info, int dir, + struct sk_buff *skb) + { +- unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; ++ unsigned int i, oldest; + + /* Look for oldest: if we find exact match, we're done. */ + for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { + if (info->seq_aft_nl[dir][i] == nl_seq) + return; +- +- if (oldest == info->seq_aft_nl_num[dir] || +- before(info->seq_aft_nl[dir][i], +- info->seq_aft_nl[dir][oldest])) +- oldest = i; + } + + if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { + info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; +- } else if (oldest != NUM_SEQ_TO_REMEMBER && +- after(nl_seq, info->seq_aft_nl[dir][oldest])) { +- info->seq_aft_nl[dir][oldest] = nl_seq; ++ } else { ++ if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1])) ++ oldest = 0; ++ else ++ oldest = 1; ++ ++ if (after(nl_seq, info->seq_aft_nl[dir][oldest])) ++ info->seq_aft_nl[dir][oldest] = nl_seq; + } + } + +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 129d75e..9c5a19d 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -644,7 +644,22 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) + p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); + if (IS_ERR(p)) { + err = PTR_ERR(p); +- gss_msg->msg.errno = (err == -EAGAIN) ? -EAGAIN : -EACCES; ++ switch (err) { ++ case -EACCES: ++ gss_msg->msg.errno = err; ++ err = mlen; ++ break; ++ case -EFAULT: ++ case -ENOMEM: ++ case -EINVAL: ++ case -ENOSYS: ++ gss_msg->msg.errno = -EAGAIN; ++ break; ++ default: ++ printk(KERN_CRIT "%s: bad return from " ++ "gss_fill_context: %ld\n", __func__, err); ++ BUG(); ++ } + goto err_release_msg; + } + gss_msg->ctx = gss_get_ctx(ctx); +diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c +index ef45eba..2deb0ed 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -131,8 +131,10 @@ gss_import_sec_context_kerberos(const void *p, + struct krb5_ctx *ctx; + int tmp; + +- if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) ++ if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) { ++ p = ERR_PTR(-ENOMEM); + goto out_err; ++ } + + p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); + if (IS_ERR(p)) +diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c +index 6efbb0c..76e4c6f 100644 +--- a/net/sunrpc/auth_gss/gss_mech_switch.c ++++ b/net/sunrpc/auth_gss/gss_mech_switch.c +@@ -252,7 +252,7 @@ gss_import_sec_context(const void *input_token, size_t bufsize, + struct gss_ctx **ctx_id) + { + if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL))) +- return GSS_S_FAILURE; ++ return -ENOMEM; + (*ctx_id)->mech_type = gss_mech_get(mech); + + return mech->gm_ops +diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c +index df124f7..0266cca 100644 +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -711,7 +711,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) + spin_unlock_bh(&pool->sp_lock); + + len = 0; +- if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { ++ if (test_bit(XPT_LISTENER, &xprt->xpt_flags) && ++ !test_bit(XPT_CLOSE, &xprt->xpt_flags)) { + struct svc_xprt *newxpt; + newxpt = xprt->xpt_ops->xpo_accept(xprt); + if (newxpt) { +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index f256dff..efd24a7 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1714,7 +1714,7 @@ int regulatory_hint_user(const char *alpha2) + request->wiphy_idx = WIPHY_IDX_STALE; + request->alpha2[0] = alpha2[0]; + request->alpha2[1] = alpha2[1]; +- request->initiator = NL80211_REGDOM_SET_BY_USER, ++ request->initiator = NL80211_REGDOM_SET_BY_USER; + + queue_regulatory_request(request); + +diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c +index 7337abd..67ca440 100644 +--- a/sound/pci/ac97/ac97_patch.c ++++ b/sound/pci/ac97/ac97_patch.c +@@ -1870,6 +1870,7 @@ static unsigned int ad1981_jacks_blacklist[] = { + 0x10140554, /* Thinkpad T42p/R50p */ + 0x10140567, /* Thinkpad T43p 2668-G7U */ + 0x10140581, /* Thinkpad X41-2527 */ ++ 0x10280160, /* Dell Dimension 2400 */ + 0x104380b0, /* Asus A7V8X-MX */ + 0x11790241, /* Toshiba Satellite A-15 S127 */ + 0x144dc01a, /* Samsung NP-X20C004/SEG */ +diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c +index d6752df..42b4fbb 100644 +--- a/sound/pci/atiixp.c ++++ b/sound/pci/atiixp.c +@@ -297,6 +297,7 @@ static struct pci_device_id snd_atiixp_ids[] = { + MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); + + static struct snd_pci_quirk atiixp_quirks[] __devinitdata = { ++ SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0), + SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0), + { } /* terminator */ + }; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index e40d31f..a4cb183 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -15323,7 +15323,7 @@ static struct alc_config_preset alc861vd_presets[] = { + static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, + const struct auto_pin_cfg *cfg) + { +- return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); ++ return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); + } + + +diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c +index 593d5b9..2089fe7 100644 +--- a/sound/soc/codecs/wm8350.c ++++ b/sound/soc/codecs/wm8350.c +@@ -925,7 +925,7 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) + iface |= 0x3 << 8; + break; + case SND_SOC_DAIFMT_DSP_B: +- iface |= 0x3 << 8; /* lg not sure which mode */ ++ iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV; + break; + default: + return -EINVAL; +diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c +index 060d5d0..8db62e2 100644 +--- a/sound/soc/codecs/wm8510.c ++++ b/sound/soc/codecs/wm8510.c +@@ -425,23 +425,23 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, + + /* filter coefficient */ + switch (params_rate(params)) { +- case SNDRV_PCM_RATE_8000: ++ case 8000: + adn |= 0x5 << 1; + break; +- case SNDRV_PCM_RATE_11025: ++ case 11025: + adn |= 0x4 << 1; + break; +- case SNDRV_PCM_RATE_16000: ++ case 16000: + adn |= 0x3 << 1; + break; +- case SNDRV_PCM_RATE_22050: ++ case 22050: + adn |= 0x2 << 1; + break; +- case SNDRV_PCM_RATE_32000: ++ case 32000: + adn |= 0x1 << 1; + break; +- case SNDRV_PCM_RATE_44100: +- case SNDRV_PCM_RATE_48000: ++ case 44100: ++ case 48000: + break; + } + +diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c +index 1ef2454..63bc2ae 100644 +--- a/sound/soc/codecs/wm8940.c ++++ b/sound/soc/codecs/wm8940.c +@@ -379,23 +379,23 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream, + iface |= (1 << 9); + + switch (params_rate(params)) { +- case SNDRV_PCM_RATE_8000: ++ case 8000: + addcntrl |= (0x5 << 1); + break; +- case SNDRV_PCM_RATE_11025: ++ case 11025: + addcntrl |= (0x4 << 1); + break; +- case SNDRV_PCM_RATE_16000: ++ case 16000: + addcntrl |= (0x3 << 1); + break; +- case SNDRV_PCM_RATE_22050: ++ case 22050: + addcntrl |= (0x2 << 1); + break; +- case SNDRV_PCM_RATE_32000: ++ case 32000: + addcntrl |= (0x1 << 1); + break; +- case SNDRV_PCM_RATE_44100: +- case SNDRV_PCM_RATE_48000: ++ case 44100: ++ case 48000: + break; + } + ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl); +diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c +index b0bd1c0..0dbf6fe 100644 +--- a/sound/soc/codecs/wm8974.c ++++ b/sound/soc/codecs/wm8974.c +@@ -480,23 +480,23 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream, + + /* filter coefficient */ + switch (params_rate(params)) { +- case SNDRV_PCM_RATE_8000: ++ case 8000: + adn |= 0x5 << 1; + break; +- case SNDRV_PCM_RATE_11025: ++ case 11025: + adn |= 0x4 << 1; + break; +- case SNDRV_PCM_RATE_16000: ++ case 16000: + adn |= 0x3 << 1; + break; +- case SNDRV_PCM_RATE_22050: ++ case 22050: + adn |= 0x2 << 1; + break; +- case SNDRV_PCM_RATE_32000: ++ case 32000: + adn |= 0x1 << 1; + break; +- case SNDRV_PCM_RATE_44100: +- case SNDRV_PCM_RATE_48000: ++ case 44100: ++ case 48000: + break; + } + diff --git a/debian/patches/debian/mremap-fix-conflict-between-2.6.32.4-and-vserver.patch b/debian/patches/debian/mremap-fix-conflict-between-2.6.32.4-and-vserver.patch new file mode 100644 index 000000000..78a71f97e --- /dev/null +++ b/debian/patches/debian/mremap-fix-conflict-between-2.6.32.4-and-vserver.patch @@ -0,0 +1,32 @@ +From: Ben Hutchings +Subject: [PATCH] mm/mremap: Fix conflict between 2.6.32.4 and vserver + +Make some cosmetic changes to the reworked mremap in 2.6.32.4 so that +the vserver patch will still apply (with fuzz 1). + +--- a/mm/mremap.c ++++ b/mm/mremap.c +@@ -288,11 +288,11 @@ + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + locked += new_len - old_len; + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) +- goto Eagain; ++ goto out; + } +- +- if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) ++ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) { + goto Enomem; ++ } + + if (vma->vm_flags & VM_ACCOUNT) { + unsigned long charged = (new_len - old_len) >> PAGE_SHIFT; +@@ -309,7 +309,7 @@ + return ERR_PTR(-EINVAL); + Enomem: + return ERR_PTR(-ENOMEM); +-Eagain: ++out: + return ERR_PTR(-EAGAIN); + } + diff --git a/debian/patches/series/6 b/debian/patches/series/6 index e665bdd7d..bad8cf6f8 100644 --- a/debian/patches/series/6 +++ b/debian/patches/series/6 @@ -12,9 +12,6 @@ + features/x86/iTCO_wdt-Add-support-for-Intel-Ibex-Peak.patch + bugfix/all/Documentation-3c509-document-ethtool-support.patch + bugfix/all/drm-i915-disable-powersave.patch -+ bugfix/all/intel-agp-Clear-entire-GTT-on-startup.patch -+ bugfix/all/drm-remove-address-mask-param-for-drm_pci_alloc.patch -+ bugfix/all/fasync-split-fasync_helper.patch + features/all/module-firmware/0025-tty-declare-MODULE_FIRMWARE-in-various-drivers.patch + features/all/module-firmware/0026-staging-declare-MODULE_FIRMWARE-in-various-drivers.patch + features/all/module-firmware/0027-sep-include-driver-name-in-firmware-filenames.patch @@ -25,3 +22,7 @@ + features/all/rt28x0sta-constify-RTUSBMultiWrite-RTUSBFirmwareWrite.patch + features/all/rt28x0sta-use-request_firmware.patch + features/all/rt3090sta-use-request_firmware.patch +- bugfix/all/modules-Skip-empty-section-notes.patch +- bugfix/all/ath5k-Fix-eeprom-checksum-check-for-custom-sized-eeproms.patch ++ bugfix/all/stable/2.6.32.4.patch ++ debian/mremap-fix-conflict-between-2.6.32.4-and-vserver.patch