Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

riscv: compat: syscall: Add compat_sys_call_table implementation

Implement compat sys_call_table and some system call functions:
truncate64, ftruncate64, fallocate, pread64, pwrite64,
sync_file_range, readahead, fadvise64_64 which need argument
translation.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20220405071314.3225832-12-guoren@kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

authored by

Guo Ren and committed by
Palmer Dabbelt
59c10c52 01abdfea

+148 -3
+1
arch/riscv/include/asm/syscall.h
··· 16 16 17 17 /* The array of function pointers for syscalls. */ 18 18 extern void * const sys_call_table[]; 19 + extern void * const compat_sys_call_table[]; 19 20 20 21 /* 21 22 * Only the low 32 bits of orig_r0 are meaningful, so we return int.
+11
arch/riscv/include/asm/unistd.h
··· 11 11 #define __ARCH_WANT_SYS_CLONE 12 12 #define __ARCH_WANT_MEMFD_SECRET 13 13 14 + #ifdef CONFIG_COMPAT 15 + #define __ARCH_WANT_COMPAT_TRUNCATE64 16 + #define __ARCH_WANT_COMPAT_FTRUNCATE64 17 + #define __ARCH_WANT_COMPAT_FALLOCATE 18 + #define __ARCH_WANT_COMPAT_PREAD64 19 + #define __ARCH_WANT_COMPAT_PWRITE64 20 + #define __ARCH_WANT_COMPAT_SYNC_FILE_RANGE 21 + #define __ARCH_WANT_COMPAT_READAHEAD 22 + #define __ARCH_WANT_COMPAT_FADVISE64_64 23 + #endif 24 + 14 25 #include <uapi/asm/unistd.h> 15 26 16 27 #define NR_syscalls (__NR_syscalls)
+1 -1
arch/riscv/include/uapi/asm/unistd.h
··· 15 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 16 */ 17 17 18 - #ifdef __LP64__ 18 + #if defined(__LP64__) && !defined(__SYSCALL_COMPAT) 19 19 #define __ARCH_WANT_NEW_STAT 20 20 #define __ARCH_WANT_SET_GET_RLIMIT 21 21 #endif /* __LP64__ */
+1
arch/riscv/kernel/Makefile
··· 69 69 obj-$(CONFIG_JUMP_LABEL) += jump_label.o 70 70 71 71 obj-$(CONFIG_EFI) += efi.o 72 + obj-$(CONFIG_COMPAT) += compat_syscall_table.o
+19
arch/riscv/kernel/compat_syscall_table.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #define __SYSCALL_COMPAT 4 + 5 + #include <linux/compat.h> 6 + #include <linux/syscalls.h> 7 + #include <asm-generic/mman-common.h> 8 + #include <asm-generic/syscalls.h> 9 + #include <asm/syscall.h> 10 + 11 + #undef __SYSCALL 12 + #define __SYSCALL(nr, call) [nr] = (call), 13 + 14 + asmlinkage long compat_sys_rt_sigreturn(void); 15 + 16 + void * const compat_sys_call_table[__NR_syscalls] = { 17 + [0 ... __NR_syscalls - 1] = sys_ni_syscall, 18 + #include <asm/unistd.h> 19 + };
+4 -2
arch/riscv/kernel/sys_riscv.c
··· 33 33 { 34 34 return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0); 35 35 } 36 - #else 36 + #endif 37 + 38 + #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT) 37 39 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, 38 40 unsigned long, prot, unsigned long, flags, 39 41 unsigned long, fd, off_t, offset) ··· 46 44 */ 47 45 return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 12); 48 46 } 49 - #endif /* !CONFIG_64BIT */ 47 + #endif 50 48 51 49 /* 52 50 * Allows the instruction cache to be flushed from userspace. Despite RISC-V
+24
fs/open.c
··· 224 224 } 225 225 #endif /* BITS_PER_LONG == 32 */ 226 226 227 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_TRUNCATE64) 228 + COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname, 229 + compat_arg_u64_dual(length)) 230 + { 231 + return ksys_truncate(pathname, compat_arg_u64_glue(length)); 232 + } 233 + #endif 234 + 235 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FTRUNCATE64) 236 + COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, 237 + compat_arg_u64_dual(length)) 238 + { 239 + return ksys_ftruncate(fd, compat_arg_u64_glue(length)); 240 + } 241 + #endif 227 242 228 243 int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) 229 244 { ··· 353 338 { 354 339 return ksys_fallocate(fd, mode, offset, len); 355 340 } 341 + 342 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FALLOCATE) 343 + COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, compat_arg_u64_dual(offset), 344 + compat_arg_u64_dual(len)) 345 + { 346 + return ksys_fallocate(fd, mode, compat_arg_u64_glue(offset), 347 + compat_arg_u64_glue(len)); 348 + } 349 + #endif 356 350 357 351 /* 358 352 * access() needs to use the real uid/gid, not the effective uid/gid.
+16
fs/read_write.c
··· 682 682 return ksys_pread64(fd, buf, count, pos); 683 683 } 684 684 685 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PREAD64) 686 + COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf, 687 + size_t, count, compat_arg_u64_dual(pos)) 688 + { 689 + return ksys_pread64(fd, buf, count, compat_arg_u64_glue(pos)); 690 + } 691 + #endif 692 + 685 693 ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf, 686 694 size_t count, loff_t pos) 687 695 { ··· 715 707 { 716 708 return ksys_pwrite64(fd, buf, count, pos); 717 709 } 710 + 711 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PWRITE64) 712 + COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, buf, 713 + size_t, count, compat_arg_u64_dual(pos)) 714 + { 715 + return ksys_pwrite64(fd, buf, count, compat_arg_u64_glue(pos)); 716 + } 717 + #endif 718 718 719 719 static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, 720 720 loff_t *ppos, int type, rwf_t flags)
+9
fs/sync.c
··· 373 373 return ksys_sync_file_range(fd, offset, nbytes, flags); 374 374 } 375 375 376 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_SYNC_FILE_RANGE) 377 + COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, compat_arg_u64_dual(offset), 378 + compat_arg_u64_dual(nbytes), unsigned int, flags) 379 + { 380 + return ksys_sync_file_range(fd, compat_arg_u64_glue(offset), 381 + compat_arg_u64_glue(nbytes), flags); 382 + } 383 + #endif 384 + 376 385 /* It would be nice if people remember that not all the world's an i386 377 386 when they introduce new system calls */ 378 387 SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
+7
include/asm-generic/compat.h
··· 14 14 #define COMPAT_OFF_T_MAX 0x7fffffff 15 15 #endif 16 16 17 + #if !defined(compat_arg_u64) && !defined(CONFIG_CPU_BIG_ENDIAN) 18 + #define compat_arg_u64(name) u32 name##_lo, u32 name##_hi 19 + #define compat_arg_u64_dual(name) u32, name##_lo, u32, name##_hi 20 + #define compat_arg_u64_glue(name) (((u64)name##_lo & 0xffffffffUL) | \ 21 + ((u64)name##_hi << 32)) 22 + #endif 23 + 17 24 /* These types are common across all compat ABIs */ 18 25 typedef u32 compat_size_t; 19 26 typedef s32 compat_ssize_t;
+37
include/linux/compat.h
··· 926 926 /* obsolete: net/socket.c */ 927 927 asmlinkage long compat_sys_socketcall(int call, u32 __user *args); 928 928 929 + #ifdef __ARCH_WANT_COMPAT_TRUNCATE64 930 + asmlinkage long compat_sys_truncate64(const char __user *pathname, compat_arg_u64(len)); 931 + #endif 932 + 933 + #ifdef __ARCH_WANT_COMPAT_FTRUNCATE64 934 + asmlinkage long compat_sys_ftruncate64(unsigned int fd, compat_arg_u64(len)); 935 + #endif 936 + 937 + #ifdef __ARCH_WANT_COMPAT_FALLOCATE 938 + asmlinkage long compat_sys_fallocate(int fd, int mode, compat_arg_u64(offset), 939 + compat_arg_u64(len)); 940 + #endif 941 + 942 + #ifdef __ARCH_WANT_COMPAT_PREAD64 943 + asmlinkage long compat_sys_pread64(unsigned int fd, char __user *buf, size_t count, 944 + compat_arg_u64(pos)); 945 + #endif 946 + 947 + #ifdef __ARCH_WANT_COMPAT_PWRITE64 948 + asmlinkage long compat_sys_pwrite64(unsigned int fd, const char __user *buf, size_t count, 949 + compat_arg_u64(pos)); 950 + #endif 951 + 952 + #ifdef __ARCH_WANT_COMPAT_SYNC_FILE_RANGE 953 + asmlinkage long compat_sys_sync_file_range(int fd, compat_arg_u64(pos), 954 + compat_arg_u64(nbytes), unsigned int flags); 955 + #endif 956 + 957 + #ifdef __ARCH_WANT_COMPAT_FADVISE64_64 958 + asmlinkage long compat_sys_fadvise64_64(int fd, compat_arg_u64(pos), 959 + compat_arg_u64(len), int advice); 960 + #endif 961 + 962 + #ifdef __ARCH_WANT_COMPAT_READAHEAD 963 + asmlinkage long compat_sys_readahead(int fd, compat_arg_u64(offset), size_t count); 964 + #endif 965 + 929 966 #endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */ 930 967 931 968 /**
+11
mm/fadvise.c
··· 215 215 } 216 216 217 217 #endif 218 + 219 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FADVISE64_64) 220 + 221 + COMPAT_SYSCALL_DEFINE6(fadvise64_64, int, fd, compat_arg_u64_dual(offset), 222 + compat_arg_u64_dual(len), int, advice) 223 + { 224 + return ksys_fadvise64_64(fd, compat_arg_u64_glue(offset), 225 + compat_arg_u64_glue(len), advice); 226 + } 227 + 228 + #endif 218 229 #endif
+7
mm/readahead.c
··· 746 746 return ksys_readahead(fd, offset, count); 747 747 } 748 748 749 + #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_READAHEAD) 750 + COMPAT_SYSCALL_DEFINE4(readahead, int, fd, compat_arg_u64_dual(offset), size_t, count) 751 + { 752 + return ksys_readahead(fd, compat_arg_u64_glue(offset), count); 753 + } 754 + #endif 755 + 749 756 /** 750 757 * readahead_expand - Expand a readahead request 751 758 * @ractl: The request to be expanded