10156411bSCatalin Marinas /* 20156411bSCatalin Marinas * arch/arm64/kernel/sys32.c 30156411bSCatalin Marinas * 40156411bSCatalin Marinas * Copyright (C) 2015 ARM Ltd. 50156411bSCatalin Marinas * 60156411bSCatalin Marinas * This program is free software(void); you can redistribute it and/or modify 70156411bSCatalin Marinas * it under the terms of the GNU General Public License version 2 as 80156411bSCatalin Marinas * published by the Free Software Foundation. 90156411bSCatalin Marinas * 100156411bSCatalin Marinas * This program is distributed in the hope that it will be useful, 110156411bSCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of 120156411bSCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 130156411bSCatalin Marinas * GNU General Public License for more details. 140156411bSCatalin Marinas * 150156411bSCatalin Marinas * You should have received a copy of the GNU General Public License 160156411bSCatalin Marinas * along with this program. If not, see <http(void);//www.gnu.org/licenses/>. 170156411bSCatalin Marinas */ 180156411bSCatalin Marinas 190156411bSCatalin Marinas /* 200156411bSCatalin Marinas * Needed to avoid conflicting __NR_* macros between uapi/asm/unistd.h and 210156411bSCatalin Marinas * asm/unistd32.h. 220156411bSCatalin Marinas */ 230156411bSCatalin Marinas #define __COMPAT_SYSCALL_NR 240156411bSCatalin Marinas 2555f84926SMark Rutland #include <linux/compat.h> 260156411bSCatalin Marinas #include <linux/compiler.h> 270156411bSCatalin Marinas #include <linux/syscalls.h> 280156411bSCatalin Marinas 2927d83e68SMark Rutland #include <asm/syscall.h> 3027d83e68SMark Rutland 313085e164SMark Rutland asmlinkage long compat_sys_sigreturn(void); 323085e164SMark Rutland asmlinkage long compat_sys_rt_sigreturn(void); 3355f84926SMark Rutland 3455f84926SMark Rutland COMPAT_SYSCALL_DEFINE3(aarch32_statfs64, const char __user *, pathname, 3555f84926SMark Rutland compat_size_t, sz, struct compat_statfs64 __user *, buf) 3655f84926SMark Rutland { 3755f84926SMark Rutland /* 3855f84926SMark Rutland * 32-bit ARM applies an OABI compatibility fixup to statfs64 and 3955f84926SMark Rutland * fstatfs64 regardless of whether OABI is in use, and therefore 4055f84926SMark Rutland * arbitrary binaries may rely upon it, so we must do the same. 4155f84926SMark Rutland * For more details, see commit: 4255f84926SMark Rutland * 4355f84926SMark Rutland * 713c481519f19df9 ("[ARM] 3108/2: old ABI compat: statfs64 and 4455f84926SMark Rutland * fstatfs64") 4555f84926SMark Rutland */ 4655f84926SMark Rutland if (sz == 88) 4755f84926SMark Rutland sz = 84; 4855f84926SMark Rutland 4955f84926SMark Rutland return kcompat_sys_statfs64(pathname, sz, buf); 5055f84926SMark Rutland } 5155f84926SMark Rutland 5255f84926SMark Rutland COMPAT_SYSCALL_DEFINE3(aarch32_fstatfs64, unsigned int, fd, compat_size_t, sz, 5355f84926SMark Rutland struct compat_statfs64 __user *, buf) 5455f84926SMark Rutland { 5555f84926SMark Rutland /* see aarch32_statfs64 */ 5655f84926SMark Rutland if (sz == 88) 5755f84926SMark Rutland sz = 84; 5855f84926SMark Rutland 5955f84926SMark Rutland return kcompat_sys_fstatfs64(fd, sz, buf); 6055f84926SMark Rutland } 6155f84926SMark Rutland 6255f84926SMark Rutland /* 6355f84926SMark Rutland * Note: off_4k is always in units of 4K. If we can't do the 6455f84926SMark Rutland * requested offset because it is not page-aligned, we return -EINVAL. 6555f84926SMark Rutland */ 6655f84926SMark Rutland COMPAT_SYSCALL_DEFINE6(aarch32_mmap2, unsigned long, addr, unsigned long, len, 6755f84926SMark Rutland unsigned long, prot, unsigned long, flags, 6855f84926SMark Rutland unsigned long, fd, unsigned long, off_4k) 6955f84926SMark Rutland { 7055f84926SMark Rutland if (off_4k & (~PAGE_MASK >> 12)) 7155f84926SMark Rutland return -EINVAL; 7255f84926SMark Rutland 7355f84926SMark Rutland off_4k >>= (PAGE_SHIFT - 12); 7455f84926SMark Rutland 7555f84926SMark Rutland return ksys_mmap_pgoff(addr, len, prot, flags, fd, off_4k); 7655f84926SMark Rutland } 7755f84926SMark Rutland 7855f84926SMark Rutland #ifdef CONFIG_CPU_BIG_ENDIAN 7955f84926SMark Rutland #define arg_u32p(name) u32, name##_hi, u32, name##_lo 8055f84926SMark Rutland #else 8155f84926SMark Rutland #define arg_u32p(name) u32, name##_lo, u32, name##_hi 8255f84926SMark Rutland #endif 8355f84926SMark Rutland 8455f84926SMark Rutland #define arg_u64(name) (((u64)name##_hi << 32) | name##_lo) 8555f84926SMark Rutland 8655f84926SMark Rutland COMPAT_SYSCALL_DEFINE6(aarch32_pread64, unsigned int, fd, char __user *, buf, 8755f84926SMark Rutland size_t, count, u32, __pad, arg_u32p(pos)) 8855f84926SMark Rutland { 8955f84926SMark Rutland return ksys_pread64(fd, buf, count, arg_u64(pos)); 9055f84926SMark Rutland } 9155f84926SMark Rutland 9255f84926SMark Rutland COMPAT_SYSCALL_DEFINE6(aarch32_pwrite64, unsigned int, fd, 9355f84926SMark Rutland const char __user *, buf, size_t, count, u32, __pad, 9455f84926SMark Rutland arg_u32p(pos)) 9555f84926SMark Rutland { 9655f84926SMark Rutland return ksys_pwrite64(fd, buf, count, arg_u64(pos)); 9755f84926SMark Rutland } 9855f84926SMark Rutland 9955f84926SMark Rutland COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname, 10055f84926SMark Rutland u32, __pad, arg_u32p(length)) 10155f84926SMark Rutland { 10255f84926SMark Rutland return ksys_truncate(pathname, arg_u64(length)); 10355f84926SMark Rutland } 10455f84926SMark Rutland 10555f84926SMark Rutland COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad, 10655f84926SMark Rutland arg_u32p(length)) 10755f84926SMark Rutland { 10855f84926SMark Rutland return ksys_ftruncate(fd, arg_u64(length)); 10955f84926SMark Rutland } 11055f84926SMark Rutland 11155f84926SMark Rutland COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad, 11255f84926SMark Rutland arg_u32p(offset), size_t, count) 11355f84926SMark Rutland { 11455f84926SMark Rutland return ksys_readahead(fd, arg_u64(offset), count); 11555f84926SMark Rutland } 11655f84926SMark Rutland 11755f84926SMark Rutland COMPAT_SYSCALL_DEFINE6(aarch32_fadvise64_64, int, fd, int, advice, 11855f84926SMark Rutland arg_u32p(offset), arg_u32p(len)) 11955f84926SMark Rutland { 12055f84926SMark Rutland return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice); 12155f84926SMark Rutland } 12255f84926SMark Rutland 12355f84926SMark Rutland COMPAT_SYSCALL_DEFINE6(aarch32_sync_file_range2, int, fd, unsigned int, flags, 12455f84926SMark Rutland arg_u32p(offset), arg_u32p(nbytes)) 12555f84926SMark Rutland { 12655f84926SMark Rutland return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes), 12755f84926SMark Rutland flags); 12855f84926SMark Rutland } 12955f84926SMark Rutland 13055f84926SMark Rutland COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode, 13155f84926SMark Rutland arg_u32p(offset), arg_u32p(len)) 13255f84926SMark Rutland { 13355f84926SMark Rutland return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len)); 13455f84926SMark Rutland } 1350156411bSCatalin Marinas 1360156411bSCatalin Marinas #undef __SYSCALL 13727d83e68SMark Rutland #define __SYSCALL(nr, sym) [nr] = (syscall_fn_t)sym, 1380156411bSCatalin Marinas 13980d63bc3SMark Rutland const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = { 14027d83e68SMark Rutland [0 ... __NR_compat_syscalls - 1] = (syscall_fn_t)sys_ni_syscall, 1410156411bSCatalin Marinas #include <asm/unistd32.h> 1420156411bSCatalin Marinas }; 143