aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/compiler.h
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2018-08-22 00:56:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-22 13:52:47 -0400
commit7290d58095712a89f845e1bca05334796dd49ed2 (patch)
treede45008a48a615cecaa61b9306edfe067b397785 /include/linux/compiler.h
parentf922c4abdf7648523589abee9460c87f51630d2f (diff)
module: use relative references for __ksymtab entries
An ordinary arm64 defconfig build has ~64 KB worth of __ksymtab entries, each consisting of two 64-bit fields containing absolute references, to the symbol itself and to a char array containing its name, respectively. When we build the same configuration with KASLR enabled, we end up with an additional ~192 KB of relocations in the .init section, i.e., one 24 byte entry for each absolute reference, which all need to be processed at boot time. Given how the struct kernel_symbol that describes each entry is completely local to module.c (except for the references emitted by EXPORT_SYMBOL() itself), we can easily modify it to contain two 32-bit relative references instead. This reduces the size of the __ksymtab section by 50% for all 64-bit architectures, and gets rid of the runtime relocations entirely for architectures implementing KASLR, either via standard PIE linking (arm64) or using custom host tools (x86). Note that the binary search involving __ksymtab contents relies on each section being sorted by symbol name. This is implemented based on the input section names, not the names in the ksymtab entries, so this patch does not interfere with that. Given that the use of place-relative relocations requires support both in the toolchain and in the module loader, we cannot enable this feature for all architectures. So make it dependent on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Link: http://lkml.kernel.org/r/20180704083651.24360-4-ard.biesheuvel@linaro.org Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Jessica Yu <jeyu@kernel.org> Acked-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Will Deacon <will.deacon@arm.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Bjorn Helgaas <bhelgaas@google.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: James Morris <james.morris@microsoft.com> Cc: James Morris <jmorris@namei.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Kees Cook <keescook@chromium.org> Cc: Nicolas Pitre <nico@linaro.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Petr Mladek <pmladek@suse.com> Cc: Russell King <linux@armlinux.org.uk> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Garnier <thgarnie@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/compiler.h')
-rw-r--r--include/linux/compiler.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index c8eab637a2a7..681d866efb1e 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -280,6 +280,25 @@ unsigned long read_word_at_a_time(const void *addr)
280 280
281#endif /* __KERNEL__ */ 281#endif /* __KERNEL__ */
282 282
283/*
284 * Force the compiler to emit 'sym' as a symbol, so that we can reference
285 * it from inline assembler. Necessary in case 'sym' could be inlined
286 * otherwise, or eliminated entirely due to lack of references that are
287 * visible to the compiler.
288 */
289#define __ADDRESSABLE(sym) \
290 static void * __attribute__((section(".discard.addressable"), used)) \
291 __PASTE(__addressable_##sym, __LINE__) = (void *)&sym;
292
293/**
294 * offset_to_ptr - convert a relative memory offset to an absolute pointer
295 * @off: the address of the 32-bit offset value
296 */
297static inline void *offset_to_ptr(const int *off)
298{
299 return (void *)((unsigned long)off + *off);
300}
301
283#endif /* __ASSEMBLY__ */ 302#endif /* __ASSEMBLY__ */
284 303
285#ifndef __optimize 304#ifndef __optimize