From nobody Sat Jul 12 09:24:34 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1519949059580600.8812842503625; Thu, 1 Mar 2018 16:04:19 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 7A398224C0F38; Thu, 1 Mar 2018 15:58:06 -0800 (PST) Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 935EC22485A98 for ; Thu, 1 Mar 2018 15:58:05 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E115E4084FEC; Fri, 2 Mar 2018 00:04:13 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-4.rdu2.redhat.com [10.10.120.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id B11B310EE987; Fri, 2 Mar 2018 00:04:12 +0000 (UTC) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org From: Laszlo Ersek To: edk2-devel-01 Date: Fri, 2 Mar 2018 01:03:49 +0100 Message-Id: <20180302000408.14201-2-lersek@redhat.com> In-Reply-To: <20180302000408.14201-1-lersek@redhat.com> References: <20180302000408.14201-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Fri, 02 Mar 2018 00:04:13 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Fri, 02 Mar 2018 00:04:13 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'lersek@redhat.com' RCPT:'' Subject: [edk2] [PATCH 01/20] OvmfPkg/MemEncryptSevLib: rewrap to 79 characters width X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jordan Justen , Brijesh Singh , Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" There are many overlong lines; it's hard to work with the library like this. Rewrap all files to 79 columns. Cc: Ard Biesheuvel Cc: Brijesh Singh Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek --- OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf | 7 +- OvmfPkg/Include/Library/MemEncryptSevLib.h | 20 ++- OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h | 111 ++++= ++++------ OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c | 34 +++-- OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c | 8 +- OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 58 ++++= --- OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c | 158 ++++= +++++++++------- 7 files changed, 253 insertions(+), 143 deletions(-) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf = b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf index 3cfd80a28c1d..81b075194ace 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf @@ -1,45 +1,48 @@ ## @file # Library provides the helper functions for SEV guest # # Copyright (c) 2017 Advanced Micro Devices. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the B= SD # License which accompanies this distribution. The full text of the licen= se # 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 IM= PLIED. +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR +# IMPLIED. # # ## =20 [Defines] INF_VERSION =3D 1.25 BASE_NAME =3D MemEncryptSevLib FILE_GUID =3D c1594631-3888-4be4-949f-9c630dbc842b MODULE_TYPE =3D BASE VERSION_STRING =3D 1.0 LIBRARY_CLASS =3D MemEncryptSevLib|PEIM DXE_DRIVER DXE_= RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER =20 # -# The following information is for reference only and not required by the = build tools. +# The following information is for reference only and not required by the = build +# tools. # # VALID_ARCHITECTURES =3D IA32 X64 # =20 [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec =20 [Sources.X64] MemEncryptSevLibInternal.c X64/MemEncryptSevLib.c X64/VirtualMemory.c =20 [Sources.IA32] MemEncryptSevLibInternal.c Ia32/MemEncryptSevLib.c =20 [LibraryClasses] diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/L= ibrary/MemEncryptSevLib.h index b6753762423e..4f3ba9f22cb4 100644 --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h @@ -18,64 +18,68 @@ #define _MEM_ENCRYPT_SEV_LIB_H_ =20 #include =20 /** Returns a boolean to indicate whether SEV is enabled =20 @retval TRUE SEV is active @retval FALSE SEV is not enabled **/ BOOLEAN EFIAPI MemEncryptSevIsEnabled ( VOID ); =20 /** This function clears memory encryption bit for the memory region specifi= ed by BaseAddress and Number of pages from the current page table context. =20 - @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] 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 b= it (mostly TRUE except MMIO addresses) =20 - @retval RETURN_SUCCESS The attributes were cleared for the me= mory region. + @retval RETURN_SUCCESS The attributes were cleared for the me= mory + region. @retval RETURN_INVALID_PARAMETER Number of pages is zero. @retval RETURN_UNSUPPORTED Clearing memory encryption attribute i= s not supported **/ RETURN_STATUS EFIAPI MemEncryptSevClearPageEncMask ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumberOfPages, IN BOOLEAN CacheFlush ); =20 /** This function sets memory encryption bit for the memory region specified= by BaseAddress and Number of pages from the current page table context. =20 - @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] 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 b= it (mostly TRUE except MMIO addresses) =20 - @retval RETURN_SUCCESS The attributes were set for the memory= region. + @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 i= s 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/Ovm= fPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h index e7b5634b45c1..7dd1bbe0eb26 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h @@ -1,212 +1,239 @@ /** @file =20 Virtual Memory Management Services to set or clear the memory encryption= bit =20 -Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
-Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 -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 + This program and the accompanying materials are licensed and made availa= ble + 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 =20 -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. =20 -Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h + Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h =20 **/ =20 #ifndef __VIRTUAL_MEMORY__ #define __VIRTUAL_MEMORY__ =20 #include #include #include #include #include =20 #include #define SYS_CODE64_SEL 0x38 =20 #pragma pack(1) =20 // // Page-Map Level-4 Offset (PML4) and // Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB // =20 typedef union { struct { - UINT64 Present:1; // 0 =3D Not present in memory, 1 = =3D Present in memory + UINT64 Present:1; // 0 =3D Not present in memory, + // 1 =3D Present in memory UINT64 ReadWrite:1; // 0 =3D Read-Only, 1=3D Read/Write UINT64 UserSupervisor:1; // 0 =3D Supervisor, 1=3DUser - UINT64 WriteThrough:1; // 0 =3D Write-Back caching, 1=3DWri= te-Through caching + UINT64 WriteThrough:1; // 0 =3D Write-Back caching, + // 1 =3D Write-Through caching UINT64 CacheDisabled:1; // 0 =3D Cached, 1=3DNon-Cached - UINT64 Accessed:1; // 0 =3D Not accessed, 1 =3D Accesse= d (set by CPU) + UINT64 Accessed:1; // 0 =3D Not accessed, + // 1 =3D Accessed (set by CPU) UINT64 Reserved:1; // Reserved UINT64 MustBeZero:2; // Must Be Zero UINT64 Available:3; // Available for use by system softw= are UINT64 PageTableBaseAddress:40; // Page Table Base Address UINT64 AvabilableHigh:11; // Available for use by system softw= are UINT64 Nx:1; // No Execute bit } Bits; UINT64 Uint64; } PAGE_MAP_AND_DIRECTORY_POINTER; =20 // // Page Table Entry 4KB // typedef union { struct { - UINT64 Present:1; // 0 =3D Not present in memory, 1 = =3D Present in memory + UINT64 Present:1; // 0 =3D Not present in memory, + // 1 =3D Present in memory UINT64 ReadWrite:1; // 0 =3D Read-Only, 1=3D Read/Write UINT64 UserSupervisor:1; // 0 =3D Supervisor, 1=3DUser - UINT64 WriteThrough:1; // 0 =3D Write-Back caching, 1=3DWri= te-Through caching + UINT64 WriteThrough:1; // 0 =3D Write-Back caching, + // 1 =3D Write-Through caching UINT64 CacheDisabled:1; // 0 =3D Cached, 1=3DNon-Cached - UINT64 Accessed:1; // 0 =3D Not accessed, 1 =3D Accesse= d (set by CPU) - UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D written by= processor on access to page + UINT64 Accessed:1; // 0 =3D Not accessed, + // 1 =3D Accessed (set by CPU) + UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D written by + // processor on access to page UINT64 PAT:1; // - UINT64 Global:1; // 0 =3D Not global page, 1 =3D glob= al page TLB not cleared on CR3 write + UINT64 Global:1; // 0 =3D Not global page, 1 =3D glob= al page + // TLB not cleared on CR3 write UINT64 Available:3; // Available for use by system softw= are UINT64 PageTableBaseAddress:40; // Page Table Base Address UINT64 AvabilableHigh:11; // Available for use by system softw= are - UINT64 Nx:1; // 0 =3D Execute Code, 1 =3D No Code= Execution + UINT64 Nx:1; // 0 =3D Execute Code, + // 1 =3D No Code Execution } Bits; UINT64 Uint64; } PAGE_TABLE_4K_ENTRY; =20 // // Page Table Entry 2MB // typedef union { struct { - UINT64 Present:1; // 0 =3D Not present in memory, 1 = =3D Present in memory + UINT64 Present:1; // 0 =3D Not present in memory, + // 1 =3D Present in memory UINT64 ReadWrite:1; // 0 =3D Read-Only, 1=3D Read/Write UINT64 UserSupervisor:1; // 0 =3D Supervisor, 1=3DUser - UINT64 WriteThrough:1; // 0 =3D Write-Back caching, 1=3DWri= te-Through caching + UINT64 WriteThrough:1; // 0 =3D Write-Back caching, + // 1=3DWrite-Through caching UINT64 CacheDisabled:1; // 0 =3D Cached, 1=3DNon-Cached - UINT64 Accessed:1; // 0 =3D Not accessed, 1 =3D Accesse= d (set by CPU) - UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D written by= processor on access to page + UINT64 Accessed:1; // 0 =3D Not accessed, + // 1 =3D Accessed (set by CPU) + UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D written by + // processor on access to page UINT64 MustBe1:1; // Must be 1 - UINT64 Global:1; // 0 =3D Not global page, 1 =3D glob= al page TLB not cleared on CR3 write + UINT64 Global:1; // 0 =3D Not global page, 1 =3D glob= al page + // TLB not cleared on CR3 write UINT64 Available:3; // Available for use by system softw= are UINT64 PAT:1; // UINT64 MustBeZero:8; // Must be zero; UINT64 PageTableBaseAddress:31; // Page Table Base Address UINT64 AvabilableHigh:11; // Available for use by system softw= are - UINT64 Nx:1; // 0 =3D Execute Code, 1 =3D No Code= Execution + UINT64 Nx:1; // 0 =3D Execute Code, + // 1 =3D No Code Execution } Bits; UINT64 Uint64; } PAGE_TABLE_ENTRY; =20 // // Page Table Entry 1GB // typedef union { struct { - UINT64 Present:1; // 0 =3D Not present in memory, 1 = =3D Present in memory + UINT64 Present:1; // 0 =3D Not present in memory, + // 1 =3D Present in memory UINT64 ReadWrite:1; // 0 =3D Read-Only, 1=3D Read/Write UINT64 UserSupervisor:1; // 0 =3D Supervisor, 1=3DUser - UINT64 WriteThrough:1; // 0 =3D Write-Back caching, 1=3DWri= te-Through caching + UINT64 WriteThrough:1; // 0 =3D Write-Back caching, + // 1 =3D Write-Through caching UINT64 CacheDisabled:1; // 0 =3D Cached, 1=3DNon-Cached - UINT64 Accessed:1; // 0 =3D Not accessed, 1 =3D Accesse= d (set by CPU) - UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D written by= processor on access to page + UINT64 Accessed:1; // 0 =3D Not accessed, + // 1 =3D Accessed (set by CPU) + UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D written by + // processor on access to page UINT64 MustBe1:1; // Must be 1 - UINT64 Global:1; // 0 =3D Not global page, 1 =3D glob= al page TLB not cleared on CR3 write + UINT64 Global:1; // 0 =3D Not global page, 1 =3D glob= al page + // TLB not cleared on CR3 write UINT64 Available:3; // Available for use by system softw= are UINT64 PAT:1; // UINT64 MustBeZero:17; // Must be zero; UINT64 PageTableBaseAddress:22; // Page Table Base Address UINT64 AvabilableHigh:11; // Available for use by system softw= are - UINT64 Nx:1; // 0 =3D Execute Code, 1 =3D No Code= Execution + UINT64 Nx:1; // 0 =3D Execute Code, + // 1 =3D No Code Execution } Bits; UINT64 Uint64; } PAGE_TABLE_1G_ENTRY; =20 #pragma pack() =20 #define IA32_PG_P BIT0 #define IA32_PG_RW BIT1 #define IA32_PG_PS BIT7 =20 #define PAGING_PAE_INDEX_MASK 0x1FF =20 #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull =20 #define PAGING_L1_ADDRESS_SHIFT 12 #define PAGING_L2_ADDRESS_SHIFT 21 #define PAGING_L3_ADDRESS_SHIFT 30 #define PAGING_L4_ADDRESS_SHIFT 39 =20 #define PAGING_PML4E_NUMBER 4 =20 #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 =20 #define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB #define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB -#define PAGE_TABLE_POOL_UNIT_PAGES EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNI= T_SIZE) +#define PAGE_TABLE_POOL_UNIT_PAGES \ + EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE) #define PAGE_TABLE_POOL_ALIGN_MASK \ (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1)) =20 typedef struct { VOID *NextPool; UINTN Offset; UINTN FreePages; } PAGE_TABLE_POOL; =20 =20 =20 /** - This function clears memory encryption bit for the memory region specifi= ed by PhysicalAddress - and length from the current page table context. + This function clears memory encryption bit for the memory region specifi= ed by + PhysicalAddress and length from the current page table context. =20 - @param[in] PhysicalAddress The physical address that is the sta= rt address of a memory region. + @param[in] PhysicalAddress The physical address that is the sta= rt + address of a memory region. @param[in] Length The length of memory region - @param[in] Flush Flush the caches before applying the= encryption mask + @param[in] Flush Flush the caches before applying the + encryption mask =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory region. + @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 attrib= ute is not supported + @retval RETURN_UNSUPPORTED Setting the memory encyrption attrib= ute + is not supported **/ RETURN_STATUS EFIAPI InternalMemEncryptSevSetMemoryDecrypted ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINT64 Length, IN BOOLEAN CacheFlush ); =20 /** This function sets memory encryption bit for the memory region specified= by PhysicalAddress and length from the current page table context. =20 - @param[in] PhysicalAddress The physical address that is the sta= rt address - of a memory region. + @param[in] PhysicalAddress The physical address that is the sta= rt + address of a memory region. @param[in] Length The length of memory region @param[in] Flush Flush the caches before applying the encryption mask =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory region. + @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 attrib= ute is - not supported + @retval RETURN_UNSUPPORTED Setting the memory encyrption attrib= ute + is not supported **/ RETURN_STATUS EFIAPI InternalMemEncryptSevSetMemoryEncrypted ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINT64 Length, IN BOOLEAN CacheFlush ); =20 #endif diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b= /OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c index a2ea99019917..d1130df2d0e7 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c @@ -1,84 +1,90 @@ /** @file =20 Secure Encrypted Virtualization (SEV) library helper function =20 Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 - 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 licen= se may - be found at http://opensource.org/licenses/bsd-license.php + This program and the accompanying materials are licensed and made availa= ble + 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 =20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. =20 **/ =20 #include #include #include #include #include #include =20 /** This function clears memory encryption bit for the memory region specifi= ed by BaseAddress and Number of pages from the current page table context. =20 - @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use cur= rent 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] Cr3BaseAddress Cr3 Base Address (if zero then use cur= rent + 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 b= it (mostly TRUE except MMIO addresses) =20 - @retval RETURN_SUCCESS The attributes were cleared for the me= mory region. + @retval RETURN_SUCCESS The attributes were cleared for the me= mory + region. @retval RETURN_INVALID_PARAMETER Number of pages is zero. @retval RETURN_UNSUPPORTED Clearing memory encryption attribute i= s 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; } =20 /** This function sets memory encryption bit for the memory region specified= by BaseAddress and Number of pages from the current page table context. =20 - @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use cur= rent 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] Cr3BaseAddress Cr3 Base Address (if zero then use cur= rent + 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 b= it (mostly TRUE except MMIO addresses) =20 - @retval RETURN_SUCCESS The attributes were set for the memory= region. + @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 i= s 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 index 002f079c7eb3..ff561236d819 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c @@ -1,30 +1,30 @@ /** @file =20 Secure Encrypted Virtualization (SEV) library helper function =20 Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 - 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 licen= se may - be found at http://opensource.org/licenses/bsd-license.php + This program and the accompanying materials are licensed and made availa= ble + 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 =20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. =20 **/ =20 #include #include #include #include #include #include =20 STATIC BOOLEAN mSevStatus =3D FALSE; STATIC BOOLEAN mSevStatusChecked =3D FALSE; =20 /** =20 Returns a boolean to indicate whether SEV is enabled =20 diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/= OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c index 9ec76708bd7b..4b7fdf7d044d 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c @@ -1,84 +1,98 @@ /** @file =20 Secure Encrypted Virtualization (SEV) library helper function =20 Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 - 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 licen= se may - be found at http://opensource.org/licenses/bsd-license.php + This program and the accompanying materials are licensed and made availa= ble + 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 =20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. =20 **/ =20 #include #include #include #include #include #include =20 #include "VirtualMemory.h" =20 /** =20 This function clears memory encryption bit for the memory region specifi= ed by BaseAddress and Number of pages from the current page table context. =20 - @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use c= urrent CR3) - @param[in] BaseAddress The physical address that is the sta= rt address - of a memory region. - @param[in] NumberOfPages The number of pages from start memor= y region. + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress The physical address that is the sta= rt + 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) =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory - region. + @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 attri= bute is - not supported + @retval RETURN_UNSUPPORTED Clearing the memory encryption attri= bute + is not supported **/ RETURN_STATUS EFIAPI MemEncryptSevClearPageEncMask ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages, IN BOOLEAN Flush ) { - return InternalMemEncryptSevSetMemoryDecrypted (Cr3BaseAddress, BaseAddr= ess, EFI_PAGES_TO_SIZE(NumPages), Flush); + return InternalMemEncryptSevSetMemoryDecrypted ( + Cr3BaseAddress, + BaseAddress, + EFI_PAGES_TO_SIZE (NumPages), + Flush + ); } =20 /** =20 This function clears memory encryption bit for the memory region specifi= ed by BaseAddress and Number of pages from the current page table context. =20 - @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use c= urrent CR3) - @param[in] BaseAddress The physical address that is the sta= rt address - of a memory region. - @param[in] NumberOfPages The number of pages from start memor= y region. + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress The physical address that is the sta= rt + 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) =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory - region. + @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 attri= bute is - not supported + @retval RETURN_UNSUPPORTED Clearing the memory encryption attri= bute + is not supported **/ RETURN_STATUS EFIAPI MemEncryptSevSetPageEncMask ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages, IN BOOLEAN Flush ) { - return InternalMemEncryptSevSetMemoryEncrypted (Cr3BaseAddress, BaseAddr= ess, EFI_PAGES_TO_SIZE(NumPages), Flush); + return InternalMemEncryptSevSetMemoryEncrypted ( + Cr3BaseAddress, + BaseAddress, + EFI_PAGES_TO_SIZE (NumPages), + Flush + ); } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c b/Ovm= fPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c index 4185874c99b8..65b8babaac44 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c @@ -1,36 +1,36 @@ /** @file =20 Virtual Memory Management Services to set or clear the memory encryption= bit =20 -Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
-Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Incorporated. All rights reserved.
=20 -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 + This program and the accompanying materials are licensed and made availa= ble + 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 =20 -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. =20 -Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c + Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c =20 **/ =20 #include #include #include =20 #include "VirtualMemory.h" =20 STATIC BOOLEAN mAddressEncMaskChecked =3D FALSE; STATIC UINT64 mAddressEncMask; STATIC PAGE_TABLE_POOL *mPageTablePool =3D NULL; =20 typedef enum { SetCBit, ClearCBit } MAP_RANGE_MODE; =20 /** Get the memory encryption mask @@ -52,45 +52,46 @@ GetMemEncryptionAddressMask ( } =20 // // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position) // AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL); EncryptionMask =3D LShiftU64 (1, Ebx.Bits.PtePosBits); =20 mAddressEncMask =3D EncryptionMask & PAGING_1G_ADDRESS_MASK_64; mAddressEncMaskChecked =3D TRUE; =20 return mAddressEncMask; } =20 /** Initialize a buffer pool for page table use only. =20 To reduce the potential split operation on page table, the pages reserve= d for page table should be allocated in the times of PAGE_TABLE_POOL_UNIT_PAGE= S and at the boundary of PAGE_TABLE_POOL_ALIGNMENT. So the page pool is always - initialized with number of pages greater than or equal to the given Pool= Pages. + initialized with number of pages greater than or equal to the given + PoolPages. =20 Once the pages in the pool are used up, this method should be called aga= in to - reserve at least another PAGE_TABLE_POOL_UNIT_PAGES. Usually this won't = happen - often in practice. + reserve at least another PAGE_TABLE_POOL_UNIT_PAGES. Usually this won't + happen often in practice. =20 @param[in] PoolPages The least page number of the pool to be create= d. =20 @retval TRUE The pool is initialized successfully. @retval FALSE The memory is out of resource. **/ STATIC BOOLEAN InitializePageTablePool ( IN UINTN PoolPages ) { VOID *Buffer; =20 // // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one pag= e for // header. // PoolPages +=3D 1; // Add one page for header. PoolPages =3D ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) * @@ -166,89 +167,96 @@ AllocatePageTableMemory ( =20 mPageTablePool->Offset +=3D EFI_PAGES_TO_SIZE (Pages); mPageTablePool->FreePages -=3D Pages; =20 DEBUG (( DEBUG_VERBOSE, "%a:%a: Buffer=3D0x%Lx Pages=3D%ld\n", gEfiCallerBaseName, __FUNCTION__, Buffer, Pages )); =20 return Buffer; } =20 =20 /** Split 2M page to 4K. =20 - @param[in] PhysicalAddress Start physical address the 2M page= covered. + @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. =20 **/ 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; =20 PageTableEntry =3D AllocatePageTableMemory(1); =20 PageTableEntry1 =3D PageTableEntry; =20 AddressEncMask =3D GetMemEncryptionAddressMask (); =20 ASSERT (PageTableEntry !=3D NULL); ASSERT (*PageEntry2M & AddressEncMask); =20 PhysicalAddress4K =3D PhysicalAddress; - for (IndexOfPageTableEntries =3D 0; IndexOfPageTableEntries < 512; Index= OfPageTableEntries++, PageTableEntry++, PhysicalAddress4K +=3D SIZE_4KB) { + for (IndexOfPageTableEntries =3D 0; + IndexOfPageTableEntries < 512; + (IndexOfPageTableEntries++, + PageTableEntry++, + PhysicalAddress4K +=3D SIZE_4KB)) { // // Fill in the Page Table entries // PageTableEntry->Uint64 =3D (UINT64) PhysicalAddress4K | AddressEncMask; PageTableEntry->Bits.ReadWrite =3D 1; PageTableEntry->Bits.Present =3D 1; - if ((PhysicalAddress4K >=3D StackBase) && (PhysicalAddress4K < StackBa= se + StackSize)) { + if ((PhysicalAddress4K >=3D StackBase) && + (PhysicalAddress4K < StackBase + StackSize)) { // // Set Nx bit for stack. // PageTableEntry->Bits.Nx =3D 1; } } =20 // // Fill in 2M page entry. // - *PageEntry2M =3D (UINT64) (UINTN) PageTableEntry1 | IA32_PG_P | IA32_PG_= RW | AddressEncMask; + *PageEntry2M =3D ((UINT64)(UINTN)PageTableEntry1 | + IA32_PG_P | IA32_PG_RW | AddressEncMask); } =20 /** Set one page of page table pool memory to be read-only. =20 @param[in] PageTableBase Base address of page table (CR3). @param[in] Address Start address of a page to be set as read-on= ly. @param[in] Level4Paging Level 4 paging flag. =20 **/ STATIC VOID SetPageTablePoolReadOnly ( IN UINTN PageTableBase, IN EFI_PHYSICAL_ADDRESS Address, IN BOOLEAN Level4Paging ) { UINTN Index; UINTN EntryIndex; @@ -374,96 +382,108 @@ EnablePageTableProtection ( PAGE_TABLE_POOL *HeadPool; PAGE_TABLE_POOL *Pool; UINT64 PoolSize; EFI_PHYSICAL_ADDRESS Address; =20 if (mPageTablePool =3D=3D NULL) { return; } =20 // // SetPageTablePoolReadOnly might update mPageTablePool. It's safer to // remember original one in advance. // HeadPool =3D mPageTablePool; Pool =3D HeadPool; do { Address =3D (EFI_PHYSICAL_ADDRESS)(UINTN)Pool; PoolSize =3D Pool->Offset + EFI_PAGES_TO_SIZE (Pool->FreePages); =20 // - // The size of one pool must be multiple of PAGE_TABLE_POOL_UNIT_SIZE,= which - // is one of page size of the processor (2MB by default). Let's apply = the - // protection to them one by one. + // The size of one pool must be multiple of PAGE_TABLE_POOL_UNIT_SIZE, + // which is one of page size of the processor (2MB by default). Let's = apply + // the protection to them one by one. // while (PoolSize > 0) { SetPageTablePoolReadOnly(PageTableBase, Address, Level4Paging); Address +=3D PAGE_TABLE_POOL_UNIT_SIZE; PoolSize -=3D PAGE_TABLE_POOL_UNIT_SIZE; } =20 Pool =3D Pool->NextPool; } while (Pool !=3D HeadPool); =20 } =20 =20 /** Split 1G page to 2M. =20 - @param[in] PhysicalAddress Start physical address the 1G page= covered. + @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. =20 **/ 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; =20 PageDirectoryEntry =3D AllocatePageTableMemory(1); =20 AddressEncMask =3D GetMemEncryptionAddressMask (); ASSERT (PageDirectoryEntry !=3D NULL); ASSERT (*PageEntry1G & GetMemEncryptionAddressMask ()); // // Fill in 1G page entry. // - *PageEntry1G =3D (UINT64) (UINTN) PageDirectoryEntry | IA32_PG_P | IA32_= PG_RW | AddressEncMask; + *PageEntry1G =3D ((UINT64)(UINTN)PageDirectoryEntry | + IA32_PG_P | IA32_PG_RW | AddressEncMask); =20 PhysicalAddress2M =3D PhysicalAddress; - for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries < 51= 2; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += =3D SIZE_2MB) { - if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M= + SIZE_2MB) > StackBase)) { + for (IndexOfPageDirectoryEntries =3D 0; + IndexOfPageDirectoryEntries < 512; + (IndexOfPageDirectoryEntries++, + PageDirectoryEntry++, + PhysicalAddress2M +=3D SIZE_2MB)) { + if ((PhysicalAddress2M < StackBase + StackSize) && + ((PhysicalAddress2M + SIZE_2MB) > StackBase)) { // // Need to split this 2M page that covers stack range. // - Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, S= tackBase, StackSize); + Split2MPageTo4K ( + PhysicalAddress2M, + (UINT64 *)PageDirectoryEntry, + StackBase, + StackSize + ); } else { // // Fill in the Page Directory entries // PageDirectoryEntry->Uint64 =3D (UINT64) PhysicalAddress2M | AddressE= ncMask; PageDirectoryEntry->Bits.ReadWrite =3D 1; PageDirectoryEntry->Bits.Present =3D 1; PageDirectoryEntry->Bits.MustBe1 =3D 1; } } } =20 =20 /** Set or Clear the memory encryption bit =20 @param[in] PagetablePoint Page table entry pointer (PTE). @param[in] Mode Set or Clear encryption bit =20 **/ @@ -510,62 +530,63 @@ VOID DisableReadOnlyPageWriteProtect ( VOID ) { AsmWriteCr0 (AsmReadCr0() & ~BIT16); } =20 /** Enable Write Protect on pages marked as read-only. **/ VOID EnableReadOnlyPageWriteProtect ( VOID ) { AsmWriteCr0 (AsmReadCr0() | BIT16); } =20 =20 /** - This function either sets or clears memory encryption bit for the memory= region - specified by PhysicalAddress and length from the current page table cont= ext. + This function either sets or clears memory encryption bit for the memory + region specified by PhysicalAddress and length from the current page tab= le + context. =20 The function iterates through the physicalAddress one page at a time, an= d 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 attemp= ts 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. =20 @param[in] PhysicalAddress The physical address that is the sta= rt 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 =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory - region. + @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 attrib= ute is - not supported + @retval RETURN_UNSUPPORTED Setting the memory encyrption attrib= ute + is not supported **/ =20 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; @@ -584,81 +605,84 @@ SetMemoryEncDec ( (Mode =3D=3D SetCBit) ? "Encrypt" : "Decrypt", (UINT32)CacheFlush )); =20 // // Check if we have a valid memory encryption mask // AddressEncMask =3D GetMemEncryptionAddressMask (); if (!AddressEncMask) { return RETURN_ACCESS_DENIED; } =20 PgTableMask =3D AddressEncMask | EFI_PAGE_MASK; =20 if (Length =3D=3D 0) { return RETURN_INVALID_PARAMETER; } =20 // // We are going to change the memory encryption attribute from C=3D0 -> = C=3D1 or - // vice versa Flush the caches to ensure that data is written into memor= y with - // correct C-bit + // vice versa Flush the caches to ensure that data is written into memory + // with correct C-bit // if (CacheFlush) { WriteBackInvalidateDataCacheRange((VOID*) (UINTN)PhysicalAddress, Leng= th); } =20 // // Make sure that the page table is changeable. // IsWpEnabled =3D IsReadOnlyPageWriteProtected (); if (IsWpEnabled) { DisableReadOnlyPageWriteProtect (); } =20 Status =3D EFI_SUCCESS; =20 while (Length) { // // If Cr3BaseAddress is not specified then read the current CR3 // if (Cr3BaseAddress =3D=3D 0) { Cr3BaseAddress =3D AsmReadCr3(); } =20 PageMapLevel4Entry =3D (VOID*) (Cr3BaseAddress & ~PgTableMask); PageMapLevel4Entry +=3D PML4_OFFSET(PhysicalAddress); if (!PageMapLevel4Entry->Bits.Present) { DEBUG (( DEBUG_ERROR, "%a:%a: bad PML4 for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); Status =3D RETURN_NO_MAPPING; goto Done; } =20 - PageDirectory1GEntry =3D (VOID*) ((PageMapLevel4Entry->Bits.PageTableB= aseAddress<<12) & ~PgTableMask); + PageDirectory1GEntry =3D (VOID *)( + (PageMapLevel4Entry->Bits.PageTableBaseAddres= s << + 12) & ~PgTableMask + ); PageDirectory1GEntry +=3D PDP_OFFSET(PhysicalAddress); if (!PageDirectory1GEntry->Bits.Present) { DEBUG (( DEBUG_ERROR, "%a:%a: bad PDPE for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); Status =3D RETURN_NO_MAPPING; goto Done; } =20 // // 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 @@ -668,90 +692,110 @@ SetMemoryEncDec ( DEBUG (( DEBUG_VERBOSE, "%a:%a: updated 1GB entry for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); PhysicalAddress +=3D BIT30; Length -=3D BIT30; } else { // // We must split the page // DEBUG (( DEBUG_VERBOSE, "%a:%a: splitting 1GB page for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); - Split1GPageTo2M(((UINT64)PageDirectory1GEntry->Bits.PageTableBaseA= ddress)<<30, (UINT64*) PageDirectory1GEntry, 0, 0); + Split1GPageTo2M ( + (UINT64)PageDirectory1GEntry->Bits.PageTableBaseAddress << 30, + (UINT64 *)PageDirectory1GEntry, + 0, + 0 + ); continue; } } else { // // Actually a PDP // - PageUpperDirectoryPointerEntry =3D (PAGE_MAP_AND_DIRECTORY_POINTER*)= PageDirectory1GEntry; - PageDirectory2MEntry =3D (VOID*) ((PageUpperDirectoryPointerEntry->B= its.PageTableBaseAddress<<12) & ~PgTableMask); + PageUpperDirectoryPointerEntry =3D + (PAGE_MAP_AND_DIRECTORY_POINTER *)PageDirectory1GEntry; + PageDirectory2MEntry =3D + (VOID *)( + (PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress << + 12) & ~PgTableMask + ); PageDirectory2MEntry +=3D PDE_OFFSET(PhysicalAddress); if (!PageDirectory2MEntry->Bits.Present) { DEBUG (( DEBUG_ERROR, "%a:%a: bad PDE for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); Status =3D RETURN_NO_MAPPING; goto Done; } // // 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 ent= ry // if (!(PhysicalAddress & (BIT21-1)) && Length >=3D BIT21) { SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode); PhysicalAddress +=3D BIT21; Length -=3D BIT21; } else { // // We must split up this page into 4K pages // DEBUG (( DEBUG_VERBOSE, "%a:%a: splitting 2MB page for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); - Split2MPageTo4K (((UINT64)PageDirectory2MEntry->Bits.PageTableBa= seAddress) << 21, (UINT64*) PageDirectory2MEntry, 0, 0); + Split2MPageTo4K ( + (UINT64)PageDirectory2MEntry->Bits.PageTableBaseAddress << 21, + (UINT64 *)PageDirectory2MEntry, + 0, + 0 + ); continue; } } else { - PageDirectoryPointerEntry =3D (PAGE_MAP_AND_DIRECTORY_POINTER*) Pa= geDirectory2MEntry; - PageTableEntry =3D (VOID*) (PageDirectoryPointerEntry->Bits.PageTa= bleBaseAddress<<12 & ~PgTableMask); + PageDirectoryPointerEntry =3D + (PAGE_MAP_AND_DIRECTORY_POINTER *)PageDirectory2MEntry; + PageTableEntry =3D + (VOID *)( + (PageDirectoryPointerEntry->Bits.PageTableBaseAddress << + 12) & ~PgTableMask + ); PageTableEntry +=3D PTE_OFFSET(PhysicalAddress); if (!PageTableEntry->Bits.Present) { DEBUG (( DEBUG_ERROR, "%a:%a: bad PTE for Physical=3D0x%Lx\n", gEfiCallerBaseName, __FUNCTION__, PhysicalAddress )); Status =3D RETURN_NO_MAPPING; goto Done; } SetOrClearCBit (&PageTableEntry->Uint64, Mode); PhysicalAddress +=3D EFI_PAGE_SIZE; Length -=3D EFI_PAGE_SIZE; } } } =20 // @@ -771,66 +815,78 @@ Done: // // Restore page table write protection, if any. // if (IsWpEnabled) { EnableReadOnlyPageWriteProtect (); } =20 return Status; } =20 /** This function clears memory encryption bit for the memory region specifi= ed by PhysicalAddress and length from the current page table context. =20 @param[in] PhysicalAddress The physical address that is the sta= rt address of a memory region. @param[in] Length The length of memory region @param[in] Flush Flush the caches before applying the encryption mask =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory - region. + @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 attrib= ute is - not supported + @retval RETURN_UNSUPPORTED Setting the memory encyrption attrib= ute + is not supported **/ RETURN_STATUS EFIAPI InternalMemEncryptSevSetMemoryDecrypted ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINTN Length, IN BOOLEAN Flush ) { =20 - return SetMemoryEncDec (Cr3BaseAddress, PhysicalAddress, Length, ClearCB= it, Flush); + return SetMemoryEncDec ( + Cr3BaseAddress, + PhysicalAddress, + Length, + ClearCBit, + Flush + ); } =20 /** This function sets memory encryption bit for the memory region specified= by PhysicalAddress and length from the current page table context. =20 - @param[in] PhysicalAddress The physical address that is the sta= rt address - of a memory region. + @param[in] PhysicalAddress The physical address that is the sta= rt + address of a memory region. @param[in] Length The length of memory region @param[in] Flush Flush the caches before applying the encryption mask =20 - @retval RETURN_SUCCESS The attributes were cleared for the = memory - region. + @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 attrib= ute is - not supported + @retval RETURN_UNSUPPORTED Setting the memory encyrption attrib= ute + is not supported **/ RETURN_STATUS EFIAPI InternalMemEncryptSevSetMemoryEncrypted ( IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS PhysicalAddress, IN UINTN Length, IN BOOLEAN Flush ) { - return SetMemoryEncDec (Cr3BaseAddress, PhysicalAddress, Length, SetCBit= , Flush); + return SetMemoryEncDec ( + Cr3BaseAddress, + PhysicalAddress, + Length, + SetCBit, + Flush + ); } --=20 2.14.1.3.gb7cf6e02401b _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel