arm64: fix implementation of mmap2 compat syscall
authorAndreas Schwab <schwab@suse.de>
Mon, 16 Mar 2015 16:32:22 +0000 (16:32 +0000)
committerWill Deacon <will.deacon@arm.com>
Thu, 19 Mar 2015 10:43:51 +0000 (10:43 +0000)
The arm mmap2 syscall takes the offset in units of 4K, thus with 64K pages
the offset needs to be scaled to units of pages.

Signed-off-by: Andreas Schwab <schwab@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
[will: removed redundant lr parameter, localised PAGE_SHIFT #if check]
Signed-off-by: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/unistd32.h
arch/arm64/kernel/entry32.S
arch/arm64/kernel/sys32.c

index 27224426e0bf920de713c22cd4b6ca125c84d9bf..cef934a90f17ecec303a1dcd12133a962f27b9d1 100644 (file)
@@ -406,7 +406,7 @@ __SYSCALL(__NR_vfork, sys_vfork)
 #define __NR_ugetrlimit 191    /* SuS compliant getrlimit */
 __SYSCALL(__NR_ugetrlimit, compat_sys_getrlimit)               /* SuS compliant getrlimit */
 #define __NR_mmap2 192
-__SYSCALL(__NR_mmap2, sys_mmap_pgoff)
+__SYSCALL(__NR_mmap2, compat_sys_mmap2_wrapper)
 #define __NR_truncate64 193
 __SYSCALL(__NR_truncate64, compat_sys_truncate64_wrapper)
 #define __NR_ftruncate64 194
index 9a8f6ae2530e701741f1c8ddb1eff677abbd7ab1..bd9bfaa9269bc59980e89209e22ac0286288f9ef 100644 (file)
  */
 
 #include <linux/linkage.h>
+#include <linux/const.h>
 
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
+#include <asm/errno.h>
+#include <asm/page.h>
 
 /*
  * System call wrappers for the AArch32 compatibility layer.
@@ -53,6 +56,21 @@ ENTRY(compat_sys_fstatfs64_wrapper)
        b       compat_sys_fstatfs64
 ENDPROC(compat_sys_fstatfs64_wrapper)
 
+/*
+ * Note: off_4k (w5) is always in units of 4K. If we can't do the
+ * requested offset because it is not page-aligned, we return -EINVAL.
+ */
+ENTRY(compat_sys_mmap2_wrapper)
+#if PAGE_SHIFT > 12
+       tst     w5, #~PAGE_MASK >> 12
+       b.ne    1f
+       lsr     w5, w5, #PAGE_SHIFT - 12
+#endif
+       b       sys_mmap_pgoff
+1:     mov     x0, #-EINVAL
+       ret
+ENDPROC(compat_sys_mmap2_wrapper)
+
 /*
  * Wrappers for AArch32 syscalls that either take 64-bit parameters
  * in registers or that take 32-bit parameters which require sign
index 2d5ab3c90b820f1b40e0a7a0098cafa4992721ea..a40b1343b819f86bdf4a0e80f143a12425f8fd6b 100644 (file)
@@ -37,6 +37,7 @@ asmlinkage long compat_sys_readahead_wrapper(void);
 asmlinkage long compat_sys_fadvise64_64_wrapper(void);
 asmlinkage long compat_sys_sync_file_range2_wrapper(void);
 asmlinkage long compat_sys_fallocate_wrapper(void);
+asmlinkage long compat_sys_mmap2_wrapper(void);
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym)     [nr] = sym,