From nobody Mon Sep 16 19:37:44 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+101647+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+101647+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1679557319; cv=none; d=zohomail.com; s=zohoarc; b=KpB8wDbpf4+cfLsG5MIj7lnLB5EW0A4Q2U2Dqq22Oy0SzjaLhogekXYPeO05MjJR5GN9mlU+y5YVNY/0vB/OZV3x9aDv7u5UHfj3TFl8pOXFJfoXhYljcEA7fiJ5uhXuMWCdZxE+z7btYpbx2uZkM+3/mHRrC7+fRygkxzJO/Jk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1679557319; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Vv1zb7w4iCQH+4dQDo+uJGQduKVDr0AOmukr6ISW1gA=; b=U6ic5PILwqRPR7iNLnRODDWgv904LXU7a2qR6gV508F2mG0NvW0y+hEanIURwX9ktcz27Su/V4TZCLR+1SBrZ3C2eDX3BQnNWEwN0ZOFUDW+kLVzPLvrZ1D9F9Lq5jYmFrKUkLZifdkomIRTI1F5cennLS8ZFq/MHtloLS30CBY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+101647+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1679557319802814.0833398832239; Thu, 23 Mar 2023 00:41:59 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id sW6SYY1788612xYvuQN1IfCU; Thu, 23 Mar 2023 00:41:59 -0700 X-Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mx.groups.io with SMTP id smtpd.web11.66779.1679557305298569223 for ; Thu, 23 Mar 2023 00:41:58 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10657"; a="425699875" X-IronPort-AV: E=Sophos;i="5.98,283,1673942400"; d="scan'208";a="425699875" X-Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Mar 2023 00:41:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10657"; a="684616900" X-IronPort-AV: E=Sophos;i="5.98,283,1673942400"; d="scan'208";a="684616900" X-Received: from shwdeopenlab702.ccr.corp.intel.com ([10.239.55.92]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Mar 2023 00:41:57 -0700 From: "duntan" To: devel@edk2.groups.io Cc: Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann Subject: [edk2-devel] [Patch V4 19/21] UefiCpuPkg/CpuPageTableLib: Enable PAE paging Date: Thu, 23 Mar 2023 15:40:55 +0800 Message-Id: <20230323074057.549-20-dun.tan@intel.com> In-Reply-To: <20230323074057.549-1-dun.tan@intel.com> References: <20230323074057.549-1-dun.tan@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,dun.tan@intel.com X-Gm-Message-State: L1XWOSAQlgOcti0doxfJXTrUx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1679557319; bh=5oipK0eWtlailr0wnHUkRXud9bpdkqcywL8MU9IrheY=; h=Cc:Date:From:Reply-To:Subject:To; b=cGPgTgWOPBt+RF2TfKqusBOhNdOXcPsqwXfRduGWzauFt9nzWjk7kxVexZBRZRl6FUz WqmzSmmC1bGTA53xjDu4pdpVzJJoIQsPPy4Z2kEv7YM2w7LqiMwJlGyEYrG+QEBqOldBQ MGqXiNLxSuc6eGfqU0oKmMZYxZHKQSPsO3Y= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1679557321802100002 Content-Type: text/plain; charset="utf-8" Modify CpuPageTableLib code to enable PAE paging. In PageTableMap() API: When creating new PAE page table, after creating page table, set all MustBeZero fields of 4 PDPTE to 0. The MustBeZero fields are treated as RW and other attributes by the common map logic. So they might be set to 1. When updating exsiting PAE page table, the special steps are: 1.Prepare 4K-aligned 32bytes memory in stack for 4 temp PDPTE. 2.Copy original 4 PDPTE to the 4 temp PDPTE and set the RW, UserSupervisor to 1 and set Nx of 4 temp PDPTE to 0. 4.After updating the page table, set the MustBeZero fields of 4 temp PDPTE to 0. 5.Copy the temp PDPTE to original PDPTE. In PageTableParse() API, also create 4 temp PDPTE in stack. Copy original 4 PDPTE to the 4 temp PDPTE. Then set the RW, UserSupervisor to 1 and set Nx of 4 temp PDPTE to 0. Finally use the address of temp PDPTE as the page table address. Signed-off-by: Dun Tan Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann --- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h | 10 +++++++--- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 53 ++++++++++++++= ++++++++++++++++++++++++++++++++++----- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableParse.c | 25 ++++++++++++++= +++++++---- 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h b/UefiCpuPkg= /Library/CpuPageTableLib/CpuPageTable.h index 2c67ecb469..521d56c148 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h @@ -15,11 +15,14 @@ #include #include =20 -#define IA32_PE_BASE_ADDRESS_MASK_40 0xFFFFFFFFFF000ull -#define IA32_PE_BASE_ADDRESS_MASK_39 0xFFFFFFFFFE000ull +#define IA32_PE_BASE_ADDRESS_MASK_40 0xFFFFFFFFFF000ull +#define IA32_PE_BASE_ADDRESS_MASK_39 0xFFFFFFFFFE000ull +#define IA32_PE_BASE_ADDRESS_MASK_PAE_PDPTE 0xFFFFFFFFFFFE0ull =20 #define REGION_LENGTH(l) LShiftU64 (1, (l) * 9 + 3) =20 +#define MAX_PAE_PDPTE_NUM 4 + typedef enum { Pte =3D 1, Pde =3D 2, @@ -60,7 +63,8 @@ typedef union { UINT64 Uint64; } IA32_PAGE_NON_LEAF_ENTRY; =20 -#define IA32_PNLE_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_PE_BAS= E_ADDRESS_MASK_40) +#define IA32_PNLE_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_P= E_BASE_ADDRESS_MASK_40) +#define IA32_PAE_PDPTE_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_P= E_BASE_ADDRESS_MASK_PAE_PDPTE) =20 /// /// Format of a PML5 Entry (PML5E) that References a PML4 Table diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpu= Pkg/Library/CpuPageTableLib/CpuPageTableMap.c index 773948349e..8769e45f25 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -661,15 +661,17 @@ PageTableMap ( IA32_PAGE_LEVEL MaxLeafLevel; IA32_MAP_ATTRIBUTE ParentAttribute; BOOLEAN LocalIsModified; + UINTN Index; + IA32_PAGING_ENTRY *PagingEntry; + UINT8 BufferInStack[SIZE_4KB - 1 + MAX_PAE_PDPTE_NUM * siz= eof (IA32_PAGING_ENTRY)]; =20 if (Length =3D=3D 0) { return RETURN_SUCCESS; } =20 - if ((PagingMode =3D=3D Paging32bit) || (PagingMode =3D=3D PagingPae) || = (PagingMode >=3D PagingModeMax)) { + if ((PagingMode =3D=3D Paging32bit) || (PagingMode >=3D PagingModeMax)) { // // 32bit paging is never supported. - // PAE paging will be supported later. // return RETURN_UNSUPPORTED; } @@ -706,17 +708,32 @@ PageTableMap ( =20 MaxLeafLevel =3D (IA32_PAGE_LEVEL)(UINT8)PagingMode; MaxLevel =3D (IA32_PAGE_LEVEL)(UINT8)(PagingMode >> 8); - MaxLinearAddress =3D LShiftU64 (1, 12 + MaxLevel * 9); + MaxLinearAddress =3D (PagingMode =3D=3D PagingPae) ? LShiftU64 (1, 32) := LShiftU64 (1, 12 + MaxLevel * 9); =20 if ((LinearAddress > MaxLinearAddress) || (Length > MaxLinearAddress - L= inearAddress)) { // - // Maximum linear address is (1 << 48) or (1 << 57) + // Maximum linear address is (1 << 32), (1 << 48) or (1 << 57) // return RETURN_INVALID_PARAMETER; } =20 TopPagingEntry.Uintn =3D *PageTable; if (TopPagingEntry.Uintn !=3D 0) { + if (PagingMode =3D=3D PagingPae) { + // + // Create 4 temporary PDPTE at a 4k-aligned address. + // Copy the original PDPTE content and set ReadWrite, UserSupervisor= to 1, set Nx to 0. + // + TopPagingEntry.Uintn =3D ALIGN_VALUE ((UINTN)BufferInStack, BASE_4KB= ); + PagingEntry =3D (IA32_PAGING_ENTRY *)(TopPagingEntry.Uintn); + CopyMem (PagingEntry, (VOID *)(*PageTable), MAX_PAE_PDPTE_NUM * size= of (IA32_PAGING_ENTRY)); + for (Index =3D 0; Index < MAX_PAE_PDPTE_NUM; Index++) { + PagingEntry[Index].Pnle.Bits.ReadWrite =3D 1; + PagingEntry[Index].Pnle.Bits.UserSupervisor =3D 1; + PagingEntry[Index].Pnle.Bits.Nx =3D 0; + } + } + TopPagingEntry.Pce.Present =3D 1; TopPagingEntry.Pce.ReadWrite =3D 1; TopPagingEntry.Pce.UserSupervisor =3D 1; @@ -792,7 +809,33 @@ PageTableMap ( } =20 if (!RETURN_ERROR (Status)) { - *PageTable =3D (UINTN)(TopPagingEntry.Uintn & IA32_PE_BASE_ADDRESS_MAS= K_40); + PagingEntry =3D (IA32_PAGING_ENTRY *)(UINTN)(TopPagingEntry.Uintn & IA= 32_PE_BASE_ADDRESS_MASK_40); + + if (PagingMode =3D=3D PagingPae) { + // + // These MustBeZero fields are treated as RW and other attributes by= the common map logic. So they might be set to 1. + // + for (Index =3D 0; Index < MAX_PAE_PDPTE_NUM; Index++) { + PagingEntry[Index].PdptePae.Bits.MustBeZero =3D 0; + PagingEntry[Index].PdptePae.Bits.MustBeZero2 =3D 0; + PagingEntry[Index].PdptePae.Bits.MustBeZero3 =3D 0; + } + + if (*PageTable !=3D 0) { + // + // Copy temp PDPTE to original PDPTE. + // + CopyMem ((VOID *)(*PageTable), PagingEntry, MAX_PAE_PDPTE_NUM * si= zeof (IA32_PAGING_ENTRY)); + } + } + + if (*PageTable =3D=3D 0) { + // + // Do not assign the *PageTable when it's an existing page table. + // If it's an existing PAE page table, PagingEntry is the temp buffe= r in stack. + // + *PageTable =3D (UINTN)PagingEntry; + } } =20 return Status; diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableParse.c b/UefiC= puPkg/Library/CpuPageTableLib/CpuPageTableParse.c index 65490751ab..f6d7b9bb4c 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableParse.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableParse.c @@ -158,6 +158,7 @@ VOID PageTableLibParsePnle ( IN UINT64 PageTableBaseAddress, IN UINTN Level, + IN UINTN MaxLevel, IN UINT64 RegionStart, IN IA32_MAP_ATTRIBUTE *ParentMapAttribute, IN OUT IA32_MAP_ENTRY *Map, @@ -171,13 +172,15 @@ PageTableLibParsePnle ( UINTN Index; IA32_MAP_ATTRIBUTE MapAttribute; UINT64 RegionLength; + UINTN PagingEntryNumber; =20 ASSERT (OneEntry !=3D NULL); =20 - PagingEntry =3D (IA32_PAGING_ENTRY *)(UINTN)PageTableBaseAddress; - RegionLength =3D REGION_LENGTH (Level); + PagingEntry =3D (IA32_PAGING_ENTRY *)(UINTN)PageTableBaseAddress; + RegionLength =3D REGION_LENGTH (Level); + PagingEntryNumber =3D ((MaxLevel =3D=3D 3) && (Level =3D=3D 3)) ? MAX_PA= E_PDPTE_NUM : 512; =20 - for (Index =3D 0; Index < 512; Index++, RegionStart +=3D RegionLength) { + for (Index =3D 0; Index < PagingEntryNumber; Index++, RegionStart +=3D R= egionLength) { if (PagingEntry[Index].Pce.Present =3D=3D 0) { continue; } @@ -228,6 +231,7 @@ PageTableLibParsePnle ( PageTableLibParsePnle ( IA32_PNLE_PAGE_TABLE_BASE_ADDRESS (&PagingEntry[Index].Pnle), Level - 1, + MaxLevel, RegionStart, &MapAttribute, Map, @@ -269,6 +273,8 @@ PageTableParse ( IA32_MAP_ENTRY *LastEntry; IA32_MAP_ENTRY OneEntry; UINTN MaxLevel; + UINTN Index; + IA32_PAGING_ENTRY BufferInStack[MAX_PAE_PDPTE_NUM]; =20 if ((PagingMode =3D=3D Paging32bit) || (PagingMode >=3D PagingModeMax)) { // @@ -290,6 +296,17 @@ PageTableParse ( return RETURN_SUCCESS; } =20 + if (PagingMode =3D=3D PagingPae) { + CopyMem (BufferInStack, (VOID *)PageTable, sizeof (BufferInStack)); + for (Index =3D 0; Index < MAX_PAE_PDPTE_NUM; Index++) { + BufferInStack[Index].Pnle.Bits.ReadWrite =3D 1; + BufferInStack[Index].Pnle.Bits.UserSupervisor =3D 1; + BufferInStack[Index].Pnle.Bits.Nx =3D 0; + } + + PageTable =3D (UINTN)BufferInStack; + } + // // Page table layout is as below: // @@ -319,7 +336,7 @@ PageTableParse ( MapCapacity =3D *MapCount; *MapCount =3D 0; LastEntry =3D NULL; - PageTableLibParsePnle ((UINT64)PageTable, MaxLevel, 0, &NopAttribute, Ma= p, MapCount, MapCapacity, &LastEntry, &OneEntry); + PageTableLibParsePnle ((UINT64)PageTable, MaxLevel, MaxLevel, 0, &NopAtt= ribute, Map, MapCount, MapCapacity, &LastEntry, &OneEntry); =20 if (*MapCount > MapCapacity) { return RETURN_BUFFER_TOO_SMALL; --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#101647): https://edk2.groups.io/g/devel/message/101647 Mute This Topic: https://groups.io/mt/97796397/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-