[PATCH v2] x86/build: Mark per-cpu symbols as absolute

From: ndesaulniers
Date: Wed Dec 19 2018 - 14:02:16 EST


From: Rafael Ãvila de EspÃndola <rafael@xxxxxxxxxx>

The kernel has many variables that it wants to have per CPU. It is
similar to how each thread wants a copy of a thread local variable.

To access such variable, the code has to find the offset of that
variable in the per cpu block and add it to the address of the current
brock for that cpu.

Section 3.10.8 of ld.bfd's documentation states:
```
For expressions involving numbers, relative addresses and absolute
addresses, ld follows these rules to evaluate terms:

Other binary operations, that is, between two relative addresses
not in the same section, or between a relative address and an
absolute address, first convert any non-absolute term to an
absolute address before applying the operator."
```

Note that ld.lld does not implement this behavior. Instead, we can
explicitly mark non-absolute terms ABSOLUTE via linker script. This is
no functional change for ld.bfd which coverts the term to ABSOLUTE
anyways as specified above.

Reported-by: Dmitry Golovin <dima@xxxxxxxxxx>
Tested-by: Dmitry Golovin <dima@xxxxxxxxxx>
Suggested-by: Borislav Petkov <bp@xxxxxxxxx>
Suggested-by: Michael Matz <matz@xxxxxxx>
Signed-off-by: Tri Vo <trong@xxxxxxxxxxx>
Signed-off-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>
Signed-off-by: Rafael Ãvila de EspÃndola <rafael@xxxxxxxxxx>
[nd: commit message updated as per Boris' and Michael's sugguestions]
---
Changes from v1 -> v2: commit message updated

arch/x86/kernel/vmlinux.lds.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 0d618ee634ac..ee3b5c7d662e 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -401,7 +401,7 @@ SECTIONS
* Per-cpu symbols which need to be offset from __per_cpu_load
* for the boot processor.
*/
-#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
+#define INIT_PER_CPU(x) init_per_cpu__##x = ABSOLUTE(x) + __per_cpu_load
INIT_PER_CPU(gdt_page);
INIT_PER_CPU(irq_stack_union);

--
2.20.1.415.g653613c723-goog