| 3511 | } |
| 3512 | |
| 3513 | void |
| 3514 | pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) |
| 3515 | { |
| 3516 | |
| 3517 | sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); |
| 3518 | |
| 3519 | /* |
| 3520 | * XXX: Some CPUs fault, hang, or trash the local APIC |
| 3521 | * registers if we use CLFLUSH on the local APIC range. The |
| 3522 | * local APIC is always uncached, so we don't need to flush |
| 3523 | * for that range anyway. |
| 3524 | */ |
| 3525 | if (pmap_kextract(sva) == lapic_paddr) |
| 3526 | return; |
| 3527 | |
| 3528 | if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) { |
| 3529 | /* |
| 3530 | * Do per-cache line flush. Use a locked |
| 3531 | * instruction to insure that previous stores are |
| 3532 | * included in the write-back. The processor |
| 3533 | * propagates flush to other processors in the cache |
| 3534 | * coherence domain. |
| 3535 | */ |
| 3536 | atomic_thread_fence_seq_cst(); |
| 3537 | for (; sva < eva; sva += cpu_clflush_line_size) |
| 3538 | clflushopt(sva); |
| 3539 | atomic_thread_fence_seq_cst(); |
| 3540 | } else { |
| 3541 | /* |
| 3542 | * Writes are ordered by CLFLUSH on Intel CPUs. |
| 3543 | */ |
| 3544 | if (cpu_vendor_id != CPU_VENDOR_INTEL) |
| 3545 | mfence(); |
| 3546 | for (; sva < eva; sva += cpu_clflush_line_size) |
| 3547 | clflush(sva); |
| 3548 | if (cpu_vendor_id != CPU_VENDOR_INTEL) |
| 3549 | mfence(); |
| 3550 | } |
| 3551 | } |
| 3552 | |
| 3553 | static void |
| 3554 | pmap_invalidate_cache_range_all(vm_offset_t sva, vm_offset_t eva) |
no test coverage detected