From nobody Thu May 15 01:53:46 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 150871987702346.868873199599534; Sun, 22 Oct 2017 17:51:17 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 114DF202E618C; Sun, 22 Oct 2017 17:47:25 -0700 (PDT) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2117B202E5CFE for ; Sun, 22 Oct 2017 17:47:24 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga104.jf.intel.com with ESMTP; 22 Oct 2017 17:51:06 -0700 Received: from jwang36-mobl2.ccr.corp.intel.com ([10.239.192.55]) by fmsmga001.fm.intel.com with ESMTP; 22 Oct 2017 17:51:05 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.31; helo=mga06.intel.com; envelope-from=jian.j.wang@intel.com; receiver=edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,420,1503385200"; d="scan'208";a="1208758194" From: Jian J Wang To: edk2-devel@lists.01.org Date: Mon, 23 Oct 2017 08:50:53 +0800 Message-Id: <20171023005054.7528-6-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171023005054.7528-1-jian.j.wang@intel.com> References: <20171023005054.7528-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v3 5/6] UefiCpuPkg/PiSmmCpuDxeSmm: Disable page table protection X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jiewen Yao , Eric Dong MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" > 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 Cc: Jiewen Yao Suggested-by: Ayellet Wolman Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- 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/PiSmmCpu= DxeSmm/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; =20 + // + // Don't mark page table as read-only if heap guard is enabled. + // + if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) !=3D 0) { + return ; + } + DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n")); =20 // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmC= puDxeSmm/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 =3D { SmmWriteSaveState }; =20 +/// +/// SMM Memory Attribute Protocol instance +/// +EFI_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute =3D { + EdkiiSmmGetMemoryAttributes, + EdkiiSmmSetMemoryAttributes, + EdkiiSmmClearMemoryAttributes +}; + EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER]; =20 // @@ -893,6 +902,17 @@ PiCpuSmmEntry ( ); ASSERT_EFI_ERROR (Status); =20 + // + // Install the SMM Memory Attribute Protocol into SMM protocol database + // + Status =3D 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 supp= orted. // diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmC= puDxeSmm/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 #include #include +#include =20 #include #include @@ -1068,4 +1069,101 @@ TransferApToSafeState ( IN UINTN NumberToFinishAddress ); =20 +/** + 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 memo= ry + region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combinatio= n of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + 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 memo= ry + region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combinatio= n of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + 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 p= art + 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 me= mory + region. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + 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/PiSm= mCpuDxeSmm/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 =20 [Guids] gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # = it is used for S3 boot. @@ -159,6 +160,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStaticPageTable ## CONS= UMES gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONS= UMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ##= CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ##= CONSUMES =20 [Depex] gEfiMpServiceProtocolGuid diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPk= g/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 memo= ry + region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combinatio= n of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + 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 memo= ry + region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combinatio= n of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + 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 p= art + 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 me= mory + region. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + 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 =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Size =3D (INT64)Length; + MemAttr =3D (UINT64)-1; + + do { + + PageEntry =3D GetPageTableEntry (BaseAddress, &PageAttr); + if (PageEntry =3D=3D NULL || PageAttr =3D=3D 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 =3D GetAttributesFromPageEntry (PageEntry); + if (MemAttr !=3D (UINT64)-1 && *Attributes !=3D MemAttr) { + return EFI_NO_MAPPING; + } + + switch (PageAttr) { + case Page4K: + Address =3D *PageEntry & ~mAddressEncMask & PAGING_4K_ADDRESS_MA= SK_64; + Size -=3D (SIZE_4KB - (BaseAddress - Address)); + BaseAddress +=3D (SIZE_4KB - (BaseAddress - Address)); + break; + + case Page2M: + Address =3D *PageEntry & ~mAddressEncMask & PAGING_2M_ADDRESS_MA= SK_64; + Size -=3D SIZE_2MB - (BaseAddress - Address); + BaseAddress +=3D SIZE_2MB - (BaseAddress - Address); + break; + + case Page1G: + Address =3D *PageEntry & ~mAddressEncMask & PAGING_1G_ADDRESS_MA= SK_64; + Size -=3D SIZE_1GB - (BaseAddress - Address); + BaseAddress +=3D SIZE_1GB - (BaseAddress - Address); + break; + + default: + return EFI_UNSUPPORTED; + } + + MemAttr =3D *Attributes; + + } while (Size > 0); + + return EFI_SUCCESS; +} + diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuD= xeSmm/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; =20 - if (!mCpuSmmStaticPageTable) { + if (!mCpuSmmStaticPageTable + || (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) !=3D 0) { return ; } =20 --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel