Created
August 1, 2021 08:18
-
-
Save ptr1337/0a472b1ba36973584928873bcfe97928 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 841d090cab781709c26974af8309ac309ec32875 Mon Sep 17 00:00:00 2001 | |
From: mssx86 <mss@tutanota.de> | |
Date: Thu, 13 May 2021 21:43:18 +0300 | |
Subject: [PATCH] andikleen lto-5.12-3 3fb2a4dd for 5.12.3. | |
--- | |
Documentation/bpf/btf.rst | 4 ++ | |
Documentation/kbuild/lto-build.rst | 70 ++++++++++++++++++++ | |
Kbuild | 3 + | |
Makefile | 9 ++- | |
arch/Kconfig | 53 +++++++++++++++ | |
arch/x86/Kconfig | 5 +- | |
arch/x86/boot/compressed/string.c | 4 +- | |
arch/x86/entry/vdso/Makefile | 2 + | |
arch/x86/include/asm/preempt.h | 4 +- | |
arch/x86/kernel/alternative.c | 6 +- | |
arch/x86/kernel/cpu/resctrl/monitor.c | 2 +- | |
arch/x86/kernel/module.c | 7 +- | |
arch/x86/lib/memcpy_32.c | 6 +- | |
arch/x86/lib/msr-smp.c | 4 +- | |
arch/x86/purgatory/Makefile | 1 + | |
arch/x86/realmode/Makefile | 1 + | |
drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | 4 +- | |
drivers/gpu/drm/i915/i915_drv.h | 6 +- | |
drivers/media/pci/cobalt/cobalt-i2c.c | 2 +- | |
drivers/media/pci/cx18/cx18-i2c.c | 2 +- | |
drivers/media/platform/sti/delta/delta-ipc.c | 4 +- | |
drivers/xen/time.c | 2 +- | |
fs/open.c | 2 +- | |
include/crypto/internal/poly1305.h | 2 +- | |
include/linux/btf_ids.h | 28 ++++---- | |
include/linux/compiler_attributes.h | 16 +++++ | |
include/linux/compiler_types.h | 10 +++ | |
include/linux/export.h | 6 +- | |
include/linux/init.h | 2 +- | |
include/linux/linkage.h | 16 ++--- | |
include/linux/static_call.h | 21 +++--- | |
include/linux/tracepoint.h | 4 +- | |
init/Kconfig | 6 ++ | |
kernel/Makefile | 2 +- | |
kernel/bpf/btf.c | 1 + | |
kernel/bpf/core.c | 2 +- | |
kernel/bpf/map_iter.c | 1 + | |
kernel/bpf/prog_iter.c | 1 + | |
kernel/bpf/task_iter.c | 1 + | |
kernel/livepatch/Kconfig | 1 + | |
kernel/locking/spinlock.c | 56 ++++++++-------- | |
kernel/sched/core.c | 18 +++-- | |
kernel/softirq.c | 2 +- | |
kernel/static_call.c | 14 ++-- | |
kernel/time/posix-stubs.c | 2 +- | |
lib/Kconfig.debug | 1 + | |
net/core/filter.c | 2 + | |
net/ipv6/route.c | 1 + | |
net/netlink/af_netlink.c | 1 + | |
scripts/Makefile.build | 23 ++++--- | |
scripts/Makefile.lib | 2 +- | |
scripts/Makefile.lto | 40 +++++++++++ | |
scripts/Makefile.modfinal | 10 +-- | |
scripts/Makefile.modpost | 6 +- | |
scripts/bloat-o-meter | 2 +- | |
scripts/gcc-ld | 18 +++-- | |
scripts/gen_autoksyms.sh | 4 +- | |
scripts/link-vmlinux.sh | 49 +++++++------- | |
scripts/mksysmap | 3 +- | |
scripts/mod/Makefile | 3 + | |
scripts/mod/modpost.c | 22 +++++- | |
tools/objtool/arch/x86/decode.c | 7 +- | |
tools/objtool/check.c | 34 +++++++--- | |
tools/objtool/include/objtool/check.h | 4 +- | |
tools/objtool/orc_gen.c | 19 ++++-- | |
65 files changed, 482 insertions(+), 184 deletions(-) | |
create mode 100644 Documentation/kbuild/lto-build.rst | |
create mode 100644 scripts/Makefile.lto | |
diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst | |
index 44dc789de..ee59e827d 100644 | |
--- a/Documentation/bpf/btf.rst | |
+++ b/Documentation/bpf/btf.rst | |
@@ -706,6 +706,9 @@ with following syntax:: | |
BTF_ID_LIST(list) | |
BTF_ID(type1, name1) | |
BTF_ID(type2, name2) | |
+ BTF_ID_LIST_END | |
+ | |
+The unsorted list must be terminated with ``BTF_ID_LIST_END``. | |
resulting in following layout in .BTF_ids section:: | |
@@ -723,6 +726,7 @@ want to define unused entry in BTF_ID_LIST, like:: | |
BTF_ID(struct, sk_buff) | |
BTF_ID_UNUSED | |
BTF_ID(struct, task_struct) | |
+ BTF_ID_LIST_END | |
The ``BTF_SET_START/END`` macros pair defines sorted list of BTF ID values | |
and their count, with following syntax:: | |
diff --git a/Documentation/kbuild/lto-build.rst b/Documentation/kbuild/lto-build.rst | |
new file mode 100644 | |
index 000000000..e8a0f149e | |
--- /dev/null | |
+++ b/Documentation/kbuild/lto-build.rst | |
@@ -0,0 +1,70 @@ | |
+===================================================== | |
+gcc link time optimization (LTO) for the Linux kernel | |
+===================================================== | |
+ | |
+Link Time Optimization allows the compiler to optimize the complete program | |
+instead of just each file. | |
+ | |
+The compiler can inline functions between files and do various other global | |
+optimizations, like specializing functions for common parameters, | |
+determing when global variables are clobbered, making functions pure/const, | |
+propagating constants globally, removing unneeded data and others. | |
+ | |
+It will also drop unused functions which can make the kernel | |
+image smaller in some circumstances, in particular for small kernel | |
+configurations. | |
+ | |
+For small monolithic kernels it can throw away unused code very effectively | |
+(especially when modules are disabled) and usually shrinks | |
+the code size. | |
+ | |
+Build time and memory consumption at build time will increase, depending | |
+on the size of the largest binary. Modular kernels are less affected. | |
+With LTO incremental builds are less incremental, as always the whole | |
+binary needs to be re-optimized (but not re-parsed) | |
+ | |
+Oopses can be somewhat more difficult to read, due to the more aggressive | |
+inlining: it helps to use scripts/faddr2line. | |
+ | |
+It is currently incompatible with live patching. | |
+ | |
+Normal "reasonable" builds work with less than 4GB of RAM, but very large | |
+configurations like allyesconfig typically need more memory. The actual | |
+memory needed depends on the available memory (gcc sizes its garbage | |
+collector pools based on that or on the ulimit -m limits) and | |
+the compiler version. | |
+ | |
+Requirements: | |
+------------- | |
+- Enough memory: 4GB for a standard build, more for allyesconfig | |
+The peak memory usage happens single threaded (when lto-wpa merges types), | |
+so dialing back -j options will not help much. | |
+ | |
+A 32bit hosted compiler is unlikely to work due to the memory requirements. | |
+You can however build a kernel targeted at 32bit on a 64bit host. | |
+ | |
+FAQs: | |
+----- | |
+Q: I get a section type attribute conflict | |
+A: Usually because of someone doing | |
+const __initdata (should be const __initconst) or const __read_mostly | |
+(should be just const). Check both symbols reported by gcc. | |
+ | |
+References: | |
+----------- | |
+ | |
+Presentation on Kernel LTO | |
+(note, performance numbers/details totally outdated.) | |
+http://halobates.de/kernel-lto.pdf | |
+ | |
+Generic gcc LTO: | |
+http://www.ucw.cz/~hubicka/slides/labs2013.pdf | |
+http://www.hipeac.net/system/files/barcelona.pdf | |
+ | |
+Somewhat outdated too: | |
+http://gcc.gnu.org/projects/lto/lto.pdf | |
+http://gcc.gnu.org/projects/lto/whopr.pdf | |
+ | |
+Happy Link-Time-Optimizing! | |
+ | |
+Andi Kleen | |
diff --git a/Kbuild b/Kbuild | |
index fa441b98c..69c86a38e 100644 | |
--- a/Kbuild | |
+++ b/Kbuild | |
@@ -10,6 +10,8 @@ bounds-file := include/generated/bounds.h | |
always-y := $(bounds-file) | |
targets := kernel/bounds.s | |
+kernel/bounds.s: KBUILD_CFLAGS += $(DISABLE_LTO_GCC) | |
+ | |
$(bounds-file): kernel/bounds.s FORCE | |
$(call filechk,offsets,__LINUX_BOUNDS_H__) | |
@@ -32,6 +34,7 @@ always-y += $(offsets-file) | |
targets += arch/$(SRCARCH)/kernel/asm-offsets.s | |
arch/$(SRCARCH)/kernel/asm-offsets.s: $(timeconst-file) $(bounds-file) | |
+arch/$(SRCARCH)/kernel/asm-offsets.s: KBUILD_CFLAGS += $(DISABLE_LTO_GCC) | |
$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s FORCE | |
$(call filechk,offsets,__ASM_OFFSETS_H__) | |
diff --git a/Makefile b/Makefile | |
index 53a4b1cb7..961b66a77 100644 | |
--- a/Makefile | |
+++ b/Makefile | |
@@ -437,6 +437,7 @@ STRIP = llvm-strip | |
else | |
CC = $(CROSS_COMPILE)gcc | |
LD = $(CROSS_COMPILE)ld | |
+LDFINAL = $(LD) | |
AR = $(CROSS_COMPILE)ar | |
NM = $(CROSS_COMPILE)nm | |
OBJCOPY = $(CROSS_COMPILE)objcopy | |
@@ -509,7 +510,7 @@ CLANG_FLAGS := | |
export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC | |
export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL | |
export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX | |
-export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD | |
+export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD LDFINAL | |
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE | |
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS | |
@@ -977,6 +978,7 @@ include-$(CONFIG_KASAN) += scripts/Makefile.kasan | |
include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan | |
include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan | |
include-$(CONFIG_KCOV) += scripts/Makefile.kcov | |
+include-$(CONFIG_LTO_GCC) += scripts/Makefile.lto | |
include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins | |
include $(addprefix $(srctree)/, $(include-y)) | |
@@ -1191,8 +1193,9 @@ $(autoksyms_h): | |
ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) | |
# Final link of vmlinux with optional arch pass after final link | |
-cmd_link-vmlinux = \ | |
- $(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ | |
+cmd_link-vmlinux = \ | |
+ $(CONFIG_SHELL) $< "$(LD)" "$(LDFINAL)" "$(KBUILD_LDFLAGS)" \ | |
+ "$(LDFLAGS_vmlinux)" ; \ | |
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) | |
vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE | |
diff --git a/arch/Kconfig b/arch/Kconfig | |
index ecfd3520b..23702ce4a 100644 | |
--- a/arch/Kconfig | |
+++ b/arch/Kconfig | |
@@ -643,6 +643,21 @@ config HAS_LTO_CLANG | |
The compiler and Kconfig options support building with Clang's | |
LTO. | |
+config ARCH_SUPPORTS_GCC_LTO | |
+ bool | |
+ | |
+# Some ar versions leak file descriptors when using the LTO | |
+# plugin and cause strange errors when ulimit -n is too low. | |
+# Pick an arbitrary threshold, which should be enough for most | |
+# kernel configs. This was a regression that is only | |
+# in some transient binutils version, so either older or | |
+# new enough is ok. | |
+# This might not be the exact range with this bug. | |
+config BAD_AR | |
+ depends on LD_VERSION = 23000 | |
+ depends on $(shell,ulimit -n) < 4000 | |
+ def_bool y | |
+ | |
choice | |
prompt "Link Time Optimization (LTO)" | |
default LTO_NONE | |
@@ -690,8 +705,46 @@ config LTO_CLANG_THIN | |
https://clang.llvm.org/docs/ThinLTO.html | |
If unsure, say Y. | |
+ | |
+config LTO_GCC | |
+ bool "gcc LTO" | |
+ depends on ARCH_SUPPORTS_GCC_LTO && CC_IS_GCC | |
+ depends on GCC_VERSION >= 90000 | |
+ depends on LD_VERSION >= 22700 | |
+ depends on !BAD_AR | |
+ select LTO | |
+ select CC_NEEDS_FRE_WA if GCC_VERSION < 100300 | |
+ help | |
+ Enable whole program (link time) optimizations (LTO) for the the | |
+ whole kernel and each module. This usually increases compile time, | |
+ especially for incremential builds, but tends to generate better code | |
+ as well as some global checks. | |
+ | |
+ It allows the compiler to inline functions between different files | |
+ and do other global optimization, like propagating constants between | |
+ functions, determine side effects of functions, avoid unnecessary | |
+ register saving around functions, or optimize unused function arguments. | |
+ It also allows the compiler to drop unused functions. | |
+ | |
+ With this option the compiler will also do some global checking over | |
+ different source files. | |
+ | |
+ This requires a gcc 9 or later compiler and binutils >= 2.27. | |
+ | |
+ On larger non modular configurations this may need more than 4GB of | |
+ RAM for the link phase, as well as a 64bit host compiler. | |
+ | |
+ For more information see Documentation/kbuild/lto-build.rst | |
endchoice | |
+config LTO_CP_CLONE | |
+ bool "Allow aggressive cloning for function specialization" | |
+ depends on LTO_GCC | |
+ help | |
+ Allow the compiler to clone and specialize functions for specific | |
+ arguments when it determines these arguments are commonly | |
+ called. Experimential. Will increase text size. | |
+ | |
config HAVE_ARCH_WITHIN_STACK_FRAMES | |
bool | |
help | |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig | |
index 268b7d5c9..703de5619 100644 | |
--- a/arch/x86/Kconfig | |
+++ b/arch/x86/Kconfig | |
@@ -156,7 +156,9 @@ config X86 | |
select HAVE_ARCH_MMAP_RND_BITS if MMU | |
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT | |
select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT | |
- select HAVE_ARCH_PREL32_RELOCATIONS | |
+ # LTO can move assembler to different files, so all | |
+ # the init functions would need to be global for this to work | |
+ select HAVE_ARCH_PREL32_RELOCATIONS if !LTO_GCC | |
select HAVE_ARCH_SECCOMP_FILTER | |
select HAVE_ARCH_THREAD_STRUCT_WHITELIST | |
select HAVE_ARCH_STACKLEAK | |
@@ -242,6 +244,7 @@ config X86 | |
select PCI_DOMAINS if PCI | |
select PCI_LOCKLESS_CONFIG if PCI | |
select PERF_EVENTS | |
+ select ARCH_SUPPORTS_GCC_LTO | |
select RTC_LIB | |
select RTC_MC146818_LIB | |
select SPARSE_IRQ | |
diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c | |
index 81fc1eaa3..05aa7a05e 100644 | |
--- a/arch/x86/boot/compressed/string.c | |
+++ b/arch/x86/boot/compressed/string.c | |
@@ -50,7 +50,7 @@ void *memset(void *s, int c, size_t n) | |
return s; | |
} | |
-void *memmove(void *dest, const void *src, size_t n) | |
+__visible __used void *memmove(void *dest, const void *src, size_t n) | |
{ | |
unsigned char *d = dest; | |
const unsigned char *s = src; | |
@@ -65,7 +65,7 @@ void *memmove(void *dest, const void *src, size_t n) | |
} | |
/* Detect and warn about potential overlaps, but handle them with memmove. */ | |
-void *memcpy(void *dest, const void *src, size_t n) | |
+__visible __used void *memcpy(void *dest, const void *src, size_t n) | |
{ | |
if (dest > src && dest - src < n) { | |
warn("Avoiding potentially unsafe overlapping memcpy()!"); | |
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile | |
index 05c4abc2f..35dad9437 100644 | |
--- a/arch/x86/entry/vdso/Makefile | |
+++ b/arch/x86/entry/vdso/Makefile | |
@@ -3,6 +3,8 @@ | |
# Building vDSO images for x86. | |
# | |
+KBUILD_CFLAGS += $(DISABLE_LTO_GCC) | |
+ | |
# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before | |
# the inclusion of generic Makefile. | |
ARCH_REL_TYPE_ABS := R_X86_64_JUMP_SLOT|R_X86_64_GLOB_DAT|R_X86_64_RELATIVE| | |
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h | |
index f8cb8af4d..903ad9011 100644 | |
--- a/arch/x86/include/asm/preempt.h | |
+++ b/arch/x86/include/asm/preempt.h | |
@@ -106,12 +106,12 @@ static __always_inline bool should_resched(int preempt_offset) | |
#ifdef CONFIG_PREEMPTION | |
extern asmlinkage void preempt_schedule(void); | |
-extern asmlinkage void preempt_schedule_thunk(void); | |
+extern __visible asmlinkage void preempt_schedule_thunk(void); | |
#define __preempt_schedule_func preempt_schedule_thunk | |
extern asmlinkage void preempt_schedule_notrace(void); | |
-extern asmlinkage void preempt_schedule_notrace_thunk(void); | |
+extern __visible asmlinkage void preempt_schedule_notrace_thunk(void); | |
#define __preempt_schedule_notrace_func preempt_schedule_notrace_thunk | |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c | |
index 8d778e467..e1c52f7d4 100644 | |
--- a/arch/x86/kernel/alternative.c | |
+++ b/arch/x86/kernel/alternative.c | |
@@ -634,11 +634,12 @@ extern struct paravirt_patch_site __start_parainstructions[], | |
* convention such that we can 'call' it from assembly. | |
*/ | |
-extern void int3_magic(unsigned int *ptr); /* defined in asm */ | |
+extern __visible void int3_magic(unsigned int *ptr); /* defined in asm */ | |
asm ( | |
" .pushsection .init.text, \"ax\", @progbits\n" | |
" .type int3_magic, @function\n" | |
+" .globl int3_magic\n" | |
"int3_magic:\n" | |
" movl $1, (%" _ASM_ARG1 ")\n" | |
" ret\n" | |
@@ -646,7 +647,7 @@ asm ( | |
" .popsection\n" | |
); | |
-extern __initdata unsigned long int3_selftest_ip; /* defined in asm below */ | |
+extern __initdata __visible unsigned long int3_selftest_ip; /* defined in asm below */ | |
static int __init | |
int3_exception_notify(struct notifier_block *self, unsigned long val, void *data) | |
@@ -687,6 +688,7 @@ static void __init int3_selftest(void) | |
asm volatile ("1: int3; nop; nop; nop; nop\n\t" | |
".pushsection .init.data,\"aw\"\n\t" | |
".align " __ASM_SEL(4, 8) "\n\t" | |
+ ".globl int3_selftest_ip\n\t" | |
".type int3_selftest_ip, @object\n\t" | |
".size int3_selftest_ip, " __ASM_SEL(4, 8) "\n\t" | |
"int3_selftest_ip:\n\t" | |
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c | |
index 7ac31210e..4327792a2 100644 | |
--- a/arch/x86/kernel/cpu/resctrl/monitor.c | |
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c | |
@@ -84,7 +84,7 @@ unsigned int resctrl_cqm_threshold; | |
static const struct mbm_correction_factor_table { | |
u32 rmidthreshold; | |
u64 cf; | |
-} mbm_cf_table[] __initdata = { | |
+} mbm_cf_table[] __initconst = { | |
{7, CF(1.000000)}, | |
{15, CF(1.000000)}, | |
{15, CF(0.969650)}, | |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c | |
index 5e9a34b5b..ff61a45fc 100644 | |
--- a/arch/x86/kernel/module.c | |
+++ b/arch/x86/kernel/module.c | |
@@ -218,6 +218,11 @@ overflow: | |
return -ENOEXEC; | |
} | |
+static void *copy_write(void *dest, const void *src, size_t len) | |
+{ | |
+ return memcpy(dest, src, len); | |
+} | |
+ | |
int apply_relocate_add(Elf64_Shdr *sechdrs, | |
const char *strtab, | |
unsigned int symindex, | |
@@ -226,7 +231,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |
{ | |
int ret; | |
bool early = me->state == MODULE_STATE_UNFORMED; | |
- void *(*write)(void *, const void *, size_t) = memcpy; | |
+ void *(*write)(void *, const void *, size_t) = copy_write; | |
if (!early) { | |
write = text_poke; | |
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c | |
index e565d1c90..3435cd754 100644 | |
--- a/arch/x86/lib/memcpy_32.c | |
+++ b/arch/x86/lib/memcpy_32.c | |
@@ -5,7 +5,7 @@ | |
#undef memcpy | |
#undef memset | |
-__visible void *memcpy(void *to, const void *from, size_t n) | |
+__used __visible void *memcpy(void *to, const void *from, size_t n) | |
{ | |
#if defined(CONFIG_X86_USE_3DNOW) && !defined(CONFIG_FORTIFY_SOURCE) | |
return __memcpy3d(to, from, n); | |
@@ -15,13 +15,13 @@ __visible void *memcpy(void *to, const void *from, size_t n) | |
} | |
EXPORT_SYMBOL(memcpy); | |
-__visible void *memset(void *s, int c, size_t count) | |
+__used __visible void *memset(void *s, int c, size_t count) | |
{ | |
return __memset(s, c, count); | |
} | |
EXPORT_SYMBOL(memset); | |
-__visible void *memmove(void *dest, const void *src, size_t n) | |
+__used __visible void *memmove(void *dest, const void *src, size_t n) | |
{ | |
int d0,d1,d2,d3,d4,d5; | |
char *ret = dest; | |
diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c | |
index 75a0915b0..40bbe56bd 100644 | |
--- a/arch/x86/lib/msr-smp.c | |
+++ b/arch/x86/lib/msr-smp.c | |
@@ -252,7 +252,7 @@ static void __wrmsr_safe_regs_on_cpu(void *info) | |
rv->err = wrmsr_safe_regs(rv->regs); | |
} | |
-int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | |
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) | |
{ | |
int err; | |
struct msr_regs_info rv; | |
@@ -265,7 +265,7 @@ int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | |
} | |
EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu); | |
-int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | |
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) | |
{ | |
int err; | |
struct msr_regs_info rv; | |
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile | |
index 95ea17a9d..e3b04a62d 100644 | |
--- a/arch/x86/purgatory/Makefile | |
+++ b/arch/x86/purgatory/Makefile | |
@@ -1,5 +1,6 @@ | |
# SPDX-License-Identifier: GPL-2.0 | |
OBJECT_FILES_NON_STANDARD := y | |
+KBUILD_CFLAGS += $(DISABLE_LTO_GCC) | |
purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string.o | |
diff --git a/arch/x86/realmode/Makefile b/arch/x86/realmode/Makefile | |
index 6b1f3a4ee..af8945f4b 100644 | |
--- a/arch/x86/realmode/Makefile | |
+++ b/arch/x86/realmode/Makefile | |
@@ -10,6 +10,7 @@ | |
# Sanitizer runtimes are unavailable and cannot be linked here. | |
KASAN_SANITIZE := n | |
KCSAN_SANITIZE := n | |
+#KBUILD_CFLAGS += $(DISABLE_LTO) | |
OBJECT_FILES_NON_STANDARD := y | |
subdir- := rm | |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | |
index 66bbca61e..e846844c8 100644 | |
--- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | |
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | |
@@ -330,8 +330,8 @@ int kfd_iommu_resume(struct kfd_dev *kfd) | |
} | |
extern bool amd_iommu_pc_supported(void); | |
-extern u8 amd_iommu_pc_get_max_banks(u16 devid); | |
-extern u8 amd_iommu_pc_get_max_counters(u16 devid); | |
+extern u8 amd_iommu_pc_get_max_banks(unsigned devid); | |
+extern u8 amd_iommu_pc_get_max_counters(unsigned devid); | |
/** kfd_iommu_add_perf_counters - Add IOMMU performance counters to topology | |
*/ | |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h | |
index cb62ddba2..c80add5f6 100644 | |
--- a/drivers/gpu/drm/i915/i915_drv.h | |
+++ b/drivers/gpu/drm/i915/i915_drv.h | |
@@ -1095,11 +1095,11 @@ struct drm_i915_private { | |
* in 0.5us units for WM1+. | |
*/ | |
/* primary */ | |
- u16 pri_latency[5]; | |
+ u16 pri_latency[8]; | |
/* sprite */ | |
- u16 spr_latency[5]; | |
+ u16 spr_latency[8]; | |
/* cursor */ | |
- u16 cur_latency[5]; | |
+ u16 cur_latency[8]; | |
/* | |
* Raw watermark memory latency values | |
* for SKL for all 8 levels | |
diff --git a/drivers/media/pci/cobalt/cobalt-i2c.c b/drivers/media/pci/cobalt/cobalt-i2c.c | |
index 10c9ee33f..ab8b7e31e 100644 | |
--- a/drivers/media/pci/cobalt/cobalt-i2c.c | |
+++ b/drivers/media/pci/cobalt/cobalt-i2c.c | |
@@ -302,7 +302,7 @@ static const struct i2c_algorithm cobalt_algo = { | |
}; | |
/* init + register i2c algo-bit adapter */ | |
-int cobalt_i2c_init(struct cobalt *cobalt) | |
+__no_fre int cobalt_i2c_init(struct cobalt *cobalt) | |
{ | |
int i, err; | |
int status; | |
diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c | |
index a83435245..ae775ab0b 100644 | |
--- a/drivers/media/pci/cx18/cx18-i2c.c | |
+++ b/drivers/media/pci/cx18/cx18-i2c.c | |
@@ -214,7 +214,7 @@ static const struct i2c_algo_bit_data cx18_i2c_algo_template = { | |
}; | |
/* init + register i2c adapter */ | |
-int init_cx18_i2c(struct cx18 *cx) | |
+__no_fre int init_cx18_i2c(struct cx18 *cx) | |
{ | |
int i, err; | |
CX18_DEBUG_I2C("i2c init\n"); | |
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c | |
index 186d88f02..371429d81 100644 | |
--- a/drivers/media/platform/sti/delta/delta-ipc.c | |
+++ b/drivers/media/platform/sti/delta/delta-ipc.c | |
@@ -175,8 +175,8 @@ int delta_ipc_open(struct delta_ctx *pctx, const char *name, | |
msg.ipc_buf_size = ipc_buf_size; | |
msg.ipc_buf_paddr = ctx->ipc_buf->paddr; | |
- memcpy(msg.name, name, sizeof(msg.name)); | |
- msg.name[sizeof(msg.name) - 1] = 0; | |
+ memset(msg.name, 0, sizeof(msg.name)); | |
+ strcpy(msg.name, name); | |
msg.param_size = param->size; | |
memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size); | |
diff --git a/drivers/xen/time.c b/drivers/xen/time.c | |
index 108edbcbc..fc7dd451b 100644 | |
--- a/drivers/xen/time.c | |
+++ b/drivers/xen/time.c | |
@@ -144,7 +144,7 @@ void xen_get_runstate_snapshot(struct vcpu_runstate_info *res) | |
} | |
/* return true when a vcpu could run but has no real cpu to run on */ | |
-bool xen_vcpu_stolen(int vcpu) | |
+__visible bool xen_vcpu_stolen(int vcpu) | |
{ | |
return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable; | |
} | |
diff --git a/fs/open.c b/fs/open.c | |
index e53af13b5..f15eec2d4 100644 | |
--- a/fs/open.c | |
+++ b/fs/open.c | |
@@ -66,7 +66,7 @@ int do_truncate(struct user_namespace *mnt_userns, struct dentry *dentry, | |
return ret; | |
} | |
-long vfs_truncate(const struct path *path, loff_t length) | |
+__visible long vfs_truncate(const struct path *path, loff_t length) | |
{ | |
struct user_namespace *mnt_userns; | |
struct inode *inode; | |
diff --git a/include/crypto/internal/poly1305.h b/include/crypto/internal/poly1305.h | |
index 064e52ca5..90ee36411 100644 | |
--- a/include/crypto/internal/poly1305.h | |
+++ b/include/crypto/internal/poly1305.h | |
@@ -18,7 +18,7 @@ | |
* only the ε-almost-∆-universal hash function (not the full MAC) is computed. | |
*/ | |
-void poly1305_core_setkey(struct poly1305_core_key *key, const u8 *raw_key); | |
+void poly1305_core_setkey(struct poly1305_core_key *key, const u8 raw_key[16]); | |
static inline void poly1305_core_init(struct poly1305_state *state) | |
{ | |
*state = (struct poly1305_state){}; | |
diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h | |
index 57890b357..7986c4284 100644 | |
--- a/include/linux/btf_ids.h | |
+++ b/include/linux/btf_ids.h | |
@@ -25,14 +25,13 @@ struct btf_id_set { | |
#define BTF_IDS_SECTION ".BTF_ids" | |
#define ____BTF_ID(symbol) \ | |
-asm( \ | |
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
-".local " #symbol " ; \n" \ | |
+".globl " #symbol " ; \n" \ | |
".type " #symbol ", STT_OBJECT; \n" \ | |
".size " #symbol ", 4; \n" \ | |
#symbol ": \n" \ | |
".zero 4 \n" \ | |
-".popsection; \n"); | |
+".popsection; \n" | |
#define __BTF_ID(symbol) \ | |
____BTF_ID(symbol) | |
@@ -47,6 +46,8 @@ asm( \ | |
#define BTF_ID(prefix, name) \ | |
__BTF_ID(__ID(__BTF_ID__##prefix##__##name##__)) | |
+#define BTF_ID_LIST_END ); | |
+ | |
/* | |
* The BTF_ID_LIST macro defines pure (unsorted) list | |
* of BTF IDs, with following layout: | |
@@ -67,11 +68,11 @@ asm( \ | |
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
"." #scope " " #name "; \n" \ | |
#name ":; \n" \ | |
-".popsection; \n"); | |
+".popsection; \n" | |
#define BTF_ID_LIST(name) \ | |
-__BTF_ID_LIST(name, local) \ | |
-extern u32 name[]; | |
+extern u32 name[]; \ | |
+__BTF_ID_LIST(name, globl) \ | |
#define BTF_ID_LIST_GLOBAL(name) \ | |
__BTF_ID_LIST(name, globl) | |
@@ -80,8 +81,9 @@ __BTF_ID_LIST(name, globl) | |
* a single entry. | |
*/ | |
#define BTF_ID_LIST_SINGLE(name, prefix, typename) \ | |
- BTF_ID_LIST(name) \ | |
- BTF_ID(prefix, typename) | |
+ BTF_ID_LIST(name) \ | |
+ BTF_ID(prefix, typename) \ | |
+ BTF_ID_LIST_END | |
/* | |
* The BTF_ID_UNUSED macro defines 4 zero bytes. | |
@@ -95,10 +97,9 @@ __BTF_ID_LIST(name, globl) | |
*/ | |
#define BTF_ID_UNUSED \ | |
-asm( \ | |
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
".zero 4 \n" \ | |
-".popsection; \n"); | |
+".popsection; \n" | |
/* | |
* The BTF_SET_START/END macros pair defines sorted list of | |
@@ -119,15 +120,14 @@ asm( \ | |
* | |
*/ | |
#define __BTF_SET_START(name, scope) \ | |
-asm( \ | |
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
"." #scope " __BTF_ID__set__" #name "; \n" \ | |
"__BTF_ID__set__" #name ":; \n" \ | |
".zero 4 \n" \ | |
-".popsection; \n"); | |
+".popsection; \n" | |
#define BTF_SET_START(name) \ | |
-__BTF_ID_LIST(name, local) \ | |
+__BTF_ID_LIST(name, globl) \ | |
__BTF_SET_START(name, local) | |
#define BTF_SET_START_GLOBAL(name) \ | |
@@ -135,7 +135,6 @@ __BTF_ID_LIST(name, globl) \ | |
__BTF_SET_START(name, globl) | |
#define BTF_SET_END(name) \ | |
-asm( \ | |
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ | |
".size __BTF_ID__set__" #name ", .-" #name " \n" \ | |
".popsection; \n"); \ | |
@@ -148,6 +147,7 @@ extern struct btf_id_set name; | |
#define BTF_ID_UNUSED | |
#define BTF_ID_LIST_GLOBAL(name) u32 name[1]; | |
#define BTF_ID_LIST_SINGLE(name, prefix, typename) static u32 name[1]; | |
+#define BTF_ID_LIST_END | |
#define BTF_SET_START(name) static struct btf_id_set name = { 0 }; | |
#define BTF_SET_START_GLOBAL(name) static struct btf_id_set name = { 0 }; | |
#define BTF_SET_END(name) | |
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h | |
index c043b8d2b..48a004dea 100644 | |
--- a/include/linux/compiler_attributes.h | |
+++ b/include/linux/compiler_attributes.h | |
@@ -34,6 +34,7 @@ | |
# define __GCC4_has_attribute___no_caller_saved_registers__ 0 | |
# define __GCC4_has_attribute___noclone__ 1 | |
# define __GCC4_has_attribute___nonstring__ 0 | |
+# define __GCC4_has_attribute___no_reorder__ 0 | |
# define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) | |
# define __GCC4_has_attribute___no_sanitize_undefined__ (__GNUC_MINOR__ >= 9) | |
# define __GCC4_has_attribute___fallthrough__ 0 | |
@@ -214,7 +215,12 @@ | |
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes | |
* clang: https://clang.llvm.org/docs/AttributeReference.html#flatten | |
*/ | |
+#ifndef CONFIG_LTO_GCC | |
# define __flatten __attribute__((flatten)) | |
+#else | |
+/* Causes very large memory use with gcc 10 in LTO mode */ | |
+# define __flatten | |
+#endif | |
/* | |
* Note the missing underscores. | |
@@ -290,4 +296,14 @@ | |
*/ | |
#define __weak __attribute__((__weak__)) | |
+/* | |
+ * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes | |
+ */ | |
+ | |
+#if __has_attribute(__no_reorder__) | |
+#define __noreorder __attribute__((no_reorder)) | |
+#else | |
+#define __noreorder | |
+#endif | |
+ | |
#endif /* __LINUX_COMPILER_ATTRIBUTES_H */ | |
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h | |
index e5dd5a4ae..bac3c526f 100644 | |
--- a/include/linux/compiler_types.h | |
+++ b/include/linux/compiler_types.h | |
@@ -252,6 +252,16 @@ struct ftrace_likely_data { | |
#define asm_inline asm | |
#endif | |
+/* | |
+ * Work around compiler crash in some gcc versions by disabling | |
+ * FRE pass for a function. | |
+ */ | |
+#ifdef CONFIG_CC_NEEDS_FRE_WA | |
+#define __no_fre __attribute__((optimize("-fno-tree-fre"))) | |
+#else | |
+#define __no_fre | |
+#endif | |
+ | |
/* Are two types/vars the same type (ignoring qualifiers)? */ | |
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) | |
diff --git a/include/linux/export.h b/include/linux/export.h | |
index 6271a5d9c..2ebd8c84d 100644 | |
--- a/include/linux/export.h | |
+++ b/include/linux/export.h | |
@@ -96,12 +96,14 @@ struct kernel_symbol { | |
*/ | |
#define ___EXPORT_SYMBOL(sym, sec, ns) \ | |
extern typeof(sym) sym; \ | |
- extern const char __kstrtab_##sym[]; \ | |
- extern const char __kstrtabns_##sym[]; \ | |
+ extern const char __visible __kstrtab_##sym[]; \ | |
+ extern const char __visible __kstrtabns_##sym[]; \ | |
__CRC_SYMBOL(sym, sec); \ | |
asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ | |
+ " .globl __kstrtab_" #sym " \n" \ | |
"__kstrtab_" #sym ": \n" \ | |
" .asciz \"" #sym "\" \n" \ | |
+ " .globl __kstrtabns_" #sym " \n" \ | |
"__kstrtabns_" #sym ": \n" \ | |
" .asciz \"" ns "\" \n" \ | |
" .previous \n"); \ | |
diff --git a/include/linux/init.h b/include/linux/init.h | |
index 31f54de58..4223047df 100644 | |
--- a/include/linux/init.h | |
+++ b/include/linux/init.h | |
@@ -245,7 +245,7 @@ extern bool initcall_debug; | |
".previous \n"); | |
#else | |
#define ____define_initcall(fn, __unused, __name, __sec) \ | |
- static initcall_t __name __used \ | |
+ static initcall_t __name __used __noreorder \ | |
__attribute__((__section__(__sec))) = fn; | |
#endif | |
diff --git a/include/linux/linkage.h b/include/linux/linkage.h | |
index dbf8506de..645e5a73b 100644 | |
--- a/include/linux/linkage.h | |
+++ b/include/linux/linkage.h | |
@@ -23,17 +23,17 @@ | |
#endif | |
#ifndef cond_syscall | |
-#define cond_syscall(x) asm( \ | |
- ".weak " __stringify(x) "\n\t" \ | |
- ".set " __stringify(x) "," \ | |
- __stringify(sys_ni_syscall)) | |
+#define cond_syscall(x) \ | |
+ extern long x(void) __attribute__((alias("sys_ni_syscall"), weak)); | |
#endif | |
#ifndef SYSCALL_ALIAS | |
-#define SYSCALL_ALIAS(alias, name) asm( \ | |
- ".globl " __stringify(alias) "\n\t" \ | |
- ".set " __stringify(alias) "," \ | |
- __stringify(name)) | |
+#define SYSCALL_ALIAS(a, name) \ | |
+ long a(void) __attribute__((alias(__stringify(name)))) | |
+#define SYSCALL_ALIAS_PROTO(a, name) \ | |
+ typeof(a) a __attribute__((alias(__stringify(name)))) | |
+#else | |
+#define SYSCALL_ALIAS_PROTO(a, name) SYSCALL_ALIAS(a, name) | |
#endif | |
#define __page_aligned_data __section(".data..page_aligned") __aligned(PAGE_SIZE) | |
diff --git a/include/linux/static_call.h b/include/linux/static_call.h | |
index 85ecc789f..e75aef659 100644 | |
--- a/include/linux/static_call.h | |
+++ b/include/linux/static_call.h | |
@@ -100,6 +100,8 @@ | |
#ifdef CONFIG_HAVE_STATIC_CALL | |
#include <asm/static_call.h> | |
+extern long __static_call_return0(void); | |
+ | |
/* | |
* Either @site or @tramp can be NULL. | |
*/ | |
@@ -148,11 +150,9 @@ extern void __static_call_update(struct static_call_key *key, void *tramp, void | |
extern int static_call_mod_init(struct module *mod); | |
extern int static_call_text_reserved(void *start, void *end); | |
-extern long __static_call_return0(void); | |
- | |
#define __DEFINE_STATIC_CALL(name, _func, _func_init) \ | |
DECLARE_STATIC_CALL(name, _func); \ | |
- struct static_call_key STATIC_CALL_KEY(name) = { \ | |
+ __visible struct static_call_key STATIC_CALL_KEY(name) = { \ | |
.func = _func_init, \ | |
.type = 1, \ | |
}; \ | |
@@ -160,7 +160,7 @@ extern long __static_call_return0(void); | |
#define DEFINE_STATIC_CALL_NULL(name, _func) \ | |
DECLARE_STATIC_CALL(name, _func); \ | |
- struct static_call_key STATIC_CALL_KEY(name) = { \ | |
+ __visible struct static_call_key STATIC_CALL_KEY(name) = { \ | |
.func = NULL, \ | |
.type = 1, \ | |
}; \ | |
@@ -193,14 +193,14 @@ struct static_call_key { | |
#define __DEFINE_STATIC_CALL(name, _func, _func_init) \ | |
DECLARE_STATIC_CALL(name, _func); \ | |
- struct static_call_key STATIC_CALL_KEY(name) = { \ | |
+ __visible struct static_call_key STATIC_CALL_KEY(name) = { \ | |
.func = _func_init, \ | |
}; \ | |
ARCH_DEFINE_STATIC_CALL_TRAMP(name, _func_init) | |
#define DEFINE_STATIC_CALL_NULL(name, _func) \ | |
DECLARE_STATIC_CALL(name, _func); \ | |
- struct static_call_key STATIC_CALL_KEY(name) = { \ | |
+ __visible struct static_call_key STATIC_CALL_KEY(name) = { \ | |
.func = NULL, \ | |
}; \ | |
ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) | |
@@ -221,11 +221,6 @@ static inline int static_call_text_reserved(void *start, void *end) | |
return 0; | |
} | |
-static inline long __static_call_return0(void) | |
-{ | |
- return 0; | |
-} | |
- | |
#define EXPORT_STATIC_CALL(name) \ | |
EXPORT_SYMBOL(STATIC_CALL_KEY(name)); \ | |
EXPORT_SYMBOL(STATIC_CALL_TRAMP(name)) | |
@@ -254,13 +249,13 @@ static inline long __static_call_return0(void) | |
#define __DEFINE_STATIC_CALL(name, _func, _func_init) \ | |
DECLARE_STATIC_CALL(name, _func); \ | |
- struct static_call_key STATIC_CALL_KEY(name) = { \ | |
+ __visible struct static_call_key STATIC_CALL_KEY(name) = { \ | |
.func = _func_init, \ | |
} | |
#define DEFINE_STATIC_CALL_NULL(name, _func) \ | |
DECLARE_STATIC_CALL(name, _func); \ | |
- struct static_call_key STATIC_CALL_KEY(name) = { \ | |
+ __visible struct static_call_key STATIC_CALL_KEY(name) = { \ | |
.func = NULL, \ | |
} | |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h | |
index 9cfb099da..00ca51b38 100644 | |
--- a/include/linux/tracepoint.h | |
+++ b/include/linux/tracepoint.h | |
@@ -229,7 +229,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) | |
* poking RCU a bit. | |
*/ | |
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ | |
- extern int __traceiter_##name(data_proto); \ | |
+ extern int __visible __traceiter_##name(data_proto); \ | |
DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \ | |
extern struct tracepoint __tracepoint_##name; \ | |
static inline void trace_##name(proto) \ | |
@@ -296,7 +296,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) | |
.unregfunc = _unreg, \ | |
.funcs = NULL }; \ | |
__TRACEPOINT_ENTRY(_name); \ | |
- int __traceiter_##_name(void *__data, proto) \ | |
+ __visible int __traceiter_##_name(void *__data, proto) \ | |
{ \ | |
struct tracepoint_func *it_func_ptr; \ | |
void *it_func; \ | |
diff --git a/init/Kconfig b/init/Kconfig | |
index 5f5c776ef..696212271 100644 | |
--- a/init/Kconfig | |
+++ b/init/Kconfig | |
@@ -1339,6 +1339,12 @@ config HAVE_LD_DEAD_CODE_DATA_ELIMINATION | |
sections (e.g., '.text.init'). Typically '.' in section names | |
is used to distinguish them from label names / C identifiers. | |
+config CC_NEEDS_FRE_WA | |
+ bool | |
+ help | |
+ Disable FRE compiler pass in some functions to work around | |
+ gcc segfault. | |
+ | |
config LD_DEAD_CODE_DATA_ELIMINATION | |
bool "Dead code and data elimination (EXPERIMENTAL)" | |
depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION | |
diff --git a/kernel/Makefile b/kernel/Makefile | |
index 605ec3e70..4071dbad2 100644 | |
--- a/kernel/Makefile | |
+++ b/kernel/Makefile | |
@@ -110,7 +110,7 @@ obj-$(CONFIG_CPU_PM) += cpu_pm.o | |
obj-$(CONFIG_BPF) += bpf/ | |
obj-$(CONFIG_KCSAN) += kcsan/ | |
obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o | |
-obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call.o | |
+obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o | |
obj-$(CONFIG_PERF_EVENTS) += events/ | |
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c | |
index b1a76fe04..4e79f6989 100644 | |
--- a/kernel/bpf/btf.c | |
+++ b/kernel/bpf/btf.c | |
@@ -4407,6 +4407,7 @@ static int btf_translate_to_vmlinux(struct bpf_verifier_log *log, | |
BTF_ID_LIST(bpf_ctx_convert_btf_id) | |
BTF_ID(struct, bpf_ctx_convert) | |
+BTF_ID_LIST_END | |
struct btf *btf_parse_vmlinux(void) | |
{ | |
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c | |
index 75244ecb2..1b89e0ece 100644 | |
--- a/kernel/bpf/core.c | |
+++ b/kernel/bpf/core.c | |
@@ -1373,7 +1373,7 @@ u64 __weak bpf_probe_read_kernel(void *dst, u32 size, const void *unsafe_ptr) | |
* | |
* Decode and execute eBPF instructions. | |
*/ | |
-static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack) | |
+static u64 __noreorder ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack) | |
{ | |
#define BPF_INSN_2_LBL(x, y) [BPF_##x | BPF_##y] = &&x##_##y | |
#define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z | |
diff --git a/kernel/bpf/map_iter.c b/kernel/bpf/map_iter.c | |
index 6a9542af4..548180dc4 100644 | |
--- a/kernel/bpf/map_iter.c | |
+++ b/kernel/bpf/map_iter.c | |
@@ -80,6 +80,7 @@ static const struct seq_operations bpf_map_seq_ops = { | |
BTF_ID_LIST(btf_bpf_map_id) | |
BTF_ID(struct, bpf_map) | |
+BTF_ID_LIST_END | |
static const struct bpf_iter_seq_info bpf_map_seq_info = { | |
.seq_ops = &bpf_map_seq_ops, | |
diff --git a/kernel/bpf/prog_iter.c b/kernel/bpf/prog_iter.c | |
index 53a73c841..f9ea2dc32 100644 | |
--- a/kernel/bpf/prog_iter.c | |
+++ b/kernel/bpf/prog_iter.c | |
@@ -80,6 +80,7 @@ static const struct seq_operations bpf_prog_seq_ops = { | |
BTF_ID_LIST(btf_bpf_prog_id) | |
BTF_ID(struct, bpf_prog) | |
+BTF_ID_LIST_END | |
static const struct bpf_iter_seq_info bpf_prog_seq_info = { | |
.seq_ops = &bpf_prog_seq_ops, | |
diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c | |
index b68cb5d6d..99cc112d6 100644 | |
--- a/kernel/bpf/task_iter.c | |
+++ b/kernel/bpf/task_iter.c | |
@@ -528,6 +528,7 @@ BTF_ID_LIST(btf_task_file_ids) | |
BTF_ID(struct, task_struct) | |
BTF_ID(struct, file) | |
BTF_ID(struct, vm_area_struct) | |
+BTF_ID_LIST_END | |
static const struct bpf_iter_seq_info task_seq_info = { | |
.seq_ops = &task_seq_ops, | |
diff --git a/kernel/livepatch/Kconfig b/kernel/livepatch/Kconfig | |
index 53d51ed61..8c004f211 100644 | |
--- a/kernel/livepatch/Kconfig | |
+++ b/kernel/livepatch/Kconfig | |
@@ -12,6 +12,7 @@ config LIVEPATCH | |
depends on KALLSYMS_ALL | |
depends on HAVE_LIVEPATCH | |
depends on !TRIM_UNUSED_KSYMS | |
+ depends on !LTO_GCC # not supported in gcc 10 | |
help | |
Say Y here if you want to support kernel live patching. | |
This option has no runtime impact until a kernel "patch" | |
diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c | |
index 0ff08380f..f2b65270e 100644 | |
--- a/kernel/locking/spinlock.c | |
+++ b/kernel/locking/spinlock.c | |
@@ -130,7 +130,7 @@ BUILD_LOCK_OPS(write, rwlock); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_TRYLOCK | |
-int __lockfunc _raw_spin_trylock(raw_spinlock_t *lock) | |
+noinline int __lockfunc _raw_spin_trylock(raw_spinlock_t *lock) | |
{ | |
return __raw_spin_trylock(lock); | |
} | |
@@ -138,7 +138,7 @@ EXPORT_SYMBOL(_raw_spin_trylock); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH | |
-int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock) | |
+noinline int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock) | |
{ | |
return __raw_spin_trylock_bh(lock); | |
} | |
@@ -146,7 +146,7 @@ EXPORT_SYMBOL(_raw_spin_trylock_bh); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_LOCK | |
-void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) | |
+noinline void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) | |
{ | |
__raw_spin_lock(lock); | |
} | |
@@ -154,7 +154,7 @@ EXPORT_SYMBOL(_raw_spin_lock); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE | |
-unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) | |
+noinline unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) | |
{ | |
return __raw_spin_lock_irqsave(lock); | |
} | |
@@ -162,7 +162,7 @@ EXPORT_SYMBOL(_raw_spin_lock_irqsave); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_LOCK_IRQ | |
-void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) | |
+noinline void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) | |
{ | |
__raw_spin_lock_irq(lock); | |
} | |
@@ -170,7 +170,7 @@ EXPORT_SYMBOL(_raw_spin_lock_irq); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_LOCK_BH | |
-void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) | |
+noinline void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) | |
{ | |
__raw_spin_lock_bh(lock); | |
} | |
@@ -178,7 +178,7 @@ EXPORT_SYMBOL(_raw_spin_lock_bh); | |
#endif | |
#ifdef CONFIG_UNINLINE_SPIN_UNLOCK | |
-void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) | |
+noinline void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) | |
{ | |
__raw_spin_unlock(lock); | |
} | |
@@ -186,7 +186,7 @@ EXPORT_SYMBOL(_raw_spin_unlock); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE | |
-void __lockfunc _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) | |
+noinline void __lockfunc _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) | |
{ | |
__raw_spin_unlock_irqrestore(lock, flags); | |
} | |
@@ -194,7 +194,7 @@ EXPORT_SYMBOL(_raw_spin_unlock_irqrestore); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ | |
-void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) | |
+noinline void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) | |
{ | |
__raw_spin_unlock_irq(lock); | |
} | |
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(_raw_spin_unlock_irq); | |
#endif | |
#ifndef CONFIG_INLINE_SPIN_UNLOCK_BH | |
-void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) | |
+noinline void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) | |
{ | |
__raw_spin_unlock_bh(lock); | |
} | |
@@ -210,7 +210,7 @@ EXPORT_SYMBOL(_raw_spin_unlock_bh); | |
#endif | |
#ifndef CONFIG_INLINE_READ_TRYLOCK | |
-int __lockfunc _raw_read_trylock(rwlock_t *lock) | |
+noinline int __lockfunc _raw_read_trylock(rwlock_t *lock) | |
{ | |
return __raw_read_trylock(lock); | |
} | |
@@ -218,7 +218,7 @@ EXPORT_SYMBOL(_raw_read_trylock); | |
#endif | |
#ifndef CONFIG_INLINE_READ_LOCK | |
-void __lockfunc _raw_read_lock(rwlock_t *lock) | |
+noinline void __lockfunc _raw_read_lock(rwlock_t *lock) | |
{ | |
__raw_read_lock(lock); | |
} | |
@@ -226,7 +226,7 @@ EXPORT_SYMBOL(_raw_read_lock); | |
#endif | |
#ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE | |
-unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) | |
+noinline unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) | |
{ | |
return __raw_read_lock_irqsave(lock); | |
} | |
@@ -234,7 +234,7 @@ EXPORT_SYMBOL(_raw_read_lock_irqsave); | |
#endif | |
#ifndef CONFIG_INLINE_READ_LOCK_IRQ | |
-void __lockfunc _raw_read_lock_irq(rwlock_t *lock) | |
+noinline void __lockfunc _raw_read_lock_irq(rwlock_t *lock) | |
{ | |
__raw_read_lock_irq(lock); | |
} | |
@@ -242,7 +242,7 @@ EXPORT_SYMBOL(_raw_read_lock_irq); | |
#endif | |
#ifndef CONFIG_INLINE_READ_LOCK_BH | |
-void __lockfunc _raw_read_lock_bh(rwlock_t *lock) | |
+noinline void __lockfunc _raw_read_lock_bh(rwlock_t *lock) | |
{ | |
__raw_read_lock_bh(lock); | |
} | |
@@ -250,7 +250,7 @@ EXPORT_SYMBOL(_raw_read_lock_bh); | |
#endif | |
#ifndef CONFIG_INLINE_READ_UNLOCK | |
-void __lockfunc _raw_read_unlock(rwlock_t *lock) | |
+noinline void __lockfunc _raw_read_unlock(rwlock_t *lock) | |
{ | |
__raw_read_unlock(lock); | |
} | |
@@ -258,7 +258,7 @@ EXPORT_SYMBOL(_raw_read_unlock); | |
#endif | |
#ifndef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE | |
-void __lockfunc _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
+noinline void __lockfunc _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
{ | |
__raw_read_unlock_irqrestore(lock, flags); | |
} | |
@@ -266,7 +266,7 @@ EXPORT_SYMBOL(_raw_read_unlock_irqrestore); | |
#endif | |
#ifndef CONFIG_INLINE_READ_UNLOCK_IRQ | |
-void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) | |
+noinline void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) | |
{ | |
__raw_read_unlock_irq(lock); | |
} | |
@@ -274,7 +274,7 @@ EXPORT_SYMBOL(_raw_read_unlock_irq); | |
#endif | |
#ifndef CONFIG_INLINE_READ_UNLOCK_BH | |
-void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) | |
+noinline void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) | |
{ | |
__raw_read_unlock_bh(lock); | |
} | |
@@ -282,7 +282,7 @@ EXPORT_SYMBOL(_raw_read_unlock_bh); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_TRYLOCK | |
-int __lockfunc _raw_write_trylock(rwlock_t *lock) | |
+noinline int __lockfunc _raw_write_trylock(rwlock_t *lock) | |
{ | |
return __raw_write_trylock(lock); | |
} | |
@@ -290,7 +290,7 @@ EXPORT_SYMBOL(_raw_write_trylock); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_LOCK | |
-void __lockfunc _raw_write_lock(rwlock_t *lock) | |
+noinline void __lockfunc _raw_write_lock(rwlock_t *lock) | |
{ | |
__raw_write_lock(lock); | |
} | |
@@ -298,7 +298,7 @@ EXPORT_SYMBOL(_raw_write_lock); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE | |
-unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) | |
+noinline unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) | |
{ | |
return __raw_write_lock_irqsave(lock); | |
} | |
@@ -306,7 +306,7 @@ EXPORT_SYMBOL(_raw_write_lock_irqsave); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_LOCK_IRQ | |
-void __lockfunc _raw_write_lock_irq(rwlock_t *lock) | |
+noinline void __lockfunc _raw_write_lock_irq(rwlock_t *lock) | |
{ | |
__raw_write_lock_irq(lock); | |
} | |
@@ -314,7 +314,7 @@ EXPORT_SYMBOL(_raw_write_lock_irq); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_LOCK_BH | |
-void __lockfunc _raw_write_lock_bh(rwlock_t *lock) | |
+noinline void __lockfunc _raw_write_lock_bh(rwlock_t *lock) | |
{ | |
__raw_write_lock_bh(lock); | |
} | |
@@ -322,7 +322,7 @@ EXPORT_SYMBOL(_raw_write_lock_bh); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_UNLOCK | |
-void __lockfunc _raw_write_unlock(rwlock_t *lock) | |
+noinline void __lockfunc _raw_write_unlock(rwlock_t *lock) | |
{ | |
__raw_write_unlock(lock); | |
} | |
@@ -330,7 +330,7 @@ EXPORT_SYMBOL(_raw_write_unlock); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE | |
-void __lockfunc _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
+noinline void __lockfunc _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
{ | |
__raw_write_unlock_irqrestore(lock, flags); | |
} | |
@@ -338,7 +338,7 @@ EXPORT_SYMBOL(_raw_write_unlock_irqrestore); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQ | |
-void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) | |
+noinline void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) | |
{ | |
__raw_write_unlock_irq(lock); | |
} | |
@@ -346,7 +346,7 @@ EXPORT_SYMBOL(_raw_write_unlock_irq); | |
#endif | |
#ifndef CONFIG_INLINE_WRITE_UNLOCK_BH | |
-void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) | |
+noinline void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) | |
{ | |
__raw_write_unlock_bh(lock); | |
} | |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c | |
index 98191218d..272a654f5 100644 | |
--- a/kernel/sched/core.c | |
+++ b/kernel/sched/core.c | |
@@ -8086,12 +8086,20 @@ void __init sched_init(void) | |
unsigned long ptr = 0; | |
int i; | |
- /* Make sure the linker didn't screw up */ | |
- BUG_ON(&idle_sched_class + 1 != &fair_sched_class || | |
- &fair_sched_class + 1 != &rt_sched_class || | |
- &rt_sched_class + 1 != &dl_sched_class); | |
+ /* | |
+ * Make sure the linker didn't screw up. | |
+ * We have to use RELOC_HIDE to prevent gcc from optimizing | |
+ * them to true because they're technically undefined in ISO-C. | |
+ */ | |
+ BUG_ON(RELOC_HIDE(&idle_sched_class, 0) + 1 != | |
+ RELOC_HIDE(&fair_sched_class, 0)); | |
+ BUG_ON(RELOC_HIDE(&fair_sched_class, 0) + 1 != | |
+ RELOC_HIDE(&rt_sched_class, 0)); | |
+ BUG_ON(RELOC_HIDE(&rt_sched_class, 0) + 1 != | |
+ RELOC_HIDE(&dl_sched_class, 0)); | |
#ifdef CONFIG_SMP | |
- BUG_ON(&dl_sched_class + 1 != &stop_sched_class); | |
+ BUG_ON(RELOC_HIDE(&dl_sched_class, 0) + 1 != | |
+ RELOC_HIDE(&stop_sched_class, 0)); | |
#endif | |
wait_bit_init(); | |
diff --git a/kernel/softirq.c b/kernel/softirq.c | |
index 9908ec4a9..462c8f6b8 100644 | |
--- a/kernel/softirq.c | |
+++ b/kernel/softirq.c | |
@@ -429,7 +429,7 @@ static inline void __irq_exit_rcu(void) | |
* | |
* Also processes softirqs if needed and possible. | |
*/ | |
-void irq_exit_rcu(void) | |
+__visible void irq_exit_rcu(void) | |
{ | |
__irq_exit_rcu(); | |
/* must be last! */ | |
diff --git a/kernel/static_call.c b/kernel/static_call.c | |
index 2c5950b0b..f22836e22 100644 | |
--- a/kernel/static_call.c | |
+++ b/kernel/static_call.c | |
@@ -10,6 +10,8 @@ | |
#include <linux/processor.h> | |
#include <asm/sections.h> | |
+#ifdef CONFIG_HAVE_STATIC_CALL_INLINE | |
+ | |
extern struct static_call_site __start_static_call_sites[], | |
__stop_static_call_sites[]; | |
extern struct static_call_tramp_key __start_static_call_tramp_key[], | |
@@ -496,14 +498,18 @@ int __init static_call_init(void) | |
} | |
early_initcall(static_call_init); | |
-long __static_call_return0(void) | |
+#endif /* HAVE_STATIC_CALL_INLINE */ | |
+ | |
+__visible long __static_call_return0(void) | |
{ | |
return 0; | |
} | |
#ifdef CONFIG_STATIC_CALL_SELFTEST | |
-static int func_a(int x) | |
+int __visible sc_func_a(int x); /* Avoid warning */ | |
+ | |
+int __visible sc_func_a(int x) | |
{ | |
return x+1; | |
} | |
@@ -513,7 +519,7 @@ static int func_b(int x) | |
return x+2; | |
} | |
-DEFINE_STATIC_CALL(sc_selftest, func_a); | |
+DEFINE_STATIC_CALL(sc_selftest, sc_func_a); | |
static struct static_call_data { | |
int (*func)(int); | |
@@ -522,7 +528,7 @@ static struct static_call_data { | |
} static_call_data [] __initdata = { | |
{ NULL, 2, 3 }, | |
{ func_b, 2, 4 }, | |
- { func_a, 2, 3 } | |
+ { sc_func_a, 2, 3 } | |
}; | |
static int __init test_static_call_init(void) | |
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c | |
index fcb3b21d8..24fafe778 100644 | |
--- a/kernel/time/posix-stubs.c | |
+++ b/kernel/time/posix-stubs.c | |
@@ -31,7 +31,7 @@ asmlinkage long sys_ni_posix_timers(void) | |
} | |
#ifndef SYS_NI | |
-#define SYS_NI(name) SYSCALL_ALIAS(sys_##name, sys_ni_posix_timers) | |
+#define SYS_NI(name) SYSCALL_ALIAS_PROTO(sys_##name, sys_ni_posix_timers) | |
#endif | |
#ifndef COMPAT_SYS_NI | |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug | |
index 417c3d3e5..bfc9959f4 100644 | |
--- a/lib/Kconfig.debug | |
+++ b/lib/Kconfig.debug | |
@@ -244,6 +244,7 @@ config DEBUG_INFO_COMPRESSED | |
config DEBUG_INFO_SPLIT | |
bool "Produce split debuginfo in .dwo files" | |
depends on $(cc-option,-gsplit-dwarf) | |
+ depends on !LTO_GCC | |
help | |
Generate debug info into separate .dwo files. This significantly | |
reduces the build directory size for builds with DEBUG_INFO, | |
diff --git a/net/core/filter.c b/net/core/filter.c | |
index 9323d34d3..46f78b3c6 100644 | |
--- a/net/core/filter.c | |
+++ b/net/core/filter.c | |
@@ -10479,6 +10479,7 @@ BTF_ID_LIST_GLOBAL(btf_sock_ids) | |
#define BTF_SOCK_TYPE(name, type) BTF_ID(struct, type) | |
BTF_SOCK_TYPE_xxx | |
#undef BTF_SOCK_TYPE | |
+BTF_ID_LIST_END | |
#else | |
u32 btf_sock_ids[MAX_BTF_SOCK_TYPE]; | |
#endif | |
@@ -10601,6 +10602,7 @@ BPF_CALL_1(bpf_sock_from_file, struct file *, file) | |
BTF_ID_LIST(bpf_sock_from_file_btf_ids) | |
BTF_ID(struct, socket) | |
BTF_ID(struct, file) | |
+BTF_ID_LIST_END | |
const struct bpf_func_proto bpf_sock_from_file_proto = { | |
.func = bpf_sock_from_file, | |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c | |
index 373d48073..6db42e5b1 100644 | |
--- a/net/ipv6/route.c | |
+++ b/net/ipv6/route.c | |
@@ -6471,6 +6471,7 @@ DEFINE_BPF_ITER_FUNC(ipv6_route, struct bpf_iter_meta *meta, struct fib6_info *r | |
BTF_ID_LIST(btf_fib6_info_id) | |
BTF_ID(struct, fib6_info) | |
+BTF_ID_LIST_END | |
static const struct bpf_iter_seq_info ipv6_route_seq_info = { | |
.seq_ops = &ipv6_route_seq_ops, | |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c | |
index 3a62f97ac..3abcf2d12 100644 | |
--- a/net/netlink/af_netlink.c | |
+++ b/net/netlink/af_netlink.c | |
@@ -2838,6 +2838,7 @@ static const struct rhashtable_params netlink_rhashtable_params = { | |
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS) | |
BTF_ID_LIST(btf_netlink_sock_id) | |
BTF_ID(struct, netlink_sock) | |
+BTF_ID_LIST_END | |
static const struct bpf_iter_seq_info netlink_seq_info = { | |
.seq_ops = &netlink_seq_ops, | |
diff --git a/scripts/Makefile.build b/scripts/Makefile.build | |
index 1b6094a13..59de68083 100644 | |
--- a/scripts/Makefile.build | |
+++ b/scripts/Makefile.build | |
@@ -165,11 +165,11 @@ ifdef CONFIG_MODVERSIONS | |
# the actual value of the checksum generated by genksyms | |
# o remove .tmp_<file>.o to <file>.o | |
-ifdef CONFIG_LTO_CLANG | |
+ifdef CONFIG_LTO | |
# 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 \ | |
+ if $(NM) $@ 2>/dev/null | grep -q __kstrtab; then \ | |
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ | |
> $@.symversions; \ | |
fi; | |
@@ -179,7 +179,7 @@ cmd_modversions_c = \ | |
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ | |
> $(@D)/.tmp_$(@F:.o=.ver); \ | |
\ | |
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ | |
+ $(LDFINAL) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ | |
-T $(@D)/.tmp_$(@F:.o=.ver); \ | |
mv -f $(@D)/.tmp_$(@F) $@; \ | |
rm -f $(@D)/.tmp_$(@F:.o=.ver); \ | |
@@ -217,7 +217,7 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), | |
endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT | |
ifdef CONFIG_STACK_VALIDATION | |
-ifndef CONFIG_LTO_CLANG | |
+ifndef CONFIG_LTO | |
ifneq ($(SKIP_STACK_VALIDATION),1) | |
__objtool_obj := $(objtree)/tools/objtool/objtool | |
@@ -233,7 +233,7 @@ objtool_obj = $(if $(patsubst y%,, \ | |
$(__objtool_obj)) | |
endif # SKIP_STACK_VALIDATION | |
-endif # CONFIG_LTO_CLANG | |
+endif # CONFIG_LTO | |
endif # CONFIG_STACK_VALIDATION | |
# Rebuild all objects when objtool changes, or is enabled/disabled. | |
@@ -280,7 +280,8 @@ $(obj)/%.mod: $(obj)/%.o FORCE | |
$(call if_changed,mod) | |
quiet_cmd_cc_lst_c = MKLST $@ | |
- cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ | |
+ cmd_cc_lst_c = $(if $(CONFIG_LTO),$(warning Listing in LTO mode does not match final binary)) \ | |
+ $(CC) $(c_flags) -g -c -o $*.o $< && \ | |
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ | |
System.map $(OBJDUMP) > $@ | |
@@ -341,7 +342,7 @@ cmd_modversions_S = \ | |
$(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ | |
> $(@D)/.tmp_$(@F:.o=.ver); \ | |
\ | |
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ | |
+ $(LDFINAL) $(KBUILD_LDFLAGS) -r $(KBUILD_MOD_LDFLAGS) -o $(@D)/.tmp_$(@F) $@ \ | |
-T $(@D)/.tmp_$(@F:.o=.ver); \ | |
mv -f $(@D)/.tmp_$(@F) $@; \ | |
rm -f $(@D)/.tmp_$(@F:.o=.ver); \ | |
@@ -382,7 +383,7 @@ $(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) | |
+ifeq ($(CONFIG_LTO) $(CONFIG_MODVERSIONS),y y) | |
cmd_update_lto_symversions = \ | |
rm -f $@.symversions \ | |
$(foreach n, $(filter-out FORCE,$^), \ | |
@@ -433,15 +434,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 | |
+ifdef CONFIG_LTO | |
quiet_cmd_link_multi-m = AR [M] $@ | |
cmd_link_multi-m = \ | |
$(cmd_update_lto_symversions); \ | |
rm -f $@; \ | |
$(AR) cDPrsT $@ $(filter %.o,$^) | |
else | |
-quiet_cmd_link_multi-m = LD [M] $@ | |
- cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) | |
+quiet_cmd_link_multi-m = LDFINAL [M] $@ | |
+ cmd_link_multi-m = $(LDFINAL) $(ld_flags) -r -o $@ $(filter %.o,$^) | |
endif | |
$(multi-used-m): FORCE | |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib | |
index 8cd67b1b6..d5d5e5643 100644 | |
--- a/scripts/Makefile.lib | |
+++ b/scripts/Makefile.lib | |
@@ -188,7 +188,7 @@ quiet_modtag = $(if $(part-of-module),[M], ) | |
modkern_cflags = \ | |
$(if $(part-of-module), \ | |
- $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ | |
+ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ | |
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) | |
modkern_aflags = $(if $(part-of-module), \ | |
diff --git a/scripts/Makefile.lto b/scripts/Makefile.lto | |
new file mode 100644 | |
index 000000000..df97be2d9 | |
--- /dev/null | |
+++ b/scripts/Makefile.lto | |
@@ -0,0 +1,40 @@ | |
+# | |
+# Support for gcc link time optimization | |
+# | |
+ | |
+DISABLE_LTO_GCC := | |
+export DISABLE_LTO_GCC | |
+ | |
+ifdef CONFIG_LTO_GCC | |
+ CC_FLAGS_LTO_GCC := -flto | |
+ DISABLE_LTO_GCC := -fno-lto | |
+ | |
+ KBUILD_CFLAGS += ${CC_FLAGS_LTO_GCC} | |
+ | |
+ lto-flags-y := -flto -flinker-output=nolto-rel -flto=jobserver | |
+ lto-flags-y += -fwhole-program | |
+ | |
+ lto-flags-$(CONFIG_LTO_CP_CLONE) += -fipa-cp-clone | |
+ | |
+ # allow extra flags from command line | |
+ lto-flags-y += ${LTO_EXTRA_CFLAGS} | |
+ | |
+ # For LTO we need to use gcc to do the linking, not ld | |
+ # directly. Use a wrapper to convert the ld command line | |
+ # to gcc | |
+ LDFINAL := ${CONFIG_SHELL} ${srctree}/scripts/gcc-ld \ | |
+ ${lto-flags-y} | |
+ | |
+ # LTO gcc creates a lot of files in TMPDIR, and with /tmp as tmpfs | |
+ # it's easy to drive the machine OOM. Use the object directory | |
+ # instead for temporaries. | |
+ # This has the drawback that there might be some junk more visible | |
+ # after interrupted compilations, but you would have that junk | |
+ # there anyways in /tmp. | |
+ TMPDIR ?= $(objtree) | |
+ export TMPDIR | |
+ | |
+ # use plugin aware tools | |
+ AR = $(CROSS_COMPILE)gcc-ar | |
+ NM = $(CROSS_COMPILE)gcc-nm | |
+endif # CONFIG_LTO_GCC | |
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal | |
index 735e11e90..4033e8803 100644 | |
--- a/scripts/Makefile.modfinal | |
+++ b/scripts/Makefile.modfinal | |
@@ -30,8 +30,8 @@ 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 | |
+ifdef CONFIG_LTO | |
+# With CONFIG_LTO, reuse the object file we compiled for modpost to | |
# avoid a second slow LTO link | |
prelink-ext := .lto | |
@@ -47,11 +47,11 @@ cmd_ld_ko_o += \ | |
endif # SKIP_STACK_VALIDATION | |
endif # CONFIG_STACK_VALIDATION | |
-endif # CONFIG_LTO_CLANG | |
+endif # CONFIG_LTO | |
-quiet_cmd_ld_ko_o = LD [M] $@ | |
+quiet_cmd_ld_ko_o = LDFINAL [M] $@ | |
cmd_ld_ko_o += \ | |
- $(LD) -r $(KBUILD_LDFLAGS) \ | |
+ $(LDFINAL) -r $(KBUILD_LDFLAGS) \ | |
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ | |
-T scripts/module.lds -o $@ $(filter %.o, $^); \ | |
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) | |
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost | |
index 066beffca..54ec57859 100644 | |
--- a/scripts/Makefile.modpost | |
+++ b/scripts/Makefile.modpost | |
@@ -105,14 +105,14 @@ $(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 | |
+ifdef CONFIG_LTO | |
+# With CONFIG_LTO, .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 $@ \ | |
+ $(LDFINAL) $(ld_flags) -r -o $@ \ | |
$(shell [ -s $(@:.lto.o=.o.symversions) ] && \ | |
echo -T $(@:.lto.o=.o.symversions)) \ | |
--whole-archive $^ | |
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter | |
index dcd8d8750..ec5ece4ee 100755 | |
--- a/scripts/bloat-o-meter | |
+++ b/scripts/bloat-o-meter | |
@@ -37,7 +37,7 @@ def getsizes(file, format): | |
if name.startswith("__addressable_"): continue | |
if name == "linux_banner": continue | |
# statics and some other optimizations adds random .NUMBER | |
- name = re_NUMBER.sub('', name) | |
+ name = re_NUMBER.sub('', name).replace(".lto_priv", "") | |
sym[name] = sym.get(name, 0) + int(size, 16) | |
return sym | |
diff --git a/scripts/gcc-ld b/scripts/gcc-ld | |
index 997b818c3..13e85ece8 100755 | |
--- a/scripts/gcc-ld | |
+++ b/scripts/gcc-ld | |
@@ -6,18 +6,26 @@ | |
ARGS="-nostdlib" | |
+for j in "$@" ; do | |
+ if [ "$j" = -v ] ; then | |
+ exec `$CC -print-prog-name=ld` -v | |
+ fi | |
+done | |
+ | |
while [ "$1" != "" ] ; do | |
case "$1" in | |
- -save-temps|-m32|-m64) N="$1" ;; | |
+ -save-temps*|-m32|-m64) N="$1" ;; | |
-r) N="$1" ;; | |
+ -flinker-output*) N="$1" ;; | |
-[Wg]*) N="$1" ;; | |
-[olv]|-[Ofd]*|-nostdlib) N="$1" ;; | |
- --end-group|--start-group) | |
+ --end-group|--start-group|--whole-archive|--no-whole-archive|\ | |
+--no-undefined|--hash-style*|--build-id*|--eh-frame-hdr|-Bsymbolic) | |
N="-Wl,$1" ;; | |
-[RTFGhIezcbyYu]*|\ | |
--script|--defsym|-init|-Map|--oformat|-rpath|\ | |
--rpath-link|--sort-section|--section-start|-Tbss|-Tdata|-Ttext|\ | |
---version-script|--dynamic-list|--version-exports-symbol|--wrap|-m) | |
+-rpath-link|--sort-section|--section-start|-Tbss|-Tdata|-Ttext|-soname|\ | |
+--version-script|--dynamic-list|--version-exports-symbol|--wrap|-m|-z) | |
A="$1" ; shift ; N="-Wl,$A,$1" ;; | |
-[m]*) N="$1" ;; | |
-*) N="-Wl,$1" ;; | |
@@ -27,4 +35,6 @@ while [ "$1" != "" ] ; do | |
shift | |
done | |
+[ -n "$V" ] && echo >&2 $CC $ARGS | |
+ | |
exec $CC $ARGS | |
diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh | |
index da320151e..ece61af2c 100755 | |
--- a/scripts/gen_autoksyms.sh | |
+++ b/scripts/gen_autoksyms.sh | |
@@ -26,10 +26,10 @@ if [ -n "$CONFIG_MODVERSIONS" ]; then | |
needed_symbols="$needed_symbols module_layout" | |
fi | |
-# With CONFIG_LTO_CLANG, LLVM bitcode has not yet been compiled into a binary | |
+# With CONFIG_LTO, LLVM bitcode has not yet been compiled into a binary | |
# when the .mod files are generated, which means they don't yet contain | |
# references to certain symbols that will be present in the final binaries. | |
-if [ -n "$CONFIG_LTO_CLANG" ]; then | |
+if [ -n "$CONFIG_LTO" ]; then | |
# intrinsic functions | |
needed_symbols="$needed_symbols memcpy memmove memset" | |
# ftrace | |
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh | |
index 3b261b0f7..27aac42bd 100755 | |
--- a/scripts/link-vmlinux.sh | |
+++ b/scripts/link-vmlinux.sh | |
@@ -31,8 +31,9 @@ | |
set -e | |
LD="$1" | |
-KBUILD_LDFLAGS="$2" | |
-LDFLAGS_vmlinux="$3" | |
+LDFINAL="$2" | |
+KBUILD_LDFLAGS="$3" | |
+LDFLAGS_vmlinux="$4" | |
# Nice output in kbuild format | |
# Will be supressed by "make -s" | |
@@ -54,7 +55,7 @@ gen_initcalls() | |
> .tmp_initcalls.lds | |
} | |
-# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into | |
+# If CONFIG_LTO is selected, collect generated symbol versions into | |
# .tmp_symversions.lds | |
gen_symversions() | |
{ | |
@@ -82,9 +83,12 @@ modpost_link() | |
${KBUILD_VMLINUX_LIBS} \ | |
--end-group" | |
- if [ -n "${CONFIG_LTO_CLANG}" ]; then | |
- gen_initcalls | |
- lds="-T .tmp_initcalls.lds" | |
+ if [ -n "${CONFIG_LTO}" ]; then | |
+ lds="" | |
+ if [ -n "${CONFIG_LTO_CLANG}" ] ; then | |
+ gen_initcalls | |
+ lds="-T .tmp_initcalls.lds" | |
+ fi | |
if [ -n "${CONFIG_MODVERSIONS}" ]; then | |
gen_symversions | |
@@ -98,7 +102,7 @@ modpost_link() | |
info LD ${1} | |
fi | |
- ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects} | |
+ ${LDFINAL} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects} | |
} | |
objtool_link() | |
@@ -106,7 +110,7 @@ objtool_link() | |
local objtoolcmd; | |
local objtoolopt; | |
- if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then | |
+ if [ "${CONFIG_LTO} ${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. | |
if [ -n "${CONFIG_UNWINDER_ORC}" ]; then | |
@@ -132,7 +136,7 @@ objtool_link() | |
if [ -z "${CONFIG_FRAME_POINTER}" ]; then | |
objtoolopt="${objtoolopt} --no-fp" | |
fi | |
- if [ -n "${CONFIG_GCOV_KERNEL}" ] || [ -n "${CONFIG_LTO_CLANG}" ]; then | |
+ if [ -n "${CONFIG_GCOV_KERNEL}" ] || [ -n "${CONFIG_LTO}" ]; then | |
objtoolopt="${objtoolopt} --no-unreachable" | |
fi | |
if [ -n "${CONFIG_RETPOLINE}" ]; then | |
@@ -162,12 +166,12 @@ vmlinux_link() | |
shift | |
# The kallsyms linking does not need debug symbols included. | |
- if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then | |
+ if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ]; then | |
strip_debug=-Wl,--strip-debug | |
fi | |
if [ "${SRCARCH}" != "um" ]; then | |
- if [ -n "${CONFIG_LTO_CLANG}" ]; then | |
+ if [ -n "${CONFIG_LTO}" ]; then | |
# Use vmlinux.o instead of performing the slow LTO | |
# link again. | |
objects="--whole-archive \ | |
@@ -228,7 +232,14 @@ gen_btf() | |
vmlinux_link ${1} | |
info "BTF" ${2} | |
- LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} | |
+ | |
+ BTF_ARGS="" | |
+ if [ -n "${CONFIG_LTO_GCC}" ]; then | |
+ # gcc LTO generates some dwarf symbols that pahole | |
+ # doesn't like. Skip those instead of aborting. | |
+ BTF_ARGS=--btf_encode_force | |
+ fi | |
+ LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${BTF_ARGS} ${1} | |
# Create ${2} which contains just .BTF section but no symbols. Add | |
# SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all | |
@@ -306,20 +317,6 @@ cleanup() | |
rm -f vmlinux.o | |
} | |
-on_exit() | |
-{ | |
- if [ $? -ne 0 ]; then | |
- cleanup | |
- fi | |
-} | |
-trap on_exit EXIT | |
- | |
-on_signals() | |
-{ | |
- exit 1 | |
-} | |
-trap on_signals HUP INT QUIT TERM | |
- | |
# Use "make V=1" to debug this script | |
case "${KBUILD_VERBOSE}" in | |
*1*) | |
diff --git a/scripts/mksysmap b/scripts/mksysmap | |
index 9aa23d158..8b525c484 100755 | |
--- a/scripts/mksysmap | |
+++ b/scripts/mksysmap | |
@@ -34,6 +34,7 @@ | |
# U - undefined global symbols | |
# N - debugging symbols | |
# w - local weak symbols | |
+# W - weak symbols if they contain .c. | |
# readprofile starts reading symbols when _stext is found, and | |
# continue until it finds a symbol which is not either of 'T', 't', | |
@@ -41,4 +42,4 @@ | |
# so we just ignore them to let readprofile continue to work. | |
# (At least sparc64 has __crc_ in the middle). | |
-$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)' > $2 | |
+$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\(W .*\.c\.\)' > $2 | |
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile | |
index c9e38ad93..aa3465d6b 100644 | |
--- a/scripts/mod/Makefile | |
+++ b/scripts/mod/Makefile | |
@@ -1,6 +1,7 @@ | |
# SPDX-License-Identifier: GPL-2.0 | |
OBJECT_FILES_NON_STANDARD := y | |
CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO) | |
+CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO_GCC) | |
hostprogs-always-y += modpost mk_elfconfig | |
always-y += empty.o | |
@@ -9,6 +10,8 @@ modpost-objs := modpost.o file2alias.o sumversion.o | |
devicetable-offsets-file := devicetable-offsets.h | |
+$(obj)/devicetable-offsets.s: KBUILD_CFLAGS += $(DISABLE_LTO_GCC) | |
+ | |
$(obj)/$(devicetable-offsets-file): $(obj)/devicetable-offsets.s FORCE | |
$(call filechk,offsets,__DEVICETABLE_OFFSETS_H__) | |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c | |
index 24725e50c..3ba0e6970 100644 | |
--- a/scripts/mod/modpost.c | |
+++ b/scripts/mod/modpost.c | |
@@ -1559,6 +1559,20 @@ static void report_sec_mismatch(const char *modname, | |
fprintf(stderr, "\n"); | |
} | |
+/* For checks remove .lto_priv.0 which is added randomly by gcc LTO */ | |
+ | |
+static char *cleansym(const char *sym) | |
+{ | |
+ char *nsym = strdup(sym); | |
+ char *p; | |
+ if (!nsym) | |
+ exit(ENOMEM); | |
+ p = strstr(nsym, ".lto_priv.0"); | |
+ if (p && p[11] == 0) | |
+ *p = 0; | |
+ return nsym; | |
+} | |
+ | |
static void default_mismatch_handler(const char *modname, struct elf_info *elf, | |
const struct sectioncheck* const mismatch, | |
Elf_Rela *r, Elf_Sym *sym, const char *fromsec) | |
@@ -1568,6 +1582,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, | |
Elf_Sym *from; | |
const char *tosym; | |
const char *fromsym; | |
+ char *fromsym_clean, *tosym_clean; | |
from = find_elf_symbol2(elf, r->r_offset, fromsec); | |
fromsym = sym_name(elf, from); | |
@@ -1579,14 +1594,19 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, | |
to = find_elf_symbol(elf, r->r_addend, sym); | |
tosym = sym_name(elf, to); | |
+ fromsym_clean = cleansym(fromsym); | |
+ tosym_clean = cleansym(tosym); | |
+ | |
/* check whitelist - we may ignore it */ | |
if (secref_whitelist(mismatch, | |
- fromsec, fromsym, tosec, tosym)) { | |
+ fromsec, fromsym_clean, tosec, tosym_clean)) { | |
report_sec_mismatch(modname, mismatch, | |
fromsec, r->r_offset, fromsym, | |
is_function(from), tosec, tosym, | |
is_function(to)); | |
} | |
+ free(fromsym_clean); | |
+ free(tosym_clean); | |
} | |
static int is_executable_section(struct elf_info* elf, unsigned int section_index) | |
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c | |
index 549813cff..bcc92ca70 100644 | |
--- a/tools/objtool/arch/x86/decode.c | |
+++ b/tools/objtool/arch/x86/decode.c | |
@@ -613,7 +613,12 @@ const char *arch_nop_insn(int len) | |
int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg) | |
{ | |
- struct cfi_reg *cfa = &insn->cfi.cfa; | |
+ struct cfi_reg *cfa; | |
+ | |
+ if (sp_reg == ORC_REG_UNDEFINED && !insn->cfip) | |
+ return 0; | |
+ | |
+ cfa = &insn_get_cfi(insn)->cfa; | |
switch (sp_reg) { | |
case ORC_REG_UNDEFINED: | |
diff --git a/tools/objtool/check.c b/tools/objtool/check.c | |
index 5e5388a38..cf292aafd 100644 | |
--- a/tools/objtool/check.c | |
+++ b/tools/objtool/check.c | |
@@ -253,6 +253,20 @@ static void init_insn_state(struct insn_state *state, struct section *sec) | |
state->noinstr = sec->noinstr; | |
} | |
+struct cfi_state *insn_get_cfi(struct instruction *insn) | |
+{ | |
+ if (!insn->cfip) { | |
+ struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1); | |
+ if (!cfi) { | |
+ WARN("calloc failed"); | |
+ exit(1); | |
+ } | |
+ init_cfi_state(cfi); | |
+ insn->cfip = cfi; | |
+ } | |
+ return insn->cfip; | |
+} | |
+ | |
/* | |
* Call the arch-specific instruction decoder for all the instructions and add | |
* them to the global instruction list. | |
@@ -289,7 +303,6 @@ static int decode_instructions(struct objtool_file *file) | |
memset(insn, 0, sizeof(*insn)); | |
INIT_LIST_HEAD(&insn->alts); | |
INIT_LIST_HEAD(&insn->stack_ops); | |
- init_cfi_state(&insn->cfi); | |
insn->sec = sec; | |
insn->offset = offset; | |
@@ -1138,7 +1151,6 @@ static int handle_group_alt(struct objtool_file *file, | |
memset(nop, 0, sizeof(*nop)); | |
INIT_LIST_HEAD(&nop->alts); | |
INIT_LIST_HEAD(&nop->stack_ops); | |
- init_cfi_state(&nop->cfi); | |
nop->sec = special_alt->new_sec; | |
nop->offset = special_alt->new_off + special_alt->new_len; | |
@@ -1557,7 +1569,7 @@ static int read_unwind_hints(struct objtool_file *file) | |
insn->hint = true; | |
if (hint->type == UNWIND_HINT_TYPE_FUNC) { | |
- set_func_state(&insn->cfi); | |
+ set_func_state(insn_get_cfi(insn)); | |
continue; | |
} | |
@@ -1567,9 +1579,9 @@ static int read_unwind_hints(struct objtool_file *file) | |
return -1; | |
} | |
- insn->cfi.cfa.offset = bswap_if_needed(hint->sp_offset); | |
- insn->cfi.type = hint->type; | |
- insn->cfi.end = hint->end; | |
+ insn_get_cfi(insn)->cfa.offset = bswap_if_needed(hint->sp_offset); | |
+ insn_get_cfi(insn)->type = hint->type; | |
+ insn_get_cfi(insn)->end = hint->end; | |
} | |
return 0; | |
@@ -2421,9 +2433,9 @@ static int propagate_alt_cfi(struct objtool_file *file, struct instruction *insn | |
group_off = insn->offset - insn->alt_group->first_insn->offset; | |
if (!alt_cfi[group_off]) { | |
- alt_cfi[group_off] = &insn->cfi; | |
+ alt_cfi[group_off] = insn_get_cfi(insn); | |
} else { | |
- if (memcmp(alt_cfi[group_off], &insn->cfi, sizeof(struct cfi_state))) { | |
+ if (memcmp(alt_cfi[group_off], insn_get_cfi(insn), sizeof(struct cfi_state))) { | |
WARN_FUNC("stack layout conflict in alternatives", | |
insn->sec, insn->offset); | |
return -1; | |
@@ -2472,7 +2484,7 @@ static int handle_insn_ops(struct instruction *insn, struct insn_state *state) | |
static bool insn_cfi_match(struct instruction *insn, struct cfi_state *cfi2) | |
{ | |
- struct cfi_state *cfi1 = &insn->cfi; | |
+ struct cfi_state *cfi1 = insn_get_cfi(insn); | |
int i; | |
if (memcmp(&cfi1->cfa, &cfi2->cfa, sizeof(cfi1->cfa))) { | |
@@ -2694,9 +2706,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, | |
state.instr += insn->instr; | |
if (insn->hint) | |
- state.cfi = insn->cfi; | |
+ state.cfi = *insn_get_cfi(insn); | |
else | |
- insn->cfi = state.cfi; | |
+ *insn_get_cfi(insn) = state.cfi; | |
insn->visited |= visited; | |
diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h | |
index f5be79810..01b4a65c6 100644 | |
--- a/tools/objtool/include/objtool/check.h | |
+++ b/tools/objtool/include/objtool/check.h | |
@@ -59,9 +59,11 @@ struct instruction { | |
struct list_head alts; | |
struct symbol *func; | |
struct list_head stack_ops; | |
- struct cfi_state cfi; | |
+ struct cfi_state *cfip; | |
}; | |
+extern struct cfi_state *insn_get_cfi(struct instruction *); | |
+ | |
static inline bool is_static_jump(struct instruction *insn) | |
{ | |
return insn->type == INSN_JUMP_CONDITIONAL || | |
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c | |
index 738aa5021..46f89481e 100644 | |
--- a/tools/objtool/orc_gen.c | |
+++ b/tools/objtool/orc_gen.c | |
@@ -13,13 +13,19 @@ | |
#include <objtool/warn.h> | |
#include <objtool/endianness.h> | |
-static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi) | |
+static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, | |
+ struct instruction *insn) | |
{ | |
- struct instruction *insn = container_of(cfi, struct instruction, cfi); | |
struct cfi_reg *bp = &cfi->regs[CFI_BP]; | |
memset(orc, 0, sizeof(*orc)); | |
+ if (!cfi) { | |
+ orc->end = 0; | |
+ orc->sp_reg = ORC_REG_UNDEFINED; | |
+ return 0; | |
+ } | |
+ | |
orc->end = cfi->end; | |
if (cfi->cfa.base == CFI_UNDEFINED) { | |
@@ -179,7 +185,7 @@ int orc_create(struct objtool_file *file) | |
int i; | |
if (!alt_group) { | |
- if (init_orc_entry(&orc, &insn->cfi)) | |
+ if (init_orc_entry(&orc, insn->cfip, insn)) | |
return -1; | |
if (!memcmp(&prev_orc, &orc, sizeof(orc))) | |
continue; | |
@@ -203,7 +209,8 @@ int orc_create(struct objtool_file *file) | |
struct cfi_state *cfi = alt_group->cfi[i]; | |
if (!cfi) | |
continue; | |
- if (init_orc_entry(&orc, cfi)) | |
+ /* errors are reported on the original insn */ | |
+ if (init_orc_entry(&orc, cfi, insn)) | |
return -1; | |
if (!memcmp(&prev_orc, &orc, sizeof(orc))) | |
continue; | |
@@ -231,8 +238,8 @@ int orc_create(struct objtool_file *file) | |
/* Create .orc_unwind, .orc_unwind_ip and .rela.orc_unwind_ip sections: */ | |
sec = find_section_by_name(file->elf, ".orc_unwind"); | |
if (sec) { | |
- WARN("file already has .orc_unwind section, skipping"); | |
- return -1; | |
+ /* Don't regenerate if it already exists */ | |
+ return 0; | |
} | |
orc_sec = elf_create_section(file->elf, ".orc_unwind", 0, | |
sizeof(struct orc_entry), nr); | |
-- | |
2.31.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment