/** @file Virtual Memory Management Services to set or clear the memory encryption bit Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h **/ #ifndef __VIRTUAL_MEMORY__ #define __VIRTUAL_MEMORY__ #include #include #include #include #include #include #define SYS_CODE64_SEL 0x38 #pragma pack(1) // // Page-Map Level-4 Offset (PML4) 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 AvabilableHigh:11; // Available for use by system software UINT64 Nx:1; // No Execute bit } Bits; UINT64 Uint64; } PAGE_MAP_AND_DIRECTORY_POINTER; // // Page Table Entry 4KB // 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 PAT: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 PageTableBaseAddress:40; // Page Table Base Address UINT64 AvabilableHigh:11; // Available for use by system software UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution } Bits; UINT64 Uint64; } PAGE_TABLE_4K_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 AvabilableHigh:11; // Available for use by system software UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution } Bits; UINT64 Uint64; } PAGE_TABLE_ENTRY; // // 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 AvabilableHigh:11; // Available for use by system software UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution } Bits; UINT64 Uint64; } PAGE_TABLE_1G_ENTRY; #pragma pack() #define IA32_PG_P BIT0 #define IA32_PG_RW BIT1 #define PAGETABLE_ENTRY_MASK ((1UL << 9) - 1) #define PML4_OFFSET(x) ( (x >> 39) & PAGETABLE_ENTRY_MASK) #define PDP_OFFSET(x) ( (x >> 30) & PAGETABLE_ENTRY_MASK) #define PDE_OFFSET(x) ( (x >> 21) & PAGETABLE_ENTRY_MASK) #define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK) #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull /** This function clears memory encryption bit for the memory region specified by PhysicalAddress and length from the current page table context. @param[in] PhysicalAddress The physical address that is the start address of a memory region. @param[in] Length The length of memory region @param[in] Flush Flush the caches before applying the encryption mask @retval RETURN_SUCCESS The attributes were cleared for the memory region. @retval RETURN_INVALID_PARAMETER Number of pages is zero. @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute is not supported **/ RETURN_STATUS EFIAPI InternalMemEncryptSevSetMemoryDecrypted ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINT64 Length, IN BOOLEAN CacheFlush ); /** This function sets memory encryption bit for the memory region specified by PhysicalAddress and length from the current page table context. @param[in] PhysicalAddress The physical address that is the start address of a memory region. @param[in] Length The length of memory region @param[in] Flush Flush the caches before applying the encryption mask @retval RETURN_SUCCESS The attributes were cleared for the memory region. @retval RETURN_INVALID_PARAMETER Number of pages is zero. @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute is not supported **/ RETURN_STATUS EFIAPI InternalMemEncryptSevSetMemoryEncrypted ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINT64 Length, IN BOOLEAN CacheFlush ); #endif