[PATCH] vDSO, kbuild: Provide vDSO debug variants at runtime
Thomas Weißschuh <[email protected]> Wed, 08 Jul 2026 15:56:27 +0200
| Newsgroups | gmane.linux.kernel,gmane.linux.kbuild.devel |
|---|---|
| Message-ID | <[email protected]> |
Finding the debug version of the vDSO is not trivial as there is no common scheme where it is placed. That's especially problematic for CI testing. The vDSO futex unlock mechanism requires for testing to have access to the inner labels of the unlock assembly, which are only accessible via the debug so. Also for general debugging purposes it's convenient to have access to the debug vDSO at a well defined place. The files are placed in /sys/kernel/vdso_debug.tar.xz. They use the regular 'make vdso_install' layout, including build-id symlinks to find the correct file for each process. The design is kept close to the ones of the similar IKCONFIG and IKHEADERS. On x86 the x32 vDSO is derived from the x86_64 one, necessitating an explicit dependency to avoid errors due to concurrent builds. Suggested-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/lkml/[email protected]/ Signed-off-by: Thomas Weißschuh <[email protected]> --- Makefile | 33 ++++++++++++++++++++++++++++++++- arch/x86/Makefile | 3 +++ init/Kconfig | 10 ++++++++++ kernel/Makefile | 1 + kernel/vdso_debug.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b9c5792c79e0..8049f10c27b2 100644 --- a/Makefile +++ b/Makefile @@ -298,7 +298,7 @@ no-dot-config-targets := $(clean-targets) \ %asm-generic kernelversion %src-pkg dt_binding_check \ dt_style_selftest \ outputmakefile rustavailable rustfmt rustfmtcheck \ - run-command + run-command have-vdso-debug no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \ image_name single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/ @@ -1539,6 +1539,37 @@ vdso_install: export INSTALL_FILES = $(vdso-install-y) vdso_install: $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vdsoinst +# --------------------------------------------------------------------------- +# vDSO embedded debug symbols + +PHONY += vdso_prepare + +# Build the targets in $(vdso-install-y) +# Some architectures may do this already through vdso_prepare, +# so add a dependency to avoid race conditions +$(vdso-install-y): vdso_prepare prepare0 FORCE + @$(MAKE) $(build)=$(patsubst %/,%,$(dir $@)) $@ + +tar-opts := --mtime='1970-01-01 00:00:00' --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X + +quiet_cmd_vdso_debug_tar_xz = VDSODBG $@ + cmd_vdso_debug_tar_xz = \ + rm -rf $(tmp-target); mkdir -p $(tmp-target)/vdso/; \ + $(MAKE) quiet=@ MODLIB=$(tmp-target) vdso_install; \ + $(TAR) $(tar-opts) -a -c -f $@ -C $(tmp-target)/vdso/ . + +targets += vdso_debug.tar.xz +vdso_debug.tar.xz: $(vdso-install-y) FORCE + $(call if_changed,vdso_debug_tar_xz) + +ifdef CONFIG_IVDSODEBUG +prepare: vdso_debug.tar.xz +endif + +PHONY += have-vdso-debug +have-vdso-debug: + @echo $(if $(vdso-install-y)$(vdso-install-),y,n) + # --------------------------------------------------------------------------- # Tools diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 598f178102ee..b762fddb620e 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -316,6 +316,9 @@ vdso-install-$(CONFIG_X86_64) += arch/x86/entry/vdso/vdso64/vdso64.so.dbg vdso-install-$(CONFIG_X86_X32_ABI) += arch/x86/entry/vdso/vdso64/vdsox32.so.dbg vdso-install-$(CONFIG_COMPAT_32) += arch/x86/entry/vdso/vdso32/vdso32.so.dbg +# vdsox32.so.dbg is derived from vdso64.so.dbg. Avoid races with CONFIG_IVDSODEBUG +arch/x86/entry/vdso/vdso64/vdsox32.so.dbg: arch/x86/entry/vdso/vdso64/vdso64.so.dbg + archprepare: checkbin checkbin: ifdef CONFIG_MITIGATION_RETPOLINE diff --git a/init/Kconfig b/init/Kconfig index 5230d4879b1c..f09132a44264 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -801,6 +801,16 @@ config IKHEADERS or similar programs. If you build the headers as a module, a module called kheaders.ko is built which can be loaded on-demand to get access to headers. +config IVDSODEBUG + tristate "Enable vDSO debug information through /sys/kernel/vdso_debug.tar.xz" + depends on SYSFS + depends on "$(shell,make have-vdso-debug)" + help + This option enables access to the vDSO debug information. That can be + used to debug applications and test the vDSO implementation. + + If configured as M the module will be called vdso_debug.ko. + config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" range 12 25 diff --git a/kernel/Makefile b/kernel/Makefile index 1e1a31673577..8adcc26ef859 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -93,6 +93,7 @@ obj-$(CONFIG_USER_NS) += user_namespace.o obj-$(CONFIG_PID_NS) += pid_namespace.o obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_IKHEADERS) += kheaders.o +obj-$(CONFIG_IVDSODEBUG) += vdso_debug.o obj-$(CONFIG_SMP) += stop_machine.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o audit_watch.o audit_fsnotify.o audit_tree.o diff --git a/kernel/vdso_debug.c b/kernel/vdso_debug.c new file mode 100644 index 000000000000..72d4f11327fc --- /dev/null +++ b/kernel/vdso_debug.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/cache.h> +#include <linux/init.h> +#include <linux/kobject.h> +#include <linux/module.h> +#include <linux/sysfs.h> + +asm ( +" .pushsection .rodata, \"a\" \n" +" .global vdso_debug_data \n" +"vdso_debug_data: \n" +" .incbin \"vdso_debug.tar.xz\" \n" +" .global vdso_debug_data_end \n" +"vdso_debug_data_end: \n" +" .popsection \n" +); + +extern char vdso_debug_data[]; +extern char vdso_debug_data_end[]; + +static struct bin_attribute vdso_debug_attr __ro_after_init = + __BIN_ATTR_SIMPLE_RO(vdso_debug.tar.xz, 0444); + +static int __init vdso_debug_init(void) +{ + vdso_debug_attr.private = vdso_debug_data; + vdso_debug_attr.size = vdso_debug_data_end - vdso_debug_data; + + return sysfs_create_bin_file(kernel_kobj, &vdso_debug_attr); +} + +static void __exit vdso_debug_exit(void) +{ + sysfs_remove_bin_file(kernel_kobj, &vdso_debug_attr); +} + +module_init(vdso_debug_init); +module_exit(vdso_debug_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Thomas Weißschuh <[email protected]>"); +MODULE_DESCRIPTION("Provide vDSO debug information at runtime"); --- base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482 change-id: 20260624-vdso-sysfs-abfd14fde5a7 Best regards, -- Thomas Weißschuh <[email protected]>