aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2017-01-11 09:54:53 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2017-01-12 13:10:52 -0500
commit41c066f2c4d436c535616fe182331766c57838f0 (patch)
treea805b9567c20c7d8b3853d57b6915b80ca7c5b49
parent69d012345a1a32d3f03957f14d972efccc106a98 (diff)
arm64: assembler: make adr_l work in modules under KASLR
When CONFIG_RANDOMIZE_MODULE_REGION_FULL=y, the offset between loaded modules and the core kernel may exceed 4 GB, putting symbols exported by the core kernel out of the reach of the ordinary adrp/add instruction pairs used to generate relative symbol references. So make the adr_l macro emit a movz/movk sequence instead when executing in module context. While at it, remove the pointless special case for the stack pointer. Acked-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/asm/assembler.h36
1 files changed, 27 insertions, 9 deletions
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 446f6c46d4b1..3a4301163e04 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -164,22 +164,25 @@ lr .req x30 // link register
164 164
165/* 165/*
166 * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where 166 * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
167 * <symbol> is within the range +/- 4 GB of the PC. 167 * <symbol> is within the range +/- 4 GB of the PC when running
168 * in core kernel context. In module context, a movz/movk sequence
169 * is used, since modules may be loaded far away from the kernel
170 * when KASLR is in effect.
168 */ 171 */
169 /* 172 /*
170 * @dst: destination register (64 bit wide) 173 * @dst: destination register (64 bit wide)
171 * @sym: name of the symbol 174 * @sym: name of the symbol
172 * @tmp: optional scratch register to be used if <dst> == sp, which
173 * is not allowed in an adrp instruction
174 */ 175 */
175 .macro adr_l, dst, sym, tmp= 176 .macro adr_l, dst, sym
176 .ifb \tmp 177#ifndef MODULE
177 adrp \dst, \sym 178 adrp \dst, \sym
178 add \dst, \dst, :lo12:\sym 179 add \dst, \dst, :lo12:\sym
179 .else 180#else
180 adrp \tmp, \sym 181 movz \dst, #:abs_g3:\sym
181 add \dst, \tmp, :lo12:\sym 182 movk \dst, #:abs_g2_nc:\sym
182 .endif 183 movk \dst, #:abs_g1_nc:\sym
184 movk \dst, #:abs_g0_nc:\sym
185#endif
183 .endm 186 .endm
184 187
185 /* 188 /*
@@ -190,6 +193,7 @@ lr .req x30 // link register
190 * the address 193 * the address
191 */ 194 */
192 .macro ldr_l, dst, sym, tmp= 195 .macro ldr_l, dst, sym, tmp=
196#ifndef MODULE
193 .ifb \tmp 197 .ifb \tmp
194 adrp \dst, \sym 198 adrp \dst, \sym
195 ldr \dst, [\dst, :lo12:\sym] 199 ldr \dst, [\dst, :lo12:\sym]
@@ -197,6 +201,15 @@ lr .req x30 // link register
197 adrp \tmp, \sym 201 adrp \tmp, \sym
198 ldr \dst, [\tmp, :lo12:\sym] 202 ldr \dst, [\tmp, :lo12:\sym]
199 .endif 203 .endif
204#else
205 .ifb \tmp
206 adr_l \dst, \sym
207 ldr \dst, [\dst]
208 .else
209 adr_l \tmp, \sym
210 ldr \dst, [\tmp]
211 .endif
212#endif
200 .endm 213 .endm
201 214
202 /* 215 /*
@@ -206,8 +219,13 @@ lr .req x30 // link register
206 * while <src> needs to be preserved. 219 * while <src> needs to be preserved.
207 */ 220 */
208 .macro str_l, src, sym, tmp 221 .macro str_l, src, sym, tmp
222#ifndef MODULE
209 adrp \tmp, \sym 223 adrp \tmp, \sym
210 str \src, [\tmp, :lo12:\sym] 224 str \src, [\tmp, :lo12:\sym]
225#else
226 adr_l \tmp, \sym
227 str \src, [\tmp]
228#endif
211 .endm 229 .endm
212 230
213 /* 231 /*