UefiCpuPkg/PiSmmCpuDxeSmm: Using global semaphores in aligned buffer

Update all global semaphores to the ones in allocated aligned
semaphores buffer.

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
Jeff Fan 2016-03-22 10:15:53 +08:00 committed by Michael Kinney
parent d67b73cc38
commit fe3a75bc41
5 changed files with 51 additions and 45 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
Page table manipulation functions for IA-32 processors Page table manipulation functions for IA-32 processors
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR> Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -14,8 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "PiSmmCpuDxeSmm.h" #include "PiSmmCpuDxeSmm.h"
SPIN_LOCK mPFLock;
/** /**
Create PageTable for SMM use. Create PageTable for SMM use.
@ -33,7 +31,7 @@ SmmInitPageTable (
// //
// Initialize spin lock // Initialize spin lock
// //
InitializeSpinLock (&mPFLock); InitializeSpinLock (mPFLock);
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
// //
@ -94,7 +92,7 @@ SmiPFHandler (
ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT); ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
AcquireSpinLock (&mPFLock); AcquireSpinLock (mPFLock);
PFAddress = AsmReadCr2 (); PFAddress = AsmReadCr2 ();
@ -128,5 +126,5 @@ SmiPFHandler (
SmiDefaultPFHandler (); SmiDefaultPFHandler ();
} }
ReleaseSpinLock (&mPFLock); ReleaseSpinLock (mPFLock);
} }

View File

@ -23,6 +23,7 @@ SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData = NULL;
UINTN mSmmMpSyncDataSize; UINTN mSmmMpSyncDataSize;
SMM_CPU_SEMAPHORES mSmmCpuSemaphores; SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
UINTN mSemaphoreSize; UINTN mSemaphoreSize;
SPIN_LOCK *mPFLock = NULL;
/** /**
Performs an atomic compare exchange operation to get semaphore. Performs an atomic compare exchange operation to get semaphore.
@ -165,9 +166,9 @@ AllCpusInSmmWithExceptions (
SMM_CPU_DATA_BLOCK *CpuData; SMM_CPU_DATA_BLOCK *CpuData;
EFI_PROCESSOR_INFORMATION *ProcessorInfo; EFI_PROCESSOR_INFORMATION *ProcessorInfo;
ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus); ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
if (mSmmMpSyncData->Counter == mNumberOfCpus) { if (*mSmmMpSyncData->Counter == mNumberOfCpus) {
return TRUE; return TRUE;
} }
@ -206,7 +207,7 @@ SmmWaitForApArrival (
UINT64 Timer; UINT64 Timer;
UINTN Index; UINTN Index;
ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus); ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
// //
// Platform implementor should choose a timeout value appropriately: // Platform implementor should choose a timeout value appropriately:
@ -245,7 +246,7 @@ SmmWaitForApArrival (
// - In relaxed flow, CheckApArrival() will check SMI disabling status before calling this function. // - In relaxed flow, CheckApArrival() will check SMI disabling status before calling this function.
// In both cases, adding SMI-disabling checking code increases overhead. // In both cases, adding SMI-disabling checking code increases overhead.
// //
if (mSmmMpSyncData->Counter < mNumberOfCpus) { if (*mSmmMpSyncData->Counter < mNumberOfCpus) {
// //
// Send SMI IPIs to bring outside processors in // Send SMI IPIs to bring outside processors in
// //
@ -322,7 +323,7 @@ BSPHandler (
// //
// Flag BSP's presence // Flag BSP's presence
// //
mSmmMpSyncData->InsideSmm = TRUE; *mSmmMpSyncData->InsideSmm = TRUE;
// //
// Initialize Debug Agent to start source level debug in BSP handler // Initialize Debug Agent to start source level debug in BSP handler
@ -360,8 +361,8 @@ BSPHandler (
// //
// Lock the counter down and retrieve the number of APs // Lock the counter down and retrieve the number of APs
// //
mSmmMpSyncData->AllCpusInSync = TRUE; *mSmmMpSyncData->AllCpusInSync = TRUE;
ApCount = LockdownSemaphore (&mSmmMpSyncData->Counter) - 1; ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;
// //
// Wait for all APs to get ready for programming MTRRs // Wait for all APs to get ready for programming MTRRs
@ -448,8 +449,8 @@ BSPHandler (
// //
// Lock the counter down and retrieve the number of APs // Lock the counter down and retrieve the number of APs
// //
mSmmMpSyncData->AllCpusInSync = TRUE; *mSmmMpSyncData->AllCpusInSync = TRUE;
ApCount = LockdownSemaphore (&mSmmMpSyncData->Counter) - 1; ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;
// //
// Make sure all APs have their Present flag set // Make sure all APs have their Present flag set
// //
@ -469,7 +470,7 @@ BSPHandler (
// //
// Notify all APs to exit // Notify all APs to exit
// //
mSmmMpSyncData->InsideSmm = FALSE; *mSmmMpSyncData->InsideSmm = FALSE;
ReleaseAllAPs (); ReleaseAllAPs ();
// //
@ -532,8 +533,8 @@ BSPHandler (
// //
// Allow APs to check in from this point on // Allow APs to check in from this point on
// //
mSmmMpSyncData->Counter = 0; *mSmmMpSyncData->Counter = 0;
mSmmMpSyncData->AllCpusInSync = FALSE; *mSmmMpSyncData->AllCpusInSync = FALSE;
} }
/** /**
@ -560,12 +561,12 @@ APHandler (
// //
for (Timer = StartSyncTimer (); for (Timer = StartSyncTimer ();
!IsSyncTimerTimeout (Timer) && !IsSyncTimerTimeout (Timer) &&
!mSmmMpSyncData->InsideSmm; !(*mSmmMpSyncData->InsideSmm);
) { ) {
CpuPause (); CpuPause ();
} }
if (!mSmmMpSyncData->InsideSmm) { if (!(*mSmmMpSyncData->InsideSmm)) {
// //
// BSP timeout in the first round // BSP timeout in the first round
// //
@ -586,23 +587,23 @@ APHandler (
// //
for (Timer = StartSyncTimer (); for (Timer = StartSyncTimer ();
!IsSyncTimerTimeout (Timer) && !IsSyncTimerTimeout (Timer) &&
!mSmmMpSyncData->InsideSmm; !(*mSmmMpSyncData->InsideSmm);
) { ) {
CpuPause (); CpuPause ();
} }
if (!mSmmMpSyncData->InsideSmm) { if (!(*mSmmMpSyncData->InsideSmm)) {
// //
// Give up since BSP is unable to enter SMM // Give up since BSP is unable to enter SMM
// and signal the completion of this AP // and signal the completion of this AP
WaitForSemaphore (&mSmmMpSyncData->Counter); WaitForSemaphore (mSmmMpSyncData->Counter);
return; return;
} }
} else { } else {
// //
// Don't know BSP index. Give up without sending IPI to BSP. // Don't know BSP index. Give up without sending IPI to BSP.
// //
WaitForSemaphore (&mSmmMpSyncData->Counter); WaitForSemaphore (mSmmMpSyncData->Counter);
return; return;
} }
} }
@ -666,7 +667,7 @@ APHandler (
// //
// Check if BSP wants to exit SMM // Check if BSP wants to exit SMM
// //
if (!mSmmMpSyncData->InsideSmm) { if (!(*mSmmMpSyncData->InsideSmm)) {
break; break;
} }
@ -1043,7 +1044,7 @@ SmiRendezvous (
// Determine if BSP has been already in progress. Note this must be checked after // Determine if BSP has been already in progress. Note this must be checked after
// ValidSmi because BSP may clear a valid SMI source after checking in. // ValidSmi because BSP may clear a valid SMI source after checking in.
// //
BspInProgress = mSmmMpSyncData->InsideSmm; BspInProgress = *mSmmMpSyncData->InsideSmm;
if (!BspInProgress && !ValidSmi) { if (!BspInProgress && !ValidSmi) {
// //
@ -1058,7 +1059,7 @@ SmiRendezvous (
// //
// Signal presence of this processor // Signal presence of this processor
// //
if (ReleaseSemaphore (&mSmmMpSyncData->Counter) == 0) { if (ReleaseSemaphore (mSmmMpSyncData->Counter) == 0) {
// //
// BSP has already ended the synchronization, so QUIT!!! // BSP has already ended the synchronization, so QUIT!!!
// //
@ -1066,7 +1067,7 @@ SmiRendezvous (
// //
// Wait for BSP's signal to finish SMI // Wait for BSP's signal to finish SMI
// //
while (mSmmMpSyncData->AllCpusInSync) { while (*mSmmMpSyncData->AllCpusInSync) {
CpuPause (); CpuPause ();
} }
goto Exit; goto Exit;
@ -1173,7 +1174,7 @@ SmiRendezvous (
// //
// Wait for BSP's signal to exit SMI // Wait for BSP's signal to exit SMI
// //
while (mSmmMpSyncData->AllCpusInSync) { while (*mSmmMpSyncData->AllCpusInSync) {
CpuPause (); CpuPause ();
} }
@ -1235,6 +1236,12 @@ InitializeSmmCpuSemaphores (
mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock
= (SPIN_LOCK *)SemaphoreAddr; = (SPIN_LOCK *)SemaphoreAddr;
mSmmMpSyncData->Counter = mSmmCpuSemaphores.SemaphoreGlobal.Counter;
mSmmMpSyncData->InsideSmm = mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm;
mSmmMpSyncData->AllCpusInSync = mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync;
mPFLock = mSmmCpuSemaphores.SemaphoreGlobal.PFLock;
mConfigSmmCodeAccessCheckLock = mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock;
mSemaphoreSize = SemaphoreSize; mSemaphoreSize = SemaphoreSize;
} }

View File

@ -1,7 +1,7 @@
/** @file /** @file
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU. Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR> Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -104,7 +104,7 @@ BOOLEAN mSmmCodeAccessCheckEnable = FALSE;
// //
// Spin lock used to serialize setting of SMM Code Access Check feature // Spin lock used to serialize setting of SMM Code Access Check feature
// //
SPIN_LOCK mConfigSmmCodeAccessCheckLock; SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
/** /**
Initialize IDT to setup exception handlers for SMM. Initialize IDT to setup exception handlers for SMM.
@ -1338,7 +1338,7 @@ ConfigSmmCodeAccessCheckOnCurrentProcessor (
// //
// Release the spin lock user to serialize the updates to the SMM Feature Control MSR // Release the spin lock user to serialize the updates to the SMM Feature Control MSR
// //
ReleaseSpinLock (&mConfigSmmCodeAccessCheckLock); ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
} }
/** /**
@ -1374,13 +1374,13 @@ ConfigSmmCodeAccessCheck (
// //
// Initialize the lock used to serialize the MSR programming in BSP and all APs // Initialize the lock used to serialize the MSR programming in BSP and all APs
// //
InitializeSpinLock (&mConfigSmmCodeAccessCheckLock); InitializeSpinLock (mConfigSmmCodeAccessCheckLock);
// //
// Acquire Config SMM Code Access Check spin lock. The BSP will release the // Acquire Config SMM Code Access Check spin lock. The BSP will release the
// spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor(). // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
// //
AcquireSpinLock (&mConfigSmmCodeAccessCheckLock); AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
// //
// Enable SMM Code Access Check feature on the BSP. // Enable SMM Code Access Check feature on the BSP.
@ -1397,7 +1397,7 @@ ConfigSmmCodeAccessCheck (
// Acquire Config SMM Code Access Check spin lock. The AP will release the // Acquire Config SMM Code Access Check spin lock. The AP will release the
// spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor(). // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
// //
AcquireSpinLock (&mConfigSmmCodeAccessCheckLock); AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
// //
// Call SmmStartupThisAp() to enable SMM Code Access Check on an AP. // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP.
@ -1408,14 +1408,14 @@ ConfigSmmCodeAccessCheck (
// //
// Wait for the AP to release the Config SMM Code Access Check spin lock. // Wait for the AP to release the Config SMM Code Access Check spin lock.
// //
while (!AcquireSpinLockOrFail (&mConfigSmmCodeAccessCheckLock)) { while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) {
CpuPause (); CpuPause ();
} }
// //
// Release the Config SMM Code Access Check spin lock. // Release the Config SMM Code Access Check spin lock.
// //
ReleaseSpinLock (&mConfigSmmCodeAccessCheckLock); ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
} }
} }
} }

View File

@ -314,10 +314,10 @@ typedef struct {
// so that UC cache-ability can be set together. // so that UC cache-ability can be set together.
// //
SMM_CPU_DATA_BLOCK *CpuData; SMM_CPU_DATA_BLOCK *CpuData;
volatile UINT32 Counter; volatile UINT32 *Counter;
volatile UINT32 BspIndex; volatile UINT32 BspIndex;
volatile BOOLEAN InsideSmm; volatile BOOLEAN *InsideSmm;
volatile BOOLEAN AllCpusInSync; volatile BOOLEAN *AllCpusInSync;
volatile SMM_CPU_SYNC_MODE EffectiveSyncMode; volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
volatile BOOLEAN SwitchBsp; volatile BOOLEAN SwitchBsp;
volatile BOOLEAN *CandidateBsp; volatile BOOLEAN *CandidateBsp;
@ -388,6 +388,8 @@ extern UINTN mSmmStackArrayEnd;
extern UINTN mSmmStackSize; extern UINTN mSmmStackSize;
extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService; extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService;
extern IA32_DESCRIPTOR gcSmiInitGdtr; extern IA32_DESCRIPTOR gcSmiInitGdtr;
extern SPIN_LOCK *mPFLock;
extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
/** /**
Create 4G PageTable in SMRAM. Create 4G PageTable in SMRAM.

View File

@ -1,7 +1,7 @@
/** @file /** @file
Page Fault (#PF) handler for X64 processors Page Fault (#PF) handler for X64 processors
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR> Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -17,7 +17,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define PAGE_TABLE_PAGES 8 #define PAGE_TABLE_PAGES 8
#define ACC_MAX_BIT BIT3 #define ACC_MAX_BIT BIT3
LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool); LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
SPIN_LOCK mPFLock;
BOOLEAN m1GPageTableSupport = FALSE; BOOLEAN m1GPageTableSupport = FALSE;
/** /**
@ -107,7 +106,7 @@ SmmInitPageTable (
// //
// Initialize spin lock // Initialize spin lock
// //
InitializeSpinLock (&mPFLock); InitializeSpinLock (mPFLock);
m1GPageTableSupport = Is1GPageSupport (); m1GPageTableSupport = Is1GPageSupport ();
// //
@ -651,7 +650,7 @@ SmiPFHandler (
ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT); ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
AcquireSpinLock (&mPFLock); AcquireSpinLock (mPFLock);
PFAddress = AsmReadCr2 (); PFAddress = AsmReadCr2 ();
@ -688,5 +687,5 @@ SmiPFHandler (
SmiDefaultPFHandler (); SmiDefaultPFHandler ();
} }
ReleaseSpinLock (&mPFLock); ReleaseSpinLock (mPFLock);
} }