UefiCpuPkg/MpInitLib: Enable execute disable bit.

This patch synchronizes the No-Execute bit in the IA32_EFER
register for the APs before the RestoreVolatileRegisters operation.

The commit 964a4f0, titled "Eliminate the second INIT-SIPI-SIPI
sequence," replaces the second INIT-SIPI-SIPI sequence with the BSP
calling the SwitchApContext function to initiate a specialized start-up
signal, waking up APs in the DXE instead of using INIT-SIPI-SIPI.

Due to this change, the logic for "Enable execute disable bit" in
MpFuncs.nasm is no longer executed. However, to ensure the proper setup
of the page table, it is necessary to synchronize the IA32_EFER.NXE for
APs before executing RestoreVolatileRegisters .

Based on SDM:
If IA32_EFER.NXE is set to 1, it signifies execute-disable, meaning
instruction fetches are not allowed from the 4-KByte page controlled by
this entry. Conversely, if it is set to 0, it is reserved.

Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek lersek@redhat.com
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Yuanhao Xie 2023-11-10 16:03:02 +08:00 committed by mergify[bot]
parent 8736b8fdca
commit cb3f41a937
2 changed files with 12 additions and 3 deletions

View File

@ -910,9 +910,16 @@ DxeApEntryPoint (
CPU_MP_DATA *CpuMpData
)
{
UINTN ProcessorNumber;
UINTN ProcessorNumber;
MSR_IA32_EFER_REGISTER EferMsr;
GetProcessorNumber (CpuMpData, &ProcessorNumber);
if (CpuMpData->EnableExecuteDisableForSwitchContext) {
EferMsr.Uint64 = AsmReadMsr64 (MSR_IA32_EFER);
EferMsr.Bits.NXE = 1;
AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64);
}
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount);
PlaceAPInMwaitLoopOrRunLoop (
@ -2188,8 +2195,9 @@ MpInitLibInitialize (
if (MpHandOff->WaitLoopExecutionMode == sizeof (VOID *)) {
ASSERT (CpuMpData->ApLoopMode != ApInHltLoop);
CpuMpData->FinishedCount = 0;
CpuMpData->InitFlag = ApInitDone;
CpuMpData->FinishedCount = 0;
CpuMpData->InitFlag = ApInitDone;
CpuMpData->EnableExecuteDisableForSwitchContext = IsBspExecuteDisableEnabled ();
SaveCpuMpData (CpuMpData);
//
// In scenarios where both the PEI and DXE phases run in the same

View File

@ -270,6 +270,7 @@ struct _CPU_MP_DATA {
UINT64 TotalTime;
EFI_EVENT WaitEvent;
UINTN **FailedCpuList;
BOOLEAN EnableExecuteDisableForSwitchContext;
AP_INIT_STATE InitFlag;
BOOLEAN SwitchBspFlag;