Agree. Per my understanding this driver is only needed for virtualization firmware, it is not needed for a real platform firmware. Putting it to OVMF makes more sense.
Thank you Yao Jiewen From: Brijesh Singh [mailto:[email protected]] Sent: Saturday, May 27, 2017 5:07 AM To: Justen, Jordan L <[email protected]>; Yao, Jiewen <[email protected]>; Fan, Jeff <[email protected]>; [email protected] Cc: [email protected]; [email protected]; [email protected]; Laszlo Ersek <[email protected]> Subject: Re: [PATCH v6 04/17] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library Hi Jordan, I don't have any strong feeling on where this lib should go, but since SEV (Secure Encrypted Virtualization) feature is applicable only when are building/booting the OVMF platform hence I thought OVMF is the right place for it. Thanks Brijesh On 05/26/2017 03:54 PM, Jordan Justen wrote: > Jiewen, Jeff, Brijesh, > > Is there a reason this shouldn't go under UefiCpuPkg rather than > OvmfPkg? > > -Jordan > > On 2017-05-26 07:43:52, Brijesh Singh wrote: >> Add Secure Encrypted Virtualization (SEV) helper library. >> The library provides the routines to: >> - set or clear memory encryption bit for a given memory region. >> - query whether SEV is enabled. >> >> >> Cc: Jordan Justen >> <[email protected]<mailto:[email protected]>> >> Cc: Laszlo Ersek <[email protected]<mailto:[email protected]>> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Brijesh Singh >> <[email protected]<mailto:[email protected]>> >> Reviewed-by: Laszlo Ersek <[email protected]<mailto:[email protected]>> >> --- >> OvmfPkg/OvmfPkgIa32.dsc | 1 + >> OvmfPkg/OvmfPkgIa32X64.dsc | 1 + >> OvmfPkg/OvmfPkgX64.dsc | 1 + >> OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf | 50 +++ >> OvmfPkg/Include/Library/MemEncryptSevLib.h | 81 ++++ >> OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h | 184 >> ++++++++ >> OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c | 84 ++++ >> OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c | 90 ++++ >> OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 84 ++++ >> OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c | 439 >> ++++++++++++++++++++ >> 10 files changed, 1015 insertions(+) >> >> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc >> index b5c874b65afc..98691c0a6d99 100644 >> --- a/OvmfPkg/OvmfPkgIa32.dsc >> +++ b/OvmfPkg/OvmfPkgIa32.dsc >> @@ -145,6 +145,7 @@ [LibraryClasses] >> QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf >> VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf >> LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf >> + >> MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf >> !if $(SMM_REQUIRE) == FALSE >> LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf >> !endif >> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc >> index 1d071cac2bef..3b51513a4d95 100644 >> --- a/OvmfPkg/OvmfPkgIa32X64.dsc >> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc >> @@ -150,6 +150,7 @@ [LibraryClasses] >> QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf >> VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf >> LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf >> + >> MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf >> !if $(SMM_REQUIRE) == FALSE >> LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf >> !endif >> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc >> index 2bea75437788..ebf07cd585dd 100644 >> --- a/OvmfPkg/OvmfPkgX64.dsc >> +++ b/OvmfPkg/OvmfPkgX64.dsc >> @@ -150,6 +150,7 @@ [LibraryClasses] >> QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf >> VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf >> LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf >> + >> MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf >> !if $(SMM_REQUIRE) == FALSE >> LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf >> !endif >> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf >> b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf >> new file mode 100644 >> index 000000000000..3cfd80a28c1d >> --- /dev/null >> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf >> @@ -0,0 +1,50 @@ >> +## @file >> +# Library provides the helper functions for SEV guest >> +# >> +# Copyright (c) 2017 Advanced Micro Devices. All rights reserved.<BR> >> +# >> +# 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. >> +# >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 1.25 >> + BASE_NAME = MemEncryptSevLib >> + FILE_GUID = c1594631-3888-4be4-949f-9c630dbc842b >> + MODULE_TYPE = BASE >> + VERSION_STRING = 1.0 >> + LIBRARY_CLASS = MemEncryptSevLib|PEIM DXE_DRIVER >> DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER >> + >> +# >> +# The following information is for reference only and not required by the >> build tools. >> +# >> +# VALID_ARCHITECTURES = IA32 X64 >> +# >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + MdeModulePkg/MdeModulePkg.dec >> + OvmfPkg/OvmfPkg.dec >> + UefiCpuPkg/UefiCpuPkg.dec >> + >> +[Sources.X64] >> + MemEncryptSevLibInternal.c >> + X64/MemEncryptSevLib.c >> + X64/VirtualMemory.c >> + >> +[Sources.IA32] >> + MemEncryptSevLibInternal.c >> + Ia32/MemEncryptSevLib.c >> + >> +[LibraryClasses] >> + BaseLib >> + CpuLib >> + CacheMaintenanceLib >> + DebugLib >> + MemoryAllocationLib >> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h >> b/OvmfPkg/Include/Library/MemEncryptSevLib.h >> new file mode 100644 >> index 000000000000..b6753762423e >> --- /dev/null >> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h >> @@ -0,0 +1,81 @@ >> +/** @file >> + >> + Define Secure Encrypted Virtualization (SEV) base library helper function >> + >> + Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> >> + >> + 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. >> + >> +**/ >> + >> +#ifndef _MEM_ENCRYPT_SEV_LIB_H_ >> +#define _MEM_ENCRYPT_SEV_LIB_H_ >> + >> +#include <Base.h> >> + >> +/** >> + Returns a boolean to indicate whether SEV is enabled >> + >> + @retval TRUE SEV is active >> + @retval FALSE SEV is not enabled >> + **/ >> +BOOLEAN >> +EFIAPI >> +MemEncryptSevIsEnabled ( >> + VOID >> + ); >> + >> +/** >> + This function clears memory encryption bit for the memory region specified >> + by BaseAddress and Number of pages from the current page table context. >> + >> + @param[in] BaseAddress The physical address that is the start >> address >> + of a memory region. >> + @param[in] NumberOfPages The number of pages from start memory >> region. >> + @param[in] Flush Flush the caches before clearing the bit >> + (mostly TRUE except MMIO addresses) >> + >> + @retval RETURN_SUCCESS The attributes were cleared for the >> memory region. >> + @retval RETURN_INVALID_PARAMETER Number of pages is zero. >> + @retval RETURN_UNSUPPORTED Clearing memory encryption attribute is >> not >> + supported >> + **/ >> +RETURN_STATUS >> +EFIAPI >> +MemEncryptSevClearPageEncMask ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS BaseAddress, >> + IN UINTN NumberOfPages, >> + IN BOOLEAN CacheFlush >> + ); >> + >> +/** >> + This function sets memory encryption bit for the memory region specified >> by >> + BaseAddress and Number of pages from the current page table context. >> + >> + @param[in] BaseAddress The physical address that is the start >> address >> + of a memory region. >> + @param[in] NumberOfPages The number of pages from start memory >> region. >> + @param[in] Flush Flush the caches before clearing the bit >> + (mostly TRUE except MMIO addresses) >> + >> + @retval RETURN_SUCCESS The attributes were set for the memory >> region. >> + @retval RETURN_INVALID_PARAMETER Number of pages is zero. >> + @retval RETURN_UNSUPPORTED Clearing memory encryption attribute is >> not >> + supported >> + **/ >> +RETURN_STATUS >> +EFIAPI >> +MemEncryptSevSetPageEncMask ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS BaseAddress, >> + IN UINTN NumberOfPages, >> + IN BOOLEAN CacheFlush >> + ); >> +#endif // _MEM_ENCRYPT_SEV_LIB_H_ >> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h >> b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h >> new file mode 100644 >> index 000000000000..70cd2187a326 >> --- /dev/null >> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h >> @@ -0,0 +1,184 @@ >> +/** @file >> + >> + Virtual Memory Management Services to set or clear the memory encryption >> bit >> + >> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> >> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> >> + >> +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 <Uefi.h> >> +#include <Library/BaseLib.h> >> +#include <Library/BaseMemoryLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/MemoryAllocationLib.h> >> + >> +#include <Library/CacheMaintenanceLib.h> >> +#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 >> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c >> b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c >> new file mode 100644 >> index 000000000000..a2ea99019917 >> --- /dev/null >> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c >> @@ -0,0 +1,84 @@ >> +/** @file >> + >> + Secure Encrypted Virtualization (SEV) library helper function >> + >> + Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> >> + >> + 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. >> + >> +**/ >> + >> +#include <Library/BaseLib.h> >> +#include <Library/DebugLib.h> >> +#include <Register/Cpuid.h> >> +#include <Register/Amd/Cpuid.h> >> +#include <Register/Amd/Msr.h> >> +#include <Library/MemEncryptSevLib.h> >> + >> +/** >> + This function clears memory encryption bit for the memory region specified >> + by BaseAddress and Number of pages from the current page table context. >> + >> + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use >> current CR3) >> + @param[in] BaseAddress The physical address that is the start >> address >> + of a memory region. >> + @param[in] NumberOfPages The number of pages from start memory >> region. >> + @param[in] Flush Flush the caches before clearing the bit >> + (mostly TRUE except MMIO addresses) >> + >> + @retval RETURN_SUCCESS The attributes were cleared for the >> memory region. >> + @retval RETURN_INVALID_PARAMETER Number of pages is zero. >> + @retval RETURN_UNSUPPORTED Clearing memory encryption attribute is >> not >> + supported >> + **/ >> +RETURN_STATUS >> +EFIAPI >> +MemEncryptSevClearPageEncMask ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS BaseAddress, >> + IN UINTN NumberOfPages, >> + IN BOOLEAN Flush >> + ) >> +{ >> + // >> + // Memory encryption bit is not accessible in 32-bit mode >> + // >> + return RETURN_UNSUPPORTED; >> +} >> + >> +/** >> + This function sets memory encryption bit for the memory region specified >> by >> + BaseAddress and Number of pages from the current page table context. >> + >> + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use >> current CR3) >> + @param[in] BaseAddress The physical address that is the start >> address >> + of a memory region. >> + @param[in] NumberOfPages The number of pages from start memory >> region. >> + @param[in] Flush Flush the caches before clearing the bit >> + (mostly TRUE except MMIO addresses) >> + >> + @retval RETURN_SUCCESS The attributes were set for the memory >> region. >> + @retval RETURN_INVALID_PARAMETER Number of pages is zero. >> + @retval RETURN_UNSUPPORTED Clearing memory encryption attribute is >> not >> + supported >> + **/ >> +RETURN_STATUS >> +EFIAPI >> +MemEncryptSevSetPageEncMask ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS BaseAddress, >> + IN UINTN NumberOfPages, >> + IN BOOLEAN Flush >> + ) >> +{ >> + // >> + // Memory encryption bit is not accessible in 32-bit mode >> + // >> + return RETURN_UNSUPPORTED; >> +} >> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c >> b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c >> new file mode 100644 >> index 000000000000..002f079c7eb3 >> --- /dev/null >> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c >> @@ -0,0 +1,90 @@ >> +/** @file >> + >> + Secure Encrypted Virtualization (SEV) library helper function >> + >> + Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> >> + >> + 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. >> + >> +**/ >> + >> +#include <Library/BaseLib.h> >> +#include <Library/DebugLib.h> >> +#include <Register/Cpuid.h> >> +#include <Register/Amd/Cpuid.h> >> +#include <Register/Amd/Msr.h> >> +#include <Library/MemEncryptSevLib.h> >> + >> +STATIC BOOLEAN mSevStatus = FALSE; >> +STATIC BOOLEAN mSevStatusChecked = FALSE; >> + >> +/** >> + >> + Returns a boolean to indicate whether SEV is enabled >> + >> + @retval TRUE SEV is enabled >> + @retval FALSE SEV is not enabled >> + **/ >> +STATIC >> +BOOLEAN >> +EFIAPI >> +InternalMemEncryptSevIsEnabled ( >> + VOID >> + ) >> +{ >> + UINT32 RegEax; >> + MSR_SEV_STATUS_REGISTER Msr; >> + CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax; >> + >> + // >> + // Check if memory encryption leaf exist >> + // >> + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); >> + if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) { >> + // >> + // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported) >> + // >> + AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL); >> + >> + if (Eax.Bits.SevBit) { >> + // >> + // Check MSR_0xC0010131 Bit 0 (Sev Enabled) >> + // >> + Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS); >> + if (Msr.Bits.SevBit) { >> + return TRUE; >> + } >> + } >> + } >> + >> + return FALSE; >> +} >> + >> +/** >> + >> + Returns a boolean to indicate whether SEV is enabled >> + >> + @retval TRUE SEV is enabled >> + @retval FALSE SEV is not enabled >> + **/ >> +BOOLEAN >> +EFIAPI >> +MemEncryptSevIsEnabled ( >> + VOID >> + ) >> +{ >> + if (mSevStatusChecked) { >> + return mSevStatus; >> + } >> + >> + mSevStatus = InternalMemEncryptSevIsEnabled(); >> + mSevStatusChecked = TRUE; >> + >> + return mSevStatus; >> +} >> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c >> b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c >> new file mode 100644 >> index 000000000000..9ec76708bd7b >> --- /dev/null >> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c >> @@ -0,0 +1,84 @@ >> +/** @file >> + >> + Secure Encrypted Virtualization (SEV) library helper function >> + >> + Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> >> + >> + 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. >> + >> +**/ >> + >> +#include <Library/BaseLib.h> >> +#include <Library/DebugLib.h> >> +#include <Register/Cpuid.h> >> +#include <Register/Amd/Cpuid.h> >> +#include <Register/Amd/Msr.h> >> +#include <Library/MemEncryptSevLib.h> >> + >> +#include "VirtualMemory.h" >> + >> +/** >> + >> + This function clears memory encryption bit for the memory region >> specified by >> + BaseAddress and Number of pages from the current page table context. >> + >> + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use >> current CR3) >> + @param[in] BaseAddress The physical address that is the >> start address >> + of a memory region. >> + @param[in] NumberOfPages The number of pages from start memory >> region. >> + @param[in] Flush Flush the caches before clearing the >> bit >> + (mostly TRUE except MMIO addresses) >> + >> + @retval RETURN_SUCCESS The attributes were cleared for the >> memory >> + region. >> + @retval RETURN_INVALID_PARAMETER Number of pages is zero. >> + @retval RETURN_UNSUPPORTED Clearing the memory encryption >> attribute is >> + not supported >> + **/ >> +RETURN_STATUS >> +EFIAPI >> +MemEncryptSevClearPageEncMask ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS BaseAddress, >> + IN UINTN NumPages, >> + IN BOOLEAN Flush >> + ) >> +{ >> + return InternalMemEncryptSevSetMemoryDecrypted (Cr3BaseAddress, >> BaseAddress, EFI_PAGES_TO_SIZE(NumPages), Flush); >> +} >> + >> +/** >> + >> + This function clears memory encryption bit for the memory region >> specified by >> + BaseAddress and Number of pages from the current page table context. >> + >> + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use >> current CR3) >> + @param[in] BaseAddress The physical address that is the >> start address >> + of a memory region. >> + @param[in] NumberOfPages The number of pages from start memory >> region. >> + @param[in] Flush Flush the caches before clearing the >> bit >> + (mostly TRUE except MMIO addresses) >> + >> + @retval RETURN_SUCCESS The attributes were cleared for the >> memory >> + region. >> + @retval RETURN_INVALID_PARAMETER Number of pages is zero. >> + @retval RETURN_UNSUPPORTED Clearing the memory encryption >> attribute is >> + not supported >> + **/ >> +RETURN_STATUS >> +EFIAPI >> +MemEncryptSevSetPageEncMask ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS BaseAddress, >> + IN UINTN NumPages, >> + IN BOOLEAN Flush >> + ) >> +{ >> + return InternalMemEncryptSevSetMemoryEncrypted (Cr3BaseAddress, >> BaseAddress, EFI_PAGES_TO_SIZE(NumPages), Flush); >> +} >> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c >> b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c >> new file mode 100644 >> index 000000000000..7cbbf915f443 >> --- /dev/null >> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c >> @@ -0,0 +1,439 @@ >> +/** @file >> + >> + Virtual Memory Management Services to set or clear the memory encryption >> bit >> + >> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> >> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> >> + >> +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.c >> + >> +**/ >> + >> +#include <Library/CpuLib.h> >> +#include <Register/Cpuid.h> >> +#include <Register/Amd/Cpuid.h> >> + >> +#include "VirtualMemory.h" >> + >> +STATIC BOOLEAN mAddressEncMaskChecked = FALSE; >> +STATIC UINT64 mAddressEncMask; >> + >> +typedef enum { >> + SetCBit, >> + ClearCBit >> +} MAP_RANGE_MODE; >> + >> +/** >> + Get the memory encryption mask >> + >> + @param[out] EncryptionMask contains the pte mask. >> + >> +**/ >> +STATIC >> +UINT64 >> +GetMemEncryptionAddressMask ( >> + VOID >> + ) >> +{ >> + UINT64 EncryptionMask; >> + CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx; >> + >> + if (mAddressEncMaskChecked) { >> + return mAddressEncMask; >> + } >> + >> + // >> + // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position) >> + // >> + AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL); >> + EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits); >> + >> + mAddressEncMask = EncryptionMask & PAGING_1G_ADDRESS_MASK_64; >> + mAddressEncMaskChecked = TRUE; >> + >> + return mAddressEncMask; >> +} >> + >> +/** >> + Split 2M page to 4K. >> + >> + @param[in] PhysicalAddress Start physical address the 2M page >> covered. >> + @param[in, out] PageEntry2M Pointer to 2M page entry. >> + @param[in] StackBase Stack base address. >> + @param[in] StackSize Stack size. >> + >> +**/ >> +STATIC >> +VOID >> +Split2MPageTo4K ( >> + IN PHYSICAL_ADDRESS PhysicalAddress, >> + IN OUT UINT64 *PageEntry2M, >> + IN PHYSICAL_ADDRESS StackBase, >> + IN UINTN StackSize >> + ) >> +{ >> + PHYSICAL_ADDRESS PhysicalAddress4K; >> + UINTN IndexOfPageTableEntries; >> + PAGE_TABLE_4K_ENTRY *PageTableEntry, *PageTableEntry1; >> + UINT64 AddressEncMask; >> + >> + PageTableEntry = AllocatePages(1); >> + >> + PageTableEntry1 = PageTableEntry; >> + >> + AddressEncMask = GetMemEncryptionAddressMask (); >> + >> + ASSERT (PageTableEntry != NULL); >> + ASSERT (*PageEntry2M & AddressEncMask); >> + >> + PhysicalAddress4K = PhysicalAddress; >> + for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; >> IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) { >> + // >> + // Fill in the Page Table entries >> + // >> + PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask; >> + PageTableEntry->Bits.ReadWrite = 1; >> + PageTableEntry->Bits.Present = 1; >> + if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase >> + StackSize)) { >> + // >> + // Set Nx bit for stack. >> + // >> + PageTableEntry->Bits.Nx = 1; >> + } >> + } >> + >> + // >> + // Fill in 2M page entry. >> + // >> + *PageEntry2M = (UINT64) (UINTN) PageTableEntry1 | IA32_PG_P | IA32_PG_RW >> | AddressEncMask; >> +} >> + >> +/** >> + Split 1G page to 2M. >> + >> + @param[in] PhysicalAddress Start physical address the 1G page >> covered. >> + @param[in, out] PageEntry1G Pointer to 1G page entry. >> + @param[in] StackBase Stack base address. >> + @param[in] StackSize Stack size. >> + >> +**/ >> +STATIC >> +VOID >> +Split1GPageTo2M ( >> + IN PHYSICAL_ADDRESS PhysicalAddress, >> + IN OUT UINT64 *PageEntry1G, >> + IN PHYSICAL_ADDRESS StackBase, >> + IN UINTN StackSize >> + ) >> +{ >> + PHYSICAL_ADDRESS PhysicalAddress2M; >> + UINTN IndexOfPageDirectoryEntries; >> + PAGE_TABLE_ENTRY *PageDirectoryEntry; >> + UINT64 AddressEncMask; >> + >> + PageDirectoryEntry = AllocatePages(1); >> + >> + AddressEncMask = GetMemEncryptionAddressMask (); >> + ASSERT (PageDirectoryEntry != NULL); >> + ASSERT (*PageEntry1G & GetMemEncryptionAddressMask ()); >> + // >> + // Fill in 1G page entry. >> + // >> + *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | IA32_PG_P | >> IA32_PG_RW | AddressEncMask; >> + >> + PhysicalAddress2M = PhysicalAddress; >> + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; >> IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += >> SIZE_2MB) { >> + if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M >> + SIZE_2MB) > StackBase)) { >> + // >> + // Need to split this 2M page that covers stack range. >> + // >> + Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, >> StackBase, StackSize); >> + } else { >> + // >> + // Fill in the Page Directory entries >> + // >> + PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | >> AddressEncMask; >> + PageDirectoryEntry->Bits.ReadWrite = 1; >> + PageDirectoryEntry->Bits.Present = 1; >> + PageDirectoryEntry->Bits.MustBe1 = 1; >> + } >> + } >> +} >> + >> + >> +/** >> + Set or Clear the memory encryption bit >> + >> + @param[in] PagetablePoint Page table entry pointer (PTE). >> + @param[in] Mode Set or Clear encryption bit >> + >> +**/ >> +STATIC VOID >> +SetOrClearCBit( >> + IN OUT UINT64* PageTablePointer, >> + IN MAP_RANGE_MODE Mode >> + ) >> +{ >> + UINT64 AddressEncMask; >> + >> + AddressEncMask = GetMemEncryptionAddressMask (); >> + >> + if (Mode == SetCBit) { >> + *PageTablePointer |= AddressEncMask; >> + } else { >> + *PageTablePointer &= ~AddressEncMask; >> + } >> + >> +} >> + >> +/** >> + This function either sets or clears memory encryption bit for the memory >> region >> + specified by PhysicalAddress and length from the current page table >> context. >> + >> + The function iterates through the physicalAddress one page at a time, and >> set >> + or clears the memory encryption mask in the page table. If it encounters >> + that a given physical address range is part of large page then it >> attempts to >> + change the attribute at one go (based on size), otherwise it splits the >> + large pages into smaller (e.g 2M page into 4K pages) and then try to set >> or >> + clear the encryption bit on the smallest page size. >> + >> + @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] Mode Set or Clear mode >> + @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 >> +**/ >> + >> +STATIC >> +RETURN_STATUS >> +EFIAPI >> +SetMemoryEncDec ( >> + IN PHYSICAL_ADDRESS Cr3BaseAddress, >> + IN PHYSICAL_ADDRESS PhysicalAddress, >> + IN UINTN Length, >> + IN MAP_RANGE_MODE Mode, >> + IN BOOLEAN CacheFlush >> + ) >> +{ >> + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; >> + PAGE_MAP_AND_DIRECTORY_POINTER *PageUpperDirectoryPointerEntry; >> + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; >> + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; >> + PAGE_TABLE_ENTRY *PageDirectory2MEntry; >> + PAGE_TABLE_4K_ENTRY *PageTableEntry; >> + UINT64 PgTableMask; >> + UINT64 AddressEncMask; >> + >> + // >> + // Check if we have a valid memory encryption mask >> + // >> + AddressEncMask = GetMemEncryptionAddressMask (); >> + if (!AddressEncMask) { >> + return RETURN_ACCESS_DENIED; >> + } >> + >> + PgTableMask = AddressEncMask | EFI_PAGE_MASK; >> + >> + if (Length == 0) { >> + return RETURN_INVALID_PARAMETER; >> + } >> + >> + // >> + // We are going to change the memory encryption attribute from C=0 -> C=1 >> or >> + // vice versa Flush the caches to ensure that data is written into memory >> with >> + // correct C-bit >> + // >> + if (CacheFlush) { >> + WriteBackInvalidateDataCacheRange((VOID*) (UINTN)PhysicalAddress, >> Length); >> + } >> + >> + while (Length) >> + { >> + // >> + // If Cr3BaseAddress is not specified then read the current CR3 >> + // >> + if (Cr3BaseAddress == 0) { >> + Cr3BaseAddress = AsmReadCr3(); >> + } >> + >> + PageMapLevel4Entry = (VOID*) (Cr3BaseAddress & ~PgTableMask); >> + PageMapLevel4Entry += PML4_OFFSET(PhysicalAddress); >> + if (!PageMapLevel4Entry->Bits.Present) { >> + DEBUG ((DEBUG_WARN, >> + "%a:%a ERROR bad PML4 for %lx\n", gEfiCallerBaseName, __FUNCTION__, >> + PhysicalAddress)); >> + return RETURN_NO_MAPPING; >> + } >> + >> + PageDirectory1GEntry = (VOID*) >> ((PageMapLevel4Entry->Bits.PageTableBaseAddress<<12) & ~PgTableMask); >> + PageDirectory1GEntry += PDP_OFFSET(PhysicalAddress); >> + if (!PageDirectory1GEntry->Bits.Present) { >> + DEBUG ((DEBUG_WARN, >> + "%a:%a ERROR bad PDPE for %lx\n", gEfiCallerBaseName, >> + __FUNCTION__, PhysicalAddress)); >> + return RETURN_NO_MAPPING; >> + } >> + >> + // >> + // If the MustBe1 bit is not 1, it's not actually a 1GB entry >> + // >> + if (PageDirectory1GEntry->Bits.MustBe1) { >> + // >> + // Valid 1GB page >> + // If we have at least 1GB to go, we can just update this entry >> + // >> + if (!(PhysicalAddress & (BIT30 - 1)) && Length >= BIT30) { >> + SetOrClearCBit(&PageDirectory1GEntry->Uint64, Mode); >> + DEBUG ((DEBUG_VERBOSE, >> + "%a:%a Updated 1GB entry for %lx\n", gEfiCallerBaseName, >> + __FUNCTION__, PhysicalAddress)); >> + PhysicalAddress += BIT30; >> + Length -= BIT30; >> + } else { >> + // >> + // We must split the page >> + // >> + DEBUG ((DEBUG_VERBOSE, >> + "%a:%a Spliting 1GB page\n", gEfiCallerBaseName, __FUNCTION__)); >> + >> Split1GPageTo2M(((UINT64)PageDirectory1GEntry->Bits.PageTableBaseAddress)<<30, >> (UINT64*) PageDirectory1GEntry, 0, 0); >> + continue; >> + } >> + } else { >> + // >> + // Actually a PDP >> + // >> + PageUpperDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER*) >> PageDirectory1GEntry; >> + PageDirectory2MEntry = (VOID*) >> ((PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress<<12) & >> ~PgTableMask); >> + PageDirectory2MEntry += PDE_OFFSET(PhysicalAddress); >> + if (!PageDirectory2MEntry->Bits.Present) { >> + DEBUG ((DEBUG_WARN, >> + "%a:%a ERROR bad PDE for %lx\n", gEfiCallerBaseName, __FUNCTION__, >> + PhysicalAddress)); >> + return RETURN_NO_MAPPING; >> + } >> + // >> + // If the MustBe1 bit is not a 1, it's not a 2MB entry >> + // >> + if (PageDirectory2MEntry->Bits.MustBe1) { >> + // >> + // Valid 2MB page >> + // If we have at least 2MB left to go, we can just update this entry >> + // >> + if (!(PhysicalAddress & (BIT21-1)) && Length >= BIT21) { >> + SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode); >> + PhysicalAddress += BIT21; >> + Length -= BIT21; >> + } else { >> + // >> + // We must split up this page into 4K pages >> + // >> + DEBUG ((DEBUG_VERBOSE, >> + "%a:%a Spliting 2MB page at %lx\n", >> gEfiCallerBaseName,__FUNCTION__, >> + PhysicalAddress)); >> + Split2MPageTo4K >> (((UINT64)PageDirectory2MEntry->Bits.PageTableBaseAddress) << 21, (UINT64*) >> PageDirectory2MEntry, 0, 0); >> + continue; >> + } >> + } else { >> + PageDirectoryPointerEntry = (PAGE_MAP_AND_DIRECTORY_POINTER*) >> PageDirectory2MEntry; >> + PageTableEntry = (VOID*) >> (PageDirectoryPointerEntry->Bits.PageTableBaseAddress<<12 & ~PgTableMask); >> + PageTableEntry += PTE_OFFSET(PhysicalAddress); >> + if (!PageTableEntry->Bits.Present) { >> + DEBUG ((DEBUG_WARN, >> + "%a:%a ERROR bad PTE for %lx\n", gEfiCallerBaseName, >> + __FUNCTION__, PhysicalAddress)); >> + return RETURN_NO_MAPPING; >> + } >> + SetOrClearCBit (&PageTableEntry->Uint64, Mode); >> + PhysicalAddress += EFI_PAGE_SIZE; >> + Length -= EFI_PAGE_SIZE; >> + } >> + } >> + } >> + >> + // >> + // Flush TLB >> + // >> + CpuFlushTlb(); >> + >> + return RETURN_SUCCESS; >> +} >> + >> +/** >> + 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 UINTN Length, >> + IN BOOLEAN Flush >> + ) >> +{ >> + >> + DEBUG ((DEBUG_VERBOSE, >> + "%a:%a Clear C-bit Cr3 %Lx Base %Lx Length %Lx flush %d\n", >> + gEfiCallerBaseName, __FUNCTION__, Cr3BaseAddress, PhysicalAddress, >> Length, >> + Flush)); >> + return SetMemoryEncDec (Cr3BaseAddress, PhysicalAddress, Length, >> ClearCBit, Flush); >> +} >> + >> +/** >> + 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 UINTN Length, >> + IN BOOLEAN Flush >> + ) >> +{ >> + DEBUG ((DEBUG_VERBOSE, >> + "%a:%a Set C-bit Cr3 %Lx Base %Lx Length %Lx flush %d\n", >> + gEfiCallerBaseName, __FUNCTION__, Cr3BaseAddress, PhysicalAddress, >> Length, >> + Flush)); >> + return SetMemoryEncDec (Cr3BaseAddress, PhysicalAddress, Length, SetCBit, >> Flush); >> +} >> -- >> 2.7.4 >> _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

