| @@ -27,6 +27,7 @@ · 26 unmodified lines |
| 27 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
| 28 | #include <asm/sections.h> | 28 | #include <asm/sections.h> |
| 29 | #include <asm/shmparam.h> | 29 | #include <asm/shmparam.h> |
| | 30 | #include <asm/mmu_context.h> |
| 30 | | 31 | |
| 31 | int split_tlb __ro_after_init; | 32 | int split_tlb __ro_after_init; |
| 32 | int dcache_stride __ro_after_init; | 33 | int dcache_stride __ro_after_init; |
| @@ -91,7 +92,7 @@ static inline void flush_data_cache(void) · 58 unmodified lines |
| 91 | } | 92 | } |
| 92 | | 93 | |
| 93 | | 94 | |
| 94 | /* Virtual address of pfn. */ | 95 | /* Kernel virtual address of pfn. */ |
| 95 | #define pfn_va(pfn) __va(PFN_PHYS(pfn)) | 96 | #define pfn_va(pfn) __va(PFN_PHYS(pfn)) |
| 96 | | 97 | |
| 97 | void | 98 | void |
| @@ -124,11 +125,13 @@ show_cache_info(struct seq_file *m) · 26 unmodified lines |
| 124 | cache_info.ic_size/1024 ); | 125 | cache_info.ic_size/1024 ); |
| 125 | if (cache_info.dc_loop != 1) | 126 | if (cache_info.dc_loop != 1) |
| 126 | snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop); | 127 | snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop); |
| 127 | seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n", | 128 | seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s, alias=%d)\n", |
| 128 | cache_info.dc_size/1024, | 129 | cache_info.dc_size/1024, |
| 129 | (cache_info.dc_conf.cc_wt ? "WT":"WB"), | 130 | (cache_info.dc_conf.cc_wt ? "WT":"WB"), |
| 130 | (cache_info.dc_conf.cc_sh ? ", shared I/D":""), | 131 | (cache_info.dc_conf.cc_sh ? ", shared I/D":""), |
| 131 | ((cache_info.dc_loop == 1) ? "direct mapped" : buf)); | 132 | ((cache_info.dc_loop == 1) ? "direct mapped" : buf), |
| | 133 | cache_info.dc_conf.cc_alias |
| | 134 | ); |
| 132 | seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", | 135 | seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", |
| 133 | cache_info.it_size, | 136 | cache_info.it_size, |
| 134 | cache_info.dt_size, | 137 | cache_info.dt_size, |
| @@ -324,25 +327,81 @@ __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, · 189 unmodified lines |
| 324 | preempt_enable(); | 327 | preempt_enable(); |
| 325 | } | 328 | } |
| 326 | | 329 | |
| 327 | static inline void | 330 | static void flush_user_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) |
| 328 | __purge_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, | | |
| 329 | unsigned long physaddr) | | |
| 330 | { | 331 | { |
| 331 | if (!static_branch_likely(&parisc_has_cache)) | 332 | unsigned long flags, space, pgd, prot; |
| 332 | return; | 333 | #ifdef CONFIG_TLB_PTLOCK |
| | 334 | unsigned long pgd_lock; |
| | 335 | #endif |
| | 336 | |
| | 337 | vmaddr &= PAGE_MASK; |
| | 338 | |
| 333 | preempt_disable(); | 339 | preempt_disable(); |
| 334 | purge_dcache_page_asm(physaddr, vmaddr); | 340 | |
| | 341 | /* Set context for flush */ |
| | 342 | local_irq_save(flags); |
| | 343 | prot = mfctl(8); |
| | 344 | space = mfsp(SR_USER); |
| | 345 | pgd = mfctl(25); |
| | 346 | #ifdef CONFIG_TLB_PTLOCK |
| | 347 | pgd_lock = mfctl(28); |
| | 348 | #endif |
| | 349 | switch_mm_irqs_off(NULL, vma->vm_mm, NULL); |
| | 350 | local_irq_restore(flags); |
| | 351 | |
| | 352 | flush_user_dcache_range_asm(vmaddr, vmaddr + PAGE_SIZE); |
| 335 | if (vma->vm_flags & VM_EXEC) | 353 | if (vma->vm_flags & VM_EXEC) |
| 336 | flush_icache_page_asm(physaddr, vmaddr); | 354 | flush_user_icache_range_asm(vmaddr, vmaddr + PAGE_SIZE); |
| | 355 | flush_tlb_page(vma, vmaddr); |
| | 356 | |
| | 357 | /* Restore previous context */ |
| | 358 | local_irq_save(flags); |
| | 359 | #ifdef CONFIG_TLB_PTLOCK |
| | 360 | mtctl(pgd_lock, 28); |
| | 361 | #endif |
| | 362 | mtctl(pgd, 25); |
| | 363 | mtsp(space, SR_USER); |
| | 364 | mtctl(prot, 8); |
| | 365 | local_irq_restore(flags); |
| | 366 | |
| 337 | preempt_enable(); | 367 | preempt_enable(); |
| 338 | } | 368 | } |
| 339 | | 369 | |
| | 370 | static inline pte_t *get_ptep(struct mm_struct *mm, unsigned long addr) |
| | 371 | { |
| | 372 | pte_t *ptep = NULL; |
| | 373 | pgd_t *pgd = mm->pgd; |
| | 374 | p4d_t *p4d; |
| | 375 | pud_t *pud; |
| | 376 | pmd_t *pmd; |
| | 377 | |
| | 378 | if (!pgd_none(*pgd)) { |
| | 379 | p4d = p4d_offset(pgd, addr); |
| | 380 | if (!p4d_none(*p4d)) { |
| | 381 | pud = pud_offset(p4d, addr); |
| | 382 | if (!pud_none(*pud)) { |
| | 383 | pmd = pmd_offset(pud, addr); |
| | 384 | if (!pmd_none(*pmd)) |
| | 385 | ptep = pte_offset_map(pmd, addr); |
| | 386 | } |
| | 387 | } |
| | 388 | } |
| | 389 | return ptep; |
| | 390 | } |
| | 391 | |
| | 392 | static inline bool pte_needs_flush(pte_t pte) |
| | 393 | { |
| | 394 | return (pte_val(pte) & (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NO_CACHE)) |
| | 395 | == (_PAGE_PRESENT | _PAGE_ACCESSED); |
| | 396 | } |
| | 397 | |
| 340 | void flush_dcache_page(struct page *page) | 398 | void flush_dcache_page(struct page *page) |
| 341 | { | 399 | { |
| 342 | struct address_space *mapping = page_mapping_file(page); | 400 | struct address_space *mapping = page_mapping_file(page); |
| 343 | struct vm_area_struct *mpnt; | 401 | struct vm_area_struct *mpnt; |
| 344 | unsigned long offset; | 402 | unsigned long offset; |
| 345 | unsigned long addr, old_addr = 0; | 403 | unsigned long addr, old_addr = 0; |
| | 404 | unsigned long count = 0; |
| 346 | pgoff_t pgoff; | 405 | pgoff_t pgoff; |
| 347 | | 406 | |
| 348 | if (mapping && !mapping_mapped(mapping)) { | 407 | if (mapping && !mapping_mapped(mapping)) { |
| @@ -357,33 +416,52 @@ void flush_dcache_page(struct page *page) · 8 unmodified lines |
| 357 | | 416 | |
| 358 | pgoff = page->index; | 417 | pgoff = page->index; |
| 359 | | 418 | |
| 360 | /* We have carefully arranged in arch_get_unmapped_area() that | 419 | /* |
| | 420 | * We have carefully arranged in arch_get_unmapped_area() that |
| 361 | * *any* mappings of a file are always congruently mapped (whether | 421 | * *any* mappings of a file are always congruently mapped (whether |
| 362 | * declared as MAP_PRIVATE or MAP_SHARED), so we only need | 422 | * declared as MAP_PRIVATE or MAP_SHARED), so we only need |
| 363 | * to flush one address here for them all to become coherent */ | 423 | * to flush one address here for them all to become coherent |
| 364 | | 424 | * on machines that support equivalent aliasing |
| | 425 | */ |
| 365 | flush_dcache_mmap_lock(mapping); | 426 | flush_dcache_mmap_lock(mapping); |
| 366 | vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { | 427 | vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { |
| 367 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; | 428 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; |
| 368 | addr = mpnt->vm_start + offset; | 429 | addr = mpnt->vm_start + offset; |
| | 430 | if (parisc_requires_coherency()) { |
| | 431 | pte_t *ptep; |
| 369 | | 432 | |
| 370 | /* The TLB is the engine of coherence on parisc: The | 433 | ptep = get_ptep(mpnt->vm_mm, addr); |
| 371 | * CPU is entitled to speculate any page with a TLB | 434 | if (ptep && pte_needs_flush(*ptep)) |
| 372 | * mapping, so here we kill the mapping then flush the | 435 | flush_user_cache_page(mpnt, addr); |
| 373 | * page along a special flush only alias mapping. | 436 | } else { |
| 374 | * This guarantees that the page is no-longer in the | 437 | /* |
| 375 | * cache for any process and nor may it be | 438 | * The TLB is the engine of coherence on parisc: |
| 376 | * speculatively read in (until the user or kernel | 439 | * The CPU is entitled to speculate any page |
| 377 | * specifically accesses it, of course) */ | 440 | * with a TLB mapping, so here we kill the |
| 378 | | 441 | * mapping then flush the page along a special |
| 379 | flush_tlb_page(mpnt, addr); | 442 | * flush only alias mapping. This guarantees that |
| 380 | if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1)) | 443 | * the page is no-longer in the cache for any |
| 381 | != (addr & (SHM_COLOUR - 1))) { | 444 | * process and nor may it be speculatively read |
| 382 | __flush_cache_page(mpnt, addr, page_to_phys(page)); | 445 | * in (until the user or kernel specifically |
| 383 | if (parisc_requires_coherency() && old_addr) | 446 | * accesses it, of course) |
| 384 | printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n", old_addr, addr, mpnt->vm_file); | 447 | */ |
| 385 | old_addr = addr; | 448 | flush_tlb_page(mpnt, addr); |
| | 449 | if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1)) |
| | 450 | != (addr & (SHM_COLOUR - 1))) { |
| | 451 | __flush_cache_page(mpnt, addr, page_to_phys(page)); |
| | 452 | /* |
| | 453 | * Software is allowed to have any number |
| | 454 | * of private mappings to a page. |
| | 455 | */ |
| | 456 | if (!(mpnt->vm_flags & VM_SHARED)) |
| | 457 | continue; |
| | 458 | if (old_addr) |
| | 459 | pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n", |
| | 460 | old_addr, addr, mpnt->vm_file); |
| | 461 | old_addr = addr; |
| | 462 | } |
| 386 | } | 463 | } |
| | 464 | WARN_ON(++count == 4096); |
| 387 | } | 465 | } |
| 388 | flush_dcache_mmap_unlock(mapping); | 466 | flush_dcache_mmap_unlock(mapping); |
| 389 | } | 467 | } |
| @@ -403,7 +481,7 @@ void __init parisc_setup_cache_timing(void) · 13 unmodified lines |
| 403 | { | 481 | { |
| 404 | unsigned long rangetime, alltime; | 482 | unsigned long rangetime, alltime; |
| 405 | unsigned long size; | 483 | unsigned long size; |
| 406 | unsigned long threshold; | 484 | unsigned long threshold, threshold2; |
| 407 | | 485 | |
| 408 | alltime = mfctl(16); | 486 | alltime = mfctl(16); |
| 409 | flush_data_cache(); | 487 | flush_data_cache(); |
| @@ -417,11 +495,16 @@ void __init parisc_setup_cache_timing(void) · 7 unmodified lines |
| 417 | printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n", | 495 | printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n", |
| 418 | alltime, size, rangetime); | 496 | alltime, size, rangetime); |
| 419 | | 497 | |
| 420 | threshold = L1_CACHE_ALIGN(size * alltime / rangetime); | 498 | threshold = L1_CACHE_ALIGN((unsigned long)((uint64_t)size * alltime / rangetime)); |
| 421 | if (threshold > cache_info.dc_size) | 499 | pr_info("Calculated flush threshold is %lu KiB\n", |
| 422 | threshold = cache_info.dc_size; | 500 | threshold/1024); |
| 423 | if (threshold) | 501 | |
| 424 | parisc_cache_flush_threshold = threshold; | 502 | /* |
| | 503 | * The threshold computed above isn't very reliable. The following |
| | 504 | * heuristic works reasonably well on c8000/rp3440. |
| | 505 | */ |
| | 506 | threshold2 = cache_info.dc_size * num_online_cpus(); |
| | 507 | parisc_cache_flush_threshold = threshold2; |
| 425 | printk(KERN_INFO "Cache flush threshold set to %lu KiB\n", | 508 | printk(KERN_INFO "Cache flush threshold set to %lu KiB\n", |
| 426 | parisc_cache_flush_threshold/1024); | 509 | parisc_cache_flush_threshold/1024); |
| 427 | | 510 | |
| @@ -477,19 +560,47 @@ void flush_kernel_dcache_page_addr(void *addr) · 49 unmodified lines |
| 477 | } | 560 | } |
| 478 | EXPORT_SYMBOL(flush_kernel_dcache_page_addr); | 561 | EXPORT_SYMBOL(flush_kernel_dcache_page_addr); |
| 479 | | 562 | |
| 480 | void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, | 563 | static void flush_cache_page_if_present(struct vm_area_struct *vma, |
| 481 | struct page *pg) | 564 | unsigned long vmaddr, unsigned long pfn) |
| 482 | { | 565 | { |
| 483 | /* Copy using kernel mapping. No coherency is needed (all in | 566 | pte_t *ptep = get_ptep(vma->vm_mm, vmaddr); |
| 484 | kunmap) for the `to' page. However, the `from' page needs to | 567 | |
| 485 | be flushed through a mapping equivalent to the user mapping | 568 | /* |
| 486 | before it can be accessed through the kernel mapping. */ | 569 | * The pte check is racy and sometimes the flush will trigger |
| 487 | preempt_disable(); | 570 | * a non-access TLB miss. Hopefully, the page has already been |
| 488 | flush_dcache_page_asm(__pa(vfrom), vaddr); | 571 | * flushed. |
| 489 | copy_page_asm(vto, vfrom); | 572 | */ |
| 490 | preempt_enable(); | 573 | if (ptep && pte_needs_flush(*ptep)) |
| | 574 | flush_cache_page(vma, vmaddr, pfn); |
| | 575 | } |
| | 576 | |
| | 577 | void copy_user_highpage(struct page *to, struct page *from, |
| | 578 | unsigned long vaddr, struct vm_area_struct *vma) |
| | 579 | { |
| | 580 | void *kto, *kfrom; |
| | 581 | |
| | 582 | kfrom = kmap_local_page(from); |
| | 583 | kto = kmap_local_page(to); |
| | 584 | flush_cache_page_if_present(vma, vaddr, page_to_pfn(from)); |
| | 585 | copy_page_asm(kto, kfrom); |
| | 586 | kunmap_local(kto); |
| | 587 | kunmap_local(kfrom); |
| | 588 | } |
| | 589 | |
| | 590 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
| | 591 | unsigned long user_vaddr, void *dst, void *src, int len) |
| | 592 | { |
| | 593 | flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page)); |
| | 594 | memcpy(dst, src, len); |
| | 595 | flush_kernel_dcache_range_asm((unsigned long)dst, (unsigned long)dst + len); |
| | 596 | } |
| | 597 | |
| | 598 | void copy_from_user_page(struct vm_area_struct *vma, struct page *page, |
| | 599 | unsigned long user_vaddr, void *dst, void *src, int len) |
| | 600 | { |
| | 601 | flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page)); |
| | 602 | memcpy(dst, src, len); |
| 491 | } | 603 | } |
| 492 | EXPORT_SYMBOL(copy_user_page); | | |
| 493 | | 604 | |
| 494 | /* __flush_tlb_range() | 605 | /* __flush_tlb_range() |
| 495 | * | 606 | * |
| @@ -520,92 +631,105 @@ int __flush_tlb_range(unsigned long sid, unsigned long start, · 24 unmodified lines |
| 520 | return 0; | 631 | return 0; |
| 521 | } | 632 | } |
| 522 | | 633 | |
| 523 | static inline unsigned long mm_total_size(struct mm_struct *mm) | 634 | static void flush_cache_pages(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
| 524 | { | 635 | { |
| 525 | struct vm_area_struct *vma; | 636 | unsigned long addr, pfn; |
| 526 | unsigned long usize = 0; | 637 | pte_t *ptep; |
| 527 | | | |
| 528 | for (vma = mm->mmap; vma; vma = vma->vm_next) | | |
| 529 | usize += vma->vm_end - vma->vm_start; | | |
| 530 | return usize; | | |
| 531 | } | | |
| 532 | | | |
| 533 | static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr) | | |
| 534 | { | | |
| 535 | pte_t *ptep = NULL; | | |
| 536 | | 638 | |
| 537 | if (!pgd_none(*pgd)) { | 639 | for (addr = start; addr < end; addr += PAGE_SIZE) { |
| 538 | p4d_t *p4d = p4d_offset(pgd, addr); | 640 | /* |
| 539 | if (!p4d_none(*p4d)) { | 641 | * The vma can contain pages that aren't present. Although |
| 540 | pud_t *pud = pud_offset(p4d, addr); | 642 | * the pte search is expensive, we need the pte to find the |
| 541 | if (!pud_none(*pud)) { | 643 | * page pfn and to check whether the page should be flushed. |
| 542 | pmd_t *pmd = pmd_offset(pud, addr); | 644 | */ |
| 543 | if (!pmd_none(*pmd)) | 645 | ptep = get_ptep(vma->vm_mm, addr); |
| 544 | ptep = pte_offset_map(pmd, addr); | 646 | if (ptep && pte_needs_flush(*ptep)) { |
| | 647 | if (parisc_requires_coherency()) { |
| | 648 | flush_user_cache_page(vma, addr); |
| | 649 | } else { |
| | 650 | pfn = pte_pfn(*ptep); |
| | 651 | if (WARN_ON(!pfn_valid(pfn))) |
| | 652 | return; |
| | 653 | __flush_cache_page(vma, addr, PFN_PHYS(pfn)); |
| 545 | } | 654 | } |
| 546 | } | 655 | } |
| 547 | } | 656 | } |
| 548 | return ptep; | | |
| 549 | } | 657 | } |
| 550 | | 658 | |
| 551 | static void flush_cache_pages(struct vm_area_struct *vma, struct mm_struct *mm, | 659 | static inline unsigned long mm_total_size(struct mm_struct *mm) |
| 552 | unsigned long start, unsigned long end) | | |
| 553 | { | 660 | { |
| 554 | unsigned long addr, pfn; | 661 | struct vm_area_struct *vma; |
| 555 | pte_t *ptep; | 662 | unsigned long usize = 0; |
| 556 | | 663 | |
| 557 | for (addr = start; addr < end; addr += PAGE_SIZE) { | 664 | for (vma = mm->mmap; vma && usize < parisc_cache_flush_threshold; vma = vma->vm_next) |
| 558 | ptep = get_ptep(mm->pgd, addr); | 665 | usize += vma->vm_end - vma->vm_start; |
| 559 | if (ptep) { | 666 | return usize; |
| 560 | pfn = pte_pfn(*ptep); | | |
| 561 | flush_cache_page(vma, addr, pfn); | | |
| 562 | } | | |
| 563 | } | | |
| 564 | } | 667 | } |
| 565 | | 668 | |
| 566 | void flush_cache_mm(struct mm_struct *mm) | 669 | void flush_cache_mm(struct mm_struct *mm) |
| 567 | { | 670 | { |
| 568 | struct vm_area_struct *vma; | 671 | struct vm_area_struct *vma; |
| 569 | | 672 | |
| 570 | /* Flushing the whole cache on each cpu takes forever on | 673 | /* |
| 571 | rp3440, etc. So, avoid it if the mm isn't too big. */ | 674 | * Flushing the whole cache on each cpu takes forever on |
| 572 | if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && | 675 | * rp3440, etc. So, avoid it if the mm isn't too big. |
| 573 | mm_total_size(mm) >= parisc_cache_flush_threshold) { | 676 | * |
| 574 | if (mm->context.space_id) | 677 | * Note that we must flush the entire cache on machines |
| 575 | flush_tlb_all(); | 678 | * with aliasing caches to prevent random segmentation |
| | 679 | * faults. |
| | 680 | */ |
| | 681 | if (!parisc_requires_coherency() |
| | 682 | || mm_total_size(mm) >= parisc_cache_flush_threshold) { |
| | 683 | if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) |
| | 684 | return; |
| | 685 | flush_tlb_all(); |
| 576 | flush_cache_all(); | 686 | flush_cache_all(); |
| 577 | return; | 687 | return; |
| 578 | } | 688 | } |
| 579 | | 689 | |
| | 690 | /* Flush mm */ |
| 580 | for (vma = mm->mmap; vma; vma = vma->vm_next) | 691 | for (vma = mm->mmap; vma; vma = vma->vm_next) |
| 581 | flush_cache_pages(vma, mm, vma->vm_start, vma->vm_end); | 692 | flush_cache_pages(vma, vma->vm_start, vma->vm_end); |
| 582 | } | 693 | } |
| 583 | | 694 | |
| 584 | void flush_cache_range(struct vm_area_struct *vma, | 695 | void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
| 585 | unsigned long start, unsigned long end) | | |
| 586 | { | 696 | { |
| 587 | if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && | 697 | if (!parisc_requires_coherency() |
| 588 | end - start >= parisc_cache_flush_threshold) { | 698 | || end - start >= parisc_cache_flush_threshold) { |
| 589 | if (vma->vm_mm->context.space_id) | 699 | if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) |
| 590 | flush_tlb_range(vma, start, end); | 700 | return; |
| | 701 | flush_tlb_range(vma, start, end); |
| 591 | flush_cache_all(); | 702 | flush_cache_all(); |
| 592 | return; | 703 | return; |
| 593 | } | 704 | } |
| 594 | | 705 | |
| 595 | flush_cache_pages(vma, vma->vm_mm, start, end); | 706 | flush_cache_pages(vma, start, end); |
| 596 | } | 707 | } |
| 597 | | 708 | |
| 598 | void | 709 | void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) |
| 599 | flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) | | |
| 600 | { | 710 | { |
| 601 | if (pfn_valid(pfn)) { | 711 | if (WARN_ON(!pfn_valid(pfn))) |
| 602 | if (likely(vma->vm_mm->context.space_id)) { | 712 | return; |
| 603 | flush_tlb_page(vma, vmaddr); | 713 | if (parisc_requires_coherency()) |
| 604 | __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); | 714 | flush_user_cache_page(vma, vmaddr); |
| 605 | } else { | 715 | else |
| 606 | __purge_cache_page(vma, vmaddr, PFN_PHYS(pfn)); | 716 | __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); |
| 607 | } | 717 | } |
| | 718 | |
| | 719 | void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) |
| | 720 | { |
| | 721 | if (!PageAnon(page)) |
| | 722 | return; |
| | 723 | |
| | 724 | if (parisc_requires_coherency()) { |
| | 725 | flush_user_cache_page(vma, vmaddr); |
| | 726 | return; |
| 608 | } | 727 | } |
| | 728 | |
| | 729 | flush_tlb_page(vma, vmaddr); |
| | 730 | preempt_disable(); |
| | 731 | flush_dcache_page_asm(page_to_phys(page), vmaddr); |
| | 732 | preempt_enable(); |
| 609 | } | 733 | } |
| 610 | | 734 | |
| 611 | void flush_kernel_vmap_range(void *vaddr, int size) | 735 | void flush_kernel_vmap_range(void *vaddr, int size) |