mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/PiSmmCpuDxeSmm: Add 2 function to disable/enable CR0.WP
Add two functions to disable/enable CR0.WP. These two unctions will also be used in later commits. This commit doesn't change any functionality. Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
f51967280b
commit
7b6e7d0098
|
@ -1567,4 +1567,28 @@ SmmWaitForApArrival (
|
|||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Disable Write Protect on pages marked as read-only if Cr0.Bits.WP is 1.
|
||||
|
||||
@param[out] WpEnabled If Cr0.WP is enabled.
|
||||
@param[out] CetEnabled If CET is enabled.
|
||||
**/
|
||||
VOID
|
||||
DisableReadOnlyPageWriteProtect (
|
||||
OUT BOOLEAN *WpEnabled,
|
||||
OUT BOOLEAN *CetEnabled
|
||||
);
|
||||
|
||||
/**
|
||||
Enable Write Protect on pages marked as read-only.
|
||||
|
||||
@param[out] WpEnabled If Cr0.WP should be enabled.
|
||||
@param[out] CetEnabled If CET should be enabled.
|
||||
**/
|
||||
VOID
|
||||
EnableReadOnlyPageWriteProtect (
|
||||
BOOLEAN WpEnabled,
|
||||
BOOLEAN CetEnabled
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,64 @@ PAGE_TABLE_POOL *mPageTablePool = NULL;
|
|||
//
|
||||
BOOLEAN mIsReadOnlyPageTable = FALSE;
|
||||
|
||||
/**
|
||||
Disable Write Protect on pages marked as read-only if Cr0.Bits.WP is 1.
|
||||
|
||||
@param[out] WpEnabled If Cr0.WP is enabled.
|
||||
@param[out] CetEnabled If CET is enabled.
|
||||
**/
|
||||
VOID
|
||||
DisableReadOnlyPageWriteProtect (
|
||||
OUT BOOLEAN *WpEnabled,
|
||||
OUT BOOLEAN *CetEnabled
|
||||
)
|
||||
{
|
||||
IA32_CR0 Cr0;
|
||||
|
||||
*CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
|
||||
Cr0.UintN = AsmReadCr0 ();
|
||||
*WpEnabled = (Cr0.Bits.WP != 0) ? TRUE : FALSE;
|
||||
if (*WpEnabled) {
|
||||
if (*CetEnabled) {
|
||||
//
|
||||
// CET must be disabled if WP is disabled. Disable CET before clearing CR0.WP.
|
||||
//
|
||||
DisableCet ();
|
||||
}
|
||||
|
||||
Cr0.Bits.WP = 0;
|
||||
AsmWriteCr0 (Cr0.UintN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Enable Write Protect on pages marked as read-only.
|
||||
|
||||
@param[out] WpEnabled If Cr0.WP should be enabled.
|
||||
@param[out] CetEnabled If CET should be enabled.
|
||||
**/
|
||||
VOID
|
||||
EnableReadOnlyPageWriteProtect (
|
||||
BOOLEAN WpEnabled,
|
||||
BOOLEAN CetEnabled
|
||||
)
|
||||
{
|
||||
IA32_CR0 Cr0;
|
||||
|
||||
if (WpEnabled) {
|
||||
Cr0.UintN = AsmReadCr0 ();
|
||||
Cr0.Bits.WP = 1;
|
||||
AsmWriteCr0 (Cr0.UintN);
|
||||
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// re-enable CET.
|
||||
//
|
||||
EnableCet ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize a buffer pool for page table use only.
|
||||
|
||||
|
@ -62,10 +120,9 @@ InitializePageTablePool (
|
|||
IN UINTN PoolPages
|
||||
)
|
||||
{
|
||||
VOID *Buffer;
|
||||
BOOLEAN CetEnabled;
|
||||
BOOLEAN WpEnabled;
|
||||
IA32_CR0 Cr0;
|
||||
VOID *Buffer;
|
||||
BOOLEAN WpEnabled;
|
||||
BOOLEAN CetEnabled;
|
||||
|
||||
//
|
||||
// Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for
|
||||
|
@ -102,34 +159,9 @@ InitializePageTablePool (
|
|||
// If page table memory has been marked as RO, mark the new pool pages as read-only.
|
||||
//
|
||||
if (mIsReadOnlyPageTable) {
|
||||
CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
|
||||
Cr0.UintN = AsmReadCr0 ();
|
||||
WpEnabled = (Cr0.Bits.WP != 0) ? TRUE : FALSE;
|
||||
if (WpEnabled) {
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// CET must be disabled if WP is disabled. Disable CET before clearing CR0.WP.
|
||||
//
|
||||
DisableCet ();
|
||||
}
|
||||
|
||||
Cr0.Bits.WP = 0;
|
||||
AsmWriteCr0 (Cr0.UintN);
|
||||
}
|
||||
|
||||
DisableReadOnlyPageWriteProtect (&WpEnabled, &CetEnabled);
|
||||
SmmSetMemoryAttributes ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (PoolPages), EFI_MEMORY_RO);
|
||||
if (WpEnabled) {
|
||||
Cr0.UintN = AsmReadCr0 ();
|
||||
Cr0.Bits.WP = 1;
|
||||
AsmWriteCr0 (Cr0.UintN);
|
||||
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// re-enable CET.
|
||||
//
|
||||
EnableCet ();
|
||||
}
|
||||
}
|
||||
EnableReadOnlyPageWriteProtect (WpEnabled, CetEnabled);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1786,6 +1818,7 @@ SetPageTableAttributes (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
BOOLEAN WpEnabled;
|
||||
BOOLEAN CetEnabled;
|
||||
|
||||
if (!IfReadOnlyPageTableNeeded ()) {
|
||||
|
@ -1799,15 +1832,7 @@ SetPageTableAttributes (
|
|||
// Disable write protection, because we need mark page table to be write protected.
|
||||
// We need *write* page table memory, to mark itself to be *read only*.
|
||||
//
|
||||
CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// CET must be disabled if WP is disabled.
|
||||
//
|
||||
DisableCet ();
|
||||
}
|
||||
|
||||
AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);
|
||||
DisableReadOnlyPageWriteProtect (&WpEnabled, &CetEnabled);
|
||||
|
||||
// Set memory used by page table as Read Only.
|
||||
DEBUG ((DEBUG_INFO, "Start...\n"));
|
||||
|
@ -1816,20 +1841,12 @@ SetPageTableAttributes (
|
|||
//
|
||||
// Enable write protection, after page table attribute updated.
|
||||
//
|
||||
AsmWriteCr0 (AsmReadCr0 () | CR0_WP);
|
||||
EnableReadOnlyPageWriteProtect (TRUE, CetEnabled);
|
||||
mIsReadOnlyPageTable = TRUE;
|
||||
|
||||
//
|
||||
// Flush TLB after mark all page table pool as read only.
|
||||
//
|
||||
FlushTlbForAll ();
|
||||
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// re-enable CET.
|
||||
//
|
||||
EnableCet ();
|
||||
}
|
||||
|
||||
PERF_FUNCTION_END ();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue