Don't attempt to use clflush on the local APIC register window. Various
CPUs exhibit bad behavior if this is done (Intel Errata AAJ3, hangs on Pentium-M, and trashing of the local APIC registers on a VIA C7). The local APIC is implicitly mapped UC already via MTRRs, so the clflush isn't necessary anyway. MFC after: 2 weeks
This commit is contained in:
parent
d8067c27f5
commit
4a3c4478d3
@ -1149,6 +1149,15 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
|
||||
else if ((cpu_feature & CPUID_CLFSH) != 0 &&
|
||||
eva - sva < PMAP_CLFLUSH_THRESHOLD) {
|
||||
|
||||
/*
|
||||
* XXX: Some CPUs fault, hang, or trash the local APIC
|
||||
* registers if we use CLFLUSH on the local APIC
|
||||
* range. The local APIC is always uncached, so we
|
||||
* don't need to flush for that range anyway.
|
||||
*/
|
||||
if (pmap_kextract(sva) == lapic_paddr)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Otherwise, do per-cache line flush. Use the mfence
|
||||
* instruction to insure that previous stores are
|
||||
|
@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
|
||||
* and to when physical maps must be made correct.
|
||||
*/
|
||||
|
||||
#include "opt_apic.h"
|
||||
#include "opt_cpu.h"
|
||||
#include "opt_pmap.h"
|
||||
#include "opt_smp.h"
|
||||
@ -1175,6 +1176,16 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
|
||||
else if ((cpu_feature & CPUID_CLFSH) != 0 &&
|
||||
eva - sva < PMAP_CLFLUSH_THRESHOLD) {
|
||||
|
||||
#ifdef DEV_APIC
|
||||
/*
|
||||
* XXX: Some CPUs fault, hang, or trash the local APIC
|
||||
* registers if we use CLFLUSH on the local APIC
|
||||
* range. The local APIC is always uncached, so we
|
||||
* don't need to flush for that range anyway.
|
||||
*/
|
||||
if (pmap_kextract(sva) == lapic_paddr)
|
||||
return;
|
||||
#endif
|
||||
/*
|
||||
* Otherwise, do per-cache line flush. Use the mfence
|
||||
* instruction to insure that previous stores are
|
||||
|
@ -227,8 +227,8 @@ lapic_init(vm_paddr_t addr)
|
||||
/* Map the local APIC and setup the spurious interrupt handler. */
|
||||
KASSERT(trunc_page(addr) == addr,
|
||||
("local APIC not aligned on a page boundary"));
|
||||
lapic = pmap_mapdev(addr, sizeof(lapic_t));
|
||||
lapic_paddr = addr;
|
||||
lapic = pmap_mapdev(addr, sizeof(lapic_t));
|
||||
setidt(APIC_SPURIOUS_INT, IDTVEC(spuriousint), SDT_APIC, SEL_KPL,
|
||||
GSEL_APIC);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user