Unverified Commit 7eb6369d authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

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
parents 93c06516 9be84592
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -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"
+9 −84
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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
+0 −5
Original line number Diff line number Diff line
@@ -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 −32
Original line number Diff line number Diff line
@@ -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;
Loading