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 - 2020, 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 Return the pagetable memory encryption mask. 183 184 @return The pagetable memory encryption mask. 185 186 **/ 187 UINT64 188 EFIAPI 189 InternalGetMemEncryptionAddressMask ( 190 VOID 191 ); 192 193 /** 194 This function clears memory encryption bit for the memory region specified by 195 PhysicalAddress and Length from the current page table context. 196 197 @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use 198 current CR3) 199 @param[in] PhysicalAddress The physical address that is the start 200 address of a memory region. 201 @param[in] Length The length of memory region 202 @param[in] Flush Flush the caches before applying the 203 encryption mask 204 205 @retval RETURN_SUCCESS The attributes were cleared for the 206 memory region. 207 @retval RETURN_INVALID_PARAMETER Number of pages is zero. 208 @retval RETURN_UNSUPPORTED Clearing the memory encyrption attribute 209 is not supported 210 **/ 211 RETURN_STATUS 212 EFIAPI 213 InternalMemEncryptSevSetMemoryDecrypted ( 214 IN PHYSICAL_ADDRESS Cr3BaseAddress, 215 IN PHYSICAL_ADDRESS PhysicalAddress, 216 IN UINTN Length, 217 IN BOOLEAN Flush 218 ); 219 220 /** 221 This function sets memory encryption bit for the memory region specified by 222 PhysicalAddress and Length from the current page table context. 223 224 @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use 225 current CR3) 226 @param[in] PhysicalAddress The physical address that is the start 227 address of a memory region. 228 @param[in] Length The length of memory region 229 @param[in] Flush Flush the caches before applying the 230 encryption mask 231 232 @retval RETURN_SUCCESS The attributes were set for the memory 233 region. 234 @retval RETURN_INVALID_PARAMETER Number of pages is zero. 235 @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute 236 is not supported 237 **/ 238 RETURN_STATUS 239 EFIAPI 240 InternalMemEncryptSevSetMemoryEncrypted ( 241 IN PHYSICAL_ADDRESS Cr3BaseAddress, 242 IN PHYSICAL_ADDRESS PhysicalAddress, 243 IN UINTN Length, 244 IN BOOLEAN Flush 245 ); 246 247 /** 248 Returns the encryption state of the specified virtual address range. 249 250 @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use 251 current CR3) 252 @param[in] BaseAddress Base address to check 253 @param[in] Length Length of virtual address range 254 255 @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped 256 unencrypted 257 @retval MemEncryptSevAddressRangeEncrypted Address range is mapped 258 encrypted 259 @retval MemEncryptSevAddressRangeMixed Address range is mapped mixed 260 @retval MemEncryptSevAddressRangeError Address range is not mapped 261 **/ 262 MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE 263 EFIAPI 264 InternalMemEncryptSevGetAddressRangeState ( 265 IN PHYSICAL_ADDRESS Cr3BaseAddress, 266 IN PHYSICAL_ADDRESS BaseAddress, 267 IN UINTN Length 268 ); 269 270 #endif 271