diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-14 17:24:33 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-14 17:24:33 -0500 |
| commit | 0861fd1c25a8ce79ae7647e384cb6555c46e1690 (patch) | |
| tree | 37cb316d5c8efd0cbb764c9080f10ff902b3c11c | |
| parent | 5ae93760cbedda64eab0a7012cc3785c32399641 (diff) | |
| parent | 5fd6690c8fb2c3012012979dd8ce7492c69c5d86 (diff) | |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas:
- fix EFI stub cache maintenance causing aborts during boot on certain
platforms
- handle byte stores in __clear_user without panicking
- fix race condition in aarch64_insn_patch_text_sync() (instruction
patching)
- Couple of type fixes
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: ARCH_PFN_OFFSET should be unsigned long
Correct the race condition in aarch64_insn_patch_text_sync()
arm64: __clear_user: handle exceptions on strb
arm64: Fix data type for physical address
arm64: efi: Fix stub cache maintenance
| -rw-r--r-- | arch/arm64/include/asm/memory.h | 2 | ||||
| -rw-r--r-- | arch/arm64/kernel/efi-entry.S | 27 | ||||
| -rw-r--r-- | arch/arm64/kernel/insn.c | 5 | ||||
| -rw-r--r-- | arch/arm64/lib/clear_user.S | 2 | ||||
| -rw-r--r-- | arch/arm64/mm/mmu.c | 2 |
5 files changed, 27 insertions, 11 deletions
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index ccc7087d3c4e..a62cd077457b 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h | |||
| @@ -142,7 +142,7 @@ static inline void *phys_to_virt(phys_addr_t x) | |||
| 142 | * virt_to_page(k) convert a _valid_ virtual address to struct page * | 142 | * virt_to_page(k) convert a _valid_ virtual address to struct page * |
| 143 | * virt_addr_valid(k) indicates whether a virtual address is valid | 143 | * virt_addr_valid(k) indicates whether a virtual address is valid |
| 144 | */ | 144 | */ |
| 145 | #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET | 145 | #define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET) |
| 146 | 146 | ||
| 147 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) | 147 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) |
| 148 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) | 148 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) |
diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S index 619b1dd7bcde..d18a44940968 100644 --- a/arch/arm64/kernel/efi-entry.S +++ b/arch/arm64/kernel/efi-entry.S | |||
| @@ -54,18 +54,17 @@ ENTRY(efi_stub_entry) | |||
| 54 | b.eq efi_load_fail | 54 | b.eq efi_load_fail |
| 55 | 55 | ||
| 56 | /* | 56 | /* |
| 57 | * efi_entry() will have relocated the kernel image if necessary | 57 | * efi_entry() will have copied the kernel image if necessary and we |
| 58 | * and we return here with device tree address in x0 and the kernel | 58 | * return here with device tree address in x0 and the kernel entry |
| 59 | * entry point stored at *image_addr. Save those values in registers | 59 | * point stored at *image_addr. Save those values in registers which |
| 60 | * which are callee preserved. | 60 | * are callee preserved. |
| 61 | */ | 61 | */ |
| 62 | mov x20, x0 // DTB address | 62 | mov x20, x0 // DTB address |
| 63 | ldr x0, [sp, #16] // relocated _text address | 63 | ldr x0, [sp, #16] // relocated _text address |
| 64 | mov x21, x0 | 64 | mov x21, x0 |
| 65 | 65 | ||
| 66 | /* | 66 | /* |
| 67 | * Flush dcache covering current runtime addresses | 67 | * Calculate size of the kernel Image (same for original and copy). |
| 68 | * of kernel text/data. Then flush all of icache. | ||
| 69 | */ | 68 | */ |
| 70 | adrp x1, _text | 69 | adrp x1, _text |
| 71 | add x1, x1, #:lo12:_text | 70 | add x1, x1, #:lo12:_text |
| @@ -73,9 +72,24 @@ ENTRY(efi_stub_entry) | |||
| 73 | add x2, x2, #:lo12:_edata | 72 | add x2, x2, #:lo12:_edata |
| 74 | sub x1, x2, x1 | 73 | sub x1, x2, x1 |
| 75 | 74 | ||
| 75 | /* | ||
| 76 | * Flush the copied Image to the PoC, and ensure it is not shadowed by | ||
| 77 | * stale icache entries from before relocation. | ||
| 78 | */ | ||
| 76 | bl __flush_dcache_area | 79 | bl __flush_dcache_area |
| 77 | ic ialluis | 80 | ic ialluis |
| 78 | 81 | ||
| 82 | /* | ||
| 83 | * Ensure that the rest of this function (in the original Image) is | ||
| 84 | * visible when the caches are disabled. The I-cache can't have stale | ||
| 85 | * entries for the VA range of the current image, so no maintenance is | ||
| 86 | * necessary. | ||
| 87 | */ | ||
| 88 | adr x0, efi_stub_entry | ||
| 89 | adr x1, efi_stub_entry_end | ||
| 90 | sub x1, x1, x0 | ||
| 91 | bl __flush_dcache_area | ||
| 92 | |||
| 79 | /* Turn off Dcache and MMU */ | 93 | /* Turn off Dcache and MMU */ |
| 80 | mrs x0, CurrentEL | 94 | mrs x0, CurrentEL |
| 81 | cmp x0, #CurrentEL_EL2 | 95 | cmp x0, #CurrentEL_EL2 |
| @@ -105,4 +119,5 @@ efi_load_fail: | |||
| 105 | ldp x29, x30, [sp], #32 | 119 | ldp x29, x30, [sp], #32 |
| 106 | ret | 120 | ret |
| 107 | 121 | ||
| 122 | efi_stub_entry_end: | ||
| 108 | ENDPROC(efi_stub_entry) | 123 | ENDPROC(efi_stub_entry) |
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index e007714ded04..8cd27fedc8b6 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c | |||
| @@ -163,9 +163,10 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg) | |||
| 163 | * which ends with "dsb; isb" pair guaranteeing global | 163 | * which ends with "dsb; isb" pair guaranteeing global |
| 164 | * visibility. | 164 | * visibility. |
| 165 | */ | 165 | */ |
| 166 | atomic_set(&pp->cpu_count, -1); | 166 | /* Notify other processors with an additional increment. */ |
| 167 | atomic_inc(&pp->cpu_count); | ||
| 167 | } else { | 168 | } else { |
| 168 | while (atomic_read(&pp->cpu_count) != -1) | 169 | while (atomic_read(&pp->cpu_count) <= num_online_cpus()) |
| 169 | cpu_relax(); | 170 | cpu_relax(); |
| 170 | isb(); | 171 | isb(); |
| 171 | } | 172 | } |
diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S index 6e0ed93d51fe..c17967fdf5f6 100644 --- a/arch/arm64/lib/clear_user.S +++ b/arch/arm64/lib/clear_user.S | |||
| @@ -46,7 +46,7 @@ USER(9f, strh wzr, [x0], #2 ) | |||
| 46 | sub x1, x1, #2 | 46 | sub x1, x1, #2 |
| 47 | 4: adds x1, x1, #1 | 47 | 4: adds x1, x1, #1 |
| 48 | b.mi 5f | 48 | b.mi 5f |
| 49 | strb wzr, [x0] | 49 | USER(9f, strb wzr, [x0] ) |
| 50 | 5: mov x0, #0 | 50 | 5: mov x0, #0 |
| 51 | ret | 51 | ret |
| 52 | ENDPROC(__clear_user) | 52 | ENDPROC(__clear_user) |
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 0bf90d26e745..f4f8b500f74c 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
| @@ -202,7 +202,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, | 204 | static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, |
| 205 | unsigned long end, unsigned long phys, | 205 | unsigned long end, phys_addr_t phys, |
| 206 | int map_io) | 206 | int map_io) |
| 207 | { | 207 | { |
| 208 | pud_t *pud; | 208 | pud_t *pud; |
