1 /** @file 2 3 Virtual Memory Management Services to set or clear the memory encryption bit 4 5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> 6 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> 7 8 SPDX-License-Identifier: BSD-2-Clause-Patent 9 10 Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h 11 12 **/ 13 14 #ifndef __VIRTUAL_MEMORY__ 15 #define __VIRTUAL_MEMORY__ 16 17 #include <Library/BaseLib.h> 18 #include <Library/BaseMemoryLib.h> 19 #include <Library/CacheMaintenanceLib.h> 20 #include <Library/DebugLib.h> 21 #include <Library/MemoryAllocationLib.h> 22 #include <Uefi.h> 23 24 #define SYS_CODE64_SEL 0x38 25 26 #pragma pack(1) 27 28 // 29 // Page-Map Level-4 Offset (PML4) and 30 // Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB 31 // 32 33 typedef union { 34 struct { 35 UINT64 Present:1; // 0 = Not present in memory, 36 // 1 = Present in memory 37 UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write 38 UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User 39 UINT64 WriteThrough:1; // 0 = Write-Back caching, 40 // 1 = Write-Through caching 41 UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached 42 UINT64 Accessed:1; // 0 = Not accessed, 43 // 1 = Accessed (set by CPU) 44 UINT64 Reserved:1; // Reserved 45 UINT64 MustBeZero:2; // Must Be Zero 46 UINT64 Available:3; // Available for use by system software 47 UINT64 PageTableBaseAddress:40; // Page Table Base Address 48 UINT64 AvabilableHigh:11; // Available for use by system software 49 UINT64 Nx:1; // No Execute bit 50 } Bits; 51 UINT64 Uint64; 52 } PAGE_MAP_AND_DIRECTORY_POINTER; 53 54 // 55 // Page Table Entry 4KB 56 // 57 typedef union { 58 struct { 59 UINT64 Present:1; // 0 = Not present in memory, 60 // 1 = Present in memory 61 UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write 62 UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User 63 UINT64 WriteThrough:1; // 0 = Write-Back caching, 64 // 1 = Write-Through caching 65 UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached 66 UINT64 Accessed:1; // 0 = Not accessed, 67 // 1 = Accessed (set by CPU) 68 UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by 69 // processor on access to page 70 UINT64 PAT:1; // 71 UINT64 Global:1; // 0 = Not global page, 1 = global page 72 // TLB not cleared on CR3 write 73 UINT64 Available:3; // Available for use by system software 74 UINT64 PageTableBaseAddress:40; // Page Table Base Address 75 UINT64 AvabilableHigh:11; // Available for use by system software 76 UINT64 Nx:1; // 0 = Execute Code, 77 // 1 = No Code Execution 78 } Bits; 79 UINT64 Uint64; 80 } PAGE_TABLE_4K_ENTRY; 81 82 // 83 // Page Table Entry 2MB 84 // 85 typedef union { 86 struct { 87 UINT64 Present:1; // 0 = Not present in memory, 88 // 1 = Present in memory 89 UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write 90 UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User 91 UINT64 WriteThrough:1; // 0 = Write-Back caching, 92 // 1=Write-Through caching 93 UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached 94 UINT64 Accessed:1; // 0 = Not accessed, 95 // 1 = Accessed (set by CPU) 96 UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by 97 // processor on access to page 98 UINT64 MustBe1:1; // Must be 1 99 UINT64 Global:1; // 0 = Not global page, 1 = global page 100 // TLB not cleared on CR3 write 101 UINT64 Available:3; // Available for use by system software 102 UINT64 PAT:1; // 103 UINT64 MustBeZero:8; // Must be zero; 104 UINT64 PageTableBaseAddress:31; // Page Table Base Address 105 UINT64 AvabilableHigh:11; // Available for use by system software 106 UINT64 Nx:1; // 0 = Execute Code, 107 // 1 = No Code Execution 108 } Bits; 109 UINT64 Uint64; 110 } PAGE_TABLE_ENTRY; 111 112 // 113 // Page Table Entry 1GB 114 // 115 typedef union { 116 struct { 117 UINT64 Present:1; // 0 = Not present in memory, 118 // 1 = Present in memory 119 UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write 120 UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User 121 UINT64 WriteThrough:1; // 0 = Write-Back caching, 122 // 1 = Write-Through caching 123 UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached 124 UINT64 Accessed:1; // 0 = Not accessed, 125 // 1 = Accessed (set by CPU) 126 UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by 127 // processor on access to page 128 UINT64 MustBe1:1; // Must be 1 129 UINT64 Global:1; // 0 = Not global page, 1 = global page 130 // TLB not cleared on CR3 write 131 UINT64 Available:3; // Available for use by system software 132 UINT64 PAT:1; // 133 UINT64 MustBeZero:17; // Must be zero; 134 UINT64 PageTableBaseAddress:22; // Page Table Base Address 135 UINT64 AvabilableHigh:11; // Available for use by system software 136 UINT64 Nx:1; // 0 = Execute Code, 137 // 1 = No Code Execution 138 } Bits; 139 UINT64 Uint64; 140 } PAGE_TABLE_1G_ENTRY; 141 142 #pragma pack() 143 144 #define IA32_PG_P BIT0 145 #define IA32_PG_RW BIT1 146 #define IA32_PG_PS BIT7 147 148 #define PAGING_PAE_INDEX_MASK 0x1FF 149 150 #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull 151 #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull 152 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull 153 154 #define PAGING_L1_ADDRESS_SHIFT 12 155 #define PAGING_L2_ADDRESS_SHIFT 21 156 #define PAGING_L3_ADDRESS_SHIFT 30 157 #define PAGING_L4_ADDRESS_SHIFT 39 158 159 #define PAGING_PML4E_NUMBER 4 160 161 #define PAGETABLE_ENTRY_MASK ((1UL << 9) - 1) 162 #define PML4_OFFSET(x) ( (x >> 39) & PAGETABLE_ENTRY_MASK) 163 #define PDP_OFFSET(x) ( (x >> 30) & PAGETABLE_ENTRY_MASK) 164 #define PDE_OFFSET(x) ( (x >> 21) & PAGETABLE_ENTRY_MASK) 165 #define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK) 166 #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull 167 168 #define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB 169 #define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB 170 #define PAGE_TABLE_POOL_UNIT_PAGES \ 171 EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE) 172 #define PAGE_TABLE_POOL_ALIGN_MASK \ 173 (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1)) 174 175 typedef struct { 176 VOID *NextPool; 177 UINTN Offset; 178 UINTN FreePages; 179 } PAGE_TABLE_POOL; 180 181 182 183 /** 184 This function clears memory encryption bit for the memory region specified by 185 PhysicalAddress and Length from the current page table context. 186 187 @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use 188 current CR3) 189 @param[in] PhysicalAddress The physical address that is the start 190 address of a memory region. 191 @param[in] Length The length of memory region 192 @param[in] Flush Flush the caches before applying the 193 encryption mask 194 195 @retval RETURN_SUCCESS The attributes were cleared for the 196 memory region. 197 @retval RETURN_INVALID_PARAMETER Number of pages is zero. 198 @retval RETURN_UNSUPPORTED Clearing the memory encyrption attribute 199 is not supported 200 **/ 201 RETURN_STATUS 202 EFIAPI 203 InternalMemEncryptSevSetMemoryDecrypted ( 204 IN PHYSICAL_ADDRESS Cr3BaseAddress, 205 IN PHYSICAL_ADDRESS PhysicalAddress, 206 IN UINTN Length, 207 IN BOOLEAN Flush 208 ); 209 210 /** 211 This function sets memory encryption bit for the memory region specified by 212 PhysicalAddress and Length from the current page table context. 213 214 @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use 215 current CR3) 216 @param[in] PhysicalAddress The physical address that is the start 217 address of a memory region. 218 @param[in] Length The length of memory region 219 @param[in] Flush Flush the caches before applying the 220 encryption mask 221 222 @retval RETURN_SUCCESS The attributes were set for the memory 223 region. 224 @retval RETURN_INVALID_PARAMETER Number of pages is zero. 225 @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute 226 is not supported 227 **/ 228 RETURN_STATUS 229 EFIAPI 230 InternalMemEncryptSevSetMemoryEncrypted ( 231 IN PHYSICAL_ADDRESS Cr3BaseAddress, 232 IN PHYSICAL_ADDRESS PhysicalAddress, 233 IN UINTN Length, 234 IN BOOLEAN Flush 235 ); 236 237 #endif 238