Commit 3ac6cffe authored by Tejun Heo's avatar Tejun Heo Committed by Ingo Molnar

linker script: use separate simpler definition for PERCPU()

Impact: fix linker screwup on x86_32

Recent x86_64 zerobased patches introduced PERCPU_VADDR() to put
.data.percpu to a predefined address and re-defined PERCPU() in terms
of it.  The new macro defined one extra symbol, __per_cpu_load, for
LMA of the section so that the init data could be accessed.  This new
symbol introduced the following problems to x86_32.

1. If __per_cpu_load is defined outside of .data.percpu as an absolute
   symbol, relocation generation for relocatable kernel fails due to
   absolute relocation.

2. If __per_cpu_load is put inside .data.percpu with absolute address
   assignment to work around #1, linker gets confused and under
   certain configurations ends up relocating the symbol against
   .data.percpu such that the load address gets added on top of
   already set load address.

As x86_32 doesn't use predefined address for .data.percpu, there's no
need for it to care about the possibility of __per_cpu_load being
different from __per_cpu_start.

This patch defines PERCPU() separately so that __per_cpu_load is
defined inside .data.percpu so that everything is ordinary
linking-wise.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent c43e0e46
...@@ -445,10 +445,9 @@ ...@@ -445,10 +445,9 @@
* section in the linker script will go there too. @phdr should have * section in the linker script will go there too. @phdr should have
* a leading colon. * a leading colon.
* *
* This macro defines three symbols, __per_cpu_load, __per_cpu_start * Note that this macros defines __per_cpu_load as an absolute symbol.
* and __per_cpu_end. The first one is the vaddr of loaded percpu * If there is no need to put the percpu section at a predetermined
* init data. __per_cpu_start equals @vaddr and __per_cpu_end is the * address, use PERCPU().
* end offset.
*/ */
#define PERCPU_VADDR(vaddr, phdr) \ #define PERCPU_VADDR(vaddr, phdr) \
VMLINUX_SYMBOL(__per_cpu_load) = .; \ VMLINUX_SYMBOL(__per_cpu_load) = .; \
...@@ -470,7 +469,20 @@ ...@@ -470,7 +469,20 @@
* Align to @align and outputs output section for percpu area. This * Align to @align and outputs output section for percpu area. This
* macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and * macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and
* __per_cpu_start will be identical. * __per_cpu_start will be identical.
*
* This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except
* that __per_cpu_load is defined as a relative symbol against
* .data.percpu which is required for relocatable x86_32
* configuration.
*/ */
#define PERCPU(align) \ #define PERCPU(align) \
. = ALIGN(align); \ . = ALIGN(align); \
PERCPU_VADDR( , ) .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__per_cpu_load) = .; \
VMLINUX_SYMBOL(__per_cpu_start) = .; \
*(.data.percpu.first) \
*(.data.percpu.page_aligned) \
*(.data.percpu) \
*(.data.percpu.shared_aligned) \
VMLINUX_SYMBOL(__per_cpu_end) = .; \
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment