diff options
| -rw-r--r-- | arch/parisc/kernel/cache.c | 41 |
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) | |||
| 579 | void flush_cache_range(struct vm_area_struct *vma, | 582 | void 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 | ||
| 595 | void | 619 | void |
| 596 | flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) | 620 | flush_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 | } |
