diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-03-14 12:32:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-03-14 12:32:00 -0400 |
commit | 9c987a33a864cf405e4c22104508a26197310fd0 (patch) | |
tree | 5b2c7584e1bad40e6733183e801efb50435897b3 /arch/arm64 | |
parent | e6c2d9ce12ad784c82ac289f3adbabc06c6ff996 (diff) | |
parent | 947bb7587fc2c1d1f6b89462ef1255ec30d4e682 (diff) |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas:
- add TLB invalidation for page table tear-down which was missed when
support for CONFIG_HAVE_RCU_TABLE_FREE was added (assuming page table
freeing was always deferred)
- use UEFI for system and reset poweroff if available
- fix asm label placement in relation to the alignment statement
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: put __boot_cpu_mode label after alignment instead of before
efi/arm64: use UEFI for system reset and poweroff
arm64: Invalidate the TLB corresponding to intermediate page table levels
Diffstat (limited to 'arch/arm64')
-rw-r--r-- | arch/arm64/include/asm/tlb.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/tlbflush.h | 13 | ||||
-rw-r--r-- | arch/arm64/kernel/efi.c | 9 | ||||
-rw-r--r-- | arch/arm64/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/process.c | 8 |
5 files changed, 34 insertions, 1 deletions
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index c028fe37456f..53d9c354219f 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h | |||
@@ -48,6 +48,7 @@ static inline void tlb_flush(struct mmu_gather *tlb) | |||
48 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | 48 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, |
49 | unsigned long addr) | 49 | unsigned long addr) |
50 | { | 50 | { |
51 | __flush_tlb_pgtable(tlb->mm, addr); | ||
51 | pgtable_page_dtor(pte); | 52 | pgtable_page_dtor(pte); |
52 | tlb_remove_entry(tlb, pte); | 53 | tlb_remove_entry(tlb, pte); |
53 | } | 54 | } |
@@ -56,6 +57,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
56 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | 57 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, |
57 | unsigned long addr) | 58 | unsigned long addr) |
58 | { | 59 | { |
60 | __flush_tlb_pgtable(tlb->mm, addr); | ||
59 | tlb_remove_entry(tlb, virt_to_page(pmdp)); | 61 | tlb_remove_entry(tlb, virt_to_page(pmdp)); |
60 | } | 62 | } |
61 | #endif | 63 | #endif |
@@ -64,6 +66,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | |||
64 | static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp, | 66 | static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp, |
65 | unsigned long addr) | 67 | unsigned long addr) |
66 | { | 68 | { |
69 | __flush_tlb_pgtable(tlb->mm, addr); | ||
67 | tlb_remove_entry(tlb, virt_to_page(pudp)); | 70 | tlb_remove_entry(tlb, virt_to_page(pudp)); |
68 | } | 71 | } |
69 | #endif | 72 | #endif |
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index 4abe9b945f77..c3bb05b98616 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h | |||
@@ -144,6 +144,19 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end | |||
144 | } | 144 | } |
145 | 145 | ||
146 | /* | 146 | /* |
147 | * Used to invalidate the TLB (walk caches) corresponding to intermediate page | ||
148 | * table levels (pgd/pud/pmd). | ||
149 | */ | ||
150 | static inline void __flush_tlb_pgtable(struct mm_struct *mm, | ||
151 | unsigned long uaddr) | ||
152 | { | ||
153 | unsigned long addr = uaddr >> 12 | ((unsigned long)ASID(mm) << 48); | ||
154 | |||
155 | dsb(ishst); | ||
156 | asm("tlbi vae1is, %0" : : "r" (addr)); | ||
157 | dsb(ish); | ||
158 | } | ||
159 | /* | ||
147 | * On AArch64, the cache coherency is handled via the set_pte_at() function. | 160 | * On AArch64, the cache coherency is handled via the set_pte_at() function. |
148 | */ | 161 | */ |
149 | static inline void update_mmu_cache(struct vm_area_struct *vma, | 162 | static inline void update_mmu_cache(struct vm_area_struct *vma, |
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index b42c7b480e1e..2b8d70164428 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -354,3 +354,12 @@ void efi_virtmap_unload(void) | |||
354 | efi_set_pgd(current->active_mm); | 354 | efi_set_pgd(current->active_mm); |
355 | preempt_enable(); | 355 | preempt_enable(); |
356 | } | 356 | } |
357 | |||
358 | /* | ||
359 | * UpdateCapsule() depends on the system being shutdown via | ||
360 | * ResetSystem(). | ||
361 | */ | ||
362 | bool efi_poweroff_required(void) | ||
363 | { | ||
364 | return efi_enabled(EFI_RUNTIME_SERVICES); | ||
365 | } | ||
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 8ce88e08c030..07f930540f4a 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -585,8 +585,8 @@ ENDPROC(set_cpu_boot_mode_flag) | |||
585 | * zeroing of .bss would clobber it. | 585 | * zeroing of .bss would clobber it. |
586 | */ | 586 | */ |
587 | .pushsection .data..cacheline_aligned | 587 | .pushsection .data..cacheline_aligned |
588 | ENTRY(__boot_cpu_mode) | ||
589 | .align L1_CACHE_SHIFT | 588 | .align L1_CACHE_SHIFT |
589 | ENTRY(__boot_cpu_mode) | ||
590 | .long BOOT_CPU_MODE_EL2 | 590 | .long BOOT_CPU_MODE_EL2 |
591 | .long 0 | 591 | .long 0 |
592 | .popsection | 592 | .popsection |
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index fde9923af859..c6b1f3b96f45 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <stdarg.h> | 21 | #include <stdarg.h> |
22 | 22 | ||
23 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
24 | #include <linux/efi.h> | ||
24 | #include <linux/export.h> | 25 | #include <linux/export.h> |
25 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -150,6 +151,13 @@ void machine_restart(char *cmd) | |||
150 | local_irq_disable(); | 151 | local_irq_disable(); |
151 | smp_send_stop(); | 152 | smp_send_stop(); |
152 | 153 | ||
154 | /* | ||
155 | * UpdateCapsule() depends on the system being reset via | ||
156 | * ResetSystem(). | ||
157 | */ | ||
158 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | ||
159 | efi_reboot(reboot_mode, NULL); | ||
160 | |||
153 | /* Now call the architecture specific reboot code. */ | 161 | /* Now call the architecture specific reboot code. */ |
154 | if (arm_pm_restart) | 162 | if (arm_pm_restart) |
155 | arm_pm_restart(reboot_mode, cmd); | 163 | arm_pm_restart(reboot_mode, cmd); |