4652 lines
138 KiB
Diff
4652 lines
138 KiB
Diff
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 <asm-generic/mman.h>
|
|
+
|
|
+#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 <linux/ipc.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
-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 <linux/errno.h>
|
|
-#include <linux/fs.h>
|
|
-#include <linux/file.h>
|
|
-#include <linux/mm.h>
|
|
#include <linux/unistd.h>
|
|
|
|
-#include <asm/mman.h>
|
|
-#include <asm/uaccess.h>
|
|
-#include <asm/syscalls.h>
|
|
-
|
|
-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 <asm/cacheflush.h>
|
|
#include <asm/dma.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)
|
|
-{
|
|
- 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 <asm/uaccess.h>
|
|
#include <asm/segment.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)
|
|
-{
|
|
- 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 <asm/traps.h>
|
|
#include <asm/unistd.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)
|
|
-{
|
|
- 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 <asm/page.h>
|
|
#include <asm/unistd.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)
|
|
-{
|
|
- 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 <asm/cacheflush.h>
|
|
#include <asm/unistd.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)
|
|
-{
|
|
- 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 <asm-generic/mman.h>
|
|
+
|
|
+#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 <asm/uaccess.h>
|
|
|
|
-#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 <asm/uaccess.h>
|
|
#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 <asm/cacheflush.h>
|
|
#include <asm/cachectl.h>
|
|
|
|
-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 <asm/syscalls.h>
|
|
|
|
-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 <linux/hrtimer.h>
|
|
#include <linux/tick.h>
|
|
#include <linux/sched.h>
|
|
+#include <linux/math64.h>
|
|
|
|
#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 <linux/list.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/cpu.h>
|
|
+#include <linux/pci.h>
|
|
#include <asm/msr.h>
|
|
#include <asm/processor.h>
|
|
|
|
@@ -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 <corbet@lwn.net>
|
|
*/
|
|
#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 <linux/rational.h>
|
|
+#include <linux/module.h>
|
|
|
|
/*
|
|
* 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 <linux/module.h>
|
|
#include <linux/err.h>
|
|
#include <linux/sched.h>
|
|
+#include <linux/hugetlb.h>
|
|
+#include <linux/syscalls.h>
|
|
+#include <linux/mman.h>
|
|
+#include <linux/file.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
#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 <linux/netdevice.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <net/mac80211.h>
|
|
+#include <net/ieee80211_radiotap.h>
|
|
#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;
|
|
}
|
|
|