aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/pgtable.h11
-rw-r--r--arch/powerpc/kernel/eeh.c6
-rw-r--r--arch/powerpc/kernel/io-workarounds.c10
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c5
-rw-r--r--arch/powerpc/kvm/book3s_hv_rm_mmu.c30
-rw-r--r--arch/powerpc/kvm/e500_mmu_host.c14
-rw-r--r--arch/powerpc/mm/hash_utils_64.c2
-rw-r--r--arch/powerpc/mm/hugetlbpage.c22
-rw-r--r--arch/powerpc/perf/callchain.c24
9 files changed, 88 insertions, 36 deletions
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 92fe01c355a9..11a38635dd65 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -247,8 +247,17 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
247#define pmd_large(pmd) 0 247#define pmd_large(pmd) 0
248#define has_transparent_hugepage() 0 248#define has_transparent_hugepage() 0
249#endif 249#endif
250pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, 250pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
251 unsigned *shift); 251 unsigned *shift);
252static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
253 unsigned *shift)
254{
255 if (!arch_irqs_disabled()) {
256 pr_info("%s called with irq enabled\n", __func__);
257 dump_stack();
258 }
259 return __find_linux_pte_or_hugepte(pgdir, ea, shift);
260}
252#endif /* __ASSEMBLY__ */ 261#endif /* __ASSEMBLY__ */
253 262
254#endif /* __KERNEL__ */ 263#endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index a4c62eb0ee48..44b480e3a5af 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -334,9 +334,11 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
334 int hugepage_shift; 334 int hugepage_shift;
335 335
336 /* 336 /*
337 * We won't find hugepages here, iomem 337 * We won't find hugepages here(this is iomem). Hence we are not
338 * worried about _PAGE_SPLITTING/collapse. Also we will not hit
339 * page table free, because of init_mm.
338 */ 340 */
339 ptep = find_linux_pte_or_hugepte(init_mm.pgd, token, &hugepage_shift); 341 ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token, &hugepage_shift);
340 if (!ptep) 342 if (!ptep)
341 return token; 343 return token;
342 WARN_ON(hugepage_shift); 344 WARN_ON(hugepage_shift);
diff --git a/arch/powerpc/kernel/io-workarounds.c b/arch/powerpc/kernel/io-workarounds.c
index 24b968f8e4d8..63d9cc4d7366 100644
--- a/arch/powerpc/kernel/io-workarounds.c
+++ b/arch/powerpc/kernel/io-workarounds.c
@@ -71,15 +71,15 @@ struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
71 vaddr = (unsigned long)PCI_FIX_ADDR(addr); 71 vaddr = (unsigned long)PCI_FIX_ADDR(addr);
72 if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END) 72 if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
73 return NULL; 73 return NULL;
74 74 /*
75 ptep = find_linux_pte_or_hugepte(init_mm.pgd, vaddr, 75 * We won't find huge pages here (iomem). Also can't hit
76 * a page table free due to init_mm
77 */
78 ptep = __find_linux_pte_or_hugepte(init_mm.pgd, vaddr,
76 &hugepage_shift); 79 &hugepage_shift);
77 if (ptep == NULL) 80 if (ptep == NULL)
78 paddr = 0; 81 paddr = 0;
79 else { 82 else {
80 /*
81 * we don't have hugepages backing iomem
82 */
83 WARN_ON(hugepage_shift); 83 WARN_ON(hugepage_shift);
84 paddr = pte_pfn(*ptep) << PAGE_SHIFT; 84 paddr = pte_pfn(*ptep) << PAGE_SHIFT;
85 } 85 }
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 534acb3c6c3d..26df3864d85a 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -539,12 +539,13 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
539 if (!writing && hpte_is_writable(r)) { 539 if (!writing && hpte_is_writable(r)) {
540 unsigned int hugepage_shift; 540 unsigned int hugepage_shift;
541 pte_t *ptep, pte; 541 pte_t *ptep, pte;
542 unsigned long flags;
542 543
543 /* 544 /*
544 * We need to protect against page table destruction 545 * We need to protect against page table destruction
545 * while looking up and updating the pte. 546 * while looking up and updating the pte.
546 */ 547 */
547 rcu_read_lock_sched(); 548 local_irq_save(flags);
548 ptep = find_linux_pte_or_hugepte(current->mm->pgd, 549 ptep = find_linux_pte_or_hugepte(current->mm->pgd,
549 hva, &hugepage_shift); 550 hva, &hugepage_shift);
550 if (ptep) { 551 if (ptep) {
@@ -553,7 +554,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
553 if (pte_write(pte)) 554 if (pte_write(pte))
554 write_ok = 1; 555 write_ok = 1;
555 } 556 }
556 rcu_read_unlock_sched(); 557 local_irq_restore(flags);
557 } 558 }
558 } 559 }
559 560
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 73e083cb9f7e..f559b25de173 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -26,11 +26,14 @@ static void *real_vmalloc_addr(void *x)
26{ 26{
27 unsigned long addr = (unsigned long) x; 27 unsigned long addr = (unsigned long) x;
28 pte_t *p; 28 pte_t *p;
29 29 /*
30 p = find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL); 30 * assume we don't have huge pages in vmalloc space...
31 * So don't worry about THP collapse/split. Called
32 * Only in realmode, hence won't need irq_save/restore.
33 */
34 p = __find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL);
31 if (!p || !pte_present(*p)) 35 if (!p || !pte_present(*p))
32 return NULL; 36 return NULL;
33 /* assume we don't have huge pages in vmalloc space... */
34 addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK); 37 addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK);
35 return __va(addr); 38 return __va(addr);
36} 39}
@@ -153,7 +156,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
153 pte_t *ptep; 156 pte_t *ptep;
154 unsigned int writing; 157 unsigned int writing;
155 unsigned long mmu_seq; 158 unsigned long mmu_seq;
156 unsigned long rcbits; 159 unsigned long rcbits, irq_flags = 0;
157 160
158 psize = hpte_page_size(pteh, ptel); 161 psize = hpte_page_size(pteh, ptel);
159 if (!psize) 162 if (!psize)
@@ -189,7 +192,16 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
189 192
190 /* Translate to host virtual address */ 193 /* Translate to host virtual address */
191 hva = __gfn_to_hva_memslot(memslot, gfn); 194 hva = __gfn_to_hva_memslot(memslot, gfn);
192 ptep = find_linux_pte_or_hugepte(pgdir, hva, &hpage_shift); 195 /*
196 * If we had a page table table change after lookup, we would
197 * retry via mmu_notifier_retry.
198 */
199 if (realmode)
200 ptep = __find_linux_pte_or_hugepte(pgdir, hva, &hpage_shift);
201 else {
202 local_irq_save(irq_flags);
203 ptep = find_linux_pte_or_hugepte(pgdir, hva, &hpage_shift);
204 }
193 if (ptep) { 205 if (ptep) {
194 pte_t pte; 206 pte_t pte;
195 unsigned int host_pte_size; 207 unsigned int host_pte_size;
@@ -202,9 +214,11 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
202 * We should always find the guest page size 214 * We should always find the guest page size
203 * to <= host page size, if host is using hugepage 215 * to <= host page size, if host is using hugepage
204 */ 216 */
205 if (host_pte_size < psize) 217 if (host_pte_size < psize) {
218 if (!realmode)
219 local_irq_restore(flags);
206 return H_PARAMETER; 220 return H_PARAMETER;
207 221 }
208 pte = kvmppc_read_update_linux_pte(ptep, writing, hpage_shift); 222 pte = kvmppc_read_update_linux_pte(ptep, writing, hpage_shift);
209 if (pte_present(pte) && !pte_protnone(pte)) { 223 if (pte_present(pte) && !pte_protnone(pte)) {
210 if (writing && !pte_write(pte)) 224 if (writing && !pte_write(pte))
@@ -216,6 +230,8 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
216 pa |= gpa & ~PAGE_MASK; 230 pa |= gpa & ~PAGE_MASK;
217 } 231 }
218 } 232 }
233 if (!realmode)
234 local_irq_restore(irq_flags);
219 235
220 ptel &= ~(HPTE_R_PP0 - psize); 236 ptel &= ~(HPTE_R_PP0 - psize);
221 ptel |= pa; 237 ptel |= pa;
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c
index a1f5b0d4b1d6..4d33e199edcc 100644
--- a/arch/powerpc/kvm/e500_mmu_host.c
+++ b/arch/powerpc/kvm/e500_mmu_host.c
@@ -338,6 +338,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
338 pte_t *ptep; 338 pte_t *ptep;
339 unsigned int wimg = 0; 339 unsigned int wimg = 0;
340 pgd_t *pgdir; 340 pgd_t *pgdir;
341 unsigned long flags;
341 342
342 /* used to check for invalidations in progress */ 343 /* used to check for invalidations in progress */
343 mmu_seq = kvm->mmu_notifier_seq; 344 mmu_seq = kvm->mmu_notifier_seq;
@@ -468,14 +469,23 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
468 469
469 470
470 pgdir = vcpu_e500->vcpu.arch.pgdir; 471 pgdir = vcpu_e500->vcpu.arch.pgdir;
472 /*
473 * We are just looking at the wimg bits, so we don't
474 * care much about the trans splitting bit.
475 * We are holding kvm->mmu_lock so a notifier invalidate
476 * can't run hence pfn won't change.
477 */
478 local_irq_save(flags);
471 ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL); 479 ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL);
472 if (ptep) { 480 if (ptep) {
473 pte_t pte = READ_ONCE(*ptep); 481 pte_t pte = READ_ONCE(*ptep);
474 482
475 if (pte_present(pte)) 483 if (pte_present(pte)) {
476 wimg = (pte_val(pte) >> PTE_WIMGE_SHIFT) & 484 wimg = (pte_val(pte) >> PTE_WIMGE_SHIFT) &
477 MAS2_WIMGE_MASK; 485 MAS2_WIMGE_MASK;
478 else { 486 local_irq_restore(flags);
487 } else {
488 local_irq_restore(flags);
479 pr_err_ratelimited("%s: pte not present: gfn %lx,pfn %lx\n", 489 pr_err_ratelimited("%s: pte not present: gfn %lx,pfn %lx\n",
480 __func__, (long)gfn, pfn); 490 __func__, (long)gfn, pfn);
481 ret = -EINVAL; 491 ret = -EINVAL;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 2c2022d16059..444f7a5b859b 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1066,7 +1066,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
1066#endif /* CONFIG_PPC_64K_PAGES */ 1066#endif /* CONFIG_PPC_64K_PAGES */
1067 1067
1068 /* Get PTE and page size from page tables */ 1068 /* Get PTE and page size from page tables */
1069 ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugeshift); 1069 ptep = __find_linux_pte_or_hugepte(pgdir, ea, &hugeshift);
1070 if (ptep == NULL || !pte_present(*ptep)) { 1070 if (ptep == NULL || !pte_present(*ptep)) {
1071 DBG_LOW(" no PTE !\n"); 1071 DBG_LOW(" no PTE !\n");
1072 rc = 1; 1072 rc = 1;
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 2cb278a2f658..a9dbb27ca887 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -109,7 +109,7 @@ int pgd_huge(pgd_t pgd)
109pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 109pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
110{ 110{
111 /* Only called for hugetlbfs pages, hence can ignore THP */ 111 /* Only called for hugetlbfs pages, hence can ignore THP */
112 return find_linux_pte_or_hugepte(mm->pgd, addr, NULL); 112 return __find_linux_pte_or_hugepte(mm->pgd, addr, NULL);
113} 113}
114 114
115static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, 115static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
@@ -682,28 +682,35 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
682 } while (addr = next, addr != end); 682 } while (addr = next, addr != end);
683} 683}
684 684
685/*
686 * We are holding mmap_sem, so a parallel huge page collapse cannot run.
687 * To prevent hugepage split, disable irq.
688 */
685struct page * 689struct page *
686follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) 690follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
687{ 691{
688 pte_t *ptep; 692 pte_t *ptep;
689 struct page *page; 693 struct page *page;
690 unsigned shift; 694 unsigned shift;
691 unsigned long mask; 695 unsigned long mask, flags;
692 /* 696 /*
693 * Transparent hugepages are handled by generic code. We can skip them 697 * Transparent hugepages are handled by generic code. We can skip them
694 * here. 698 * here.
695 */ 699 */
700 local_irq_save(flags);
696 ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift); 701 ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
697 702
698 /* Verify it is a huge page else bail. */ 703 /* Verify it is a huge page else bail. */
699 if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep)) 704 if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep)) {
705 local_irq_restore(flags);
700 return ERR_PTR(-EINVAL); 706 return ERR_PTR(-EINVAL);
701 707 }
702 mask = (1UL << shift) - 1; 708 mask = (1UL << shift) - 1;
703 page = pte_page(*ptep); 709 page = pte_page(*ptep);
704 if (page) 710 if (page)
705 page += (address & mask) / PAGE_SIZE; 711 page += (address & mask) / PAGE_SIZE;
706 712
713 local_irq_restore(flags);
707 return page; 714 return page;
708} 715}
709 716
@@ -950,9 +957,12 @@ void flush_dcache_icache_hugepage(struct page *page)
950 * 957 *
951 * So long as we atomically load page table pointers we are safe against teardown, 958 * So long as we atomically load page table pointers we are safe against teardown,
952 * we can follow the address down to the the page and take a ref on it. 959 * we can follow the address down to the the page and take a ref on it.
960 * This function need to be called with interrupts disabled. We use this variant
961 * when we have MSR[EE] = 0 but the paca->soft_enabled = 1
953 */ 962 */
954 963
955pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) 964pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
965 unsigned *shift)
956{ 966{
957 pgd_t pgd, *pgdp; 967 pgd_t pgd, *pgdp;
958 pud_t pud, *pudp; 968 pud_t pud, *pudp;
@@ -1031,7 +1041,7 @@ out:
1031 *shift = pdshift; 1041 *shift = pdshift;
1032 return ret_pte; 1042 return ret_pte;
1033} 1043}
1034EXPORT_SYMBOL_GPL(find_linux_pte_or_hugepte); 1044EXPORT_SYMBOL_GPL(__find_linux_pte_or_hugepte);
1035 1045
1036int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, 1046int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
1037 unsigned long end, int write, struct page **pages, int *nr) 1047 unsigned long end, int write, struct page **pages, int *nr)
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index ead55351b254..ff09cde20cd2 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -111,41 +111,45 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
111 * interrupt context, so if the access faults, we read the page tables 111 * interrupt context, so if the access faults, we read the page tables
112 * to find which page (if any) is mapped and access it directly. 112 * to find which page (if any) is mapped and access it directly.
113 */ 113 */
114static int read_user_stack_slow(void __user *ptr, void *ret, int nb) 114static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
115{ 115{
116 int ret = -EFAULT;
116 pgd_t *pgdir; 117 pgd_t *pgdir;
117 pte_t *ptep, pte; 118 pte_t *ptep, pte;
118 unsigned shift; 119 unsigned shift;
119 unsigned long addr = (unsigned long) ptr; 120 unsigned long addr = (unsigned long) ptr;
120 unsigned long offset; 121 unsigned long offset;
121 unsigned long pfn; 122 unsigned long pfn, flags;
122 void *kaddr; 123 void *kaddr;
123 124
124 pgdir = current->mm->pgd; 125 pgdir = current->mm->pgd;
125 if (!pgdir) 126 if (!pgdir)
126 return -EFAULT; 127 return -EFAULT;
127 128
129 local_irq_save(flags);
128 ptep = find_linux_pte_or_hugepte(pgdir, addr, &shift); 130 ptep = find_linux_pte_or_hugepte(pgdir, addr, &shift);
131 if (!ptep)
132 goto err_out;
129 if (!shift) 133 if (!shift)
130 shift = PAGE_SHIFT; 134 shift = PAGE_SHIFT;
131 135
132 /* align address to page boundary */ 136 /* align address to page boundary */
133 offset = addr & ((1UL << shift) - 1); 137 offset = addr & ((1UL << shift) - 1);
134 addr -= offset;
135 138
136 if (ptep == NULL) 139 pte = READ_ONCE(*ptep);
137 return -EFAULT;
138 pte = *ptep;
139 if (!pte_present(pte) || !(pte_val(pte) & _PAGE_USER)) 140 if (!pte_present(pte) || !(pte_val(pte) & _PAGE_USER))
140 return -EFAULT; 141 goto err_out;
141 pfn = pte_pfn(pte); 142 pfn = pte_pfn(pte);
142 if (!page_is_ram(pfn)) 143 if (!page_is_ram(pfn))
143 return -EFAULT; 144 goto err_out;
144 145
145 /* no highmem to worry about here */ 146 /* no highmem to worry about here */
146 kaddr = pfn_to_kaddr(pfn); 147 kaddr = pfn_to_kaddr(pfn);
147 memcpy(ret, kaddr + offset, nb); 148 memcpy(buf, kaddr + offset, nb);
148 return 0; 149 ret = 0;
150err_out:
151 local_irq_restore(flags);
152 return ret;
149} 153}
150 154
151static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) 155static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)