Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries

2018-03-11 Thread Ard Biesheuvel
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)


Re: [PATCH v8 3/6] module: use relative references for __ksymtab entries

2018-03-11 Thread Ard Biesheuvel
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

2018-03-11 Thread Ard Biesheuvel
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)
@@ 

[PATCH v8 3/6] module: use relative references for __ksymtab entries

2018-03-11 Thread Ard Biesheuvel
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

2018-01-02 Thread Ard Biesheuvel
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 

[PATCH v7 03/10] module: use relative references for __ksymtab entries

2018-01-02 Thread Ard Biesheuvel
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

2017-12-28 Thread kbuild test robot
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

2017-12-28 Thread kbuild test robot
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

2017-12-28 Thread Ard Biesheuvel
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

2017-12-28 Thread Ard Biesheuvel
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

2017-12-28 Thread Ingo Molnar

* 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

2017-12-28 Thread Ingo Molnar

* 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

2017-12-27 Thread Ard Biesheuvel
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

2017-12-27 Thread Ard Biesheuvel
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

2017-12-27 Thread Linus Torvalds
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

2017-12-27 Thread Linus Torvalds
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

2017-12-27 Thread Ard Biesheuvel
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

2017-12-27 Thread Ard Biesheuvel
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

2017-12-27 Thread Linus Torvalds
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


Re: [PATCH v6 2/8] module: use relative references for __ksymtab entries

2017-12-27 Thread Linus Torvalds
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

2017-12-27 Thread Ard Biesheuvel
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 

[PATCH v6 2/8] module: use relative references for __ksymtab entries

2017-12-27 Thread Ard Biesheuvel
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

2017-12-25 Thread Ard Biesheuvel
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 

[PATCH v5 2/8] module: use relative references for __ksymtab entries

2017-12-25 Thread Ard Biesheuvel
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

2017-09-09 Thread Ard Biesheuvel

> 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 

Re: module: use relative references for __ksymtab entries

2017-09-09 Thread Ard Biesheuvel

> 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

2017-09-09 Thread Thomas Garnier
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 

Re: module: use relative references for __ksymtab entries

2017-09-09 Thread Thomas Garnier
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

2017-09-09 Thread Jessica Yu

+++ 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 

Re: module: use relative references for __ksymtab entries

2017-09-09 Thread Jessica Yu

+++ 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

2017-08-19 Thread Ard Biesheuvel
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 

[PATCH v3 2/5] module: use relative references for __ksymtab entries

2017-08-19 Thread Ard Biesheuvel
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

2017-08-18 Thread Ard Biesheuvel
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: 

[PATCH v2 2/6] module: use relative references for __ksymtab entries

2017-08-18 Thread Ard Biesheuvel
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

2017-08-14 Thread Ard Biesheuvel
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 

[PATCH 2/5] module: use relative references for __ksymtab entries

2017-08-14 Thread Ard Biesheuvel
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

2017-08-06 Thread kbuild test robot
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

2017-08-06 Thread kbuild test robot
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

2017-08-06 Thread kbuild test robot
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

2017-08-06 Thread kbuild test robot
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

2017-08-06 Thread Ard Biesheuvel
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" 

[PATCH v2] module: use relative references for __ksymtab entries

2017-08-06 Thread Ard Biesheuvel
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

2017-08-02 Thread Ard Biesheuvel
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 }

[RFC PATCH] module: use relative references for __ksymtab entries

2017-08-02 Thread Ard Biesheuvel
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