linux/arch/arm64/kernel/sys32.c
<<
>>
Prefs
   1/*
   2 * arch/arm64/kernel/sys32.c
   3 *
   4 * Copyright (C) 2015 ARM Ltd.
   5 *
   6 * This program is free software(void); you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program.  If not, see <http(void);//www.gnu.org/licenses/>.
  17 */
  18
  19/*
  20 * Needed to avoid conflicting __NR_* macros between uapi/asm/unistd.h and
  21 * asm/unistd32.h.
  22 */
  23#define __COMPAT_SYSCALL_NR
  24
  25#include <linux/compat.h>
  26#include <linux/compiler.h>
  27#include <linux/syscalls.h>
  28
  29#include <asm/syscall.h>
  30
  31asmlinkage long compat_sys_sigreturn(void);
  32asmlinkage long compat_sys_rt_sigreturn(void);
  33
  34COMPAT_SYSCALL_DEFINE3(aarch32_statfs64, const char __user *, pathname,
  35                       compat_size_t, sz, struct compat_statfs64 __user *, buf)
  36{
  37        /*
  38         * 32-bit ARM applies an OABI compatibility fixup to statfs64 and
  39         * fstatfs64 regardless of whether OABI is in use, and therefore
  40         * arbitrary binaries may rely upon it, so we must do the same.
  41         * For more details, see commit:
  42         *
  43         * 713c481519f19df9 ("[ARM] 3108/2: old ABI compat: statfs64 and
  44         * fstatfs64")
  45         */
  46        if (sz == 88)
  47                sz = 84;
  48
  49        return kcompat_sys_statfs64(pathname, sz, buf);
  50}
  51
  52COMPAT_SYSCALL_DEFINE3(aarch32_fstatfs64, unsigned int, fd, compat_size_t, sz,
  53                       struct compat_statfs64 __user *, buf)
  54{
  55        /* see aarch32_statfs64 */
  56        if (sz == 88)
  57                sz = 84;
  58
  59        return kcompat_sys_fstatfs64(fd, sz, buf);
  60}
  61
  62/*
  63 * Note: off_4k is always in units of 4K. If we can't do the
  64 * requested offset because it is not page-aligned, we return -EINVAL.
  65 */
  66COMPAT_SYSCALL_DEFINE6(aarch32_mmap2, unsigned long, addr, unsigned long, len,
  67                       unsigned long, prot, unsigned long, flags,
  68                       unsigned long, fd, unsigned long, off_4k)
  69{
  70        if (off_4k & (~PAGE_MASK >> 12))
  71                return -EINVAL;
  72
  73        off_4k >>= (PAGE_SHIFT - 12);
  74
  75        return ksys_mmap_pgoff(addr, len, prot, flags, fd, off_4k);
  76}
  77
  78#ifdef CONFIG_CPU_BIG_ENDIAN
  79#define arg_u32p(name)  u32, name##_hi, u32, name##_lo
  80#else
  81#define arg_u32p(name)  u32, name##_lo, u32, name##_hi
  82#endif
  83
  84#define arg_u64(name)   (((u64)name##_hi << 32) | name##_lo)
  85
  86COMPAT_SYSCALL_DEFINE6(aarch32_pread64, unsigned int, fd, char __user *, buf,
  87                       size_t, count, u32, __pad, arg_u32p(pos))
  88{
  89        return ksys_pread64(fd, buf, count, arg_u64(pos));
  90}
  91
  92COMPAT_SYSCALL_DEFINE6(aarch32_pwrite64, unsigned int, fd,
  93                       const char __user *, buf, size_t, count, u32, __pad,
  94                       arg_u32p(pos))
  95{
  96        return ksys_pwrite64(fd, buf, count, arg_u64(pos));
  97}
  98
  99COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname,
 100                       u32, __pad, arg_u32p(length))
 101{
 102        return ksys_truncate(pathname, arg_u64(length));
 103}
 104
 105COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad,
 106                       arg_u32p(length))
 107{
 108        return ksys_ftruncate(fd, arg_u64(length));
 109}
 110
 111COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad,
 112                       arg_u32p(offset), size_t, count)
 113{
 114        return ksys_readahead(fd, arg_u64(offset), count);
 115}
 116
 117COMPAT_SYSCALL_DEFINE6(aarch32_fadvise64_64, int, fd, int, advice,
 118                       arg_u32p(offset), arg_u32p(len))
 119{
 120        return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice);
 121}
 122
 123COMPAT_SYSCALL_DEFINE6(aarch32_sync_file_range2, int, fd, unsigned int, flags,
 124                       arg_u32p(offset), arg_u32p(nbytes))
 125{
 126        return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes),
 127                                    flags);
 128}
 129
 130COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
 131                       arg_u32p(offset), arg_u32p(len))
 132{
 133        return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
 134}
 135
 136asmlinkage long sys_ni_syscall(const struct pt_regs *);
 137#define __arm64_sys_ni_syscall  sys_ni_syscall
 138
 139#undef __SYSCALL
 140#define __SYSCALL(nr, sym)      asmlinkage long __arm64_##sym(const struct pt_regs *);
 141#include <asm/unistd32.h>
 142
 143#undef __SYSCALL
 144#define __SYSCALL(nr, sym)      [nr] = (syscall_fn_t)__arm64_##sym,
 145
 146const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = {
 147        [0 ... __NR_compat_syscalls - 1] = (syscall_fn_t)sys_ni_syscall,
 148#include <asm/unistd32.h>
 149};
 150