aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel/cache.c')
-rw-r--r--arch/parisc/kernel/cache.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 79089778725b..e3b45546d589 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -543,7 +543,8 @@ void flush_cache_mm(struct mm_struct *mm)
543 rp3440, etc. So, avoid it if the mm isn't too big. */ 543 rp3440, etc. So, avoid it if the mm isn't too big. */
544 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && 544 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
545 mm_total_size(mm) >= parisc_cache_flush_threshold) { 545 mm_total_size(mm) >= parisc_cache_flush_threshold) {
546 flush_tlb_all(); 546 if (mm->context)
547 flush_tlb_all();
547 flush_cache_all(); 548 flush_cache_all();
548 return; 549 return;
549 } 550 }
@@ -571,6 +572,8 @@ void flush_cache_mm(struct mm_struct *mm)
571 pfn = pte_pfn(*ptep); 572 pfn = pte_pfn(*ptep);
572 if (!pfn_valid(pfn)) 573 if (!pfn_valid(pfn))
573 continue; 574 continue;
575 if (unlikely(mm->context))
576 flush_tlb_page(vma, addr);
574 __flush_cache_page(vma, addr, PFN_PHYS(pfn)); 577 __flush_cache_page(vma, addr, PFN_PHYS(pfn));
575 } 578 }
576 } 579 }
@@ -579,26 +582,46 @@ void flush_cache_mm(struct mm_struct *mm)
579void flush_cache_range(struct vm_area_struct *vma, 582void flush_cache_range(struct vm_area_struct *vma,
580 unsigned long start, unsigned long end) 583 unsigned long start, unsigned long end)
581{ 584{
585 pgd_t *pgd;
586 unsigned long addr;
587
582 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && 588 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
583 end - start >= parisc_cache_flush_threshold) { 589 end - start >= parisc_cache_flush_threshold) {
584 flush_tlb_range(vma, start, end); 590 if (vma->vm_mm->context)
591 flush_tlb_range(vma, start, end);
585 flush_cache_all(); 592 flush_cache_all();
586 return; 593 return;
587 } 594 }
588 595
589 flush_user_dcache_range_asm(start, end); 596 if (vma->vm_mm->context == mfsp(3)) {
590 if (vma->vm_flags & VM_EXEC) 597 flush_user_dcache_range_asm(start, end);
591 flush_user_icache_range_asm(start, end); 598 if (vma->vm_flags & VM_EXEC)
592 flush_tlb_range(vma, start, end); 599 flush_user_icache_range_asm(start, end);
600 flush_tlb_range(vma, start, end);
601 return;
602 }
603
604 pgd = vma->vm_mm->pgd;
605 for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
606 unsigned long pfn;
607 pte_t *ptep = get_ptep(pgd, addr);
608 if (!ptep)
609 continue;
610 pfn = pte_pfn(*ptep);
611 if (pfn_valid(pfn)) {
612 if (unlikely(vma->vm_mm->context))
613 flush_tlb_page(vma, addr);
614 __flush_cache_page(vma, addr, PFN_PHYS(pfn));
615 }
616 }
593} 617}
594 618
595void 619void
596flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) 620flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
597{ 621{
598 BUG_ON(!vma->vm_mm->context);
599
600 if (pfn_valid(pfn)) { 622 if (pfn_valid(pfn)) {
601 flush_tlb_page(vma, vmaddr); 623 if (likely(vma->vm_mm->context))
624 flush_tlb_page(vma, vmaddr);
602 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); 625 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
603 } 626 }
604} 627}