UefiCpuPkg/PiSmmCpuDxeSmm: Differentiate PerformRemainingTasks

For MM:
SMRAM & PageTable itself & SMM Paging State shall be configured
once the gEdkiiPiMmMemoryAttributesTableGuid is installed by
SMM core. It will happen after MmIpl.Entrypoint.
PerformRemainingTasks will be called before MmIpl.Entrypoint
exit.

For SMM:
SMRAM & PageTable itself & SMM Paging State are still
configured in the first SMI when SMM ready to lock happen.

So, this patch is to differentiate PerformRemainingTasks for MM
and SMM.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Dun Tan <dun.tan@intel.com>
Cc: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Wei6 Xu <wei6.xu@intel.com>
Cc: Yuanhao Xie <yuanhao.xie@intel.com>
This commit is contained in:
Jiaxin Wu 2024-06-26 15:43:52 +08:00 committed by mergify[bot]
parent 268397a892
commit 79468b58c3
5 changed files with 188 additions and 102 deletions

View File

@ -96,11 +96,6 @@ BOOLEAN mCetSupported = TRUE;
UINTN mMaxNumberOfCpus = 0;
UINTN mNumberOfCpus = 0;
//
// SMM ready to lock flag
//
BOOLEAN mSmmReadyToLock = FALSE;
//
// Global used to cache PCD for SMM Code Access Check enable
//
@ -1525,82 +1520,6 @@ AllocateCodePages (
return (VOID *)(UINTN)Memory;
}
/**
Perform the remaining tasks.
**/
VOID
PerformRemainingTasks (
VOID
)
{
if (mSmmReadyToLock) {
PERF_FUNCTION_BEGIN ();
//
// Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for
// all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling
// SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock
// is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call
// FlushTlbForAll() that need to start up the aps. So it need to let all
// aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck()
// also will start up the aps.
//
if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) {
DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n"));
}
//
// Start SMM Profile feature
//
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
SmmProfileStart ();
}
//
// Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable.
//
InitPaging ();
//
// Mark critical region to be read-only in page table
//
SetMemMapAttributes ();
if (IsRestrictedMemoryAccess ()) {
//
// For outside SMRAM, we only map SMM communication buffer or MMIO.
//
SetUefiMemMapAttributes ();
//
// Set page table itself to be read-only
//
SetPageTableAttributes ();
}
//
// Configure SMM Code Access Check feature if available.
//
ConfigSmmCodeAccessCheck ();
//
// Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
// as the implementation is provided by platform.
//
PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
SmmCpuFeaturesCompleteSmmReadyToLock ();
PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
//
// Clean SMM ready to lock flag
//
mSmmReadyToLock = FALSE;
PERF_FUNCTION_END ();
}
}
/**
Perform the pre tasks.

View File

@ -273,7 +273,6 @@ extern UINT8 mSmmSaveStateRegisterLma;
extern BOOLEAN mBtsSupported;
extern UINTN mMsrDsAreaSize;
extern BOOLEAN mAcpiS3Enable;
extern BOOLEAN mSmmReadyToLock;
#define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB
#define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB
@ -780,6 +779,24 @@ SmmClearMemoryAttributes (
IN UINT64 Attributes
);
/**
Retrieves a pointer to the system configuration table from the SMM System Table
based on a specified GUID.
@param[in] TableGuid The pointer to table's GUID type.
@param[out] Table The pointer to the table associated with TableGuid in the EFI System Table.
@retval EFI_SUCCESS A configuration table matching TableGuid was found.
@retval EFI_NOT_FOUND A configuration table matching TableGuid could not be found.
**/
EFI_STATUS
EFIAPI
SmmGetSystemConfigurationTable (
IN EFI_GUID *TableGuid,
OUT VOID **Table
);
/**
Initialize MP synchronization data.
@ -932,10 +949,13 @@ DumpModuleInfoByIp (
/**
This function sets memory attribute according to MemoryAttributesTable.
@param MemoryAttributesTable A pointer to the buffer of SmmMemoryAttributesTable.
**/
VOID
SetMemMapAttributes (
VOID
EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable
);
/**

View File

@ -18,6 +18,98 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
const BOOLEAN mIsStandaloneMm = FALSE;
//
// SMM ready to lock flag
//
BOOLEAN mSmmReadyToLock = FALSE;
/**
Perform the remaining tasks.
**/
VOID
PerformRemainingTasks (
VOID
)
{
EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
if (mSmmReadyToLock) {
PERF_FUNCTION_BEGIN ();
//
// Start SMM Profile feature
//
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
SmmProfileStart ();
}
//
// Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for
// all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling
// SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock
// is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call
// FlushTlbForAll() that need to start up the aps. So it need to let all
// aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck()
// also will start up the aps.
//
if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) {
DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n"));
}
//
// Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable.
//
InitPaging ();
//
// gEdkiiPiSmmMemoryAttributesTableGuid should have been published at EndOfDxe by SmmCore
// Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on
// the memory protection attribute setting in MM Core.
//
SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
//
// Set critical region attribute in page table according to the MemoryAttributesTable
//
if (MemoryAttributesTable != NULL) {
SetMemMapAttributes (MemoryAttributesTable);
}
if (IsRestrictedMemoryAccess ()) {
//
// For outside SMRAM, we only map SMM communication buffer or MMIO.
//
SetUefiMemMapAttributes ();
//
// Set page table itself to be read-only
//
SetPageTableAttributes ();
}
//
// Configure SMM Code Access Check feature if available.
//
ConfigSmmCodeAccessCheck ();
//
// Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
// as the implementation is provided by platform.
//
PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
SmmCpuFeaturesCompleteSmmReadyToLock ();
PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
//
// Clean SMM ready to lock flag
//
mSmmReadyToLock = FALSE;
PERF_FUNCTION_END ();
}
}
/**
To get system port address of the SMI Command Port in FADT table.

View File

@ -15,6 +15,63 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
const BOOLEAN mIsStandaloneMm = TRUE;
//
// RemainingTasks Done flag
//
BOOLEAN mRemainingTasksDone = FALSE;
/**
Perform the remaining tasks.
**/
VOID
PerformRemainingTasks (
VOID
)
{
EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
if (!mRemainingTasksDone) {
PERF_FUNCTION_BEGIN ();
//
// gEdkiiPiSmmMemoryAttributesTableGuid should have been published after SmmCore dispatched all MM drivers (MmDriverDispatchHandler).
// Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on
// the memory protection attribute setting in MM Core.
//
SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
//
// Set critical region attribute in page table according to the MemoryAttributesTable
//
if (MemoryAttributesTable != NULL) {
SetMemMapAttributes (MemoryAttributesTable);
}
if (IsRestrictedMemoryAccess ()) {
//
// Set page table itself to be read-only
//
SetPageTableAttributes ();
}
//
// Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
// as the implementation is provided by platform.
//
PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
SmmCpuFeaturesCompleteSmmReadyToLock ();
PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
//
// Mark RemainingTasks Done flag to TRUE
//
mRemainingTasksDone = TRUE;
PERF_FUNCTION_END ();
}
}
/**
To get system port address of the SMI Command Port.

View File

@ -993,31 +993,29 @@ SetMemMapWithNonPresentRange (
/**
This function sets memory attribute according to MemoryAttributesTable.
@param MemoryAttributesTable A pointer to the buffer of SmmMemoryAttributesTable.
**/
VOID
SetMemMapAttributes (
VOID
EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable
)
{
EFI_MEMORY_DESCRIPTOR *MemoryMap;
EFI_MEMORY_DESCRIPTOR *MemoryMapStart;
UINTN MemoryMapEntryCount;
UINTN DescriptorSize;
UINTN Index;
EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
UINTN PageTable;
EFI_STATUS Status;
IA32_MAP_ENTRY *Map;
UINTN Count;
UINT64 MemoryAttribute;
BOOLEAN WriteProtect;
BOOLEAN CetEnabled;
EFI_MEMORY_DESCRIPTOR *MemoryMap;
EFI_MEMORY_DESCRIPTOR *MemoryMapStart;
UINTN MemoryMapEntryCount;
UINTN DescriptorSize;
UINTN Index;
UINTN PageTable;
EFI_STATUS Status;
IA32_MAP_ENTRY *Map;
UINTN Count;
UINT64 MemoryAttribute;
BOOLEAN WriteProtect;
BOOLEAN CetEnabled;
SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
if (MemoryAttributesTable == NULL) {
DEBUG ((DEBUG_INFO, "MemoryAttributesTable - NULL\n"));
return;
}
ASSERT (MemoryAttributesTable != NULL);
PERF_FUNCTION_BEGIN ();