summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuanhao Xie <yuanhao.xie@intel.com>2023-11-10 16:03:02 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-11-27 05:21:45 +0000
commitcb3f41a9378822a0bcf0febf898af254b4994b8d (patch)
treed873dc720298af9700f3777dbf38b6256c282908
parent8736b8fdca85e02933cdb0a13309de14c9799ece (diff)
downloadedk2-cb3f41a9378822a0bcf0febf898af254b4994b8d.tar.gz
edk2-cb3f41a9378822a0bcf0febf898af254b4994b8d.tar.bz2
edk2-cb3f41a9378822a0bcf0febf898af254b4994b8d.zip
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>
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c14
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h1
2 files changed, 12 insertions, 3 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 9a6ec5db5c..f29e66a14f 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -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
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 763db4963d..af296f6ac0 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -270,6 +270,7 @@ struct _CPU_MP_DATA {
UINT64 TotalTime;
EFI_EVENT WaitEvent;
UINTN **FailedCpuList;
+ BOOLEAN EnableExecuteDisableForSwitchContext;
AP_INIT_STATE InitFlag;
BOOLEAN SwitchBspFlag;