diff options
| -rw-r--r-- | arch/arm64/include/asm/assembler.h | 36 |
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 | /* |
