[RFC PATCH 1/1] riscv: add Kconfig.vdso

Zhangjin Wu falcon at tinylab.org
Thu May 18 10:48:52 PDT 2023


Allow users to disable the vdso and compat vdso in Kconfig.

Copied and adapted some code from arm and arm64.

Size measured with a small rv64 config of v6.4-rc2:

            Config | Size      | Shrink
    ---------------|-----------|--------
           default | 1588 KB   |
    no compat vdso | 1584 KB   | -4 KB
     (and) no vdso | 1576 KB   | -12 KB

Signed-off-by: Zhangjin Wu <falcon at tinylab.org>
---
 arch/riscv/Kconfig                |  6 +-----
 arch/riscv/Kconfig.vdso           | 28 ++++++++++++++++++++++++++++
 arch/riscv/Makefile               |  8 +++++---
 arch/riscv/include/asm/elf.h      |  6 ++++--
 arch/riscv/include/asm/mmu.h      |  2 ++
 arch/riscv/include/asm/vdso.h     |  8 ++++----
 arch/riscv/kernel/Makefile        |  4 ++--
 arch/riscv/kernel/alternative.c   |  2 +-
 arch/riscv/kernel/compat_signal.c |  2 ++
 arch/riscv/kernel/entry.S         |  2 +-
 arch/riscv/kernel/signal.c        |  4 ++--
 arch/riscv/kernel/sys_riscv.c     |  2 +-
 arch/riscv/kernel/vdso.c          | 10 +++++-----
 13 files changed, 58 insertions(+), 26 deletions(-)
 create mode 100644 arch/riscv/Kconfig.vdso

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 348c0fa1fc8c..79a6b3f1e697 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -34,7 +34,6 @@ config RISCV
 	select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
-	select ARCH_HAS_VDSO_DATA
 	select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
 	select ARCH_STACKWALK
@@ -63,7 +62,6 @@ config RISCV
 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 	select GENERIC_EARLY_IOREMAP
 	select GENERIC_ENTRY
-	select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IOREMAP if MMU
 	select GENERIC_IRQ_IPI if SMP
@@ -76,8 +74,6 @@ config RISCV
 	select GENERIC_PTDUMP if MMU
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
-	select GENERIC_TIME_VSYSCALL if MMU && 64BIT
-	select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
 	select HARDIRQS_SW_RESEND
 	select HAS_IOPORT if MMU
 	select HAVE_ARCH_AUDITSYSCALL
@@ -105,7 +101,6 @@ config RISCV
 	select HAVE_FUNCTION_ARG_ACCESS_API
 	select HAVE_FUNCTION_ERROR_INJECTION
 	select HAVE_GCC_PLUGINS
-	select HAVE_GENERIC_VDSO if MMU && 64BIT
 	select HAVE_IRQ_TIME_ACCOUNTING
 	select HAVE_KPROBES if !XIP_KERNEL
 	select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
@@ -262,6 +257,7 @@ config RISCV_DMA_NONCOHERENT
 config AS_HAS_INSN
 	def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
 
+source "arch/riscv/Kconfig.vdso"
 source "arch/riscv/Kconfig.socs"
 source "arch/riscv/Kconfig.errata"
 
diff --git a/arch/riscv/Kconfig.vdso b/arch/riscv/Kconfig.vdso
new file mode 100644
index 000000000000..3c7ec638361d
--- /dev/null
+++ b/arch/riscv/Kconfig.vdso
@@ -0,0 +1,28 @@
+menu "VDSO selection"
+	depends on MMU
+
+config VDSO
+	bool "Enable VDSO for acceleration of some system calls" if EXPERT
+	default y
+	select HAVE_GENERIC_VDSO if 64BIT
+	select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
+	select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO
+	select GENERIC_TIME_VSYSCALL if 64BIT
+	select ARCH_HAS_VDSO_DATA
+	help
+	  Place in the process address space an ELF shared object
+	  providing fast implementations of gettimeofday and
+	  clock_gettime.
+
+config COMPAT_VDSO
+	bool "Enable vDSO for 32-bit applications" if EXPERT
+	default y
+	depends on VDSO
+	depends on COMPAT
+	select GENERIC_COMPAT_VDSO
+	help
+	  Place in the process address space of 32-bit applications an
+	  ELF shared object providing fast implementations of gettimeofday
+	  and clock_gettime.
+
+endmenu # "VDSO selection"
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 0fb256bf8270..6aa32e83f812 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -130,18 +130,20 @@ endif
 libs-y += arch/riscv/lib/
 libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
