mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 07:34:06 +02:00
UefiCpuPkg: rename the SmiDefaultPFHandler function
Rename SmiDefaultPFHandler to SmiProfileMapPFAddress and move the implementation to SmmProfileArch.c since it only will be used when SMM profile is enabled. Signed-off-by: Dun Tan <dun.tan@intel.com>
This commit is contained in:
parent
cae90a8390
commit
8b8ac5d986
@ -82,18 +82,6 @@ AllocPage (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Page Fault handler for SMM use.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SmiDefaultPFHandler (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CpuDeadLoop ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
ThePage Fault handler wrapper for SMM use.
|
ThePage Fault handler wrapper for SMM use.
|
||||||
|
|
||||||
|
@ -76,3 +76,15 @@ ClearTrapFlag (
|
|||||||
{
|
{
|
||||||
SystemContext.SystemContextIa32->Eflags &= (UINTN) ~BIT8;
|
SystemContext.SystemContextIa32->Eflags &= (UINTN) ~BIT8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create new entry in page table for page fault address in SmmProfilePFHandler.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmProfileMapPFAddress (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CpuDeadLoop ();
|
||||||
|
}
|
||||||
|
@ -1337,7 +1337,7 @@ SmmProfilePFHandler (
|
|||||||
//
|
//
|
||||||
// If SMM profile does not start, call original page fault handler.
|
// If SMM profile does not start, call original page fault handler.
|
||||||
//
|
//
|
||||||
SmiDefaultPFHandler ();
|
SmmProfileMapPFAddress ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +153,11 @@ AllocPage (
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Page Fault handler for SMM use.
|
Create new entry in page table for page fault address in SmmProfilePFHandler.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
SmiDefaultPFHandler (
|
SmmProfileMapPFAddress (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -700,156 +700,6 @@ AllocPage (
|
|||||||
return RetVal;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Page Fault handler for SMM use.
|
|
||||||
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SmiDefaultPFHandler (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT64 *PageTable;
|
|
||||||
UINT64 *PageTableTop;
|
|
||||||
UINT64 PFAddress;
|
|
||||||
UINTN StartBit;
|
|
||||||
UINTN EndBit;
|
|
||||||
UINT64 PTIndex;
|
|
||||||
UINTN Index;
|
|
||||||
SMM_PAGE_SIZE_TYPE PageSize;
|
|
||||||
UINTN NumOfPages;
|
|
||||||
UINTN PageAttribute;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT64 *UpperEntry;
|
|
||||||
BOOLEAN Enable5LevelPaging;
|
|
||||||
IA32_CR4 Cr4;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set default SMM page attribute
|
|
||||||
//
|
|
||||||
PageSize = SmmPageSize2M;
|
|
||||||
NumOfPages = 1;
|
|
||||||
PageAttribute = 0;
|
|
||||||
|
|
||||||
EndBit = 0;
|
|
||||||
PageTableTop = (UINT64 *)(AsmReadCr3 () & gPhyMask);
|
|
||||||
PFAddress = AsmReadCr2 ();
|
|
||||||
|
|
||||||
Cr4.UintN = AsmReadCr4 ();
|
|
||||||
Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0);
|
|
||||||
|
|
||||||
Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute);
|
|
||||||
//
|
|
||||||
// If platform not support page table attribute, set default SMM page attribute
|
|
||||||
//
|
|
||||||
if (Status != EFI_SUCCESS) {
|
|
||||||
PageSize = SmmPageSize2M;
|
|
||||||
NumOfPages = 1;
|
|
||||||
PageAttribute = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageSize >= MaxSmmPageSizeType) {
|
|
||||||
PageSize = SmmPageSize2M;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NumOfPages > 512) {
|
|
||||||
NumOfPages = 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (PageSize) {
|
|
||||||
case SmmPageSize4K:
|
|
||||||
//
|
|
||||||
// BIT12 to BIT20 is Page Table index
|
|
||||||
//
|
|
||||||
EndBit = 12;
|
|
||||||
break;
|
|
||||||
case SmmPageSize2M:
|
|
||||||
//
|
|
||||||
// BIT21 to BIT29 is Page Directory index
|
|
||||||
//
|
|
||||||
EndBit = 21;
|
|
||||||
PageAttribute |= (UINTN)IA32_PG_PS;
|
|
||||||
break;
|
|
||||||
case SmmPageSize1G:
|
|
||||||
if (!m1GPageTableSupport) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!"));
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// BIT30 to BIT38 is Page Directory Pointer Table index
|
|
||||||
//
|
|
||||||
EndBit = 30;
|
|
||||||
PageAttribute |= (UINTN)IA32_PG_PS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If execute-disable is enabled, set NX bit
|
|
||||||
//
|
|
||||||
if (mXdEnabled) {
|
|
||||||
PageAttribute |= IA32_PG_NX;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Index = 0; Index < NumOfPages; Index++) {
|
|
||||||
PageTable = PageTableTop;
|
|
||||||
UpperEntry = NULL;
|
|
||||||
for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) {
|
|
||||||
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met:
|
|
||||||
// 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity.
|
|
||||||
// 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry.
|
|
||||||
//
|
|
||||||
if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) {
|
|
||||||
if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
|
|
||||||
//
|
|
||||||
// If the entry is not present, allocate one page from page pool for it
|
|
||||||
//
|
|
||||||
PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Save the upper entry address
|
|
||||||
//
|
|
||||||
UpperEntry = PageTable + PTIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// BIT9 to BIT11 of entry is used to save access record,
|
|
||||||
// initialize value is 7
|
|
||||||
//
|
|
||||||
PageTable[PTIndex] |= (UINT64)IA32_PG_A;
|
|
||||||
SetAccNum (PageTable + PTIndex, 7);
|
|
||||||
PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Found the appropriate entry.
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fill the new entry
|
|
||||||
//
|
|
||||||
PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) |
|
|
||||||
PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
|
|
||||||
if (UpperEntry != NULL) {
|
|
||||||
SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the next page address if we need to create more page tables
|
|
||||||
//
|
|
||||||
PFAddress += (1ull << StartBit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
ThePage Fault handler wrapper for SMM use.
|
ThePage Fault handler wrapper for SMM use.
|
||||||
|
|
||||||
|
@ -109,6 +109,156 @@ AcquirePage (
|
|||||||
mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;
|
mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create new entry in page table for page fault address in SmmProfilePFHandler.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmProfileMapPFAddress (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 *PageTable;
|
||||||
|
UINT64 *PageTableTop;
|
||||||
|
UINT64 PFAddress;
|
||||||
|
UINTN StartBit;
|
||||||
|
UINTN EndBit;
|
||||||
|
UINT64 PTIndex;
|
||||||
|
UINTN Index;
|
||||||
|
SMM_PAGE_SIZE_TYPE PageSize;
|
||||||
|
UINTN NumOfPages;
|
||||||
|
UINTN PageAttribute;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT64 *UpperEntry;
|
||||||
|
BOOLEAN Enable5LevelPaging;
|
||||||
|
IA32_CR4 Cr4;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set default SMM page attribute
|
||||||
|
//
|
||||||
|
PageSize = SmmPageSize2M;
|
||||||
|
NumOfPages = 1;
|
||||||
|
PageAttribute = 0;
|
||||||
|
|
||||||
|
EndBit = 0;
|
||||||
|
PageTableTop = (UINT64 *)(AsmReadCr3 () & gPhyMask);
|
||||||
|
PFAddress = AsmReadCr2 ();
|
||||||
|
|
||||||
|
Cr4.UintN = AsmReadCr4 ();
|
||||||
|
Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0);
|
||||||
|
|
||||||
|
Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute);
|
||||||
|
//
|
||||||
|
// If platform not support page table attribute, set default SMM page attribute
|
||||||
|
//
|
||||||
|
if (Status != EFI_SUCCESS) {
|
||||||
|
PageSize = SmmPageSize2M;
|
||||||
|
NumOfPages = 1;
|
||||||
|
PageAttribute = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PageSize >= MaxSmmPageSizeType) {
|
||||||
|
PageSize = SmmPageSize2M;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NumOfPages > 512) {
|
||||||
|
NumOfPages = 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (PageSize) {
|
||||||
|
case SmmPageSize4K:
|
||||||
|
//
|
||||||
|
// BIT12 to BIT20 is Page Table index
|
||||||
|
//
|
||||||
|
EndBit = 12;
|
||||||
|
break;
|
||||||
|
case SmmPageSize2M:
|
||||||
|
//
|
||||||
|
// BIT21 to BIT29 is Page Directory index
|
||||||
|
//
|
||||||
|
EndBit = 21;
|
||||||
|
PageAttribute |= (UINTN)IA32_PG_PS;
|
||||||
|
break;
|
||||||
|
case SmmPageSize1G:
|
||||||
|
if (!m1GPageTableSupport) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!"));
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// BIT30 to BIT38 is Page Directory Pointer Table index
|
||||||
|
//
|
||||||
|
EndBit = 30;
|
||||||
|
PageAttribute |= (UINTN)IA32_PG_PS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If execute-disable is enabled, set NX bit
|
||||||
|
//
|
||||||
|
if (mXdEnabled) {
|
||||||
|
PageAttribute |= IA32_PG_NX;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumOfPages; Index++) {
|
||||||
|
PageTable = PageTableTop;
|
||||||
|
UpperEntry = NULL;
|
||||||
|
for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) {
|
||||||
|
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met:
|
||||||
|
// 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity.
|
||||||
|
// 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry.
|
||||||
|
//
|
||||||
|
if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) {
|
||||||
|
if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
|
||||||
|
//
|
||||||
|
// If the entry is not present, allocate one page from page pool for it
|
||||||
|
//
|
||||||
|
PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Save the upper entry address
|
||||||
|
//
|
||||||
|
UpperEntry = PageTable + PTIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// BIT9 to BIT11 of entry is used to save access record,
|
||||||
|
// initialize value is 7
|
||||||
|
//
|
||||||
|
PageTable[PTIndex] |= (UINT64)IA32_PG_A;
|
||||||
|
SetAccNum (PageTable + PTIndex, 7);
|
||||||
|
PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Found the appropriate entry.
|
||||||
|
//
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the new entry
|
||||||
|
//
|
||||||
|
PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) |
|
||||||
|
PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
|
||||||
|
if (UpperEntry != NULL) {
|
||||||
|
SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the next page address if we need to create more page tables
|
||||||
|
//
|
||||||
|
PFAddress += (1ull << StartBit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Update page table to map the memory correctly in order to make the instruction
|
Update page table to map the memory correctly in order to make the instruction
|
||||||
which caused page fault execute successfully. And it also save the original page
|
which caused page fault execute successfully. And it also save the original page
|
||||||
@ -220,7 +370,7 @@ RestorePageTableAbove4G (
|
|||||||
//
|
//
|
||||||
// Create one entry in page table for page fault address.
|
// Create one entry in page table for page fault address.
|
||||||
//
|
//
|
||||||
SmiDefaultPFHandler ();
|
SmmProfileMapPFAddress ();
|
||||||
//
|
//
|
||||||
// Find the page table entry created just now.
|
// Find the page table entry created just now.
|
||||||
//
|
//
|
||||||
|
@ -55,6 +55,8 @@ typedef struct _PEBS_RECORD {
|
|||||||
|
|
||||||
#pragma pack ()
|
#pragma pack ()
|
||||||
|
|
||||||
|
extern BOOLEAN m1GPageTableSupport;
|
||||||
|
|
||||||
#define PHYSICAL_ADDRESS_MASK ((1ull << 52) - SIZE_4KB)
|
#define PHYSICAL_ADDRESS_MASK ((1ull << 52) - SIZE_4KB)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,4 +100,57 @@ InitPagesForPFHandler (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set sub-entries number in entry.
|
||||||
|
|
||||||
|
@param[in, out] Entry Pointer to entry
|
||||||
|
@param[in] SubEntryNum Sub-entries number based on 0:
|
||||||
|
0 means there is 1 sub-entry under this entry
|
||||||
|
0x1ff means there is 512 sub-entries under this entry
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SetSubEntriesNum (
|
||||||
|
IN OUT UINT64 *Entry,
|
||||||
|
IN UINT64 SubEntryNum
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return sub-entries number in entry.
|
||||||
|
|
||||||
|
@param[in] Entry Pointer to entry
|
||||||
|
|
||||||
|
@return Sub-entries number based on 0:
|
||||||
|
0 means there is 1 sub-entry under this entry
|
||||||
|
0x1ff means there is 512 sub-entries under this entry
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
GetSubEntriesNum (
|
||||||
|
IN UINT64 *Entry
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allocate free Page for PageFault handler use.
|
||||||
|
|
||||||
|
@return Page address.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
AllocPage (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set access record in entry.
|
||||||
|
|
||||||
|
@param[in, out] Entry Pointer to entry
|
||||||
|
@param[in] Acc Access record value
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SetAccNum (
|
||||||
|
IN OUT UINT64 *Entry,
|
||||||
|
IN UINT64 Acc
|
||||||
|
);
|
||||||
|
|
||||||
#endif // _SMM_PROFILE_ARCH_H_
|
#endif // _SMM_PROFILE_ARCH_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user