svn commit: r247547 - in stable/9/sys: amd64/amd64 i386/i386 x86/x86
John Baldwin
jhb at FreeBSD.org
Fri Mar 1 14:54:28 UTC 2013
Author: jhb
Date: Fri Mar 1 14:54:26 2013
New Revision: 247547
URL: http://svnweb.freebsd.org/changeset/base/247547
Log:
MFC 245577,245640:
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.
Modified:
stable/9/sys/amd64/amd64/pmap.c
stable/9/sys/i386/i386/pmap.c
stable/9/sys/x86/x86/local_apic.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/amd64/amd64/pmap.c
==============================================================================
--- stable/9/sys/amd64/amd64/pmap.c Fri Mar 1 13:27:32 2013 (r247546)
+++ stable/9/sys/amd64/amd64/pmap.c Fri Mar 1 14:54:26 2013 (r247547)
@@ -109,6 +109,7 @@ __FBSDID("$FreeBSD$");
#include "opt_vm.h"
#include <sys/param.h>
+#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
@@ -140,6 +141,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_reserv.h>
#include <vm/uma.h>
+#include <machine/intr_machdep.h>
+#include <machine/apicvar.h>
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
@@ -1166,6 +1169,15 @@ pmap_invalidate_cache_range(vm_offset_t
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
* included in the write-back. The processor
Modified: stable/9/sys/i386/i386/pmap.c
==============================================================================
--- stable/9/sys/i386/i386/pmap.c Fri Mar 1 13:27:32 2013 (r247546)
+++ stable/9/sys/i386/i386/pmap.c Fri Mar 1 14:54:26 2013 (r247547)
@@ -103,6 +103,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"
@@ -142,6 +143,11 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_reserv.h>
#include <vm/uma.h>
+#ifdef DEV_APIC
+#include <sys/bus.h>
+#include <machine/intr_machdep.h>
+#include <machine/apicvar.h>
+#endif
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
@@ -1191,6 +1197,16 @@ pmap_invalidate_cache_range(vm_offset_t
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
Modified: stable/9/sys/x86/x86/local_apic.c
==============================================================================
--- stable/9/sys/x86/x86/local_apic.c Fri Mar 1 13:27:32 2013 (r247546)
+++ stable/9/sys/x86/x86/local_apic.c Fri Mar 1 14:54:26 2013 (r247547)
@@ -223,8 +223,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);
More information about the svn-src-stable-9
mailing list