+ifeq ($(CONFIG_VDSO),y)
 PHONY += vdso_install
 vdso_install:
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
-	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+	$(if $(CONFIG_COMPAT_VDSO),$(Q)$(MAKE) \
 		$(build)=arch/riscv/kernel/compat_vdso compat_$@)
+endif
 
 ifeq ($(KBUILD_EXTMOD),)
-ifeq ($(CONFIG_MMU),y)
+ifeq ($(CONFIG_VDSO),y)
 prepare: vdso_prepare
 vdso_prepare: prepare0
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
-	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+	$(if $(CONFIG_COMPAT_VDSO),$(Q)$(MAKE) \
 		$(build)=arch/riscv/kernel/compat_vdso include/generated/compat_vdso-offsets.h)
 
 endif
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 30e7d2455960..e67ed2696f23 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -78,7 +78,7 @@ extern unsigned long elf_hwcap;
 
 #define COMPAT_ELF_PLATFORM	(NULL)
 
-#ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
 #define ARCH_DLINFO						\
 do {								\
 	/*							\
@@ -110,7 +110,7 @@ do {								\
 struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 	int uses_interp);
-#endif /* CONFIG_MMU */
+#endif /* CONFIG_VDSO */
 
 #define ELF_CORE_COPY_REGS(dest, regs)			\
 do {							\
@@ -136,10 +136,12 @@ 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];
 
+#ifdef CONFIG_COMPAT_VDSO
 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
 
 #endif /* CONFIG_COMPAT */
 #endif /* _ASM_RISCV_ELF_H */
diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
index 0099dc116168..8e88e81fcc32 100644
--- a/arch/riscv/include/asm/mmu.h
+++ b/arch/riscv/include/asm/mmu.h
@@ -15,7 +15,9 @@ typedef struct {
 #else
 	atomic_long_t id;
 #endif
+#ifdef CONFIG_VDSO
 	void *vdso;
+#endif
 #ifdef CONFIG_SMP
 	/* A local icache flush is needed before user execution can resume. */
 	cpumask_t icache_stale_mask;
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index f891478829a5..a4cedac5bdc9 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -12,7 +12,7 @@
  * All systems with an MMU have a VDSO, but systems without an MMU don't
  * support shared libraries and therefore don't have one.
  */
-#ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
 
 #define __VVAR_PAGES    2
 
@@ -22,7 +22,7 @@
 #define VDSO_SYMBOL(base, name)							\
 	(void __user *)((unsigned long)(base) + __vdso_##name##_offset)
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_VDSO
 #include <generated/compat_vdso-offsets.h>
 
 #define COMPAT_VDSO_SYMBOL(base, name)						\
@@ -30,12 +30,12 @@
 
 extern char compat_vdso_start[], compat_vdso_end[];
 
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_COMPAT_VDSO */
 
 extern char vdso_start[], vdso_end[];
 
 #endif /* !__ASSEMBLY__ */
 
-#endif /* CONFIG_MMU */
+#endif /* CONFIG_VDSO */
 
 #endif /* _ASM_RISCV_VDSO_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index fbdccc21418a..0bc4eb093e47 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -52,7 +52,7 @@ obj-y	+= stacktrace.o
 obj-y	+= cacheinfo.o
 obj-y	+= patch.o
 obj-y	+= probes/
-obj-$(CONFIG_MMU) += vdso.o vdso/
+obj-$(CONFIG_VDSO) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_M_MODE)	+= traps_misaligned.o
 obj-$(CONFIG_FPU)		+= fpu.o
@@ -89,6 +89,6 @@ 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/
+obj-$(CONFIG_COMPAT_VDSO)	+= compat_vdso/
 
 obj-$(CONFIG_64BIT)		+= pi/
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 6b75788c18e6..16e9a10e24b4 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -181,7 +181,7 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
 				stage);
 }
 
