Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Oct 2016 18:47:47 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r307975 - head/sys/i386/i386
Message-ID:  <201610261847.u9QIllRU064601@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Oct 26 18:47:47 2016
New Revision: 307975
URL: https://svnweb.freebsd.org/changeset/base/307975

Log:
  Enable EFER_NXE properly on APs.
  
  EFER_NXE is set in the EFER MSR by initializecpu() and must be set on all
  CPUs in the system.  When PG_NX support was added to PAE on i386, the
  block to enable EFER_NXE was placed in a section of initializecpu() that
  only runs if 'cpu == CPU_686'.  During early boot, locore does an
  initial pass to set cpu that sets it to CPU_686 on all CPUs later than
  a Pentium.  Later, printcpuinfo() adjusts the 'cpu' variable on
  PII and later CPUs to one of CPU_PII, CPU_PIII, or CPU_P4.  However,
  printcpuinfo() is called after initializecpu() on the BSP, so the BSP
  would enable EFER_NXE and pg_nx.  The APs execute initializecpu() much
  later after printcpuinfo() has run.  The end result on a modern CPU was
  that cpu was set to CPU_PIII when the APs invoked initializecpu(), so
  they did not enable EFER_NXE.  As a result, the APs would fault when
  trying to access any pages marked with PG_NX set.
  
  When booting a 2 CPU PAE kernel in bhyve this manifested as a hang before
  single user mode.  The attempt to execute /bin/init tried to copy out
  the exec strings (argv, etc.) to a non-executable mapping while running
  on the AP.  The instruction kept faulting due to invalid bits in the PTE
  in an infinite loop.
  
  Fix this by moving the code to enable EFER_NXE out of the switch statement
  on 'cpu' and always doing it if 'amd_feature' supports AMDID_NX.
  
  MFC after:	2 weeks

Modified:
  head/sys/i386/i386/initcpu.c

Modified: head/sys/i386/i386/initcpu.c
==============================================================================
--- head/sys/i386/i386/initcpu.c	Wed Oct 26 18:20:06 2016	(r307974)
+++ head/sys/i386/i386/initcpu.c	Wed Oct 26 18:47:47 2016	(r307975)
@@ -753,16 +753,6 @@ initializecpu(void)
 			init_transmeta();
 			break;
 		}
-#if defined(PAE) || defined(PAE_TABLES)
-		if ((amd_feature & AMDID_NX) != 0) {
-			uint64_t msr;
-
-			msr = rdmsr(MSR_EFER) | EFER_NXE;
-			wrmsr(MSR_EFER, msr);
-			pg_nx = PG_NX;
-			elf32_nxstack = 1;
-		}
-#endif
 		break;
 #endif
 	default:
@@ -774,6 +764,16 @@ initializecpu(void)
 		cpu_fxsr = hw_instruction_sse = 1;
 	}
 #endif
+#if defined(PAE) || defined(PAE_TABLES)
+	if ((amd_feature & AMDID_NX) != 0) {
+		uint64_t msr;
+
+		msr = rdmsr(MSR_EFER) | EFER_NXE;
+		wrmsr(MSR_EFER, msr);
+		pg_nx = PG_NX;
+		elf32_nxstack = 1;
+	}
+#endif
 }
 
 void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610261847.u9QIllRU064601>