aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-03-31 17:13:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-03-31 17:13:25 -0400
commit176ab02d4916f09d5d8cb63372d142df4378cdea (patch)
tree7039b1282e7b34341789a5416fbd7ca5da0e557a
parente06df6a7eae1ab1ef4deb076aeeaed90e948e5c0 (diff)
parentef178f9238b142cc1020265e176b20d27fd02ba9 (diff)
Merge branch 'x86-asmlinkage-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 LTO changes from Peter Anvin: "More infrastructure work in preparation for link-time optimization (LTO). Most of these changes is to make sure symbols accessed from assembly code are properly marked as visible so the linker doesn't remove them. My understanding is that the changes to support LTO are still not upstream in binutils, but are on the way there. This patchset should conclude the x86-specific changes, and remaining patches to actually enable LTO will be fed through the Kbuild tree (other than keeping up with changes to the x86 code base, of course), although not necessarily in this merge window" * 'x86-asmlinkage-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits) Kbuild, lto: Handle basic LTO in modpost Kbuild, lto: Disable LTO for asm-offsets.c Kbuild, lto: Add a gcc-ld script to let run gcc as ld Kbuild, lto: add ld-version and ld-ifversion macros Kbuild, lto: Drop .number postfixes in modpost Kbuild, lto, workaround: Don't warn for initcall_reference in modpost lto: Disable LTO for sys_ni lto: Handle LTO common symbols in module loader lto, workaround: Add workaround for initcall reordering lto: Make asmlinkage __visible x86, lto: Disable LTO for the x86 VDSO initconst, x86: Fix initconst mistake in ts5500 code initconst: Fix initconst mistake in dcdbas asmlinkage: Make trace_hardirqs_on/off_caller visible asmlinkage, x86: Fix 32bit memcpy for LTO asmlinkage Make __stack_chk_failed and memcmp visible asmlinkage: Mark rwsem functions that can be called from assembler asmlinkage asmlinkage: Make main_extable_sort_needed visible asmlinkage, mutex: Mark __visible asmlinkage: Make trace_hardirq visible ...
-rw-r--r--arch/x86/kernel/time.c2
-rw-r--r--arch/x86/lib/memcpy_32.c6
-rw-r--r--arch/x86/platform/ts5500/ts5500.c2
-rw-r--r--arch/x86/vdso/Makefile10
-rw-r--r--drivers/firmware/dcdbas.c2
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c9
-rw-r--r--include/linux/init.h20
-rw-r--r--include/linux/io.h2
-rw-r--r--include/linux/linkage.h4
-rw-r--r--include/linux/lockdep.h2
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/extable.c2
-rw-r--r--kernel/locking/lockdep.c6
-rw-r--r--kernel/locking/mutex.c10
-rw-r--r--kernel/locking/rwsem-xadd.c4
-rw-r--r--kernel/module.c4
-rw-r--r--kernel/panic.c2
-rw-r--r--kernel/timer.c2
-rw-r--r--kernel/trace/trace_irqsoff.c4
-rw-r--r--lib/string.c2
-rw-r--r--scripts/Kbuild.include9
-rw-r--r--scripts/Makefile.build2
-rw-r--r--scripts/gcc-ld29
-rwxr-xr-xscripts/ld-version.sh8
-rw-r--r--scripts/mod/modpost.c25
-rw-r--r--scripts/mod/modpost.h2
-rw-r--r--virt/kvm/kvm_main.c2
27 files changed, 138 insertions, 37 deletions
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index 24d3c91e9812..6ec91c00d84d 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -23,7 +23,7 @@
23#include <asm/time.h> 23#include <asm/time.h>
24 24
25#ifdef CONFIG_X86_64 25#ifdef CONFIG_X86_64
26DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES; 26__visible DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES;
27#endif 27#endif
28 28
29unsigned long profile_pc(struct pt_regs *regs) 29unsigned long profile_pc(struct pt_regs *regs)
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c
index e78761d6b7f8..a404b4b75533 100644
--- a/arch/x86/lib/memcpy_32.c
+++ b/arch/x86/lib/memcpy_32.c
@@ -4,7 +4,7 @@
4#undef memcpy 4#undef memcpy
5#undef memset 5#undef memset
6 6
7void *memcpy(void *to, const void *from, size_t n) 7__visible void *memcpy(void *to, const void *from, size_t n)
8{ 8{
9#ifdef CONFIG_X86_USE_3DNOW 9#ifdef CONFIG_X86_USE_3DNOW
10 return __memcpy3d(to, from, n); 10 return __memcpy3d(to, from, n);
@@ -14,13 +14,13 @@ void *memcpy(void *to, const void *from, size_t n)
14} 14}
15EXPORT_SYMBOL(memcpy); 15EXPORT_SYMBOL(memcpy);
16 16
17void *memset(void *s, int c, size_t count) 17__visible void *memset(void *s, int c, size_t count)
18{ 18{
19 return __memset(s, c, count); 19 return __memset(s, c, count);
20} 20}
21EXPORT_SYMBOL(memset); 21EXPORT_SYMBOL(memset);
22 22
23void *memmove(void *dest, const void *src, size_t n) 23__visible void *memmove(void *dest, const void *src, size_t n)
24{ 24{
25 int d0,d1,d2,d3,d4,d5; 25 int d0,d1,d2,d3,d4,d5;
26 char *ret = dest; 26 char *ret = dest;
diff --git a/arch/x86/platform/ts5500/ts5500.c b/arch/x86/platform/ts5500/ts5500.c
index 39febb214e8c..9471b9456f25 100644
--- a/arch/x86/platform/ts5500/ts5500.c
+++ b/arch/x86/platform/ts5500/ts5500.c
@@ -88,7 +88,7 @@ struct ts5500_sbc {
88static const struct { 88static const struct {
89 const char * const string; 89 const char * const string;
90 const ssize_t offset; 90 const ssize_t offset;
91} ts5500_signatures[] __initdata = { 91} ts5500_signatures[] __initconst = {
92 { "TS-5x00 AMD Elan", 0xb14 }, 92 { "TS-5x00 AMD Elan", 0xb14 },
93}; 93};
94 94
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index fd14be1d1472..9206ac7961a5 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -2,6 +2,8 @@
2# Building vDSO images for x86. 2# Building vDSO images for x86.
3# 3#
4 4
5KBUILD_CFLAGS += $(DISABLE_LTO)
6
5VDSO64-$(CONFIG_X86_64) := y 7VDSO64-$(CONFIG_X86_64) := y
6VDSOX32-$(CONFIG_X86_X32_ABI) := y 8VDSOX32-$(CONFIG_X86_X32_ABI) := y
7VDSO32-$(CONFIG_X86_32) := y 9VDSO32-$(CONFIG_X86_32) := y
@@ -35,7 +37,8 @@ export CPPFLAGS_vdso.lds += -P -C
35 37
36VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ 38VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
37 -Wl,--no-undefined \ 39 -Wl,--no-undefined \
38 -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 40 -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 \
41 $(DISABLE_LTO)
39 42
40$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so 43$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
41 44
@@ -127,7 +130,7 @@ vdso32.so-$(VDSO32-y) += sysenter
127vdso32-images = $(vdso32.so-y:%=vdso32-%.so) 130vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
128 131
129CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) 132CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
130VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1 133VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1
131 134
132# This makes sure the $(obj) subdirectory exists even though vdso32/ 135# This makes sure the $(obj) subdirectory exists even though vdso32/
133# is not a kbuild sub-make subdirectory. 136# is not a kbuild sub-make subdirectory.
@@ -181,7 +184,8 @@ quiet_cmd_vdso = VDSO $@
181 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ 184 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
182 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' 185 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
183 186
184VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) 187VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
188 $(LTO_CFLAGS)
185GCOV_PROFILE := n 189GCOV_PROFILE := n
186 190
187# 191#
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 1b5e8e46226d..7160c43c59fc 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -584,7 +584,7 @@ static struct platform_driver dcdbas_driver = {
584 .remove = dcdbas_remove, 584 .remove = dcdbas_remove,
585}; 585};
586 586
587static const struct platform_device_info dcdbas_dev_info __initdata = { 587static const struct platform_device_info dcdbas_dev_info __initconst = {
588 .name = DRIVER_NAME, 588 .name = DRIVER_NAME,
589 .id = -1, 589 .id = -1,
590 .dma_mask = DMA_BIT_MASK(32), 590 .dma_mask = DMA_BIT_MASK(32),
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 769d265b221b..deb7f4bcdb7b 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -21,7 +21,7 @@
21 21
22#include "pnpbios.h" 22#include "pnpbios.h"
23 23
24static struct { 24__visible struct {
25 u16 offset; 25 u16 offset;
26 u16 segment; 26 u16 segment;
27} pnp_bios_callpoint; 27} pnp_bios_callpoint;
@@ -41,6 +41,7 @@ asmlinkage void pnp_bios_callfunc(void);
41 41
42__asm__(".text \n" 42__asm__(".text \n"
43 __ALIGN_STR "\n" 43 __ALIGN_STR "\n"
44 ".globl pnp_bios_callfunc\n"
44 "pnp_bios_callfunc:\n" 45 "pnp_bios_callfunc:\n"
45 " pushl %edx \n" 46 " pushl %edx \n"
46 " pushl %ecx \n" 47 " pushl %ecx \n"
@@ -66,9 +67,9 @@ static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
66 * after PnP BIOS oopses. 67 * after PnP BIOS oopses.
67 */ 68 */
68 69
69u32 pnp_bios_fault_esp; 70__visible u32 pnp_bios_fault_esp;
70u32 pnp_bios_fault_eip; 71__visible u32 pnp_bios_fault_eip;
71u32 pnp_bios_is_utter_crap = 0; 72__visible u32 pnp_bios_is_utter_crap = 0;
72 73
73static spinlock_t pnp_bios_lock; 74static spinlock_t pnp_bios_lock;
74 75
diff --git a/include/linux/init.h b/include/linux/init.h
index e1688802964f..a3ba27076342 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -163,6 +163,23 @@ extern bool initcall_debug;
163 163
164#ifndef __ASSEMBLY__ 164#ifndef __ASSEMBLY__
165 165
166#ifdef CONFIG_LTO
167/* Work around a LTO gcc problem: when there is no reference to a variable
168 * in a module it will be moved to the end of the program. This causes
169 * reordering of initcalls which the kernel does not like.
170 * Add a dummy reference function to avoid this. The function is
171 * deleted by the linker.
172 */
173#define LTO_REFERENCE_INITCALL(x) \
174 ; /* yes this is needed */ \
175 static __used __exit void *reference_##x(void) \
176 { \
177 return &x; \
178 }
179#else
180#define LTO_REFERENCE_INITCALL(x)
181#endif
182
166/* initcalls are now grouped by functionality into separate 183/* initcalls are now grouped by functionality into separate
167 * subsections. Ordering inside the subsections is determined 184 * subsections. Ordering inside the subsections is determined
168 * by link order. 185 * by link order.
@@ -175,7 +192,8 @@ extern bool initcall_debug;
175 192
176#define __define_initcall(fn, id) \ 193#define __define_initcall(fn, id) \
177 static initcall_t __initcall_##fn##id __used \ 194 static initcall_t __initcall_##fn##id __used \
178 __attribute__((__section__(".initcall" #id ".init"))) = fn 195 __attribute__((__section__(".initcall" #id ".init"))) = fn; \
196 LTO_REFERENCE_INITCALL(__initcall_##fn##id)
179 197
180/* 198/*
181 * Early initcalls run before initializing SMP. 199 * Early initcalls run before initializing SMP.
diff --git a/include/linux/io.h b/include/linux/io.h
index f4f42faec686..8a18e75600cc 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -24,7 +24,7 @@
24 24
25struct device; 25struct device;
26 26
27void __iowrite32_copy(void __iomem *to, const void *from, size_t count); 27__visible void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
28void __iowrite64_copy(void __iomem *to, const void *from, size_t count); 28void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
29 29
30#ifdef CONFIG_MMU 30#ifdef CONFIG_MMU
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index a6a42dd02466..34a513a2727b 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -12,9 +12,9 @@
12#endif 12#endif
13 13
14#ifdef __cplusplus 14#ifdef __cplusplus
15#define CPP_ASMLINKAGE extern "C" 15#define CPP_ASMLINKAGE extern "C" __visible
16#else 16#else
17#define CPP_ASMLINKAGE 17#define CPP_ASMLINKAGE __visible
18#endif 18#endif
19 19
20#ifndef asmlinkage 20#ifndef asmlinkage
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 060e5137fd80..008388f920d7 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -265,7 +265,7 @@ extern void lockdep_info(void);
265extern void lockdep_reset(void); 265extern void lockdep_reset(void);
266extern void lockdep_reset_lock(struct lockdep_map *lock); 266extern void lockdep_reset_lock(struct lockdep_map *lock);
267extern void lockdep_free_key_range(void *start, unsigned long size); 267extern void lockdep_free_key_range(void *start, unsigned long size);
268extern void lockdep_sys_exit(void); 268extern asmlinkage void lockdep_sys_exit(void);
269 269
270extern void lockdep_off(void); 270extern void lockdep_off(void);
271extern void lockdep_on(void); 271extern void lockdep_on(void);
diff --git a/kernel/Makefile b/kernel/Makefile
index 4fd847488b76..f2a8b6246ce9 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -18,6 +18,9 @@ CFLAGS_REMOVE_cgroup-debug.o = -pg
18CFLAGS_REMOVE_irq_work.o = -pg 18CFLAGS_REMOVE_irq_work.o = -pg
19endif 19endif
20 20
21# cond_syscall is currently not LTO compatible
22CFLAGS_sys_ni.o = $(DISABLE_LTO)
23
21obj-y += sched/ 24obj-y += sched/
22obj-y += locking/ 25obj-y += locking/
23obj-y += power/ 26obj-y += power/
diff --git a/kernel/extable.c b/kernel/extable.c
index 763faf037ec1..d8a6446adbcb 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -36,7 +36,7 @@ extern struct exception_table_entry __start___ex_table[];
36extern struct exception_table_entry __stop___ex_table[]; 36extern struct exception_table_entry __stop___ex_table[];
37 37
38/* Cleared by build time tools if the table is already sorted. */ 38/* Cleared by build time tools if the table is already sorted. */
39u32 __initdata main_extable_sort_needed = 1; 39u32 __initdata __visible main_extable_sort_needed = 1;
40 40
41/* Sort the kernel's built-in exception table */ 41/* Sort the kernel's built-in exception table */
42void __init sort_main_extable(void) 42void __init sort_main_extable(void)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index bf0c6b0dd9c5..b0e9467922e1 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -2557,7 +2557,7 @@ static void __trace_hardirqs_on_caller(unsigned long ip)
2557 debug_atomic_inc(hardirqs_on_events); 2557 debug_atomic_inc(hardirqs_on_events);
2558} 2558}
2559 2559
2560void trace_hardirqs_on_caller(unsigned long ip) 2560__visible void trace_hardirqs_on_caller(unsigned long ip)
2561{ 2561{
2562 time_hardirqs_on(CALLER_ADDR0, ip); 2562 time_hardirqs_on(CALLER_ADDR0, ip);
2563 2563
@@ -2610,7 +2610,7 @@ EXPORT_SYMBOL(trace_hardirqs_on);
2610/* 2610/*
2611 * Hardirqs were disabled: 2611 * Hardirqs were disabled:
2612 */ 2612 */
2613void trace_hardirqs_off_caller(unsigned long ip) 2613__visible void trace_hardirqs_off_caller(unsigned long ip)
2614{ 2614{
2615 struct task_struct *curr = current; 2615 struct task_struct *curr = current;
2616 2616
@@ -4188,7 +4188,7 @@ void debug_show_held_locks(struct task_struct *task)
4188} 4188}
4189EXPORT_SYMBOL_GPL(debug_show_held_locks); 4189EXPORT_SYMBOL_GPL(debug_show_held_locks);
4190 4190
4191void lockdep_sys_exit(void) 4191asmlinkage void lockdep_sys_exit(void)
4192{ 4192{
4193 struct task_struct *curr = current; 4193 struct task_struct *curr = current;
4194 4194
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 14fe72cc8ce7..bc73d33c6760 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -75,8 +75,7 @@ EXPORT_SYMBOL(__mutex_init);
75 * We also put the fastpath first in the kernel image, to make sure the 75 * We also put the fastpath first in the kernel image, to make sure the
76 * branch is predicted by the CPU as default-untaken. 76 * branch is predicted by the CPU as default-untaken.
77 */ 77 */
78static __used noinline void __sched 78__visible void __sched __mutex_lock_slowpath(atomic_t *lock_count);
79__mutex_lock_slowpath(atomic_t *lock_count);
80 79
81/** 80/**
82 * mutex_lock - acquire the mutex 81 * mutex_lock - acquire the mutex
@@ -189,7 +188,8 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock)
189} 188}
190#endif 189#endif
191 190
192static __used noinline void __sched __mutex_unlock_slowpath(atomic_t *lock_count); 191__visible __used noinline
192void __sched __mutex_unlock_slowpath(atomic_t *lock_count);
193 193
194/** 194/**
195 * mutex_unlock - release the mutex 195 * mutex_unlock - release the mutex
@@ -716,7 +716,7 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count, int nested)
716/* 716/*
717 * Release the lock, slowpath: 717 * Release the lock, slowpath:
718 */ 718 */
719static __used noinline void 719__visible void
720__mutex_unlock_slowpath(atomic_t *lock_count) 720__mutex_unlock_slowpath(atomic_t *lock_count)
721{ 721{
722 __mutex_unlock_common_slowpath(lock_count, 1); 722 __mutex_unlock_common_slowpath(lock_count, 1);
@@ -773,7 +773,7 @@ int __sched mutex_lock_killable(struct mutex *lock)
773} 773}
774EXPORT_SYMBOL(mutex_lock_killable); 774EXPORT_SYMBOL(mutex_lock_killable);
775 775
776static __used noinline void __sched 776__visible void __sched
777__mutex_lock_slowpath(atomic_t *lock_count) 777__mutex_lock_slowpath(atomic_t *lock_count)
778{ 778{
779 struct mutex *lock = container_of(lock_count, struct mutex, count); 779 struct mutex *lock = container_of(lock_count, struct mutex, count);
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c
index 19c5fa95e0b4..1d66e08e897d 100644
--- a/kernel/locking/rwsem-xadd.c
+++ b/kernel/locking/rwsem-xadd.c
@@ -143,6 +143,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, enum rwsem_wake_type wake_type)
143/* 143/*
144 * wait for the read lock to be granted 144 * wait for the read lock to be granted
145 */ 145 */
146__visible
146struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) 147struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
147{ 148{
148 long count, adjustment = -RWSEM_ACTIVE_READ_BIAS; 149 long count, adjustment = -RWSEM_ACTIVE_READ_BIAS;
@@ -190,6 +191,7 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
190/* 191/*
191 * wait until we successfully acquire the write lock 192 * wait until we successfully acquire the write lock
192 */ 193 */
194__visible
193struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem) 195struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
194{ 196{
195 long count, adjustment = -RWSEM_ACTIVE_WRITE_BIAS; 197 long count, adjustment = -RWSEM_ACTIVE_WRITE_BIAS;
@@ -252,6 +254,7 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
252 * handle waking up a waiter on the semaphore 254 * handle waking up a waiter on the semaphore
253 * - up_read/up_write has decremented the active part of count if we come here 255 * - up_read/up_write has decremented the active part of count if we come here
254 */ 256 */
257__visible
255struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem) 258struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem)
256{ 259{
257 unsigned long flags; 260 unsigned long flags;
@@ -272,6 +275,7 @@ struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem)
272 * - caller incremented waiting part of count and discovered it still negative 275 * - caller incremented waiting part of count and discovered it still negative
273 * - just wake up any readers at the front of the queue 276 * - just wake up any readers at the front of the queue
274 */ 277 */
278__visible
275struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem) 279struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem)
276{ 280{
277 unsigned long flags; 281 unsigned long flags;
diff --git a/kernel/module.c b/kernel/module.c
index ca2c1aded7ee..8dc7f5e80dd8 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1948,6 +1948,10 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
1948 1948
1949 switch (sym[i].st_shndx) { 1949 switch (sym[i].st_shndx) {
1950 case SHN_COMMON: 1950 case SHN_COMMON:
1951 /* Ignore common symbols */
1952 if (!strncmp(name, "__gnu_lto", 9))
1953 break;
1954
1951 /* We compiled with -fno-common. These are not 1955 /* We compiled with -fno-common. These are not
1952 supposed to happen. */ 1956 supposed to happen. */
1953 pr_debug("Common symbol: %s\n", name); 1957 pr_debug("Common symbol: %s\n", name);
diff --git a/kernel/panic.c b/kernel/panic.c
index 2270cfd1d6be..cca8a913ae7c 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -459,7 +459,7 @@ EXPORT_SYMBOL(warn_slowpath_null);
459 * Called when gcc's -fstack-protector feature is used, and 459 * Called when gcc's -fstack-protector feature is used, and
460 * gcc detects corruption of the on-stack canary value 460 * gcc detects corruption of the on-stack canary value
461 */ 461 */
462void __stack_chk_fail(void) 462__visible void __stack_chk_fail(void)
463{ 463{
464 panic("stack-protector: Kernel stack is corrupted in: %p\n", 464 panic("stack-protector: Kernel stack is corrupted in: %p\n",
465 __builtin_return_address(0)); 465 __builtin_return_address(0));
diff --git a/kernel/timer.c b/kernel/timer.c
index accfd241b9e5..d78de047599b 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -52,7 +52,7 @@
52#define CREATE_TRACE_POINTS 52#define CREATE_TRACE_POINTS
53#include <trace/events/timer.h> 53#include <trace/events/timer.h>
54 54
55u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; 55__visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
56 56
57EXPORT_SYMBOL(jiffies_64); 57EXPORT_SYMBOL(jiffies_64);
58 58
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 2aefbee93a6d..887ef88b0bc7 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -498,14 +498,14 @@ void trace_hardirqs_off(void)
498} 498}
499EXPORT_SYMBOL(trace_hardirqs_off); 499EXPORT_SYMBOL(trace_hardirqs_off);
500 500
501void trace_hardirqs_on_caller(unsigned long caller_addr) 501__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
502{ 502{
503 if (!preempt_trace() && irq_trace()) 503 if (!preempt_trace() && irq_trace())
504 stop_critical_timing(CALLER_ADDR0, caller_addr); 504 stop_critical_timing(CALLER_ADDR0, caller_addr);
505} 505}
506EXPORT_SYMBOL(trace_hardirqs_on_caller); 506EXPORT_SYMBOL(trace_hardirqs_on_caller);
507 507
508void trace_hardirqs_off_caller(unsigned long caller_addr) 508__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
509{ 509{
510 if (!preempt_trace() && irq_trace()) 510 if (!preempt_trace() && irq_trace())
511 start_critical_timing(CALLER_ADDR0, caller_addr); 511 start_critical_timing(CALLER_ADDR0, caller_addr);
diff --git a/lib/string.c b/lib/string.c
index e5878de4f101..9b1f9062a202 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -648,7 +648,7 @@ EXPORT_SYMBOL(memmove);
648 * @count: The size of the area. 648 * @count: The size of the area.
649 */ 649 */
650#undef memcmp 650#undef memcmp
651int memcmp(const void *cs, const void *ct, size_t count) 651__visible int memcmp(const void *cs, const void *ct, size_t count)
652{ 652{
653 const unsigned char *su1, *su2; 653 const unsigned char *su1, *su2;
654 int res = 0; 654 int res = 0;
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 547e15daf03d..93a0da26582b 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -155,6 +155,15 @@ ld-option = $(call try-run,\
155# Important: no spaces around options 155# Important: no spaces around options
156ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2)) 156ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))
157 157
158# ld-version
159# Usage: $(call ld-version)
160# Note this is mainly for HJ Lu's 3 number binutil versions
161ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
162
163# ld-ifversion
164# Usage: $(call ld-ifversion, -ge, 22252, y)
165ld-ifversion = $(shell [ $(call ld-version) $(1) $(2) ] && echo $(3))
166
158###### 167######
159 168
160### 169###
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index d5d859c80729..9f0ee22b914f 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -198,7 +198,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi)
198$(multi-objs-y:.o=.lst) : modname = $(modname-multi) 198$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
199 199
200quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ 200quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
201cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< 201cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $<
202 202
203$(obj)/%.s: $(src)/%.c FORCE 203$(obj)/%.s: $(src)/%.c FORCE
204 $(call if_changed_dep,cc_s_c) 204 $(call if_changed_dep,cc_s_c)
diff --git a/scripts/gcc-ld b/scripts/gcc-ld
new file mode 100644
index 000000000000..cadab9a13ed7
--- /dev/null
+++ b/scripts/gcc-ld
@@ -0,0 +1,29 @@
1#!/bin/sh
2# run gcc with ld options
3# used as a wrapper to execute link time optimizations
4# yes virginia, this is not pretty
5
6ARGS="-nostdlib"
7
8while [ "$1" != "" ] ; do
9 case "$1" in
10 -save-temps|-m32|-m64) N="$1" ;;
11 -r) N="$1" ;;
12 -[Wg]*) N="$1" ;;
13 -[olv]|-[Ofd]*|-nostdlib) N="$1" ;;
14 --end-group|--start-group)
15 N="-Wl,$1" ;;
16 -[RTFGhIezcbyYu]*|\
17--script|--defsym|-init|-Map|--oformat|-rpath|\
18-rpath-link|--sort-section|--section-start|-Tbss|-Tdata|-Ttext|\
19--version-script|--dynamic-list|--version-exports-symbol|--wrap|-m)
20 A="$1" ; shift ; N="-Wl,$A,$1" ;;
21 -[m]*) N="$1" ;;
22 -*) N="-Wl,$1" ;;
23 *) N="$1" ;;
24 esac
25 ARGS="$ARGS $N"
26 shift
27done
28
29exec $CC $ARGS
diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh
new file mode 100755
index 000000000000..198580d245e0
--- /dev/null
+++ b/scripts/ld-version.sh
@@ -0,0 +1,8 @@
1#!/usr/bin/awk -f
2# extract linker version number from stdin and turn into single number
3 {
4 gsub(".*)", "");
5 split($1,a, ".");
6 print a[1]*10000000 + a[2]*100000 + a[3]*10000 + a[4]*100 + a[5];
7 exit
8 }
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 99a45fdc1bbf..066355673930 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -623,7 +623,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
623 623
624 switch (sym->st_shndx) { 624 switch (sym->st_shndx) {
625 case SHN_COMMON: 625 case SHN_COMMON:
626 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); 626 if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) {
627 /* Should warn here, but modpost runs before the linker */
628 } else
629 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
627 break; 630 break;
628 case SHN_UNDEF: 631 case SHN_UNDEF:
629 /* undefined symbol */ 632 /* undefined symbol */
@@ -849,6 +852,7 @@ static const char *section_white_list[] =
849 ".xt.lit", /* xtensa */ 852 ".xt.lit", /* xtensa */
850 ".arcextmap*", /* arc */ 853 ".arcextmap*", /* arc */
851 ".gnu.linkonce.arcext*", /* arc : modules */ 854 ".gnu.linkonce.arcext*", /* arc : modules */
855 ".gnu.lto*",
852 NULL 856 NULL
853}; 857};
854 858
@@ -1455,6 +1459,10 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
1455 to = find_elf_symbol(elf, r->r_addend, sym); 1459 to = find_elf_symbol(elf, r->r_addend, sym);
1456 tosym = sym_name(elf, to); 1460 tosym = sym_name(elf, to);
1457 1461
1462 if (!strncmp(fromsym, "reference___initcall",
1463 sizeof("reference___initcall")-1))
1464 return;
1465
1458 /* check whitelist - we may ignore it */ 1466 /* check whitelist - we may ignore it */
1459 if (secref_whitelist(mismatch, 1467 if (secref_whitelist(mismatch,
1460 fromsec, fromsym, tosec, tosym)) { 1468 fromsec, fromsym, tosec, tosym)) {
@@ -1693,6 +1701,19 @@ static void check_sec_ref(struct module *mod, const char *modname,
1693 } 1701 }
1694} 1702}
1695 1703
1704static char *remove_dot(char *s)
1705{
1706 char *end;
1707 int n = strcspn(s, ".");
1708
1709 if (n > 0 && s[n] != 0) {
1710 strtoul(s + n + 1, &end, 10);
1711 if (end > s + n + 1 && (*end == '.' || *end == 0))
1712 s[n] = 0;
1713 }
1714 return s;
1715}
1716
1696static void read_symbols(char *modname) 1717static void read_symbols(char *modname)
1697{ 1718{
1698 const char *symname; 1719 const char *symname;
@@ -1731,7 +1752,7 @@ static void read_symbols(char *modname)
1731 } 1752 }
1732 1753
1733 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { 1754 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
1734 symname = info.strtab + sym->st_name; 1755 symname = remove_dot(info.strtab + sym->st_name);
1735 1756
1736 handle_modversions(mod, &info, sym, symname); 1757 handle_modversions(mod, &info, sym, symname);
1737 handle_moddevtable(mod, &info, sym, symname); 1758 handle_moddevtable(mod, &info, sym, symname);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 51207e4d5f8b..168b43dc0a59 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -127,7 +127,7 @@ struct elf_info {
127 Elf_Section export_gpl_sec; 127 Elf_Section export_gpl_sec;
128 Elf_Section export_unused_gpl_sec; 128 Elf_Section export_unused_gpl_sec;
129 Elf_Section export_gpl_future_sec; 129 Elf_Section export_gpl_future_sec;
130 const char *strtab; 130 char *strtab;
131 char *modinfo; 131 char *modinfo;
132 unsigned int modinfo_len; 132 unsigned int modinfo_len;
133 133
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 03a0381b1cb7..b5ec7fb986f6 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -102,7 +102,7 @@ static void kvm_release_pfn_dirty(pfn_t pfn);
102static void mark_page_dirty_in_slot(struct kvm *kvm, 102static void mark_page_dirty_in_slot(struct kvm *kvm,
103 struct kvm_memory_slot *memslot, gfn_t gfn); 103 struct kvm_memory_slot *memslot, gfn_t gfn);
104 104
105bool kvm_rebooting; 105__visible bool kvm_rebooting;
106EXPORT_SYMBOL_GPL(kvm_rebooting); 106EXPORT_SYMBOL_GPL(kvm_rebooting);
107 107
108static bool largepages_enabled = true; 108static bool largepages_enabled = true;