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
|
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
|
#endif
|
||||||
|
|
|
@ -40,6 +40,64 @@ PAGE_TABLE_POOL *mPageTablePool = NULL;
|
||||||
//
|
//
|
||||||
BOOLEAN mIsReadOnlyPageTable = FALSE;
|
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.
|
Initialize a buffer pool for page table use only.
|
||||||
|
|
||||||
|
@ -62,10 +120,9 @@ InitializePageTablePool (
|
||||||
IN UINTN PoolPages
|
IN UINTN PoolPages
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VOID *Buffer;
|
VOID *Buffer;
|
||||||
BOOLEAN CetEnabled;
|
BOOLEAN WpEnabled;
|
||||||
BOOLEAN WpEnabled;
|
BOOLEAN CetEnabled;
|
||||||
IA32_CR0 Cr0;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for
|
// 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 page table memory has been marked as RO, mark the new pool pages as read-only.
|
||||||
//
|
//
|
||||||
if (mIsReadOnlyPageTable) {
|
if (mIsReadOnlyPageTable) {
|
||||||
CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
|
DisableReadOnlyPageWriteProtect (&WpEnabled, &CetEnabled);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
SmmSetMemoryAttributes ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (PoolPages), EFI_MEMORY_RO);
|
SmmSetMemoryAttributes ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (PoolPages), EFI_MEMORY_RO);
|
||||||
if (WpEnabled) {
|
EnableReadOnlyPageWriteProtect (WpEnabled, CetEnabled);
|
||||||
Cr0.UintN = AsmReadCr0 ();
|
|
||||||
Cr0.Bits.WP = 1;
|
|
||||||
AsmWriteCr0 (Cr0.UintN);
|
|
||||||
|
|
||||||
if (CetEnabled) {
|
|
||||||
//
|
|
||||||
// re-enable CET.
|
|
||||||
//
|
|
||||||
EnableCet ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1786,6 +1818,7 @@ SetPageTableAttributes (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
BOOLEAN WpEnabled;
|
||||||
BOOLEAN CetEnabled;
|
BOOLEAN CetEnabled;
|
||||||
|
|
||||||
if (!IfReadOnlyPageTableNeeded ()) {
|
if (!IfReadOnlyPageTableNeeded ()) {
|
||||||
|
@ -1799,15 +1832,7 @@ SetPageTableAttributes (
|
||||||
// Disable write protection, because we need mark page table to be write protected.
|
// 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*.
|
// We need *write* page table memory, to mark itself to be *read only*.
|
||||||
//
|
//
|
||||||
CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
|
DisableReadOnlyPageWriteProtect (&WpEnabled, &CetEnabled);
|
||||||
if (CetEnabled) {
|
|
||||||
//
|
|
||||||
// CET must be disabled if WP is disabled.
|
|
||||||
//
|
|
||||||
DisableCet ();
|
|
||||||
}
|
|
||||||
|
|
||||||
AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);
|
|
||||||
|
|
||||||
// Set memory used by page table as Read Only.
|
// Set memory used by page table as Read Only.
|
||||||
DEBUG ((DEBUG_INFO, "Start...\n"));
|
DEBUG ((DEBUG_INFO, "Start...\n"));
|
||||||
|
@ -1816,20 +1841,12 @@ SetPageTableAttributes (
|
||||||
//
|
//
|
||||||
// Enable write protection, after page table attribute updated.
|
// Enable write protection, after page table attribute updated.
|
||||||
//
|
//
|
||||||
AsmWriteCr0 (AsmReadCr0 () | CR0_WP);
|
EnableReadOnlyPageWriteProtect (TRUE, CetEnabled);
|
||||||
mIsReadOnlyPageTable = TRUE;
|
mIsReadOnlyPageTable = TRUE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Flush TLB after mark all page table pool as read only.
|
// Flush TLB after mark all page table pool as read only.
|
||||||
//
|
//
|
||||||
FlushTlbForAll ();
|
FlushTlbForAll ();
|
||||||
|
|
||||||
if (CetEnabled) {
|
|
||||||
//
|
|
||||||
// re-enable CET.
|
|
||||||
//
|
|
||||||
EnableCet ();
|
|
||||||
}
|
|
||||||
|
|
||||||
PERF_FUNCTION_END ();
|
PERF_FUNCTION_END ();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue