diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-01-13 20:00:42 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-01-13 20:00:42 -0500 |
| commit | a65c92597dc7556eaa219a70336d66c058a9627c (patch) | |
| tree | a3000e3ac170b2dbdc346ad03996ac96636b42f0 | |
| parent | c79d47f14fbadce94af3b606a54984a3f25ea558 (diff) | |
| parent | 41c066f2c4d436c535616fe182331766c57838f0 (diff) | |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas:
- Fix huge_ptep_set_access_flags() to return "changed" when any of the
ptes in the contiguous range is changed, not just the last one
- Fix the adr_l assembly macro to work in modules under KASLR
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: assembler: make adr_l work in modules under KASLR
arm64: hugetlb: fix the wrong return value for huge_ptep_set_access_flags
| -rw-r--r-- | arch/arm64/include/asm/assembler.h | 36 | ||||
| -rw-r--r-- | arch/arm64/mm/hugetlbpage.c | 2 |
2 files changed, 28 insertions, 10 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 | /* |
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 964b7549af5c..e25584d72396 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c | |||
| @@ -239,7 +239,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, | |||
| 239 | ncontig = find_num_contig(vma->vm_mm, addr, cpte, | 239 | ncontig = find_num_contig(vma->vm_mm, addr, cpte, |
| 240 | *cpte, &pgsize); | 240 | *cpte, &pgsize); |
| 241 | for (i = 0; i < ncontig; ++i, ++cpte, addr += pgsize) { | 241 | for (i = 0; i < ncontig; ++i, ++cpte, addr += pgsize) { |
| 242 | changed = ptep_set_access_flags(vma, addr, cpte, | 242 | changed |= ptep_set_access_flags(vma, addr, cpte, |
| 243 | pfn_pte(pfn, | 243 | pfn_pte(pfn, |
| 244 | hugeprot), | 244 | hugeprot), |
| 245 | dirty); | 245 | dirty); |
