Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries
On 11 March 2018 at 12:38, Ard Biesheuvelwrote: > 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. > > Cc: Arnd Bergmann > Cc: Andrew Morton > Cc: Ingo Molnar > Cc: Kees Cook > Cc: Thomas Garnier > Cc: Nicolas Pitre > Acked-by: Jessica Yu > Signed-off-by: Ard Biesheuvel > --- > arch/x86/include/asm/Kbuild | 1 + > arch/x86/include/asm/export.h | 5 --- > include/asm-generic/export.h | 12 - > include/linux/compiler.h | 19 > include/linux/export.h| 46 +++- > kernel/module.c | 32 +++--- > 6 files changed, 91 insertions(+), 24 deletions(-) > ... > diff --git a/include/linux/compiler.h b/include/linux/compiler.h > index ab4711c63601..0a9328ea9dbd 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) > > #endif /* __KERNEL__ */ > > +/* > + * Force the compiler to emit 'sym' as a symbol, so that we can reference > + * it from inline assembler. Necessary in case 'sym' could be inlined > + * otherwise, or eliminated entirely due to lack of references that are > + * visible to the compiler. > + */ > +#define __ADDRESSABLE(sym) \ > + static void * const __attribute__((section(".discard"), used)) \ > + __PASTE(__addressable_##sym, __LINE__) = (void *) > + kernelci.org tells me that I need to drop the 'const' here, or we may end up with .discard sections with conflicting attributes (r/o vs r/w) in some cases (CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y)
Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries
On 11 March 2018 at 12:38, Ard Biesheuvel wrote: > 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. > > Cc: Arnd Bergmann > Cc: Andrew Morton > Cc: Ingo Molnar > Cc: Kees Cook > Cc: Thomas Garnier > Cc: Nicolas Pitre > Acked-by: Jessica Yu > Signed-off-by: Ard Biesheuvel > --- > arch/x86/include/asm/Kbuild | 1 + > arch/x86/include/asm/export.h | 5 --- > include/asm-generic/export.h | 12 - > include/linux/compiler.h | 19 > include/linux/export.h| 46 +++- > kernel/module.c | 32 +++--- > 6 files changed, 91 insertions(+), 24 deletions(-) > ... > diff --git a/include/linux/compiler.h b/include/linux/compiler.h > index ab4711c63601..0a9328ea9dbd 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) > > #endif /* __KERNEL__ */ > > +/* > + * Force the compiler to emit 'sym' as a symbol, so that we can reference > + * it from inline assembler. Necessary in case 'sym' could be inlined > + * otherwise, or eliminated entirely due to lack of references that are > + * visible to the compiler. > + */ > +#define __ADDRESSABLE(sym) \ > + static void * const __attribute__((section(".discard"), used)) \ > + __PASTE(__addressable_##sym, __LINE__) = (void *) > + kernelci.org tells me that I need to drop the 'const' here, or we may end up with .discard sections with conflicting attributes (r/o vs r/w) in some cases (CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y)
[PATCH v8 3/6] 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. Cc: Arnd BergmannCc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 19 include/linux/export.h| 46 +++- kernel/module.c | 32 +++--- 6 files changed, 91 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index de690c2d2e33..a0ab9ab61c75 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -8,5 +8,6 @@ generated-y += xen-hypercalls.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index ab4711c63601..0a9328ea9dbd 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) #endif /* __KERNEL__ */ +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visible to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void * const __attribute__((section(".discard"), used)) \ + __PASTE(__addressable_##sym, __LINE__) = (void *) + +/** + * offset_to_ptr - convert a relative memory offset to an absolute pointer + * @off: the address of the 32-bit offset value + */ +static inline void *offset_to_ptr(const int *off) +{ + return (void *)((unsigned long)off + *off); +} + #endif /* __ASSEMBLY__ */ #ifndef __optimize diff --git a/include/linux/export.h b/include/linux/export.h index 25005b55b079..04c78e6bfec9 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@
[PATCH v8 3/6] 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. Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 19 include/linux/export.h| 46 +++- kernel/module.c | 32 +++--- 6 files changed, 91 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index de690c2d2e33..a0ab9ab61c75 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -8,5 +8,6 @@ generated-y += xen-hypercalls.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index ab4711c63601..0a9328ea9dbd 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) #endif /* __KERNEL__ */ +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visible to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void * const __attribute__((section(".discard"), used)) \ + __PASTE(__addressable_##sym, __LINE__) = (void *) + +/** + * offset_to_ptr - convert a relative memory offset to an absolute pointer + * @off: the address of the 32-bit offset value + */ +static inline void *offset_to_ptr(const int *off) +{ + return (void *)((unsigned long)off + *off); +} + #endif /* __ASSEMBLY__ */ #ifndef __optimize diff --git a/include/linux/export.h b/include/linux/export.h index 25005b55b079..04c78e6bfec9 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +#include +/* + * Emit the
[PATCH v7 03/10] 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. Cc: Arnd BergmannCc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 10 + include/linux/export.h| 46 +++- kernel/module.c | 33 +++--- 6 files changed, 83 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..79db4aa87d75 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -327,4 +327,14 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s compiletime_assert(__native_word(t),\ "Need native word sized stores/loads for atomicity.") +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visible to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void * const __attribute__((section(".discard"), used)) \ + __PASTE(__addressable_##sym, __LINE__) = (void *) + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 6dba2fb08f77..4744cf4736b0 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef
[PATCH v7 03/10] 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. Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 10 + include/linux/export.h| 46 +++- kernel/module.c | 33 +++--- 6 files changed, 83 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..79db4aa87d75 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -327,4 +327,14 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s compiletime_assert(__native_word(t),\ "Need native word sized stores/loads for atomicity.") +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visible to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void * const __attribute__((section(".discard"), used)) \ + __PASTE(__addressable_##sym, __LINE__) = (void *) + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 6dba2fb08f77..4744cf4736b0 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +#include +/* + * Emit the ksymtab entry as a pair of relative references: this reduces + * the size by half on 64-bit
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
Hi Ard, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.15-rc5 next-20171222] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/add-support-for-relative-references-in-special-sections/20171228-171634 config: s390-gcov_defconfig (attached as .config) compiler: s390x-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=s390 All errors (new ones prefixed by >>): >> arch/s390/kernel/ebcdic.o:(.data+0x118): undefined reference to >> `__gcov_merge_add' arch/s390/kernel/ebcdic.o: In function `_GLOBAL__sub_I_00100_0__ascebc': >> ebcdic.c:(.text.startup+0xe): undefined reference to `__gcov_init' arch/s390/kernel/ebcdic.o: In function `_GLOBAL__sub_D_00100_1__ascebc': >> ebcdic.c:(.text.exit+0x8): undefined reference to `__gcov_exit' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
Hi Ard, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.15-rc5 next-20171222] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/add-support-for-relative-references-in-special-sections/20171228-171634 config: s390-gcov_defconfig (attached as .config) compiler: s390x-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=s390 All errors (new ones prefixed by >>): >> arch/s390/kernel/ebcdic.o:(.data+0x118): undefined reference to >> `__gcov_merge_add' arch/s390/kernel/ebcdic.o: In function `_GLOBAL__sub_I_00100_0__ascebc': >> ebcdic.c:(.text.startup+0xe): undefined reference to `__gcov_init' arch/s390/kernel/ebcdic.o: In function `_GLOBAL__sub_D_00100_1__ascebc': >> ebcdic.c:(.text.exit+0x8): undefined reference to `__gcov_exit' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On 28 December 2017 at 12:05, Ingo Molnarwrote: > > * Ard Biesheuvel wrote: > >> Annoyingly, we need this because there is a single instance of a >> special section that ends up in the EFI stub code: we build lib/sort.c >> again as a EFI libstub object, and given that sort() is exported, we >> end up with a ksymtab section in the EFI stub. The sort() thing has >> caused issues before [0], so perhaps I should just clone sort.c into >> drivers/firmware/efi/libstub and get rid of that hack. >> >> [0] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29f9007b3182ab3f328a31da13e6b1c9072f7a95 > > If the root problem is early bootstrap code randomly using generic facility > that > isn't __init, then we should definitely improve tooling to at least detect > these > problems. > > As bootstrap code gets improved (KASLR, more complex decompression, etc. > etc.) we > keep using new bits of generic facilities... > > So this should definitely not be hidden by open coding that function (which > has > various other disadvantages as well), but should be turned from silent > breakage > either into non-breakage (and do so not only for sort() but for other generic > functions as well), or should be turned into a build failure. > We already have safeguards in place to ensure that the arm64 EFI stub (which is essentially the same executable as the kernel proper) only pulls in code that has been made available to it explicitly. That is why sort.c is recompiled for the EFI stub, as well as all other C code that is shared between the stub and the kernel. We also have a build time check to ensure that the resulting code does not rely on absolute symbol references, which will be invalid in the UEFI execution context. So the only problem is that unneeded ksymtab/kcrctab sections, which affected ARM for obscure reasons; typically, they just take up some space. On x86, the kaslr code deals with a similar issue by #define'ing _LINUX_EXPORT_H before including linux/export.h, which also gets rid of these sections, but I was a bit reluctant to copy that pattern. Perhaps we should enhance linux/export.h for reasons such as these by adding a macro that nops out EXPORT_SYMBOL() declarations?
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On 28 December 2017 at 12:05, Ingo Molnar wrote: > > * Ard Biesheuvel wrote: > >> Annoyingly, we need this because there is a single instance of a >> special section that ends up in the EFI stub code: we build lib/sort.c >> again as a EFI libstub object, and given that sort() is exported, we >> end up with a ksymtab section in the EFI stub. The sort() thing has >> caused issues before [0], so perhaps I should just clone sort.c into >> drivers/firmware/efi/libstub and get rid of that hack. >> >> [0] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29f9007b3182ab3f328a31da13e6b1c9072f7a95 > > If the root problem is early bootstrap code randomly using generic facility > that > isn't __init, then we should definitely improve tooling to at least detect > these > problems. > > As bootstrap code gets improved (KASLR, more complex decompression, etc. > etc.) we > keep using new bits of generic facilities... > > So this should definitely not be hidden by open coding that function (which > has > various other disadvantages as well), but should be turned from silent > breakage > either into non-breakage (and do so not only for sort() but for other generic > functions as well), or should be turned into a build failure. > We already have safeguards in place to ensure that the arm64 EFI stub (which is essentially the same executable as the kernel proper) only pulls in code that has been made available to it explicitly. That is why sort.c is recompiled for the EFI stub, as well as all other C code that is shared between the stub and the kernel. We also have a build time check to ensure that the resulting code does not rely on absolute symbol references, which will be invalid in the UEFI execution context. So the only problem is that unneeded ksymtab/kcrctab sections, which affected ARM for obscure reasons; typically, they just take up some space. On x86, the kaslr code deals with a similar issue by #define'ing _LINUX_EXPORT_H before including linux/export.h, which also gets rid of these sections, but I was a bit reluctant to copy that pattern. Perhaps we should enhance linux/export.h for reasons such as these by adding a macro that nops out EXPORT_SYMBOL() declarations?
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
* Ard Biesheuvelwrote: > Annoyingly, we need this because there is a single instance of a > special section that ends up in the EFI stub code: we build lib/sort.c > again as a EFI libstub object, and given that sort() is exported, we > end up with a ksymtab section in the EFI stub. The sort() thing has > caused issues before [0], so perhaps I should just clone sort.c into > drivers/firmware/efi/libstub and get rid of that hack. > > [0] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29f9007b3182ab3f328a31da13e6b1c9072f7a95 If the root problem is early bootstrap code randomly using generic facility that isn't __init, then we should definitely improve tooling to at least detect these problems. As bootstrap code gets improved (KASLR, more complex decompression, etc. etc.) we keep using new bits of generic facilities... So this should definitely not be hidden by open coding that function (which has various other disadvantages as well), but should be turned from silent breakage either into non-breakage (and do so not only for sort() but for other generic functions as well), or should be turned into a build failure. Thanks, Ingo
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
* Ard Biesheuvel wrote: > Annoyingly, we need this because there is a single instance of a > special section that ends up in the EFI stub code: we build lib/sort.c > again as a EFI libstub object, and given that sort() is exported, we > end up with a ksymtab section in the EFI stub. The sort() thing has > caused issues before [0], so perhaps I should just clone sort.c into > drivers/firmware/efi/libstub and get rid of that hack. > > [0] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29f9007b3182ab3f328a31da13e6b1c9072f7a95 If the root problem is early bootstrap code randomly using generic facility that isn't __init, then we should definitely improve tooling to at least detect these problems. As bootstrap code gets improved (KASLR, more complex decompression, etc. etc.) we keep using new bits of generic facilities... So this should definitely not be hidden by open coding that function (which has various other disadvantages as well), but should be turned from silent breakage either into non-breakage (and do so not only for sort() but for other generic functions as well), or should be turned into a build failure. Thanks, Ingo
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On 27 December 2017 at 20:13, Linus Torvaldswrote: > On Wed, Dec 27, 2017 at 12:11 PM, Ard Biesheuvel > wrote: >> >> I tried to keep the generic patches generic, so perhaps I should just >> put the arm64 vmlinux.lds.S change in a patch on its own? > > I guess it doesn't matter, but regardless of where it gets introduced > I would like to see the explanation for where the heck that magical > ".init.discard.text" comes from. It's definitely not obvious from the > patches, and is presumably some odd arm64 special case. > This has to do with the EFI stub. x86 and ARM link it into the decompressor, and so the code and data are not annotated as __init (and doing so would involve modifying a lot of code). arm64 does not have a decompressor, and so the EFI stub is linked into the kernel proper. To make sure the code ends up in the .init segment, all sections are prepended with .init at the object level, using objcopy. Annoyingly, we need this because there is a single instance of a special section that ends up in the EFI stub code: we build lib/sort.c again as a EFI libstub object, and given that sort() is exported, we end up with a ksymtab section in the EFI stub. The sort() thing has caused issues before [0], so perhaps I should just clone sort.c into drivers/firmware/efi/libstub and get rid of that hack. [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29f9007b3182ab3f328a31da13e6b1c9072f7a95
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On 27 December 2017 at 20:13, Linus Torvalds wrote: > On Wed, Dec 27, 2017 at 12:11 PM, Ard Biesheuvel > wrote: >> >> I tried to keep the generic patches generic, so perhaps I should just >> put the arm64 vmlinux.lds.S change in a patch on its own? > > I guess it doesn't matter, but regardless of where it gets introduced > I would like to see the explanation for where the heck that magical > ".init.discard.text" comes from. It's definitely not obvious from the > patches, and is presumably some odd arm64 special case. > This has to do with the EFI stub. x86 and ARM link it into the decompressor, and so the code and data are not annotated as __init (and doing so would involve modifying a lot of code). arm64 does not have a decompressor, and so the EFI stub is linked into the kernel proper. To make sure the code ends up in the .init segment, all sections are prepended with .init at the object level, using objcopy. Annoyingly, we need this because there is a single instance of a special section that ends up in the EFI stub code: we build lib/sort.c again as a EFI libstub object, and given that sort() is exported, we end up with a ksymtab section in the EFI stub. The sort() thing has caused issues before [0], so perhaps I should just clone sort.c into drivers/firmware/efi/libstub and get rid of that hack. [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=29f9007b3182ab3f328a31da13e6b1c9072f7a95
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On Wed, Dec 27, 2017 at 12:11 PM, Ard Biesheuvelwrote: > > I tried to keep the generic patches generic, so perhaps I should just > put the arm64 vmlinux.lds.S change in a patch on its own? I guess it doesn't matter, but regardless of where it gets introduced I would like to see the explanation for where the heck that magical ".init.discard.text" comes from. It's definitely not obvious from the patches, and is presumably some odd arm64 special case. Linus
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On Wed, Dec 27, 2017 at 12:11 PM, Ard Biesheuvel wrote: > > I tried to keep the generic patches generic, so perhaps I should just > put the arm64 vmlinux.lds.S change in a patch on its own? I guess it doesn't matter, but regardless of where it gets introduced I would like to see the explanation for where the heck that magical ".init.discard.text" comes from. It's definitely not obvious from the patches, and is presumably some odd arm64 special case. Linus
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On 27 December 2017 at 20:07, Linus Torvaldswrote: > On Wed, Dec 27, 2017 at 12:50 AM, Ard Biesheuvel > wrote: >> diff --git a/include/linux/compiler.h b/include/linux/compiler.h >> index 52e611ab9a6c..fe752d365334 100644 >> --- a/include/linux/compiler.h >> +++ b/include/linux/compiler.h >> @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile >> void *p, void *res, int s >> compiletime_assert(__native_word(t),\ >> "Need native word sized stores/loads for atomicity.") >> >> +/* >> + * Force the compiler to emit 'sym' as a symbol, so that we can reference >> + * it from inline assembler. Necessary in case 'sym' could be inlined >> + * otherwise, or eliminated entirely due to lack of references that are >> + * visibile to the compiler. >> + */ >> +#define __ADDRESSABLE(sym) \ >> + static void *__attribute__((section(".discard.text"), used))\ >> + __PASTE(__discard_##sym, __LINE__)(void)\ >> + { return (void *) }\ >> + >> #endif /* __LINUX_COMPILER_H */ > > Isn't this logically the point where you should add the arm64 > vmlinux.lds.S change, and explain how ".discard.text" turns into > ".init.discard.text" for some odd arm64 reason? > I tried to keep the generic patches generic, so perhaps I should just put the arm64 vmlinux.lds.S change in a patch on its own?
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On 27 December 2017 at 20:07, Linus Torvalds wrote: > On Wed, Dec 27, 2017 at 12:50 AM, Ard Biesheuvel > wrote: >> diff --git a/include/linux/compiler.h b/include/linux/compiler.h >> index 52e611ab9a6c..fe752d365334 100644 >> --- a/include/linux/compiler.h >> +++ b/include/linux/compiler.h >> @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile >> void *p, void *res, int s >> compiletime_assert(__native_word(t),\ >> "Need native word sized stores/loads for atomicity.") >> >> +/* >> + * Force the compiler to emit 'sym' as a symbol, so that we can reference >> + * it from inline assembler. Necessary in case 'sym' could be inlined >> + * otherwise, or eliminated entirely due to lack of references that are >> + * visibile to the compiler. >> + */ >> +#define __ADDRESSABLE(sym) \ >> + static void *__attribute__((section(".discard.text"), used))\ >> + __PASTE(__discard_##sym, __LINE__)(void)\ >> + { return (void *) }\ >> + >> #endif /* __LINUX_COMPILER_H */ > > Isn't this logically the point where you should add the arm64 > vmlinux.lds.S change, and explain how ".discard.text" turns into > ".init.discard.text" for some odd arm64 reason? > I tried to keep the generic patches generic, so perhaps I should just put the arm64 vmlinux.lds.S change in a patch on its own?
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On Wed, Dec 27, 2017 at 12:50 AM, Ard Biesheuvelwrote: > diff --git a/include/linux/compiler.h b/include/linux/compiler.h > index 52e611ab9a6c..fe752d365334 100644 > --- a/include/linux/compiler.h > +++ b/include/linux/compiler.h > @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile > void *p, void *res, int s > compiletime_assert(__native_word(t),\ > "Need native word sized stores/loads for atomicity.") > > +/* > + * Force the compiler to emit 'sym' as a symbol, so that we can reference > + * it from inline assembler. Necessary in case 'sym' could be inlined > + * otherwise, or eliminated entirely due to lack of references that are > + * visibile to the compiler. > + */ > +#define __ADDRESSABLE(sym) \ > + static void *__attribute__((section(".discard.text"), used))\ > + __PASTE(__discard_##sym, __LINE__)(void)\ > + { return (void *) }\ > + > #endif /* __LINUX_COMPILER_H */ Isn't this logically the point where you should add the arm64 vmlinux.lds.S change, and explain how ".discard.text" turns into ".init.discard.text" for some odd arm64 reason? Linus
Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries
On Wed, Dec 27, 2017 at 12:50 AM, Ard Biesheuvel wrote: > diff --git a/include/linux/compiler.h b/include/linux/compiler.h > index 52e611ab9a6c..fe752d365334 100644 > --- a/include/linux/compiler.h > +++ b/include/linux/compiler.h > @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile > void *p, void *res, int s > compiletime_assert(__native_word(t),\ > "Need native word sized stores/loads for atomicity.") > > +/* > + * Force the compiler to emit 'sym' as a symbol, so that we can reference > + * it from inline assembler. Necessary in case 'sym' could be inlined > + * otherwise, or eliminated entirely due to lack of references that are > + * visibile to the compiler. > + */ > +#define __ADDRESSABLE(sym) \ > + static void *__attribute__((section(".discard.text"), used))\ > + __PASTE(__discard_##sym, __LINE__)(void)\ > + { return (void *) }\ > + > #endif /* __LINUX_COMPILER_H */ Isn't this logically the point where you should add the arm64 vmlinux.lds.S change, and explain how ".discard.text" turns into ".init.discard.text" for some odd arm64 reason? Linus
[PATCH v6 2/8] 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. Cc: Arnd BergmannCc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 11 + include/linux/export.h| 46 +++- kernel/module.c | 33 +++--- 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..fe752d365334 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s compiletime_assert(__native_word(t),\ "Need native word sized stores/loads for atomicity.") +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used))\ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..5112d0c41512 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern
[PATCH v6 2/8] 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. Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 11 + include/linux/export.h| 46 +++- kernel/module.c | 33 +++--- 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..fe752d365334 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s compiletime_assert(__native_word(t),\ "Need native word sized stores/loads for atomicity.") +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used))\ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..5112d0c41512 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +#include +/* + * Emit the ksymtab entry as a pair of
[PATCH v5 2/8] 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. Cc: Arnd BergmannCc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 11 + include/linux/export.h| 46 +++- kernel/module.c | 33 +++--- 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..fe752d365334 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s compiletime_assert(__native_word(t),\ "Need native word sized stores/loads for atomicity.") +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used))\ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..5112d0c41512 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern
[PATCH v5 2/8] 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. Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Acked-by: Jessica Yu Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 5 --- include/asm-generic/export.h | 12 - include/linux/compiler.h | 11 + include/linux/export.h| 46 +++- kernel/module.c | 33 +++--- 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 2a51d66689c5.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 52e611ab9a6c..fe752d365334 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -327,4 +327,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s compiletime_assert(__native_word(t),\ "Need native word sized stores/loads for atomicity.") +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used))\ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..5112d0c41512 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,47 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +#include +/* + * Emit the ksymtab entry as a pair of
Re: module: use relative references for __ksymtab entries
> On 9 Sep 2017, at 16:33, Thomas Garnierwrote: > >> On Sat, Sep 9, 2017 at 6:08 AM, Jessica Yu wrote: >> +++ Ard Biesheuvel [19/08/17 19:10 +0100]: >> >>> 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 dependend on whether >>> CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. > > Good idea, I assume we may still get relocations given the compiler is > pretty bad at optimizing (_ptr - .) but I might be wrong. The point is that the resulting place relative static relocations are fixed up at link time (and discarded) rather than being converted into dynamic R_xxx_RELATIVE relocations that require fixing up at runtime. The compiler rarely emits place relative relocations, in my experience, but this is probably highly arch and CFLAGS dependent. I am not sure what you mean by 'optimizing' ( - . ): if such expressions are emitted into asm, it is up to the assembler to fully resolve the expression or emit a place relative relocation, depending in whether has external linkage. > Anyway, the > size decrease is great and we can ignore these relocations if need be. Yes, if you are using --emit-relocs and mangling static relocations manually (which I suppose is the case for x86), you can add any resulting place relative relocations to the ignore list, although I would assume they are already on it. Thanks. >>> >>> Cc: Jessica Yu >>> Cc: Arnd Bergmann >>> Cc: Andrew Morton >>> Cc: Ingo Molnar >>> Cc: Kees Cook >>> Cc: Thomas Garnier >>> Cc: Nicolas Pitre >>> Signed-off-by: Ard Biesheuvel >> >> >> I ran this through some light testing and the relative ksymtab >> references seem to work just fine: >> >> Acked-by: Jessica Yu (for module changes) >> >> >>> arch/x86/include/asm/Kbuild | 1 + >>> arch/x86/include/asm/export.h | 4 -- >>> include/asm-generic/export.h | 12 +- >>> include/linux/compiler.h | 11 + >>> include/linux/export.h| 45 +++- >>> kernel/module.c | 33 +++--- >>> 6 files changed, 83 insertions(+), 23 deletions(-) >>> >>> diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild >>> index 5d6a53fd7521..3e8a88dcaa1d 100644 >>> --- a/arch/x86/include/asm/Kbuild >>> +++ b/arch/x86/include/asm/Kbuild >>> @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h >>> generic-y += clkdev.h >>> generic-y += dma-contiguous.h >>> generic-y += early_ioremap.h >>> +generic-y += export.h >>> generic-y += mcs_spinlock.h >>> generic-y += mm-arch-hooks.h >>> diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h >>> deleted file mode 100644 >>> index 138de56b13eb.. >>> --- a/arch/x86/include/asm/export.h >>> +++ /dev/null >>> @@ -1,4 +0,0 @@ >>> -#ifdef CONFIG_64BIT >>> -#define KSYM_ALIGN 16 >>> -#endif >>> -#include >>> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h >>> index 719db1968d81..97ce606459ae 100644 >>> --- a/include/asm-generic/export.h >>> +++ b/include/asm-generic/export.h >>> @@ -5,12 +5,10 @@ >>> #define KSYM_FUNC(x) x >>> #endif >>> #ifdef CONFIG_64BIT >>> -#define __put .quad >>> #ifndef KSYM_ALIGN >>> #define KSYM_ALIGN 8 >>> #endif >>> #else >>> -#define __put .long >>> #ifndef KSYM_ALIGN >>> #define KSYM_ALIGN 4 >>> #endif >>> @@ -25,6 +23,16 @@ >>> #define KSYM(name) name >>> #endif >>> >>> +.macro __put, val, name >>> +#ifdef
Re: module: use relative references for __ksymtab entries
> On 9 Sep 2017, at 16:33, Thomas Garnier wrote: > >> On Sat, Sep 9, 2017 at 6:08 AM, Jessica Yu wrote: >> +++ Ard Biesheuvel [19/08/17 19:10 +0100]: >> >>> 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 dependend on whether >>> CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. > > Good idea, I assume we may still get relocations given the compiler is > pretty bad at optimizing (_ptr - .) but I might be wrong. The point is that the resulting place relative static relocations are fixed up at link time (and discarded) rather than being converted into dynamic R_xxx_RELATIVE relocations that require fixing up at runtime. The compiler rarely emits place relative relocations, in my experience, but this is probably highly arch and CFLAGS dependent. I am not sure what you mean by 'optimizing' ( - . ): if such expressions are emitted into asm, it is up to the assembler to fully resolve the expression or emit a place relative relocation, depending in whether has external linkage. > Anyway, the > size decrease is great and we can ignore these relocations if need be. Yes, if you are using --emit-relocs and mangling static relocations manually (which I suppose is the case for x86), you can add any resulting place relative relocations to the ignore list, although I would assume they are already on it. Thanks. >>> >>> Cc: Jessica Yu >>> Cc: Arnd Bergmann >>> Cc: Andrew Morton >>> Cc: Ingo Molnar >>> Cc: Kees Cook >>> Cc: Thomas Garnier >>> Cc: Nicolas Pitre >>> Signed-off-by: Ard Biesheuvel >> >> >> I ran this through some light testing and the relative ksymtab >> references seem to work just fine: >> >> Acked-by: Jessica Yu (for module changes) >> >> >>> arch/x86/include/asm/Kbuild | 1 + >>> arch/x86/include/asm/export.h | 4 -- >>> include/asm-generic/export.h | 12 +- >>> include/linux/compiler.h | 11 + >>> include/linux/export.h| 45 +++- >>> kernel/module.c | 33 +++--- >>> 6 files changed, 83 insertions(+), 23 deletions(-) >>> >>> diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild >>> index 5d6a53fd7521..3e8a88dcaa1d 100644 >>> --- a/arch/x86/include/asm/Kbuild >>> +++ b/arch/x86/include/asm/Kbuild >>> @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h >>> generic-y += clkdev.h >>> generic-y += dma-contiguous.h >>> generic-y += early_ioremap.h >>> +generic-y += export.h >>> generic-y += mcs_spinlock.h >>> generic-y += mm-arch-hooks.h >>> diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h >>> deleted file mode 100644 >>> index 138de56b13eb.. >>> --- a/arch/x86/include/asm/export.h >>> +++ /dev/null >>> @@ -1,4 +0,0 @@ >>> -#ifdef CONFIG_64BIT >>> -#define KSYM_ALIGN 16 >>> -#endif >>> -#include >>> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h >>> index 719db1968d81..97ce606459ae 100644 >>> --- a/include/asm-generic/export.h >>> +++ b/include/asm-generic/export.h >>> @@ -5,12 +5,10 @@ >>> #define KSYM_FUNC(x) x >>> #endif >>> #ifdef CONFIG_64BIT >>> -#define __put .quad >>> #ifndef KSYM_ALIGN >>> #define KSYM_ALIGN 8 >>> #endif >>> #else >>> -#define __put .long >>> #ifndef KSYM_ALIGN >>> #define KSYM_ALIGN 4 >>> #endif >>> @@ -25,6 +23,16 @@ >>> #define KSYM(name) name >>> #endif >>> >>> +.macro __put, val, name >>> +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS >>> + .long \val - ., \name - . >>> +#elif defined(CONFIG_64BIT) >>> + .quad \val, \name >>> +#else >>> + .long \val, \name >>> +#endif >>> +.endm >>> + >>> /* >>> * note on
Re: module: use relative references for __ksymtab entries
On Sat, Sep 9, 2017 at 6:08 AM, Jessica Yuwrote: > +++ Ard Biesheuvel [19/08/17 19:10 +0100]: > >> 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 dependend on whether >> CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Good idea, I assume we may still get relocations given the compiler is pretty bad at optimizing (_ptr - .) but I might be wrong. Anyway, the size decrease is great and we can ignore these relocations if need be. Thanks. >> >> Cc: Jessica Yu >> Cc: Arnd Bergmann >> Cc: Andrew Morton >> Cc: Ingo Molnar >> Cc: Kees Cook >> Cc: Thomas Garnier >> Cc: Nicolas Pitre >> Signed-off-by: Ard Biesheuvel > > > I ran this through some light testing and the relative ksymtab > references seem to work just fine: > > Acked-by: Jessica Yu (for module changes) > > >> arch/x86/include/asm/Kbuild | 1 + >> arch/x86/include/asm/export.h | 4 -- >> include/asm-generic/export.h | 12 +- >> include/linux/compiler.h | 11 + >> include/linux/export.h| 45 +++- >> kernel/module.c | 33 +++--- >> 6 files changed, 83 insertions(+), 23 deletions(-) >> >> diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild >> index 5d6a53fd7521..3e8a88dcaa1d 100644 >> --- a/arch/x86/include/asm/Kbuild >> +++ b/arch/x86/include/asm/Kbuild >> @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h >> generic-y += clkdev.h >> generic-y += dma-contiguous.h >> generic-y += early_ioremap.h >> +generic-y += export.h >> generic-y += mcs_spinlock.h >> generic-y += mm-arch-hooks.h >> diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h >> deleted file mode 100644 >> index 138de56b13eb.. >> --- a/arch/x86/include/asm/export.h >> +++ /dev/null >> @@ -1,4 +0,0 @@ >> -#ifdef CONFIG_64BIT >> -#define KSYM_ALIGN 16 >> -#endif >> -#include >> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h >> index 719db1968d81..97ce606459ae 100644 >> --- a/include/asm-generic/export.h >> +++ b/include/asm-generic/export.h >> @@ -5,12 +5,10 @@ >> #define KSYM_FUNC(x) x >> #endif >> #ifdef CONFIG_64BIT >> -#define __put .quad >> #ifndef KSYM_ALIGN >> #define KSYM_ALIGN 8 >> #endif >> #else >> -#define __put .long >> #ifndef KSYM_ALIGN >> #define KSYM_ALIGN 4 >> #endif >> @@ -25,6 +23,16 @@ >> #define KSYM(name) name >> #endif >> >> +.macro __put, val, name >> +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS >> + .long \val - ., \name - . >> +#elif defined(CONFIG_64BIT) >> + .quad \val, \name >> +#else >> + .long \val, \name >> +#endif >> +.endm >> + >> /* >> * note on .section use: @progbits vs %progbits nastiness doesn't matter, >> * since we immediately emit into those sections anyway. >> diff --git a/include/linux/compiler.h b/include/linux/compiler.h >> index eca8ad75e28b..363fb3e734ec 100644 >> --- a/include/linux/compiler.h >> +++ b/include/linux/compiler.h >> @@ -590,4 +590,15 @@ static __always_inline void >> __write_once_size(volatile void *p, void *res, int s >> (_p1); \ >> }) >> >> +/* >> + * Force the compiler to emit 'sym' as a symbol, so that we can reference >> + * it from inline assembler. Necessary in case 'sym' could be inlined >> + * otherwise, or eliminated entirely due to lack of references that are >> + * visibile to the compiler. >> + */ >> +#define __ADDRESSABLE(sym) \ >> + static void
Re: module: use relative references for __ksymtab entries
On Sat, Sep 9, 2017 at 6:08 AM, Jessica Yu wrote: > +++ Ard Biesheuvel [19/08/17 19:10 +0100]: > >> 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 dependend on whether >> CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Good idea, I assume we may still get relocations given the compiler is pretty bad at optimizing (_ptr - .) but I might be wrong. Anyway, the size decrease is great and we can ignore these relocations if need be. Thanks. >> >> Cc: Jessica Yu >> Cc: Arnd Bergmann >> Cc: Andrew Morton >> Cc: Ingo Molnar >> Cc: Kees Cook >> Cc: Thomas Garnier >> Cc: Nicolas Pitre >> Signed-off-by: Ard Biesheuvel > > > I ran this through some light testing and the relative ksymtab > references seem to work just fine: > > Acked-by: Jessica Yu (for module changes) > > >> arch/x86/include/asm/Kbuild | 1 + >> arch/x86/include/asm/export.h | 4 -- >> include/asm-generic/export.h | 12 +- >> include/linux/compiler.h | 11 + >> include/linux/export.h| 45 +++- >> kernel/module.c | 33 +++--- >> 6 files changed, 83 insertions(+), 23 deletions(-) >> >> diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild >> index 5d6a53fd7521..3e8a88dcaa1d 100644 >> --- a/arch/x86/include/asm/Kbuild >> +++ b/arch/x86/include/asm/Kbuild >> @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h >> generic-y += clkdev.h >> generic-y += dma-contiguous.h >> generic-y += early_ioremap.h >> +generic-y += export.h >> generic-y += mcs_spinlock.h >> generic-y += mm-arch-hooks.h >> diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h >> deleted file mode 100644 >> index 138de56b13eb.. >> --- a/arch/x86/include/asm/export.h >> +++ /dev/null >> @@ -1,4 +0,0 @@ >> -#ifdef CONFIG_64BIT >> -#define KSYM_ALIGN 16 >> -#endif >> -#include >> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h >> index 719db1968d81..97ce606459ae 100644 >> --- a/include/asm-generic/export.h >> +++ b/include/asm-generic/export.h >> @@ -5,12 +5,10 @@ >> #define KSYM_FUNC(x) x >> #endif >> #ifdef CONFIG_64BIT >> -#define __put .quad >> #ifndef KSYM_ALIGN >> #define KSYM_ALIGN 8 >> #endif >> #else >> -#define __put .long >> #ifndef KSYM_ALIGN >> #define KSYM_ALIGN 4 >> #endif >> @@ -25,6 +23,16 @@ >> #define KSYM(name) name >> #endif >> >> +.macro __put, val, name >> +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS >> + .long \val - ., \name - . >> +#elif defined(CONFIG_64BIT) >> + .quad \val, \name >> +#else >> + .long \val, \name >> +#endif >> +.endm >> + >> /* >> * note on .section use: @progbits vs %progbits nastiness doesn't matter, >> * since we immediately emit into those sections anyway. >> diff --git a/include/linux/compiler.h b/include/linux/compiler.h >> index eca8ad75e28b..363fb3e734ec 100644 >> --- a/include/linux/compiler.h >> +++ b/include/linux/compiler.h >> @@ -590,4 +590,15 @@ static __always_inline void >> __write_once_size(volatile void *p, void *res, int s >> (_p1); \ >> }) >> >> +/* >> + * Force the compiler to emit 'sym' as a symbol, so that we can reference >> + * it from inline assembler. Necessary in case 'sym' could be inlined >> + * otherwise, or eliminated entirely due to lack of references that are >> + * visibile to the compiler. >> + */ >> +#define __ADDRESSABLE(sym) \ >> + static void *__attribute__((section(".discard.text"), used))\ >> + __PASTE(__discard_##sym, __LINE__)(void)\ >> + { return (void *) }\ >> + >> #endif /*
Re: module: use relative references for __ksymtab entries
+++ Ard Biesheuvel [19/08/17 19:10 +0100]: 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica YuCc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel I ran this through some light testing and the relative ksymtab references seem to work just fine: Acked-by: Jessica Yu (for module changes) arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 +- include/linux/compiler.h | 11 + include/linux/export.h| 45 +++- kernel/module.c | 33 +++--- 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..363fb3e734ec 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used)) \ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..156b974181a4 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,46 @@ extern
Re: module: use relative references for __ksymtab entries
+++ Ard Biesheuvel [19/08/17 19:10 +0100]: 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica Yu Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel I ran this through some light testing and the relative ksymtab references seem to work just fine: Acked-by: Jessica Yu (for module changes) arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 +- include/linux/compiler.h | 11 + include/linux/export.h| 45 +++- kernel/module.c | 33 +++--- 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..363fb3e734ec 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used)) \ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..156b974181a4 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,46 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of relative references: this
[PATCH v3 2/5] 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica YuCc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 +- include/linux/compiler.h | 11 + include/linux/export.h| 45 +++- kernel/module.c | 33 +++--- 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..363fb3e734ec 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used))\ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..156b974181a4 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,46 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of
[PATCH v3 2/5] 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica Yu Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 +- include/linux/compiler.h | 11 + include/linux/export.h| 45 +++- kernel/module.c | 33 +++--- 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..363fb3e734ec 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"), used))\ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..156b974181a4 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,46 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of relative references: this reduces + * the size by half on 64-bit architectures, and eliminates the need for + * absolute relocations that require runtime processing on
[PATCH v2 2/6] 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica YuCc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 +++- include/linux/compiler.h | 11 include/linux/export.h| 68 kernel/module.c | 14 ++-- 6 files changed, 86 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..3e0b707664b1 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"))) __used \ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..896883a44be3 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,67 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of relative references:
[PATCH v2 2/6] 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica Yu Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 +++- include/linux/compiler.h | 11 include/linux/export.h| 68 kernel/module.c | 14 ++-- 6 files changed, 86 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..3e0b707664b1 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void *__attribute__((section(".discard.text"))) __used \ + __PASTE(__discard_##sym, __LINE__)(void)\ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..896883a44be3 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,67 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of relative references: this reduces + * the size by half on 64-bit architectures, and eliminates the need for + * absolute relocations that require runtime processing on relocatable + *
[PATCH 2/5] 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica YuCc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 - include/linux/compiler.h | 11 + include/linux/export.h| 47 +++- kernel/module.c | 33 +++--- 6 files changed, 85 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..5644d2e653f0 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void * __attribute__((section(".discard.text"), used)) \ + __PASTE(__discard_##sym,__LINE__)(void) \ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..986d02e57253 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,48 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of relative
[PATCH 2/5] 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 dependend on whether CONFIG_HAVE_ARCH_PREL32_RELOCATIONS is defined. Cc: Jessica Yu Cc: Arnd Bergmann Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/export.h | 4 -- include/asm-generic/export.h | 12 - include/linux/compiler.h | 11 + include/linux/export.h| 47 +++- kernel/module.c | 33 +++--- 6 files changed, 85 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 5d6a53fd7521..3e8a88dcaa1d 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -9,5 +9,6 @@ generated-y += xen-hypercalls.h generic-y += clkdev.h generic-y += dma-contiguous.h generic-y += early_ioremap.h +generic-y += export.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h deleted file mode 100644 index 138de56b13eb.. --- a/arch/x86/include/asm/export.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef CONFIG_64BIT -#define KSYM_ALIGN 16 -#endif -#include diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..97ce606459ae 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -5,12 +5,10 @@ #define KSYM_FUNC(x) x #endif #ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif #else -#define __put .long #ifndef KSYM_ALIGN #define KSYM_ALIGN 4 #endif @@ -25,6 +23,16 @@ #define KSYM(name) name #endif +.macro __put, val, name +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + .long \val - ., \name - . +#elif defined(CONFIG_64BIT) + .quad \val, \name +#else + .long \val, \name +#endif +.endm + /* * note on .section use: @progbits vs %progbits nastiness doesn't matter, * since we immediately emit into those sections anyway. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index eca8ad75e28b..5644d2e653f0 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -590,4 +590,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s (_p1); \ }) +/* + * Force the compiler to emit 'sym' as a symbol, so that we can reference + * it from inline assembler. Necessary in case 'sym' could be inlined + * otherwise, or eliminated entirely due to lack of references that are + * visibile to the compiler. + */ +#define __ADDRESSABLE(sym) \ + static void * __attribute__((section(".discard.text"), used)) \ + __PASTE(__discard_##sym,__LINE__)(void) \ + { return (void *) }\ + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..986d02e57253 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,48 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +/* + * Emit the ksymtab entry as a pair of relative references: this reduces + * the size by half on 64-bit architectures, and eliminates the need for + * absolute relocations that require runtime processing on
Re: [PATCH v2] module: use relative references for __ksymtab entries
Hi Ard, [auto build test ERROR on linus/master] [also build test ERROR on v4.13-rc3 next-20170804] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/module-use-relative-references-for-__ksymtab-entries/20170806-205309 config: x86_64-allyesdebian (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/preempt.h:5, from include/linux/preempt.h:80, from include/linux/spinlock.h:50, from include/linux/mmzone.h:7, from include/linux/gfp.h:5, from include/linux/slab.h:14, from kernel/fork.c:14: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_cached_stacks causes >> a section type conflict with __discard_lockdep_tasklist_lock_is_held __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ kernel/fork.c:181:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from include/asm-generic/bug.h:15, from arch/x86/include/asm/bug.h:81, from include/linux/bug.h:4, from include/linux/mmdebug.h:4, from include/linux/gfp.h:4, from include/linux/slab.h:14, from kernel/fork.c:14: include/linux/export.h:71:4: note: '__discard_lockdep_tasklist_lock_is_held' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:111:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "_gpl") ^~~ kernel/fork.c:131:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held); ^ -- In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/preempt.h:5, from include/linux/preempt.h:80, from include/linux/spinlock.h:50, from include/linux/mmzone.h:7, from include/linux/gfp.h:5, from include/linux/slab.h:14, from mm/slab.c:89: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_slab_reap_node >> causes a section type conflict with __discard_kmem_cache_alloc __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ >> mm/slab.c:524:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(unsigned long, slab_reap_node); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from include/asm-generic/bug.h:15, from arch/x86/include/asm/bug.h:81, from include/linux/bug.h:4, from include/linux/mmdebug.h:4, from include/linux/gfp.h:4, from include/linux/slab.h:14, from mm/slab.c:89: include/linux/export.h:71:4: note: '__discard_kmem_cache_alloc' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:108:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "") ^~~ mm/slab.c:3567:1: note: in expansion of macro 'EXPORT_SYMBOL' EXPORT_SYMBOL(kmem_cache_alloc); ^ vim +92 include/linux/percpu-defs.h 62fde541 Tejun Heo 2014-06-17 37 5028eaa9 David Howells 2009-04-21 38 /* 5028eaa9 David Howells 2009-04-21 39 * Base implementat
Re: [PATCH v2] module: use relative references for __ksymtab entries
Hi Ard, [auto build test ERROR on linus/master] [also build test ERROR on v4.13-rc3 next-20170804] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/module-use-relative-references-for-__ksymtab-entries/20170806-205309 config: x86_64-allyesdebian (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/preempt.h:5, from include/linux/preempt.h:80, from include/linux/spinlock.h:50, from include/linux/mmzone.h:7, from include/linux/gfp.h:5, from include/linux/slab.h:14, from kernel/fork.c:14: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_cached_stacks causes >> a section type conflict with __discard_lockdep_tasklist_lock_is_held __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ kernel/fork.c:181:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from include/asm-generic/bug.h:15, from arch/x86/include/asm/bug.h:81, from include/linux/bug.h:4, from include/linux/mmdebug.h:4, from include/linux/gfp.h:4, from include/linux/slab.h:14, from kernel/fork.c:14: include/linux/export.h:71:4: note: '__discard_lockdep_tasklist_lock_is_held' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:111:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "_gpl") ^~~ kernel/fork.c:131:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held); ^ -- In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/preempt.h:5, from include/linux/preempt.h:80, from include/linux/spinlock.h:50, from include/linux/mmzone.h:7, from include/linux/gfp.h:5, from include/linux/slab.h:14, from mm/slab.c:89: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_slab_reap_node >> causes a section type conflict with __discard_kmem_cache_alloc __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ >> mm/slab.c:524:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(unsigned long, slab_reap_node); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from include/asm-generic/bug.h:15, from arch/x86/include/asm/bug.h:81, from include/linux/bug.h:4, from include/linux/mmdebug.h:4, from include/linux/gfp.h:4, from include/linux/slab.h:14, from mm/slab.c:89: include/linux/export.h:71:4: note: '__discard_kmem_cache_alloc' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:108:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "") ^~~ mm/slab.c:3567:1: note: in expansion of macro 'EXPORT_SYMBOL' EXPORT_SYMBOL(kmem_cache_alloc); ^ vim +92 include/linux/percpu-defs.h 62fde541 Tejun Heo 2014-06-17 37 5028eaa9 David Howells 2009-04-21 38 /* 5028eaa9 David Howells 2009-04-21 39 * Base implementat
Re: [PATCH v2] module: use relative references for __ksymtab entries
Hi Ard, [auto build test ERROR on linus/master] [also build test ERROR on v4.13-rc3 next-20170804] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/module-use-relative-references-for-__ksymtab-entries/20170806-205309 config: x86_64-allyesdebian (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel//locking/lockdep.c:29: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_cpu_lock_stats >> causes a section type conflict with __discard_lockdep_off __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ kernel//locking/lockdep.c:156:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from arch/x86/include/asm/percpu.h:44, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel//locking/lockdep.c:29: include/linux/export.h:71:4: note: '__discard_lockdep_off' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:108:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "") ^~~ kernel//locking/lockdep.c:329:1: note: in expansion of macro 'EXPORT_SYMBOL' EXPORT_SYMBOL(lockdep_off); ^ -- In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel///locking/lockdep.c:29: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_cpu_lock_stats >> causes a section type conflict with __discard_lockdep_off __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ kernel///locking/lockdep.c:156:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from arch/x86/include/asm/percpu.h:44, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel///locking/lockdep.c:29: include/linux/export.h:71:4: note: '__discard_lockdep_off' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:108:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "") ^~~ kernel///locking/lockdep.c:329:1: note: in expansion of macro 'EXPORT_SYMBOL' EXPORT_SYMBOL(lockdep_off); ^ vim +92 include/linux/percpu-defs.h 62fde541 Tejun Heo 2014-06-17 37 5028eaa9 David Howells 2009-04-21 38 /* 5028eaa9 David Howells 2009-04-21 39 * Base implementations of per-CPU variable declarations and definitions, where 5028eaa9 David Howells 2009-04-21 40 * the section in which the variable is to be placed is provided by the 7c756e6e Tejun Heo 2009-06-24 41 * 'sec' argument. This may be used to affect the parameters governing the 5028eaa9 David Howells 2009-04-21 42 * variable's storage. 5028eaa9 David Howells 2009-04-21 43 * 5028eaa9 David Howells 2009-04-21 44 * NOTE! The sections for the DECLARE and for the DEFINE must match, lest 5028eaa9 David Howells 2009-04-21 45 * linkage errors occur due the compiler generating the wrong code to access 5028eaa9
Re: [PATCH v2] module: use relative references for __ksymtab entries
Hi Ard, [auto build test ERROR on linus/master] [also build test ERROR on v4.13-rc3 next-20170804] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ard-Biesheuvel/module-use-relative-references-for-__ksymtab-entries/20170806-205309 config: x86_64-allyesdebian (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel//locking/lockdep.c:29: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_cpu_lock_stats >> causes a section type conflict with __discard_lockdep_off __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ kernel//locking/lockdep.c:156:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from arch/x86/include/asm/percpu.h:44, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel//locking/lockdep.c:29: include/linux/export.h:71:4: note: '__discard_lockdep_off' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:108:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "") ^~~ kernel//locking/lockdep.c:329:1: note: in expansion of macro 'EXPORT_SYMBOL' EXPORT_SYMBOL(lockdep_off); ^ -- In file included from include/asm-generic/percpu.h:6:0, from arch/x86/include/asm/percpu.h:542, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel///locking/lockdep.c:29: >> include/linux/percpu-defs.h:92:26: error: __pcpu_unique_cpu_lock_stats >> causes a section type conflict with __discard_lockdep_off __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^ include/linux/percpu-defs.h:116:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ kernel///locking/lockdep.c:156:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); ^~ In file included from include/linux/linkage.h:6:0, from include/linux/kernel.h:6, from arch/x86/include/asm/percpu.h:44, from arch/x86/include/asm/current.h:5, from include/linux/mutex.h:13, from kernel///locking/lockdep.c:29: include/linux/export.h:71:4: note: '__discard_lockdep_off' was declared here __discard_##sym(void) { return (void *) } \ ^ include/linux/export.h:104:25: note: in expansion of macro '___EXPORT_SYMBOL' #define __EXPORT_SYMBOL ___EXPORT_SYMBOL ^~~~ include/linux/export.h:108:2: note: in expansion of macro '__EXPORT_SYMBOL' __EXPORT_SYMBOL(sym, "") ^~~ kernel///locking/lockdep.c:329:1: note: in expansion of macro 'EXPORT_SYMBOL' EXPORT_SYMBOL(lockdep_off); ^ vim +92 include/linux/percpu-defs.h 62fde541 Tejun Heo 2014-06-17 37 5028eaa9 David Howells 2009-04-21 38 /* 5028eaa9 David Howells 2009-04-21 39 * Base implementations of per-CPU variable declarations and definitions, where 5028eaa9 David Howells 2009-04-21 40 * the section in which the variable is to be placed is provided by the 7c756e6e Tejun Heo 2009-06-24 41 * 'sec' argument. This may be used to affect the parameters governing the 5028eaa9 David Howells 2009-04-21 42 * variable's storage. 5028eaa9 David Howells 2009-04-21 43 * 5028eaa9 David Howells 2009-04-21 44 * NOTE! The sections for the DECLARE and for the DEFINE must match, lest 5028eaa9 David Howells 2009-04-21 45 * linkage errors occur due the compiler generating the wrong code to access 5028eaa9
[PATCH v2] 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). Since EXPORT_SYMBOL() no longer refers to struct kernel_symbol, move the definition into module.c, which is its only user. 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. Cc: Jessica YuCc: Arnd Bergmann Cc: Russell King Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- v2: - fix error in modpost due to missing local __ksymtab_xxx symbol names Note that ARM requires a little tweak to ensure that the unwind info related to the discarded code is discarded as well. I'm sure there will be an arch or two where something similar may be required. arch/arm/kernel/vmlinux.lds.S | 1 + include/asm-generic/export.h | 10 +-- include/linux/export.h| 28 ++ kernel/module.c | 31 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index c83a7ba737d6..4bdba75e510c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -89,6 +89,7 @@ SECTIONS #endif *(.discard) *(.discard.*) + *(.ARM.exidx.discard) } . = PAGE_OFFSET + TEXT_OFFSET; diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..fac5b2e6df37 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -4,17 +4,9 @@ #ifndef KSYM_FUNC #define KSYM_FUNC(x) x #endif -#ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif -#else -#define __put .long -#ifndef KSYM_ALIGN -#define KSYM_ALIGN 4 -#endif -#endif #ifndef KCRC_ALIGN #define KCRC_ALIGN 4 #endif @@ -35,7 +27,7 @@ .section ___ksymtab\sec+\name,"a" .balign KSYM_ALIGN KSYM(__ksymtab_\name): - __put \val, KSYM(__kstrtab_\name) + .long \val - ., KSYM(__kstrtab_\name) - . .previous .section __ksymtab_strings,"a" KSYM(__kstrtab_\name): diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..943656d74f0c 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,27 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif -/* For every exported symbol, place a struct in the __ksymtab section */ +/* + * For every exported symbol, place a struct in the __ksymtab section. + * Note that we have to visibly take the address of sym, so the compiler + * is forced to emit it, rather than inlining it or removing it + * altogether. Do so in a way that avoids taking the address statically, + * and emit that code into a section that is discarded by the linker. + */ #define ___EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"), aligned(1))) \ + __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ = VMLINUX_SYMBOL_STR(sym); \ - static const struct kernel_symbol __ksymtab_##sym \ - __used \ - __attribute__((section("___ksymtab"
[PATCH v2] 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). Since EXPORT_SYMBOL() no longer refers to struct kernel_symbol, move the definition into module.c, which is its only user. 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. Cc: Jessica Yu Cc: Arnd Bergmann Cc: Russell King Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- v2: - fix error in modpost due to missing local __ksymtab_xxx symbol names Note that ARM requires a little tweak to ensure that the unwind info related to the discarded code is discarded as well. I'm sure there will be an arch or two where something similar may be required. arch/arm/kernel/vmlinux.lds.S | 1 + include/asm-generic/export.h | 10 +-- include/linux/export.h| 28 ++ kernel/module.c | 31 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index c83a7ba737d6..4bdba75e510c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -89,6 +89,7 @@ SECTIONS #endif *(.discard) *(.discard.*) + *(.ARM.exidx.discard) } . = PAGE_OFFSET + TEXT_OFFSET; diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..fac5b2e6df37 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -4,17 +4,9 @@ #ifndef KSYM_FUNC #define KSYM_FUNC(x) x #endif -#ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif -#else -#define __put .long -#ifndef KSYM_ALIGN -#define KSYM_ALIGN 4 -#endif -#endif #ifndef KCRC_ALIGN #define KCRC_ALIGN 4 #endif @@ -35,7 +27,7 @@ .section ___ksymtab\sec+\name,"a" .balign KSYM_ALIGN KSYM(__ksymtab_\name): - __put \val, KSYM(__kstrtab_\name) + .long \val - ., KSYM(__kstrtab_\name) - . .previous .section __ksymtab_strings,"a" KSYM(__kstrtab_\name): diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..943656d74f0c 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,27 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif -/* For every exported symbol, place a struct in the __ksymtab section */ +/* + * For every exported symbol, place a struct in the __ksymtab section. + * Note that we have to visibly take the address of sym, so the compiler + * is forced to emit it, rather than inlining it or removing it + * altogether. Do so in a way that avoids taking the address statically, + * and emit that code into a section that is discarded by the linker. + */ #define ___EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"), aligned(1))) \ + __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ = VMLINUX_SYMBOL_STR(sym); \ - static const struct kernel_symbol __ksymtab_##sym \ - __used \ - __attribute__((section("___ksymtab" sec "+" #sym), used)) \ - = { (unsigned long), __kstrtab_##sym } + static void * __attribute__((section(".discard"), used))\ +
[RFC PATCH] 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). Since EXPORT_SYMBOL() no longer refers to struct kernel_symbol, move the definition into module.c, which is its only user. 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. Cc: Jessica YuCc: Arnd Bergmann Cc: Russell King Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- Note that ARM requires a little tweak to ensure that the unwind info related to the discarded code is discarded as well. I'm sure there will be an arch or two where something similar may be required. arch/arm/kernel/vmlinux.lds.S | 1 + include/asm-generic/export.h | 10 +-- include/linux/export.h| 27 + kernel/module.c | 31 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index c83a7ba737d6..4bdba75e510c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -89,6 +89,7 @@ SECTIONS #endif *(.discard) *(.discard.*) + *(.ARM.exidx.discard) } . = PAGE_OFFSET + TEXT_OFFSET; diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..fac5b2e6df37 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -4,17 +4,9 @@ #ifndef KSYM_FUNC #define KSYM_FUNC(x) x #endif -#ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif -#else -#define __put .long -#ifndef KSYM_ALIGN -#define KSYM_ALIGN 4 -#endif -#endif #ifndef KCRC_ALIGN #define KCRC_ALIGN 4 #endif @@ -35,7 +27,7 @@ .section ___ksymtab\sec+\name,"a" .balign KSYM_ALIGN KSYM(__ksymtab_\name): - __put \val, KSYM(__kstrtab_\name) + .long \val - ., KSYM(__kstrtab_\name) - . .previous .section __ksymtab_strings,"a" KSYM(__kstrtab_\name): diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..06d673799ac8 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,26 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif -/* For every exported symbol, place a struct in the __ksymtab section */ +/* + * For every exported symbol, place a struct in the __ksymtab section. + * Note that we have to visibly take the address of sym, so the compiler + * is forced to emit it, rather than inlining it or removing it + * altogether. Do so in a way that avoids taking the address statically, + * and emit that code into a section that is discarded by the linker. + */ #define ___EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"), aligned(1))) \ + __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ = VMLINUX_SYMBOL_STR(sym); \ - static const struct kernel_symbol __ksymtab_##sym \ - __used \ - __attribute__((section("___ksymtab" sec "+" #sym), used)) \ - = { (unsigned long), __kstrtab_##sym }
[RFC PATCH] 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). Since EXPORT_SYMBOL() no longer refers to struct kernel_symbol, move the definition into module.c, which is its only user. 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. Cc: Jessica Yu Cc: Arnd Bergmann Cc: Russell King Cc: Andrew Morton Cc: Ingo Molnar Cc: Kees Cook Cc: Thomas Garnier Cc: Nicolas Pitre Signed-off-by: Ard Biesheuvel --- Note that ARM requires a little tweak to ensure that the unwind info related to the discarded code is discarded as well. I'm sure there will be an arch or two where something similar may be required. arch/arm/kernel/vmlinux.lds.S | 1 + include/asm-generic/export.h | 10 +-- include/linux/export.h| 27 + kernel/module.c | 31 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index c83a7ba737d6..4bdba75e510c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -89,6 +89,7 @@ SECTIONS #endif *(.discard) *(.discard.*) + *(.ARM.exidx.discard) } . = PAGE_OFFSET + TEXT_OFFSET; diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 719db1968d81..fac5b2e6df37 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -4,17 +4,9 @@ #ifndef KSYM_FUNC #define KSYM_FUNC(x) x #endif -#ifdef CONFIG_64BIT -#define __put .quad #ifndef KSYM_ALIGN #define KSYM_ALIGN 8 #endif -#else -#define __put .long -#ifndef KSYM_ALIGN -#define KSYM_ALIGN 4 -#endif -#endif #ifndef KCRC_ALIGN #define KCRC_ALIGN 4 #endif @@ -35,7 +27,7 @@ .section ___ksymtab\sec+\name,"a" .balign KSYM_ALIGN KSYM(__ksymtab_\name): - __put \val, KSYM(__kstrtab_\name) + .long \val - ., KSYM(__kstrtab_\name) - . .previous .section __ksymtab_strings,"a" KSYM(__kstrtab_\name): diff --git a/include/linux/export.h b/include/linux/export.h index 1a1dfdb2a5c6..06d673799ac8 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -24,12 +24,6 @@ #define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) #ifndef __ASSEMBLY__ -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - #ifdef MODULE extern struct module __this_module; #define THIS_MODULE (&__this_module) @@ -60,17 +54,26 @@ extern struct module __this_module; #define __CRC_SYMBOL(sym, sec) #endif -/* For every exported symbol, place a struct in the __ksymtab section */ +/* + * For every exported symbol, place a struct in the __ksymtab section. + * Note that we have to visibly take the address of sym, so the compiler + * is forced to emit it, rather than inlining it or removing it + * altogether. Do so in a way that avoids taking the address statically, + * and emit that code into a section that is discarded by the linker. + */ #define ___EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"), aligned(1))) \ + __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ = VMLINUX_SYMBOL_STR(sym); \ - static const struct kernel_symbol __ksymtab_##sym \ - __used \ - __attribute__((section("___ksymtab" sec "+" #sym), used)) \ - = { (unsigned long), __kstrtab_##sym } + static void * __attribute__((section(".discard"), used))\ + __discard_##sym(void) { return (void *) } \ + asm(" .section \"___ksymtab" sec