RISC-V: Add support for rv32 userspace via COMPAT
The RISC-V port supports the rv32i and rv64i base ISAs, but provides no mechanism to run 32-bit userspace on 64-bit systems. This adds that support, via the COMPAT framework. As the RISC-V ISAs (and uABIs) were developed concurrently, the resulting compat support is mostly generic. This includes a handful of cleanups to the generic compat infrastructure to more cleanly support RISC-V, followed by the RISC-V implementation. * palmer/riscv-compat: riscv: compat: Add COMPAT Kbuild skeletal support riscv: compat: ptrace: Add compat_arch_ptrace implement riscv: compat: signal: Add rt_frame implementation riscv: compat: vdso: Add setup additional pages implementation riscv: compat: vdso: Add COMPAT_VDSO base code implementation riscv: compat: Add hw capability check for elf riscv: compat: Add elf.h implementation riscv: compat: process: Add UXL_32 support in start_thread riscv: compat: syscall: Add entry.S implementation riscv: compat: syscall: Add compat_sys_call_table implementation riscv: compat: Support TASK_SIZE for compat mode riscv: compat: Add basic compat data type implementation riscv: Fixup difference with defconfig syscalls: compat: Fix the missing part for __SYSCALL_COMPAT asm-generic: compat: Cleanup duplicate definitions fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT arch: Add SYSVIPC_COMPAT for all architectures compat: consolidate the compat_flock{,64} definition uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in fcntl.h uapi: simplify __ARCH_FLOCK{,64}_PAD a little
This commit is contained in:
commit
7eb6369d7a
@ -2122,10 +2122,6 @@ config DMI
|
||||
|
||||
endmenu
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on COMPAT && SYSVIPC
|
||||
|
||||
menu "Power management options"
|
||||
|
||||
source "kernel/power/Kconfig"
|
||||
|
@ -8,6 +8,15 @@
|
||||
#define compat_mode_t compat_mode_t
|
||||
typedef u16 compat_mode_t;
|
||||
|
||||
#define __compat_uid_t __compat_uid_t
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
|
||||
#define compat_ipc_pid_t compat_ipc_pid_t
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
#define compat_statfs compat_statfs
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
@ -19,21 +28,15 @@ typedef u16 compat_mode_t;
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#ifdef __AARCH64EB__
|
||||
#define COMPAT_UTS_MACHINE "armv8b\0\0"
|
||||
#else
|
||||
#define COMPAT_UTS_MACHINE "armv8l\0\0"
|
||||
#endif
|
||||
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
typedef u16 __compat_uid16_t;
|
||||
typedef u16 __compat_gid16_t;
|
||||
typedef u32 compat_dev_t;
|
||||
typedef s32 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
|
||||
struct compat_stat {
|
||||
#ifdef __AARCH64EB__
|
||||
@ -65,26 +68,6 @@ struct compat_stat {
|
||||
compat_ulong_t __unused4[2];
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12 /* using 'struct flock64' */
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
int f_type;
|
||||
int f_bsize;
|
||||
@ -107,64 +90,6 @@ struct compat_statfs {
|
||||
#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
|
||||
#define COMPAT_MINSIGSTKSZ 2048
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
__compat_gid32_t gid;
|
||||
__compat_uid32_t cuid;
|
||||
__compat_gid32_t cgid;
|
||||
unsigned short mode;
|
||||
unsigned short __pad1;
|
||||
unsigned short seq;
|
||||
unsigned short __pad2;
|
||||
compat_ulong_t unused1;
|
||||
compat_ulong_t unused2;
|
||||
};
|
||||
|
||||
struct compat_semid64_ds {
|
||||
struct compat_ipc64_perm sem_perm;
|
||||
compat_ulong_t sem_otime;
|
||||
compat_ulong_t sem_otime_high;
|
||||
compat_ulong_t sem_ctime;
|
||||
compat_ulong_t sem_ctime_high;
|
||||
compat_ulong_t sem_nsems;
|
||||
compat_ulong_t __unused3;
|
||||
compat_ulong_t __unused4;
|
||||
};
|
||||
|
||||
struct compat_msqid64_ds {
|
||||
struct compat_ipc64_perm msg_perm;
|
||||
compat_ulong_t msg_stime;
|
||||
compat_ulong_t msg_stime_high;
|
||||
compat_ulong_t msg_rtime;
|
||||
compat_ulong_t msg_rtime_high;
|
||||
compat_ulong_t msg_ctime;
|
||||
compat_ulong_t msg_ctime_high;
|
||||
compat_ulong_t msg_cbytes;
|
||||
compat_ulong_t msg_qnum;
|
||||
compat_ulong_t msg_qbytes;
|
||||
compat_pid_t msg_lspid;
|
||||
compat_pid_t msg_lrpid;
|
||||
compat_ulong_t __unused4;
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
|
||||
struct compat_shmid64_ds {
|
||||
struct compat_ipc64_perm shm_perm;
|
||||
compat_size_t shm_segsz;
|
||||
compat_ulong_t shm_atime;
|
||||
compat_ulong_t shm_atime_high;
|
||||
compat_ulong_t shm_dtime;
|
||||
compat_ulong_t shm_dtime_high;
|
||||
compat_ulong_t shm_ctime;
|
||||
compat_ulong_t shm_ctime_high;
|
||||
compat_pid_t shm_cpid;
|
||||
compat_pid_t shm_lpid;
|
||||
compat_ulong_t shm_nattch;
|
||||
compat_ulong_t __unused4;
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
|
||||
static inline int is_compat_task(void)
|
||||
{
|
||||
return test_thread_flag(TIF_32BIT);
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*/
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define __ARCH_WANT_COMPAT_STAT
|
||||
#define __ARCH_WANT_COMPAT_STAT64
|
||||
#define __ARCH_WANT_SYS_GETHOSTNAME
|
||||
#define __ARCH_WANT_SYS_PAUSE
|
||||
|
@ -3198,16 +3198,12 @@ config MIPS32_COMPAT
|
||||
config COMPAT
|
||||
bool
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
bool
|
||||
|
||||
config MIPS32_O32
|
||||
bool "Kernel support for o32 binaries"
|
||||
depends on 64BIT
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT
|
||||
select MIPS32_COMPAT
|
||||
select SYSVIPC_COMPAT if SYSVIPC
|
||||
help
|
||||
Select this option if you want to run o32 binaries. These are pure
|
||||
32-bit binaries as used by the 32-bit Linux/MIPS port. Most of
|
||||
@ -3221,7 +3217,6 @@ config MIPS32_N32
|
||||
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
|
||||
select COMPAT
|
||||
select MIPS32_COMPAT
|
||||
select SYSVIPC_COMPAT if SYSVIPC
|
||||
help
|
||||
Select this option if you want to run n32 binaries. These are
|
||||
64-bit binaries using 32-bit quantities for addressing and certain
|
||||
|
@ -9,28 +9,28 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#define __compat_uid_t __compat_uid_t
|
||||
typedef s32 __compat_uid_t;
|
||||
typedef s32 __compat_gid_t;
|
||||
|
||||
typedef __compat_uid_t __compat_uid32_t;
|
||||
typedef __compat_gid_t __compat_gid32_t;
|
||||
#define __compat_uid32_t __compat_uid32_t
|
||||
#define __compat_gid32_t __compat_gid32_t
|
||||
|
||||
#define compat_statfs compat_statfs
|
||||
#define compat_ipc64_perm compat_ipc64_perm
|
||||
|
||||
#define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */
|
||||
#define _COMPAT_NSIG_BPW 32
|
||||
typedef u32 compat_sigset_word;
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0x7fffffffUL
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "mips\0\0\0"
|
||||
|
||||
typedef u32 compat_dev_t;
|
||||
typedef u32 compat_nlink_t;
|
||||
typedef s32 compat_ipc_pid_t;
|
||||
typedef struct {
|
||||
s32 val[2];
|
||||
} compat_fsid_t;
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
@ -55,27 +55,8 @@ struct compat_stat {
|
||||
s32 st_pad4[14];
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
s32 l_sysid;
|
||||
compat_pid_t l_pid;
|
||||
s32 pad[4];
|
||||
};
|
||||
|
||||
#define F_GETLK64 33
|
||||
#define F_SETLK64 34
|
||||
#define F_SETLKW64 35
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
#define __ARCH_COMPAT_FLOCK_EXTRA_SYSID s32 l_sysid;
|
||||
#define __ARCH_COMPAT_FLOCK_PAD s32 pad[4];
|
||||
|
||||
struct compat_statfs {
|
||||
int f_type;
|
||||
@ -92,10 +73,6 @@ struct compat_statfs {
|
||||
int f_spare[5];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0x7fffffffUL
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
|
@ -50,6 +50,8 @@
|
||||
# ifdef CONFIG_32BIT
|
||||
# define __ARCH_WANT_STAT64
|
||||
# define __ARCH_WANT_SYS_TIME32
|
||||
# else
|
||||
# define __ARCH_WANT_COMPAT_STAT
|
||||
# endif
|
||||
# ifdef CONFIG_MIPS32_O32
|
||||
# define __ARCH_WANT_SYS_TIME32
|
||||
|
@ -44,36 +44,16 @@
|
||||
#define F_SETOWN 24 /* for sockets. */
|
||||
#define F_GETOWN 23 /* for sockets. */
|
||||
|
||||
#ifndef __mips64
|
||||
#if __BITS_PER_LONG == 32 || defined(__KERNEL__)
|
||||
#define F_GETLK64 33 /* using 'struct flock64' */
|
||||
#define F_SETLK64 34
|
||||
#define F_SETLKW64 35
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The flavours of struct flock. "struct flock" is the ABI compliant
|
||||
* variant. Finally struct flock64 is the LFS variant of struct flock. As
|
||||
* a historic accident and inconsistence with the ABI definition it doesn't
|
||||
* contain all the same fields as struct flock.
|
||||
*/
|
||||
#endif /* __BITS_PER_LONG == 32 || defined(__KERNEL__) */
|
||||
|
||||
#if _MIPS_SIM != _MIPS_SIM_ABI64
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
__kernel_off_t l_start;
|
||||
__kernel_off_t l_len;
|
||||
long l_sysid;
|
||||
__kernel_pid_t l_pid;
|
||||
long pad[4];
|
||||
};
|
||||
|
||||
#define HAVE_ARCH_STRUCT_FLOCK
|
||||
|
||||
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
|
||||
#define __ARCH_FLOCK_EXTRA_SYSID long l_sysid;
|
||||
#define __ARCH_FLOCK_PAD long pad[4];
|
||||
#endif
|
||||
|
||||
#include <asm-generic/fcntl.h>
|
||||
|
||||
|
@ -331,10 +331,6 @@ config COMPAT
|
||||
def_bool y
|
||||
depends on 64BIT
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on COMPAT && SYSVIPC
|
||||
|
||||
config AUDIT_ARCH
|
||||
def_bool y
|
||||
|
||||
|
@ -11,16 +11,16 @@
|
||||
#define compat_mode_t compat_mode_t
|
||||
typedef u16 compat_mode_t;
|
||||
|
||||
#define compat_ipc_pid_t compat_ipc_pid_t
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
#define compat_ipc64_perm compat_ipc64_perm
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "parisc\0\0"
|
||||
|
||||
typedef u32 __compat_uid_t;
|
||||
typedef u32 __compat_gid_t;
|
||||
typedef u32 compat_dev_t;
|
||||
typedef u16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev; /* dev_t is 32 bits on parisc */
|
||||
@ -53,37 +53,6 @@ struct compat_stat {
|
||||
u32 st_spare4[3];
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
s32 f_type;
|
||||
s32 f_bsize;
|
||||
s32 f_blocks;
|
||||
s32 f_bfree;
|
||||
s32 f_bavail;
|
||||
s32 f_files;
|
||||
s32 f_ffree;
|
||||
__kernel_fsid_t f_fsid;
|
||||
s32 f_namelen;
|
||||
s32 f_frsize;
|
||||
s32 f_flags;
|
||||
s32 f_spare[4];
|
||||
};
|
||||
|
||||
struct compat_sigcontext {
|
||||
compat_int_t sc_flags;
|
||||
compat_int_t sc_gr[32]; /* PSW in sc_gr[0] */
|
||||
@ -93,10 +62,6 @@ struct compat_sigcontext {
|
||||
compat_int_t sc_sar; /* cr11 */
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0xffffffff
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid_t uid;
|
||||
|
@ -164,6 +164,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
#define __ARCH_WANT_SYS_CLONE3
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#define __ARCH_WANT_COMPAT_STAT
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define __ARCH_WANT_SYS_TIME
|
||||
|
@ -298,11 +298,6 @@ config COMPAT
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
bool
|
||||
depends on COMPAT && SYSVIPC
|
||||
default y
|
||||
|
||||
config SCHED_OMIT_FRAME_POINTER
|
||||
bool
|
||||
default y
|
||||
|
@ -8,21 +8,20 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define compat_ipc_pid_t compat_ipc_pid_t
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
#define compat_ipc64_perm compat_ipc64_perm
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define COMPAT_UTS_MACHINE "ppc\0\0"
|
||||
#else
|
||||
#define COMPAT_UTS_MACHINE "ppcle\0\0"
|
||||
#endif
|
||||
|
||||
typedef u32 __compat_uid_t;
|
||||
typedef u32 __compat_gid_t;
|
||||
typedef u32 compat_dev_t;
|
||||
typedef s16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
@ -44,45 +43,6 @@ struct compat_stat {
|
||||
u32 __unused4[2];
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12 /* using 'struct flock64' */
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
int f_type;
|
||||
int f_bsize;
|
||||
int f_blocks;
|
||||
int f_bfree;
|
||||
int f_bavail;
|
||||
int f_files;
|
||||
int f_ffree;
|
||||
compat_fsid_t f_fsid;
|
||||
int f_namelen; /* SunOS ignores this field. */
|
||||
int f_frsize;
|
||||
int f_flags;
|
||||
int f_spare[4];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0xffffffff
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
|
||||
/*
|
||||
* ipc64_perm is actually 32/64bit clean but since the compat layer refers to
|
||||
* it we may as well define it.
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define __ARCH_WANT_SYS_TIME
|
||||
#define __ARCH_WANT_SYS_UTIME
|
||||
#define __ARCH_WANT_SYS_NEWFSTATAT
|
||||
#define __ARCH_WANT_COMPAT_STAT
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#endif
|
||||
#define __ARCH_WANT_SYS_FORK
|
||||
|
@ -76,6 +76,7 @@ config RISCV
|
||||
select HAVE_ARCH_KGDB if !XIP_KERNEL
|
||||
select HAVE_ARCH_KGDB_QXFER_PKT
|
||||
select HAVE_ARCH_MMAP_RND_BITS if MMU
|
||||
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
|
||||
@ -127,12 +128,18 @@ config ARCH_MMAP_RND_BITS_MIN
|
||||
default 18 if 64BIT
|
||||
default 8
|
||||
|
||||
config ARCH_MMAP_RND_COMPAT_BITS_MIN
|
||||
default 8
|
||||
|
||||
# max bits determined by the following formula:
|
||||
# VA_BITS - PAGE_SHIFT - 3
|
||||
config ARCH_MMAP_RND_BITS_MAX
|
||||
default 24 if 64BIT # SV39 based
|
||||
default 17
|
||||
|
||||
config ARCH_MMAP_RND_COMPAT_BITS_MAX
|
||||
default 17
|
||||
|
||||
# set if we run in machine mode, cleared if we run in supervisor mode
|
||||
config RISCV_M_MODE
|
||||
bool
|
||||
@ -422,6 +429,18 @@ config CRASH_DUMP
|
||||
|
||||
For more details see Documentation/admin-guide/kdump/kdump.rst
|
||||
|
||||
config COMPAT
|
||||
bool "Kernel support for 32-bit U-mode"
|
||||
default 64BIT
|
||||
depends on 64BIT && MMU
|
||||
help
|
||||
This option enables support for a 32-bit U-mode running under a 64-bit
|
||||
kernel at S-mode. riscv32-specific components such as system calls,
|
||||
the user helper functions (vdso), signal rt_frame functions and the
|
||||
ptrace interface are handled appropriately by the kernel.
|
||||
|
||||
If you want to execute 32-bit userspace applications, say Y.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Boot options"
|
||||
|
@ -112,12 +112,17 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
|
||||
PHONY += vdso_install
|
||||
vdso_install:
|
||||
$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
|
||||
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
||||
$(build)=arch/riscv/kernel/compat_vdso $@)
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
ifeq ($(CONFIG_MMU),y)
|
||||
prepare: vdso_prepare
|
||||
vdso_prepare: prepare0
|
||||
$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
|
||||
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
||||
$(build)=arch/riscv/kernel/compat_vdso include/generated/compat_vdso-offsets.h)
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -154,3 +159,7 @@ PHONY += rv64_randconfig
|
||||
rv64_randconfig:
|
||||
$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/riscv/configs/64-bit.config \
|
||||
-f $(srctree)/Makefile randconfig
|
||||
|
||||
PHONY += rv32_defconfig
|
||||
rv32_defconfig:
|
||||
$(Q)$(MAKE) -f $(srctree)/Makefile defconfig 32-bit.config
|
||||
|
129
arch/riscv/include/asm/compat.h
Normal file
129
arch/riscv/include/asm/compat.h
Normal file
@ -0,0 +1,129 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef __ASM_COMPAT_H
|
||||
#define __ASM_COMPAT_H
|
||||
|
||||
#define COMPAT_UTS_MACHINE "riscv\0\0"
|
||||
|
||||
/*
|
||||
* Architecture specific compatibility types
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
static inline int is_compat_task(void)
|
||||
{
|
||||
return test_thread_flag(TIF_32BIT);
|
||||
}
|
||||
|
||||
struct compat_user_regs_struct {
|
||||
compat_ulong_t pc;
|
||||
compat_ulong_t ra;
|
||||
compat_ulong_t sp;
|
||||
compat_ulong_t gp;
|
||||
compat_ulong_t tp;
|
||||
compat_ulong_t t0;
|
||||
compat_ulong_t t1;
|
||||
compat_ulong_t t2;
|
||||
compat_ulong_t s0;
|
||||
compat_ulong_t s1;
|
||||
compat_ulong_t a0;
|
||||
compat_ulong_t a1;
|
||||
compat_ulong_t a2;
|
||||
compat_ulong_t a3;
|
||||
compat_ulong_t a4;
|
||||
compat_ulong_t a5;
|
||||
compat_ulong_t a6;
|
||||
compat_ulong_t a7;
|
||||
compat_ulong_t s2;
|
||||
compat_ulong_t s3;
|
||||
compat_ulong_t s4;
|
||||
compat_ulong_t s5;
|
||||
compat_ulong_t s6;
|
||||
compat_ulong_t s7;
|
||||
compat_ulong_t s8;
|
||||
compat_ulong_t s9;
|
||||
compat_ulong_t s10;
|
||||
compat_ulong_t s11;
|
||||
compat_ulong_t t3;
|
||||
compat_ulong_t t4;
|
||||
compat_ulong_t t5;
|
||||
compat_ulong_t t6;
|
||||
};
|
||||
|
||||
static inline void regs_to_cregs(struct compat_user_regs_struct *cregs,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
cregs->pc = (compat_ulong_t) regs->epc;
|
||||
cregs->ra = (compat_ulong_t) regs->ra;
|
||||
cregs->sp = (compat_ulong_t) regs->sp;
|
||||
cregs->gp = (compat_ulong_t) regs->gp;
|
||||
cregs->tp = (compat_ulong_t) regs->tp;
|
||||
cregs->t0 = (compat_ulong_t) regs->t0;
|
||||
cregs->t1 = (compat_ulong_t) regs->t1;
|
||||
cregs->t2 = (compat_ulong_t) regs->t2;
|
||||
cregs->s0 = (compat_ulong_t) regs->s0;
|
||||
cregs->s1 = (compat_ulong_t) regs->s1;
|
||||
cregs->a0 = (compat_ulong_t) regs->a0;
|
||||
cregs->a1 = (compat_ulong_t) regs->a1;
|
||||
cregs->a2 = (compat_ulong_t) regs->a2;
|
||||
cregs->a3 = (compat_ulong_t) regs->a3;
|
||||
cregs->a4 = (compat_ulong_t) regs->a4;
|
||||
cregs->a5 = (compat_ulong_t) regs->a5;
|
||||
cregs->a6 = (compat_ulong_t) regs->a6;
|
||||
cregs->a7 = (compat_ulong_t) regs->a7;
|
||||
cregs->s2 = (compat_ulong_t) regs->s2;
|
||||
cregs->s3 = (compat_ulong_t) regs->s3;
|
||||
cregs->s4 = (compat_ulong_t) regs->s4;
|
||||
cregs->s5 = (compat_ulong_t) regs->s5;
|
||||
cregs->s6 = (compat_ulong_t) regs->s6;
|
||||
cregs->s7 = (compat_ulong_t) regs->s7;
|
||||
cregs->s8 = (compat_ulong_t) regs->s8;
|
||||
cregs->s9 = (compat_ulong_t) regs->s9;
|
||||
cregs->s10 = (compat_ulong_t) regs->s10;
|
||||
cregs->s11 = (compat_ulong_t) regs->s11;
|
||||
cregs->t3 = (compat_ulong_t) regs->t3;
|
||||
cregs->t4 = (compat_ulong_t) regs->t4;
|
||||
cregs->t5 = (compat_ulong_t) regs->t5;
|
||||
cregs->t6 = (compat_ulong_t) regs->t6;
|
||||
};
|
||||
|
||||
static inline void cregs_to_regs(struct compat_user_regs_struct *cregs,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
regs->epc = (unsigned long) cregs->pc;
|
||||
regs->ra = (unsigned long) cregs->ra;
|
||||
regs->sp = (unsigned long) cregs->sp;
|
||||
regs->gp = (unsigned long) cregs->gp;
|
||||
regs->tp = (unsigned long) cregs->tp;
|
||||
regs->t0 = (unsigned long) cregs->t0;
|
||||
regs->t1 = (unsigned long) cregs->t1;
|
||||
regs->t2 = (unsigned long) cregs->t2;
|
||||
regs->s0 = (unsigned long) cregs->s0;
|
||||
regs->s1 = (unsigned long) cregs->s1;
|
||||
regs->a0 = (unsigned long) cregs->a0;
|
||||
regs->a1 = (unsigned long) cregs->a1;
|
||||
regs->a2 = (unsigned long) cregs->a2;
|
||||
regs->a3 = (unsigned long) cregs->a3;
|
||||
regs->a4 = (unsigned long) cregs->a4;
|
||||
regs->a5 = (unsigned long) cregs->a5;
|
||||
regs->a6 = (unsigned long) cregs->a6;
|
||||
regs->a7 = (unsigned long) cregs->a7;
|
||||
regs->s2 = (unsigned long) cregs->s2;
|
||||
regs->s3 = (unsigned long) cregs->s3;
|
||||
regs->s4 = (unsigned long) cregs->s4;
|
||||
regs->s5 = (unsigned long) cregs->s5;
|
||||
regs->s6 = (unsigned long) cregs->s6;
|
||||
regs->s7 = (unsigned long) cregs->s7;
|
||||
regs->s8 = (unsigned long) cregs->s8;
|
||||
regs->s9 = (unsigned long) cregs->s9;
|
||||
regs->s10 = (unsigned long) cregs->s10;
|
||||
regs->s11 = (unsigned long) cregs->s11;
|
||||
regs->t3 = (unsigned long) cregs->t3;
|
||||
regs->t4 = (unsigned long) cregs->t4;
|
||||
regs->t5 = (unsigned long) cregs->t5;
|
||||
regs->t6 = (unsigned long) cregs->t6;
|
||||
};
|
||||
|
||||
#endif /* __ASM_COMPAT_H */
|
@ -36,6 +36,13 @@
|
||||
#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define SR_UXL _AC(0x300000000, UL) /* XLEN mask for U-mode */
|
||||
#define SR_UXL_32 _AC(0x100000000, UL) /* XLEN = 32 for U-mode */
|
||||
#define SR_UXL_64 _AC(0x200000000, UL) /* XLEN = 64 for U-mode */
|
||||
#define SR_UXL_SHIFT 32
|
||||
#endif
|
||||
|
||||
/* SATP flags */
|
||||
#ifndef CONFIG_64BIT
|
||||
#define SATP_PPN _AC(0x003FFFFF, UL)
|
||||
|
@ -8,6 +8,8 @@
|
||||
#ifndef _ASM_RISCV_ELF_H
|
||||
#define _ASM_RISCV_ELF_H
|
||||
|
||||
#include <uapi/linux/elf.h>
|
||||
#include <linux/compat.h>
|
||||
#include <uapi/asm/elf.h>
|
||||
#include <asm/auxvec.h>
|
||||
#include <asm/byteorder.h>
|
||||
@ -18,18 +20,24 @@
|
||||
*/
|
||||
#define ELF_ARCH EM_RISCV
|
||||
|
||||
#ifndef ELF_CLASS
|
||||
#ifdef CONFIG_64BIT
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#else
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
|
||||
#define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
|
||||
((x)->e_ident[EI_CLASS] == ELF_CLASS))
|
||||
|
||||
extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
|
||||
#define compat_elf_check_arch compat_elf_check_arch
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
#define ELF_EXEC_PAGESIZE (PAGE_SIZE)
|
||||
@ -43,8 +51,14 @@
|
||||
#define ELF_ET_DYN_BASE ((TASK_SIZE / 3) * 2)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
|
||||
0x7ff >> (PAGE_SHIFT - 12) : \
|
||||
0x3ffff >> (PAGE_SHIFT - 12))
|
||||
#else
|
||||
#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* This yields a mask that user programs can use to figure out what
|
||||
* instruction set this CPU supports. This could be done in user space,
|
||||
@ -60,11 +74,19 @@ extern unsigned long elf_hwcap;
|
||||
*/
|
||||
#define ELF_PLATFORM (NULL)
|
||||
|
||||
#define COMPAT_ELF_PLATFORM (NULL)
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define ARCH_DLINFO \
|
||||
do { \
|
||||
/* \
|
||||
* Note that we add ulong after elf_addr_t because \
|
||||
* casting current->mm->context.vdso triggers a cast \
|
||||
* warning of cast from pointer to integer for \
|
||||
* COMPAT ELFCLASS32. \
|
||||
*/ \
|
||||
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
|
||||
(elf_addr_t)current->mm->context.vdso); \
|
||||
(elf_addr_t)(ulong)current->mm->context.vdso); \
|
||||
NEW_AUX_ENT(AT_L1I_CACHESIZE, \
|
||||
get_cache_size(1, CACHE_TYPE_INST)); \
|
||||
NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, \
|
||||
@ -90,4 +112,28 @@ do { \
|
||||
*(struct user_regs_struct *)regs; \
|
||||
} while (0);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
set_thread_flag(TIF_32BIT); \
|
||||
else \
|
||||
clear_thread_flag(TIF_32BIT); \
|
||||
if (personality(current->personality) != PER_LINUX32) \
|
||||
set_personality(PER_LINUX | \
|
||||
(current->personality & (~PER_MASK))); \
|
||||
} while (0)
|
||||
|
||||
#define COMPAT_ELF_ET_DYN_BASE ((TASK_SIZE_32 / 3) * 2)
|
||||
|
||||
/* rv32 registers */
|
||||
typedef compat_ulong_t compat_elf_greg_t;
|
||||
typedef compat_elf_greg_t compat_elf_gregset_t[ELF_NGREG];
|
||||
|
||||
extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
int uses_interp);
|
||||
#define compat_arch_setup_additional_pages \
|
||||
compat_arch_setup_additional_pages
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* _ASM_RISCV_ELF_H */
|
||||
|
@ -16,6 +16,7 @@ typedef struct {
|
||||
atomic_long_t id;
|
||||
#endif
|
||||
void *vdso;
|
||||
void *vdso_info;
|
||||
#ifdef CONFIG_SMP
|
||||
/* A local icache flush is needed before user execution can resume. */
|
||||
cpumask_t icache_stale_mask;
|
||||
|
@ -740,8 +740,17 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
|
||||
* 63–48 all equal to bit 47, or else a page-fault exception will occur."
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
#define TASK_SIZE (PGDIR_SIZE * PTRS_PER_PGD / 2)
|
||||
#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
|
||||
#define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2)
|
||||
#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
|
||||
#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
|
||||
TASK_SIZE_32 : TASK_SIZE_64)
|
||||
#else
|
||||
#define TASK_SIZE TASK_SIZE_64
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define TASK_SIZE FIXADDR_START
|
||||
#define TASK_SIZE_MIN TASK_SIZE
|
||||
|
@ -19,7 +19,11 @@
|
||||
#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
|
||||
|
||||
#define STACK_TOP TASK_SIZE
|
||||
#define STACK_TOP_MAX STACK_TOP
|
||||
#ifdef CONFIG_64BIT
|
||||
#define STACK_TOP_MAX TASK_SIZE_64
|
||||
#else
|
||||
#define STACK_TOP_MAX TASK_SIZE
|
||||
#endif
|
||||
#define STACK_ALIGN 16
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
18
arch/riscv/include/asm/signal32.h
Normal file
18
arch/riscv/include/asm/signal32.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ASM_SIGNAL32_H
|
||||
#define __ASM_SIGNAL32_H
|
||||
|
||||
#if IS_ENABLED(CONFIG_COMPAT)
|
||||
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
|
||||
struct pt_regs *regs);
|
||||
#else
|
||||
static inline
|
||||
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -16,6 +16,7 @@
|
||||
|
||||
/* The array of function pointers for syscalls. */
|
||||
extern void * const sys_call_table[];
|
||||
extern void * const compat_sys_call_table[];
|
||||
|
||||
/*
|
||||
* Only the low 32 bits of orig_r0 are meaningful, so we return int.
|
||||
|
@ -97,6 +97,7 @@ struct thread_info {
|
||||
#define TIF_SECCOMP 8 /* syscall secure computing */
|
||||
#define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */
|
||||
#define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */
|
||||
#define TIF_32BIT 11 /* compat-mode 32bit process */
|
||||
|
||||
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
||||
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
|
||||
|
@ -11,6 +11,17 @@
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
#define __ARCH_WANT_MEMFD_SECRET
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define __ARCH_WANT_COMPAT_TRUNCATE64
|
||||
#define __ARCH_WANT_COMPAT_FTRUNCATE64
|
||||
#define __ARCH_WANT_COMPAT_FALLOCATE
|
||||
#define __ARCH_WANT_COMPAT_PREAD64
|
||||
#define __ARCH_WANT_COMPAT_PWRITE64
|
||||
#define __ARCH_WANT_COMPAT_SYNC_FILE_RANGE
|
||||
#define __ARCH_WANT_COMPAT_READAHEAD
|
||||
#define __ARCH_WANT_COMPAT_FADVISE64_64
|
||||
#endif
|
||||
|
||||
#include <uapi/asm/unistd.h>
|
||||
|
||||
#define NR_syscalls (__NR_syscalls)
|
||||
|
@ -21,6 +21,15 @@
|
||||
|
||||
#define VDSO_SYMBOL(base, name) \
|
||||
(void __user *)((unsigned long)(base) + __vdso_##name##_offset)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <generated/compat_vdso-offsets.h>
|
||||
|
||||
#define COMPAT_VDSO_SYMBOL(base, name) \
|
||||
(void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __LP64__
|
||||
#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
|
||||
#define __ARCH_WANT_NEW_STAT
|
||||
#define __ARCH_WANT_SET_GET_RLIMIT
|
||||
#endif /* __LP64__ */
|
||||
|
@ -84,3 +84,6 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
|
||||
obj-$(CONFIG_EFI) += efi.o
|
||||
obj-$(CONFIG_COMPAT) += compat_syscall_table.o
|
||||
obj-$(CONFIG_COMPAT) += compat_signal.o
|
||||
obj-$(CONFIG_COMPAT) += compat_vdso/
|
||||
|
243
arch/riscv/kernel/compat_signal.c
Normal file
243
arch/riscv/kernel/compat_signal.c
Normal file
@ -0,0 +1,243 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/csr.h>
|
||||
#include <asm/signal32.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#define COMPAT_DEBUG_SIG 0
|
||||
|
||||
struct compat_sigcontext {
|
||||
struct compat_user_regs_struct sc_regs;
|
||||
union __riscv_fp_state sc_fpregs;
|
||||
};
|
||||
|
||||
struct compat_ucontext {
|
||||
compat_ulong_t uc_flags;
|
||||
struct compat_ucontext *uc_link;
|
||||
compat_stack_t uc_stack;
|
||||
sigset_t uc_sigmask;
|
||||
/* There's some padding here to allow sigset_t to be expanded in the
|
||||
* future. Though this is unlikely, other architectures put uc_sigmask
|
||||
* at the end of this structure and explicitly state it can be
|
||||
* expanded, so we didn't want to box ourselves in here. */
|
||||
__u8 __unused[1024 / 8 - sizeof(sigset_t)];
|
||||
/* We can't put uc_sigmask at the end of this structure because we need
|
||||
* to be able to expand sigcontext in the future. For example, the
|
||||
* vector ISA extension will almost certainly add ISA state. We want
|
||||
* to ensure all user-visible ISA state can be saved and restored via a
|
||||
* ucontext, so we're putting this at the end in order to allow for
|
||||
* infinite extensibility. Since we know this will be extended and we
|
||||
* assume sigset_t won't be extended an extreme amount, we're
|
||||
* prioritizing this. */
|
||||
struct compat_sigcontext uc_mcontext;
|
||||
};
|
||||
|
||||
struct compat_rt_sigframe {
|
||||
struct compat_siginfo info;
|
||||
struct compat_ucontext uc;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FPU
|
||||
static long compat_restore_fp_state(struct pt_regs *regs,
|
||||
union __riscv_fp_state __user *sc_fpregs)
|
||||
{
|
||||
long err;
|
||||
struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
|
||||
size_t i;
|
||||
|
||||
err = __copy_from_user(¤t->thread.fstate, state, sizeof(*state));
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
fstate_restore(current, regs);
|
||||
|
||||
/* We support no other extension state at this time. */
|
||||
for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
|
||||
u32 value;
|
||||
|
||||
err = __get_user(value, &sc_fpregs->q.reserved[i]);
|
||||
if (unlikely(err))
|
||||
break;
|
||||
if (value != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static long compat_save_fp_state(struct pt_regs *regs,
|
||||
union __riscv_fp_state __user *sc_fpregs)
|
||||
{
|
||||
long err;
|
||||
struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
|
||||
size_t i;
|
||||
|
||||
fstate_save(current, regs);
|
||||
err = __copy_to_user(state, ¤t->thread.fstate, sizeof(*state));
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
/* We support no other extension state at this time. */
|
||||
for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
|
||||
err = __put_user(0, &sc_fpregs->q.reserved[i]);
|
||||
if (unlikely(err))
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
#define compat_save_fp_state(task, regs) (0)
|
||||
#define compat_restore_fp_state(task, regs) (0)
|
||||
#endif
|
||||
|
||||
static long compat_restore_sigcontext(struct pt_regs *regs,
|
||||
struct compat_sigcontext __user *sc)
|
||||
{
|
||||
long err;
|
||||
struct compat_user_regs_struct cregs;
|
||||
|
||||
/* sc_regs is structured the same as the start of pt_regs */
|
||||
err = __copy_from_user(&cregs, &sc->sc_regs, sizeof(sc->sc_regs));
|
||||
|
||||
cregs_to_regs(&cregs, regs);
|
||||
|
||||
/* Restore the floating-point state. */
|
||||
if (has_fpu())
|
||||
err |= compat_restore_fp_state(regs, &sc->sc_fpregs);
|
||||
return err;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
struct compat_rt_sigframe __user *frame;
|
||||
struct task_struct *task;
|
||||
sigset_t set;
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
current->restart_block.fn = do_no_restart_syscall;
|
||||
|
||||
frame = (struct compat_rt_sigframe __user *)regs->sp;
|
||||
|
||||
if (!access_ok(frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
||||
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
|
||||
goto badframe;
|
||||
|
||||
set_current_blocked(&set);
|
||||
|
||||
if (compat_restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
|
||||
if (compat_restore_altstack(&frame->uc.uc_stack))
|
||||
goto badframe;
|
||||
|
||||
return regs->a0;
|
||||
|
||||
badframe:
|
||||
task = current;
|
||||
if (show_unhandled_signals) {
|
||||
pr_info_ratelimited(
|
||||
"%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
|
||||
task->comm, task_pid_nr(task), __func__,
|
||||
frame, (void *)regs->epc, (void *)regs->sp);
|
||||
}
|
||||
force_sig(SIGSEGV);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long compat_setup_sigcontext(struct compat_rt_sigframe __user *frame,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
struct compat_sigcontext __user *sc = &frame->uc.uc_mcontext;
|
||||
struct compat_user_regs_struct cregs;
|
||||
long err;
|
||||
|
||||
regs_to_cregs(&cregs, regs);
|
||||
|
||||
/* sc_regs is structured the same as the start of pt_regs */
|
||||
err = __copy_to_user(&sc->sc_regs, &cregs, sizeof(sc->sc_regs));
|
||||
/* Save the floating-point state. */
|
||||
if (has_fpu())
|
||||
err |= compat_save_fp_state(regs, &sc->sc_fpregs);
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void __user *compat_get_sigframe(struct ksignal *ksig,
|
||||
struct pt_regs *regs, size_t framesize)
|
||||
{
|
||||
unsigned long sp;
|
||||
/* Default to using normal stack */
|
||||
sp = regs->sp;
|
||||
|
||||
/*
|
||||
* If we are on the alternate signal stack and would overflow it, don't.
|
||||
* Return an always-bogus address instead so we will die with SIGSEGV.
|
||||
*/
|
||||
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
|
||||
return (void __user __force *)(-1UL);
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
sp = sigsp(sp, ksig) - framesize;
|
||||
|
||||
/* Align the stack frame. */
|
||||
sp &= ~0xfUL;
|
||||
|
||||
return (void __user *)sp;
|
||||
}
|
||||
|
||||
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
struct compat_rt_sigframe __user *frame;
|
||||
long err = 0;
|
||||
|
||||
frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
|
||||
if (!access_ok(frame, sizeof(*frame)))
|
||||
return -EFAULT;
|
||||
|
||||
err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
|
||||
|
||||
/* Create the ucontext. */
|
||||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(NULL, &frame->uc.uc_link);
|
||||
err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
|
||||
err |= compat_setup_sigcontext(frame, regs);
|
||||
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
regs->ra = (unsigned long)COMPAT_VDSO_SYMBOL(
|
||||
current->mm->context.vdso, rt_sigreturn);
|
||||
|
||||
/*
|
||||
* Set up registers for signal handler.
|
||||
* Registers that we don't modify keep the value they had from
|
||||
* user-space at the time we took the signal.
|
||||
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
|
||||
* since some things rely on this (e.g. glibc's debug/segfault.c).
|
||||
*/
|
||||
regs->epc = (unsigned long)ksig->ka.sa.sa_handler;
|
||||
regs->sp = (unsigned long)frame;
|
||||
regs->a0 = ksig->sig; /* a0: signal number */
|
||||
regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
|
||||
regs->a2 = (unsigned long)(&frame->uc); /* a2: ucontext pointer */
|
||||
|
||||
#if COMPAT_DEBUG_SIG
|
||||
pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
|
||||
current->comm, task_pid_nr(current), ksig->sig,
|
||||
(void *)regs->epc, (void *)regs->ra, frame);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
19
arch/riscv/kernel/compat_syscall_table.c
Normal file
19
arch/riscv/kernel/compat_syscall_table.c
Normal file
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#define __SYSCALL_COMPAT
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <asm-generic/mman-common.h>
|
||||
#include <asm-generic/syscalls.h>
|
||||
#include <asm/syscall.h>
|
||||
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, call) [nr] = (call),
|
||||
|
||||
asmlinkage long compat_sys_rt_sigreturn(void);
|
||||
|
||||
void * const compat_sys_call_table[__NR_syscalls] = {
|
||||
[0 ... __NR_syscalls - 1] = sys_ni_syscall,
|
||||
#include <asm/unistd.h>
|
||||
};
|
2
arch/riscv/kernel/compat_vdso/.gitignore
vendored
Normal file
2
arch/riscv/kernel/compat_vdso/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
compat_vdso.lds
|
78
arch/riscv/kernel/compat_vdso/Makefile
Normal file
78
arch/riscv/kernel/compat_vdso/Makefile
Normal file
@ -0,0 +1,78 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Makefile for compat_vdso
|
||||
#
|
||||
|
||||
# Symbols present in the compat_vdso
|
||||
compat_vdso-syms = rt_sigreturn
|
||||
compat_vdso-syms += getcpu
|
||||
compat_vdso-syms += flush_icache
|
||||
|
||||
COMPAT_CC := $(CC)
|
||||
COMPAT_LD := $(LD)
|
||||
|
||||
COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32
|
||||
COMPAT_LD_FLAGS := -melf32lriscv
|
||||
|
||||
# Files to link into the compat_vdso
|
||||
obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
|
||||
|
||||
# Build rules
|
||||
targets := $(obj-compat_vdso) compat_vdso.so compat_vdso.so.dbg compat_vdso.lds
|
||||
obj-compat_vdso := $(addprefix $(obj)/, $(obj-compat_vdso))
|
||||
|
||||
obj-y += compat_vdso.o
|
||||
CPPFLAGS_compat_vdso.lds += -P -C -U$(ARCH)
|
||||
|
||||
# Disable profiling and instrumentation for VDSO code
|
||||
GCOV_PROFILE := n
|
||||
KCOV_INSTRUMENT := n
|
||||
KASAN_SANITIZE := n
|
||||
UBSAN_SANITIZE := n
|
||||
|
||||
# Force dependency
|
||||
$(obj)/compat_vdso.o: $(obj)/compat_vdso.so
|
||||
|
||||
# link rule for the .so file, .lds has to be first
|
||||
$(obj)/compat_vdso.so.dbg: $(obj)/compat_vdso.lds $(obj-compat_vdso) FORCE
|
||||
$(call if_changed,compat_vdsold)
|
||||
LDFLAGS_compat_vdso.so.dbg = -shared -S -soname=linux-compat_vdso.so.1 \
|
||||
--build-id=sha1 --hash-style=both --eh-frame-hdr
|
||||
|
||||
$(obj-compat_vdso): %.o: %.S FORCE
|
||||
$(call if_changed_dep,compat_vdsoas)
|
||||
|
||||
# strip rule for the .so file
|
||||
$(obj)/%.so: OBJCOPYFLAGS := -S
|
||||
$(obj)/%.so: $(obj)/%.so.dbg FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
# Generate VDSO offsets using helper script
|
||||
gen-compat_vdsosym := $(srctree)/$(src)/gen_compat_vdso_offsets.sh
|
||||
quiet_cmd_compat_vdsosym = VDSOSYM $@
|
||||
cmd_compat_vdsosym = $(NM) $< | $(gen-compat_vdsosym) | LC_ALL=C sort > $@
|
||||
|
||||
include/generated/compat_vdso-offsets.h: $(obj)/compat_vdso.so.dbg FORCE
|
||||
$(call if_changed,compat_vdsosym)
|
||||
|
||||
# actual build commands
|
||||
# The DSO images are built using a special linker script
|
||||
# Make sure only to export the intended __compat_vdso_xxx symbol offsets.
|
||||
quiet_cmd_compat_vdsold = VDSOLD $@
|
||||
cmd_compat_vdsold = $(COMPAT_LD) $(ld_flags) $(COMPAT_LD_FLAGS) -T $(filter-out FORCE,$^) -o $@.tmp && \
|
||||
$(OBJCOPY) $(patsubst %, -G __compat_vdso_%, $(compat_vdso-syms)) $@.tmp $@ && \
|
||||
rm $@.tmp
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_compat_vdsoas = VDSOAS $@
|
||||
cmd_compat_vdsoas = $(COMPAT_CC) $(a_flags) $(COMPAT_CC_FLAGS) -c -o $@ $<
|
||||
|
||||
# install commands for the unstripped file
|
||||
quiet_cmd_compat_vdso_install = INSTALL $@
|
||||
cmd_compat_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/compat_vdso/$@
|
||||
|
||||
compat_vdso.so: $(obj)/compat_vdso.so.dbg
|
||||
@mkdir -p $(MODLIB)/compat_vdso
|
||||
$(call cmd,compat_vdso_install)
|
||||
|
||||
compat_vdso_install: compat_vdso.so
|
8
arch/riscv/kernel/compat_vdso/compat_vdso.S
Normal file
8
arch/riscv/kernel/compat_vdso/compat_vdso.S
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#define vdso_start compat_vdso_start
|
||||
#define vdso_end compat_vdso_end
|
||||
|
||||
#define __VDSO_PATH "arch/riscv/kernel/compat_vdso/compat_vdso.so"
|
||||
|
||||
#include "../vdso/vdso.S"
|
3
arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
Normal file
3
arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
Normal file
@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include "../vdso/vdso.lds.S"
|
3
arch/riscv/kernel/compat_vdso/flush_icache.S
Normal file
3
arch/riscv/kernel/compat_vdso/flush_icache.S
Normal file
@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include "../vdso/flush_icache.S"
|
5
arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
Executable file
5
arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
LC_ALL=C
|
||||
sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define compat\2_offset\t0x\1/p'
|
3
arch/riscv/kernel/compat_vdso/getcpu.S
Normal file
3
arch/riscv/kernel/compat_vdso/getcpu.S
Normal file
@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include "../vdso/getcpu.S"
|
3
arch/riscv/kernel/compat_vdso/note.S
Normal file
3
arch/riscv/kernel/compat_vdso/note.S
Normal file
@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include "../vdso/note.S"
|
3
arch/riscv/kernel/compat_vdso/rt_sigreturn.S
Normal file
3
arch/riscv/kernel/compat_vdso/rt_sigreturn.S
Normal file
@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include "../vdso/rt_sigreturn.S"
|
@ -207,13 +207,27 @@ check_syscall_nr:
|
||||
* Syscall number held in a7.
|
||||
* If syscall number is above allowed value, redirect to ni_syscall.
|
||||
*/
|
||||
bgeu a7, t0, 1f
|
||||
bgeu a7, t0, 3f
|
||||
#ifdef CONFIG_COMPAT
|
||||
REG_L s0, PT_STATUS(sp)
|
||||
srli s0, s0, SR_UXL_SHIFT
|
||||
andi s0, s0, (SR_UXL >> SR_UXL_SHIFT)
|
||||
li t0, (SR_UXL_32 >> SR_UXL_SHIFT)
|
||||
sub t0, s0, t0
|
||||
bnez t0, 1f
|
||||
|
||||
/* Call compat_syscall */
|
||||
la s0, compat_sys_call_table
|
||||
j 2f
|
||||
1:
|
||||
#endif
|
||||
/* Call syscall */
|
||||
la s0, sys_call_table
|
||||
2:
|
||||
slli t0, a7, RISCV_LGPTR
|
||||
add s0, s0, t0
|
||||
REG_L s0, 0(s0)
|
||||
1:
|
||||
3:
|
||||
jalr s0
|
||||
|
||||
ret_from_syscall:
|
||||
|
@ -84,6 +84,34 @@ void show_regs(struct pt_regs *regs)
|
||||
dump_backtrace(regs, NULL, KERN_DEFAULT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static bool compat_mode_supported __read_mostly;
|
||||
|
||||
bool compat_elf_check_arch(Elf32_Ehdr *hdr)
|
||||
{
|
||||
return compat_mode_supported &&
|
||||
hdr->e_machine == EM_RISCV &&
|
||||
hdr->e_ident[EI_CLASS] == ELFCLASS32;
|
||||
}
|
||||
|
||||
static int __init compat_mode_detect(void)
|
||||
{
|
||||
unsigned long tmp = csr_read(CSR_STATUS);
|
||||
|
||||
csr_write(CSR_STATUS, (tmp & ~SR_UXL) | SR_UXL_32);
|
||||
compat_mode_supported =
|
||||
(csr_read(CSR_STATUS) & SR_UXL) == SR_UXL_32;
|
||||
|
||||
csr_write(CSR_STATUS, tmp);
|
||||
|
||||
pr_info("riscv: ELF compat mode %s",
|
||||
compat_mode_supported ? "supported" : "failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_initcall(compat_mode_detect);
|
||||
#endif
|
||||
|
||||
void start_thread(struct pt_regs *regs, unsigned long pc,
|
||||
unsigned long sp)
|
||||
{
|
||||
@ -98,6 +126,15 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
|
||||
}
|
||||
regs->epc = pc;
|
||||
regs->sp = sp;
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
regs->status &= ~SR_UXL;
|
||||
|
||||
if (is_compat_task())
|
||||
regs->status |= SR_UXL_32;
|
||||
else
|
||||
regs->status |= SR_UXL_64;
|
||||
#endif
|
||||
}
|
||||
|
||||
void flush_thread(void)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/regset.h>
|
||||
@ -110,11 +111,6 @@ static const struct user_regset_view riscv_user_native_view = {
|
||||
.n = ARRAY_SIZE(riscv_user_regset),
|
||||
};
|
||||
|
||||
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
|
||||
{
|
||||
return &riscv_user_native_view;
|
||||
}
|
||||
|
||||
struct pt_regs_offset {
|
||||
const char *name;
|
||||
int offset;
|
||||
@ -272,3 +268,84 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
|
||||
trace_sys_exit(regs, regs_return_value(regs));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_riscv_gpr_get(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
struct membuf to)
|
||||
{
|
||||
struct compat_user_regs_struct cregs;
|
||||
|
||||
regs_to_cregs(&cregs, task_pt_regs(target));
|
||||
|
||||
return membuf_write(&to, &cregs,
|
||||
sizeof(struct compat_user_regs_struct));
|
||||
}
|
||||
|
||||
static int compat_riscv_gpr_set(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
struct compat_user_regs_struct cregs;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);
|
||||
|
||||
cregs_to_regs(&cregs, task_pt_regs(target));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct user_regset compat_riscv_user_regset[] = {
|
||||
[REGSET_X] = {
|
||||
.core_note_type = NT_PRSTATUS,
|
||||
.n = ELF_NGREG,
|
||||
.size = sizeof(compat_elf_greg_t),
|
||||
.align = sizeof(compat_elf_greg_t),
|
||||
.regset_get = compat_riscv_gpr_get,
|
||||
.set = compat_riscv_gpr_set,
|
||||
},
|
||||
#ifdef CONFIG_FPU
|
||||
[REGSET_F] = {
|
||||
.core_note_type = NT_PRFPREG,
|
||||
.n = ELF_NFPREG,
|
||||
.size = sizeof(elf_fpreg_t),
|
||||
.align = sizeof(elf_fpreg_t),
|
||||
.regset_get = riscv_fpr_get,
|
||||
.set = riscv_fpr_set,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct user_regset_view compat_riscv_user_native_view = {
|
||||
.name = "riscv",
|
||||
.e_machine = EM_RISCV,
|
||||
.regsets = compat_riscv_user_regset,
|
||||
.n = ARRAY_SIZE(compat_riscv_user_regset),
|
||||
};
|
||||
|
||||
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
compat_ulong_t caddr, compat_ulong_t cdata)
|
||||
{
|
||||
long ret = -EIO;
|
||||
|
||||
switch (request) {
|
||||
default:
|
||||
ret = compat_ptrace_request(child, request, caddr, cdata);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
|
||||
{
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (test_tsk_thread_flag(task, TIF_32BIT))
|
||||
return &compat_riscv_user_native_view;
|
||||
else
|
||||
#endif
|
||||
return &riscv_user_native_view;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Copyright (C) 2012 Regents of the University of California
|
||||
*/
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
@ -14,6 +15,7 @@
|
||||
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/vdso.h>
|
||||
#include <asm/signal32.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/csr.h>
|
||||
|
||||
@ -261,7 +263,10 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
||||
rseq_signal_deliver(ksig, regs);
|
||||
|
||||
/* Set up the stack frame */
|
||||
ret = setup_rt_frame(ksig, oldset, regs);
|
||||
if (is_compat_task())
|
||||
ret = compat_setup_rt_frame(ksig, oldset, regs);
|
||||
else
|
||||
ret = setup_rt_frame(ksig, oldset, regs);
|
||||
|
||||
signal_setup_done(ret, ksig, 0);
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
|
||||
{
|
||||
return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0);
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
|
||||
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
|
||||
unsigned long, prot, unsigned long, flags,
|
||||
unsigned long, fd, off_t, offset)
|
||||
@ -44,7 +46,7 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
|
||||
*/
|
||||
return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 12);
|
||||
}
|
||||
#endif /* !CONFIG_64BIT */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allows the instruction cache to be flushed from userspace. Despite RISC-V
|
||||
|
@ -23,6 +23,9 @@ struct vdso_data {
|
||||
#endif
|
||||
|
||||
extern char vdso_start[], vdso_end[];
|
||||
#ifdef CONFIG_COMPAT
|
||||
extern char compat_vdso_start[], compat_vdso_end[];
|
||||
#endif
|
||||
|
||||
enum vvar_pages {
|
||||
VVAR_DATA_PAGE_OFFSET,
|
||||
@ -30,6 +33,11 @@ enum vvar_pages {
|
||||
VVAR_NR_PAGES,
|
||||
};
|
||||
|
||||
enum rv_vdso_map {
|
||||
RV_VDSO_MAP_VVAR,
|
||||
RV_VDSO_MAP_VDSO,
|
||||
};
|
||||
|
||||
#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
|
||||
|
||||
/*
|
||||
@ -52,12 +60,6 @@ struct __vdso_info {
|
||||
struct vm_special_mapping *cm;
|
||||
};
|
||||
|
||||
static struct __vdso_info vdso_info __ro_after_init = {
|
||||
.name = "vdso",
|
||||
.vdso_code_start = vdso_start,
|
||||
.vdso_code_end = vdso_end,
|
||||
};
|
||||
|
||||
static int vdso_mremap(const struct vm_special_mapping *sm,
|
||||
struct vm_area_struct *new_vma)
|
||||
{
|
||||
@ -66,37 +68,33 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init __vdso_init(void)
|
||||
static void __init __vdso_init(struct __vdso_info *vdso_info)
|
||||
{
|
||||
unsigned int i;
|
||||
struct page **vdso_pagelist;
|
||||
unsigned long pfn;
|
||||
|
||||
if (memcmp(vdso_info.vdso_code_start, "\177ELF", 4)) {
|
||||
pr_err("vDSO is not a valid ELF object!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (memcmp(vdso_info->vdso_code_start, "\177ELF", 4))
|
||||
panic("vDSO is not a valid ELF object!\n");
|
||||
|
||||
vdso_info.vdso_pages = (
|
||||
vdso_info.vdso_code_end -
|
||||
vdso_info.vdso_code_start) >>
|
||||
vdso_info->vdso_pages = (
|
||||
vdso_info->vdso_code_end -
|
||||
vdso_info->vdso_code_start) >>
|
||||
PAGE_SHIFT;
|
||||
|
||||
vdso_pagelist = kcalloc(vdso_info.vdso_pages,
|
||||
vdso_pagelist = kcalloc(vdso_info->vdso_pages,
|
||||
sizeof(struct page *),
|
||||
GFP_KERNEL);
|
||||
if (vdso_pagelist == NULL)
|
||||
return -ENOMEM;
|
||||
panic("vDSO kcalloc failed!\n");
|
||||
|
||||
/* Grab the vDSO code pages. */
|
||||
pfn = sym_to_pfn(vdso_info.vdso_code_start);
|
||||
pfn = sym_to_pfn(vdso_info->vdso_code_start);
|
||||
|
||||
for (i = 0; i < vdso_info.vdso_pages; i++)
|
||||
for (i = 0; i < vdso_info->vdso_pages; i++)
|
||||
vdso_pagelist[i] = pfn_to_page(pfn + i);
|
||||
|
||||
vdso_info.cm->pages = vdso_pagelist;
|
||||
|
||||
return 0;
|
||||
vdso_info->cm->pages = vdso_pagelist;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TIME_NS
|
||||
@ -116,13 +114,14 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
|
||||
{
|
||||
struct mm_struct *mm = task->mm;
|
||||
struct vm_area_struct *vma;
|
||||
struct __vdso_info *vdso_info = mm->context.vdso_info;
|
||||
|
||||
mmap_read_lock(mm);
|
||||
|
||||
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
|
||||
if (vma_is_special_mapping(vma, vdso_info.dm))
|
||||
if (vma_is_special_mapping(vma, vdso_info->dm))
|
||||
zap_page_range(vma, vma->vm_start, size);
|
||||
}
|
||||
|
||||
@ -187,11 +186,6 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
|
||||
return vmf_insert_pfn(vma, vmf->address, pfn);
|
||||
}
|
||||
|
||||
enum rv_vdso_map {
|
||||
RV_VDSO_MAP_VVAR,
|
||||
RV_VDSO_MAP_VDSO,
|
||||
};
|
||||
|
||||
static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
|
||||
[RV_VDSO_MAP_VVAR] = {
|
||||
.name = "[vvar]",
|
||||
@ -203,25 +197,46 @@ static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct __vdso_info vdso_info __ro_after_init = {
|
||||
.name = "vdso",
|
||||
.vdso_code_start = vdso_start,
|
||||
.vdso_code_end = vdso_end,
|
||||
.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
|
||||
.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static struct __vdso_info compat_vdso_info __ro_after_init = {
|
||||
.name = "compat_vdso",
|
||||
.vdso_code_start = compat_vdso_start,
|
||||
.vdso_code_end = compat_vdso_end,
|
||||
.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
|
||||
.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init vdso_init(void)
|
||||
{
|
||||
vdso_info.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR];
|
||||
vdso_info.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO];
|
||||
__vdso_init(&vdso_info);
|
||||
#ifdef CONFIG_COMPAT
|
||||
__vdso_init(&compat_vdso_info);
|
||||
#endif
|
||||
|
||||
return __vdso_init();
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(vdso_init);
|
||||
|
||||
static int __setup_additional_pages(struct mm_struct *mm,
|
||||
struct linux_binprm *bprm,
|
||||
int uses_interp)
|
||||
int uses_interp,
|
||||
struct __vdso_info *vdso_info)
|
||||
{
|
||||
unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
|
||||
void *ret;
|
||||
|
||||
BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
|
||||
|
||||
vdso_text_len = vdso_info.vdso_pages << PAGE_SHIFT;
|
||||
vdso_text_len = vdso_info->vdso_pages << PAGE_SHIFT;
|
||||
/* Be sure to map the data page */
|
||||
vdso_mapping_len = vdso_text_len + VVAR_SIZE;
|
||||
|
||||
@ -232,16 +247,18 @@ static int __setup_additional_pages(struct mm_struct *mm,
|
||||
}
|
||||
|
||||
ret = _install_special_mapping(mm, vdso_base, VVAR_SIZE,
|
||||
(VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info.dm);
|
||||
(VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info->dm);
|
||||
if (IS_ERR(ret))
|
||||
goto up_fail;
|
||||
|
||||
vdso_base += VVAR_SIZE;
|
||||
mm->context.vdso = (void *)vdso_base;
|
||||
mm->context.vdso_info = (void *)vdso_info;
|
||||
|
||||
ret =
|
||||
_install_special_mapping(mm, vdso_base, vdso_text_len,
|
||||
(VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
|
||||
vdso_info.cm);
|
||||
vdso_info->cm);
|
||||
|
||||
if (IS_ERR(ret))
|
||||
goto up_fail;
|
||||
@ -253,6 +270,24 @@ up_fail:
|
||||
return PTR_ERR(ret);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
int uses_interp)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
int ret;
|
||||
|
||||
if (mmap_write_lock_killable(mm))
|
||||
return -EINTR;
|
||||
|
||||
ret = __setup_additional_pages(mm, bprm, uses_interp,
|
||||
&compat_vdso_info);
|
||||
mmap_write_unlock(mm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
@ -261,7 +296,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||
if (mmap_write_lock_killable(mm))
|
||||
return -EINTR;
|
||||
|
||||
ret = __setup_additional_pages(mm, bprm, uses_interp);
|
||||
ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso_info);
|
||||
mmap_write_unlock(mm);
|
||||
|
||||
return ret;
|
||||
|
@ -7,12 +7,16 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifndef __VDSO_PATH
|
||||
#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso.so"
|
||||
#endif
|
||||
|
||||
__PAGE_ALIGNED_DATA
|
||||
|
||||
.globl vdso_start, vdso_end
|
||||
.balign PAGE_SIZE
|
||||
vdso_start:
|
||||
.incbin "arch/riscv/kernel/vdso/vdso.so"
|
||||
.incbin __VDSO_PATH
|
||||
.balign PAGE_SIZE
|
||||
vdso_end:
|
||||
|
||||
|
@ -399,9 +399,6 @@ config COMPAT
|
||||
(and some other stuff like libraries and such) is needed for
|
||||
executing 31 bit applications. It is safe to say "Y".
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y if COMPAT && SYSVIPC
|
||||
|
||||
config SMP
|
||||
def_bool y
|
||||
|
||||
|
@ -12,6 +12,18 @@
|
||||
#define compat_mode_t compat_mode_t
|
||||
typedef u16 compat_mode_t;
|
||||
|
||||
#define __compat_uid_t __compat_uid_t
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
|
||||
#define compat_dev_t compat_dev_t
|
||||
typedef u16 compat_dev_t;
|
||||
|
||||
#define compat_ipc_pid_t compat_ipc_pid_t
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
#define compat_statfs compat_statfs
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \
|
||||
@ -53,15 +65,9 @@ typedef u16 compat_mode_t;
|
||||
PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
|
||||
PSW32_ASC_PRIMARY)
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
|
||||
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
typedef u16 compat_dev_t;
|
||||
typedef u16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
|
||||
typedef struct {
|
||||
u32 mask;
|
||||
@ -102,26 +108,6 @@ struct compat_stat {
|
||||
u32 __unused5;
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
u32 f_type;
|
||||
u32 f_bsize;
|
||||
@ -152,10 +138,6 @@ struct compat_statfs64 {
|
||||
u32 f_spare[4];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0xffffffff
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
|
||||
/*
|
||||
* A pointer passed in from user mode. This should not
|
||||
* be used for syscall parameters, just declare them
|
||||
@ -178,61 +160,4 @@ static inline int is_compat_task(void)
|
||||
|
||||
#endif
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
__compat_gid32_t gid;
|
||||
__compat_uid32_t cuid;
|
||||
__compat_gid32_t cgid;
|
||||
compat_mode_t mode;
|
||||
unsigned short __pad1;
|
||||
unsigned short seq;
|
||||
unsigned short __pad2;
|
||||
unsigned int __unused1;
|
||||
unsigned int __unused2;
|
||||
};
|
||||
|
||||
struct compat_semid64_ds {
|
||||
struct compat_ipc64_perm sem_perm;
|
||||
compat_ulong_t sem_otime;
|
||||
compat_ulong_t sem_otime_high;
|
||||
compat_ulong_t sem_ctime;
|
||||
compat_ulong_t sem_ctime_high;
|
||||
compat_ulong_t sem_nsems;
|
||||
compat_ulong_t __unused1;
|
||||
compat_ulong_t __unused2;
|
||||
};
|
||||
|
||||
struct compat_msqid64_ds {
|
||||
struct compat_ipc64_perm msg_perm;
|
||||
compat_ulong_t msg_stime;
|
||||
compat_ulong_t msg_stime_high;
|
||||
compat_ulong_t msg_rtime;
|
||||
compat_ulong_t msg_rtime_high;
|
||||
compat_ulong_t msg_ctime;
|
||||
compat_ulong_t msg_ctime_high;
|
||||
compat_ulong_t msg_cbytes;
|
||||
compat_ulong_t msg_qnum;
|
||||
compat_ulong_t msg_qbytes;
|
||||
compat_pid_t msg_lspid;
|
||||
compat_pid_t msg_lrpid;
|
||||
compat_ulong_t __unused1;
|
||||
compat_ulong_t __unused2;
|
||||
};
|
||||
|
||||
struct compat_shmid64_ds {
|
||||
struct compat_ipc64_perm shm_perm;
|
||||
compat_size_t shm_segsz;
|
||||
compat_ulong_t shm_atime;
|
||||
compat_ulong_t shm_atime_high;
|
||||
compat_ulong_t shm_dtime;
|
||||
compat_ulong_t shm_dtime_high;
|
||||
compat_ulong_t shm_ctime;
|
||||
compat_ulong_t shm_ctime_high;
|
||||
compat_pid_t shm_cpid;
|
||||
compat_pid_t shm_lpid;
|
||||
compat_ulong_t shm_nattch;
|
||||
compat_ulong_t __unused1;
|
||||
compat_ulong_t __unused2;
|
||||
};
|
||||
#endif /* _ASM_S390X_COMPAT_H */
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define __ARCH_WANT_SYS_SIGPENDING
|
||||
#define __ARCH_WANT_SYS_SIGPROCMASK
|
||||
# ifdef CONFIG_COMPAT
|
||||
# define __ARCH_WANT_COMPAT_STAT
|
||||
# define __ARCH_WANT_SYS_TIME32
|
||||
# define __ARCH_WANT_SYS_UTIME32
|
||||
# endif
|
||||
|
@ -488,9 +488,4 @@ config COMPAT
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
bool
|
||||
depends on COMPAT && SYSVIPC
|
||||
default y
|
||||
|
||||
source "drivers/sbus/char/Kconfig"
|
||||
|
@ -9,17 +9,25 @@
|
||||
#define compat_mode_t compat_mode_t
|
||||
typedef u16 compat_mode_t;
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "sparc\0\0"
|
||||
|
||||
#define __compat_uid_t __compat_uid_t
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
|
||||
#define compat_dev_t compat_dev_t
|
||||
typedef u16 compat_dev_t;
|
||||
|
||||
#define compat_ipc_pid_t compat_ipc_pid_t
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
#define compat_ipc64_perm compat_ipc64_perm
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0x7fffffff
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_UTS_MACHINE "sparc\0\0"
|
||||
|
||||
typedef s16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
@ -75,46 +83,7 @@ struct compat_stat64 {
|
||||
unsigned int __unused5;
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
short __unused;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
short __unused;
|
||||
};
|
||||
|
||||
struct compat_statfs {
|
||||
int f_type;
|
||||
int f_bsize;
|
||||
int f_blocks;
|
||||
int f_bfree;
|
||||
int f_bavail;
|
||||
int f_files;
|
||||
int f_ffree;
|
||||
compat_fsid_t f_fsid;
|
||||
int f_namelen; /* SunOS ignores this field. */
|
||||
int f_frsize;
|
||||
int f_flags;
|
||||
int f_spare[4];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0x7fffffff
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
#define __ARCH_COMPAT_FLOCK_PAD short __unused;
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define __ARCH_WANT_SYS_TIME
|
||||
#define __ARCH_WANT_SYS_UTIME
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#define __ARCH_WANT_COMPAT_STAT
|
||||
#endif
|
||||
|
||||
#ifdef __32bit_syscall_numbers__
|
||||
|
@ -2872,10 +2872,6 @@ config COMPAT
|
||||
if COMPAT
|
||||
config COMPAT_FOR_U64_ALIGNMENT
|
||||
def_bool y
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on SYSVIPC
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
@ -15,17 +15,23 @@
|
||||
#define compat_mode_t compat_mode_t
|
||||
typedef u16 compat_mode_t;
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#define COMPAT_UTS_MACHINE "i686\0\0"
|
||||
|
||||
#define __compat_uid_t __compat_uid_t
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
|
||||
#define compat_dev_t compat_dev_t
|
||||
typedef u16 compat_dev_t;
|
||||
|
||||
#define compat_ipc_pid_t compat_ipc_pid_t
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
|
||||
#define compat_statfs compat_statfs
|
||||
|
||||
#include <asm-generic/compat.h>
|
||||
|
||||
#define COMPAT_UTS_MACHINE "i686\0\0"
|
||||
|
||||
typedef u16 compat_nlink_t;
|
||||
typedef u16 compat_ipc_pid_t;
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
@ -50,29 +56,11 @@ struct compat_stat {
|
||||
u32 __unused5;
|
||||
};
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
};
|
||||
|
||||
#define F_GETLK64 12 /* using 'struct flock64' */
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
|
||||
/*
|
||||
* IA32 uses 4 byte alignment for 64 bit quantities,
|
||||
* so we need to pack this structure.
|
||||
* IA32 uses 4 byte alignment for 64 bit quantities, so we need to pack the
|
||||
* compat flock64 structure.
|
||||
*/
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
} __attribute__((packed));
|
||||
#define __ARCH_NEED_COMPAT_FLOCK64_PACKED
|
||||
|
||||
struct compat_statfs {
|
||||
int f_type;
|
||||
@ -89,68 +77,6 @@ struct compat_statfs {
|
||||
int f_spare[4];
|
||||
};
|
||||
|
||||
#define COMPAT_RLIM_INFINITY 0xffffffff
|
||||
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
__compat_gid32_t gid;
|
||||
__compat_uid32_t cuid;
|
||||
__compat_gid32_t cgid;
|
||||
unsigned short mode;
|
||||
unsigned short __pad1;
|
||||
unsigned short seq;
|
||||
unsigned short __pad2;
|
||||
compat_ulong_t unused1;
|
||||
compat_ulong_t unused2;
|
||||
};
|
||||
|
||||
struct compat_semid64_ds {
|
||||
struct compat_ipc64_perm sem_perm;
|
||||
compat_ulong_t sem_otime;
|
||||
compat_ulong_t sem_otime_high;
|
||||
compat_ulong_t sem_ctime;
|
||||
compat_ulong_t sem_ctime_high;
|
||||
compat_ulong_t sem_nsems;
|
||||
compat_ulong_t __unused3;
|
||||
compat_ulong_t __unused4;
|
||||
};
|
||||
|
||||
struct compat_msqid64_ds {
|
||||
struct compat_ipc64_perm msg_perm;
|
||||
compat_ulong_t msg_stime;
|
||||
compat_ulong_t msg_stime_high;
|
||||
compat_ulong_t msg_rtime;
|
||||
compat_ulong_t msg_rtime_high;
|
||||
compat_ulong_t msg_ctime;
|
||||
compat_ulong_t msg_ctime_high;
|
||||
compat_ulong_t msg_cbytes;
|
||||
compat_ulong_t msg_qnum;
|
||||
compat_ulong_t msg_qbytes;
|
||||
compat_pid_t msg_lspid;
|
||||
compat_pid_t msg_lrpid;
|
||||
compat_ulong_t __unused4;
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
|
||||
struct compat_shmid64_ds {
|
||||
struct compat_ipc64_perm shm_perm;
|
||||
compat_size_t shm_segsz;
|
||||
compat_ulong_t shm_atime;
|
||||
compat_ulong_t shm_atime_high;
|
||||
compat_ulong_t shm_dtime;
|
||||
compat_ulong_t shm_dtime_high;
|
||||
compat_ulong_t shm_ctime;
|
||||
compat_ulong_t shm_ctime_high;
|
||||
compat_pid_t shm_cpid;
|
||||
compat_pid_t shm_lpid;
|
||||
compat_ulong_t shm_nattch;
|
||||
compat_ulong_t __unused4;
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_X86_X32_ABI
|
||||
#define COMPAT_USE_64BIT_TIME \
|
||||
(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
|
||||
|
@ -22,6 +22,7 @@
|
||||
# include <asm/unistd_32_ia32.h>
|
||||
# define __ARCH_WANT_SYS_TIME
|
||||
# define __ARCH_WANT_SYS_UTIME
|
||||
# define __ARCH_WANT_COMPAT_STAT
|
||||
# define __ARCH_WANT_COMPAT_SYS_PREADV64
|
||||
# define __ARCH_WANT_COMPAT_SYS_PWRITEV64
|
||||
# define __ARCH_WANT_COMPAT_SYS_PREADV64V2
|
||||
|
24
fs/open.c
24
fs/open.c
@ -224,6 +224,21 @@ SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
|
||||
}
|
||||
#endif /* BITS_PER_LONG == 32 */
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_TRUNCATE64)
|
||||
COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
|
||||
compat_arg_u64_dual(length))
|
||||
{
|
||||
return ksys_truncate(pathname, compat_arg_u64_glue(length));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FTRUNCATE64)
|
||||
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd,
|
||||
compat_arg_u64_dual(length))
|
||||
{
|
||||
return ksys_ftruncate(fd, compat_arg_u64_glue(length));
|
||||
}
|
||||
#endif
|
||||
|
||||
int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||
{
|
||||
@ -339,6 +354,15 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
|
||||
return ksys_fallocate(fd, mode, offset, len);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FALLOCATE)
|
||||
COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, compat_arg_u64_dual(offset),
|
||||
compat_arg_u64_dual(len))
|
||||
{
|
||||
return ksys_fallocate(fd, mode, compat_arg_u64_glue(offset),
|
||||
compat_arg_u64_glue(len));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
* We do this by temporarily clearing all FS-related capabilities and
|
||||
|
@ -682,6 +682,14 @@ SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
|
||||
return ksys_pread64(fd, buf, count, pos);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PREAD64)
|
||||
COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
|
||||
size_t, count, compat_arg_u64_dual(pos))
|
||||
{
|
||||
return ksys_pread64(fd, buf, count, compat_arg_u64_glue(pos));
|
||||
}
|
||||
#endif
|
||||
|
||||
ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf,
|
||||
size_t count, loff_t pos)
|
||||
{
|
||||
@ -708,6 +716,14 @@ SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
|
||||
return ksys_pwrite64(fd, buf, count, pos);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PWRITE64)
|
||||
COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, buf,
|
||||
size_t, count, compat_arg_u64_dual(pos))
|
||||
{
|
||||
return ksys_pwrite64(fd, buf, count, compat_arg_u64_glue(pos));
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
|
||||
loff_t *ppos, int type, rwf_t flags)
|
||||
{
|
||||
|
@ -660,7 +660,7 @@ SYSCALL_DEFINE5(statx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_STAT)
|
||||
static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
|
||||
{
|
||||
struct compat_stat tmp;
|
||||
|
@ -373,6 +373,15 @@ SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
|
||||
return ksys_sync_file_range(fd, offset, nbytes, flags);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_SYNC_FILE_RANGE)
|
||||
COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, compat_arg_u64_dual(offset),
|
||||
compat_arg_u64_dual(nbytes), unsigned int, flags)
|
||||
{
|
||||
return ksys_sync_file_range(fd, compat_arg_u64_glue(offset),
|
||||
compat_arg_u64_glue(nbytes), flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* It would be nice if people remember that not all the world's an i386
|
||||
when they introduce new system calls */
|
||||
SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
|
||||
|
@ -2,6 +2,25 @@
|
||||
#ifndef __ASM_GENERIC_COMPAT_H
|
||||
#define __ASM_GENERIC_COMPAT_H
|
||||
|
||||
#ifndef COMPAT_USER_HZ
|
||||
#define COMPAT_USER_HZ 100
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_RLIM_INFINITY
|
||||
#define COMPAT_RLIM_INFINITY 0xffffffff
|
||||
#endif
|
||||
|
||||
#ifndef COMPAT_OFF_T_MAX
|
||||
#define COMPAT_OFF_T_MAX 0x7fffffff
|
||||
#endif
|
||||
|
||||
#if !defined(compat_arg_u64) && !defined(CONFIG_CPU_BIG_ENDIAN)
|
||||
#define compat_arg_u64(name) u32 name##_lo, u32 name##_hi
|
||||
#define compat_arg_u64_dual(name) u32, name##_lo, u32, name##_hi
|
||||
#define compat_arg_u64_glue(name) (((u64)name##_lo & 0xffffffffUL) | \
|
||||
((u64)name##_hi << 32))
|
||||
#endif
|
||||
|
||||
/* These types are common across all compat ABIs */
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
@ -24,6 +43,11 @@ typedef u32 compat_caddr_t;
|
||||
typedef u32 compat_aio_context_t;
|
||||
typedef u32 compat_old_sigset_t;
|
||||
|
||||
#ifndef __compat_uid_t
|
||||
typedef u32 __compat_uid_t;
|
||||
typedef u32 __compat_gid_t;
|
||||
#endif
|
||||
|
||||
#ifndef __compat_uid32_t
|
||||
typedef u32 __compat_uid32_t;
|
||||
typedef u32 __compat_gid32_t;
|
||||
@ -47,4 +71,93 @@ typedef u32 compat_sigset_word;
|
||||
#define _COMPAT_NSIG_BPW 32
|
||||
#endif
|
||||
|
||||
#ifndef compat_dev_t
|
||||
typedef u32 compat_dev_t;
|
||||
#endif
|
||||
|
||||
#ifndef compat_ipc_pid_t
|
||||
typedef s32 compat_ipc_pid_t;
|
||||
#endif
|
||||
|
||||
#ifndef compat_fsid_t
|
||||
typedef __kernel_fsid_t compat_fsid_t;
|
||||
#endif
|
||||
|
||||
#ifndef compat_statfs
|
||||
struct compat_statfs {
|
||||
compat_int_t f_type;
|
||||
compat_int_t f_bsize;
|
||||
compat_int_t f_blocks;
|
||||
compat_int_t f_bfree;
|
||||
compat_int_t f_bavail;
|
||||
compat_int_t f_files;
|
||||
compat_int_t f_ffree;
|
||||
compat_fsid_t f_fsid;
|
||||
compat_int_t f_namelen;
|
||||
compat_int_t f_frsize;
|
||||
compat_int_t f_flags;
|
||||
compat_int_t f_spare[4];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef compat_ipc64_perm
|
||||
struct compat_ipc64_perm {
|
||||
compat_key_t key;
|
||||
__compat_uid32_t uid;
|
||||
__compat_gid32_t gid;
|
||||
__compat_uid32_t cuid;
|
||||
__compat_gid32_t cgid;
|
||||
compat_mode_t mode;
|
||||
unsigned char __pad1[4 - sizeof(compat_mode_t)];
|
||||
compat_ushort_t seq;
|
||||
compat_ushort_t __pad2;
|
||||
compat_ulong_t unused1;
|
||||
compat_ulong_t unused2;
|
||||
};
|
||||
|
||||
struct compat_semid64_ds {
|
||||
struct compat_ipc64_perm sem_perm;
|
||||
compat_ulong_t sem_otime;
|
||||
compat_ulong_t sem_otime_high;
|
||||
compat_ulong_t sem_ctime;
|
||||
compat_ulong_t sem_ctime_high;
|
||||
compat_ulong_t sem_nsems;
|
||||
compat_ulong_t __unused3;
|
||||
compat_ulong_t __unused4;
|
||||
};
|
||||
|
||||
struct compat_msqid64_ds {
|
||||
struct compat_ipc64_perm msg_perm;
|
||||
compat_ulong_t msg_stime;
|
||||
compat_ulong_t msg_stime_high;
|
||||
compat_ulong_t msg_rtime;
|
||||
compat_ulong_t msg_rtime_high;
|
||||
compat_ulong_t msg_ctime;
|
||||
compat_ulong_t msg_ctime_high;
|
||||
compat_ulong_t msg_cbytes;
|
||||
compat_ulong_t msg_qnum;
|
||||
compat_ulong_t msg_qbytes;
|
||||
compat_pid_t msg_lspid;
|
||||
compat_pid_t msg_lrpid;
|
||||
compat_ulong_t __unused4;
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
|
||||
struct compat_shmid64_ds {
|
||||
struct compat_ipc64_perm shm_perm;
|
||||
compat_size_t shm_segsz;
|
||||
compat_ulong_t shm_atime;
|
||||
compat_ulong_t shm_atime_high;
|
||||
compat_ulong_t shm_dtime;
|
||||
compat_ulong_t shm_dtime_high;
|
||||
compat_ulong_t shm_ctime;
|
||||
compat_ulong_t shm_ctime_high;
|
||||
compat_pid_t shm_cpid;
|
||||
compat_pid_t shm_lpid;
|
||||
compat_ulong_t shm_nattch;
|
||||
compat_ulong_t __unused4;
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -258,6 +258,37 @@ struct compat_rlimit {
|
||||
compat_ulong_t rlim_max;
|
||||
};
|
||||
|
||||
#ifdef __ARCH_NEED_COMPAT_FLOCK64_PACKED
|
||||
#define __ARCH_COMPAT_FLOCK64_PACK __attribute__((packed))
|
||||
#else
|
||||
#define __ARCH_COMPAT_FLOCK64_PACK
|
||||
#endif
|
||||
|
||||
struct compat_flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_off_t l_start;
|
||||
compat_off_t l_len;
|
||||
#ifdef __ARCH_COMPAT_FLOCK_EXTRA_SYSID
|
||||
__ARCH_COMPAT_FLOCK_EXTRA_SYSID
|
||||
#endif
|
||||
compat_pid_t l_pid;
|
||||
#ifdef __ARCH_COMPAT_FLOCK_PAD
|
||||
__ARCH_COMPAT_FLOCK_PAD
|
||||
#endif
|
||||
};
|
||||
|
||||
struct compat_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
compat_loff_t l_start;
|
||||
compat_loff_t l_len;
|
||||
compat_pid_t l_pid;
|
||||
#ifdef __ARCH_COMPAT_FLOCK64_PAD
|
||||
__ARCH_COMPAT_FLOCK64_PAD
|
||||
#endif
|
||||
} __ARCH_COMPAT_FLOCK64_PACK;
|
||||
|
||||
struct compat_rusage {
|
||||
struct old_timeval32 ru_utime;
|
||||
struct old_timeval32 ru_stime;
|
||||
@ -895,6 +926,43 @@ asmlinkage long compat_sys_sigaction(int sig,
|
||||
/* obsolete: net/socket.c */
|
||||
asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_TRUNCATE64
|
||||
asmlinkage long compat_sys_truncate64(const char __user *pathname, compat_arg_u64(len));
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_FTRUNCATE64
|
||||
asmlinkage long compat_sys_ftruncate64(unsigned int fd, compat_arg_u64(len));
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_FALLOCATE
|
||||
asmlinkage long compat_sys_fallocate(int fd, int mode, compat_arg_u64(offset),
|
||||
compat_arg_u64(len));
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_PREAD64
|
||||
asmlinkage long compat_sys_pread64(unsigned int fd, char __user *buf, size_t count,
|
||||
compat_arg_u64(pos));
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_PWRITE64
|
||||
asmlinkage long compat_sys_pwrite64(unsigned int fd, const char __user *buf, size_t count,
|
||||
compat_arg_u64(pos));
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYNC_FILE_RANGE
|
||||
asmlinkage long compat_sys_sync_file_range(int fd, compat_arg_u64(pos),
|
||||
compat_arg_u64(nbytes), unsigned int flags);
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_FADVISE64_64
|
||||
asmlinkage long compat_sys_fadvise64_64(int fd, compat_arg_u64(pos),
|
||||
compat_arg_u64(len), int advice);
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_READAHEAD
|
||||
asmlinkage long compat_sys_readahead(int fd, compat_arg_u64(offset), size_t count);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */
|
||||
|
||||
/**
|
||||
|
@ -116,13 +116,13 @@
|
||||
#define F_GETSIG 11 /* for sockets. */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
#if __BITS_PER_LONG == 32 || defined(__KERNEL__)
|
||||
#ifndef F_GETLK64
|
||||
#define F_GETLK64 12 /* using 'struct flock64' */
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
#endif
|
||||
#endif
|
||||
#endif /* __BITS_PER_LONG == 32 || defined(__KERNEL__) */
|
||||
|
||||
#ifndef F_SETOWN_EX
|
||||
#define F_SETOWN_EX 15
|
||||
@ -192,25 +192,19 @@ struct f_owner_ex {
|
||||
|
||||
#define F_LINUX_SPECIFIC_BASE 1024
|
||||
|
||||
#ifndef HAVE_ARCH_STRUCT_FLOCK
|
||||
#ifndef __ARCH_FLOCK_PAD
|
||||
#define __ARCH_FLOCK_PAD
|
||||
#endif
|
||||
|
||||
struct flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
__kernel_off_t l_start;
|
||||
__kernel_off_t l_len;
|
||||
__kernel_pid_t l_pid;
|
||||
#ifdef __ARCH_FLOCK_EXTRA_SYSID
|
||||
__ARCH_FLOCK_EXTRA_SYSID
|
||||
#endif
|
||||
#ifdef __ARCH_FLOCK_PAD
|
||||
__ARCH_FLOCK_PAD
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ARCH_STRUCT_FLOCK64
|
||||
#ifndef __ARCH_FLOCK64_PAD
|
||||
#define __ARCH_FLOCK64_PAD
|
||||
#endif
|
||||
|
||||
struct flock64 {
|
||||
short l_type;
|
||||
@ -218,8 +212,9 @@ struct flock64 {
|
||||
__kernel_loff_t l_start;
|
||||
__kernel_loff_t l_len;
|
||||
__kernel_pid_t l_pid;
|
||||
#ifdef __ARCH_FLOCK64_PAD
|
||||
__ARCH_FLOCK64_PAD
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _ASM_GENERIC_FCNTL_H */
|
||||
|
@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
|
||||
|
||||
/* kernel/ptrace.c */
|
||||
#define __NR_ptrace 117
|
||||
__SYSCALL(__NR_ptrace, sys_ptrace)
|
||||
__SC_COMP(__NR_ptrace, sys_ptrace, compat_sys_ptrace)
|
||||
|
||||
/* kernel/sched/core.c */
|
||||
#define __NR_sched_setparam 118
|
||||
@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
|
||||
#define __NR_kexec_file_load 294
|
||||
__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load)
|
||||
/* 295 through 402 are unassigned to sync up with generic numbers, don't use */
|
||||
#if __BITS_PER_LONG == 32
|
||||
#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
|
||||
#define __NR_clock_gettime64 403
|
||||
__SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
|
||||
#define __NR_clock_settime64 404
|
||||
|
@ -390,6 +390,10 @@ config SYSVIPC_SYSCTL
|
||||
depends on SYSCTL
|
||||
default y
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on COMPAT && SYSVIPC
|
||||
|
||||
config POSIX_MQUEUE
|
||||
bool "POSIX Message Queues"
|
||||
depends on NET
|
||||
|
11
mm/fadvise.c
11
mm/fadvise.c
@ -214,5 +214,16 @@ SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
|
||||
return ksys_fadvise64_64(fd, offset, len, advice);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FADVISE64_64)
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(fadvise64_64, int, fd, compat_arg_u64_dual(offset),
|
||||
compat_arg_u64_dual(len), int, advice)
|
||||
{
|
||||
return ksys_fadvise64_64(fd, compat_arg_u64_glue(offset),
|
||||
compat_arg_u64_glue(len), advice);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -746,6 +746,13 @@ SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count)
|
||||
return ksys_readahead(fd, offset, count);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_READAHEAD)
|
||||
COMPAT_SYSCALL_DEFINE4(readahead, int, fd, compat_arg_u64_dual(offset), size_t, count)
|
||||
{
|
||||
return ksys_readahead(fd, compat_arg_u64_glue(offset), count);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* readahead_expand - Expand a readahead request
|
||||
* @ractl: The request to be expanded
|
||||
|
@ -115,13 +115,11 @@
|
||||
#define F_GETSIG 11 /* for sockets. */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
#ifndef F_GETLK64
|
||||
#define F_GETLK64 12 /* using 'struct flock64' */
|
||||
#define F_SETLK64 13
|
||||
#define F_SETLKW64 14
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef F_SETOWN_EX
|
||||
#define F_SETOWN_EX 15
|
||||
@ -187,25 +185,19 @@ struct f_owner_ex {
|
||||
|
||||
#define F_LINUX_SPECIFIC_BASE 1024
|
||||
|
||||
#ifndef HAVE_ARCH_STRUCT_FLOCK
|
||||
#ifndef __ARCH_FLOCK_PAD
|
||||
#define __ARCH_FLOCK_PAD
|
||||
#endif
|
||||
|
||||
struct flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
__kernel_off_t l_start;
|
||||
__kernel_off_t l_len;
|
||||
__kernel_pid_t l_pid;
|
||||
#ifdef __ARCH_FLOCK_EXTRA_SYSID
|
||||
__ARCH_FLOCK_EXTRA_SYSID
|
||||
#endif
|
||||
#ifdef __ARCH_FLOCK_PAD
|
||||
__ARCH_FLOCK_PAD
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ARCH_STRUCT_FLOCK64
|
||||
#ifndef __ARCH_FLOCK64_PAD
|
||||
#define __ARCH_FLOCK64_PAD
|
||||
#endif
|
||||
|
||||
struct flock64 {
|
||||
short l_type;
|
||||
@ -213,8 +205,9 @@ struct flock64 {
|
||||
__kernel_loff_t l_start;
|
||||
__kernel_loff_t l_len;
|
||||
__kernel_pid_t l_pid;
|
||||
#ifdef __ARCH_FLOCK64_PAD
|
||||
__ARCH_FLOCK64_PAD
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _ASM_GENERIC_FCNTL_H */
|
||||
|
@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
|
||||
|
||||
/* kernel/ptrace.c */
|
||||
#define __NR_ptrace 117
|
||||
__SYSCALL(__NR_ptrace, sys_ptrace)
|
||||
__SC_COMP(__NR_ptrace, sys_ptrace, compat_sys_ptrace)
|
||||
|
||||
/* kernel/sched/core.c */
|
||||
#define __NR_sched_setparam 118
|
||||
@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
|
||||
#define __NR_kexec_file_load 294
|
||||
__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load)
|
||||
/* 295 through 402 are unassigned to sync up with generic numbers, don't use */
|
||||
#if __BITS_PER_LONG == 32
|
||||
#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
|
||||
#define __NR_clock_gettime64 403
|
||||
__SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
|
||||
#define __NR_clock_settime64 404
|
||||
|
Loading…
x
Reference in New Issue
Block a user