Message ID | 95c2e86acbcaf8966251a471997b3f0cd3c64fbd.1684430522.git.falcon@tinylab.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | riscv: Allow disable vdso support | expand |
On Thu, 18 May 2023 10:48:52 PDT (-0700), falcon@tinylab.org wrote: > 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 Do the resulting kernels actually work? As far as I can tell this disables some syscalls that would break userspace (that time-related stuff that would be turned off) and the lack of rt_sigreturn would need an executable stack (which probably cancels out any benefits from the smaller text size). > Signed-off-by: Zhangjin Wu <falcon@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) > {
Hi, Palmer Thanks very much for your review. > On Thu, 18 May 2023 10:48:52 PDT (-0700), falcon@tinylab.org wrote: > > 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 > > Do the resulting kernels actually work? As far as I can tell this > disables some syscalls that would break userspace (that time-related > stuff that would be turned off) and the lack of rt_sigreturn would need > an executable stack (which probably cancels out any benefits from the > smaller text size). > Yes, its working is limited in extremely small embedded systems (who don't require such syscalls or their vdso speedup variants), the libc we currently tested is NoLibc. This is part of our work on kernel tinification for RISC-V, exactly, it is derived from the in-progress DCE/DSE work [1]. The simple background logic here is if the target system don't require a target syscall, no need to provide both the syscall and/or its vdso variants from kernel side. seems this logic is not specific to RISC-V, perhaps we should rethink it under the whole DSE work (Arnd has given some suggestions), for example, let the DSE 'framework' (based on user-space profiling) tell us which vdso variants should be reserved and which one is not required, manual selection is really not that friendly although ARM also currently provide the same config option. Thanks, Zhangjin Wu --- [1]: https://lore.kernel.org/lkml/cover.1695679700.git.falcon@tinylab.org/
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) {
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@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