UefiCpuPkg/PiSmmCpuDxeSmm: Fix SMM stack offset is not correct

In function InitGdt(), SmiPFHandler() and Gen4GPageTable(), it uses
 CpuIndex * mSmmStackSize to get the SMM stack address offset for
 multi processor. It misses the SMM Shadow Stack Size. Each processor
 will use mSmmStackSize + mSmmShadowStackSize in the memory.
It should use CpuIndex * (mSmmStackSize + mSmmShadowStackSize) to get
 this SMM stack address offset. If mSmmShadowStackSize > 0 and multi
 processor enabled, it will get the wrong offset value.
CET shadow stack feature will set the value of mSmmShadowStackSize.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3237

Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Roger Feng <roger.feng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
Sheng Wei 2021-02-26 12:00:34 +08:00 committed by mergify[bot]
parent 0930e7ff64
commit ef91b07388
3 changed files with 8 additions and 4 deletions

View File

@ -23,6 +23,8 @@ SPIN_LOCK *mPFLock = NULL;
SMM_CPU_SYNC_MODE mCpuSmmSyncMode; SMM_CPU_SYNC_MODE mCpuSmmSyncMode;
BOOLEAN mMachineCheckSupported = FALSE; BOOLEAN mMachineCheckSupported = FALSE;
extern UINTN mSmmShadowStackSize;
/** /**
Performs an atomic compare exchange operation to get semaphore. Performs an atomic compare exchange operation to get semaphore.
The compare exchange operation must be performed using The compare exchange operation must be performed using
@ -920,7 +922,7 @@ Gen4GPageTable (
// Add two more pages for known good stack and stack guard page, // Add two more pages for known good stack and stack guard page,
// then find the lower 2MB aligned address. // then find the lower 2MB aligned address.
// //
High2MBoundary = (mSmmStackArrayEnd - mSmmStackSize + EFI_PAGE_SIZE * 2) & ~(SIZE_2MB-1); High2MBoundary = (mSmmStackArrayEnd - mSmmStackSize - mSmmShadowStackSize + EFI_PAGE_SIZE * 2) & ~(SIZE_2MB-1);
PagesNeeded = ((High2MBoundary - Low2MBoundary) / SIZE_2MB) + 1; PagesNeeded = ((High2MBoundary - Low2MBoundary) / SIZE_2MB) + 1;
} }
// //
@ -971,7 +973,7 @@ Gen4GPageTable (
// Mark the guard page as non-present // Mark the guard page as non-present
// //
Pte[Index] = PageAddress | mAddressEncMask; Pte[Index] = PageAddress | mAddressEncMask;
GuardPage += mSmmStackSize; GuardPage += (mSmmStackSize + mSmmShadowStackSize);
if (GuardPage > mSmmStackArrayEnd) { if (GuardPage > mSmmStackArrayEnd) {
GuardPage = 0; GuardPage = 0;
} }

View File

@ -13,6 +13,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define PAGE_TABLE_PAGES 8 #define PAGE_TABLE_PAGES 8
#define ACC_MAX_BIT BIT3 #define ACC_MAX_BIT BIT3
extern UINTN mSmmShadowStackSize;
LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool); LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
BOOLEAN m1GPageTableSupport = FALSE; BOOLEAN m1GPageTableSupport = FALSE;
BOOLEAN mCpuSmmRestrictedMemoryAccess; BOOLEAN mCpuSmmRestrictedMemoryAccess;
@ -1037,7 +1039,7 @@ SmiPFHandler (
(PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) { (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
DumpCpuContext (InterruptType, SystemContext); DumpCpuContext (InterruptType, SystemContext);
CpuIndex = GetCpuIndex (); CpuIndex = GetCpuIndex ();
GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * mSmmStackSize); GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * (mSmmStackSize + mSmmShadowStackSize));
if ((FeaturePcdGet (PcdCpuSmmStackGuard)) && if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
(PFAddress >= GuardPageAddress) && (PFAddress >= GuardPageAddress) &&
(PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) { (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) {

View File

@ -93,7 +93,7 @@ InitGdt (
// //
// Setup top of known good stack as IST1 for each processor. // Setup top of known good stack as IST1 for each processor.
// //
*(UINTN *)(TssBase + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize); *(UINTN *)(TssBase + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * (mSmmStackSize + mSmmShadowStackSize));
} }
} }