-#ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
 static void __init apply_vdso_alternatives(void)
 {
 	const Elf_Ehdr *hdr;
diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
index 6ec4e34255a9..9405880b1df6 100644
--- a/arch/riscv/kernel/compat_signal.c
+++ b/arch/riscv/kernel/compat_signal.c
@@ -217,8 +217,10 @@ int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	if (err)
 		return -EFAULT;
 
+#ifdef CONFIG_COMPAT_VDSO
 	regs->ra = (unsigned long)COMPAT_VDSO_SYMBOL(
 			current->mm->context.vdso, rt_sigreturn);
+#endif
 
 	/*
 	 * Set up registers for signal handler.
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 3fbb100bc9e4..11c5e6edae3c 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -345,7 +345,7 @@ SYM_CODE_START(excp_vect_table)
 excp_vect_table_end:
 SYM_CODE_END(excp_vect_table)
 
-#ifndef CONFIG_MMU
+#ifndef CONFIG_VDSO
 SYM_CODE_START(__user_rt_sigreturn)
 	li a7, __NR_rt_sigreturn
 	scall
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 9aff9d720590..bb8ee87ae28f 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -29,7 +29,7 @@ extern u32 __user_rt_sigreturn[2];
 struct rt_sigframe {
 	struct siginfo info;
 	struct ucontext uc;
-#ifndef CONFIG_MMU
+#ifndef CONFIG_VDSO
 	u32 sigreturn_code[2];
 #endif
 };
@@ -201,7 +201,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 		return -EFAULT;
 
 	/* Set up to return from userspace. */
-#ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
 	regs->ra = (unsigned long)VDSO_SYMBOL(
 		current->mm->context.vdso, rt_sigreturn);
 #else
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 5db29683ebee..8691bc8d247b 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -246,7 +246,7 @@ static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs,
 	return 0;
 }
 
-#ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
 
 static int __init init_hwprobe_vdso_data(void)
 {
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 9a68e7eaae4d..8a4cb4e4bd8b 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -50,7 +50,7 @@ struct __vdso_info {
 };
 
 static struct __vdso_info vdso_info;
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_VDSO
 static struct __vdso_info compat_vdso_info;
 #endif
 
@@ -115,7 +115,7 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 	for_each_vma(vmi, vma) {
 		if (vma_is_special_mapping(vma, vdso_info.dm))
 			zap_vma_pages(vma);
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_VDSO
 		if (vma_is_special_mapping(vma, compat_vdso_info.dm))
 			zap_vma_pages(vma);
 #endif
@@ -179,7 +179,7 @@ static struct __vdso_info vdso_info __ro_after_init = {
 	.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
 };
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_VDSO
 static struct vm_special_mapping rv_compat_vdso_maps[] __ro_after_init = {
 	[RV_VDSO_MAP_VVAR] = {
 		.name   = "[vvar]",
@@ -203,7 +203,7 @@ static struct __vdso_info compat_vdso_info __ro_after_init = {
 static int __init vdso_init(void)
 {
 	__vdso_init(&vdso_info);
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_VDSO
 	__vdso_init(&compat_vdso_info);
 #endif
 
@@ -254,7 +254,7 @@ static int __setup_additional_pages(struct mm_struct *mm,
 	return PTR_ERR(ret);
 }
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_VDSO
 int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
 				       int uses_interp)
 {
-- 
2.25.1




More information about the linux-riscv mailing list