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 | |
| 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
| -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); |
