From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.54]) by mx.groups.io with SMTP id smtpd.web11.2918.1608065561661812247 for ; Tue, 15 Dec 2020 12:52:41 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=o7pEZei7; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.237.54, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=aSyzIzOwmqFiOSxkHpzUWtBkANBugw2/5qnwpjmSG2ikacqQhYyWyAfj1vN3qI/VFboTlOfFTnUqO2TtE2kZiTuG9EOogdXqIs/EH/dNBgn8nv1jFnZ4ebvuuBG4BvXS9wtEYHQsbB/q/bOhFAXVZVpUah5M7ZS49+yLeolo7T5o1tGqziWazNozsEMILyqNlrrPWDdcJMqnYbPMUc1tJoJHiRjBgzl5OCiL399LMKoZbR1X9hygaz9DSAhDVMSNfKRgPg/tfEVUwnBjGmUcnie3XaJt6WtRDWRr16tEsCrtpfLra/K1GlRAk3w5tJv+ax3DyCSqHUiPH+M/voB0Qg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FG1h2Hw03TDiWayBN6sbKxtBLL/zBNJv5liu5U3JvEA=; b=GLvGnN/N+eWPwInRj1hybEQHQZ6tXkJ0lANTa0GQ6zlBsv1ixaE3UjrAhnWZdQvG3tYALh2Syuk6D3D7bZDrblVcMOEVsJxSMD6b2pSBazRufG9UWY3JWbhLKFJC0+qH1/ZvIaxZnMA58JoCQQ7Om1vCqKILru7nNGd+IEX8HbmsvQFFi/YmyRMvkStr0LQKgr7vQ4abzXC8KQ4himZNEY2Ae/RydUfNx3Cc9XwE+en9jdybJFpyaPATNbvBRQz3PK4k3H08dt+nj9BupkCUYbD7zv3hY0aXtRNsV3Gj60KE+Yk7FUFiZIv9QzPfyc692ogSGImaX+5OswpQYZl/QQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FG1h2Hw03TDiWayBN6sbKxtBLL/zBNJv5liu5U3JvEA=; b=o7pEZei72VQQSkPetuNSDqmqPWqtEG+t8tGIQjROcfFvNqnJo7KYxpOGzKNbo+mBhC8l90gFqHr9whLqtY1a64vnzDycogYkhyE5PyEYpzeB3EQaFnbitn16bwjtgVBYacl90TE30YVUKXZJaYk8kJsgbYATXx83fnEcZWCVdlA= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=amd.com; Received: from DM5PR12MB1355.namprd12.prod.outlook.com (10.168.234.7) by DM6PR12MB4155.namprd12.prod.outlook.com (10.141.8.79) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.15; Tue, 15 Dec 2020 20:52:38 +0000 Received: from DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::d95e:b9d:1d6a:e845]) by DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::d95e:b9d:1d6a:e845%12]) with mapi id 15.20.3654.025; Tue, 15 Dec 2020 20:52:38 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [PATCH 09/12] OvmfPkg/MemEncryptSevLib: Address range encryption state interface Date: Tue, 15 Dec 2020 14:51:08 -0600 Message-ID: <6877ca800856e85692d7ab99357895fa318f36c7.1608065471.git.thomas.lendacky@amd.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: CH2PR03CA0026.namprd03.prod.outlook.com (2603:10b6:610:59::36) To DM5PR12MB1355.namprd12.prod.outlook.com (2603:10b6:3:6e::7) Return-Path: thomas.lendacky@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from tlendack-t1.amd.com (165.204.77.1) by CH2PR03CA0026.namprd03.prod.outlook.com (2603:10b6:610:59::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12 via Frontend Transport; Tue, 15 Dec 2020 20:52:37 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 1d9f9f75-7427-4535-9340-08d8a13b5bc6 X-MS-TrafficTypeDiagnostic: DM6PR12MB4155: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6108; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: cJIPLHG07ez3eg3Zl1R/sweXJ7T2CM7wCBqAT4hhUo7hHQaUSf55X3S0ggHwgv338PxL4u8/uB4quQfZ7neAdQ7KX/a1kTixFoE/ORLWBOWmphbvFEacVg+mZn7NShBHUVawxLNXPv9d+9fZPV3zVbtnsSdSTlTBwOOZ/JKQk+VkNA+fO416kaahKNDEDQ5w8Wmw8eLfBhO1Kry7tmZTbEqs91U2Qo8JGDolF+74R4ELT3UT8XFXHrt88n13OCUwAKSxFRhnBumECVpCGSY0b2q/3ppCNu/r62AnUsMsimh6GJ6cXsaDIVm56uxsyDsXB8LQkdf2uUncRlKyUJOUSncFFGPZp35a87Ta7TK50MUmf6jXLrBS+cMO8zeG9/JkhvR08gh3MG2P5u0xl5KPvtZio+TXt86au1/qkhKuBIXhO/YmAncGS9OnVEc3DhDqMjk65lyYaxtVgTM1kt3/mw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM5PR12MB1355.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(376002)(366004)(136003)(346002)(66946007)(26005)(4326008)(19627235002)(16526019)(45954011)(6916009)(8676002)(36756003)(508600001)(52116002)(30864003)(6666004)(83380400001)(5660300002)(8936002)(966005)(186003)(54906003)(956004)(2616005)(66476007)(2906002)(86362001)(34490700003)(6486002)(66556008)(7696005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?Ru1R0KLVqIgJqSTmOo18qipDZHMIJiXlrjMSM9hYJQBSyh2qo8oeNr+56VL7?= =?us-ascii?Q?9mlwvX4QGITXsRUDAn4nGddUFUYL4HBAE53SCSV3F0WvePdpa7otHSlnUfct?= =?us-ascii?Q?qdvCA0m/exBDl3xrCpK65/0JCJpXdcBz2qQ8OzjDNvB4CJomFaPfjU140ZJj?= =?us-ascii?Q?XiMh+mOSiJEwhxXwNqyYOIxn50vR1WyGaq7d6crnHgda5fgGRJOjABWEgCxf?= =?us-ascii?Q?hqZp/4ru/1XO9YUVBDYC7dXtTUyzTg6xF0FbM2myZ+tboMGgLBBbFfkFOO6c?= =?us-ascii?Q?0ZBpv8ryVZtNopRnfITxLzsmDJrDlRJljCkQfF+rjmbDRGShDBaVbIEI/nEM?= =?us-ascii?Q?XaEShM0Hj6wAw8LqNlu//ojQix7bu8jpzvrnyGX2F/7O7gm89iZZkuvLCEZ8?= =?us-ascii?Q?bRrRF2iMKwQ3ywFmMpPPbsvxVAEOGkm3n0XbD9HYXaOMBZI3DfQK6dtCkZWv?= =?us-ascii?Q?KZE0jtoyplk4I0Ouwm3Sb2Gc3vdvWUmeubjsQ107THtysmuk6y4WDzwKbBRf?= =?us-ascii?Q?0W4EqeU09kCdrcf7nFXgdp3LWBf9lsyfBge7aTq9RHOXsYawYkSvRBAF0Wos?= =?us-ascii?Q?RVqalOnk0VakLASj7mYym5Yg5RkaboDvv1A/+YgWryqNjR0iULUMaoMRIZKw?= =?us-ascii?Q?8dXrPeQr7eoSHjIGBDeouPBz6xjpo1LbYo5iCuWDdNCplrvbqqMcZ0NKMYk4?= =?us-ascii?Q?rHH6Wljq6P5VehSkCTsQNogePO48Egu70lGsDDXhUJceEkiLCslWlj028mrz?= =?us-ascii?Q?hxP55zIzAqMoFTqO5cVm2m275ZwF0IQtCRiIsOLkAXakbRd1gQ5Zs2Zd9jYH?= =?us-ascii?Q?TbO/iZvI58HWPSCHgh4hNZxhvKRI5Mh0x7DyFQp3YTKHkwbe8YpdkezCTE2P?= =?us-ascii?Q?hUKInekeMm5Xe9IeS48gbDXzDUBlk59HLVGcpQzeLKEc2toFBfFYrirMIODP?= =?us-ascii?Q?ttdS52XUA6jpa5Uem7YUPERrDq5NOu2D6tP/YpUAEzj+OBlylCQILWRcEjUk?= =?us-ascii?Q?Fvlb?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthSource: DM5PR12MB1355.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Dec 2020 20:52:38.6708 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: 1d9f9f75-7427-4535-9340-08d8a13b5bc6 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: VNUzWsVIBhKPl54f2U21448rEPnhu1wDBv6y/tuFjb8mhCgRYZTNXNLPklTvtWqv0gGl8HYyRiaSEcYpVmSwPw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4155 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable From: Tom Lendacky BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3108 Update the MemEncryptSevLib library to include an interface that can report the encryption state on a range of memory. The values will represent the range as being unencrypted, encrypted, a mix of unencrypted and encrypted, and error (e.g. ranges that aren't mapped). Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Brijesh Singh Signed-off-by: Tom Lendacky --- .../DxeBaseMemEncryptSevLib.inf | 1 + .../PeiBaseMemEncryptSevLib.inf | 1 + .../SecBaseMemEncryptSevLib.inf | 1 + OvmfPkg/Include/Library/MemEncryptSevLib.h | 33 +++ .../BaseMemEncryptSevLib/X64/VirtualMemory.h | 35 ++- .../Ia32/MemEncryptSevLib.c | 31 ++- .../X64/MemEncryptSevLib.c | 32 ++- .../X64/PeiDxeVirtualMemory.c | 19 +- .../X64/SecVirtualMemory.c | 20 ++ .../BaseMemEncryptSevLib/X64/VirtualMemory.c | 207 ++++++++++++++++++ 10 files changed, 368 insertions(+), 12 deletions(-) create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.= c diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.i= nf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf index 390f2d60677f..04728a5dd256 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf @@ -34,6 +34,7 @@ [Sources.X64] MemEncryptSevLibInternal.c X64/MemEncryptSevLib.c X64/PeiDxeVirtualMemory.c + X64/VirtualMemory.c X64/VirtualMemory.h =20 [Sources.IA32] diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.i= nf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf index cb973fdeb868..4e4f59c0b0b6 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf @@ -34,6 +34,7 @@ [Sources.X64] MemEncryptSevLibInternal.c X64/MemEncryptSevLib.c X64/PeiDxeVirtualMemory.c + X64/VirtualMemory.c X64/VirtualMemory.h =20 [Sources.IA32] diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.i= nf b/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf index b26f739d69fd..79389298a3b3 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf @@ -34,6 +34,7 @@ [Sources.X64] MemEncryptSevLibInternal.c X64/MemEncryptSevLib.c X64/SecVirtualMemory.c + X64/VirtualMemory.c X64/VirtualMemory.h =20 [Sources.IA32] diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/L= ibrary/MemEncryptSevLib.h index 394065f15bc1..421b2e2c2c1e 100644 --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h @@ -33,6 +33,16 @@ typedef struct _SEC_SEV_ES_WORK_AREA { UINT64 EncryptionMask; } SEC_SEV_ES_WORK_AREA; =20 +// +// Memory encryption address range states. +// +typedef enum { + MemEncryptSevAddressRangeUnencrypted, + MemEncryptSevAddressRangeEncrypted, + MemEncryptSevAddressRangeMixed, + MemEncryptSevAddressRangeError, +} MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE; + /** Returns a boolean to indicate whether SEV-ES is enabled. =20 @@ -147,4 +157,27 @@ MemEncryptSevGetEncryptionMask ( VOID ); =20 +/** + Returns the encryption state of the specified virtual address range. + + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress Base address to check + @param[in] Length Length of virtual address range + + @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped + unencrypted + @retval MemEncryptSevAddressRangeEncrypted Address range is mapped + encrypted + @retval MemEncryptSevAddressRangeMixed Address range is mapped mi= xed + @retval MemEncryptSevAddressRangeError Address range is not mappe= d +**/ +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE +EFIAPI +MemEncryptSevGetAddressRangeState ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ); + #endif // _MEM_ENCRYPT_SEV_LIB_H_ diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/Ovm= fPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h index 26d26cd922a4..996f94f07ebb 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h @@ -3,7 +3,7 @@ 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) 2017 - 2020, AMD Incorporated. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -178,7 +178,17 @@ typedef struct { UINTN FreePages; } PAGE_TABLE_POOL; =20 +/** + Return the pagetable memory encryption mask. =20 + @return The pagetable memory encryption mask. + +**/ +UINT64 +EFIAPI +InternalGetMemEncryptionAddressMask ( + VOID + ); =20 /** This function clears memory encryption bit for the memory region specifi= ed by @@ -234,4 +244,27 @@ InternalMemEncryptSevSetMemoryEncrypted ( IN BOOLEAN Flush ); =20 +/** + Returns the encryption state of the specified virtual address range. + + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress Base address to check + @param[in] Length Length of virtual address range + + @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped + unencrypted + @retval MemEncryptSevAddressRangeEncrypted Address range is mapped + encrypted + @retval MemEncryptSevAddressRangeMixed Address range is mapped mi= xed + @retval MemEncryptSevAddressRangeError Address range is not mappe= d +**/ +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE +EFIAPI +InternalMemEncryptSevGetAddressRangeState ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ); + #endif diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b= /OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c index b4f6e5738e6e..12a5bf495bd7 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c @@ -2,7 +2,7 @@ =20 Secure Encrypted Virtualization (SEV) library helper function =20 - Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -82,3 +82,32 @@ MemEncryptSevSetPageEncMask ( // return RETURN_UNSUPPORTED; } + +/** + Returns the encryption state of the specified virtual address range. + + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress Base address to check + @param[in] Length Length of virtual address range + + @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped + unencrypted + @retval MemEncryptSevAddressRangeEncrypted Address range is mapped + encrypted + @retval MemEncryptSevAddressRangeMixed Address range is mapped mi= xed + @retval MemEncryptSevAddressRangeError Address range is not mappe= d +**/ +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE +EFIAPI +MemEncryptSevGetAddressRangeState ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ) +{ + // + // Memory is always encrypted in 32-bit mode + // + return MemEncryptSevAddressRangeEncrypted; +} diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/= OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c index cf0921e21464..4fea6a6be0ac 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c @@ -2,7 +2,7 @@ =20 Secure Encrypted Virtualization (SEV) library helper function =20 - Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -88,3 +88,33 @@ MemEncryptSevSetPageEncMask ( Flush ); } + +/** + Returns the encryption state of the specified virtual address range. + + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress Base address to check + @param[in] Length Length of virtual address range + + @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped + unencrypted + @retval MemEncryptSevAddressRangeEncrypted Address range is mapped + encrypted + @retval MemEncryptSevAddressRangeMixed Address range is mapped mi= xed + @retval MemEncryptSevAddressRangeError Address range is not mappe= d +**/ +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE +EFIAPI +MemEncryptSevGetAddressRangeState ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ) +{ + return InternalMemEncryptSevGetAddressRangeState ( + Cr3BaseAddress, + BaseAddress, + Length + ); +} diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c= b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c index 3a5bab657bd7..d3455e812bd1 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c @@ -28,14 +28,14 @@ typedef enum { } MAP_RANGE_MODE; =20 /** - Get the memory encryption mask + Return the pagetable memory encryption mask. =20 - @param[out] EncryptionMask contains the pte mask. + @return The pagetable memory encryption mask. =20 **/ -STATIC UINT64 -GetMemEncryptionAddressMask ( +EFIAPI +InternalGetMemEncryptionAddressMask ( VOID ) { @@ -200,7 +200,7 @@ Split2MPageTo4K ( =20 PageTableEntry1 =3D PageTableEntry; =20 - AddressEncMask =3D GetMemEncryptionAddressMask (); + AddressEncMask =3D InternalGetMemEncryptionAddressMask (); =20 ASSERT (PageTableEntry !=3D NULL); ASSERT (*PageEntry2M & AddressEncMask); @@ -286,7 +286,7 @@ SetPageTablePoolReadOnly ( LevelSize[3] =3D SIZE_1GB; LevelSize[4] =3D SIZE_512GB; =20 - AddressEncMask =3D GetMemEncryptionAddressMask(); + AddressEncMask =3D InternalGetMemEncryptionAddressMask(); PageTable =3D (UINT64 *)(UINTN)PageTableBase; PoolUnitSize =3D PAGE_TABLE_POOL_UNIT_SIZE; =20 @@ -431,7 +431,7 @@ Split1GPageTo2M ( =20 PageDirectoryEntry =3D AllocatePageTableMemory(1); =20 - AddressEncMask =3D GetMemEncryptionAddressMask (); + AddressEncMask =3D InternalGetMemEncryptionAddressMask (); ASSERT (PageDirectoryEntry !=3D NULL); ASSERT (*PageEntry1G & AddressEncMask); // @@ -485,7 +485,7 @@ SetOrClearCBit( { UINT64 AddressEncMask; =20 - AddressEncMask =3D GetMemEncryptionAddressMask (); + AddressEncMask =3D InternalGetMemEncryptionAddressMask (); =20 if (Mode =3D=3D SetCBit) { *PageTablePointer |=3D AddressEncMask; @@ -527,6 +527,7 @@ DisableReadOnlyPageWriteProtect ( /** Enable Write Protect on pages marked as read-only. **/ +STATIC VOID EnableReadOnlyPageWriteProtect ( VOID @@ -605,7 +606,7 @@ SetMemoryEncDec ( // // Check if we have a valid memory encryption mask // - AddressEncMask =3D GetMemEncryptionAddressMask (); + AddressEncMask =3D InternalGetMemEncryptionAddressMask (); if (!AddressEncMask) { return RETURN_ACCESS_DENIED; } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c b/= OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c index 5c337ea0b820..bca5e3febb1b 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c @@ -13,6 +13,26 @@ =20 #include "VirtualMemory.h" =20 +/** + Return the pagetable memory encryption mask. + + @return The pagetable memory encryption mask. + +**/ +UINT64 +EFIAPI +InternalGetMemEncryptionAddressMask ( + VOID + ) +{ + UINT64 EncryptionMask; + + EncryptionMask =3D MemEncryptSevGetEncryptionMask (); + EncryptionMask &=3D PAGING_1G_ADDRESS_MASK_64; + + return EncryptionMask; +} + /** This function clears memory encryption bit for the memory region specifi= ed by PhysicalAddress and Length from the current page table context. diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c b/Ovm= fPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c new file mode 100644 index 000000000000..36aabcf556a7 --- /dev/null +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c @@ -0,0 +1,207 @@ +/** @file + + Virtual Memory Management Services to test an address range encryption s= tate + + Copyright (c) 2020, AMD Incorporated. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include "VirtualMemory.h" + +/** + Returns the (updated) address range state based upon the page table + entry. + + @param[in] CurrentState The current address range state + @param[in] PageDirectoryEntry The page table entry to check + @param[in] AddressEncMask The encryption mask + + @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped + unencrypted + @retval MemEncryptSevAddressRangeEncrypted Address range is mapped + encrypted + @retval MemEncryptSevAddressRangeMixed Address range is mapped mi= xed +**/ +STATIC +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE +UpdateAddressState ( + IN MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE CurrentState, + IN UINT64 PageDirectoryEntry, + IN UINT64 AddressEncMask + ) +{ + if (CurrentState =3D=3D MemEncryptSevAddressRangeEncrypted) { + if ((PageDirectoryEntry & AddressEncMask) =3D=3D 0) { + CurrentState =3D MemEncryptSevAddressRangeMixed; + } + } else if (CurrentState =3D=3D MemEncryptSevAddressRangeUnencrypted) { + if ((PageDirectoryEntry & AddressEncMask) !=3D 0) { + CurrentState =3D MemEncryptSevAddressRangeMixed; + } + } else if (CurrentState =3D=3D MemEncryptSevAddressRangeError) { + // + // First address check, set initial state + // + if ((PageDirectoryEntry & AddressEncMask) =3D=3D 0) { + CurrentState =3D MemEncryptSevAddressRangeUnencrypted; + } else { + CurrentState =3D MemEncryptSevAddressRangeEncrypted; + } + } + + return CurrentState; +} + +/** + Returns the encryption state of the specified virtual address range. + + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] BaseAddress Base address to check + @param[in] Length Length of virtual address range + + @retval MemEncryptSevAddressRangeUnencrypted Address range is mapped + unencrypted + @retval MemEncryptSevAddressRangeEncrypted Address range is mapped + encrypted + @retval MemEncryptSevAddressRangeMixed Address range is mapped mi= xed + @retval MemEncryptSevAddressRangeError Address range is not mappe= d +**/ +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE +EFIAPI +InternalMemEncryptSevGetAddressRangeState ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINTN Length + ) +{ + 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 AddressEncMask; + UINT64 PgTableMask; + PHYSICAL_ADDRESS Address; + PHYSICAL_ADDRESS AddressEnd; + MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE State; + + // + // If Cr3BaseAddress is not specified then read the current CR3 + // + if (Cr3BaseAddress =3D=3D 0) { + Cr3BaseAddress =3D AsmReadCr3(); + } + + AddressEncMask =3D MemEncryptSevGetEncryptionMask (); + AddressEncMask &=3D PAGING_1G_ADDRESS_MASK_64; + + PgTableMask =3D AddressEncMask | EFI_PAGE_MASK; + + State =3D MemEncryptSevAddressRangeError; + + // + // Encryption is on a page basis, so start at the beginning of the + // virtual address page boundary and walk page-by-page. + // + Address =3D (PHYSICAL_ADDRESS) (UINTN) BaseAddress & ~EFI_PAGE_MASK; + AddressEnd =3D (PHYSICAL_ADDRESS) + (UINTN) (BaseAddress + Length); + + while (Address < AddressEnd) { + PageMapLevel4Entry =3D (VOID*) (Cr3BaseAddress & ~PgTableMask); + PageMapLevel4Entry +=3D PML4_OFFSET (Address); + if (!PageMapLevel4Entry->Bits.Present) { + return MemEncryptSevAddressRangeError; + } + + PageDirectory1GEntry =3D (VOID *) ( + (PageMapLevel4Entry->Bits.PageTableBaseAddres= s << + 12) & ~PgTableMask + ); + PageDirectory1GEntry +=3D PDP_OFFSET (Address); + if (!PageDirectory1GEntry->Bits.Present) { + return MemEncryptSevAddressRangeError; + } + + // + // If the MustBe1 bit is not 1, it's not actually a 1GB entry + // + if (PageDirectory1GEntry->Bits.MustBe1) { + // + // Valid 1GB page + // + State =3D UpdateAddressState ( + State, + PageDirectory1GEntry->Uint64, + AddressEncMask + ); + + Address +=3D BIT30; + continue; + } + + // + // Actually a PDP + // + PageUpperDirectoryPointerEntry =3D + (PAGE_MAP_AND_DIRECTORY_POINTER *) PageDirectory1GEntry; + PageDirectory2MEntry =3D + (VOID *) ( + (PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress << + 12) & ~PgTableMask + ); + PageDirectory2MEntry +=3D PDE_OFFSET (Address); + if (!PageDirectory2MEntry->Bits.Present) { + return MemEncryptSevAddressRangeError; + } + + // + // If the MustBe1 bit is not a 1, it's not a 2MB entry + // + if (PageDirectory2MEntry->Bits.MustBe1) { + // + // Valid 2MB page + // + State =3D UpdateAddressState ( + State, + PageDirectory2MEntry->Uint64, + AddressEncMask + ); + + Address +=3D BIT21; + continue; + } + + // + // Actually a PMD + // + PageDirectoryPointerEntry =3D + (PAGE_MAP_AND_DIRECTORY_POINTER *)PageDirectory2MEntry; + PageTableEntry =3D + (VOID *)( + (PageDirectoryPointerEntry->Bits.PageTableBaseAddress << + 12) & ~PgTableMask + ); + PageTableEntry +=3D PTE_OFFSET (Address); + if (!PageTableEntry->Bits.Present) { + return MemEncryptSevAddressRangeError; + } + + State =3D UpdateAddressState ( + State, + PageTableEntry->Uint64, + AddressEncMask + ); + + Address +=3D EFI_PAGE_SIZE; + } + + return State; +} --=20 2.28.0