From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web11.3579.1678270169090361638 for ; Wed, 08 Mar 2023 02:09:29 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=Y9BYeOuK; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: dun.tan@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678270169; x=1709806169; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nCo3OwnlJV2gcNqvPSSpg5ne7VDOs8KHLRL9/yquSo4=; b=Y9BYeOuKbJ6Jau1yHHMbx1EKBY8xmCknJPAbABBuBJNAGhXC9Z9fTqEr 08EztRpCo8A/ntdHZSzkMn0hNAPUuECVRuG+GD2jZEwIqAo6+Ql9iW3L8 pEbsgJvIOF4A41+n06nEPubcBGANYq+/3RutOca8SIZeGIhVBkGRmm05e PvpZBYY4NOLr7p09ZZ7uWlm2CJsZIIxbwdcO/Nnx4Fhv9zJ7GoxlvZvhH MO94qeqtfhK+wSVbFZxwT6ByY/Rm9ij52Vf5o/Qj81yYNtPab4gSuRRO2 Ct3us977CIjjdh2GD7vFSnbuFpWmAoyRUVMlvHffJ5mqw7f1I6gK8CRUh w==; X-IronPort-AV: E=McAfee;i="6500,9779,10642"; a="338442881" X-IronPort-AV: E=Sophos;i="5.98,243,1673942400"; d="scan'208";a="338442881" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2023 02:09:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10642"; a="745862905" X-IronPort-AV: E=Sophos;i="5.98,243,1673942400"; d="scan'208";a="745862905" Received: from shwdeopenlab702.ccr.corp.intel.com ([10.239.55.92]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2023 02:09:27 -0800 From: "duntan" To: devel@edk2.groups.io Cc: Zhiguang Liu , Eric Dong , Ray Ni , Rahul Kumar Subject: [Patch V2 13/14] UefiCpuPkg: Fix IA32 build failure in CpuPageTableLib.inf Date: Wed, 8 Mar 2023 18:07:57 +0800 Message-Id: <20230308100758.669-14-dun.tan@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 In-Reply-To: <20230308100758.669-1-dun.tan@intel.com> References: <20230308100758.669-1-dun.tan@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Zhiguang Liu The definition of IA32_MAP_ATTRIBUTE has 64 bits, and one of the bit field PageTableBaseAddress is from bit 12 to bit 52. This means if the compiler treats the 64bits value as two UINT32 value, the field PageTableBaseAddress spans two UINT32 value. That's why when building in NOOPT mode in IA32, the below issue is noticed: unresolved external symbol __allshl This patch fix the build failure by seperate field PageTableBaseAddress into two fields, make sure no field spans two UINT32 value. Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Signed-off-by: Zhiguang Liu Signed-off-by: Ray Ni --- UefiCpuPkg/Include/Library/CpuPageTableLib.h | 32 ++++++++++++++++---------------- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 22 +++++++++++----------- UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c | 6 +++--- 4 files changed, 93 insertions(+), 92 deletions(-) diff --git a/UefiCpuPkg/Include/Library/CpuPageTableLib.h b/UefiCpuPkg/Include/Library/CpuPageTableLib.h index 118dff20f4..a04040123f 100644 --- a/UefiCpuPkg/Include/Library/CpuPageTableLib.h +++ b/UefiCpuPkg/Include/Library/CpuPageTableLib.h @@ -11,22 +11,22 @@ typedef union { struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User - UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) - UINT64 Pat : 1; // PAT - - UINT64 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) - UINT64 Reserved1 : 3; // Ignored - - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 Reserved2 : 7; // Ignored - UINT64 ProtectionKey : 4; // Protection key - UINT64 Nx : 1; // No Execute bit + UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory + UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write + UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User + UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching + UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached + UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) + UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) + UINT32 Pat : 1; // PAT + UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) + UINT32 Reserved1 : 3; // Ignored + UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low + + UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High + UINT32 Reserved2 : 7; // Ignored + UINT32 ProtectionKey : 4; // Protection key + UINT32 Nx : 1; // No Execute bit } Bits; UINT64 Uint64; } IA32_MAP_ATTRIBUTE; diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h index 8d856d7c7e..882719546f 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h @@ -29,11 +29,12 @@ typedef enum { } IA32_PAGE_LEVEL; typedef struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User - UINT64 Reserved : 58; - UINT64 Nx : 1; // No Execute bit + UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory + UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write + UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User + UINT32 Reserved0 : 29; + UINT32 Reserved1 : 31; + UINT32 Nx : 1; // No Execute bit } IA32_PAGE_COMMON_ENTRY; /// @@ -41,20 +42,20 @@ typedef struct { /// typedef union { struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User - UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Available0 : 1; // Ignored - UINT64 MustBeZero : 1; // Must Be Zero - - UINT64 Available2 : 4; // Ignored - - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 Available3 : 11; // Ignored - UINT64 Nx : 1; // No Execute bit + UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory + UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write + UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User + UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching + UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached + UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) + UINT32 Available0 : 1; // Ignored + UINT32 MustBeZero : 1; // Must Be Zero + UINT32 Available2 : 4; // Ignored + UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low + + UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High + UINT32 Available3 : 11; // Ignored + UINT32 Nx : 1; // No Execute bit } Bits; UINT64 Uint64; } IA32_PAGE_NON_LEAF_ENTRY; @@ -86,23 +87,23 @@ typedef IA32_PAGE_NON_LEAF_ENTRY IA32_PDE; /// typedef union { struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User - UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) - UINT64 MustBeOne : 1; // Page Size. Must Be One - - UINT64 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) - UINT64 Available1 : 3; // Ignored - UINT64 Pat : 1; // PAT - - UINT64 PageTableBaseAddress : 39; // Page Table Base Address - UINT64 Available3 : 7; // Ignored - UINT64 ProtectionKey : 4; // Protection key - UINT64 Nx : 1; // No Execute bit + UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory + UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write + UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User + UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching + UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached + UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) + UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) + UINT32 MustBeOne : 1; // Page Size. Must Be One + UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) + UINT32 Available1 : 3; // Ignored + UINT32 Pat : 1; // PAT + UINT32 PageTableBaseAddressLow : 19; // Page Table Base Address High + + UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High + UINT32 Available3 : 7; // Ignored + UINT32 ProtectionKey : 4; // Protection key + UINT32 Nx : 1; // No Execute bit } Bits; UINT64 Uint64; } IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE; @@ -123,22 +124,22 @@ typedef IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE IA32_PDPTE_1G; /// typedef union { struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User - UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) - UINT64 Pat : 1; // PAT - - UINT64 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) - UINT64 Available1 : 3; // Ignored - - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 Available3 : 7; // Ignored - UINT64 ProtectionKey : 4; // Protection key - UINT64 Nx : 1; // No Execute bit + UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory + UINT32 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write + UINT32 UserSupervisor : 1; // 0 = Supervisor, 1=User + UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching + UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached + UINT32 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) + UINT32 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU) + UINT32 Pat : 1; // PAT + UINT32 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1) + UINT32 Available1 : 3; // Ignored + UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low + + UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High + UINT32 Available3 : 7; // Ignored + UINT32 ProtectionKey : 4; // Protection key + UINT32 Nx : 1; // No Execute bit } Bits; UINT64 Uint64; } IA32_PTE_4K; @@ -149,16 +150,16 @@ typedef union { /// typedef union { struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 MustBeZero : 2; // Must Be Zero - UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached - UINT64 MustBeZero2 : 4; // Must Be Zero - - UINT64 Available : 3; // Ignored - - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 MustBeZero3 : 12; // Must Be Zero + UINT32 Present : 1; // 0 = Not present in memory, 1 = Present in memory + UINT32 MustBeZero : 2; // Must Be Zero + UINT32 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching + UINT32 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached + UINT32 MustBeZero2 : 4; // Must Be Zero + UINT32 Available : 3; // Ignored + UINT32 PageTableBaseAddressLow : 20; // Page Table Base Address Low + + UINT32 PageTableBaseAddressHigh : 20; // Page Table Base Address High + UINT32 MustBeZero3 : 12; // Must Be Zero } Bits; UINT64 Uint64; } IA32_PDPTE_PAE; diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c index d99a21a0fc..fd5c5b50d2 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -26,7 +26,7 @@ PageTableLibSetPte4K ( IN IA32_MAP_ATTRIBUTE *Mask ) { - if (Mask->Bits.PageTableBaseAddress) { + if (Mask->Bits.PageTableBaseAddressLow || Mask->Bits.PageTableBaseAddressHigh) { Pte4K->Uint64 = (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset) | (Pte4K->Uint64 & ~IA32_PE_BASE_ADDRESS_MASK_40); } @@ -93,7 +93,7 @@ PageTableLibSetPleB ( IN IA32_MAP_ATTRIBUTE *Mask ) { - if (Mask->Bits.PageTableBaseAddress) { + if (Mask->Bits.PageTableBaseAddressLow || Mask->Bits.PageTableBaseAddressHigh) { PleB->Uint64 = (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset) | (PleB->Uint64 & ~IA32_PE_BASE_ADDRESS_MASK_39); } @@ -233,7 +233,7 @@ CheckMaskAndAttrForNotPresentEntry ( if ((Attribute->Bits.Present == 0) || (Mask->Bits.Present == 0) || (Mask->Bits.ReadWrite == 0) || (Mask->Bits.UserSupervisor == 0) || (Mask->Bits.WriteThrough == 0) || (Mask->Bits.CacheDisabled == 0) || (Mask->Bits.Accessed == 0) || (Mask->Bits.Dirty == 0) || (Mask->Bits.Pat == 0) || (Mask->Bits.Global == 0) || - (Mask->Bits.PageTableBaseAddress == 0) || (Mask->Bits.ProtectionKey == 0) || (Mask->Bits.Nx == 0)) + ((Mask->Bits.PageTableBaseAddressLow == 0) && (Mask->Bits.PageTableBaseAddressHigh == 0)) || (Mask->Bits.ProtectionKey == 0) || (Mask->Bits.Nx == 0)) { return RETURN_INVALID_PARAMETER; } @@ -376,7 +376,7 @@ PageTableLibMapInLevel ( PleBAttribute.Uint64 = PageTableLibGetPleBMapAttribute (&ParentPagingEntry->PleB, ParentAttribute); if ((((IA32_MAP_ATTRIBUTE_ATTRIBUTES (&PleBAttribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)) == (IA32_MAP_ATTRIBUTE_ATTRIBUTES (Attribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)))) && - ( (Mask->Bits.PageTableBaseAddress == 0) + ( ((Mask->Bits.PageTableBaseAddressLow == 0) && (Mask->Bits.PageTableBaseAddressHigh == 0)) || ((IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&PleBAttribute) + PagingEntryIndex * RegionLength) == (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (Attribute) + Offset)))) { @@ -676,7 +676,7 @@ PageTableMap ( return RETURN_INVALID_PARAMETER; } - if ((LinearAddress % SIZE_4KB != 0) || (Length % SIZE_4KB != 0)) { + if (((UINTN)LinearAddress % SIZE_4KB != 0) || ((UINTN)Length % SIZE_4KB != 0)) { // // LinearAddress and Length should be multiple of 4K. // @@ -710,12 +710,12 @@ PageTableMap ( TopPagingEntry.Pce.Nx = 0; } - ParentAttribute.Uint64 = 0; - ParentAttribute.Bits.PageTableBaseAddress = 1; - ParentAttribute.Bits.Present = 1; - ParentAttribute.Bits.ReadWrite = 1; - ParentAttribute.Bits.UserSupervisor = 1; - ParentAttribute.Bits.Nx = 0; + ParentAttribute.Uint64 = 0; + ParentAttribute.Bits.PageTableBaseAddressLow = 1; + ParentAttribute.Bits.Present = 1; + ParentAttribute.Bits.ReadWrite = 1; + ParentAttribute.Bits.UserSupervisor = 1; + ParentAttribute.Bits.Nx = 0; // // Query the required buffer size without modifying the page table. diff --git a/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c b/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c index c10121ede5..05a40bb225 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c +++ b/UefiCpuPkg/Library/MpInitLib/X64/CreatePageTable.c @@ -37,9 +37,9 @@ CreatePageTable ( MapAttribute.Bits.Present = 1; MapAttribute.Bits.ReadWrite = 1; - MapMask.Bits.PageTableBaseAddress = 1; - MapMask.Bits.Present = 1; - MapMask.Bits.ReadWrite = 1; + MapMask.Bits.PageTableBaseAddressLow = 1; + MapMask.Bits.Present = 1; + MapMask.Bits.ReadWrite = 1; PageTable = 0; PageTableBufferSize = 0; -- 2.31.1.windows.1