From mboxrd@z Thu Jan 1 00:00:00 1970 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:49 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=Fnn4zYXX; spf=pass (domain: intel.com, ip: 192.55.52.43, 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=1679557309; x=1711093309; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JCEA/WGjHjpNJUN+SkINba0SnjgbaULgGM5xw/o9V60=; b=Fnn4zYXXdrGukwLkYXrT81muEORXpuhlgo3gQGfpqDeeRGe/9aZJwF5q OYkyZOLpNPs12JLqk0wxyd96Uw2+txWU9iGI2FIczcoFRKb2yi6E+pNfn BijU/5rXHDrt2gnY8fOk+nOzOHf6mh10Rhj7kOFmd0exlhXnYRBMJvlfp 3WMN8uX2HIpD6SukbTFBj7JAjHHmaKwic7bBb6C2vcFpkyZmx+CAXkeou ugfw+6BqJWNCjAv3ELYau830sRgABEKk6egtX/4UwAIYDDbJFfcnAUai2 qvlvdl3vc5q2DqoaBwkrzBUYVGefye0QdYwdcMKSmSO1ko2jFu9/OK93A Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10657"; a="425699792" X-IronPort-AV: E=Sophos;i="5.98,283,1673942400"; d="scan'208";a="425699792" 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:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10657"; a="684616873" X-IronPort-AV: E=Sophos;i="5.98,283,1673942400"; d="scan'208";a="684616873" 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:47 -0700 From: "duntan" To: devel@edk2.groups.io Cc: Zhiguang Liu , Eric Dong , Ray Ni , Rahul Kumar Subject: [Patch V4 15/21] UefiCpuPkg: Fix IA32 build failure in CpuPageTableLib.inf Date: Thu, 23 Mar 2023 15:40:51 +0800 Message-Id: <20230323074057.549-16-dun.tan@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 In-Reply-To: <20230323074057.549-1-dun.tan@intel.com> References: <20230323074057.549-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 +++++++++++----------- 3 files changed, 90 insertions(+), 89 deletions(-) diff --git a/UefiCpuPkg/Include/Library/CpuPageTableLib.h b/UefiCpuPkg/Include/Library/CpuPageTableLib.h index c94d82ea65..5e545a35f6 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..2c67ecb469 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 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_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 797fc2f600..982652b58b 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); } @@ -238,7 +238,7 @@ IsAttributesAndMaskValidForNonPresentEntry ( // if ((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; } @@ -396,7 +396,7 @@ PageTableLibMapInLevel ( // This function is called when the memory length is less than the region length of the parent level. // No need to split the page when the attributes equal. // - if (Mask->Bits.PageTableBaseAddress == 0) { + if ((Mask->Bits.PageTableBaseAddressLow == 0) && (Mask->Bits.PageTableBaseAddressHigh == 0)) { return RETURN_SUCCESS; } @@ -696,7 +696,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. // @@ -738,12 +738,12 @@ PageTableMap ( *IsModified = FALSE; } - 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. -- 2.31.1.windows.1