diff options
Diffstat (limited to 'arch/parisc/kernel/cache.c')
-rw-r--r-- | arch/parisc/kernel/cache.c | 57 |
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); | |||
465 | int __flush_tlb_range(unsigned long sid, unsigned long start, | 465 | int __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) | |||
581 | void flush_cache_range(struct vm_area_struct *vma, | 579 | void 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 | ||
601 | void | 595 | void |
@@ -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 | |||
613 | void flush_kernel_vmap_range(void *vaddr, int size) | 606 | void 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 | } |
622 | EXPORT_SYMBOL(flush_kernel_vmap_range); | 621 | EXPORT_SYMBOL(flush_kernel_vmap_range); |
623 | 622 | ||
624 | void invalidate_kernel_vmap_range(void *vaddr, int size) | 623 | void 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 | } |
633 | EXPORT_SYMBOL(invalidate_kernel_vmap_range); | 638 | EXPORT_SYMBOL(invalidate_kernel_vmap_range); |