[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