* [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: Save SMM ranges info into global variables
2017-03-28 8:50 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: Check all SMM ranges found Jeff Fan
@ 2017-03-28 8:50 ` Jeff Fan
2017-03-28 8:50 ` [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: Add IsInSmmRanges() to check SMM range Jeff Fan
2017-03-28 8:50 ` [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: Update saved SMM ranges check in SmmProfile Jeff Fan
2 siblings, 0 replies; 5+ messages in thread
From: Jeff Fan @ 2017-03-28 8:50 UTC (permalink / raw)
To: edk2-devel; +Cc: Jiewen Yao, Michael Kinney, Feng Tian
NX/SmmProfile feature required to protect all SMM ranges. This update is
to check all saved SMM ranges by SMM ACCESS protocol besides the range
specified by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 44 ++++++++++++++++--------------
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 4 ++-
2 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index d061482..bcdb498 100755
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -108,6 +108,12 @@ UINT64 mAddressEncMask = 0;
//
SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
+//
+// Saved SMM ranges information
+//
+EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
+UINTN mSmmCpuSmramRangeCount;
+
/**
Initialize IDT to setup exception handlers for SMM.
@@ -971,8 +977,6 @@ FindSmramInfo (
UINTN Size;
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
EFI_SMRAM_DESCRIPTOR *CurrentSmramRange;
- EFI_SMRAM_DESCRIPTOR *SmramRanges;
- UINTN SmramRangeCount;
UINTN Index;
UINT64 MaxSize;
BOOLEAN Found;
@@ -990,31 +994,31 @@ FindSmramInfo (
Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- SmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
- ASSERT (SmramRanges != NULL);
+ mSmmCpuSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
+ ASSERT (mSmmCpuSmramRanges != NULL);
- Status = SmmAccess->GetCapabilities (SmmAccess, &Size, SmramRanges);
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmCpuSmramRanges);
ASSERT_EFI_ERROR (Status);
- SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+ mSmmCpuSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
//
// Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size
//
CurrentSmramRange = NULL;
- for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < SmramRangeCount; Index++) {
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < mSmmCpuSmramRangeCount; Index++) {
//
// Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
//
- if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ if ((mSmmCpuSmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
continue;
}
- if (SmramRanges[Index].CpuStart >= BASE_1MB) {
- if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {
- if (SmramRanges[Index].PhysicalSize >= MaxSize) {
- MaxSize = SmramRanges[Index].PhysicalSize;
- CurrentSmramRange = &SmramRanges[Index];
+ if (mSmmCpuSmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) <= BASE_4GB) {
+ if (mSmmCpuSmramRanges[Index].PhysicalSize >= MaxSize) {
+ MaxSize = mSmmCpuSmramRanges[Index].PhysicalSize;
+ CurrentSmramRange = &mSmmCpuSmramRanges[Index];
}
}
}
@@ -1027,19 +1031,19 @@ FindSmramInfo (
do {
Found = FALSE;
- for (Index = 0; Index < SmramRangeCount; Index++) {
- if (SmramRanges[Index].CpuStart < *SmrrBase && *SmrrBase == (SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize)) {
- *SmrrBase = (UINT32)SmramRanges[Index].CpuStart;
- *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if (mSmmCpuSmramRanges[Index].CpuStart < *SmrrBase &&
+ *SmrrBase == (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize)) {
+ *SmrrBase = (UINT32)mSmmCpuSmramRanges[Index].CpuStart;
+ *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
Found = TRUE;
- } else if ((*SmrrBase + *SmrrSize) == SmramRanges[Index].CpuStart && SmramRanges[Index].PhysicalSize > 0) {
- *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
+ } else if ((*SmrrBase + *SmrrSize) == mSmmCpuSmramRanges[Index].CpuStart && mSmmCpuSmramRanges[Index].PhysicalSize > 0) {
+ *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
Found = TRUE;
}
}
} while (Found);
- FreePool (SmramRanges);
DEBUG ((EFI_D_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize));
}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index 71af2f1..969eb47 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -1,7 +1,7 @@
/** @file
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
-Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
This program and the accompanying materials
@@ -415,6 +415,8 @@ extern UINTN mSemaphoreSize;
extern SPIN_LOCK *mPFLock;
extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
extern SPIN_LOCK *mMemoryMappedLock;
+extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
+extern UINTN mSmmCpuSmramRangeCount;
//
// Copy of the PcdPteMemoryEncryptionAddressOrMask
--
2.9.3.windows.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: Add IsInSmmRanges() to check SMM range
2017-03-28 8:50 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: Check all SMM ranges found Jeff Fan
2017-03-28 8:50 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: Save SMM ranges info into global variables Jeff Fan
@ 2017-03-28 8:50 ` Jeff Fan
2017-03-28 8:50 ` [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: Update saved SMM ranges check in SmmProfile Jeff Fan
2 siblings, 0 replies; 5+ messages in thread
From: Jeff Fan @ 2017-03-28 8:50 UTC (permalink / raw)
To: edk2-devel; +Cc: Jiewen Yao, Michael Kinney, Feng Tian
Internal function IsInSmmRanges() is added t check SMM range by saved SMM ranges
beside by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 36 +++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index 1b84e2c..7125aec 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -1,7 +1,7 @@
/** @file
Enable SMM profile.
-Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
This program and the accompanying materials
@@ -247,6 +247,33 @@ DebugExceptionHandler (
}
/**
+ Check if the input address is in SMM ranges.
+
+ @param[in] Address The input address.
+
+ @retval TRUE The input address is in SMM.
+ @retval FALSE The input address is not in SMM.
+**/
+BOOLEAN
+IsInSmmRanges (
+ IN EFI_PHYSICAL_ADDRESS Address
+ )
+{
+ UINTN Index;
+
+ if ((Address < mCpuHotPlugData.SmrrBase) || (Address >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
+ return TRUE;
+ }
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if (Address >= mSmmCpuSmramRanges[Index].CpuStart &&
+ Address < mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
Check if the memory address will be mapped by 4KB-page.
@param Address The address of Memory.
@@ -261,7 +288,6 @@ IsAddressValid (
{
UINTN Index;
- *Nx = FALSE;
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
//
// Check configuration
@@ -276,9 +302,9 @@ IsAddressValid (
return FALSE;
} else {
- if ((Address < mCpuHotPlugData.SmrrBase) ||
- (Address >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
- *Nx = TRUE;
+ *Nx = TRUE;
+ if (IsInSmmRanges (Address)) {
+ *Nx = FALSE;
}
return TRUE;
}
--
2.9.3.windows.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm: Update saved SMM ranges check in SmmProfile
2017-03-28 8:50 [PATCH 0/3] UefiCpuPkg/PiSmmCpuDxeSmm: Check all SMM ranges found Jeff Fan
2017-03-28 8:50 ` [PATCH 1/3] UefiCpuPkg/PiSmmCpuDxeSmm: Save SMM ranges info into global variables Jeff Fan
2017-03-28 8:50 ` [PATCH 2/3] UefiCpuPkg/PiSmmCpuDxeSmm: Add IsInSmmRanges() to check SMM range Jeff Fan
@ 2017-03-28 8:50 ` Jeff Fan
2 siblings, 0 replies; 5+ messages in thread
From: Jeff Fan @ 2017-03-28 8:50 UTC (permalink / raw)
To: edk2-devel; +Cc: Jiewen Yao, Michael Kinney, Feng Tian
SmmProfile feature required to protect all SMM ranges by structure
mProtectionMemRangeTemplate. This update is to add additonal save SMM ranges
into mProtectionMemRangeTemplate besides the range specified by
mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 42 +++++++++++++++++++++++++++++-----
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index 7125aec..2713b19 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -83,6 +83,12 @@ MEMORY_PROTECTION_RANGE mProtectionMemRangeTemplate[] = {
{{0x00000000, 0x00000000},TRUE,TRUE},
//
+ // SMRAM ranges not covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz (to be fixed in runtime).
+ // It is always present and instruction fetches are allowed.
+ // {{0x00000000, 0x00000000},TRUE,FALSE},
+ //
+
+ //
// Future extended range could be added here.
//
@@ -360,7 +366,7 @@ InitProtectedMemRange (
{
UINTN Index;
UINTN NumberOfDescriptors;
- UINTN NumberOfMmioDescriptors;
+ UINTN NumberOfAddedDescriptors;
UINTN NumberOfProtectRange;
UINTN NumberOfSpliteRange;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
@@ -373,7 +379,7 @@ InitProtectedMemRange (
UINT64 Low4KBPageSize;
NumberOfDescriptors = 0;
- NumberOfMmioDescriptors = 0;
+ NumberOfAddedDescriptors = mSmmCpuSmramRangeCount;
NumberOfSpliteRange = 0;
MemorySpaceMap = NULL;
@@ -386,12 +392,12 @@ InitProtectedMemRange (
);
for (Index = 0; Index < NumberOfDescriptors; Index++) {
if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
- NumberOfMmioDescriptors++;
+ NumberOfAddedDescriptors++;
}
}
- if (NumberOfMmioDescriptors != 0) {
- TotalSize = NumberOfMmioDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
+ if (NumberOfAddedDescriptors != 0) {
+ TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
mProtectionMemRange = (MEMORY_PROTECTION_RANGE *) AllocateZeroPool (TotalSize);
ASSERT (mProtectionMemRange != NULL);
mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);
@@ -409,9 +415,27 @@ InitProtectedMemRange (
ASSERT (mSplitMemRange != NULL);
//
+ // Create SMM ranges which are set to present and execution-enable.
+ //
+ NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if (mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base &&
+ mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top) {
+ //
+ // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz
+ //
+ break;
+ }
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart;
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
+ mProtectionMemRange[NumberOfProtectRange].Nx = FALSE;
+ NumberOfProtectRange++;
+ }
+
+ //
// Create MMIO ranges which are set to present and execution-disable.
//
- NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
for (Index = 0; Index < NumberOfDescriptors; Index++) {
if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
continue;
@@ -422,6 +446,12 @@ InitProtectedMemRange (
mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
NumberOfProtectRange++;
}
+
+ //
+ // Check and updated actual protected memory ranges count
+ //
+ ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
+ mProtectionMemRangeCount = NumberOfProtectRange;
}
//
--
2.9.3.windows.2
^ permalink raw reply related [flat|nested] 5+ messages in thread