From 672981f4aec1d0131761aec60298312464bd7a50 Mon Sep 17 00:00:00 2001 From: Alan Maguire Date: Fri, 9 Oct 2026 12:23:20 +0100 Subject: kbuild, btf: Expose vmlinux inline BTF through sysfs Expose BTF inline-location information from vmlinux .BTF.inline sections in /sys/kernel/btf as vmlinux.inline. Embedded vmlinux inline BTF supports read-only mmap(). Provide runtime support for a module-delivered vmlinux inline BTF carrier. Its link record binds the carrier module name, BTF size, and SHA-256 digest to the running kernel before its data is made available through a lazy vmlinux.inline sysfs attribute. The carrier is handled before ordinary module BTF registration, so its incidental .BTF data is not exposed. Make CONFIG_DEBUG_INFO_BTF_INLINE tristate. When configured as a module, retain vmlinux final split inline BTF for btf_vmlinux_inline.ko instead of embedding it in vmlinux. Reserve .BTF.inline.link in vmlinux and extend the final resolve_btfids patch pass to bind btf_vmlinux_inline to the raw vmlinux.BTF.inline payload. This preserves the normal built-in configuration while allowing the large inline BTF payload to load on demand. Normal module inline BTF is handled separately, after its references have been relocated against the final module BTF. Signed-off-by: Alan Maguire Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261009112324.1442319-4-alan.maguire@oracle.com --- scripts/Makefile.btf | 7 +++++++ scripts/gen-btf.sh | 34 ++++++++++++++++++++++++++++++++-- scripts/link-vmlinux.sh | 8 +++++++- scripts/package/kernel.spec | 10 +++++----- 4 files changed, 51 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index a1812985a61a..98012344a81e 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -22,7 +22,14 @@ endif pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust +btf-inline := $(CONFIG_DEBUG_INFO_BTF_INLINE) +ifneq ($(btf-inline),) +btf-inline-feat := inline +pahole-flags-$(call test-ge, $(pahole-ver), 132) += --btf_features=$(btf-inline-feat) +endif + export PAHOLE_FLAGS := $(pahole-flags-y) +export BTF_INLINE := $(btf-inline) resolve-btfids-flags-y := resolve-btfids-flags-$(CONFIG_WERROR) += --fatal_warnings diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh index 8ca96eb10a69..e638291753d0 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -68,6 +68,10 @@ esac gen_btf_data() { + inline="" + if [ -n "${BTF_INLINE}" ] && [ -z "${BTF_BASE}" ]; then + inline="--inline" + fi btf1="${ELF_FILE}.BTF.1" ${PAHOLE} -J ${PAHOLE_FLAGS} \ ${BTF_BASE:+--btf_base ${BTF_BASE}} \ @@ -76,6 +80,7 @@ gen_btf_data() ${RESOLVE_BTFIDS} ${RESOLVE_BTFIDS_FLAGS} \ ${BTF_BASE:+--btf_base ${BTF_BASE}} \ + ${inline} \ --btf ${btf1} "${ELF_FILE}" } @@ -83,14 +88,28 @@ gen_btf_o() { btf_data=${ELF_FILE}.btf.o - # Create ${btf_data} which contains just .BTF section but no symbols. Add + # Create ${btf_data} which contains just BTF sections but no symbols. Add # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all # deletes all symbols including __start_BTF and __stop_BTF, which will # be redefined in the linker script. echo "" | ${CC} ${CLANG_FLAGS} ${KBUILD_CPPFLAGS} ${KBUILD_CFLAGS} -fno-lto -c -x c -o ${btf_data} - ${OBJCOPY} --add-section .BTF=${ELF_FILE}.BTF \ --set-section-flags .BTF=alloc,readonly ${btf_data} - ${OBJCOPY} --only-section=.BTF --strip-all ${btf_data} + ONLY_SEC="--only-section=.BTF" + btf_inline=${ELF_FILE}.BTF.inline + if [ "${BTF_INLINE}" = "m" ]; then + if [ -f "${btf_inline}" ]; then + cp "${btf_inline}" "${objtree}/vmlinux.BTF.inline" + else + rm -f "${objtree}/vmlinux.BTF.inline" + fi + fi + if [ "${BTF_INLINE}" = "y" ] && [ -f "${btf_inline}" ]; then + ${OBJCOPY} --add-section .BTF.inline=${btf_inline} \ + --set-section-flags .BTF.inline=alloc,readonly ${btf_data} + ONLY_SEC="${ONLY_SEC} --only-section=.BTF.inline" + fi + ${OBJCOPY} ${ONLY_SEC} --strip-all ${btf_data} # Change e_type to ET_REL so that it can be used to link final vmlinux. # GNU ld 2.35+ and lld do not allow an ET_EXEC input. @@ -111,6 +130,15 @@ embed_btf_data() if [ -f "${btf_base}" ]; then ${OBJCOPY} --add-section .BTF.base=${btf_base} ${ELF_FILE} fi + btf_inline="" + case "${ELF_FILE}" in + */btf_vmlinux_inline.ko) + btf_inline=${BTF_BASE}.BTF.inline + ;; + esac + if [ -n "${BTF_INLINE}" ] && [ -f "${btf_inline}" ]; then + ${OBJCOPY} --add-section .BTF.inline=${btf_inline} ${ELF_FILE} + fi btf_ids="${ELF_FILE}.BTF_ids" if [ -f "${btf_ids}" ]; then ${RESOLVE_BTFIDS} --patch_btfids ${btf_ids} ${ELF_FILE} @@ -121,6 +149,8 @@ cleanup() { rm -f "${ELF_FILE}.BTF.1" rm -f "${ELF_FILE}.BTF" + rm -f "${ELF_FILE}.BTF.inline" + rm -f "${ELF_FILE}.BTF.inline.link" if [ "${BTFGEN_MODE}" = "module" ]; then rm -f "${ELF_FILE}.BTF.base" rm -f "${ELF_FILE}.BTF_ids" diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index ab0b8125c8cb..5424caf5135b 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -289,7 +289,13 @@ vmlinux_link "${VMLINUX}" if is_enabled CONFIG_DEBUG_INFO_BTF; then info BTFIDS ${VMLINUX} - ${RESOLVE_BTFIDS} --patch_btfids ${btfids_vmlinux} ${VMLINUX} + if [ "${BTF_INLINE}" = "m" ]; then + ${RESOLVE_BTFIDS} --patch_btfids ${btfids_vmlinux} \ + --btf_link .BTF.inline:btf_vmlinux_inline:vmlinux.BTF.inline \ + ${VMLINUX} + else + ${RESOLVE_BTFIDS} --patch_btfids ${btfids_vmlinux} ${VMLINUX} + fi fi mksysmap "${VMLINUX}" System.map diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec index 46e80970f723..8f0933cbbe45 100644 --- a/scripts/package/kernel.spec +++ b/scripts/package/kernel.spec @@ -68,13 +68,13 @@ This package provides debug information for the kernel image and modules from th %undefine _debugsource_packages %undefine _debuginfo_subpackages -# Preserve .BTF and .BTF.base sections in kernel modules during debuginfo -# stripping. find-debuginfo.sh uses eu-strip which removes non-allocated ELF -# sections like .BTF by default. .BTF.base is required for BTF distillation -# support; without it, module BTF validation fails. +# Preserve .BTF, .BTF.base and .BTF.inline sections in kernel modules during +# debuginfo stripping. find-debuginfo.sh uses eu-strip which removes +# non-allocated ELF sections like .BTF by default. .BTF.base is required for +# BTF distillation support; without it, module BTF validation fails. %global with_keep_section %(%{__find_debuginfo} --help 2>&1 | grep -c keep-section) %if %{with_keep_section} -%global _find_debuginfo_opts -r --keep-section .BTF --keep-section .BTF.base +%global _find_debuginfo_opts -r --keep-section .BTF --keep-section .BTF.base --keep-section .BTF.inline %else %global _find_debuginfo_opts -r %endif -- cgit v1.2.3 From 42d7153fcb444b7c295560a8754a0cffafbd1c1e Mon Sep 17 00:00:00 2001 From: Alan Maguire Date: Fri, 9 Oct 2026 12:23:22 +0100 Subject: btf: Relocate and expose module inline BTF Module .BTF.inline is split relative to its module BTF. For external modules, module BTF can instead be split relative to a distilled .BTF.base and is relocated against vmlinux when the module loads. Parse ordinary module inline BTF relative to the pre-relocation module BTF. Retain the module relocation ID and string maps, then rebase inline type IDs and string offsets onto the final vmlinux/module BTF space before exposing the result through sysfs. Malformed or unrelocatable optional inline BTF is warned about and omitted without preventing normal module BTF registration. The btf_vmlinux_inline carrier remains on its existing hash-checked, vmalloc-backed publishing path, preserving mmap support for vmlinux.inline when delivered by a module. Signed-off-by: Alan Maguire Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261009112324.1442319-6-alan.maguire@oracle.com --- scripts/gen-btf.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/gen-btf.sh b/scripts/gen-btf.sh index e638291753d0..b17f1189298a 100755 --- a/scripts/gen-btf.sh +++ b/scripts/gen-btf.sh @@ -68,10 +68,7 @@ esac gen_btf_data() { - inline="" - if [ -n "${BTF_INLINE}" ] && [ -z "${BTF_BASE}" ]; then - inline="--inline" - fi + inline=${BTF_INLINE:+--inline} btf1="${ELF_FILE}.BTF.1" ${PAHOLE} -J ${PAHOLE_FLAGS} \ ${BTF_BASE:+--btf_base ${BTF_BASE}} \ @@ -130,7 +127,7 @@ embed_btf_data() if [ -f "${btf_base}" ]; then ${OBJCOPY} --add-section .BTF.base=${btf_base} ${ELF_FILE} fi - btf_inline="" + btf_inline=${ELF_FILE}.BTF.inline case "${ELF_FILE}" in */btf_vmlinux_inline.ko) btf_inline=${BTF_BASE}.BTF.inline -- cgit v1.2.3