[ROSLOAD]: Fix NX enabling

[ROSLOAD]: The IA32_MISC_ENABLE MSR bit actually _disables_ NX, so
diabling the bit _enables_ NX.
[ROSLOAD]: The MSR_XD_ENABLE_MASK is for the _high_ DWORD of the MSR
(bit 34), not the low.
[ROSLOAD]: Fix printf.
[ENVIRON/ROSLOAD]: Switch to CPU_INFO structure instead of blindly using
INT[4]. Revealed a bug in the PAE detection which was reading out of
bounds.
This commit is contained in:
Alex Ionescu 2018-01-28 16:29:43 +01:00
parent e836d0b56e
commit 478348ead1
4 changed files with 40 additions and 37 deletions

View file

@ -9783,24 +9783,26 @@ OslpMain (
_Out_ PULONG ReturnFlags _Out_ PULONG ReturnFlags
) )
{ {
INT CpuInfo[4]; CPU_INFO CpuInfo;
BOOLEAN NxDisabled; BOOLEAN NxEnabled;
NTSTATUS Status; NTSTATUS Status;
BOOLEAN ExecuteJump; BOOLEAN ExecuteJump;
LARGE_INTEGER miscMsr;
/* Check if the CPU supports NX */ /* Check if the CPU supports NX */
BlArchCpuId(0x80000001, 0, CpuInfo); BlArchCpuId(0x80000001, 0, &CpuInfo);
if (!(CpuInfo[3] & 0x10000)) if (!(CpuInfo.Edx & 0x10000))
{ {
/* It doesn't, check if this is Intel */ /* It doesn't, check if this is Intel */
EfiPrintf(L"NX disabled: %d\r\n"); EfiPrintf(L"NX disabled: %lx\r\n", CpuInfo.Edx);
if (BlArchGetCpuVendor() == CPU_INTEL) if (BlArchGetCpuVendor() == CPU_INTEL)
{ {
/* Then turn off the MSR feature for it */ /* Then turn off the MSR disable feature for it, enabling NX */
EfiPrintf(L"NX being turned off\r\n"); EfiPrintf(L"NX being turned on\r\n");
__writemsr(MSR_IA32_MISC_ENABLE, miscMsr.QuadPart = __readmsr(MSR_IA32_MISC_ENABLE);
__readmsr(MSR_IA32_MISC_ENABLE) & MSR_XD_ENABLE_MASK); miscMsr.HighPart &= MSR_XD_ENABLE_MASK;
NxDisabled = TRUE; __writemsr(MSR_IA32_MISC_ENABLE, miscMsr.QuadPart);
NxEnabled = TRUE;
} }
} }
@ -9818,12 +9820,13 @@ OslpMain (
/* Retore NX support */ /* Retore NX support */
__writemsr(MSR_EFER, __readmsr(MSR_EFER) ^ MSR_NXE); __writemsr(MSR_EFER, __readmsr(MSR_EFER) ^ MSR_NXE);
/* Did we disable NX? */ /* Did we manually enable NX? */
if (NxDisabled) if (NxEnabled)
{ {
/* Turn it back on */ /* Turn it back off */
__writemsr(MSR_IA32_MISC_ENABLE, miscMsr.QuadPart = __readmsr(MSR_IA32_MISC_ENABLE);
__readmsr(MSR_IA32_MISC_ENABLE) | ~MSR_XD_ENABLE_MASK); miscMsr.HighPart |= ~MSR_XD_ENABLE_MASK;
__writemsr(MSR_IA32_MISC_ENABLE, miscMsr.QuadPart);
} }
/* Go back */ /* Go back */
@ -9853,7 +9856,7 @@ OslMain (
NTSTATUS Status; NTSTATUS Status;
PBL_RETURN_ARGUMENTS ReturnArguments; PBL_RETURN_ARGUMENTS ReturnArguments;
PBL_APPLICATION_ENTRY AppEntry; PBL_APPLICATION_ENTRY AppEntry;
INT CpuInfo[4]; CPU_INFO CpuInfo;
ULONG Flags; ULONG Flags;
#ifdef DRAW_LOGO #ifdef DRAW_LOGO
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* gopBlt; EFI_GRAPHICS_OUTPUT_BLT_PIXEL* gopBlt;
@ -9887,10 +9890,10 @@ OslMain (
if (BlArchIsCpuIdFunctionSupported(1)) if (BlArchIsCpuIdFunctionSupported(1))
{ {
/* Query CPU features */ /* Query CPU features */
BlArchCpuId(1, 0, CpuInfo); BlArchCpuId(1, 0, &CpuInfo);
/* Check if PAE is supported */ /* Check if PAE is supported */
if (CpuInfo[4] & 0x40) if (CpuInfo.Edx & 0x40)
{ {
EfiPrintf(L"PAE Supported, but won't be used\r\n"); EfiPrintf(L"PAE Supported, but won't be used\r\n");
} }

View file

@ -1666,7 +1666,7 @@ VOID
BlArchCpuId ( BlArchCpuId (
_In_ ULONG Function, _In_ ULONG Function,
_In_ ULONG SubFunction, _In_ ULONG SubFunction,
_Out_ INT* Result _Out_ PCPU_INFO Result
); );
CPU_VENDORS CPU_VENDORS

View file

@ -904,12 +904,12 @@ BlArchGetPerformanceCounter (
) )
{ {
#if defined(_M_IX86) || defined(_M_X64) #if defined(_M_IX86) || defined(_M_X64)
INT CpuInfo[4]; CPU_INFO CpuInfo;
/* Serialize with CPUID, if it exists */ /* Serialize with CPUID, if it exists */
if (Archx86IsCpuidSupported()) if (Archx86IsCpuidSupported())
{ {
BlArchCpuId(0, 0, CpuInfo); BlArchCpuId(0, 0, &CpuInfo);
} }
/* Read the TSC */ /* Read the TSC */
@ -924,12 +924,12 @@ VOID
BlArchCpuId ( BlArchCpuId (
_In_ ULONG Function, _In_ ULONG Function,
_In_ ULONG SubFunction, _In_ ULONG SubFunction,
_Out_ INT* Result _Out_ PCPU_INFO Result
) )
{ {
#if defined(_M_IX86) || defined(_M_X64) #if defined(_M_IX86) || defined(_M_X64)
/* Use the intrinsic */ /* Use the intrinsic */
__cpuidex(Result, Function, SubFunction); __cpuidex((INT*)Result->AsUINT32, Function, SubFunction);
#endif #endif
} }
@ -938,37 +938,37 @@ BlArchGetCpuVendor (
VOID VOID
) )
{ {
INT CpuInfo[4]; CPU_INFO CpuInfo;
INT Temp; INT Temp;
/* Get the CPU Vendor */ /* Get the CPU Vendor */
BlArchCpuId(0, 0, CpuInfo); BlArchCpuId(0, 0, &CpuInfo);
Temp = CpuInfo[2]; Temp = CpuInfo.Ecx;
CpuInfo[2] = CpuInfo[3]; CpuInfo.Ecx = CpuInfo.Edx;
CpuInfo[3] = Temp; CpuInfo.Edx = Temp;
/* Check against supported values */ /* Check against supported values */
if (!strncmp((PCHAR)&CpuInfo[1], "GenuineIntel", 12)) if (!strncmp((PCHAR)&CpuInfo.Ebx, "GenuineIntel", 12))
{ {
return CPU_INTEL; return CPU_INTEL;
} }
if (!strncmp((PCHAR)&CpuInfo[1], "AuthenticAMD", 12)) if (!strncmp((PCHAR)&CpuInfo.Ebx, "AuthenticAMD", 12))
{ {
return CPU_AMD; return CPU_AMD;
} }
if (!strncmp((PCHAR)&CpuInfo[1], "CentaurHauls", 12)) if (!strncmp((PCHAR)&CpuInfo.Ebx, "CentaurHauls", 12))
{ {
return CPU_VIA; return CPU_VIA;
} }
if (!strncmp((PCHAR)&CpuInfo[1], "CyrixInstead", 12)) if (!strncmp((PCHAR)&CpuInfo.Ebx, "CyrixInstead", 12))
{ {
return CPU_CYRIX; return CPU_CYRIX;
} }
if (!strncmp((PCHAR)&CpuInfo[1], "GenuineTMx86", 12)) if (!strncmp((PCHAR)&CpuInfo.Ebx, "GenuineTMx86", 12))
{ {
return CPU_TRANSMETA; return CPU_TRANSMETA;
} }
if (!strncmp((PCHAR)&CpuInfo[1], "RiseRiseRise", 12)) if (!strncmp((PCHAR)&CpuInfo.Ebx, "RiseRiseRise", 12))
{ {
return CPU_RISE; return CPU_RISE;
} }

View file

@ -1101,7 +1101,7 @@ MmArchInitialize (
{ {
NTSTATUS Status; NTSTATUS Status;
ULONGLONG IncreaseUserVa, PerfCounter, CpuRandom; ULONGLONG IncreaseUserVa, PerfCounter, CpuRandom;
INT CpuInfo[4]; CPU_INFO CpuInfo;
/* For phase 2, just map deferred regions */ /* For phase 2, just map deferred regions */
if (Phase != 1) if (Phase != 1)
@ -1157,10 +1157,10 @@ MmArchInitialize (
if (BlArchIsCpuIdFunctionSupported(1)) if (BlArchIsCpuIdFunctionSupported(1))
{ {
/* Call it */ /* Call it */
BlArchCpuId(1, 0, CpuInfo); BlArchCpuId(1, 0, &CpuInfo);
/* Check if RDRAND is supported */ /* Check if RDRAND is supported */
if (CpuInfo[2] & 0x40000000) if (CpuInfo.Ecx & 0x40000000)
{ {
EfiPrintf(L"Your CPU can do RDRAND! Good for you!\r\n"); EfiPrintf(L"Your CPU can do RDRAND! Good for you!\r\n");
CpuRandom = 0; CpuRandom = 0;