Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries
On Mon, Jun 25, 2018 at 11:14 AM, Ard Biesheuvel wrote: > Because struct kernel_symbol is only 8 bytes in size after this > change, and aligning a 8 byte quantity to 16 bytes wastes 8 bytes. I get that, but then that means the 16-byte alignment wasn't actually necessary in the first place. > The x86 ABI may require it, but we don't actually adhere to it in the > kernel. Also, these structures never occur on the stack anyway. Ok, makes sense. Thanks, Martijn > > >>> -#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 *)&sym; >>> + >>> +/** >>> + * 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 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 >>> + * kernels. >>> + */ >>> +#define __KSYMTAB_ENTRY(sym, sec) \ >>> + __ADDRESSABLE(sym) \ >>> + asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ >>> + " .balign 8 \n" \ >>> + VMLINUX_SYMBOL_STR(__ksymtab_##sym) ": \n" \ >>> + " .long " VMLINUX_SYMBOL_STR(sym) "- .\n" \ >>> + " .long " VMLINUX_SYMBOL_STR(__kstrtab_##sym) "- .\n" \ >>> + " .previous \n") >>> + >>> +struct kernel_symbol { >>> + int value_offset; >>> + int name_offset; >>> +}; >>> +#else >>> +#define __KSYMTAB_ENTRY(sym, sec) \ >>> + static const struct kernel_symbol __ksymtab_##sym \ >>> + __attribute__((section("___ksymtab" sec "+" #sym), used)) \ >>> + = { (unsigned long)&sym, __kstrtab_##sym } >>> + >>> +struct kernel_symbol { >>> + unsigned long value; >>> + const char *name; >>> +}; >>> +#endif >>> + >>> /* For every exported symbol, place a struct in the __ksymtab section */ >>> #define ___EXPORT_SYMBOL(sym, sec) \ >>> extern typeof(sym) sym; \ >>> __CRC_SYMBOL(sym, sec) \ >>> static const char __kstrtab_##sym[]
Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries
Hi Ard, > --- 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 Why remove the 16-byte alignment here? I was working on some other code and ran into this 16-byte alignment, but I'm not sure why it's needed on x86_64 in the first place. Possibly because the ABI requires the stack to be 16-byte aligned when using sse instructions? Thanks, Martijn > -#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 *)&sym; > + > +/** > + * 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 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 > + * kernels. > + */ > +#define __KSYMTAB_ENTRY(sym, sec) \ > + __ADDRESSABLE(sym) \ > + asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ > + " .balign 8 \n" \ > + VMLINUX_SYMBOL_STR(__ksymtab_##sym) ": \n" \ > + " .long " VMLINUX_SYMBOL_STR(sym) "- .\n" \ > + " .long " VMLINUX_SYMBOL_STR(__kstrtab_##sym) "- .\n" \ > + " .previous \n") > + > +struct kernel_symbol { > + int value_offset; > + int name_offset; > +}; > +#else > +#define __KSYMTAB_ENTRY(sym, sec) \ > + static const struct kernel_symbol __ksymtab_##sym \ > + __attribute__((section("___ksymtab" sec "+" #sym), used)) \ > + = { (unsigned long)&sym, __kstrtab_##sym } > + > +struct kernel_symbol { > + unsigned long value; > + const char *name; > +}; > +#endif > + > /* For every exported symbol, place a struct in the __ksymtab section */ > #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); \ > -
Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries
On 25 June 2018 at 12:15, Martijn Coenen wrote: > On Mon, Jun 25, 2018 at 11:14 AM, Ard Biesheuvel > wrote: >> Because struct kernel_symbol is only 8 bytes in size after this >> change, and aligning a 8 byte quantity to 16 bytes wastes 8 bytes. > > I get that, but then that means the 16-byte alignment wasn't actually > necessary in the first place. > Not really, I suppose, although it is not unusual to align large arrays to the entry size if it is a power of 2, so they don't span cachelines. >> The x86 ABI may require it, but we don't actually adhere to it in the >> kernel. Also, these structures never occur on the stack anyway. > > Ok, makes sense. > > Thanks, > Martijn > >> >> -#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 *)&sym; + +/** + * 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 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 + * kernels. + */ +#define __KSYMTAB_ENTRY(sym, sec) \ + __ADDRESSABLE(sym) \ + asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ + " .balign 8 \n" \ + VMLINUX_SYMBOL_STR(__ksymtab_##sym) ": \n" \ + " .long " VMLINUX_SYMBOL_STR(sym) "- .\n" \ + " .long " VMLINUX_SYMBOL_STR(__kstrtab_##sym) "- .\n" \ + " .previous \n") + +struct kernel_symbol { + int value_offset; + int name_offset; +}; +#else +#define __KSYMTAB_ENTRY(sym, sec) \ + static const struct kernel_symbol __ksymtab_##sym \ + __attribute__((section("___ksymtab" sec "+" #sym), used)) \ + = { (unsigned long)&sym, __kstrtab_##sym } + +struct kernel_symbol { + unsigned long value; + const char *name; +}; +#endif + /* For every exported sy
Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries
On 25 June 2018 at 10:56, Martijn Coenen wrote: > Hi Ard, > >> --- 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 > > Why remove the 16-byte alignment here? Because struct kernel_symbol is only 8 bytes in size after this change, and aligning a 8 byte quantity to 16 bytes wastes 8 bytes. > I was working on some other > code and ran into this 16-byte alignment, but I'm not sure why it's > needed on x86_64 in the first place. Possibly because the ABI requires > the stack to be 16-byte aligned when using sse instructions? > The x86 ABI may require it, but we don't actually adhere to it in the kernel. Also, these structures never occur on the stack anyway. >> -#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 *)&sym; >> + >> +/** >> + * 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 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 >> + * kernels. >> + */ >> +#define __KSYMTAB_ENTRY(sym, sec) \ >> + __ADDRESSABLE(sym) \ >> + asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ >> + " .balign 8 \n" \ >> + VMLINUX_SYMBOL_STR(__ksymtab_##sym) ": \n" \ >> + " .long " VMLINUX_SYMBOL_STR(sym) "- .\n" \ >> + " .long " VMLINUX_SYMBOL_STR(__kstrtab_##sym) "- .\n" \ >> + " .previous \n") >> + >> +struct kernel_symbol { >> + int value_offset; >> + int name_offset; >> +}; >> +#else >> +#define __KSYMTAB_ENTRY(sym, sec) \ >> + static const struct kernel_symbol __ksymtab_##sym \ >> + __attribute__((section("___ksymtab" sec "+" #sym), used)) \ >> + = { (unsigned long)&sym, __kstrtab_##sym } >> + >> +struct kernel_symbol { >> + unsigned long value; >> + const char *name; >> +}; >> +#endif >> + >> /* For every exported symbol, place a struct in the __ksymtab section */ >> #define ___EXPORT_SYMBOL(sym, sec) \ >> exte
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 *)&sym; > + 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 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 *)&sym; + +/** + * 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 th