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.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 19c0c141bc3f..79089778725b 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -465,10 +465,10 @@ EXPORT_SYMBOL(copy_user_page);
465int __flush_tlb_range(unsigned long sid, unsigned long start, 465int __flush_tlb_range(unsigned long sid, unsigned long start,
466 unsigned long end) 466 unsigned long end)
467{ 467{
468 unsigned long flags, size; 468 unsigned long flags;
469 469
470 size = (end - start); 470 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
471 if (size >= parisc_tlb_flush_threshold) { 471 end - start >= parisc_tlb_flush_threshold) {
472 flush_tlb_all(); 472 flush_tlb_all();
473 return 1; 473 return 1;
474 } 474 }
@@ -539,13 +539,11 @@ void flush_cache_mm(struct mm_struct *mm)
539 struct vm_area_struct *vma; 539 struct vm_area_struct *vma;
540 pgd_t *pgd; 540 pgd_t *pgd;
541 541
542 /* Flush the TLB to avoid speculation if coherency is required. */
543 if (parisc_requires_coherency())
544 flush_tlb_all();
545
546 /* Flushing the whole cache on each cpu takes forever on 542 /* Flushing the whole cache on each cpu takes forever on
547 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. */
548 if (mm_total_size(mm) >= parisc_cache_flush_threshold) { 544 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
545 mm_total_size(mm) >= parisc_cache_flush_threshold) {
546 flush_tlb_all();
549 flush_cache_all(); 547 flush_cache_all();
550 return; 548 return;
551 } 549 }
@@ -553,9 +551,9 @@ void flush_cache_mm(struct mm_struct *mm)
553 if (mm->context == mfsp(3)) { 551 if (mm->context == mfsp(3)) {
554 for (vma = mm->mmap; vma; vma = vma->vm_next) { 552 for (vma = mm->mmap; vma; vma = vma->vm_next) {
555 flush_user_dcache_range_asm(vma->vm_start, vma->vm_end); 553 flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
556 if ((vma->vm_flags & VM_EXEC) == 0) 554 if (vma->vm_flags & VM_EXEC)
557 continue; 555 flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
558 flush_user_icache_range_asm(vma->vm_start, vma->vm_end); 556 flush_tlb_range(vma, vma->vm_start, vma->vm_end);
559 } 557 }
560 return; 558 return;
561 } 559 }
@@ -581,14 +579,9 @@ void flush_cache_mm(struct mm_struct *mm)
581void flush_cache_range(struct vm_area_struct *vma, 579void flush_cache_range(struct vm_area_struct *vma,
582 unsigned long start, unsigned long end) 580 unsigned long start, unsigned long end)
583{ 581{
584 BUG_ON(!vma->vm_mm->context); 582 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
585 583 end - start >= parisc_cache_flush_threshold) {
586 /* Flush the TLB to avoid speculation if coherency is required. */
587 if (parisc_requires_coherency())
588 flush_tlb_range(vma, start, end); 584 flush_tlb_range(vma, start, end);
589
590 if ((end - start) >= parisc_cache_flush_threshold
591 || vma->vm_mm->context != mfsp(3)) {
592 flush_cache_all(); 585 flush_cache_all();
593 return; 586 return;
594 } 587 }
@@ -596,6 +589,7 @@ void flush_cache_range(struct vm_area_struct *vma,
596 flush_user_dcache_range_asm(start, end); 589 flush_user_dcache_range_asm(start, end);
597 if (vma->vm_flags & VM_EXEC) 590 if (vma->vm_flags & VM_EXEC)
598 flush_user_icache_range_asm(start, end); 591 flush_user_icache_range_asm(start, end);
592 flush_tlb_range(vma, start, end);
599} 593}
600 594
601void 595void
@@ -604,8 +598,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
604 BUG_ON(!vma->vm_mm->context); 598 BUG_ON(!vma->vm_mm->context);
605 599
606 if (pfn_valid(pfn)) { 600 if (pfn_valid(pfn)) {
607 if (parisc_requires_coherency()) 601 flush_tlb_page(vma, vmaddr);
608 flush_tlb_page(vma, vmaddr);
609 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); 602 __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
610 } 603 }
611} 604}
@@ -613,21 +606,33 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
613void flush_kernel_vmap_range(void *vaddr, int size) 606void flush_kernel_vmap_range(void *vaddr, int size)
614{ 607{
615 unsigned long start = (unsigned long)vaddr; 608 unsigned long start = (unsigned long)vaddr;
609 unsigned long end = start + size;
616 610
617 if ((unsigned long)size > parisc_cache_flush_threshold) 611 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
612 (unsigned long)size >= parisc_cache_flush_threshold) {
613 flush_tlb_kernel_range(start, end);
618 flush_data_cache(); 614 flush_data_cache();
619 else 615 return;
620 flush_kernel_dcache_range_asm(start, start + size); 616 }
617
618 flush_kernel_dcache_range_asm(start, end);
619 flush_tlb_kernel_range(start, end);
621} 620}
622EXPORT_SYMBOL(flush_kernel_vmap_range); 621EXPORT_SYMBOL(flush_kernel_vmap_range);
623 622
624void invalidate_kernel_vmap_range(void *vaddr, int size) 623void invalidate_kernel_vmap_range(void *vaddr, int size)
625{ 624{
626 unsigned long start = (unsigned long)vaddr; 625 unsigned long start = (unsigned long)vaddr;
626 unsigned long end = start + size;
627 627
628 if ((unsigned long)size > parisc_cache_flush_threshold) 628 if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
629 (unsigned long)size >= parisc_cache_flush_threshold) {
630 flush_tlb_kernel_range(start, end);
629 flush_data_cache(); 631 flush_data_cache();
630 else 632 return;
631 flush_kernel_dcache_range_asm(start, start + size); 633 }
634
635 purge_kernel_dcache_range_asm(start, end);
636 flush_tlb_kernel_range(start, end);
632} 637}
633EXPORT_SYMBOL(invalidate_kernel_vmap_range); 638EXPORT_SYMBOL(invalidate_kernel_vmap_range);