diff options
author | Zhiguang Liu <zhiguang.liu@intel.com> | 2023-03-07 13:55:43 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2023-03-27 08:21:58 +0000 |
commit | 2e01a5c1288590ce6306717a5413bd789f495c12 (patch) | |
tree | 67b3018d080b84c953e174ab22ef33915774e3d0 | |
parent | 8727cc9a8e96608abfc29f5367a1929aae685f95 (diff) | |
download | edk2-2e01a5c1288590ce6306717a5413bd789f495c12.tar.gz edk2-2e01a5c1288590ce6306717a5413bd789f495c12.tar.bz2 edk2-2e01a5c1288590ce6306717a5413bd789f495c12.zip |
UefiCpuPkg: Fix IA32 build failure in CpuPageTableLib.inf
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 <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Ray Ni <ray.ni@intel.com>
-rw-r--r-- | UefiCpuPkg/Include/Library/CpuPageTableLib.h | 32 | ||||
-rw-r--r-- | UefiCpuPkg/Library/CpuPageTableLib/CpuPageTable.h | 125 | ||||
-rw-r--r-- | 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 352b6df6c6..78aa83b8de 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 64383cc522..7936333e01 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);
}
@@ -239,7 +239,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;
}
@@ -399,7 +399,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;
}
@@ -706,7 +706,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.
//
@@ -750,12 +750,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.
|