[Midnightbsd-cvs] src [8872] trunk/sys: dont attempt to use clflush on the local APIC register window.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon Sep 26 09:19:28 EDT 2016


Revision: 8872
          http://svnweb.midnightbsd.org/src/?rev=8872
Author:   laffer1
Date:     2016-09-26 09:19:28 -0400 (Mon, 26 Sep 2016)
Log Message:
-----------
dont attempt to use clflush on the local APIC register window. Various CPUs exhibit bad behavior if this is done (Intel errata AAJ3

Modified Paths:
--------------
    trunk/sys/amd64/amd64/pmap.c
    trunk/sys/i386/i386/pmap.c
    trunk/sys/x86/x86/local_apic.c

Modified: trunk/sys/amd64/amd64/pmap.c
===================================================================
--- trunk/sys/amd64/amd64/pmap.c	2016-09-26 13:18:18 UTC (rev 8871)
+++ trunk/sys/amd64/amd64/pmap.c	2016-09-26 13:19:28 UTC (rev 8872)
@@ -109,6 +109,7 @@
 #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 @@
 #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 @@
 	    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: trunk/sys/i386/i386/pmap.c
===================================================================
--- trunk/sys/i386/i386/pmap.c	2016-09-26 13:18:18 UTC (rev 8871)
+++ trunk/sys/i386/i386/pmap.c	2016-09-26 13:19:28 UTC (rev 8872)
@@ -103,6 +103,7 @@
  *	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 @@
 #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,7 +1197,17 @@
 	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
 		 * included in the write-back.  The processor

Modified: trunk/sys/x86/x86/local_apic.c
===================================================================
--- trunk/sys/x86/x86/local_apic.c	2016-09-26 13:18:18 UTC (rev 8871)
+++ trunk/sys/x86/x86/local_apic.c	2016-09-26 13:19:28 UTC (rev 8872)
@@ -223,8 +223,8 @@
 	/* Map the local APIC and setup the spurious interrupt handler. */
 	KASSERT(trunc_page(addr) == addr,
 	    ("local APIC not aligned on a page boundary"));
+	lapic_paddr = addr;
 	lapic = pmap_mapdev(addr, sizeof(lapic_t));
-	lapic_paddr = addr;
 	setidt(APIC_SPURIOUS_INT, IDTVEC(spuriousint), SDT_APIC, SEL_KPL,
 	    GSEL_APIC);
 



More information about the Midnightbsd-cvs mailing list