diff options
27 files changed, 2313 insertions, 2 deletions
@@ -29,9 +29,33 @@ pkgbase = linux-llvm source = 0005-x86-bump-ZO_z_extra_bytes-margin-for-zstd.patch source = 0006-x86-Add-support-for-ZSTD-compressed-kernel.patch source = 0007-.gitignore-add-ZSTD-compressed-files.patch + source = 0001-bitfield.h-don-t-compile-time-validate-_val-in-FIELD.patch + source = 0002-objtool-use-sh_info-to-find-the-base-for-.rela-secti.patch + source = 0003-objtool-don-t-autodetect-vmlinux.o.patch + source = 0004-kbuild-add-support-for-Clang-LTO.patch + source = 0005-kbuild-lto-fix-module-versioning.patch + source = 0006-kbuild-lto-fix-recordmcount.patch + source = 0007-kbuild-lto-postpone-objtool.patch + source = 0008-kbuild-lto-limit-inlining.patch + source = 0009-kbuild-lto-merge-module-sections.patch + source = 0010-kbuild-lto-remove-duplicate-dependencies-from-.mod-f.patch + source = 0011-init-lto-ensure-initcall-ordering.patch + source = 0012-init-lto-fix-PREL32-relocations.patch + source = 0013-PCI-Fix-PREL32-relocations-for-LTO.patch + source = 0014-modpost-lto-strip-.lto-from-module-names.patch + source = 0015-scripts-mod-disable-LTO-for-empty.c.patch + source = 0016-efi-libstub-disable-LTO.patch + source = 0017-drivers-misc-lkdtm-disable-LTO-for-rodata.o.patch + source = 0018-arm64-export-CC_USING_PATCHABLE_FUNCTION_ENTRY.patch + source = 0019-arm64-vdso-disable-LTO.patch + source = 0020-arm64-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch + source = 0021-g86-vdso-disable-LTO-only-for-vDSO.patch + source = 0022-x86-ftrace-disable-recordmcount-for-ftrace_make_nop.patch + source = 0023-x86-relocs-Ignore-L4_PAGE_OFFSET-relocations.patch + source = 0024-x86-build-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch source = enable_additional_cpu_optimizations_for_gcc_v10.1+_kernel_v5.8+.patch sha256sums = SKIP - sha256sums = 7748dbdc1d0ff9efa8358268e82b21b338acfb7ebbd2876753bf23c4e71da44c + sha256sums = 639e5ac559832b05d1b3be611faedab33aa65059eb8cd76879d2b92ecd17d7fa sha256sums = 8cb21e0b3411327b627a9dd15b8eb773295a0d2782b1a41b2a8839d1b2f5778c sha256sums = 2f0090ec0c9a72e6241bbea05faaef979405119ce8ef669d84dead36c8e2246e sha256sums = 5f21c12f002e71ec5b5db96832b415ce291a7e230fa07b328c21760274e72e9d @@ -40,6 +64,30 @@ pkgbase = linux-llvm sha256sums = 2b558cc58e95343bb2e3cfd96c668b671251c543124176b8687baf12cdf999d5 sha256sums = 84c275eb98fb908b742ffe51faa7feb0312550712b0cd729bf72941a2f633a65 sha256sums = f88df9ee297e229792e516ac9fb6f35ddc1aa13c3fdeb9ba15fb4de8b1dcd7c7 + sha256sums = 524b329a965f1b983fd4b78e1827854727d4ebb9c21cc9f245bf2ce91c2bed1d + sha256sums = 053582c4fa855a9219f45f864d7a03b3a28cfd04ec798b0cc47080c836669184 + sha256sums = 7e155527495f8a009efc6edc43d44c1775de64c750c9c112f6964d599eada3ef + sha256sums = 2ef22d6b576ebf452238ae48658515d5d484b3ab7448b9d62fc1295570bb8f14 + sha256sums = 9bbda700ef98d75ce24c43f5bf191f77f51d5587ea06ad5c763d9ac10d39c96e + sha256sums = 5684845b4c0a516fc907a1f24d420760f2cd2a53ab977fb409a6378f9b1f473e + sha256sums = 438c34b332cb3d67e31856f11ed71052974a869f8fd71da637343da7de0c1bf2 + sha256sums = efaa62f8d18463141958fdeb495b58c03e49f62ef7bca30e5cd261821bff4ca6 + sha256sums = c44e6e4de658ba682cba3b24f766af5bb70572869c8419c0091767726439bfa1 + sha256sums = 75939f2da39a5644e407aaee060ea00fa6b8e06bf5cc361af793affe5a660243 + sha256sums = 407e9262ed5cf234172f3048ae79513030589022acba42039ad709f490c6d139 + sha256sums = e89ceb6f4cda3fa9ae59c3482b27118df18c98d0a74665d0fe07f05017c1144e + sha256sums = eacb3b5cd7380a48ae50f38c57153a3f90a6dd890b573bf172c0d0585e4f1ab9 + sha256sums = 7854b55ff44f5ec0a94d295075679aaaf1ff3baf9039bd8a7ea73e4e9ae4f8dd + sha256sums = 4668748669f31e3535e02c11f2f4554412d5bd29279ebdbe241f515d7f34aafc + sha256sums = 729f41453d3607c6c055ae1f52e476d09a4b49169897fe136ad37a451c7872bb + sha256sums = e3d865689bc4c3ab52b9d0a897278bde415a7cd4892c0e7006ce7998c6e97fe7 + sha256sums = 4c2bc4f796ef21d1f5cbc7e4a7600a250c66de329819795f77cad3e52106b2fe + sha256sums = 85bf687909b628e36ea8a2c973cdd3ef2819f57422d5405cf338abce9037ef9a + sha256sums = 0c269cb936eec02fc767f1d4f2ca4436582f5c4f046a3b4c53608d4232a09809 + sha256sums = 0feb6c229e75c5a4ed532840bbe3ab1426ae255c0897f7852a93537e7661b461 + sha256sums = bd3f17cbb1da5293bb54a5bdeaa613098d41fe676ee327ba35867c18732ee80c + sha256sums = 539794c1dc9b8e35a73e2e165040f363d0c7f32bc5da415ae6b27a9ffe57dde2 + sha256sums = 3b956c3768e59f2d5fb0546a855138319eff60e077822667befed734c7ac84af sha256sums = 5ab29eb64e57df83b395a29a6a4f89030d142feffbfbf73b3afc6d97a2a7fd12 pkgname = linux-llvm diff --git a/0001-bitfield.h-don-t-compile-time-validate-_val-in-FIELD.patch b/0001-bitfield.h-don-t-compile-time-validate-_val-in-FIELD.patch new file mode 100644 index 000000000000..2c24d961384b --- /dev/null +++ b/0001-bitfield.h-don-t-compile-time-validate-_val-in-FIELD.patch @@ -0,0 +1,53 @@ +From 28fca8bb1d95ebb3c3a7367ee60b0f1ef6d83475 Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski <kuba@kernel.org> +Date: Tue, 7 Jul 2020 14:16:41 -0700 +Subject: [PATCH 01/24] bitfield.h: don't compile-time validate _val in + FIELD_FIT + +When ur_load_imm_any() is inlined into jeq_imm(), it's possible for the +compiler to deduce a case where _val can only have the value of -1 at +compile time. Specifically, + +/* struct bpf_insn: _s32 imm */ +u64 imm = insn->imm; /* sign extend */ +if (imm >> 32) { /* non-zero only if insn->imm is negative */ + /* inlined from ur_load_imm_any */ + u32 __imm = imm >> 32; /* therefore, always 0xffffffff */ + if (__builtin_constant_p(__imm) && __imm > 255) + compiletime_assert_XXX() + +This can result in tripping a BUILD_BUG_ON() in __BF_FIELD_CHECK() that +checks that a given value is representable in one byte (interpreted as +unsigned). + +FIELD_FIT() should return true or false at runtime for whether a value +can fit for not. Don't break the build over a value that's too large for +the mask. We'd prefer to keep the inlining and compiler optimizations +though we know this case will always return false. + +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/kernel-hardening/CAK7LNASvb0UDJ0U5wkYYRzTAdnEs64HjXpEUL7d=V0CXiAXcNw@mail.gmail.com/ +Reported-by: Masahiro Yamada <masahiroy@kernel.org> +Debugged-by: Sami Tolvanen <samitolvanen@google.com> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> +--- + include/linux/bitfield.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h +index 48ea093ff04c..4e035aca6f7e 100644 +--- a/include/linux/bitfield.h ++++ b/include/linux/bitfield.h +@@ -77,7 +77,7 @@ + */ + #define FIELD_FIT(_mask, _val) \ + ({ \ +- __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \ ++ __BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_FIT: "); \ + !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ + }) + +-- +2.28.0 + diff --git a/0002-objtool-use-sh_info-to-find-the-base-for-.rela-secti.patch b/0002-objtool-use-sh_info-to-find-the-base-for-.rela-secti.patch new file mode 100644 index 000000000000..0d42e403b30b --- /dev/null +++ b/0002-objtool-use-sh_info-to-find-the-base-for-.rela-secti.patch @@ -0,0 +1,37 @@ +From 32e8f91f5bb6bc82e198233a85ef7c2ae68742c9 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Mon, 13 Apr 2020 13:40:11 -0700 +Subject: [PATCH 02/24] objtool: use sh_info to find the base for .rela + sections + +ELF doesn't require .rela section names to match the base section. Use +the section index in sh_info to find the section instead of looking it +up by name. + +LLD, for example, generates a .rela section that doesn't match the base +section name when we merge sections in a linker script for a binary +compiled with -ffunction-sections. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> +Reviewed-by: Kees Cook <keescook@chromium.org> +--- + tools/objtool/elf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index 26d11d821941..72bfde4bc5de 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -502,7 +502,7 @@ static int read_relas(struct elf *elf) + if (sec->sh.sh_type != SHT_RELA) + continue; + +- sec->base = find_section_by_name(elf, sec->name + 5); ++ sec->base = find_section_by_index(elf, sec->sh.sh_info); + if (!sec->base) { + WARN("can't find base section for rela section %s", + sec->name); +-- +2.28.0 + diff --git a/0003-objtool-don-t-autodetect-vmlinux.o.patch b/0003-objtool-don-t-autodetect-vmlinux.o.patch new file mode 100644 index 000000000000..8841edc6aec3 --- /dev/null +++ b/0003-objtool-don-t-autodetect-vmlinux.o.patch @@ -0,0 +1,56 @@ +From 8f1687630f5771b2257fa5ca0a233634065703f0 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 17 Jul 2020 12:04:27 -0700 +Subject: [PATCH 03/24] objtool: don't autodetect vmlinux.o + +With LTO, we run objtool on vmlinux.o, but don't want noinstr +validation. This change requires --vmlinux to be passed to objtool +explicitly. + +Suggested-by: Peter Zijlstra <peterz@infradead.org> +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + scripts/link-vmlinux.sh | 2 +- + tools/objtool/builtin-check.c | 10 +--------- + 2 files changed, 2 insertions(+), 10 deletions(-) + +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index 92dd745906f4..00c6e4f28a1a 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -60,7 +60,7 @@ objtool_link() + local objtoolopt; + + if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then +- objtoolopt="check" ++ objtoolopt="check --vmlinux" + if [ -z "${CONFIG_FRAME_POINTER}" ]; then + objtoolopt="${objtoolopt} --no-fp" + fi +diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c +index 7a44174967b5..1109dd69f953 100644 +--- a/tools/objtool/builtin-check.c ++++ b/tools/objtool/builtin-check.c +@@ -40,18 +40,10 @@ const struct option check_options[] = { + + int cmd_check(int argc, const char **argv) + { +- const char *objname, *s; +- + argc = parse_options(argc, argv, check_options, check_usage, 0); + + if (argc != 1) + usage_with_options(check_usage, check_options); + +- objname = argv[0]; +- +- s = strstr(objname, "vmlinux.o"); +- if (s && !s[9]) +- vmlinux = true; +- +- return check(objname, false); ++ return check(argv[0], false); + } +-- +2.28.0 + diff --git a/0004-kbuild-add-support-for-Clang-LTO.patch b/0004-kbuild-add-support-for-Clang-LTO.patch new file mode 100644 index 000000000000..789b6e88a689 --- /dev/null +++ b/0004-kbuild-add-support-for-Clang-LTO.patch @@ -0,0 +1,361 @@ +From e8a6f455578b17e04ad08f15b76486e06f812400 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 6 Mar 2020 14:14:03 -0800 +Subject: [PATCH 04/24] kbuild: add support for Clang LTO + +This change adds build system support for Clang's Link Time +Optimization (LTO). With -flto, instead of ELF object files, Clang +produces LLVM bitcode, which is compiled into native code at link +time, allowing the final binary to be optimized globally. For more +details, see: + + https://llvm.org/docs/LinkTimeOptimization.html + +The Kconfig option CONFIG_LTO_CLANG is implemented as a choice, +which defaults to LTO being disabled. To use LTO, the architecture +must select ARCH_SUPPORTS_LTO_CLANG and support: + + - compiling with Clang, + - compiling inline assembly with Clang's integrated assembler, + - and linking with LLD. + +While using full LTO results in the best runtime performance, the +compilation is not scalable in time or memory. CONFIG_THINLTO +enables ThinLTO, which allows parallel optimization and faster +incremental builds. ThinLTO is used by default if the architecture +also selects ARCH_SUPPORTS_THINLTO: + + https://clang.llvm.org/docs/ThinLTO.html + +To enable LTO, LLVM tools must be used to handle bitcode files. The +easiest way is to pass the LLVM=1 option to make: + + $ make LLVM=1 defconfig + $ scripts/config -e LTO_CLANG + $ make LLVM=1 + +Alternatively, at least the following LLVM tools must be used: + + CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm + +To prepare for LTO support with other compilers, common parts are +gated behind the CONFIG_LTO option, and LTO can be disabled for +specific files by filtering out CC_FLAGS_LTO. + +Note that support for DYNAMIC_FTRACE and MODVERSIONS are added in +follow-up patches. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + Makefile | 18 ++++++++- + arch/Kconfig | 67 +++++++++++++++++++++++++++++++ + include/asm-generic/vmlinux.lds.h | 11 +++-- + scripts/Makefile.build | 9 ++++- + scripts/Makefile.modfinal | 9 ++++- + scripts/Makefile.modpost | 24 ++++++++++- + scripts/link-vmlinux.sh | 32 +++++++++++---- + 7 files changed, 153 insertions(+), 17 deletions(-) + +diff --git a/Makefile b/Makefile +index 38acd65aa651..44615ea079e5 100644 +--- a/Makefile ++++ b/Makefile +@@ -887,6 +887,22 @@ KBUILD_CFLAGS += $(CC_FLAGS_SCS) + export CC_FLAGS_SCS + endif + ++ifdef CONFIG_LTO_CLANG ++ifdef CONFIG_THINLTO ++CC_FLAGS_LTO_CLANG := -flto=thin -fsplit-lto-unit ++KBUILD_LDFLAGS += --thinlto-cache-dir=.thinlto-cache ++else ++CC_FLAGS_LTO_CLANG := -flto ++endif ++CC_FLAGS_LTO_CLANG += -fvisibility=default ++endif ++ ++ifdef CONFIG_LTO ++CC_FLAGS_LTO := $(CC_FLAGS_LTO_CLANG) ++KBUILD_CFLAGS += $(CC_FLAGS_LTO) ++export CC_FLAGS_LTO ++endif ++ + # arch Makefile may override CC so keep this after arch Makefile is included + NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) + +@@ -1446,7 +1462,7 @@ MRPROPER_FILES += include/config include/generated \ + *.spec + + # Directories & files removed with 'make distclean' +-DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS ++DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS .thinlto-cache + + # clean - Delete most, but leave enough to build external modules + # +diff --git a/arch/Kconfig b/arch/Kconfig +index 8cc35dc556c7..df5a42854a51 100644 +--- a/arch/Kconfig ++++ b/arch/Kconfig +@@ -552,6 +552,73 @@ config SHADOW_CALL_STACK + reading and writing arbitrary memory may be able to locate them + and hijack control flow by modifying the stacks. + ++config LTO ++ bool ++ ++config ARCH_SUPPORTS_LTO_CLANG ++ bool ++ help ++ An architecture should select this option if it supports: ++ - compiling with Clang, ++ - compiling inline assembly with Clang's integrated assembler, ++ - and linking with LLD. ++ ++config ARCH_SUPPORTS_THINLTO ++ bool ++ help ++ An architecture should select this option if it supports Clang's ++ ThinLTO. ++ ++config THINLTO ++ bool "Clang ThinLTO" ++ depends on LTO_CLANG && ARCH_SUPPORTS_THINLTO ++ default y ++ help ++ This option enables Clang's ThinLTO, which allows for parallel ++ optimization and faster incremental compiles. More information ++ can be found from Clang's documentation: ++ ++ https://clang.llvm.org/docs/ThinLTO.html ++ ++choice ++ prompt "Link Time Optimization (LTO)" ++ default LTO_NONE ++ help ++ This option enables Link Time Optimization (LTO), which allows the ++ compiler to optimize binaries globally. ++ ++ If unsure, select LTO_NONE. ++ ++config LTO_NONE ++ bool "None" ++ ++config LTO_CLANG ++ bool "Clang's Link Time Optimization (EXPERIMENTAL)" ++ # https://github.com/ClangBuiltLinux/linux/issues/510 ++ depends on CC_IS_CLANG && CLANG_VERSION >= 110000 && LD_IS_LLD ++ depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm) ++ depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm) ++ depends on ARCH_SUPPORTS_LTO_CLANG ++ depends on !FTRACE_MCOUNT_RECORD ++ depends on !KASAN ++ depends on !MODVERSIONS ++ select LTO ++ help ++ This option enables Clang's Link Time Optimization (LTO), which ++ allows the compiler to optimize the kernel globally. If you enable ++ this option, the compiler generates LLVM bitcode instead of ELF ++ object files, and the actual compilation from bitcode happens at ++ the LTO link step, which may take several minutes depending on the ++ kernel configuration. More information can be found from LLVM's ++ documentation: ++ ++ https://llvm.org/docs/LinkTimeOptimization.html ++ ++ To select this option, you also need to use LLVM tools to handle ++ the bitcode by passing LLVM=1 to make. ++ ++endchoice ++ + config HAVE_ARCH_WITHIN_STACK_FRAMES + bool + help +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 052e0f05a984..7f62f7eef94c 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -89,15 +89,18 @@ + * .data. We don't want to pull in .data..other sections, which Linux + * has defined. Same for text and bss. + * ++ * With LTO_CLANG, the linker also splits sections by default, so we need ++ * these macros to combine the sections during the final link. ++ * + * RODATA_MAIN is not used because existing code already defines .rodata.x + * sections to be brought in with rodata. + */ +-#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION ++#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) + #define TEXT_MAIN .text .text.[0-9a-zA-Z_]* +-#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..LPBX* ++#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* + #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* +-#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* +-#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* ++#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L* ++#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..compoundliteral* + #define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]* + #else + #define TEXT_MAIN .text +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index 2e8810b7e5ed..f307e708a1b7 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -108,7 +108,7 @@ endif + # --------------------------------------------------------------------------- + + quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ +- cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< ++ cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $< + + $(obj)/%.s: $(src)/%.c FORCE + $(call if_changed_dep,cc_s_c) +@@ -424,8 +424,15 @@ $(obj)/lib.a: $(lib-y) FORCE + # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object + # module is turned into a multi object module, $^ will contain header file + # dependencies recorded in the .*.cmd file. ++ifdef CONFIG_LTO_CLANG ++quiet_cmd_link_multi-m = AR [M] $@ ++cmd_link_multi-m = \ ++ rm -f $@; \ ++ $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(filter %.o,$^) ++else + quiet_cmd_link_multi-m = LD [M] $@ + cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) ++endif + + $(multi-used-m): FORCE + $(call if_changed,link_multi-m) +diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal +index 411c1e600e7d..1005b147abd0 100644 +--- a/scripts/Makefile.modfinal ++++ b/scripts/Makefile.modfinal +@@ -6,6 +6,7 @@ + PHONY := __modfinal + __modfinal: + ++include $(objtree)/include/config/auto.conf + include $(srctree)/scripts/Kbuild.include + + # for c_flags +@@ -29,6 +30,12 @@ quiet_cmd_cc_o_c = CC [M] $@ + + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) + ++ifdef CONFIG_LTO_CLANG ++# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to ++# avoid a second slow LTO link ++prelink-ext := .lto ++endif ++ + quiet_cmd_ld_ko_o = LD [M] $@ + cmd_ld_ko_o = \ + $(LD) -r $(KBUILD_LDFLAGS) \ +@@ -37,7 +44,7 @@ quiet_cmd_ld_ko_o = LD [M] $@ + -o $@ $(filter %.o, $^); \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) + +-$(modules): %.ko: %.o %.mod.o $(KBUILD_LDS_MODULE) FORCE ++$(modules): %.ko: %$(prelink-ext).o %.mod.o $(KBUILD_LDS_MODULE) FORCE + +$(call if_changed,ld_ko_o) + + targets += $(modules) $(modules:.ko=.mod.o) +diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost +index f54b6ac37ac2..a70f1f7da6aa 100644 +--- a/scripts/Makefile.modpost ++++ b/scripts/Makefile.modpost +@@ -102,12 +102,32 @@ $(input-symdump): + @echo >&2 'WARNING: Symbol version dump "$@" is missing.' + @echo >&2 ' Modules may not have dependencies or modversions.' + ++ifdef CONFIG_LTO_CLANG ++# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run ++# LTO to compile them into native code before running modpost ++prelink-ext = .lto ++ ++quiet_cmd_cc_lto_link_modules = LTO [M] $@ ++cmd_cc_lto_link_modules = \ ++ $(LD) $(ld_flags) -r -o $@ \ ++ --whole-archive $(filter-out FORCE,$^) ++ ++%.lto.o: %.o FORCE ++ $(call if_changed,cc_lto_link_modules) ++ ++PHONY += FORCE ++FORCE: ++ ++endif ++ ++modules := $(sort $(shell cat $(MODORDER))) ++ + # Read out modules.order to pass in modpost. + # Otherwise, allmodconfig would fail with "Argument list too long". + quiet_cmd_modpost = MODPOST $@ +- cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T - ++ cmd_modpost = sed 's/\.ko$$/$(prelink-ext)\.o/' $< | $(MODPOST) -T - + +-$(output-symdump): $(MODORDER) $(input-symdump) FORCE ++$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(prelink-ext).o) FORCE + $(call if_changed,modpost) + + targets += $(output-symdump) +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index 00c6e4f28a1a..4b9ae7751b63 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -52,6 +52,14 @@ modpost_link() + ${KBUILD_VMLINUX_LIBS} \ + --end-group" + ++ if [ -n "${CONFIG_LTO_CLANG}" ]; then ++ # This might take a while, so indicate that we're doing ++ # an LTO link ++ info LTO ${1} ++ else ++ info LD ${1} ++ fi ++ + ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects} + } + +@@ -99,13 +107,22 @@ vmlinux_link() + fi + + if [ "${SRCARCH}" != "um" ]; then +- objects="--whole-archive \ +- ${KBUILD_VMLINUX_OBJS} \ +- --no-whole-archive \ +- --start-group \ +- ${KBUILD_VMLINUX_LIBS} \ +- --end-group \ +- ${@}" ++ if [ -n "${CONFIG_LTO_CLANG}" ]; then ++ # Use vmlinux.o instead of performing the slow LTO ++ # link again. ++ objects="--whole-archive \ ++ vmlinux.o \ ++ --no-whole-archive \ ++ ${@}" ++ else ++ objects="--whole-archive \ ++ ${KBUILD_VMLINUX_OBJS} \ ++ --no-whole-archive \ ++ --start-group \ ++ ${KBUILD_VMLINUX_LIBS} \ ++ --end-group \ ++ ${@}" ++ fi + + ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \ + ${strip_debug#-Wl,} \ +@@ -270,7 +287,6 @@ fi; + ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 + + #link vmlinux.o +-info LD vmlinux.o + modpost_link vmlinux.o + objtool_link vmlinux.o + +-- +2.28.0 + diff --git a/0005-kbuild-lto-fix-module-versioning.patch b/0005-kbuild-lto-fix-module-versioning.patch new file mode 100644 index 000000000000..1a20ec858c1f --- /dev/null +++ b/0005-kbuild-lto-fix-module-versioning.patch @@ -0,0 +1,219 @@ +From 50f22050930b49f29dfcc607766632c7d8096402 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 6 Mar 2020 14:19:09 -0800 +Subject: [PATCH 05/24] kbuild: lto: fix module versioning + +With CONFIG_MODVERSIONS, version information is linked into each +compilation unit that exports symbols. With LTO, we cannot use this +method as all C code is compiled into LLVM bitcode instead. This +change collects symbol versions into .symversions files and merges +them in link-vmlinux.sh where they are all linked into vmlinux.o at +the same time. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + .gitignore | 1 + + Makefile | 3 ++- + arch/Kconfig | 1 - + scripts/Makefile.build | 33 +++++++++++++++++++++++++++++++-- + scripts/Makefile.modpost | 2 ++ + scripts/link-vmlinux.sh | 25 ++++++++++++++++++++++++- + 6 files changed, 60 insertions(+), 5 deletions(-) + +diff --git a/.gitignore b/.gitignore +index 162bd2b67bdf..06e76dc39ffe 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -41,6 +41,7 @@ + *.so.dbg + *.su + *.symtypes ++*.symversions + *.tab.[ch] + *.tar + *.xz +diff --git a/Makefile b/Makefile +index 44615ea079e5..b59ce19ef248 100644 +--- a/Makefile ++++ b/Makefile +@@ -1794,7 +1794,8 @@ clean: $(clean-dirs) + -o -name '.tmp_*.o.*' \ + -o -name '*.c.[012]*.*' \ + -o -name '*.ll' \ +- -o -name '*.gcno' \) -type f -print | xargs rm -f ++ -o -name '*.gcno' \ ++ -o -name '*.*.symversions' \) -type f -print | xargs rm -f + + # Generate tags for editors + # --------------------------------------------------------------------------- +diff --git a/arch/Kconfig b/arch/Kconfig +index df5a42854a51..d9c74e3b4cf8 100644 +--- a/arch/Kconfig ++++ b/arch/Kconfig +@@ -601,7 +601,6 @@ config LTO_CLANG + depends on ARCH_SUPPORTS_LTO_CLANG + depends on !FTRACE_MCOUNT_RECORD + depends on !KASAN +- depends on !MODVERSIONS + select LTO + help + This option enables Clang's Link Time Optimization (LTO), which +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index f307e708a1b7..5c0bbb6ddfcf 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -163,6 +163,15 @@ ifdef CONFIG_MODVERSIONS + # the actual value of the checksum generated by genksyms + # o remove .tmp_<file>.o to <file>.o + ++ifdef CONFIG_LTO_CLANG ++# Generate .o.symversions files for each .o with exported symbols, and link these ++# to the kernel and/or modules at the end. ++cmd_modversions_c = \ ++ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ ++ $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ ++ > $@.symversions; \ ++ fi; ++else + cmd_modversions_c = \ + if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ + $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ +@@ -174,6 +183,7 @@ cmd_modversions_c = \ + rm -f $(@D)/.tmp_$(@F:.o=.ver); \ + fi + endif ++endif + + ifdef CONFIG_FTRACE_MCOUNT_RECORD + ifndef CC_USING_RECORD_MCOUNT +@@ -389,6 +399,18 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler + $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; + $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; + ++# combine symversions for later processing ++quiet_cmd_update_lto_symversions = SYMVER $@ ++ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y) ++ cmd_update_lto_symversions = \ ++ rm -f $@.symversions \ ++ $(foreach n, $(filter-out FORCE,$^), \ ++ $(if $(wildcard $(n).symversions), \ ++ ; cat $(n).symversions >> $@.symversions)) ++else ++ cmd_update_lto_symversions = echo >/dev/null ++endif ++ + # + # Rule to compile a set of .o files into one .a file (without symbol table) + # +@@ -396,8 +418,11 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; + quiet_cmd_ar_builtin = AR $@ + cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) + ++quiet_cmd_ar_and_symver = AR $@ ++ cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin) ++ + $(obj)/built-in.a: $(real-obj-y) FORCE +- $(call if_changed,ar_builtin) ++ $(call if_changed,ar_and_symver) + + # + # Rule to create modules.order file +@@ -417,8 +442,11 @@ $(obj)/modules.order: $(obj-m) FORCE + # + # Rule to compile a set of .o files into one .a file (with symbol table) + # ++quiet_cmd_ar_lib = AR $@ ++ cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar) ++ + $(obj)/lib.a: $(lib-y) FORCE +- $(call if_changed,ar) ++ $(call if_changed,ar_lib) + + # NOTE: + # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object +@@ -427,6 +455,7 @@ $(obj)/lib.a: $(lib-y) FORCE + ifdef CONFIG_LTO_CLANG + quiet_cmd_link_multi-m = AR [M] $@ + cmd_link_multi-m = \ ++ $(cmd_update_lto_symversions); \ + rm -f $@; \ + $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(filter %.o,$^) + else +diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost +index a70f1f7da6aa..f9718bf4172d 100644 +--- a/scripts/Makefile.modpost ++++ b/scripts/Makefile.modpost +@@ -110,6 +110,8 @@ prelink-ext = .lto + quiet_cmd_cc_lto_link_modules = LTO [M] $@ + cmd_cc_lto_link_modules = \ + $(LD) $(ld_flags) -r -o $@ \ ++ $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ ++ echo -T $(@:.lto.o=.o.symversions)) \ + --whole-archive $(filter-out FORCE,$^) + + %.lto.o: %.o FORCE +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index 4b9ae7751b63..712769355a5b 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -39,11 +39,28 @@ info() + fi + } + ++# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into ++# .tmp_symversions.lds ++gen_symversions() ++{ ++ info GEN .tmp_symversions.lds ++ rm -f .tmp_symversions.lds ++ ++ for a in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do ++ for o in $(${AR} t $a 2>/dev/null); do ++ if [ -f ${o}.symversions ]; then ++ cat ${o}.symversions >> .tmp_symversions.lds ++ fi ++ done ++ done ++} ++ + # Link of vmlinux.o used for section mismatch analysis + # ${1} output file + modpost_link() + { + local objects ++ local lds="" + + objects="--whole-archive \ + ${KBUILD_VMLINUX_OBJS} \ +@@ -53,6 +70,11 @@ modpost_link() + --end-group" + + if [ -n "${CONFIG_LTO_CLANG}" ]; then ++ if [ -n "${CONFIG_MODVERSIONS}" ]; then ++ gen_symversions ++ lds="${lds} -T .tmp_symversions.lds" ++ fi ++ + # This might take a while, so indicate that we're doing + # an LTO link + info LTO ${1} +@@ -60,7 +82,7 @@ modpost_link() + info LD ${1} + fi + +- ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects} ++ ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects} + } + + objtool_link() +@@ -238,6 +260,7 @@ cleanup() + { + rm -f .btf.* + rm -f .tmp_System.map ++ rm -f .tmp_symversions.lds + rm -f .tmp_vmlinux* + rm -f System.map + rm -f vmlinux +-- +2.28.0 + diff --git a/0006-kbuild-lto-fix-recordmcount.patch b/0006-kbuild-lto-fix-recordmcount.patch new file mode 100644 index 000000000000..1156acd9ad4f --- /dev/null +++ b/0006-kbuild-lto-fix-recordmcount.patch @@ -0,0 +1,238 @@ +From 1bbbfffdb5d0f291c8fc1787a8c9857ecb4b2f93 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Thu, 2 Apr 2020 17:22:36 -0700 +Subject: [PATCH 06/24] kbuild: lto: fix recordmcount + +With LTO, LLVM bitcode won't be compiled into native code until +modpost_link. This change postpones calls to recordmcount until after +this step. + +In order to exclude specific functions from inspection, we add a new +code section .text..nomcount, which we tell recordmcount to ignore, and +a __nomcount attribute for moving functions to this section. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + Makefile | 2 +- + arch/Kconfig | 2 +- + include/asm-generic/vmlinux.lds.h | 1 + + include/linux/compiler-clang.h | 4 ++++ + include/linux/compiler_types.h | 4 ++++ + kernel/trace/ftrace.c | 1 + + scripts/Makefile.build | 9 +++++++++ + scripts/Makefile.modfinal | 18 ++++++++++++++++-- + scripts/link-vmlinux.sh | 29 +++++++++++++++++++++++++++++ + scripts/recordmcount.c | 3 ++- + 10 files changed, 68 insertions(+), 5 deletions(-) + +diff --git a/Makefile b/Makefile +index b59ce19ef248..19e2bf26c52c 100644 +--- a/Makefile ++++ b/Makefile +@@ -862,7 +862,7 @@ KBUILD_AFLAGS += $(CC_FLAGS_USING) + ifdef CONFIG_DYNAMIC_FTRACE + ifdef CONFIG_HAVE_C_RECORDMCOUNT + BUILD_C_RECORDMCOUNT := y +- export BUILD_C_RECORDMCOUNT ++ export BUILD_C_RECORDMCOUNT RECORDMCOUNT_WARN + endif + endif + endif +diff --git a/arch/Kconfig b/arch/Kconfig +index d9c74e3b4cf8..694bfdc2073f 100644 +--- a/arch/Kconfig ++++ b/arch/Kconfig +@@ -599,7 +599,7 @@ config LTO_CLANG + depends on $(success,$(NM) --help | head -n 1 | grep -qi llvm) + depends on $(success,$(AR) --help | head -n 1 | grep -qi llvm) + depends on ARCH_SUPPORTS_LTO_CLANG +- depends on !FTRACE_MCOUNT_RECORD ++ depends on !FTRACE_MCOUNT_RECORD || HAVE_C_RECORDMCOUNT + depends on !KASAN + select LTO + help +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 7f62f7eef94c..7c9a686cf633 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -566,6 +566,7 @@ + *(.text.hot TEXT_MAIN .text.fixup .text.unlikely) \ + NOINSTR_TEXT \ + *(.text..refcount) \ ++ *(.text..nomcount) \ + *(.ref.text) \ + MEM_KEEP(init.text*) \ + MEM_KEEP(exit.text*) \ +diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h +index 5e55302e3bf6..21423d6f6dc4 100644 +--- a/include/linux/compiler-clang.h ++++ b/include/linux/compiler-clang.h +@@ -63,3 +63,7 @@ + #if __has_feature(shadow_call_stack) + # define __noscs __attribute__((__no_sanitize__("shadow-call-stack"))) + #endif ++ ++#if defined(CONFIG_LTO_CLANG) && defined(CONFIG_FTRACE_MCOUNT_RECORD) ++#define __nomcount __attribute__((__section__(".text..nomcount"))) ++#endif +diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h +index 01dd58c74d80..23c7cf44aa92 100644 +--- a/include/linux/compiler_types.h ++++ b/include/linux/compiler_types.h +@@ -231,6 +231,10 @@ struct ftrace_likely_data { + # define __noscs + #endif + ++#ifndef __nomcount ++# define __nomcount ++#endif ++ + #ifndef asm_volatile_goto + #define asm_volatile_goto(x...) asm goto(x) + #endif +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 1903b80db6eb..8e3ddb8123d9 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -6062,6 +6062,7 @@ static int ftrace_cmp_ips(const void *a, const void *b) + return 0; + } + ++__nomcount + static int ftrace_process_locs(struct module *mod, + unsigned long *start, + unsigned long *end) +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index 5c0bbb6ddfcf..64e99f4baa5b 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -187,6 +187,9 @@ endif + + ifdef CONFIG_FTRACE_MCOUNT_RECORD + ifndef CC_USING_RECORD_MCOUNT ++ifndef CC_USING_PATCHABLE_FUNCTION_ENTRY ++# With LTO, we postpone recordmcount until we compile a native binary ++ifndef CONFIG_LTO_CLANG + # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl + ifdef BUILD_C_RECORDMCOUNT + ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") +@@ -200,6 +203,8 @@ sub_cmd_record_mcount = \ + if [ $(@) != "scripts/mod/empty.o" ]; then \ + $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ + fi; ++endif # CONFIG_LTO_CLANG ++ + recordmcount_source := $(srctree)/scripts/recordmcount.c \ + $(srctree)/scripts/recordmcount.h + else +@@ -209,11 +214,15 @@ sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ + "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \ + "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \ + "$(if $(part-of-module),1,0)" "$(@)"; ++ + recordmcount_source := $(srctree)/scripts/recordmcount.pl + endif # BUILD_C_RECORDMCOUNT ++ifndef CONFIG_LTO_CLANG + cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \ + $(sub_cmd_record_mcount)) ++endif # CONFIG_LTO_CLANG + endif # CC_USING_RECORD_MCOUNT ++endif # CC_USING_PATCHABLE_FUNCTION_ENTRY + endif # CONFIG_FTRACE_MCOUNT_RECORD + + ifdef CONFIG_STACK_VALIDATION +diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal +index 1005b147abd0..d168f0cfe67c 100644 +--- a/scripts/Makefile.modfinal ++++ b/scripts/Makefile.modfinal +@@ -34,10 +34,24 @@ ifdef CONFIG_LTO_CLANG + # With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to + # avoid a second slow LTO link + prelink-ext := .lto +-endif ++ ++# ELF processing was skipped earlier because we didn't have native code, ++# so let's now process the prelinked binary before we link the module. ++ ++ifdef CONFIG_FTRACE_MCOUNT_RECORD ++ifndef CC_USING_RECORD_MCOUNT ++ifndef CC_USING_PATCHABLE_FUNCTION_ENTRY ++cmd_ld_ko_o += $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) \ ++ $(@:.ko=$(prelink-ext).o); ++ ++endif # CC_USING_PATCHABLE_FUNCTION_ENTRY ++endif # CC_USING_RECORD_MCOUNT ++endif # CONFIG_FTRACE_MCOUNT_RECORD ++ ++endif # CONFIG_LTO_CLANG + + quiet_cmd_ld_ko_o = LD [M] $@ +- cmd_ld_ko_o = \ ++ cmd_ld_ko_o += \ + $(LD) -r $(KBUILD_LDFLAGS) \ + $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ + $(addprefix -T , $(KBUILD_LDS_MODULE)) \ +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index 712769355a5b..c5715608fe63 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -108,6 +108,29 @@ objtool_link() + fi + } + ++# If CONFIG_LTO_CLANG is selected, we postpone running recordmcount until ++# we have compiled LLVM IR to an object file. ++recordmcount() ++{ ++ if [ "${CONFIG_LTO_CLANG} ${CONFIG_FTRACE_MCOUNT_RECORD}" != "y y" ]; then ++ return ++ fi ++ ++ if [ -n "${CC_USING_RECORD_MCOUNT}" ]; then ++ return ++ fi ++ if [ -n "${CC_USING_PATCHABLE_FUNCTION_ENTRY}" ]; then ++ return ++ fi ++ ++ local flags="" ++ ++ [ -n "${RECORDMCOUNT_WARN}" ] && flags="-w" ++ ++ info MCOUNT $* ++ ${objtree}/scripts/recordmcount ${flags} $* ++} ++ + # Link of vmlinux + # ${1} - output file + # ${2}, ${3}, ... - optional extra .o files +@@ -316,6 +339,12 @@ objtool_link vmlinux.o + # modpost vmlinux.o to check for section mismatches + ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 + ++if [ -n "${CONFIG_LTO_CLANG}" ]; then ++ # If we postponed ELF processing steps due to LTO, process ++ # vmlinux.o instead. ++ recordmcount vmlinux.o ++fi ++ + info MODINFO modules.builtin.modinfo + ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo + info GEN modules.builtin +diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c +index 7225107a9aaf..9e9f10b4d649 100644 +--- a/scripts/recordmcount.c ++++ b/scripts/recordmcount.c +@@ -404,7 +404,8 @@ static uint32_t (*w2)(uint16_t); + /* Names of the sections that could contain calls to mcount. */ + static int is_mcounted_section_name(char const *const txtname) + { +- return strncmp(".text", txtname, 5) == 0 || ++ return (strncmp(".text", txtname, 5) == 0 && ++ strcmp(".text..nomcount", txtname) != 0) || + strcmp(".init.text", txtname) == 0 || + strcmp(".ref.text", txtname) == 0 || + strcmp(".sched.text", txtname) == 0 || +-- +2.28.0 + diff --git a/0007-kbuild-lto-postpone-objtool.patch b/0007-kbuild-lto-postpone-objtool.patch new file mode 100644 index 000000000000..2dabca6fbe89 --- /dev/null +++ b/0007-kbuild-lto-postpone-objtool.patch @@ -0,0 +1,87 @@ +From 3cce747e84f3e12dc20368a85be694828e8e6eb7 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Mon, 13 Apr 2020 16:10:13 -0700 +Subject: [PATCH 07/24] kbuild: lto: postpone objtool + +With LTO, LLVM bitcode won't be compiled into native code until +modpost_link, or modfinal for modules. This change postpones calls +to objtool until after these steps. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + scripts/Makefile.build | 2 ++ + scripts/Makefile.modfinal | 15 +++++++++++++++ + scripts/link-vmlinux.sh | 9 +++++++++ + 3 files changed, 26 insertions(+) + +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index 64e99f4baa5b..82977350f5a6 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -226,6 +226,7 @@ endif # CC_USING_PATCHABLE_FUNCTION_ENTRY + endif # CONFIG_FTRACE_MCOUNT_RECORD + + ifdef CONFIG_STACK_VALIDATION ++ifndef CONFIG_LTO_CLANG + ifneq ($(SKIP_STACK_VALIDATION),1) + + __objtool_obj := $(objtree)/tools/objtool/objtool +@@ -258,6 +259,7 @@ objtool_obj = $(if $(patsubst y%,, \ + $(__objtool_obj)) + + endif # SKIP_STACK_VALIDATION ++endif # CONFIG_LTO_CLANG + endif # CONFIG_STACK_VALIDATION + + # Rebuild all objects when objtool changes, or is enabled/disabled. +diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal +index d168f0cfe67c..9f1df2f1fab5 100644 +--- a/scripts/Makefile.modfinal ++++ b/scripts/Makefile.modfinal +@@ -48,6 +48,21 @@ endif # CC_USING_PATCHABLE_FUNCTION_ENTRY + endif # CC_USING_RECORD_MCOUNT + endif # CONFIG_FTRACE_MCOUNT_RECORD + ++ifdef CONFIG_STACK_VALIDATION ++ifneq ($(SKIP_STACK_VALIDATION),1) ++cmd_ld_ko_o += \ ++ $(objtree)/tools/objtool/objtool \ ++ $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \ ++ --module \ ++ $(if $(CONFIG_FRAME_POINTER),,--no-fp) \ ++ $(if $(CONFIG_GCOV_KERNEL),--no-unreachable,) \ ++ $(if $(CONFIG_RETPOLINE),--retpoline,) \ ++ $(if $(CONFIG_X86_SMAP),--uaccess,) \ ++ $(@:.ko=$(prelink-ext).o); ++ ++endif # SKIP_STACK_VALIDATION ++endif # CONFIG_STACK_VALIDATION ++ + endif # CONFIG_LTO_CLANG + + quiet_cmd_ld_ko_o = LD [M] $@ +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index c5715608fe63..7e9de077ee7f 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -89,8 +89,17 @@ objtool_link() + { + local objtoolopt; + ++ if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then ++ # Don't perform vmlinux validation unless explicitly requested, ++ # but run objtool on vmlinux.o now that we have an object file. ++ objtoolopt="check" ++ fi ++ + if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then + objtoolopt="check --vmlinux" ++ fi ++ ++ if [ -n "${objtoolopt}" ]; then + if [ -z "${CONFIG_FRAME_POINTER}" ]; then + objtoolopt="${objtoolopt} --no-fp" + fi +-- +2.28.0 + diff --git a/0008-kbuild-lto-limit-inlining.patch b/0008-kbuild-lto-limit-inlining.patch new file mode 100644 index 000000000000..fc91b82c7380 --- /dev/null +++ b/0008-kbuild-lto-limit-inlining.patch @@ -0,0 +1,38 @@ +From ba6bd6d4f05dc173ddcf5ff7365a7964c7769349 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Wed, 4 Dec 2019 15:57:39 -0800 +Subject: [PATCH 08/24] kbuild: lto: limit inlining + +This change limits function inlining across translation unit boundaries +in order to reduce the binary size with LTO. The -import-instr-limit +flag defines a size limit, as the number of LLVM IR instructions, for +importing functions from other TUs, defaulting to 100. + +Based on testing with arm64 defconfig, we found that a limit of 5 is a +reasonable compromise between performance and binary size, reducing the +size of a stripped vmlinux by 11%. + +Suggested-by: George Burgess IV <gbiv@google.com> +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + Makefile | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile b/Makefile +index 19e2bf26c52c..498d281aa318 100644 +--- a/Makefile ++++ b/Makefile +@@ -895,6 +895,10 @@ else + CC_FLAGS_LTO_CLANG := -flto + endif + CC_FLAGS_LTO_CLANG += -fvisibility=default ++ ++# Limit inlining across translation units to reduce binary size ++LD_FLAGS_LTO_CLANG := -mllvm -import-instr-limit=5 ++KBUILD_LDFLAGS += $(LD_FLAGS_LTO_CLANG) + endif + + ifdef CONFIG_LTO +-- +2.28.0 + diff --git a/0009-kbuild-lto-merge-module-sections.patch b/0009-kbuild-lto-merge-module-sections.patch new file mode 100644 index 000000000000..6f0272a5d05d --- /dev/null +++ b/0009-kbuild-lto-merge-module-sections.patch @@ -0,0 +1,65 @@ +From b54ed19078d33c7b777335e9ae135aec5c89ccdf Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Tue, 3 Dec 2019 15:56:24 -0800 +Subject: [PATCH 09/24] kbuild: lto: merge module sections + +LLD always splits sections with LTO, which increases module sizes. This +change adds a linker script that merges the split sections in the final +module. + +Suggested-by: Nick Desaulniers <ndesaulniers@google.com> +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + Makefile | 2 ++ + scripts/module-lto.lds | 26 ++++++++++++++++++++++++++ + 2 files changed, 28 insertions(+) + create mode 100644 scripts/module-lto.lds + +diff --git a/Makefile b/Makefile +index 498d281aa318..50d9516e1796 100644 +--- a/Makefile ++++ b/Makefile +@@ -899,6 +899,8 @@ CC_FLAGS_LTO_CLANG += -fvisibility=default + # Limit inlining across translation units to reduce binary size + LD_FLAGS_LTO_CLANG := -mllvm -import-instr-limit=5 + KBUILD_LDFLAGS += $(LD_FLAGS_LTO_CLANG) ++ ++KBUILD_LDS_MODULE += $(srctree)/scripts/module-lto.lds + endif + + ifdef CONFIG_LTO +diff --git a/scripts/module-lto.lds b/scripts/module-lto.lds +new file mode 100644 +index 000000000000..cbb11dc3639a +--- /dev/null ++++ b/scripts/module-lto.lds +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and ++ * -ffunction-sections, which increases the size of the final module. ++ * Merge the split sections in the final binary. ++ */ ++SECTIONS { ++ __patchable_function_entries : { *(__patchable_function_entries) } ++ ++ .bss : { ++ *(.bss .bss.[0-9a-zA-Z_]*) ++ *(.bss..L*) ++ } ++ ++ .data : { ++ *(.data .data.[0-9a-zA-Z_]*) ++ *(.data..L*) ++ } ++ ++ .rodata : { ++ *(.rodata .rodata.[0-9a-zA-Z_]*) ++ *(.rodata..L*) ++ } ++ ++ .text : { *(.text .text.[0-9a-zA-Z_]*) } ++} +-- +2.28.0 + diff --git a/0010-kbuild-lto-remove-duplicate-dependencies-from-.mod-f.patch b/0010-kbuild-lto-remove-duplicate-dependencies-from-.mod-f.patch new file mode 100644 index 000000000000..2ccca6751423 --- /dev/null +++ b/0010-kbuild-lto-remove-duplicate-dependencies-from-.mod-f.patch @@ -0,0 +1,38 @@ +From b71272e6ef894b1fab04efa2ba98e32d00829eb0 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Wed, 5 Feb 2020 06:09:07 -0800 +Subject: [PATCH 10/24] kbuild: lto: remove duplicate dependencies from .mod + files + +With LTO, llvm-nm prints out symbols for each archive member +separately, which results in a lot of duplicate dependencies in the +.mod file when CONFIG_TRIM_UNUSED_SYMS is enabled. When a module +consists of several compilation units, the output can exceed the +default xargs command size limit and split the dependency list to +multiple lines, which results in used symbols getting trimmed. + +This change removes duplicate dependencies, which will reduce the +probability of this happening and makes .mod files smaller and +easier to read. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + scripts/Makefile.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index 82977350f5a6..82b465ce3ca0 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -291,7 +291,7 @@ endef + + # List module undefined symbols (or empty line if not enabled) + ifdef CONFIG_TRIM_UNUSED_KSYMS +-cmd_undef_syms = $(NM) $< | sed -n 's/^ *U //p' | xargs echo ++cmd_undef_syms = $(NM) $< | sed -n 's/^ *U //p' | sort -u | xargs echo + else + cmd_undef_syms = echo + endif +-- +2.28.0 + diff --git a/0011-init-lto-ensure-initcall-ordering.patch b/0011-init-lto-ensure-initcall-ordering.patch new file mode 100644 index 000000000000..0d9c6807de34 --- /dev/null +++ b/0011-init-lto-ensure-initcall-ordering.patch @@ -0,0 +1,442 @@ +From aab50d6ec2952003f430339dcbfffa407c7349e0 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 8 Dec 2017 15:49:24 -0800 +Subject: [PATCH 11/24] init: lto: ensure initcall ordering + +With LTO, the compiler doesn't necessarily obey the link order for +initcalls, and initcall variables need globally unique names to avoid +collisions at link time. + +This change exports __KBUILD_MODNAME and adds the initcall_id() macro, +which uses it together with __COUNTER__ and __LINE__ to help ensure +these variables have unique names, and moves each variable to its own +section when LTO is enabled, so the correct order can be specified using +a linker script. + +The generate_initcall_ordering.pl script uses nm to find initcalls from +the object files passed to the linker, and generates a linker script +that specifies the intended order. With LTO, the script is called in +link-vmlinux.sh. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + include/linux/init.h | 52 +++++- + scripts/Makefile.lib | 6 +- + scripts/generate_initcall_order.pl | 270 +++++++++++++++++++++++++++++ + scripts/link-vmlinux.sh | 14 ++ + 4 files changed, 333 insertions(+), 9 deletions(-) + create mode 100755 scripts/generate_initcall_order.pl + +diff --git a/include/linux/init.h b/include/linux/init.h +index 212fc9e2f691..af638cd6dd52 100644 +--- a/include/linux/init.h ++++ b/include/linux/init.h +@@ -184,19 +184,57 @@ extern bool initcall_debug; + * as KEEP() in the linker script. + */ + ++/* Format: <modname>__<counter>_<line>_<fn> */ ++#define __initcall_id(fn) \ ++ __PASTE(__KBUILD_MODNAME, \ ++ __PASTE(__, \ ++ __PASTE(__COUNTER__, \ ++ __PASTE(_, \ ++ __PASTE(__LINE__, \ ++ __PASTE(_, fn)))))) ++ ++/* Format: __<prefix>__<iid><id> */ ++#define __initcall_name(prefix, __iid, id) \ ++ __PASTE(__, \ ++ __PASTE(prefix, \ ++ __PASTE(__, \ ++ __PASTE(__iid, id)))) ++ ++#ifdef CONFIG_LTO_CLANG ++/* ++ * With LTO, the compiler doesn't necessarily obey link order for ++ * initcalls. In order to preserve the correct order, we add each ++ * variable into its own section and generate a linker script (in ++ * scripts/link-vmlinux.sh) to specify the order of the sections. ++ */ ++#define __initcall_section(__sec, __iid) \ ++ #__sec ".init.." #__iid ++#else ++#define __initcall_section(__sec, __iid) \ ++ #__sec ".init" ++#endif ++ + #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +-#define ___define_initcall(fn, id, __sec) \ ++#define ____define_initcall(fn, __name, __sec) \ + __ADDRESSABLE(fn) \ +- asm(".section \"" #__sec ".init\", \"a\" \n" \ +- "__initcall_" #fn #id ": \n" \ ++ asm(".section \"" __sec "\", \"a\" \n" \ ++ __stringify(__name) ": \n" \ + ".long " #fn " - . \n" \ + ".previous \n"); + #else +-#define ___define_initcall(fn, id, __sec) \ +- static initcall_t __initcall_##fn##id __used \ +- __attribute__((__section__(#__sec ".init"))) = fn; ++#define ____define_initcall(fn, __name, __sec) \ ++ static initcall_t __name __used \ ++ __attribute__((__section__(__sec))) = fn; + #endif + ++#define __unique_initcall(fn, id, __sec, __iid) \ ++ ____define_initcall(fn, \ ++ __initcall_name(initcall, __iid, id), \ ++ __initcall_section(__sec, __iid)) ++ ++#define ___define_initcall(fn, id, __sec) \ ++ __unique_initcall(fn, id, __sec, __initcall_id(fn)) ++ + #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) + + /* +@@ -236,7 +274,7 @@ extern bool initcall_debug; + #define __exitcall(fn) \ + static exitcall_t __exitcall_##fn __exit_call = fn + +-#define console_initcall(fn) ___define_initcall(fn,, .con_initcall) ++#define console_initcall(fn) ___define_initcall(fn, con, .con_initcall) + + struct obs_kernel_param { + const char *str; +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 54f7b7eb580b..5d7b0b2cc594 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -106,9 +106,11 @@ target-stem = $(basename $(patsubst $(obj)/%,%,$@)) + # These flags are needed for modversions and compiling, so we define them here + # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will + # end up in (or would, if it gets compiled in) +-name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1))) ++name-fix-token = $(subst $(comma),_,$(subst -,_,$1)) ++name-fix = $(call stringify,$(call name-fix-token,$1)) + basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) +-modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) ++modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \ ++ -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname)) + modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) + + orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ +diff --git a/scripts/generate_initcall_order.pl b/scripts/generate_initcall_order.pl +new file mode 100755 +index 000000000000..fe83aec2b51e +--- /dev/null ++++ b/scripts/generate_initcall_order.pl +@@ -0,0 +1,270 @@ ++#!/usr/bin/env perl ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Generates a linker script that specifies the correct initcall order. ++# ++# Copyright (C) 2019 Google LLC ++ ++use strict; ++use warnings; ++use IO::Handle; ++use IO::Select; ++use POSIX ":sys_wait_h"; ++ ++my $nm = $ENV{'NM'} || die "$0: ERROR: NM not set?"; ++my $objtree = $ENV{'objtree'} || '.'; ++ ++## currently active child processes ++my $jobs = {}; # child process pid -> file handle ++## results from child processes ++my $results = {}; # object index -> [ { level, secname }, ... ] ++ ++## reads _NPROCESSORS_ONLN to determine the maximum number of processes to ++## start ++sub get_online_processors { ++ open(my $fh, "getconf _NPROCESSORS_ONLN 2>/dev/null |") ++ or die "$0: ERROR: failed to execute getconf: $!"; ++ my $procs = <$fh>; ++ close($fh); ++ ++ if (!($procs =~ /^\d+$/)) { ++ return 1; ++ } ++ ++ return int($procs); ++} ++ ++## writes results to the parent process ++## format: <file index> <initcall level> <base initcall section name> ++sub write_results { ++ my ($index, $initcalls) = @_; ++ ++ # sort by the counter value to ensure the order of initcalls within ++ # each object file is correct ++ foreach my $counter (sort { $a <=> $b } keys(%{$initcalls})) { ++ my $level = $initcalls->{$counter}->{'level'}; ++ ++ # section name for the initcall function ++ my $secname = $initcalls->{$counter}->{'module'} . '__' . ++ $counter . '_' . ++ $initcalls->{$counter}->{'line'} . '_' . ++ $initcalls->{$counter}->{'function'}; ++ ++ print "$index $level $secname\n"; ++ } ++} ++ ++## reads a result line from a child process and adds it to the $results array ++sub read_results{ ++ my ($fh) = @_; ++ ++ # each child prints out a full line w/ autoflush and exits after the ++ # last line, so even if buffered I/O blocks here, it shouldn't block ++ # very long ++ my $data = <$fh>; ++ ++ if (!defined($data)) { ++ return 0; ++ } ++ ++ chomp($data); ++ ++ my ($index, $level, $secname) = $data =~ ++ /^(\d+)\ ([^\ ]+)\ (.*)$/; ++ ++ if (!defined($index) || ++ !defined($level) || ++ !defined($secname)) { ++ die "$0: ERROR: child process returned invalid data: $data\n"; ++ } ++ ++ $index = int($index); ++ ++ if (!exists($results->{$index})) { ++ $results->{$index} = []; ++ } ++ ++ push (@{$results->{$index}}, { ++ 'level' => $level, ++ 'secname' => $secname ++ }); ++ ++ return 1; ++} ++ ++## finds initcalls from an object file or all object files in an archive, and ++## writes results back to the parent process ++sub find_initcalls { ++ my ($index, $file) = @_; ++ ++ die "$0: ERROR: file $file doesn't exist?" if (! -f $file); ++ ++ open(my $fh, "\"$nm\" --defined-only \"$file\" 2>/dev/null |") ++ or die "$0: ERROR: failed to execute \"$nm\": $!"; ++ ++ my $initcalls = {}; ++ ++ while (<$fh>) { ++ chomp; ++ ++ # check for the start of a new object file (if processing an ++ # archive) ++ my ($path)= $_ =~ /^(.+)\:$/; ++ ++ if (defined($path)) { ++ write_results($index, $initcalls); ++ $initcalls = {}; ++ next; ++ } ++ ++ # look for an initcall ++ my ($module, $counter, $line, $symbol) = $_ =~ ++ /[a-z]\s+__initcall__(\S*)__(\d+)_(\d+)_(.*)$/; ++ ++ if (!defined($module)) { ++ $module = '' ++ } ++ ++ if (!defined($counter) || ++ !defined($line) || ++ !defined($symbol)) { ++ next; ++ } ++ ++ # parse initcall level ++ my ($function, $level) = $symbol =~ ++ /^(.*)((early|rootfs|con|[0-9])s?)$/; ++ ++ die "$0: ERROR: invalid initcall name $symbol in $file($path)" ++ if (!defined($function) || !defined($level)); ++ ++ $initcalls->{$counter} = { ++ 'module' => $module, ++ 'line' => $line, ++ 'function' => $function, ++ 'level' => $level, ++ }; ++ } ++ ++ close($fh); ++ write_results($index, $initcalls); ++} ++ ++## waits for any child process to complete, reads the results, and adds them to ++## the $results array for later processing ++sub wait_for_results { ++ my ($select) = @_; ++ ++ my $pid = 0; ++ do { ++ # unblock children that may have a full write buffer ++ foreach my $fh ($select->can_read(0)) { ++ read_results($fh); ++ } ++ ++ # check for children that have exited, read the remaining data ++ # from them, and clean up ++ $pid = waitpid(-1, WNOHANG); ++ if ($pid > 0) { ++ if (!exists($jobs->{$pid})) { ++ next; ++ } ++ ++ my $fh = $jobs->{$pid}; ++ $select->remove($fh); ++ ++ while (read_results($fh)) { ++ # until eof ++ } ++ ++ close($fh); ++ delete($jobs->{$pid}); ++ } ++ } while ($pid > 0); ++} ++ ++## forks a child to process each file passed in the command line and collects ++## the results ++sub process_files { ++ my $index = 0; ++ my $njobs = get_online_processors(); ++ my $select = IO::Select->new(); ++ ++ while (my $file = shift(@ARGV)) { ++ # fork a child process and read it's stdout ++ my $pid = open(my $fh, '-|'); ++ ++ if (!defined($pid)) { ++ die "$0: ERROR: failed to fork: $!"; ++ } elsif ($pid) { ++ # save the child process pid and the file handle ++ $select->add($fh); ++ $jobs->{$pid} = $fh; ++ } else { ++ # in the child process ++ STDOUT->autoflush(1); ++ find_initcalls($index, "$objtree/$file"); ++ exit; ++ } ++ ++ $index++; ++ ++ # limit the number of children to $njobs ++ if (scalar(keys(%{$jobs})) >= $njobs) { ++ wait_for_results($select); ++ } ++ } ++ ++ # wait for the remaining children to complete ++ while (scalar(keys(%{$jobs})) > 0) { ++ wait_for_results($select); ++ } ++} ++ ++sub generate_initcall_lds() { ++ process_files(); ++ ++ my $sections = {}; # level -> [ secname, ...] ++ ++ # sort results to retain link order and split to sections per ++ # initcall level ++ foreach my $index (sort { $a <=> $b } keys(%{$results})) { ++ foreach my $result (@{$results->{$index}}) { ++ my $level = $result->{'level'}; ++ ++ if (!exists($sections->{$level})) { ++ $sections->{$level} = []; ++ } ++ ++ push(@{$sections->{$level}}, $result->{'secname'}); ++ } ++ } ++ ++ die "$0: ERROR: no initcalls?" if (!keys(%{$sections})); ++ ++ # print out a linker script that defines the order of initcalls for ++ # each level ++ print "SECTIONS {\n"; ++ ++ foreach my $level (sort(keys(%{$sections}))) { ++ my $section; ++ ++ if ($level eq 'con') { ++ $section = '.con_initcall.init'; ++ } else { ++ $section = ".initcall${level}.init"; ++ } ++ ++ print "\t${section} : {\n"; ++ ++ foreach my $secname (@{$sections->{$level}}) { ++ print "\t\t*(${section}..${secname}) ;\n"; ++ } ++ ++ print "\t}\n"; ++ } ++ ++ print "}\n"; ++} ++ ++generate_initcall_lds(); +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index 7e9de077ee7f..5b95af4b5c4a 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -39,6 +39,16 @@ info() + fi + } + ++# Generate a linker script to ensure correct ordering of initcalls. ++gen_initcalls() ++{ ++ info GEN .tmp_initcalls.lds ++ ++ ${srctree}/scripts/generate_initcall_order.pl \ ++ ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \ ++ > .tmp_initcalls.lds ++} ++ + # If CONFIG_LTO_CLANG is selected, collect generated symbol versions into + # .tmp_symversions.lds + gen_symversions() +@@ -70,6 +80,9 @@ modpost_link() + --end-group" + + if [ -n "${CONFIG_LTO_CLANG}" ]; then ++ gen_initcalls ++ lds="-T .tmp_initcalls.lds" ++ + if [ -n "${CONFIG_MODVERSIONS}" ]; then + gen_symversions + lds="${lds} -T .tmp_symversions.lds" +@@ -292,6 +305,7 @@ cleanup() + { + rm -f .btf.* + rm -f .tmp_System.map ++ rm -f .tmp_initcalls.lds + rm -f .tmp_symversions.lds + rm -f .tmp_vmlinux* + rm -f System.map +-- +2.28.0 + diff --git a/0012-init-lto-fix-PREL32-relocations.patch b/0012-init-lto-fix-PREL32-relocations.patch new file mode 100644 index 000000000000..9fa77b777fbb --- /dev/null +++ b/0012-init-lto-fix-PREL32-relocations.patch @@ -0,0 +1,77 @@ +From bbc874d7b9d64809d9aab8ff9a188c02003971ad Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Sun, 22 Mar 2020 17:01:40 -0700 +Subject: [PATCH 12/24] init: lto: fix PREL32 relocations + +With LTO, the compiler can rename static functions to avoid global +naming collisions. As initcall functions are typically static, +renaming can break references to them in inline assembly. This +change adds a global stub with a stable name for each initcall to +fix the issue when PREL32 relocations are used. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + include/linux/init.h | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +diff --git a/include/linux/init.h b/include/linux/init.h +index af638cd6dd52..cea63f7e7705 100644 +--- a/include/linux/init.h ++++ b/include/linux/init.h +@@ -209,26 +209,49 @@ extern bool initcall_debug; + */ + #define __initcall_section(__sec, __iid) \ + #__sec ".init.." #__iid ++ ++/* ++ * With LTO, the compiler can rename static functions to avoid ++ * global naming collisions. We use a global stub function for ++ * initcalls to create a stable symbol name whose address can be ++ * taken in inline assembly when PREL32 relocations are used. ++ */ ++#define __initcall_stub(fn, __iid, id) \ ++ __initcall_name(initstub, __iid, id) ++ ++#define __define_initcall_stub(__stub, fn) \ ++ int __init __stub(void); \ ++ int __init __stub(void) \ ++ { \ ++ return fn(); \ ++ } \ ++ __ADDRESSABLE(__stub) + #else + #define __initcall_section(__sec, __iid) \ + #__sec ".init" ++ ++#define __initcall_stub(fn, __iid, id) fn ++ ++#define __define_initcall_stub(__stub, fn) \ ++ __ADDRESSABLE(fn) + #endif + + #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +-#define ____define_initcall(fn, __name, __sec) \ +- __ADDRESSABLE(fn) \ ++#define ____define_initcall(fn, __stub, __name, __sec) \ ++ __define_initcall_stub(__stub, fn) \ + asm(".section \"" __sec "\", \"a\" \n" \ + __stringify(__name) ": \n" \ +- ".long " #fn " - . \n" \ ++ ".long " __stringify(__stub) " - . \n" \ + ".previous \n"); + #else +-#define ____define_initcall(fn, __name, __sec) \ ++#define ____define_initcall(fn, __unused, __name, __sec) \ + static initcall_t __name __used \ + __attribute__((__section__(__sec))) = fn; + #endif + + #define __unique_initcall(fn, id, __sec, __iid) \ + ____define_initcall(fn, \ ++ __initcall_stub(fn, __iid, id), \ + __initcall_name(initcall, __iid, id), \ + __initcall_section(__sec, __iid)) + +-- +2.28.0 + diff --git a/0013-PCI-Fix-PREL32-relocations-for-LTO.patch b/0013-PCI-Fix-PREL32-relocations-for-LTO.patch new file mode 100644 index 000000000000..f98e7d2cb97b --- /dev/null +++ b/0013-PCI-Fix-PREL32-relocations-for-LTO.patch @@ -0,0 +1,59 @@ +From b8a624d8f629a31cc567f34f64053fab031e70f3 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Thu, 19 Mar 2020 17:09:17 -0700 +Subject: [PATCH 13/24] PCI: Fix PREL32 relocations for LTO + +With Clang's Link Time Optimization (LTO), the compiler can rename +static functions to avoid global naming collisions. As PCI fixup +functions are typically static, renaming can break references +to them in inline assembly. This change adds a global stub to +DECLARE_PCI_FIXUP_SECTION to fix the issue when PREL32 relocations +are used. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Acked-by: Bjorn Helgaas <bhelgaas@google.com> +--- + include/linux/pci.h | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 34c1c4f45288..fd8ee60b812f 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1909,19 +1909,28 @@ enum pci_fixup_pass { + }; + + #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +-#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ +- class_shift, hook) \ +- __ADDRESSABLE(hook) \ ++#define ___DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ ++ class_shift, hook, stub) \ ++ void stub(struct pci_dev *dev); \ ++ void stub(struct pci_dev *dev) \ ++ { \ ++ hook(dev); \ ++ } \ + asm(".section " #sec ", \"a\" \n" \ + ".balign 16 \n" \ + ".short " #vendor ", " #device " \n" \ + ".long " #class ", " #class_shift " \n" \ +- ".long " #hook " - . \n" \ ++ ".long " #stub " - . \n" \ + ".previous \n"); ++ ++#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ ++ class_shift, hook, stub) \ ++ ___DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ ++ class_shift, hook, stub) + #define DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook) \ + __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ +- class_shift, hook) ++ class_shift, hook, __UNIQUE_ID(hook)) + #else + /* Anonymous variables would be nice... */ + #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ +-- +2.28.0 + diff --git a/0014-modpost-lto-strip-.lto-from-module-names.patch b/0014-modpost-lto-strip-.lto-from-module-names.patch new file mode 100644 index 000000000000..1ff4b6fde3dc --- /dev/null +++ b/0014-modpost-lto-strip-.lto-from-module-names.patch @@ -0,0 +1,116 @@ +From 56f70f11a55f51c191b3bb65821ca2f5fd9e4924 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 6 Mar 2020 13:52:03 -0800 +Subject: [PATCH 14/24] modpost: lto: strip .lto from module names + +With LTO, everything is compiled into LLVM bitcode, so we have to link +each module into native code before modpost. Kbuild uses the .lto.o +suffix for these files, which also ends up in module information. This +change strips the unnecessary .lto suffix from the module name. + +Suggested-by: Bill Wendling <morbo@google.com> +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + scripts/mod/modpost.c | 16 +++++++--------- + scripts/mod/modpost.h | 9 +++++++++ + scripts/mod/sumversion.c | 6 +++++- + 3 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c +index 69341b36f271..5a329df55cc3 100644 +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -17,7 +17,6 @@ + #include <ctype.h> + #include <string.h> + #include <limits.h> +-#include <stdbool.h> + #include <errno.h> + #include "modpost.h" + #include "../../include/linux/license.h" +@@ -80,14 +79,6 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...) + exit(1); + } + +-static inline bool strends(const char *str, const char *postfix) +-{ +- if (strlen(str) < strlen(postfix)) +- return false; +- +- return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; +-} +- + void *do_nofail(void *ptr, const char *expr) + { + if (!ptr) +@@ -1984,6 +1975,10 @@ static char *remove_dot(char *s) + size_t m = strspn(s + n + 1, "0123456789"); + if (m && (s[n + m] == '.' || s[n + m] == 0)) + s[n] = 0; ++ ++ /* strip trailing .lto */ ++ if (strends(s, ".lto")) ++ s[strlen(s) - 4] = '\0'; + } + return s; + } +@@ -2007,6 +2002,9 @@ static void read_symbols(const char *modname) + /* strip trailing .o */ + tmp = NOFAIL(strdup(modname)); + tmp[strlen(tmp) - 2] = '\0'; ++ /* strip trailing .lto */ ++ if (strends(tmp, ".lto")) ++ tmp[strlen(tmp) - 4] = '\0'; + mod = new_module(tmp); + free(tmp); + } +diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h +index 3aa052722233..fab30d201f9e 100644 +--- a/scripts/mod/modpost.h ++++ b/scripts/mod/modpost.h +@@ -2,6 +2,7 @@ + #include <stdio.h> + #include <stdlib.h> + #include <stdarg.h> ++#include <stdbool.h> + #include <string.h> + #include <sys/types.h> + #include <sys/stat.h> +@@ -180,6 +181,14 @@ static inline unsigned int get_secindex(const struct elf_info *info, + return info->symtab_shndx_start[sym - info->symtab_start]; + } + ++static inline bool strends(const char *str, const char *postfix) ++{ ++ if (strlen(str) < strlen(postfix)) ++ return false; ++ ++ return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; ++} ++ + /* file2alias.c */ + extern unsigned int cross_build; + void handle_moddevtable(struct module *mod, struct elf_info *info, +diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c +index d587f40f1117..760e6baa7eda 100644 +--- a/scripts/mod/sumversion.c ++++ b/scripts/mod/sumversion.c +@@ -391,10 +391,14 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) + struct md4_ctx md; + char *fname; + char filelist[PATH_MAX + 1]; ++ int postfix_len = 1; ++ ++ if (strends(modname, ".lto.o")) ++ postfix_len = 5; + + /* objects for a module are listed in the first line of *.mod file. */ + snprintf(filelist, sizeof(filelist), "%.*smod", +- (int)strlen(modname) - 1, modname); ++ (int)strlen(modname) - postfix_len, modname); + + buf = read_text_file(filelist); + +-- +2.28.0 + diff --git a/0015-scripts-mod-disable-LTO-for-empty.c.patch b/0015-scripts-mod-disable-LTO-for-empty.c.patch new file mode 100644 index 000000000000..2ab30257bce0 --- /dev/null +++ b/0015-scripts-mod-disable-LTO-for-empty.c.patch @@ -0,0 +1,28 @@ +From 5a21945e8fd13b08584e5e62b477dae609970c7c Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Mon, 10 Apr 2017 12:32:24 -0700 +Subject: [PATCH 15/24] scripts/mod: disable LTO for empty.c + +With CONFIG_LTO_CLANG, clang generates LLVM IR instead of ELF object +files. As empty.o is used for probing target properties, disable LTO +for it to produce an object file instead. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + scripts/mod/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile +index 296b6a3878b2..b6e3b40c6eeb 100644 +--- a/scripts/mod/Makefile ++++ b/scripts/mod/Makefile +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + OBJECT_FILES_NON_STANDARD := y ++CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO) + + hostprogs := modpost mk_elfconfig + always-y := $(hostprogs) empty.o +-- +2.28.0 + diff --git a/0016-efi-libstub-disable-LTO.patch b/0016-efi-libstub-disable-LTO.patch new file mode 100644 index 000000000000..e4e517cfcedd --- /dev/null +++ b/0016-efi-libstub-disable-LTO.patch @@ -0,0 +1,30 @@ +From b34b8b1ffab687116806638c2c8e2bbf0b70d52e Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Mon, 1 May 2017 11:08:05 -0700 +Subject: [PATCH 16/24] efi/libstub: disable LTO + +With CONFIG_LTO_CLANG, we produce LLVM bitcode instead of ELF object +files. Since LTO is not really needed here and the Makefile assumes we +produce an object file, disable LTO for libstub. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + drivers/firmware/efi/libstub/Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile +index 75daaf20374e..95e12002cc7c 100644 +--- a/drivers/firmware/efi/libstub/Makefile ++++ b/drivers/firmware/efi/libstub/Makefile +@@ -35,6 +35,8 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ + + # remove SCS flags from all objects in this directory + KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS)) ++# disable LTO ++KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS)) + + GCOV_PROFILE := n + # Sanitizer runtimes are unavailable and cannot be linked here. +-- +2.28.0 + diff --git a/0017-drivers-misc-lkdtm-disable-LTO-for-rodata.o.patch b/0017-drivers-misc-lkdtm-disable-LTO-for-rodata.o.patch new file mode 100644 index 000000000000..f6fbfc001587 --- /dev/null +++ b/0017-drivers-misc-lkdtm-disable-LTO-for-rodata.o.patch @@ -0,0 +1,29 @@ +From 32d54d9cf192a72bde7eab0358832ecb785a3b80 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Tue, 5 Dec 2017 12:54:13 -0800 +Subject: [PATCH 17/24] drivers/misc/lkdtm: disable LTO for rodata.o + +Disable LTO for rodata.o to allow objcopy to be used to +manipulate sections. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Acked-by: Kees Cook <keescook@chromium.org> +--- + drivers/misc/lkdtm/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile +index c70b3822013f..dd4c936d4d73 100644 +--- a/drivers/misc/lkdtm/Makefile ++++ b/drivers/misc/lkdtm/Makefile +@@ -13,6 +13,7 @@ lkdtm-$(CONFIG_LKDTM) += cfi.o + + KASAN_SANITIZE_stackleak.o := n + KCOV_INSTRUMENT_rodata.o := n ++CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) + + OBJCOPYFLAGS := + OBJCOPYFLAGS_rodata_objcopy.o := \ +-- +2.28.0 + diff --git a/0018-arm64-export-CC_USING_PATCHABLE_FUNCTION_ENTRY.patch b/0018-arm64-export-CC_USING_PATCHABLE_FUNCTION_ENTRY.patch new file mode 100644 index 000000000000..9e4fda6acf3a --- /dev/null +++ b/0018-arm64-export-CC_USING_PATCHABLE_FUNCTION_ENTRY.patch @@ -0,0 +1,29 @@ +From 1e323ca36f6cf7b3c85a22cf5195a05fe15002b3 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Mon, 6 Apr 2020 14:58:41 -0700 +Subject: [PATCH 18/24] arm64: export CC_USING_PATCHABLE_FUNCTION_ENTRY + +Since arm64 does not use -pg in CC_FLAGS_FTRACE with +DYNAMIC_FTRACE_WITH_REGS, skip running recordmcount by +exporting CC_USING_PATCHABLE_FUNCTION_ENTRY. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/arm64/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index 70f5905954dd..c90cc19fab92 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -115,6 +115,7 @@ endif + ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) + KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY + CC_FLAGS_FTRACE := -fpatchable-function-entry=2 ++ export CC_USING_PATCHABLE_FUNCTION_ENTRY := 1 + endif + + # Default value +-- +2.28.0 + diff --git a/0019-arm64-vdso-disable-LTO.patch b/0019-arm64-vdso-disable-LTO.patch new file mode 100644 index 000000000000..37735ae4d65e --- /dev/null +++ b/0019-arm64-vdso-disable-LTO.patch @@ -0,0 +1,31 @@ +From c317d4f54f587c42f0a4a2e3eafcf7de9d4e88d4 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Tue, 19 Dec 2017 08:55:23 -0800 +Subject: [PATCH 19/24] arm64: vdso: disable LTO + +Disable LTO for the vDSO by filtering out CC_FLAGS_LTO, as there's no +point in using link-time optimization for the small about of C code. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/arm64/kernel/vdso/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile +index 45d5cfe46429..aa47070a3ccf 100644 +--- a/arch/arm64/kernel/vdso/Makefile ++++ b/arch/arm64/kernel/vdso/Makefile +@@ -30,8 +30,8 @@ ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ + ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 + ccflags-y += -DDISABLE_BRANCH_PROFILING + +-CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) +-KBUILD_CFLAGS += $(DISABLE_LTO) ++CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \ ++ $(CC_FLAGS_LTO) + KASAN_SANITIZE := n + UBSAN_SANITIZE := n + OBJECT_FILES_NON_STANDARD := y +-- +2.28.0 + diff --git a/0020-arm64-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch b/0020-arm64-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch new file mode 100644 index 000000000000..a54a3e74a74d --- /dev/null +++ b/0020-arm64-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch @@ -0,0 +1,28 @@ +From ed4e20fa5e35bcb4a2e2ec0a47a44227349ac007 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Thu, 2 Nov 2017 09:34:42 -0700 +Subject: [PATCH 20/24] arm64: allow LTO_CLANG and THINLTO to be selected + +Allow CONFIG_LTO_CLANG and CONFIG_THINLTO to be enabled. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/arm64/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 66dc41fd49f2..c9fb665b62b5 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -72,6 +72,8 @@ config ARM64 + select ARCH_USE_SYM_ANNOTATIONS + select ARCH_SUPPORTS_MEMORY_FAILURE + select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK ++ select ARCH_SUPPORTS_LTO_CLANG ++ select ARCH_SUPPORTS_THINLTO + select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && (GCC_VERSION >= 50000 || CC_IS_CLANG) + select ARCH_SUPPORTS_NUMA_BALANCING +-- +2.28.0 + diff --git a/0021-g86-vdso-disable-LTO-only-for-vDSO.patch b/0021-g86-vdso-disable-LTO-only-for-vDSO.patch new file mode 100644 index 000000000000..fa7009ba2782 --- /dev/null +++ b/0021-g86-vdso-disable-LTO-only-for-vDSO.patch @@ -0,0 +1,48 @@ +From 69e4a800e255147d8e9fb52eaab8d6b29a33ebcf Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Tue, 16 Apr 2019 14:40:00 -0700 +Subject: [PATCH 21/24] g86, vdso: disable LTO only for vDSO + +Remove the undefined DISABLE_LTO flag from the vDSO, and filter out +CC_FLAGS_LTO flags instead where needed. Note that while we could use +Clang's LTO for the 64-bit vDSO, it won't add noticeable benefit for +the small amount of C code. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/x86/entry/vdso/Makefile | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile +index 04e65f0698f6..67f60662830a 100644 +--- a/arch/x86/entry/vdso/Makefile ++++ b/arch/x86/entry/vdso/Makefile +@@ -9,8 +9,6 @@ ARCH_REL_TYPE_ABS := R_X86_64_JUMP_SLOT|R_X86_64_GLOB_DAT|R_X86_64_RELATIVE| + ARCH_REL_TYPE_ABS += R_386_GLOB_DAT|R_386_JMP_SLOT|R_386_RELATIVE + include $(srctree)/lib/vdso/Makefile + +-KBUILD_CFLAGS += $(DISABLE_LTO) +- + # Sanitizer runtimes are unavailable and cannot be linked here. + KASAN_SANITIZE := n + UBSAN_SANITIZE := n +@@ -92,7 +90,7 @@ ifneq ($(RETPOLINE_VDSO_CFLAGS),) + endif + endif + +-$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) ++$(vobjs): KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL) + + # + # vDSO code runs in userspace and -pg doesn't help with profiling anyway. +@@ -150,6 +148,7 @@ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32)) ++KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic + KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) + KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) +-- +2.28.0 + diff --git a/0022-x86-ftrace-disable-recordmcount-for-ftrace_make_nop.patch b/0022-x86-ftrace-disable-recordmcount-for-ftrace_make_nop.patch new file mode 100644 index 000000000000..b6f69b476300 --- /dev/null +++ b/0022-x86-ftrace-disable-recordmcount-for-ftrace_make_nop.patch @@ -0,0 +1,27 @@ +From f388fe0b28282f272c8ca441e63f16c438c55bde Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Tue, 5 May 2020 14:58:24 -0700 +Subject: [PATCH 22/24] x86, ftrace: disable recordmcount for ftrace_make_nop + +Ignore mcount relocations in ftrace_make_nop. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/x86/kernel/ftrace.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c +index 51504566b3a6..c3b28b81277b 100644 +--- a/arch/x86/kernel/ftrace.c ++++ b/arch/x86/kernel/ftrace.c +@@ -121,6 +121,7 @@ ftrace_modify_code_direct(unsigned long ip, const char *old_code, + return 0; + } + ++__nomcount + int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) + { + unsigned long ip = rec->ip; +-- +2.28.0 + diff --git a/0023-x86-relocs-Ignore-L4_PAGE_OFFSET-relocations.patch b/0023-x86-relocs-Ignore-L4_PAGE_OFFSET-relocations.patch new file mode 100644 index 000000000000..72bbad0cfcf9 --- /dev/null +++ b/0023-x86-relocs-Ignore-L4_PAGE_OFFSET-relocations.patch @@ -0,0 +1,28 @@ +From be6d4b6b69e92700f1a2359de3a02c358e074926 Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 17 Apr 2020 19:28:45 -0700 +Subject: [PATCH 23/24] x86, relocs: Ignore L4_PAGE_OFFSET relocations + +L4_PAGE_OFFSET is a constant value, so don't warn about absolute +relocations. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/x86/tools/relocs.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c +index ce7188cbdae5..8f3bf34840ce 100644 +--- a/arch/x86/tools/relocs.c ++++ b/arch/x86/tools/relocs.c +@@ -47,6 +47,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { + [S_ABS] = + "^(xen_irq_disable_direct_reloc$|" + "xen_save_fl_direct_reloc$|" ++ "L4_PAGE_OFFSET|" + "VDSO|" + "__crc_)", + +-- +2.28.0 + diff --git a/0024-x86-build-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch b/0024-x86-build-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch new file mode 100644 index 000000000000..1196a76b0f7d --- /dev/null +++ b/0024-x86-build-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch @@ -0,0 +1,45 @@ +From c4850e7fee85527976519f6d55685706d41cb91b Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Wed, 10 Apr 2019 14:17:20 -0700 +Subject: [PATCH 24/24] x86, build: allow LTO_CLANG and THINLTO to be selected + +Allow CONFIG_LTO_CLANG and CONFIG_THINLTO to be enabled. + +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +--- + arch/x86/Kconfig | 2 ++ + arch/x86/Makefile | 5 +++++ + 2 files changed, 7 insertions(+) + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 4a64395bc35d..16f046d5abea 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -92,6 +92,8 @@ config X86 + select ARCH_SUPPORTS_ACPI + select ARCH_SUPPORTS_ATOMIC_RMW + select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 ++ select ARCH_SUPPORTS_LTO_CLANG if X86_64 ++ select ARCH_SUPPORTS_THINLTO if X86_64 + select ARCH_USE_BUILTIN_BSWAP + select ARCH_USE_QUEUED_RWLOCKS + select ARCH_USE_QUEUED_SPINLOCKS +diff --git a/arch/x86/Makefile b/arch/x86/Makefile +index 00e378de8bc0..a1abc1e081ad 100644 +--- a/arch/x86/Makefile ++++ b/arch/x86/Makefile +@@ -188,6 +188,11 @@ ifdef CONFIG_X86_64 + KBUILD_LDFLAGS += $(call ld-option, -z max-page-size=0x200000) + endif + ++ifdef CONFIG_LTO_CLANG ++KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \ ++ -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) ++endif ++ + # Workaround for a gcc prelease that unfortunately was shipped in a suse release + KBUILD_CFLAGS += -Wno-sign-compare + # +-- +2.28.0 + @@ -20,6 +20,7 @@ source=( "$_srcname::git+https://git.archlinux.org/linux.git#tag=$_srctag" config # the main kernel config file sphinx-workaround.patch + # ZSTD 0001-lib-prepare-zstd-for-preboot-environment.patch 0002-lib-add-zstd-support-to-decompress.patch 0003-init-add-support-for-zstd-compressed-kernel.patch @@ -27,10 +28,36 @@ source=( 0005-x86-bump-ZO_z_extra_bytes-margin-for-zstd.patch 0006-x86-Add-support-for-ZSTD-compressed-kernel.patch 0007-.gitignore-add-ZSTD-compressed-files.patch + # LTO + 0001-bitfield.h-don-t-compile-time-validate-_val-in-FIELD.patch + 0002-objtool-use-sh_info-to-find-the-base-for-.rela-secti.patch + 0003-objtool-don-t-autodetect-vmlinux.o.patch + 0004-kbuild-add-support-for-Clang-LTO.patch + 0005-kbuild-lto-fix-module-versioning.patch + 0006-kbuild-lto-fix-recordmcount.patch + 0007-kbuild-lto-postpone-objtool.patch + 0008-kbuild-lto-limit-inlining.patch + 0009-kbuild-lto-merge-module-sections.patch + 0010-kbuild-lto-remove-duplicate-dependencies-from-.mod-f.patch + 0011-init-lto-ensure-initcall-ordering.patch + 0012-init-lto-fix-PREL32-relocations.patch + 0013-PCI-Fix-PREL32-relocations-for-LTO.patch + 0014-modpost-lto-strip-.lto-from-module-names.patch + 0015-scripts-mod-disable-LTO-for-empty.c.patch + 0016-efi-libstub-disable-LTO.patch + 0017-drivers-misc-lkdtm-disable-LTO-for-rodata.o.patch + 0018-arm64-export-CC_USING_PATCHABLE_FUNCTION_ENTRY.patch + 0019-arm64-vdso-disable-LTO.patch + 0020-arm64-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch + 0021-g86-vdso-disable-LTO-only-for-vDSO.patch + 0022-x86-ftrace-disable-recordmcount-for-ftrace_make_nop.patch + 0023-x86-relocs-Ignore-L4_PAGE_OFFSET-relocations.patch + 0024-x86-build-allow-LTO_CLANG-and-THINLTO-to-be-selected.patch + # CPU enable_additional_cpu_optimizations_for_gcc_v10.1+_kernel_v5.8+.patch ) sha256sums=('SKIP' - '7748dbdc1d0ff9efa8358268e82b21b338acfb7ebbd2876753bf23c4e71da44c' + '639e5ac559832b05d1b3be611faedab33aa65059eb8cd76879d2b92ecd17d7fa' '8cb21e0b3411327b627a9dd15b8eb773295a0d2782b1a41b2a8839d1b2f5778c' '2f0090ec0c9a72e6241bbea05faaef979405119ce8ef669d84dead36c8e2246e' '5f21c12f002e71ec5b5db96832b415ce291a7e230fa07b328c21760274e72e9d' @@ -39,6 +66,30 @@ sha256sums=('SKIP' '2b558cc58e95343bb2e3cfd96c668b671251c543124176b8687baf12cdf999d5' '84c275eb98fb908b742ffe51faa7feb0312550712b0cd729bf72941a2f633a65' 'f88df9ee297e229792e516ac9fb6f35ddc1aa13c3fdeb9ba15fb4de8b1dcd7c7' + '524b329a965f1b983fd4b78e1827854727d4ebb9c21cc9f245bf2ce91c2bed1d' + '053582c4fa855a9219f45f864d7a03b3a28cfd04ec798b0cc47080c836669184' + '7e155527495f8a009efc6edc43d44c1775de64c750c9c112f6964d599eada3ef' + '2ef22d6b576ebf452238ae48658515d5d484b3ab7448b9d62fc1295570bb8f14' + '9bbda700ef98d75ce24c43f5bf191f77f51d5587ea06ad5c763d9ac10d39c96e' + '5684845b4c0a516fc907a1f24d420760f2cd2a53ab977fb409a6378f9b1f473e' + '438c34b332cb3d67e31856f11ed71052974a869f8fd71da637343da7de0c1bf2' + 'efaa62f8d18463141958fdeb495b58c03e49f62ef7bca30e5cd261821bff4ca6' + 'c44e6e4de658ba682cba3b24f766af5bb70572869c8419c0091767726439bfa1' + '75939f2da39a5644e407aaee060ea00fa6b8e06bf5cc361af793affe5a660243' + '407e9262ed5cf234172f3048ae79513030589022acba42039ad709f490c6d139' + 'e89ceb6f4cda3fa9ae59c3482b27118df18c98d0a74665d0fe07f05017c1144e' + 'eacb3b5cd7380a48ae50f38c57153a3f90a6dd890b573bf172c0d0585e4f1ab9' + '7854b55ff44f5ec0a94d295075679aaaf1ff3baf9039bd8a7ea73e4e9ae4f8dd' + '4668748669f31e3535e02c11f2f4554412d5bd29279ebdbe241f515d7f34aafc' + '729f41453d3607c6c055ae1f52e476d09a4b49169897fe136ad37a451c7872bb' + 'e3d865689bc4c3ab52b9d0a897278bde415a7cd4892c0e7006ce7998c6e97fe7' + '4c2bc4f796ef21d1f5cbc7e4a7600a250c66de329819795f77cad3e52106b2fe' + '85bf687909b628e36ea8a2c973cdd3ef2819f57422d5405cf338abce9037ef9a' + '0c269cb936eec02fc767f1d4f2ca4436582f5c4f046a3b4c53608d4232a09809' + '0feb6c229e75c5a4ed532840bbe3ab1426ae255c0897f7852a93537e7661b461' + 'bd3f17cbb1da5293bb54a5bdeaa613098d41fe676ee327ba35867c18732ee80c' + '539794c1dc9b8e35a73e2e165040f363d0c7f32bc5da415ae6b27a9ffe57dde2' + '3b956c3768e59f2d5fb0546a855138319eff60e077822667befed734c7ac84af' '5ab29eb64e57df83b395a29a6a4f89030d142feffbfbf73b3afc6d97a2a7fd12') export KBUILD_BUILD_HOST=archlinux @@ -854,6 +854,9 @@ CONFIG_HAVE_STACKPROTECTOR=y CONFIG_CC_HAS_STACKPROTECTOR_NONE=y CONFIG_STACKPROTECTOR=y CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_THINLTO=y +CONFIG_LTO_NONE=y CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y |