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
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
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
@ -14,8 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "PiSmmCpuDxeSmm.h"
SPIN_LOCK mPFLock;
/**
Create PageTable for SMM use.
@ -33,7 +31,7 @@ SmmInitPageTable (
//
// Initialize spin lock
//
InitializeSpinLock (&mPFLock);
InitializeSpinLock (mPFLock);
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
//
@ -94,7 +92,7 @@ SmiPFHandler (
ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
AcquireSpinLock (&mPFLock);
AcquireSpinLock (mPFLock);
PFAddress = AsmReadCr2 ();
@ -128,5 +126,5 @@ SmiPFHandler (
SmiDefaultPFHandler ();
}
ReleaseSpinLock (&mPFLock);
ReleaseSpinLock (mPFLock);
}

View File

@ -23,6 +23,7 @@ SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData = NULL;
UINTN mSmmMpSyncDataSize;
SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
UINTN mSemaphoreSize;
SPIN_LOCK *mPFLock = NULL;
/**
Performs an atomic compare exchange operation to get semaphore.
@ -165,9 +166,9 @@ AllCpusInSmmWithExceptions (
SMM_CPU_DATA_BLOCK *CpuData;
EFI_PROCESSOR_INFORMATION *ProcessorInfo;
ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus);
ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
if (mSmmMpSyncData->Counter == mNumberOfCpus) {
if (*mSmmMpSyncData->Counter == mNumberOfCpus) {
return TRUE;
}
@ -206,7 +207,7 @@ SmmWaitForApArrival (
UINT64 Timer;
UINTN Index;
ASSERT (mSmmMpSyncData->Counter <= mNumberOfCpus);
ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
//
// 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 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
//
@ -322,7 +323,7 @@ BSPHandler (
//
// Flag BSP's presence
//
mSmmMpSyncData->InsideSmm = TRUE;
*mSmmMpSyncData->InsideSmm = TRUE;
//
// 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
//
mSmmMpSyncData->AllCpusInSync = TRUE;
ApCount = LockdownSemaphore (&mSmmMpSyncData->Counter) - 1;
*mSmmMpSyncData->AllCpusInSync = TRUE;
ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;
//
// 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
//
mSmmMpSyncData->AllCpusInSync = TRUE;
ApCount = LockdownSemaphore (&mSmmMpSyncData->Counter) - 1;
*mSmmMpSyncData->AllCpusInSync = TRUE;
ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;
//
// Make sure all APs have their Present flag set
//
@ -469,7 +470,7 @@ BSPHandler (
//
// Notify all APs to exit
//
mSmmMpSyncData->InsideSmm = FALSE;
*mSmmMpSyncData->InsideSmm = FALSE;
ReleaseAllAPs ();
//
@ -532,8 +533,8 @@ BSPHandler (
//
// Allow APs to check in from this point on
//
mSmmMpSyncData->Counter = 0;
mSmmMpSyncData->AllCpusInSync = FALSE;
*mSmmMpSyncData->Counter = 0;
*mSmmMpSyncData->AllCpusInSync = FALSE;
}
/**
@ -560,12 +561,12 @@ APHandler (
//
for (Timer = StartSyncTimer ();
!IsSyncTimerTimeout (Timer) &&
!mSmmMpSyncData->InsideSmm;
!(*mSmmMpSyncData->InsideSmm);
) {
CpuPause ();
}
if (!mSmmMpSyncData->InsideSmm) {
if (!(*mSmmMpSyncData->InsideSmm)) {
//
// BSP timeout in the first round
//
@ -586,23 +587,23 @@ APHandler (
//
for (Timer = StartSyncTimer ();
!IsSyncTimerTimeout (Timer) &&
!mSmmMpSyncData->InsideSmm;
!(*mSmmMpSyncData->InsideSmm);
) {
CpuPause ();
}
if (!mSmmMpSyncData->InsideSmm) {
if (!(*mSmmMpSyncData->InsideSmm)) {
//
// Give up since BSP is unable to enter SMM
// and signal the completion of this AP
WaitForSemaphore (&mSmmMpSyncData->Counter);
WaitForSemaphore (mSmmMpSyncData->Counter);
return;
}
} else {
//
// Don't know BSP index. Give up without sending IPI to BSP.
//
WaitForSemaphore (&mSmmMpSyncData->Counter);
WaitForSemaphore (mSmmMpSyncData->Counter);
return;
}
}
@ -666,7 +667,7 @@ APHandler (
//
// Check if BSP wants to exit SMM
//
if (!mSmmMpSyncData->InsideSmm) {
if (!(*mSmmMpSyncData->InsideSmm)) {
break;
}
@ -1043,7 +1044,7 @@ SmiRendezvous (
// 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.
//
BspInProgress = mSmmMpSyncData->InsideSmm;
BspInProgress = *mSmmMpSyncData->InsideSmm;
if (!BspInProgress && !ValidSmi) {
//
@ -1058,7 +1059,7 @@ SmiRendezvous (
//
// Signal presence of this processor
//
if (ReleaseSemaphore (&mSmmMpSyncData->Counter) == 0) {
if (ReleaseSemaphore (mSmmMpSyncData->Counter) == 0) {
//
// BSP has already ended the synchronization, so QUIT!!!
//
@ -1066,7 +1067,7 @@ SmiRendezvous (
//
// Wait for BSP's signal to finish SMI
//
while (mSmmMpSyncData->AllCpusInSync) {
while (*mSmmMpSyncData->AllCpusInSync) {
CpuPause ();
}
goto Exit;
@ -1173,7 +1174,7 @@ SmiRendezvous (
//
// Wait for BSP's signal to exit SMI
//
while (mSmmMpSyncData->AllCpusInSync) {
while (*mSmmMpSyncData->AllCpusInSync) {
CpuPause ();
}
@ -1235,6 +1236,12 @@ InitializeSmmCpuSemaphores (
mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock
= (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;
}

View File

@ -1,7 +1,7 @@
/** @file
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
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
@ -104,7 +104,7 @@ BOOLEAN mSmmCodeAccessCheckEnable = FALSE;
//
// 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.
@ -1338,7 +1338,7 @@ ConfigSmmCodeAccessCheckOnCurrentProcessor (
//
// 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
//
InitializeSpinLock (&mConfigSmmCodeAccessCheckLock);
InitializeSpinLock (mConfigSmmCodeAccessCheckLock);
//
// Acquire Config SMM Code Access Check spin lock. The BSP will release the
// spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
//
AcquireSpinLock (&mConfigSmmCodeAccessCheckLock);
AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
//
// 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
// spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
//
AcquireSpinLock (&mConfigSmmCodeAccessCheckLock);
AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
//
// 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.
//
while (!AcquireSpinLockOrFail (&mConfigSmmCodeAccessCheckLock)) {
while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) {
CpuPause ();
}
//
// 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.
//
SMM_CPU_DATA_BLOCK *CpuData;
volatile UINT32 Counter;
volatile UINT32 *Counter;
volatile UINT32 BspIndex;
volatile BOOLEAN InsideSmm;
volatile BOOLEAN AllCpusInSync;
volatile BOOLEAN *InsideSmm;
volatile BOOLEAN *AllCpusInSync;
volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
volatile BOOLEAN SwitchBsp;
volatile BOOLEAN *CandidateBsp;
@ -388,6 +388,8 @@ extern UINTN mSmmStackArrayEnd;
extern UINTN mSmmStackSize;
extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService;
extern IA32_DESCRIPTOR gcSmiInitGdtr;
extern SPIN_LOCK *mPFLock;
extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
/**
Create 4G PageTable in SMRAM.

View File

@ -1,7 +1,7 @@
/** @file
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
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
@ -17,7 +17,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define PAGE_TABLE_PAGES 8
#define ACC_MAX_BIT BIT3
LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
SPIN_LOCK mPFLock;
BOOLEAN m1GPageTableSupport = FALSE;
/**
@ -107,7 +106,7 @@ SmmInitPageTable (
//
// Initialize spin lock
//
InitializeSpinLock (&mPFLock);
InitializeSpinLock (mPFLock);
m1GPageTableSupport = Is1GPageSupport ();
//
@ -651,7 +650,7 @@ SmiPFHandler (
ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
AcquireSpinLock (&mPFLock);
AcquireSpinLock (mPFLock);
PFAddress = AsmReadCr2 ();
@ -688,5 +687,5 @@ SmiPFHandler (
SmiDefaultPFHandler ();
}
ReleaseSpinLock (&mPFLock);
ReleaseSpinLock (mPFLock);
}