From bf06117f3f476121b839b096c8da7448f51ff7df Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Fri, 10 Feb 2023 16:27:56 -0800 Subject: [PATCH 1/2] initial upload --- .../AARCH64/PageSplitTest.c | 118 ++++++++++++++++++ .../MemoryAttributeProtocolFuncTestApp.h | 75 ----------- .../MemoryAttributeProtocolFuncTestApp.inf | 89 +++++++------ .../X64/PageSplitTest.c | 76 +++++++++++ 4 files changed, 243 insertions(+), 115 deletions(-) create mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c new file mode 100644 index 0000000000..cb136f493c --- /dev/null +++ b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c @@ -0,0 +1,118 @@ +/** @file -- PagingAuditProcessor.c + +Platform specific memory audit functions. +Copyright (c) Microsoft Corporation. All rights reserved. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include "MemoryAttributeProtocolFuncTestApp.h" + +#define TT_ADDRESS_MASK (0xFFFFFFFFFULL << 12) + +#define IS_TABLE(page, level) ((level == 3) ? FALSE : (((page) & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) +#define IS_BLOCK(page, level) ((level == 3) ? (((page) & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3) : ((page & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY)) +#define ROOT_TABLE_LEN(T0SZ) (TT_ENTRY_COUNT >> ((T0SZ) - 16) % 9) + +/** + Get an unsplit page table entry and allocate entire region so the page + doesn't need to be split on allocation + + @param[out] Address Address of allocated 2MB page region +**/ +EFI_STATUS +EFIAPI +GetUnsplitPageTableEntry ( + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + UINT64 *Pml0 = NULL; + UINT64 *Pte1G = NULL; + UINT64 *Pte2M = NULL; + UINT64 Index2 = 0; + UINT64 Index1 = 0; + UINT64 Index0 = 0; + UINT64 RootEntryCount = 0; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS BaseAddress; + + Pml0 = (UINT64 *)ArmGetTTBR0BaseAddress (); + + if (Pml0 == NULL) { + return EFI_NOT_FOUND; + } + + RootEntryCount = ROOT_TABLE_LEN (ArmGetTCR () & TCR_T0SZ_MASK); + + for (Index0 = 0x0; Index0 < RootEntryCount; Index0++) { + if (!IS_TABLE (Pml0[Index0], 0)) { + continue; + } + + Pte1G = (UINT64 *)(Pml0[Index0] & TT_ADDRESS_MASK); + + for (Index1 = 0x1; Index1 < TT_ENTRY_COUNT; Index1++ ) { + if ((Pte1G[Index1] & 0x1) == 0) { + continue; + } + + if (!IS_BLOCK (Pte1G[Index1], 1)) { + Pte2M = (UINT64 *)(Pte1G[Index1] & TT_ADDRESS_MASK); + + for (Index2 = 0x0; Index2 < TT_ENTRY_COUNT; Index2++ ) { + if ((Pte2M[Index2] & 0x1) == 0) { + continue; + } + + if (!IS_BLOCK (Pte2M[Index2], 2)) { + continue; + } else { + BaseAddress = (EFI_PHYSICAL_ADDRESS)(Pte2M[Index2] & TT_ADDRESS_MASK); + Status = gBS->AllocatePages (AllocateAddress, EfiLoaderCode, EFI_SIZE_TO_PAGES (PTE2MB), &BaseAddress); + if (!EFI_ERROR (Status)) { + *Address = BaseAddress; + return EFI_SUCCESS; + } + } + } + } + } + } + + return EFI_OUT_OF_RESOURCES; +} + +/** + Check if the 2MB page entry correlating with the input address + is set to no-execute + + @param[in] Address Address of the page table entry +**/ +UINT64 +EFIAPI +GetSpitPageTableEntryNoExecute ( + IN PHYSICAL_ADDRESS Address + ) +{ + UINT64 *Pml0 = NULL; + UINT64 *Pte1G = NULL; + UINT64 *Pte2M = NULL; + UINT64 Index2 = 0; + UINT64 Index1 = 0; + UINT64 Index0 = 0; + + Pml0 = (UINT64 *)ArmGetTTBR0BaseAddress (); + + if (Pml0 == NULL) { + return TT_UXN_MASK; + } + + Index0 = (Address >> 39) & (TT_ENTRY_COUNT - 1); + Index1 = (Address >> 30) & (TT_ENTRY_COUNT - 1); + Index2 = (Address >> 21) & (TT_ENTRY_COUNT - 1); + + Pte1G = (UINT64 *)(Pml0[Index0] & TT_ADDRESS_MASK); + Pte2M = (UINT64 *)(Pte1G[Index1] & TT_ADDRESS_MASK); + return Pte2M[Index2] & TT_UXN_MASK; +} diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h index 16dc0bc97e..1541be259e 100644 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h +++ b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h @@ -20,81 +20,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define PTE2MB 0x200000 #define PTE1GB 0x40000000 #define PTE512GB 0x8000000000 -#define PAGING_PAE_INDEX_MASK 0x1FF - -#pragma pack(1) - -// -// Page-Map Level-4 Offset (L4PageTable) and -// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB -// -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 Reserved : 1; // Reserved - UINT64 MustBeZero : 2; // Must Be Zero - UINT64 Available : 3; // Available for use by system software - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // No Execute bit - } Bits; - UINT64 Uint64; -} PAGE_MAP_AND_DIRECTORY_POINTER; - -// -// Page Table Entry 1GB -// -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 = written by processor on access to page - UINT64 MustBe1 : 1; // Must be 1 - UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available : 3; // Available for use by system software - UINT64 PAT : 1; // - UINT64 MustBeZero : 17; // Must be zero; - UINT64 PageTableBaseAddress : 22; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_1G_ENTRY; - -// -// Page Table Entry 2MB -// -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 = written by processor on access to page - UINT64 MustBe1 : 1; // Must be 1 - UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available : 3; // Available for use by system software - UINT64 PAT : 1; // - UINT64 MustBeZero : 8; // Must be zero; - UINT64 PageTableBaseAddress : 31; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_ENTRY; - -#pragma pack() /** Get an unsplit page table entry and allocate entire region so the page diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf index 7f808cde83..9ed535ee36 100644 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf +++ b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf @@ -1,40 +1,49 @@ -## @file -# TCBZ3519 -# Uefi Shell based Application that unit tests the Memory Attribute Protocol. -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = MemoryAttributeProtocolFuncTestApp - FILE_GUID = bb7f9547-68db-4bf0-a247-c022c6146df3 - MODULE_TYPE = UEFI_APPLICATION - VERSION_STRING = 1.0 - ENTRY_POINT = UefiMain - -[Sources] - MemoryAttributeProtocolFuncTestApp.c - MemoryAttributeProtocolFuncTestApp.h - -[Sources.X64] - X64/PageSplitTest.c - -[Sources.IA32, Sources.AARCH64] - PageSplitTest.c - -[Packages] - MdePkg/MdePkg.dec - UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec - -[LibraryClasses] - UefiApplicationEntryPoint - UnitTestLib - UefiBootServicesTableLib - DebugLib - -[Guids] - -[Protocols] - gEfiMemoryAttributeProtocolGuid +## @file +# TCBZ3519 +# Uefi Shell based Application that unit tests the Memory Attribute Protocol. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MemoryAttributeProtocolFuncTestApp + FILE_GUID = bb7f9547-68db-4bf0-a247-c022c6146df3 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + +[Sources] + MemoryAttributeProtocolFuncTestApp.c + MemoryAttributeProtocolFuncTestApp.h + +[Sources.X64] + X64/PageSplitTest.c + +[Sources.IA32, Sources.ARM] + PageSplitTest.c + +[Sources.AARCH64] + AARCH64/PageSplitTest.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[Packages.AARCH64] + ArmPkg/ArmPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UnitTestLib + UefiBootServicesTableLib + DebugLib + +[LibraryClasses.AARCH64] + ArmLib + +[Guids] + +[Protocols] + gEfiMemoryAttributeProtocolGuid diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c index cf5b7cc9ae..857d05ec86 100644 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c +++ b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c @@ -8,6 +8,82 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "MemoryAttributeProtocolFuncTestApp.h" +#define PAGING_PAE_INDEX_MASK 0x1FF + +#pragma pack(1) + +// +// Page-Map Level-4 Offset (L4PageTable) and +// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB +// +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 Reserved : 1; // Reserved + UINT64 MustBeZero : 2; // Must Be Zero + UINT64 Available : 3; // Available for use by system software + UINT64 PageTableBaseAddress : 40; // Page Table Base Address + UINT64 AvailableHigh : 11; // Available for use by system software + UINT64 Nx : 1; // No Execute bit + } Bits; + UINT64 Uint64; +} PAGE_MAP_AND_DIRECTORY_POINTER; + +// +// Page Table Entry 1GB +// +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 = written by processor on access to page + UINT64 MustBe1 : 1; // Must be 1 + UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write + UINT64 Available : 3; // Available for use by system software + UINT64 PAT : 1; // + UINT64 MustBeZero : 17; // Must be zero; + UINT64 PageTableBaseAddress : 22; // Page Table Base Address + UINT64 AvailableHigh : 11; // Available for use by system software + UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution + } Bits; + UINT64 Uint64; +} PAGE_TABLE_1G_ENTRY; + +// +// Page Table Entry 2MB +// +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 = written by processor on access to page + UINT64 MustBe1 : 1; // Must be 1 + UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write + UINT64 Available : 3; // Available for use by system software + UINT64 PAT : 1; // + UINT64 MustBeZero : 8; // Must be zero; + UINT64 PageTableBaseAddress : 31; // Page Table Base Address + UINT64 AvailableHigh : 11; // Available for use by system software + UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution + } Bits; + UINT64 Uint64; +} PAGE_TABLE_ENTRY; + +#pragma pack() + /** Get an unsplit page table entry and allocate entire region so the page doesn't need to be split on allocation From 1f7e1fc55fefe4c2f42f96b423dbb55162756dfd Mon Sep 17 00:00:00 2001 From: Taylor Beebe Date: Tue, 28 Feb 2023 11:22:26 -0800 Subject: [PATCH 2/2] remove test --- MdePkg/MdePkg.dsc | 2 - .../AARCH64/PageSplitTest.c | 118 ---- .../MemoryAttributeProtocolFuncTestApp.c | 510 ------------------ .../MemoryAttributeProtocolFuncTestApp.h | 48 -- .../MemoryAttributeProtocolFuncTestApp.inf | 49 -- .../PageSplitTest.c | 39 -- .../Readme.md | 19 - .../X64/PageSplitTest.c | 180 ------- 8 files changed, 965 deletions(-) delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.c delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/PageSplitTest.c delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/Readme.md delete mode 100644 MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 0866e47c01..be14da3cd4 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -162,8 +162,6 @@ [Components.IA32, Components.X64, Components.AARCH64] MdePkg/Library/BaseRngLib/BaseRngLib.inf - # TCBZ3519 MU_CHANGE: UEFI shell test for MemoryAttributeProtocol - MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf [Components.IA32, Components.X64] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c deleted file mode 100644 index cb136f493c..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/AARCH64/PageSplitTest.c +++ /dev/null @@ -1,118 +0,0 @@ -/** @file -- PagingAuditProcessor.c - -Platform specific memory audit functions. -Copyright (c) Microsoft Corporation. All rights reserved. - -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include -#include "MemoryAttributeProtocolFuncTestApp.h" - -#define TT_ADDRESS_MASK (0xFFFFFFFFFULL << 12) - -#define IS_TABLE(page, level) ((level == 3) ? FALSE : (((page) & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) -#define IS_BLOCK(page, level) ((level == 3) ? (((page) & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3) : ((page & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY)) -#define ROOT_TABLE_LEN(T0SZ) (TT_ENTRY_COUNT >> ((T0SZ) - 16) % 9) - -/** - Get an unsplit page table entry and allocate entire region so the page - doesn't need to be split on allocation - - @param[out] Address Address of allocated 2MB page region -**/ -EFI_STATUS -EFIAPI -GetUnsplitPageTableEntry ( - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - UINT64 *Pml0 = NULL; - UINT64 *Pte1G = NULL; - UINT64 *Pte2M = NULL; - UINT64 Index2 = 0; - UINT64 Index1 = 0; - UINT64 Index0 = 0; - UINT64 RootEntryCount = 0; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS BaseAddress; - - Pml0 = (UINT64 *)ArmGetTTBR0BaseAddress (); - - if (Pml0 == NULL) { - return EFI_NOT_FOUND; - } - - RootEntryCount = ROOT_TABLE_LEN (ArmGetTCR () & TCR_T0SZ_MASK); - - for (Index0 = 0x0; Index0 < RootEntryCount; Index0++) { - if (!IS_TABLE (Pml0[Index0], 0)) { - continue; - } - - Pte1G = (UINT64 *)(Pml0[Index0] & TT_ADDRESS_MASK); - - for (Index1 = 0x1; Index1 < TT_ENTRY_COUNT; Index1++ ) { - if ((Pte1G[Index1] & 0x1) == 0) { - continue; - } - - if (!IS_BLOCK (Pte1G[Index1], 1)) { - Pte2M = (UINT64 *)(Pte1G[Index1] & TT_ADDRESS_MASK); - - for (Index2 = 0x0; Index2 < TT_ENTRY_COUNT; Index2++ ) { - if ((Pte2M[Index2] & 0x1) == 0) { - continue; - } - - if (!IS_BLOCK (Pte2M[Index2], 2)) { - continue; - } else { - BaseAddress = (EFI_PHYSICAL_ADDRESS)(Pte2M[Index2] & TT_ADDRESS_MASK); - Status = gBS->AllocatePages (AllocateAddress, EfiLoaderCode, EFI_SIZE_TO_PAGES (PTE2MB), &BaseAddress); - if (!EFI_ERROR (Status)) { - *Address = BaseAddress; - return EFI_SUCCESS; - } - } - } - } - } - } - - return EFI_OUT_OF_RESOURCES; -} - -/** - Check if the 2MB page entry correlating with the input address - is set to no-execute - - @param[in] Address Address of the page table entry -**/ -UINT64 -EFIAPI -GetSpitPageTableEntryNoExecute ( - IN PHYSICAL_ADDRESS Address - ) -{ - UINT64 *Pml0 = NULL; - UINT64 *Pte1G = NULL; - UINT64 *Pte2M = NULL; - UINT64 Index2 = 0; - UINT64 Index1 = 0; - UINT64 Index0 = 0; - - Pml0 = (UINT64 *)ArmGetTTBR0BaseAddress (); - - if (Pml0 == NULL) { - return TT_UXN_MASK; - } - - Index0 = (Address >> 39) & (TT_ENTRY_COUNT - 1); - Index1 = (Address >> 30) & (TT_ENTRY_COUNT - 1); - Index2 = (Address >> 21) & (TT_ENTRY_COUNT - 1); - - Pte1G = (UINT64 *)(Pml0[Index0] & TT_ADDRESS_MASK); - Pte2M = (UINT64 *)(Pte1G[Index1] & TT_ADDRESS_MASK); - return Pte2M[Index2] & TT_UXN_MASK; -} diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.c b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.c deleted file mode 100644 index 702ea8ba53..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.c +++ /dev/null @@ -1,510 +0,0 @@ -/** @file -TCBZ3519 -UEFI Shell based application for unit testing the Memory Attribute Protocol. - -Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent -***/ - -#define UNIT_TEST_APP_NAME "Memory Attribute Protocol Unit Test Application" -#define UNIT_TEST_APP_VERSION "0.2" - -#include "MemoryAttributeProtocolFuncTestApp.h" - -/** - Ensure this image is protected. - -**/ -EFI_STATUS -STATIC -IsThisImageProtected ( - VOID - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 Length; - UINT64 Attributes; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - - if (EFI_ERROR (Status)) { - return RETURN_UNSUPPORTED; - } - - BaseAddress = (UINTN)IsThisImageProtected & ~(EFI_PAGE_SIZE - 1); - Attributes = 0; - Length = EFI_PAGE_SIZE; - - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - - if (EFI_ERROR (Status) || (Attributes == 0)) { - return RETURN_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -/** - Allocate a page, set the page to read-only, no-execute, and read-protected, then free the page to - test if the free process clears those attributes before attempting to free the memory. - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -FreePagesWithProtectionAttributesTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN Length; - UINT64 Attributes; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - Attributes = 0; - BaseAddress = 0; - Length = EFI_PAGE_SIZE; - - // Allocate any pages - Status = gBS->AllocatePages (AllocateAnyPages, EfiLoaderCode, Length, &BaseAddress); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL ((VOID *)((UINTN)BaseAddress)); - - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Get the attributes of allocated pages - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - DEBUG ((DEBUG_INFO, "%a - Attributes for memory at base: 0x%llx 0x%llx\n", __FUNCTION__, BaseAddress, Attributes)); - - // Free the pages - gBS->FreePages (BaseAddress, Length); - UT_ASSERT_NOT_EFI_ERROR (Status); - - return UNIT_TEST_PASSED; -} - -/** - Allocate a pool, set the page table entry managing that pool to read-only, no-execute, - and read-protected, then free the pool to test if the free process clears those - attributes before attempting to free the pool. - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -FreePoolWithProtectionAttributesTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN Length; - UINT64 Attributes; - VOID *Buffer; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - Attributes = 0; - BaseAddress = 0; - Length = EFI_PAGE_SIZE; - - // Allocate a pool - Status = gBS->AllocatePool (EfiLoaderCode, Length, &Buffer); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (Buffer); - - BaseAddress = ((EFI_PHYSICAL_ADDRESS)((UINTN)ALIGN_POINTER (Buffer, EFI_PAGE_SIZE))) - EFI_PAGE_SIZE; - - // Get the attributes of the pages representing the allocated pool - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Free the pool - gBS->FreePool (Buffer); - UT_ASSERT_NOT_EFI_ERROR (Status); - - return UNIT_TEST_PASSED; -} - -/** - Allocate a page, free that page, then reallocate a page specifiying the previously - allocated address to ensure that the attributes are as expected - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -AllocateFreeAllocateAtAddressTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN Length; - UINT64 Attributes; - UINT64 CachedAttributes; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - Attributes = 0; - BaseAddress = 0; - Length = EFI_PAGE_SIZE; - - // Allocate any pages - Status = gBS->AllocatePages (AllocateAnyPages, EfiLoaderCode, Length, &BaseAddress); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL ((VOID *)((UINTN)BaseAddress)); - - // Get the attributes of allocated pages - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - UT_LOG_INFO ("%a - Attributes for memory at base: 0x%llx 0x%llx\n", __FUNCTION__, BaseAddress, Attributes); - - CachedAttributes = Attributes; - - // Flip all the attributes of the page range - if ((CachedAttributes & EFI_MEMORY_XP) != 0) { - Status = MemoryAttribute->ClearMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_XP); - UT_ASSERT_NOT_EFI_ERROR (Status); - } else { - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_XP); - UT_ASSERT_NOT_EFI_ERROR (Status); - } - - if ((CachedAttributes & EFI_MEMORY_RO) != 0) { - Status = MemoryAttribute->ClearMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_RO); - UT_ASSERT_NOT_EFI_ERROR (Status); - } else { - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_RO); - UT_ASSERT_NOT_EFI_ERROR (Status); - } - - if ((CachedAttributes & EFI_MEMORY_RP) != 0) { - Status = MemoryAttribute->ClearMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_RP); - UT_ASSERT_NOT_EFI_ERROR (Status); - } else { - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, Length, EFI_MEMORY_RP); - UT_ASSERT_NOT_EFI_ERROR (Status); - } - - // Free the pages - gBS->FreePages (BaseAddress, Length); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Allocate pages at the previously allocated address - Status = gBS->AllocatePages (AllocateAddress, EfiLoaderCode, Length, &BaseAddress); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL ((VOID *)((UINTN)BaseAddress)); - - // Get the attributes of allocated pages and check them against the cached attributes - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_EQUAL (Attributes, CachedAttributes); - - UT_LOG_INFO ("%a - Attributes for memory after reallocation at base: 0x%llx 0x%llx\n", __FUNCTION__, BaseAddress, Attributes); - - // Free the pages - gBS->FreePages (BaseAddress, Length); - - return UNIT_TEST_PASSED; -} - -/** - Allocate an unsplit page range, clear the no-execute attribute from a subsection of that region - to force a split, then ensure the previously unsplit region has also had the no-execute attribute - cleared. - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -UpdateAttributesRequiresPageSplitTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 Attributes; - - Status = GetUnsplitPageTableEntry (&BaseAddress); - UT_ASSERT_NOT_EQUAL (BaseAddress, 0); - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - // Get the attributes of allocated 2MB page - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, PTE2MB, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - UT_LOG_INFO ("Attributes for 2MB page at address: 0x%llx 0x%llx\n", BaseAddress, Attributes); - - if ((Attributes & EFI_MEMORY_XP) == 0) { - // Set the 2MB region to NX - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, PTE2MB, EFI_MEMORY_XP); - UT_ASSERT_NOT_EFI_ERROR (Status); - } - - // Set subsection of 2MB region to executable - Status = MemoryAttribute->ClearMemoryAttributes (MemoryAttribute, BaseAddress + EFI_PAGE_SIZE, EFI_PAGE_SIZE, EFI_MEMORY_XP); - UT_ASSERT_NOT_EFI_ERROR (Status); - - // Check that the 2MB page is no longer NX - UT_ASSERT_EQUAL (GetSpitPageTableEntryNoExecute (BaseAddress), 0); - - // Free the pages - gBS->FreePages (BaseAddress, EFI_SIZE_TO_PAGES (PTE2MB)); - - return UNIT_TEST_PASSED; -} - -/** - Make sure test environment has protocol - - @param Context - **/ -UNIT_TEST_STATUS -EFIAPI -ProtocolExistsTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - return UNIT_TEST_PASSED; -} - -/** - Fetch the attributes, clear them, then set them back to their orignal value - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -GetClearSetAttributesRunningCodeTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 Length; - UINT64 Attributes; - UINT64 CachedAttributes; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - BaseAddress = (UINTN)GetClearSetAttributesRunningCodeTestCase & ~(EFI_PAGE_SIZE - 1); // Page align address of this page - Attributes = 0; - Length = EFI_PAGE_SIZE; - - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - UT_LOG_INFO ("Attributes for Memory at base: 0x%llx 0x%llx\n", BaseAddress, Attributes); - - CachedAttributes = Attributes; // save them for later to set - UT_ASSERT_NOT_EQUAL (0, CachedAttributes); // If attributes are zero this is unexpected and test will not work - - Status = MemoryAttribute->ClearMemoryAttributes (MemoryAttribute, BaseAddress, Length, CachedAttributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_LOG_INFO ("Attributes after clear for Memory at base: 0x%llX 0x%llx\n", BaseAddress, Attributes); - UT_ASSERT_NOT_EQUAL (Attributes, CachedAttributes); // should not be equal since we just cleared them - - Status = MemoryAttribute->SetMemoryAttributes (MemoryAttribute, BaseAddress, Length, CachedAttributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_LOG_INFO ("Attributes after set for Memory at base: 0x%llX 0x%llx\n", BaseAddress, Attributes); - UT_ASSERT_EQUAL (Attributes, CachedAttributes); // should be equal since we just cleared them - - return UNIT_TEST_PASSED; -} - -/** - Check that EfiLoaderCode is allocated as no-execute and read/write - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -GetAttributesNewBufferEfiLoaderCodeTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN Length; - UINT64 Attributes; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - Attributes = 0; - BaseAddress = 0; - Length = EFI_PAGE_SIZE; - - Status = gBS->AllocatePages (AllocateAnyPages, EfiLoaderCode, Length, &BaseAddress); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL ((VOID *)((UINTN)BaseAddress)); - - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - gBS->FreePages (BaseAddress, Length); // Free the page in case of any failures - UT_ASSERT_NOT_EFI_ERROR (Status); - - UT_LOG_INFO ("Attributes: 0x%llx\n", Attributes); - - // newly allocated efi loader code page should be RW- - UT_ASSERT_TRUE ((Attributes & EFI_MEMORY_XP) == EFI_MEMORY_XP); // should be No Execute - UT_ASSERT_FALSE ((Attributes & EFI_MEMORY_RO) == EFI_MEMORY_RO); // Should be not read only - - return UNIT_TEST_PASSED; -} - -/** - Check that code region of image is set as read-only and executable - - @param[in] Context Unit test context - -**/ -UNIT_TEST_STATUS -EFIAPI -GetAttributesRunningCodeTestCase ( - IN UNIT_TEST_CONTEXT Context - ) -{ - EFI_STATUS Status; - EFI_MEMORY_ATTRIBUTE_PROTOCOL *MemoryAttribute; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 Length; - UINT64 Attributes; - - Status = gBS->LocateProtocol (&gEfiMemoryAttributeProtocolGuid, NULL, (VOID **)&MemoryAttribute); - UT_ASSERT_NOT_EFI_ERROR (Status); - UT_ASSERT_NOT_NULL (MemoryAttribute); - - BaseAddress = (UINTN)GetAttributesRunningCodeTestCase & ~(EFI_PAGE_SIZE - 1); // Page align address of this page - Attributes = 0; - Length = EFI_PAGE_SIZE; - - Status = MemoryAttribute->GetMemoryAttributes (MemoryAttribute, BaseAddress, Length, &Attributes); - UT_ASSERT_NOT_EFI_ERROR (Status); - - UT_LOG_INFO ("Attributes: 0x%llx\n", Attributes); - // This page is the current executing code page. Should be RO and not XP - UT_ASSERT_FALSE ((Attributes & EFI_MEMORY_XP) == EFI_MEMORY_XP); // should be allowed to execute - UT_ASSERT_TRUE ((Attributes & EFI_MEMORY_RO) == EFI_MEMORY_RO); // Should be read only - - return UNIT_TEST_PASSED; -} - -/** - The driver's entry point. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point executed successfully. - @retval other Some error occurred when executing this entry point. -**/ -EFI_STATUS -EFIAPI -UefiMain ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - UNIT_TEST_FRAMEWORK_HANDLE Framework; - UNIT_TEST_SUITE_HANDLE TestSuite; - - Framework = NULL; - TestSuite = NULL; - - DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION)); - - Status = IsThisImageProtected (); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - // - // Start setting up the test framework for running the tests. - // - Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); - goto EXIT; - } - - // - // Test Suite - // - Status = CreateUnitTestSuite (&TestSuite, Framework, "Basic", "Dxe.MemoryManagement.MemoryAttributesProtocol", NULL, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Test Suite\n")); - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - AddTestCase (TestSuite, "Memory Attributes Protocol Exists", "PrototocolExists", ProtocolExistsTestCase, NULL, NULL, NULL); - AddTestCase (TestSuite, "Get Clear Set Attributes work as expected", "BasicGetClearSet", GetClearSetAttributesRunningCodeTestCase, ProtocolExistsTestCase, NULL, NULL); - AddTestCase (TestSuite, "New EfiLoaderCode buffer attributes expected", "NewEfiLoaderCodeAttributes", GetAttributesNewBufferEfiLoaderCodeTestCase, ProtocolExistsTestCase, NULL, NULL); - AddTestCase (TestSuite, "Loaded Code Attributes Allow Execution", "RunningCodeAttributes", GetAttributesRunningCodeTestCase, ProtocolExistsTestCase, NULL, NULL); - AddTestCase (TestSuite, "Allocate, free, then reallocate at the previous address", "AllocateFreeAllocateAtAddress", AllocateFreeAllocateAtAddressTestCase, ProtocolExistsTestCase, NULL, NULL); - AddTestCase (TestSuite, "Ensure higher level pages have loose page attributes after split", "UpdateAttributesRequiresPageSplit", UpdateAttributesRequiresPageSplitTestCase, ProtocolExistsTestCase, NULL, NULL); - AddTestCase (TestSuite, "Pages with protection attributes set can still be freed", "FreePagesWithProtectionAttributes", FreePagesWithProtectionAttributesTestCase, ProtocolExistsTestCase, NULL, NULL); - - // - // Execute the tests. - // - Status = RunAllTestSuites (Framework); - -EXIT: - if (Framework != NULL) { - FreeUnitTestFramework (Framework); - } - - return Status; -} diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h deleted file mode 100644 index 1541be259e..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.h +++ /dev/null @@ -1,48 +0,0 @@ -/** @file -- MemoryAttributeProtocolFuncTestApp.h -TCBZ3519 -Functionality to support MemoryAttributeProtocolFuncTestApp.c - -Copyright (c) Microsoft Corporation. All rights reserved. -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _MEM_ATTR_PROTOCOL_FUNC_TEST_APP_ -#define _MEM_ATTR_PROTOCOL_FUNC_TEST_APP_ - -#include -#include -#include -#include -#include -#include - -#define PTE2MB 0x200000 -#define PTE1GB 0x40000000 -#define PTE512GB 0x8000000000 - -/** - Get an unsplit page table entry and allocate entire region so the page - doesn't need to be split on allocation - - @param[out] Address Address of allocated 2MB page region -**/ -EFI_STATUS -EFIAPI -GetUnsplitPageTableEntry ( - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -/** - Check if the 2MB page entry correlating with the input address - is set to no-execute - - @param[in] Address Address of the page table entry -**/ -UINT64 -EFIAPI -GetSpitPageTableEntryNoExecute ( - IN PHYSICAL_ADDRESS Address - ); - -#endif // _MEM_ATTR_PROTOCOL_FUNC_TEST_APP_ diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf deleted file mode 100644 index 9ed535ee36..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/MemoryAttributeProtocolFuncTestApp.inf +++ /dev/null @@ -1,49 +0,0 @@ -## @file -# TCBZ3519 -# Uefi Shell based Application that unit tests the Memory Attribute Protocol. -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = MemoryAttributeProtocolFuncTestApp - FILE_GUID = bb7f9547-68db-4bf0-a247-c022c6146df3 - MODULE_TYPE = UEFI_APPLICATION - VERSION_STRING = 1.0 - ENTRY_POINT = UefiMain - -[Sources] - MemoryAttributeProtocolFuncTestApp.c - MemoryAttributeProtocolFuncTestApp.h - -[Sources.X64] - X64/PageSplitTest.c - -[Sources.IA32, Sources.ARM] - PageSplitTest.c - -[Sources.AARCH64] - AARCH64/PageSplitTest.c - -[Packages] - MdePkg/MdePkg.dec - UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec - -[Packages.AARCH64] - ArmPkg/ArmPkg.dec - -[LibraryClasses] - UefiApplicationEntryPoint - UnitTestLib - UefiBootServicesTableLib - DebugLib - -[LibraryClasses.AARCH64] - ArmLib - -[Guids] - -[Protocols] - gEfiMemoryAttributeProtocolGuid diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/PageSplitTest.c b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/PageSplitTest.c deleted file mode 100644 index d2d47a5f6a..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/PageSplitTest.c +++ /dev/null @@ -1,39 +0,0 @@ -/** @file MemoryAttributeProtocolFuncTestAppxAarch64.c -TCBZ3519 -Functionality to support MemoryAttributeProtocolFuncTestApp.c - -Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent -***/ - -#include "MemoryAttributeProtocolFuncTestApp.h" - -/** - Get an unsplit page table entry and allocate entire region so the page - doesn't need to be split on allocation - - @param[out] Address Address of allocated 2MB page region -**/ -EFI_STATUS -EFIAPI -GetUnsplitPageTableEntry ( - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Check if the 2MB page entry correlating with the input address - is set to no-execute - - @param[in] Address Address of the page table entry -**/ -UINT64 -EFIAPI -GetSpitPageTableEntryNoExecute ( - IN PHYSICAL_ADDRESS Address - ) -{ - return 0; -} diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/Readme.md b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/Readme.md deleted file mode 100644 index 43bbc3a8f9..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/Readme.md +++ /dev/null @@ -1,19 +0,0 @@ -# Memory Attribute Protocol UEFI shell functional Test - -## 🔹 Copyright - -Copyright (C) Microsoft Corporation. All rights reserved. -SPDX-License-Identifier: BSD-2-Clause-Patent - -## Attribution - -This test is a modified version of . - -## About This Test - -Tests does basic verification of the Memory Attribute Protocol - -* Make sure protocol exists -* Basic "good path" usage of Get/Clear/Set functions -* Get Attributes of a newly allocated EfiLoaderCode buffer -* Verify Attributes of running code (this test code) diff --git a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c b/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c deleted file mode 100644 index 857d05ec86..0000000000 --- a/MdePkg/Test/ShellTest/MemoryAttributeProtocolFuncTestApp/X64/PageSplitTest.c +++ /dev/null @@ -1,180 +0,0 @@ -/** @file PageSplitTest.c -TCBZ3519 -Functionality to support MemoryAttributeProtocolFuncTestApp.c - -Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent -***/ - -#include "MemoryAttributeProtocolFuncTestApp.h" - -#define PAGING_PAE_INDEX_MASK 0x1FF - -#pragma pack(1) - -// -// Page-Map Level-4 Offset (L4PageTable) and -// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB -// -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 Reserved : 1; // Reserved - UINT64 MustBeZero : 2; // Must Be Zero - UINT64 Available : 3; // Available for use by system software - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // No Execute bit - } Bits; - UINT64 Uint64; -} PAGE_MAP_AND_DIRECTORY_POINTER; - -// -// Page Table Entry 1GB -// -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 = written by processor on access to page - UINT64 MustBe1 : 1; // Must be 1 - UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available : 3; // Available for use by system software - UINT64 PAT : 1; // - UINT64 MustBeZero : 17; // Must be zero; - UINT64 PageTableBaseAddress : 22; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_1G_ENTRY; - -// -// Page Table Entry 2MB -// -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 = written by processor on access to page - UINT64 MustBe1 : 1; // Must be 1 - UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available : 3; // Available for use by system software - UINT64 PAT : 1; // - UINT64 MustBeZero : 8; // Must be zero; - UINT64 PageTableBaseAddress : 31; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_ENTRY; - -#pragma pack() - -/** - Get an unsplit page table entry and allocate entire region so the page - doesn't need to be split on allocation - - @param[out] Address Address of allocated 2MB page region -**/ -EFI_STATUS -EFIAPI -GetUnsplitPageTableEntry ( - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN Index2; - UINTN Index3; - UINTN Index4; - PAGE_MAP_AND_DIRECTORY_POINTER *Intermediate; - PAGE_MAP_AND_DIRECTORY_POINTER *L4PageTable; - PAGE_TABLE_1G_ENTRY *L3PageTable; - PAGE_TABLE_ENTRY *L2PageTable; - - L4PageTable = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(AsmReadCr3 ()); - - for (Index4 = 0x0; Index4 < 0x200; Index4++) { - if (!L4PageTable[Index4].Bits.Present) { - continue; - } - - L3PageTable = (PAGE_TABLE_1G_ENTRY *)(UINTN)(L4PageTable[Index4].Bits.PageTableBaseAddress << 12); - - for (Index3 = 0x0; Index3 < 0x200; Index3++ ) { - if (!L3PageTable[Index3].Bits.Present) { - continue; - } - - // - // MustBe1 indicates if the pointer is a directory pointer or a page table entry. - // - if (!(L3PageTable[Index3].Bits.MustBe1)) { - // - // We have to cast 1G and 2M directories to get all address bits. - // - Intermediate = (PAGE_MAP_AND_DIRECTORY_POINTER *)L3PageTable; - L2PageTable = (PAGE_TABLE_ENTRY *)(UINTN)(Intermediate[Index3].Bits.PageTableBaseAddress << 12); - - for (Index2 = 0x0; Index2 < 0x200; Index2++ ) { - if (L2PageTable[Index2].Bits.MustBe1) { - BaseAddress = (Index4 * PTE512GB) + (Index3 * PTE1GB) + (Index2 * PTE2MB); - Status = gBS->AllocatePages (AllocateAddress, EfiLoaderCode, EFI_SIZE_TO_PAGES (PTE2MB), &BaseAddress); - if (!EFI_ERROR (Status)) { - *Address = BaseAddress; - return EFI_SUCCESS; - } - } - } - } - } - } - - return EFI_OUT_OF_RESOURCES; -} - -/** - Check if the 2MB page entry correlating with the input address - is set to no-execute - - @param[in] Address Address of the page table entry -**/ -UINT64 -EFIAPI -GetSpitPageTableEntryNoExecute ( - IN PHYSICAL_ADDRESS Address - ) -{ - PAGE_MAP_AND_DIRECTORY_POINTER *Intermediate; - PAGE_MAP_AND_DIRECTORY_POINTER *L4PageTable; - PAGE_TABLE_1G_ENTRY *L3PageTable; - PAGE_TABLE_ENTRY *L2PageTable; - UINTN Index4; - UINTN Index3; - UINTN Index2; - - Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK; - Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK; - Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK; - - L4PageTable = (PAGE_MAP_AND_DIRECTORY_POINTER *)(UINTN)(AsmReadCr3 ()); - L3PageTable = (PAGE_TABLE_1G_ENTRY *)(UINTN)(L4PageTable[Index4].Bits.PageTableBaseAddress << 12); - Intermediate = (PAGE_MAP_AND_DIRECTORY_POINTER *)L3PageTable; - L2PageTable = (PAGE_TABLE_ENTRY *)(UINTN)(Intermediate[Index3].Bits.PageTableBaseAddress << 12); - - return L2PageTable[Index2].Bits.Nx; -}