From nobody Tue Dec 24 13:33:43 2024 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 1511245057012450.93818771809686; Mon, 20 Nov 2017 22:17:37 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 6FBE22035687D; Mon, 20 Nov 2017 22:13:18 -0800 (PST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (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 7C9A62034A7A2 for ; Mon, 20 Nov 2017 22:13:15 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2017 22:17:30 -0800 Received: from jwang36-mobl2.ccr.corp.intel.com ([10.239.193.240]) by FMSMGA003.fm.intel.com with ESMTP; 20 Nov 2017 22:17:28 -0800 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.24; helo=mga09.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.44,432,1505804400"; d="scan'208";a="4155491" From: Jian J Wang To: edk2-devel@lists.01.org Date: Tue, 21 Nov 2017 14:17:24 +0800 Message-Id: <20171121061725.11028-2-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171121061725.11028-1-jian.j.wang@intel.com> References: <20171121061725.11028-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v7 1/2] MdeModulePkg/DxeCore: Filter out all paging capabilities 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: Laszlo Ersek , Jiewen Yao , Star Zeng , Ard Biesheuvel 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" > v7: > Merge memory map after filtering code Some OSs will treat EFI_MEMORY_DESCRIPTOR.Attribute as really set attributes and change memory paging attribute accordingly. But current EFI_MEMORY_DESCRIPTOR.Attribute is assigned by value from Capabilities in GCD memory map. This might cause boot problems. Clearing all paging related capabilities can workaround it. The code added in this patch is supposed to be removed once the usage of EFI_MEMORY_DESCRIPTOR.Attribute is clarified in UEFI spec and adopted by both EDK-II Core and all supported OSs. Cc: Jiewen Yao Cc: Star Zeng Cc: Laszlo Ersek Cc: Ard Biesheuvel Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang Tested-by: Laszlo Ersek Reviewed-by tags, from v6. Reviewed-by: Star Zeng --- MdeModulePkg/Core/Dxe/DxeMain.h | 18 ++++++++++++++++++ MdeModulePkg/Core/Dxe/Mem/Page.c | 21 +++++++++++++++++++++ MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c | 1 - 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMai= n.h index 1a0babba71..07b86ba696 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2948,4 +2948,22 @@ ApplyMemoryProtectionPolicy ( IN UINT64 Length ); =20 +/** + Merge continous memory map entries whose have same attributes. + + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the current memory map. On output, + it is the size of new memory map after merge. + @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESC= RIPTOR. +**/ +VOID +MergeMemoryMap ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN OUT UINTN *MemoryMapSize, + IN UINTN DescriptorSize + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/P= age.c index f1e4a37f2a..9ff73efdfa 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -1687,6 +1687,7 @@ CoreGetMemoryMap ( EFI_GCD_MAP_ENTRY MergeGcdMapEntry; EFI_MEMORY_TYPE Type; EFI_MEMORY_DESCRIPTOR *MemoryMapStart; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; =20 // // Make sure the parameters are valid @@ -1896,6 +1897,26 @@ CoreGetMemoryMap ( // BufferSize =3D ((UINT8 *)MemoryMap - (UINT8 *)MemoryMapStart); =20 + // + // Note: Some OSs will treat EFI_MEMORY_DESCRIPTOR.Attribute as really + // set attributes and change memory paging attribute accordingly. + // But current EFI_MEMORY_DESCRIPTOR.Attribute is assigned by + // value from Capabilities in GCD memory map. This might cause + // boot problems. Clearing all paging related capabilities can + // workaround it. Following code is supposed to be removed once + // the usage of EFI_MEMORY_DESCRIPTOR.Attribute is clarified in + // UEFI spec and adopted by both EDK-II Core and all supported + // OSs. + // + MemoryMapEnd =3D MemoryMap; + MemoryMap =3D MemoryMapStart; + while (MemoryMap < MemoryMapEnd) { + MemoryMap->Attribute &=3D ~(UINT64)(EFI_MEMORY_RP | EFI_MEMORY_RO | + EFI_MEMORY_XP); + MemoryMap =3D NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size); + } + MergeMemoryMap (MemoryMapStart, &BufferSize, Size); + Status =3D EFI_SUCCESS; =20 Done: diff --git a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c b/MdeModulePkg/Co= re/Dxe/Misc/PropertiesTable.c index 6cf5edcbe5..75d9b14c1f 100644 --- a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c @@ -182,7 +182,6 @@ SortMemoryMap ( it is the size of new memory map after me= rge. @param DescriptorSize Size, in bytes, of an individual EFI_MEMO= RY_DESCRIPTOR. **/ -STATIC VOID MergeMemoryMap ( IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Tue Dec 24 13:33:43 2024 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 1511245057192159.06168098494925; Mon, 20 Nov 2017 22:17:37 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A866521B00DEC; Mon, 20 Nov 2017 22:13:18 -0800 (PST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (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 AA65A21B00DD6 for ; Mon, 20 Nov 2017 22:13:16 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2017 22:17:31 -0800 Received: from jwang36-mobl2.ccr.corp.intel.com ([10.239.193.240]) by FMSMGA003.fm.intel.com with ESMTP; 20 Nov 2017 22:17:30 -0800 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.24; helo=mga09.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.44,432,1505804400"; d="scan'208";a="4155495" From: Jian J Wang To: edk2-devel@lists.01.org Date: Tue, 21 Nov 2017 14:17:25 +0800 Message-Id: <20171121061725.11028-3-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20171121061725.11028-1-jian.j.wang@intel.com> References: <20171121061725.11028-1-jian.j.wang@intel.com> Subject: [edk2] [PATCH v7 2/2] UefiCpuPkg/CpuDxe: Fix multiple entries of RT_CODE in memory map 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: Laszlo Ersek , Jiewen Yao , Eric Dong , Star Zeng , Ard Biesheuvel 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" > v7: > No change. > v6: > Add ExecuteDisable feature check to include/exclude EFI_MEMORY_XP > v5: > Coding style clean-up > v4: > a. Remove DoUpdate and check attributes mismatch all the time to avoid > a logic hole > b. Add warning message if failed to update capability > c. Add local variable to hold new attributes to make code cleaner > v3: > a. Add comment to explain more on updating memory capabilities > b. Fix logic hole in updating attributes > c. Instead of checking illegal memory space address and size, use return > status of gDS->SetMemorySpaceCapabilities() to skip memory block which > cannot be updated with new capabilities. > v2 > a. Fix an issue which will cause setting capability failure if size is sm= aller > than a page. More than one entry of RT_CODE memory might cause boot problem for some old OSs. This patch will fix this issue to keep OS compatibility as much as possible. More detailed information, please refer to https://bugzilla.tianocore.org/show_bug.cgi?id=3D753 Cc: Eric Dong Cc: Jiewen Yao Cc: Star Zeng Cc: Laszlo Ersek Cc: Ard Biesheuvel Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang Tested-by: Laszlo Ersek Reviewed-by: Laszlo Ersek Reviewed-by tags, from v6. --- UefiCpuPkg/CpuDxe/CpuPageTable.c | 94 +++++++++++++++++++++++++++++++-----= ---- 1 file changed, 73 insertions(+), 21 deletions(-) diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTa= ble.c index 309f448a83..db41fa401f 100644 --- a/UefiCpuPkg/CpuDxe/CpuPageTable.c +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c @@ -769,6 +769,20 @@ AssignMemoryPageAttributes ( return Status; } =20 +/** + Check if Execute Disable feature is enabled or not. +**/ +BOOLEAN +IsExecuteDisableEnabled ( + VOID + ) +{ + MSR_CORE_IA32_EFER_REGISTER MsrEfer; + + MsrEfer.Uint64 =3D AsmReadMsr64 (MSR_IA32_EFER); + return (MsrEfer.Bits.NXE =3D=3D 1); +} + /** Update GCD memory space attributes according to current page table setup. **/ @@ -790,7 +804,7 @@ RefreshGcdMemoryAttributesFromPaging ( UINT64 PageStartAddress; UINT64 Attributes; UINT64 Capabilities; - BOOLEAN DoUpdate; + UINT64 NewAttributes; UINTN Index; =20 // @@ -802,17 +816,50 @@ RefreshGcdMemoryAttributesFromPaging ( =20 GetCurrentPagingContext (&PagingContext); =20 - DoUpdate =3D FALSE; - Capabilities =3D 0; - Attributes =3D 0; - BaseAddress =3D 0; - PageLength =3D 0; + Attributes =3D 0; + NewAttributes =3D 0; + BaseAddress =3D 0; + PageLength =3D 0; + + if (IsExecuteDisableEnabled ()) { + Capabilities =3D EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP; + } else { + Capabilities =3D EFI_MEMORY_RO | EFI_MEMORY_RP; + } =20 for (Index =3D 0; Index < NumberOfDescriptors; Index++) { if (MemorySpaceMap[Index].GcdMemoryType =3D=3D EfiGcdMemoryTypeNonExis= tent) { continue; } =20 + // + // Sync the actual paging related capabilities back to GCD service fir= st. + // As a side effect (good one), this can also help to avoid unnecessary + // memory map entries due to the different capabilities of the same ty= pe + // memory, such as multiple RT_CODE and RT_DATA entries in memory map, + // which could cause boot failure of some old Linux distro (before v4.= 3). + // + Status =3D gDS->SetMemorySpaceCapabilities ( + MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].Length, + MemorySpaceMap[Index].Capabilities | Capabilities + ); + if (EFI_ERROR (Status)) { + // + // If we cannot udpate the capabilities, we cannot update its + // attributes either. So just simply skip current block of memory. + // + DEBUG (( + DEBUG_WARN, + "Failed to update capability: [%lu] %016lx - %016lx (%016lx -> %01= 6lx)\r\n", + (UINT64)Index, MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length -= 1, + MemorySpaceMap[Index].Capabilities, + MemorySpaceMap[Index].Capabilities | Capabilities + )); + continue; + } + if (MemorySpaceMap[Index].BaseAddress >=3D (BaseAddress + PageLength))= { // // Current memory space starts at a new page. Resetting PageLength w= ill @@ -826,7 +873,9 @@ RefreshGcdMemoryAttributesFromPaging ( PageLength -=3D (MemorySpaceMap[Index].BaseAddress - BaseAddress); } =20 - // Sync real page attributes to GCD + // + // Sync actual page attributes to GCD + // BaseAddress =3D MemorySpaceMap[Index].BaseAddress; MemorySpaceLength =3D MemorySpaceMap[Index].Length; while (MemorySpaceLength > 0) { @@ -842,23 +891,26 @@ RefreshGcdMemoryAttributesFromPaging ( PageStartAddress =3D (*PageEntry) & (UINT64)PageAttributeToMask(P= ageAttribute); PageLength =3D PageAttributeToLength (PageAttribute) - (Bas= eAddress - PageStartAddress); Attributes =3D GetAttributesFromPageEntry (PageEntry); - - if (Attributes !=3D (MemorySpaceMap[Index].Attributes & EFI_MEMORY= _PAGETYPE_MASK)) { - DoUpdate =3D TRUE; - Attributes |=3D (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_= PAGETYPE_MASK); - Capabilities =3D Attributes | MemorySpaceMap[Index].Capabilities; - } else { - DoUpdate =3D FALSE; - } } =20 Length =3D MIN (PageLength, MemorySpaceLength); - if (DoUpdate) { - gDS->SetMemorySpaceCapabilities (BaseAddress, Length, Capabilities= ); - gDS->SetMemorySpaceAttributes (BaseAddress, Length, Attributes); - DEBUG ((DEBUG_INFO, "Update memory space attribute: [%02d] %016lx = - %016lx (%08lx -> %08lx)\r\n", - Index, BaseAddress, BaseAddress + Length - 1, - MemorySpaceMap[Index].Attributes, Attributes)= ); + if (Attributes !=3D (MemorySpaceMap[Index].Attributes & + EFI_MEMORY_PAGETYPE_MASK)) { + NewAttributes =3D (MemorySpaceMap[Index].Attributes & + ~EFI_MEMORY_PAGETYPE_MASK) | Attributes; + Status =3D gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + NewAttributes + ); + ASSERT_EFI_ERROR (Status); + DEBUG (( + DEBUG_INFO, + "Updated memory space attribute: [%lu] %016lx - %016lx (%016lx -= > %016lx)\r\n", + (UINT64)Index, BaseAddress, BaseAddress + Length - 1, + MemorySpaceMap[Index].Attributes, + NewAttributes + )); } =20 PageLength -=3D Length; --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel