summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-11-23 23:45:42 +0000
committerjhb <jhb@FreeBSD.org>2016-11-23 23:45:42 +0000
commitded614dde8a52a75dbc16d9cf57e989e98031e28 (patch)
tree45c3f12dc5bcf89ded492f1b5b0679c9486a509e /sys/i386
parent2d01764089beffda717a705d227778bb1560441a (diff)
downloadFreeBSD-src-ded614dde8a52a75dbc16d9cf57e989e98031e28.zip
FreeBSD-src-ded614dde8a52a75dbc16d9cf57e989e98031e28.tar.gz
MFC 307975: 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.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/initcpu.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 214c6f6..f675937 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -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
OpenPOWER on IntegriCloud