> v3
> According to Jiewen's feedback, implement new protocol
> gEdkiiSmmMemoryAttributeProtocolGuid
> to change memory attributes.
> v2
> According to Eric's feedback:
> a. Enclose bit-or with parentheses
> b. Add code in 32-bit code to bypass setting page table to read-only
Heap guard feature will update page attributes frequently. The page table
should not set to be read-only if heap guard feature is enabled for SMM
mode. Otherwise this feature cannot work.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 7 +
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 20 +++
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 98 +++++++++++++
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 +
UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 163 +++++++++++++++++++++
UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 3 +-
6 files changed, 292 insertions(+), 1 deletion(-)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
index f295c2ebf2..27c11f1b8d 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
@@ -184,6 +184,13 @@ SetPageTableAttributes (
BOOLEAN IsSplitted;
BOOLEAN PageTableSplitted;
+ //
+ // Don't mark page table as read-only if heap guard is enabled.
+ //
+ if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) {
+ return ;
+ }
+
DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n"));
//
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 282d2e6981..8635f2d2c8 100755
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -76,6 +76,15 @@ EFI_SMM_CPU_PROTOCOL mSmmCpu = {
SmmWriteSaveState
};
+///
+/// SMM Memory Attribute Protocol instance
+///
+EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = {
+ EdkiiSmmGetMemoryAttributes,
+ EdkiiSmmSetMemoryAttributes,
+ EdkiiSmmClearMemoryAttributes
+};
+
EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];
//
@@ -893,6 +902,17 @@ PiCpuSmmEntry (
);
ASSERT_EFI_ERROR (Status);
+ //
+ // Install the SMM Memory Attribute Protocol into SMM protocol database
+ //
+ Status = gSmst->SmmInstallProtocolInterface (
+ &mSmmCpuHandle,
+ &gEdkiiSmmMemoryAttributeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmMemoryAttribute
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Expose address of CPU Hot Plug Data structure if CPU hot plug is supported.
//
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index 1cf85c1481..e1c231e10b 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmReadyToLock.h>
#include <Protocol/SmmCpuService.h>
+#include <Protocol/SmmMemoryAttribute.h>
#include <Guid/AcpiS3Context.h>
#include <Guid/PiSmmMemoryAttributesTable.h>
@@ -1068,4 +1069,101 @@ TransferApToSafeState (
IN UINTN NumberToFinishAddress
);
+/**
+ This function set given attributes of the memory region specified by
+ BaseAddress and Length.
+
+ @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of
+ a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes The bit mask of attributes to set for the memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be set together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not support for
+ the memory resource range specified by
+ BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmSetMemoryAttributes (
+ IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+/**
+ This function clears given attributes of the memory region specified by
+ BaseAddress and Length.
+
+ @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of
+ a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes The bit mask of attributes to set for the memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be set together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not support for
+ the memory resource range specified by
+ BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmClearMemoryAttributes (
+ IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+/**
+ This function retrieve the attributes of the memory region specified by
+ BaseAddress and Length. If different attributes are got from different part
+ of the memory region, EFI_NO_MAPPING will be returned.
+
+ @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of
+ a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes Pointer to attributes returned.
+
+ @retval EFI_SUCCESS The attributes got for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes is NULL.
+ @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
+ region.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not support for
+ the memory resource range specified by
+ BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmGetMemoryAttributes (
+ IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 *Attributes
+ );
+
#endif
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
index 099792e6ce..43d9edd0d5 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -129,6 +129,7 @@
gEfiSmmCpuProtocolGuid ## PRODUCES
gEfiSmmReadyToLockProtocolGuid ## NOTIFY
gEfiSmmCpuServiceProtocolGuid ## PRODUCES
+ gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES
[Guids]
gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot.
@@ -159,6 +160,7 @@
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStaticPageTable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
[Depex]
gEfiMpServiceProtocolGuid
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index 3ad5256f1e..eb5e639e4b 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -1120,3 +1120,166 @@ IsSmmCommBufferForbiddenAddress (
}
return FALSE;
}
+
+/**
+ This function set given attributes of the memory region specified by
+ BaseAddress and Length.
+
+ @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of
+ a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes The bit mask of attributes to set for the memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be set together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not support for
+ the memory resource range specified by
+ BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmSetMemoryAttributes (
+ IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ return SmmSetMemoryAttributes (BaseAddress, Length, Attributes);
+}
+
+/**
+ This function clears given attributes of the memory region specified by
+ BaseAddress and Length.
+
+ @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of
+ a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes The bit mask of attributes to set for the memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be set together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not support for
+ the memory resource range specified by
+ BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmClearMemoryAttributes (
+ IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ return SmmClearMemoryAttributes (BaseAddress, Length, Attributes);
+}
+
+/**
+ This function retrieve the attributes of the memory region specified by
+ BaseAddress and Length. If different attributes are got from different part
+ of the memory region, EFI_NO_MAPPING will be returned.
+
+ @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of
+ a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes Pointer to attributes returned.
+
+ @retval EFI_SUCCESS The attributes got for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes is NULL.
+ @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
+ region.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not support for
+ the memory resource range specified by
+ BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+EdkiiSmmGetMemoryAttributes (
+ IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 *Attributes
+ )
+{
+ EFI_PHYSICAL_ADDRESS Address;
+ UINT64 *PageEntry;
+ UINT64 MemAttr;
+ PAGE_ATTRIBUTE PageAttr;
+ INT64 Size;
+
+ if (Length < SIZE_4KB || Attributes == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Size = (INT64)Length;
+ MemAttr = (UINT64)-1;
+
+ do {
+
+ PageEntry = GetPageTableEntry (BaseAddress, &PageAttr);
+ if (PageEntry == NULL || PageAttr == PageNone) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // If the memory range is cross page table boundary, make sure they
+ // share the same attribute. Return EFI_NO_MAPPING if not.
+ //
+ *Attributes = GetAttributesFromPageEntry (PageEntry);
+ if (MemAttr != (UINT64)-1 && *Attributes != MemAttr) {
+ return EFI_NO_MAPPING;
+ }
+
+ switch (PageAttr) {
+ case Page4K:
+ Address = *PageEntry & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64;
+ Size -= (SIZE_4KB - (BaseAddress - Address));
+ BaseAddress += (SIZE_4KB - (BaseAddress - Address));
+ break;
+
+ case Page2M:
+ Address = *PageEntry & ~mAddressEncMask & PAGING_2M_ADDRESS_MASK_64;
+ Size -= SIZE_2MB - (BaseAddress - Address);
+ BaseAddress += SIZE_2MB - (BaseAddress - Address);
+ break;
+
+ case Page1G:
+ Address = *PageEntry & ~mAddressEncMask & PAGING_1G_ADDRESS_MASK_64;
+ Size -= SIZE_1GB - (BaseAddress - Address);
+ BaseAddress += SIZE_1GB - (BaseAddress - Address);
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ MemAttr = *Attributes;
+
+ } while (Size > 0);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
index 3dde80f9ba..4d4668a0c6 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -902,7 +902,8 @@ SetPageTableAttributes (
BOOLEAN IsSplitted;
BOOLEAN PageTableSplitted;
- if (!mCpuSmmStaticPageTable) {
+ if (!mCpuSmmStaticPageTable
+ || (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) {
return ;
}
--
2.14.1.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Laszlo and Ruiyu, Could you please take a look at this part? There's a new protocol introduced. Thanks, Jian > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Jian J > Wang > Sent: Monday, October 23, 2017 8:51 AM > To: edk2-devel@lists.01.org > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com> > Subject: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable page > table protection > > > v3 > > According to Jiewen's feedback, implement new protocol > > gEdkiiSmmMemoryAttributeProtocolGuid > > to change memory attributes. > > > v2 > > According to Eric's feedback: > > a. Enclose bit-or with parentheses > > b. Add code in 32-bit code to bypass setting page table to read-only > > Heap guard feature will update page attributes frequently. The page table > should not set to be read-only if heap guard feature is enabled for SMM > mode. Otherwise this feature cannot work. > > Cc: Eric Dong <eric.dong@intel.com> > Cc: Jiewen Yao <jiewen.yao@intel.com> > Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Jian J Wang <jian.j.wang@intel.com> > --- > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 7 + > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 20 +++ > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 98 > +++++++++++++ > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 + > UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 163 > +++++++++++++++++++++ > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 3 +- > 6 files changed, 292 insertions(+), 1 deletion(-) > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > index f295c2ebf2..27c11f1b8d 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > @@ -184,6 +184,13 @@ SetPageTableAttributes ( > BOOLEAN IsSplitted; > BOOLEAN PageTableSplitted; > > + // > + // Don't mark page table as read-only if heap guard is enabled. > + // > + if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { > + return ; > + } > + > DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n")); > > // > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > index 282d2e6981..8635f2d2c8 100755 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > @@ -76,6 +76,15 @@ EFI_SMM_CPU_PROTOCOL mSmmCpu = { > SmmWriteSaveState > }; > > +/// > +/// SMM Memory Attribute Protocol instance > +/// > +EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = { > + EdkiiSmmGetMemoryAttributes, > + EdkiiSmmSetMemoryAttributes, > + EdkiiSmmClearMemoryAttributes > +}; > + > EFI_CPU_INTERRUPT_HANDLER > mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; > > // > @@ -893,6 +902,17 @@ PiCpuSmmEntry ( > ); > ASSERT_EFI_ERROR (Status); > > + // > + // Install the SMM Memory Attribute Protocol into SMM protocol database > + // > + Status = gSmst->SmmInstallProtocolInterface ( > + &mSmmCpuHandle, > + &gEdkiiSmmMemoryAttributeProtocolGuid, > + EFI_NATIVE_INTERFACE, > + &mSmmMemoryAttribute > + ); > + ASSERT_EFI_ERROR (Status); > + > // > // Expose address of CPU Hot Plug Data structure if CPU hot plug is supported. > // > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > index 1cf85c1481..e1c231e10b 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > @@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > #include <Protocol/SmmAccess2.h> > #include <Protocol/SmmReadyToLock.h> > #include <Protocol/SmmCpuService.h> > +#include <Protocol/SmmMemoryAttribute.h> > > #include <Guid/AcpiS3Context.h> > #include <Guid/PiSmmMemoryAttributesTable.h> > @@ -1068,4 +1069,101 @@ TransferApToSafeState ( > IN UINTN NumberToFinishAddress > ); > > +/** > + This function set given attributes of the memory region specified by > + BaseAddress and Length. > + > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > instance. > + @param BaseAddress The physical address that is the start address of > + a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes The bit mask of attributes to set for the memory > + region. > + > + @retval EFI_SUCCESS The attributes were set for the memory region. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes specified an illegal combination of > + attributes that cannot be set together. > + @retval EFI_UNSUPPORTED The processor does not support one or more > + bytes of the memory resource range specified > + by BaseAddress and Length. > + The bit mask of attributes is not support for > + the memory resource range specified by > + BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +EdkiiSmmSetMemoryAttributes ( > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ); > + > +/** > + This function clears given attributes of the memory region specified by > + BaseAddress and Length. > + > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > instance. > + @param BaseAddress The physical address that is the start address of > + a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes The bit mask of attributes to set for the memory > + region. > + > + @retval EFI_SUCCESS The attributes were set for the memory region. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes specified an illegal combination of > + attributes that cannot be set together. > + @retval EFI_UNSUPPORTED The processor does not support one or more > + bytes of the memory resource range specified > + by BaseAddress and Length. > + The bit mask of attributes is not support for > + the memory resource range specified by > + BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +EdkiiSmmClearMemoryAttributes ( > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ); > + > +/** > + This function retrieve the attributes of the memory region specified by > + BaseAddress and Length. If different attributes are got from different part > + of the memory region, EFI_NO_MAPPING will be returned. > + > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > instance. > + @param BaseAddress The physical address that is the start address of > + a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes Pointer to attributes returned. > + > + @retval EFI_SUCCESS The attributes got for the memory region. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes is NULL. > + @retval EFI_NO_MAPPING Attributes are not consistent cross the > memory > + region. > + @retval EFI_UNSUPPORTED The processor does not support one or more > + bytes of the memory resource range specified > + by BaseAddress and Length. > + The bit mask of attributes is not support for > + the memory resource range specified by > + BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +EdkiiSmmGetMemoryAttributes ( > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 *Attributes > + ); > + > #endif > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > index 099792e6ce..43d9edd0d5 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > @@ -129,6 +129,7 @@ > gEfiSmmCpuProtocolGuid ## PRODUCES > gEfiSmmReadyToLockProtocolGuid ## NOTIFY > gEfiSmmCpuServiceProtocolGuid ## PRODUCES > + gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES > > [Guids] > gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is > used for S3 boot. > @@ -159,6 +160,7 @@ > gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStaticPageTable ## > CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask > ## CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## > CONSUMES > > [Depex] > gEfiMpServiceProtocolGuid > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > index 3ad5256f1e..eb5e639e4b 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > @@ -1120,3 +1120,166 @@ IsSmmCommBufferForbiddenAddress ( > } > return FALSE; > } > + > +/** > + This function set given attributes of the memory region specified by > + BaseAddress and Length. > + > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > instance. > + @param BaseAddress The physical address that is the start address of > + a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes The bit mask of attributes to set for the memory > + region. > + > + @retval EFI_SUCCESS The attributes were set for the memory region. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes specified an illegal combination of > + attributes that cannot be set together. > + @retval EFI_UNSUPPORTED The processor does not support one or more > + bytes of the memory resource range specified > + by BaseAddress and Length. > + The bit mask of attributes is not support for > + the memory resource range specified by > + BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +EdkiiSmmSetMemoryAttributes ( > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ) > +{ > + return SmmSetMemoryAttributes (BaseAddress, Length, Attributes); > +} > + > +/** > + This function clears given attributes of the memory region specified by > + BaseAddress and Length. > + > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > instance. > + @param BaseAddress The physical address that is the start address of > + a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes The bit mask of attributes to set for the memory > + region. > + > + @retval EFI_SUCCESS The attributes were set for the memory region. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes specified an illegal combination of > + attributes that cannot be set together. > + @retval EFI_UNSUPPORTED The processor does not support one or more > + bytes of the memory resource range specified > + by BaseAddress and Length. > + The bit mask of attributes is not support for > + the memory resource range specified by > + BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +EdkiiSmmClearMemoryAttributes ( > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 Attributes > + ) > +{ > + return SmmClearMemoryAttributes (BaseAddress, Length, Attributes); > +} > + > +/** > + This function retrieve the attributes of the memory region specified by > + BaseAddress and Length. If different attributes are got from different part > + of the memory region, EFI_NO_MAPPING will be returned. > + > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > instance. > + @param BaseAddress The physical address that is the start address of > + a memory region. > + @param Length The size in bytes of the memory region. > + @param Attributes Pointer to attributes returned. > + > + @retval EFI_SUCCESS The attributes got for the memory region. > + @retval EFI_INVALID_PARAMETER Length is zero. > + Attributes is NULL. > + @retval EFI_NO_MAPPING Attributes are not consistent cross the > memory > + region. > + @retval EFI_UNSUPPORTED The processor does not support one or more > + bytes of the memory resource range specified > + by BaseAddress and Length. > + The bit mask of attributes is not support for > + the memory resource range specified by > + BaseAddress and Length. > + > +**/ > +EFI_STATUS > +EFIAPI > +EdkiiSmmGetMemoryAttributes ( > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length, > + IN UINT64 *Attributes > + ) > +{ > + EFI_PHYSICAL_ADDRESS Address; > + UINT64 *PageEntry; > + UINT64 MemAttr; > + PAGE_ATTRIBUTE PageAttr; > + INT64 Size; > + > + if (Length < SIZE_4KB || Attributes == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Size = (INT64)Length; > + MemAttr = (UINT64)-1; > + > + do { > + > + PageEntry = GetPageTableEntry (BaseAddress, &PageAttr); > + if (PageEntry == NULL || PageAttr == PageNone) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // If the memory range is cross page table boundary, make sure they > + // share the same attribute. Return EFI_NO_MAPPING if not. > + // > + *Attributes = GetAttributesFromPageEntry (PageEntry); > + if (MemAttr != (UINT64)-1 && *Attributes != MemAttr) { > + return EFI_NO_MAPPING; > + } > + > + switch (PageAttr) { > + case Page4K: > + Address = *PageEntry & ~mAddressEncMask & > PAGING_4K_ADDRESS_MASK_64; > + Size -= (SIZE_4KB - (BaseAddress - Address)); > + BaseAddress += (SIZE_4KB - (BaseAddress - Address)); > + break; > + > + case Page2M: > + Address = *PageEntry & ~mAddressEncMask & > PAGING_2M_ADDRESS_MASK_64; > + Size -= SIZE_2MB - (BaseAddress - Address); > + BaseAddress += SIZE_2MB - (BaseAddress - Address); > + break; > + > + case Page1G: > + Address = *PageEntry & ~mAddressEncMask & > PAGING_1G_ADDRESS_MASK_64; > + Size -= SIZE_1GB - (BaseAddress - Address); > + BaseAddress += SIZE_1GB - (BaseAddress - Address); > + break; > + > + default: > + return EFI_UNSUPPORTED; > + } > + > + MemAttr = *Attributes; > + > + } while (Size > 0); > + > + return EFI_SUCCESS; > +} > + > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > index 3dde80f9ba..4d4668a0c6 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > @@ -902,7 +902,8 @@ SetPageTableAttributes ( > BOOLEAN IsSplitted; > BOOLEAN PageTableSplitted; > > - if (!mCpuSmmStaticPageTable) { > + if (!mCpuSmmStaticPageTable > + || (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { > return ; > } > > -- > 2.14.1.windows.1 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
Jian, 1. For protocol not defined in Spec, please use EDKII prefix, instead of EFI prefix. 2. Could you please add more comments for BIT3 and BIT2 check? 3. Better to separate the protocol definition to a single commit. Thanks/Ray > -----Original Message----- > From: Wang, Jian J > Sent: Thursday, October 26, 2017 2:20 PM > To: edk2-devel@lists.01.org > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com>; > Laszlo Ersek <lersek@redhat.com>; Ni, Ruiyu <ruiyu.ni@intel.com> > Subject: RE: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable > page table protection > > Laszlo and Ruiyu, > > Could you please take a look at this part? There's a new protocol introduced. > > Thanks, > Jian > > > -----Original Message----- > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of > > Jian J Wang > > Sent: Monday, October 23, 2017 8:51 AM > > To: edk2-devel@lists.01.org > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Dong, Eric > > <eric.dong@intel.com> > > Subject: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable > page > > table protection > > > > > v3 > > > According to Jiewen's feedback, implement new protocol > > > gEdkiiSmmMemoryAttributeProtocolGuid > > > to change memory attributes. > > > > > v2 > > > According to Eric's feedback: > > > a. Enclose bit-or with parentheses > > > b. Add code in 32-bit code to bypass setting page table to read-only > > > > Heap guard feature will update page attributes frequently. The page > > table should not set to be read-only if heap guard feature is enabled > > for SMM mode. Otherwise this feature cannot work. > > > > Cc: Eric Dong <eric.dong@intel.com> > > Cc: Jiewen Yao <jiewen.yao@intel.com> > > Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com> > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Jian J Wang <jian.j.wang@intel.com> > > --- > > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 7 + > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 20 +++ > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 98 > > +++++++++++++ > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 + > > UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 163 > > +++++++++++++++++++++ > > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 3 +- > > 6 files changed, 292 insertions(+), 1 deletion(-) > > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > index f295c2ebf2..27c11f1b8d 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > @@ -184,6 +184,13 @@ SetPageTableAttributes ( > > BOOLEAN IsSplitted; > > BOOLEAN PageTableSplitted; > > > > + // > > + // Don't mark page table as read-only if heap guard is enabled. > > + // > > + if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { > > + return ; > > + } > > + > > DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n")); > > > > // > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > index 282d2e6981..8635f2d2c8 100755 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > @@ -76,6 +76,15 @@ EFI_SMM_CPU_PROTOCOL mSmmCpu = { > > SmmWriteSaveState > > }; > > > > +/// > > +/// SMM Memory Attribute Protocol instance /// > > +EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = > { > > + EdkiiSmmGetMemoryAttributes, > > + EdkiiSmmSetMemoryAttributes, > > + EdkiiSmmClearMemoryAttributes > > +}; > > + > > EFI_CPU_INTERRUPT_HANDLER > > mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; > > > > // > > @@ -893,6 +902,17 @@ PiCpuSmmEntry ( > > ); > > ASSERT_EFI_ERROR (Status); > > > > + // > > + // Install the SMM Memory Attribute Protocol into SMM protocol > > + database // Status = gSmst->SmmInstallProtocolInterface ( > > + &mSmmCpuHandle, > > + &gEdkiiSmmMemoryAttributeProtocolGuid, > > + EFI_NATIVE_INTERFACE, > > + &mSmmMemoryAttribute > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > // > > // Expose address of CPU Hot Plug Data structure if CPU hot plug is > supported. > > // > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > index 1cf85c1481..e1c231e10b 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > @@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > ANY KIND, > > EITHER EXPRESS OR IMPLIED. > > #include <Protocol/SmmAccess2.h> > > #include <Protocol/SmmReadyToLock.h> > > #include <Protocol/SmmCpuService.h> > > +#include <Protocol/SmmMemoryAttribute.h> > > > > #include <Guid/AcpiS3Context.h> > > #include <Guid/PiSmmMemoryAttributesTable.h> > > @@ -1068,4 +1069,101 @@ TransferApToSafeState ( > > IN UINTN NumberToFinishAddress > > ); > > > > +/** > > + This function set given attributes of the memory region specified > > +by > > + BaseAddress and Length. > > + > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > instance. > > + @param BaseAddress The physical address that is the start address of > > + a memory region. > > + @param Length The size in bytes of the memory region. > > + @param Attributes The bit mask of attributes to set for the memory > > + region. > > + > > + @retval EFI_SUCCESS The attributes were set for the memory > region. > > + @retval EFI_INVALID_PARAMETER Length is zero. > > + Attributes specified an illegal combination of > > + attributes that cannot be set together. > > + @retval EFI_UNSUPPORTED The processor does not support one or > more > > + bytes of the memory resource range specified > > + by BaseAddress and Length. > > + The bit mask of attributes is not support for > > + the memory resource range specified by > > + BaseAddress and Length. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +EdkiiSmmSetMemoryAttributes ( > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN UINT64 Attributes > > + ); > > + > > +/** > > + This function clears given attributes of the memory region > > +specified by > > + BaseAddress and Length. > > + > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > instance. > > + @param BaseAddress The physical address that is the start address of > > + a memory region. > > + @param Length The size in bytes of the memory region. > > + @param Attributes The bit mask of attributes to set for the memory > > + region. > > + > > + @retval EFI_SUCCESS The attributes were set for the memory > region. > > + @retval EFI_INVALID_PARAMETER Length is zero. > > + Attributes specified an illegal combination of > > + attributes that cannot be set together. > > + @retval EFI_UNSUPPORTED The processor does not support one or > more > > + bytes of the memory resource range specified > > + by BaseAddress and Length. > > + The bit mask of attributes is not support for > > + the memory resource range specified by > > + BaseAddress and Length. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +EdkiiSmmClearMemoryAttributes ( > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN UINT64 Attributes > > + ); > > + > > +/** > > + This function retrieve the attributes of the memory region > > +specified by > > + BaseAddress and Length. If different attributes are got from > > +different part > > + of the memory region, EFI_NO_MAPPING will be returned. > > + > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > instance. > > + @param BaseAddress The physical address that is the start address of > > + a memory region. > > + @param Length The size in bytes of the memory region. > > + @param Attributes Pointer to attributes returned. > > + > > + @retval EFI_SUCCESS The attributes got for the memory region. > > + @retval EFI_INVALID_PARAMETER Length is zero. > > + Attributes is NULL. > > + @retval EFI_NO_MAPPING Attributes are not consistent cross the > > memory > > + region. > > + @retval EFI_UNSUPPORTED The processor does not support one or > more > > + bytes of the memory resource range specified > > + by BaseAddress and Length. > > + The bit mask of attributes is not support for > > + the memory resource range specified by > > + BaseAddress and Length. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +EdkiiSmmGetMemoryAttributes ( > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN UINT64 *Attributes > > + ); > > + > > #endif > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > index 099792e6ce..43d9edd0d5 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > @@ -129,6 +129,7 @@ > > gEfiSmmCpuProtocolGuid ## PRODUCES > > gEfiSmmReadyToLockProtocolGuid ## NOTIFY > > gEfiSmmCpuServiceProtocolGuid ## PRODUCES > > + gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES > > > > [Guids] > > gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is > > used for S3 boot. > > @@ -159,6 +160,7 @@ > > gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStaticPageTable ## > > CONSUMES > > gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## > CONSUMES > > > gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrM > ask > > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask > ## > > CONSUMES > > > > [Depex] > > gEfiMpServiceProtocolGuid > > diff --git > a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > index 3ad5256f1e..eb5e639e4b 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > @@ -1120,3 +1120,166 @@ IsSmmCommBufferForbiddenAddress ( > > } > > return FALSE; > > } > > + > > +/** > > + This function set given attributes of the memory region specified > > +by > > + BaseAddress and Length. > > + > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > instance. > > + @param BaseAddress The physical address that is the start address of > > + a memory region. > > + @param Length The size in bytes of the memory region. > > + @param Attributes The bit mask of attributes to set for the memory > > + region. > > + > > + @retval EFI_SUCCESS The attributes were set for the memory > region. > > + @retval EFI_INVALID_PARAMETER Length is zero. > > + Attributes specified an illegal combination of > > + attributes that cannot be set together. > > + @retval EFI_UNSUPPORTED The processor does not support one or > more > > + bytes of the memory resource range specified > > + by BaseAddress and Length. > > + The bit mask of attributes is not support for > > + the memory resource range specified by > > + BaseAddress and Length. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +EdkiiSmmSetMemoryAttributes ( > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN UINT64 Attributes > > + ) > > +{ > > + return SmmSetMemoryAttributes (BaseAddress, Length, Attributes); } > > + > > +/** > > + This function clears given attributes of the memory region > > +specified by > > + BaseAddress and Length. > > + > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > instance. > > + @param BaseAddress The physical address that is the start address of > > + a memory region. > > + @param Length The size in bytes of the memory region. > > + @param Attributes The bit mask of attributes to set for the memory > > + region. > > + > > + @retval EFI_SUCCESS The attributes were set for the memory > region. > > + @retval EFI_INVALID_PARAMETER Length is zero. > > + Attributes specified an illegal combination of > > + attributes that cannot be set together. > > + @retval EFI_UNSUPPORTED The processor does not support one or > more > > + bytes of the memory resource range specified > > + by BaseAddress and Length. > > + The bit mask of attributes is not support for > > + the memory resource range specified by > > + BaseAddress and Length. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +EdkiiSmmClearMemoryAttributes ( > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN UINT64 Attributes > > + ) > > +{ > > + return SmmClearMemoryAttributes (BaseAddress, Length, Attributes); > > +} > > + > > +/** > > + This function retrieve the attributes of the memory region > > +specified by > > + BaseAddress and Length. If different attributes are got from > > +different part > > + of the memory region, EFI_NO_MAPPING will be returned. > > + > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > instance. > > + @param BaseAddress The physical address that is the start address of > > + a memory region. > > + @param Length The size in bytes of the memory region. > > + @param Attributes Pointer to attributes returned. > > + > > + @retval EFI_SUCCESS The attributes got for the memory region. > > + @retval EFI_INVALID_PARAMETER Length is zero. > > + Attributes is NULL. > > + @retval EFI_NO_MAPPING Attributes are not consistent cross the > > memory > > + region. > > + @retval EFI_UNSUPPORTED The processor does not support one or > more > > + bytes of the memory resource range specified > > + by BaseAddress and Length. > > + The bit mask of attributes is not support for > > + the memory resource range specified by > > + BaseAddress and Length. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +EdkiiSmmGetMemoryAttributes ( > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN UINT64 *Attributes > > + ) > > +{ > > + EFI_PHYSICAL_ADDRESS Address; > > + UINT64 *PageEntry; > > + UINT64 MemAttr; > > + PAGE_ATTRIBUTE PageAttr; > > + INT64 Size; > > + > > + if (Length < SIZE_4KB || Attributes == NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Size = (INT64)Length; > > + MemAttr = (UINT64)-1; > > + > > + do { > > + > > + PageEntry = GetPageTableEntry (BaseAddress, &PageAttr); > > + if (PageEntry == NULL || PageAttr == PageNone) { > > + return EFI_UNSUPPORTED; > > + } > > + > > + // > > + // If the memory range is cross page table boundary, make sure they > > + // share the same attribute. Return EFI_NO_MAPPING if not. > > + // > > + *Attributes = GetAttributesFromPageEntry (PageEntry); > > + if (MemAttr != (UINT64)-1 && *Attributes != MemAttr) { > > + return EFI_NO_MAPPING; > > + } > > + > > + switch (PageAttr) { > > + case Page4K: > > + Address = *PageEntry & ~mAddressEncMask & > > PAGING_4K_ADDRESS_MASK_64; > > + Size -= (SIZE_4KB - (BaseAddress - Address)); > > + BaseAddress += (SIZE_4KB - (BaseAddress - Address)); > > + break; > > + > > + case Page2M: > > + Address = *PageEntry & ~mAddressEncMask & > > PAGING_2M_ADDRESS_MASK_64; > > + Size -= SIZE_2MB - (BaseAddress - Address); > > + BaseAddress += SIZE_2MB - (BaseAddress - Address); > > + break; > > + > > + case Page1G: > > + Address = *PageEntry & ~mAddressEncMask & > > PAGING_1G_ADDRESS_MASK_64; > > + Size -= SIZE_1GB - (BaseAddress - Address); > > + BaseAddress += SIZE_1GB - (BaseAddress - Address); > > + break; > > + > > + default: > > + return EFI_UNSUPPORTED; > > + } > > + > > + MemAttr = *Attributes; > > + > > + } while (Size > 0); > > + > > + return EFI_SUCCESS; > > +} > > + > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > index 3dde80f9ba..4d4668a0c6 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > @@ -902,7 +902,8 @@ SetPageTableAttributes ( > > BOOLEAN IsSplitted; > > BOOLEAN PageTableSplitted; > > > > - if (!mCpuSmmStaticPageTable) { > > + if (!mCpuSmmStaticPageTable > > + || (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { > > return ; > > } > > > > -- > > 2.14.1.windows.1 > > > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
Thanks for the feedback. I'll change them in v4. > -----Original Message----- > From: Ni, Ruiyu > Sent: Thursday, October 26, 2017 3:18 PM > To: Wang, Jian J <jian.j.wang@intel.com>; edk2-devel@lists.01.org > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com>; > Laszlo Ersek <lersek@redhat.com> > Subject: RE: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable > page table protection > > Jian, > 1. For protocol not defined in Spec, please use EDKII prefix, instead of EFI prefix. > 2. Could you please add more comments for BIT3 and BIT2 check? > 3. Better to separate the protocol definition to a single commit. > > Thanks/Ray > > > -----Original Message----- > > From: Wang, Jian J > > Sent: Thursday, October 26, 2017 2:20 PM > > To: edk2-devel@lists.01.org > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Dong, Eric <eric.dong@intel.com>; > > Laszlo Ersek <lersek@redhat.com>; Ni, Ruiyu <ruiyu.ni@intel.com> > > Subject: RE: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable > > page table protection > > > > Laszlo and Ruiyu, > > > > Could you please take a look at this part? There's a new protocol introduced. > > > > Thanks, > > Jian > > > > > -----Original Message----- > > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of > > > Jian J Wang > > > Sent: Monday, October 23, 2017 8:51 AM > > > To: edk2-devel@lists.01.org > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Dong, Eric > > > <eric.dong@intel.com> > > > Subject: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable > > page > > > table protection > > > > > > > v3 > > > > According to Jiewen's feedback, implement new protocol > > > > gEdkiiSmmMemoryAttributeProtocolGuid > > > > to change memory attributes. > > > > > > > v2 > > > > According to Eric's feedback: > > > > a. Enclose bit-or with parentheses > > > > b. Add code in 32-bit code to bypass setting page table to read-only > > > > > > Heap guard feature will update page attributes frequently. The page > > > table should not set to be read-only if heap guard feature is enabled > > > for SMM mode. Otherwise this feature cannot work. > > > > > > Cc: Eric Dong <eric.dong@intel.com> > > > Cc: Jiewen Yao <jiewen.yao@intel.com> > > > Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com> > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > > Signed-off-by: Jian J Wang <jian.j.wang@intel.com> > > > --- > > > UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 7 + > > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 20 +++ > > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 98 > > > +++++++++++++ > > > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 + > > > UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 163 > > > +++++++++++++++++++++ > > > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 3 +- > > > 6 files changed, 292 insertions(+), 1 deletion(-) > > > > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > > b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > > index f295c2ebf2..27c11f1b8d 100644 > > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c > > > @@ -184,6 +184,13 @@ SetPageTableAttributes ( > > > BOOLEAN IsSplitted; > > > BOOLEAN PageTableSplitted; > > > > > > + // > > > + // Don't mark page table as read-only if heap guard is enabled. > > > + // > > > + if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { > > > + return ; > > > + } > > > + > > > DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n")); > > > > > > // > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > > index 282d2e6981..8635f2d2c8 100755 > > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > > > @@ -76,6 +76,15 @@ EFI_SMM_CPU_PROTOCOL mSmmCpu = { > > > SmmWriteSaveState > > > }; > > > > > > +/// > > > +/// SMM Memory Attribute Protocol instance /// > > > +EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = > > { > > > + EdkiiSmmGetMemoryAttributes, > > > + EdkiiSmmSetMemoryAttributes, > > > + EdkiiSmmClearMemoryAttributes > > > +}; > > > + > > > EFI_CPU_INTERRUPT_HANDLER > > > mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; > > > > > > // > > > @@ -893,6 +902,17 @@ PiCpuSmmEntry ( > > > ); > > > ASSERT_EFI_ERROR (Status); > > > > > > + // > > > + // Install the SMM Memory Attribute Protocol into SMM protocol > > > + database // Status = gSmst->SmmInstallProtocolInterface ( > > > + &mSmmCpuHandle, > > > + &gEdkiiSmmMemoryAttributeProtocolGuid, > > > + EFI_NATIVE_INTERFACE, > > > + &mSmmMemoryAttribute > > > + ); > > > + ASSERT_EFI_ERROR (Status); > > > + > > > // > > > // Expose address of CPU Hot Plug Data structure if CPU hot plug is > > supported. > > > // > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > > index 1cf85c1481..e1c231e10b 100644 > > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > > > @@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > > ANY KIND, > > > EITHER EXPRESS OR IMPLIED. > > > #include <Protocol/SmmAccess2.h> > > > #include <Protocol/SmmReadyToLock.h> > > > #include <Protocol/SmmCpuService.h> > > > +#include <Protocol/SmmMemoryAttribute.h> > > > > > > #include <Guid/AcpiS3Context.h> > > > #include <Guid/PiSmmMemoryAttributesTable.h> > > > @@ -1068,4 +1069,101 @@ TransferApToSafeState ( > > > IN UINTN NumberToFinishAddress > > > ); > > > > > > +/** > > > + This function set given attributes of the memory region specified > > > +by > > > + BaseAddress and Length. > > > + > > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > > instance. > > > + @param BaseAddress The physical address that is the start address of > > > + a memory region. > > > + @param Length The size in bytes of the memory region. > > > + @param Attributes The bit mask of attributes to set for the memory > > > + region. > > > + > > > + @retval EFI_SUCCESS The attributes were set for the memory > > region. > > > + @retval EFI_INVALID_PARAMETER Length is zero. > > > + Attributes specified an illegal combination of > > > + attributes that cannot be set together. > > > + @retval EFI_UNSUPPORTED The processor does not support one or > > more > > > + bytes of the memory resource range specified > > > + by BaseAddress and Length. > > > + The bit mask of attributes is not support for > > > + the memory resource range specified by > > > + BaseAddress and Length. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +EdkiiSmmSetMemoryAttributes ( > > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > > + IN UINT64 Length, > > > + IN UINT64 Attributes > > > + ); > > > + > > > +/** > > > + This function clears given attributes of the memory region > > > +specified by > > > + BaseAddress and Length. > > > + > > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > > instance. > > > + @param BaseAddress The physical address that is the start address of > > > + a memory region. > > > + @param Length The size in bytes of the memory region. > > > + @param Attributes The bit mask of attributes to set for the memory > > > + region. > > > + > > > + @retval EFI_SUCCESS The attributes were set for the memory > > region. > > > + @retval EFI_INVALID_PARAMETER Length is zero. > > > + Attributes specified an illegal combination of > > > + attributes that cannot be set together. > > > + @retval EFI_UNSUPPORTED The processor does not support one or > > more > > > + bytes of the memory resource range specified > > > + by BaseAddress and Length. > > > + The bit mask of attributes is not support for > > > + the memory resource range specified by > > > + BaseAddress and Length. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +EdkiiSmmClearMemoryAttributes ( > > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > > + IN UINT64 Length, > > > + IN UINT64 Attributes > > > + ); > > > + > > > +/** > > > + This function retrieve the attributes of the memory region > > > +specified by > > > + BaseAddress and Length. If different attributes are got from > > > +different part > > > + of the memory region, EFI_NO_MAPPING will be returned. > > > + > > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > > instance. > > > + @param BaseAddress The physical address that is the start address of > > > + a memory region. > > > + @param Length The size in bytes of the memory region. > > > + @param Attributes Pointer to attributes returned. > > > + > > > + @retval EFI_SUCCESS The attributes got for the memory region. > > > + @retval EFI_INVALID_PARAMETER Length is zero. > > > + Attributes is NULL. > > > + @retval EFI_NO_MAPPING Attributes are not consistent cross the > > > memory > > > + region. > > > + @retval EFI_UNSUPPORTED The processor does not support one or > > more > > > + bytes of the memory resource range specified > > > + by BaseAddress and Length. > > > + The bit mask of attributes is not support for > > > + the memory resource range specified by > > > + BaseAddress and Length. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +EdkiiSmmGetMemoryAttributes ( > > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > > + IN UINT64 Length, > > > + IN UINT64 *Attributes > > > + ); > > > + > > > #endif > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > > b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > > index 099792e6ce..43d9edd0d5 100644 > > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf > > > @@ -129,6 +129,7 @@ > > > gEfiSmmCpuProtocolGuid ## PRODUCES > > > gEfiSmmReadyToLockProtocolGuid ## NOTIFY > > > gEfiSmmCpuServiceProtocolGuid ## PRODUCES > > > + gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES > > > > > > [Guids] > > > gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is > > > used for S3 boot. > > > @@ -159,6 +160,7 @@ > > > gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStaticPageTable ## > > > CONSUMES > > > gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## > > CONSUMES > > > > > gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrM > > ask > > > ## CONSUMES > > > + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask > > ## > > > CONSUMES > > > > > > [Depex] > > > gEfiMpServiceProtocolGuid > > > diff --git > > a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > > b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > > index 3ad5256f1e..eb5e639e4b 100644 > > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > > @@ -1120,3 +1120,166 @@ IsSmmCommBufferForbiddenAddress ( > > > } > > > return FALSE; > > > } > > > + > > > +/** > > > + This function set given attributes of the memory region specified > > > +by > > > + BaseAddress and Length. > > > + > > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > > instance. > > > + @param BaseAddress The physical address that is the start address of > > > + a memory region. > > > + @param Length The size in bytes of the memory region. > > > + @param Attributes The bit mask of attributes to set for the memory > > > + region. > > > + > > > + @retval EFI_SUCCESS The attributes were set for the memory > > region. > > > + @retval EFI_INVALID_PARAMETER Length is zero. > > > + Attributes specified an illegal combination of > > > + attributes that cannot be set together. > > > + @retval EFI_UNSUPPORTED The processor does not support one or > > more > > > + bytes of the memory resource range specified > > > + by BaseAddress and Length. > > > + The bit mask of attributes is not support for > > > + the memory resource range specified by > > > + BaseAddress and Length. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +EdkiiSmmSetMemoryAttributes ( > > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > > + IN UINT64 Length, > > > + IN UINT64 Attributes > > > + ) > > > +{ > > > + return SmmSetMemoryAttributes (BaseAddress, Length, Attributes); } > > > + > > > +/** > > > + This function clears given attributes of the memory region > > > +specified by > > > + BaseAddress and Length. > > > + > > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > > instance. > > > + @param BaseAddress The physical address that is the start address of > > > + a memory region. > > > + @param Length The size in bytes of the memory region. > > > + @param Attributes The bit mask of attributes to set for the memory > > > + region. > > > + > > > + @retval EFI_SUCCESS The attributes were set for the memory > > region. > > > + @retval EFI_INVALID_PARAMETER Length is zero. > > > + Attributes specified an illegal combination of > > > + attributes that cannot be set together. > > > + @retval EFI_UNSUPPORTED The processor does not support one or > > more > > > + bytes of the memory resource range specified > > > + by BaseAddress and Length. > > > + The bit mask of attributes is not support for > > > + the memory resource range specified by > > > + BaseAddress and Length. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +EdkiiSmmClearMemoryAttributes ( > > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > > + IN UINT64 Length, > > > + IN UINT64 Attributes > > > + ) > > > +{ > > > + return SmmClearMemoryAttributes (BaseAddress, Length, Attributes); > > > +} > > > + > > > +/** > > > + This function retrieve the attributes of the memory region > > > +specified by > > > + BaseAddress and Length. If different attributes are got from > > > +different part > > > + of the memory region, EFI_NO_MAPPING will be returned. > > > + > > > + @param This The EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL > > > instance. > > > + @param BaseAddress The physical address that is the start address of > > > + a memory region. > > > + @param Length The size in bytes of the memory region. > > > + @param Attributes Pointer to attributes returned. > > > + > > > + @retval EFI_SUCCESS The attributes got for the memory region. > > > + @retval EFI_INVALID_PARAMETER Length is zero. > > > + Attributes is NULL. > > > + @retval EFI_NO_MAPPING Attributes are not consistent cross the > > > memory > > > + region. > > > + @retval EFI_UNSUPPORTED The processor does not support one or > > more > > > + bytes of the memory resource range specified > > > + by BaseAddress and Length. > > > + The bit mask of attributes is not support for > > > + the memory resource range specified by > > > + BaseAddress and Length. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +EdkiiSmmGetMemoryAttributes ( > > > + IN EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This, > > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > > + IN UINT64 Length, > > > + IN UINT64 *Attributes > > > + ) > > > +{ > > > + EFI_PHYSICAL_ADDRESS Address; > > > + UINT64 *PageEntry; > > > + UINT64 MemAttr; > > > + PAGE_ATTRIBUTE PageAttr; > > > + INT64 Size; > > > + > > > + if (Length < SIZE_4KB || Attributes == NULL) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + Size = (INT64)Length; > > > + MemAttr = (UINT64)-1; > > > + > > > + do { > > > + > > > + PageEntry = GetPageTableEntry (BaseAddress, &PageAttr); > > > + if (PageEntry == NULL || PageAttr == PageNone) { > > > + return EFI_UNSUPPORTED; > > > + } > > > + > > > + // > > > + // If the memory range is cross page table boundary, make sure they > > > + // share the same attribute. Return EFI_NO_MAPPING if not. > > > + // > > > + *Attributes = GetAttributesFromPageEntry (PageEntry); > > > + if (MemAttr != (UINT64)-1 && *Attributes != MemAttr) { > > > + return EFI_NO_MAPPING; > > > + } > > > + > > > + switch (PageAttr) { > > > + case Page4K: > > > + Address = *PageEntry & ~mAddressEncMask & > > > PAGING_4K_ADDRESS_MASK_64; > > > + Size -= (SIZE_4KB - (BaseAddress - Address)); > > > + BaseAddress += (SIZE_4KB - (BaseAddress - Address)); > > > + break; > > > + > > > + case Page2M: > > > + Address = *PageEntry & ~mAddressEncMask & > > > PAGING_2M_ADDRESS_MASK_64; > > > + Size -= SIZE_2MB - (BaseAddress - Address); > > > + BaseAddress += SIZE_2MB - (BaseAddress - Address); > > > + break; > > > + > > > + case Page1G: > > > + Address = *PageEntry & ~mAddressEncMask & > > > PAGING_1G_ADDRESS_MASK_64; > > > + Size -= SIZE_1GB - (BaseAddress - Address); > > > + BaseAddress += SIZE_1GB - (BaseAddress - Address); > > > + break; > > > + > > > + default: > > > + return EFI_UNSUPPORTED; > > > + } > > > + > > > + MemAttr = *Attributes; > > > + > > > + } while (Size > 0); > > > + > > > + return EFI_SUCCESS; > > > +} > > > + > > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > > index 3dde80f9ba..4d4668a0c6 100644 > > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > > @@ -902,7 +902,8 @@ SetPageTableAttributes ( > > > BOOLEAN IsSplitted; > > > BOOLEAN PageTableSplitted; > > > > > > - if (!mCpuSmmStaticPageTable) { > > > + if (!mCpuSmmStaticPageTable > > > + || (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) { > > > return ; > > > } > > > > > > -- > > > 2.14.1.windows.1 > > > > > > _______________________________________________ > > > edk2-devel mailing list > > > edk2-devel@lists.01.org > > > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2025 Red Hat, Inc.