summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiaxin Wu <jiaxin.wu@intel.com>2024-07-03 16:16:57 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-07-05 08:18:31 +0000
commitbef0d333dc4fccdfc75e4be31e067b467a9a4093 (patch)
treefe9b574f603ee24de7c51a3fc94a7b5e837a6ec9
parent9389b9a208cc5c7d9b055ea06d92cc4903f705ee (diff)
downloadedk2-bef0d333dc4fccdfc75e4be31e067b467a9a4093.zip
edk2-bef0d333dc4fccdfc75e4be31e067b467a9a4093.tar.gz
edk2-bef0d333dc4fccdfc75e4be31e067b467a9a4093.tar.bz2
UefiCpuPkg/PiSmmCpuDxeSmm: Fix system hang when SmmProfile enable
MMIO ranges within the mProtectionMemRange array may exceed 4G and should be configured as 'Present & NX'. However, the initial attribute for these MMIO addresses in the page table is 'non-present'. Other attributes should not be set or updated for a non-present range if the present bit mask is zero, as this could result in an error during the InitPaging for the page table update process. This patch is to resolve the error to make sure MMIO page table can be configured correctly. 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>
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index 8142d3c..692aad2 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -1,7 +1,7 @@
/** @file
Enable SMM profile.
-Copyright (c) 2012 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -594,6 +594,7 @@ InitPaging (
UINT64 Limit;
UINT64 PreviousAddress;
UINT64 MemoryAttrMask;
+ BOOLEAN IsSet;
BOOLEAN WriteProtect;
BOOLEAN CetEnabled;
@@ -616,19 +617,38 @@ InitPaging (
DEBUG ((DEBUG_INFO, "Patch page table start ...\n"));
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
- MemoryAttrMask = 0;
- if (mProtectionMemRange[Index].Nx == TRUE) {
+ Base = mProtectionMemRange[Index].Range.Base;
+ Length = mProtectionMemRange[Index].Range.Top - Base;
+
+ MemoryAttrMask = EFI_MEMORY_RP;
+ if (!mProtectionMemRange[Index].Present) {
+ //
+ // Config the EFI_MEMORY_RP attribute to make it non-present.
+ //
+ IsSet = TRUE;
+ } else {
+ //
+ // Clear the EFI_MEMORY_RP attribute to make it present.
+ //
+ IsSet = FALSE;
+
+ //
+ // Config the range as writable and executable when mapping a range as present.
+ //
+ MemoryAttrMask |= EFI_MEMORY_RO;
MemoryAttrMask |= EFI_MEMORY_XP;
}
- if (mProtectionMemRange[Index].Present == FALSE) {
- MemoryAttrMask = EFI_MEMORY_RP;
- }
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, IsSet, NULL);
+ ASSERT_RETURN_ERROR (Status);
- Base = mProtectionMemRange[Index].Range.Base;
- Length = mProtectionMemRange[Index].Range.Top - Base;
- if (MemoryAttrMask != 0) {
- Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL);
+ if (mProtectionMemRange[Index].Present && mProtectionMemRange[Index].Nx) {
+ //
+ // Since EFI_MEMORY_XP has already been cleared above, only handle the case to disable execution.
+ // Config the EFI_MEMORY_XP attribute to disable execution.
+ //
+ MemoryAttrMask = EFI_MEMORY_XP;
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL);
ASSERT_RETURN_ERROR (Status);
}