From: Laszlo Ersek <lersek@redhat.com>
To: Brijesh Singh <brijesh.singh@amd.com>,
edk2-devel@lists.01.org, jordan.l.justen@intel.com
Cc: Thomas.Lendacky@amd.com, leo.duran@amd.com
Subject: Re: [PATCH v5 04/14] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library
Date: Wed, 24 May 2017 15:06:19 +0200 [thread overview]
Message-ID: <868ad318-c652-55c2-4b4c-eeeec2f826c6@redhat.com> (raw)
In-Reply-To: <1495466592-21641-5-git-send-email-brijesh.singh@amd.com>
On 05/22/17 17:23, 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 <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> ---
> 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 | 428 ++++++++++++++++++++
> 10 files changed, 1004 insertions(+)
I have some comments for the case if you have to post a v6. Right now a
v6 is not needed just for these comments.
(1) In
<http://mid.mail-archive.com/1d04baaa-95c4-492a-57a0-3d91aea02c36@redhat.com>
I mentioned
"Since this is a BASE library, please don't use EFI_STATUS,
EFI_INVALID_PARAMETER, EFI_NO_MAPPING, EFI_SUCCESS; use RETURN_xxx instead."
You replaced most of them, but you left in "EFI_STATUS". That should be
"RETURN_STATUS".
(2) please check the lines where you added (as I asked, thanks)
gEfiCallerBaseName and __FUNCTION__. On most lines, the indentation is
incorrect, relative to "DEBUG ((".
(3) Furthermore, in some spots where you added __FUNCTION__, you forgot
to add a space after the comma.
Again, no need to resubmit just because of this, but if you do resubmit
anyway, these should be fixed up.
Thanks
Laszlo
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index f3889c29f426..25b7d73807b6 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -143,6 +143,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 2aaa21f79e49..88bf73b3fa01 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -148,6 +148,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 b1e35942ba03..b34fed16a860 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -148,6 +148,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..808a386ca07a
> --- /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
> +**/
> +EFI_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
> +**/
> +EFI_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..fa103a531dfb
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
> @@ -0,0 +1,428 @@
> +/** @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
> +EFI_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
> +**/
> +EFI_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
> +**/
> +EFI_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);
> +}
>
next prev parent reply other threads:[~2017-05-24 13:06 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-22 15:22 [PATCH v5 00/14] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2017-05-22 15:22 ` [PATCH v5 01/14] UefiCpuPkg: Define AMD Memory Encryption specific CPUID and MSR Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 02/14] OvmfPkg/ResetVector: Set C-bit when building initial page table Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 03/14] OvmfPkg: Update dsc to use IoLib from BaseIoLibIntrinsicSev.inf Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 04/14] OvmfPkg/BaseMemcryptSevLib: Add SEV helper library Brijesh Singh
2017-05-24 13:06 ` Laszlo Ersek [this message]
2017-05-24 13:23 ` Brijesh Singh
2017-05-24 22:12 ` Brijesh Singh
2017-05-25 15:10 ` Laszlo Ersek
2017-05-25 18:23 ` Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 05/14] OvmfPkg/PlatformPei: Set memory encryption PCD when SEV is enabled Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 06/14] OvmfPkg:AmdSevDxe: Add AmdSevDxe driver Brijesh Singh
2017-05-24 14:17 ` Laszlo Ersek
2017-05-22 15:23 ` [PATCH v5 07/14] OvmfPkg:IoMmuDxe: Add IoMmuDxe driver Brijesh Singh
2017-05-24 15:09 ` Laszlo Ersek
2017-05-25 17:58 ` Laszlo Ersek
2017-05-25 18:56 ` Jordan Justen
2017-05-25 19:58 ` Laszlo Ersek
2017-05-22 15:23 ` [PATCH v5 08/14] OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 09/14] OvmfPkg/QemuFwCfgLib: Prepare for SEV support Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 10/14] OvmfPkg/QemuFwCfgLib: Implement SEV internal function for SEC phase Brijesh Singh
2017-05-24 13:17 ` Laszlo Ersek
2017-05-22 15:23 ` [PATCH v5 11/14] OvmfPkg/QemuFwCfgLib: Implement SEV internal functions for PEI phase Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 12/14] OvmfPkg/QemuFwCfgLib: Implement SEV internal function for Dxe phase Brijesh Singh
2017-05-24 13:45 ` Laszlo Ersek
2017-05-22 15:23 ` [PATCH v5 13/14] OvmfPkg/QemuFwCfgLib: Add option to dynamic alloc FW_CFG_DMA Access Brijesh Singh
2017-05-22 15:23 ` [PATCH v5 14/14] OvmfPkg/QemuFwCfgLib: Add SEV support Brijesh Singh
2017-05-24 13:55 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=868ad318-c652-55c2-4b4c-eeeec2f826c6@redhat.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox