diff mbox series

[08/13] riscv: compat: Add COMPAT Kbuild skeletal support

Message ID 20211221163532.2636028-9-guoren@kernel.org (mailing list archive)
State New, archived
Headers show
Series riscv: compat: Add COMPAT mode support for rv64 | expand

Commit Message

Guo Ren Dec. 21, 2021, 4:35 p.m. UTC
From: Guo Ren <guoren@linux.alibaba.com>

Adds initial skeletal COMPAT Kbuild (Runing 32bit U-mode on 64bit
S-mode) support.
 - Setup kconfig & dummy functions for compiling.
 - Implement compat_start_thread by the way.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
 arch/riscv/Kconfig                 | 22 ++++++++++++++++++++++
 arch/riscv/include/asm/elf.h       |  8 ++++++++
 arch/riscv/include/asm/processor.h |  3 +++
 arch/riscv/kernel/Makefile         |  2 ++
 arch/riscv/kernel/compat_signal.c  | 18 ++++++++++++++++++
 arch/riscv/kernel/process.c        | 10 ++++++++++
 arch/riscv/kernel/ptrace.c         |  9 +++++++++
 arch/riscv/kernel/vdso.c           |  8 ++++++++
 8 files changed, 80 insertions(+)
 create mode 100644 arch/riscv/kernel/compat_signal.c

Comments

Arnd Bergmann Dec. 21, 2021, 5:21 p.m. UTC | #1
On Tue, Dec 21, 2021 at 5:35 PM <guoren@kernel.org> wrote:
> +
> +config SYSVIPC_COMPAT
> +       def_bool y
> +       depends on COMPAT && SYSVIPC

Can this be moved to init/Kconfig next to SYSVIPC?

> +
> +COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
> +{
> +       return 0;
> +}

This confused me a bit while reviewing, would it make sense to reorder the
patches to add the three missing functions first instead of adding the
dummy and then replacing it?


        Arnd
Guo Ren Dec. 22, 2021, 12:06 p.m. UTC | #2
On Wed, Dec 22, 2021 at 2:23 AM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Dec 21, 2021 at 5:35 PM <guoren@kernel.org> wrote:
> > +
> > +config SYSVIPC_COMPAT
> > +       def_bool y
> > +       depends on COMPAT && SYSVIPC
>
> Can this be moved to init/Kconfig next to SYSVIPC?

I would try another patchset, to see other architecture guys' advice.

$ grep SYSVIPC_COMPAT arch -r
arch/x86/Kconfig:config SYSVIPC_COMPAT
arch/parisc/Kconfig:config SYSVIPC_COMPAT
arch/powerpc/Kconfig:config SYSVIPC_COMPAT
arch/arm64/Kconfig:config SYSVIPC_COMPAT
arch/riscv/Kconfig:config SYSVIPC_COMPAT
arch/s390/Kconfig:config SYSVIPC_COMPAT
arch/mips/Kconfig:config SYSVIPC_COMPAT
arch/mips/Kconfig:      select SYSVIPC_COMPAT if SYSVIPC
arch/mips/Kconfig:      select SYSVIPC_COMPAT if SYSVIPC
arch/sparc/Kconfig:config SYSVIPC_COMPAT

>
> > +
> > +COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
> > +{
> > +       return 0;
> > +}
>
> This confused me a bit while reviewing, would it make sense to reorder the
> patches to add the three missing functions first instead of adding the
> dummy and then replacing it?
Okay, I would try in the next version. Make the compile at last.

>
>
>         Arnd
Christoph Hellwig Dec. 24, 2021, 6:54 a.m. UTC | #3
On Wed, Dec 22, 2021 at 08:06:55PM +0800, Guo Ren wrote:
> On Wed, Dec 22, 2021 at 2:23 AM Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > On Tue, Dec 21, 2021 at 5:35 PM <guoren@kernel.org> wrote:
> > > +
> > > +config SYSVIPC_COMPAT
> > > +       def_bool y
> > > +       depends on COMPAT && SYSVIPC
> >
> > Can this be moved to init/Kconfig next to SYSVIPC?
> 
> I would try another patchset, to see other architecture guys' advice.

The existing per-arch definitions are pretty much historic cruft.
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 821252b65f89..6c3515a492a8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -72,6 +72,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
@@ -122,12 +123,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
@@ -427,6 +434,21 @@  config CRASH_DUMP
 
 	  For more details see Documentation/admin-guide/kdump/kdump.rst
 
+config COMPAT
+	bool "Kernel support for 32-bit U-mode"
+	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.
+
+config SYSVIPC_COMPAT
+	def_bool y
+	depends on COMPAT && SYSVIPC
+
 endmenu
 
 menu "Boot options"
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 48c116f3c12d..37f1cbdaa242 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -129,5 +129,13 @@  do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)			   \
 typedef compat_ulong_t			compat_elf_greg_t;
 typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
 
+#define compat_start_thread		compat_start_thread
+
+
+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 */
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 8649436b8fcf..9544c138d9ce 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -62,6 +62,9 @@  extern void start_thread(struct pt_regs *regs,
 			unsigned long pc, unsigned long sp);
 
 #ifdef CONFIG_COMPAT
+extern void compat_start_thread(struct pt_regs *regs,
+				unsigned long pc, unsigned long sp);
+
 #define DEFAULT_MAP_WINDOW_64 TASK_SIZE_64
 #else
 #define DEFAULT_MAP_WINDOW_64 TASK_SIZE
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 3397ddac1a30..f83e22affd5f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -65,3 +65,5 @@  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
diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
new file mode 100644
index 000000000000..1ad3d348f37c
--- /dev/null
+++ b/arch/riscv/kernel/compat_signal.c
@@ -0,0 +1,18 @@ 
+// 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/tracehook.h>
+#include <linux/linkage.h>
+
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+#include <asm/switch_to.h>
+#include <asm/csr.h>
+
+COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
+{
+	return 0;
+}
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 03ac3aa611f5..9ebf9a95e5ea 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -15,6 +15,7 @@ 
 #include <linux/tick.h>
 #include <linux/ptrace.h>
 #include <linux/uaccess.h>
+#include <uapi/linux/elf.h>
 
 #include <asm/unistd.h>
 #include <asm/processor.h>
@@ -99,6 +100,15 @@  void start_thread(struct pt_regs *regs, unsigned long pc,
 	regs->sp = sp;
 }
 
+#ifdef CONFIG_COMPAT
+void compat_start_thread(struct pt_regs *regs, unsigned long pc,
+			 unsigned long sp)
+{
+	start_thread(regs, pc, sp);
+	regs->status |= SR_UXL_32;
+}
+#endif
+
 void flush_thread(void)
 {
 #ifdef CONFIG_FPU
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 9c0511119bad..55dd50f8a5cc 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -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>
@@ -275,3 +276,11 @@  __visible void do_syscall_trace_exit(struct pt_regs *regs)
 		trace_sys_exit(regs, regs_return_value(regs));
 #endif
 }
+
+#ifdef CONFIG_COMPAT
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+			compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	return 0;
+}
+#endif
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index a9436a65161a..4f523a23a5d1 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -253,6 +253,14 @@  static int __setup_additional_pages(struct mm_struct *mm,
 	return PTR_ERR(ret);
 }
 
+#ifdef CONFIG_COMPAT
+int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int uses_interp)
+{
+	return 0;
+}
+#endif
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;