* Remove the specified set of pages from the data and instruction caches. * * In contrast to pmap_invalidate_cache_range(), this function does not * rely on the CPU's self-snoop feature, because it is intended for use * when moving pages into a different cache domain. */
| 3566 | * when moving pages into a different cache domain. |
| 3567 | */ |
| 3568 | void |
| 3569 | pmap_invalidate_cache_pages(vm_page_t *pages, int count) |
| 3570 | { |
| 3571 | vm_offset_t daddr, eva; |
| 3572 | int i; |
| 3573 | bool useclflushopt; |
| 3574 | |
| 3575 | useclflushopt = (cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0; |
| 3576 | if (count >= PMAP_CLFLUSH_THRESHOLD / PAGE_SIZE || |
| 3577 | ((cpu_feature & CPUID_CLFSH) == 0 && !useclflushopt)) |
| 3578 | pmap_invalidate_cache(); |
| 3579 | else { |
| 3580 | if (useclflushopt) |
| 3581 | atomic_thread_fence_seq_cst(); |
| 3582 | else if (cpu_vendor_id != CPU_VENDOR_INTEL) |
| 3583 | mfence(); |
| 3584 | for (i = 0; i < count; i++) { |
| 3585 | daddr = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pages[i])); |
| 3586 | eva = daddr + PAGE_SIZE; |
| 3587 | for (; daddr < eva; daddr += cpu_clflush_line_size) { |
| 3588 | if (useclflushopt) |
| 3589 | clflushopt(daddr); |
| 3590 | else |
| 3591 | clflush(daddr); |
| 3592 | } |
| 3593 | } |
| 3594 | if (useclflushopt) |
| 3595 | atomic_thread_fence_seq_cst(); |
| 3596 | else if (cpu_vendor_id != CPU_VENDOR_INTEL) |
| 3597 | mfence(); |
| 3598 | } |
| 3599 | } |
| 3600 | |
| 3601 | void |
| 3602 | pmap_flush_cache_range(vm_offset_t sva, vm_offset_t eva) |
no test coverage detected