From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM04-BN8-obe.outbound.protection.outlook.com (NAM04-BN8-obe.outbound.protection.outlook.com [40.107.100.85]) by mx.groups.io with SMTP id smtpd.web10.1162.1610045475623419339 for ; Thu, 07 Jan 2021 10:51:15 -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=MLNQOzwU; 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.100.85, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TXrV2bz7tmi+720NPC/HGUN4gisfsIpg2/o8wPhhRQGMCN8AUvG9a6e6RvY6EkDrP8GarbOZ1xqsuo5ugoEkpfPM0JDQrHyHahotdgHEH/LrMM9vpg3P0Tkk4sFFjeqAfhkZQEv4N/XBXppVrNFbIrILQo3y8fKWdEwSgbFSpWsbUK9TedOrY99jTFZa7GQTet2Hozt3j0rOjCRqWPmTgL/rQm2tUo212X0lp8ag+FEN80MHHWTdS2+qA+0x7h1IipKspJcrvA6Oqi/OS+B+dW9QfnRVUD8VoXD1UL+cVQijCHIXxKbm9uCiG57Q2HAgrw0h2vhlkZlkIeNIX6FIQw== 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=VixXqr9fdu0Xk3pbBExKdDdhR8oJzArdr3SDPP3Xrqs=; b=JEd0/bBpuVnDFDuMbvOLTyoKtoqQhsEKUr8Oe+VfaTA7TPd+TNUOmdH1qhEJWLjsOkUC/uN6KtXvj/ObCh2C1SgHp0IRasXKWtNN71onMyuQgHcOVkecAq9aC+NbbSSWtfpKsB6ngaD+5Mxqees68LbxR5KzVgbhsIXCenKv/KoWBkIMNLFKy27VDbyTzWxPPf7M+zGj6Ng1lfjupEeg0X8aD69COlVGM3EGoyhPNQZyXDMVce3toxR9A+XaOkX3phNxXVWrAE4uQUJwssEsANOOOxuBa+Zrz6Mbnn0CslzdCmoSaSc5ba5Rqy7VVmEQN4YIueR61HOsaC6806h/TA== 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=VixXqr9fdu0Xk3pbBExKdDdhR8oJzArdr3SDPP3Xrqs=; b=MLNQOzwUtwtzxyNurJBp884vMQn1+55VhtIwb/G+WrIzd49TjczG4n5k0BEus2aT9vhr/tMAFRCm6yFkKzSj+/rw4MEFgzKj3HG+8vFARpgj2iy/9Q7Y4BdHK5r5MRk4H8a/cRVGS5hdaclUqXXQzWfrfSIhJa/Z9y01WCgOlek= 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 (2603:10b6:3:6e::7) by DM5PR1201MB0121.namprd12.prod.outlook.com (2603:10b6:4:56::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3721.23; Thu, 7 Jan 2021 18:51:13 +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.3721.024; Thu, 7 Jan 2021 18:51:13 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [PATCH v3 12/15] OvmfPkg/MemEncryptSevLib: Address range encryption state interface Date: Thu, 7 Jan 2021 12:48:22 -0600 Message-ID: <0d98f4d42a2b67310c29bac7bcdcf1eda6835847.1610045305.git.thomas.lendacky@amd.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: References: X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SN2PR01CA0042.prod.exchangelabs.com (2603:10b6:804:2::52) 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 SN2PR01CA0042.prod.exchangelabs.com (2603:10b6:804:2::52) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3742.6 via Frontend Transport; Thu, 7 Jan 2021 18:51:12 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 3de10d0f-0176-4489-3b4f-08d8b33d34a4 X-MS-TrafficTypeDiagnostic: DM5PR1201MB0121: 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: ZZ+nFju1qhK2s1GdpZhBaFUZTLWlxCVdj7eLktRsJg0+g48ct1D9zqOG39eaPhCik6P6s8OKLUB76L2/Bzi5bN3cnOlww4fL3M4jzn08BprfCLQOwqUGbwMt/wrWAVQYxIAl/tQmBc+jbRkatX0W3a95UrZIk3cSo/bw1YLcFLd3Zy1bymxEY+UDCdfwzliKOYYM8GMwwuL0TqV9EINv230bDPxN7ot4k0vxIIdWDwI3kjwhFxjr2QJR4eCWW17ducWKluwVcCONSPP44riKJrTDG1OSVpn5l1XFDRDA8Kse6s25wEg+CeuvRb98VcYykTqW1MA5p7AU5XFw4mWoNHdUkjdRwGmGufQduEHMc73p+gIVvZOKGXBTHtgUQtVTMkWrj7+dVGSYIE0r102uUeCnaMBCxTfMG/0bckOBdAPtjiKfrfMxGfhJK4vdN7PzorOoA1jSXChJxaJNdNMxdQ== 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)(39860400002)(136003)(366004)(346002)(376002)(396003)(54906003)(36756003)(316002)(30864003)(52116002)(16526019)(186003)(6666004)(7696005)(4326008)(83380400001)(66556008)(66946007)(6916009)(956004)(2906002)(8936002)(5660300002)(6486002)(66476007)(8676002)(86362001)(478600001)(966005)(45954011)(2616005)(26005)(19627235002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?7Bs/+KiI5nUczNat7It0kjViu6kZYcywGu3fy7lzdhZYFUcJtKf2u8QWQjkh?= =?us-ascii?Q?29jz0taCgSFNOAwhojCUEpgUjdpRbyctmeeqewq7wCHdCA5RsilSQ30JRu/v?= =?us-ascii?Q?LVmNYXoaXlYRL05H9yKNTNCoaY81IYWU1s9iEZW0Jq2IXKSgxMckBs/mNE6W?= =?us-ascii?Q?ipRqMRJo2qbbRQ82okIn7Y6EuuStgQlkFpkiB8LmEBJaqh2IdWis2zLbQfrv?= =?us-ascii?Q?HxeCb4phXjLuWTRWqiGUjaiAOBJs2ARxmUHipWdFdCjZe+JBolJabVzJsm5p?= =?us-ascii?Q?2trx9WpPVTa30MFDZaV3UsHudKYld0RB6+q5HkeJkhke/rYCFZXb0589nq4f?= =?us-ascii?Q?vTWLqwK+VSJzmgqbBBdj1D0TQihgKV3Hoqbv+gSJSW7rFYUA6M/gf6KbztAY?= =?us-ascii?Q?PW+V/MElDtkV01xd8M+kpj3cXqVk+waP9qvTrO3dqrXxRvh5obqYnfK7L6to?= =?us-ascii?Q?rLhoEEW6OMC90n9Tj00KKTU8TzbQ3lkRfaKEhiWbV1e+ooiGGQMvAl+6KoLa?= =?us-ascii?Q?wFudLBIGILwf7JU3a01bizLm5tUNRtvuEWtY6GbjckjnpkwOLmL7HrIFyqyy?= =?us-ascii?Q?eT2bWxln9FIhvnNBHUK2XBIe/vd8ayxX+wnDiCmDKdm7Dy6DgeUsTTgWuUuK?= =?us-ascii?Q?7UjjsZcOkw2XfhlnswxTw80y8Cj+iSR8yNtrns2qjBOCDiMyclPUiqi5HlXk?= =?us-ascii?Q?yB9S0LwPgJtnxs/ulzNHU5xh+3WjmngcSX3bBhQP9Ir8Nbq/pIae57tRO63M?= =?us-ascii?Q?ldqXz1vbE0XB6F7Du1GF06+sEfPJB3XfRx/G5JV3JjgydTebmS5QC5YEUG1p?= =?us-ascii?Q?mW2z8IZVzU52dcgOmU8QTYGdzDGW4mOLcvmcQR60APntcVAXylJJZIzIYP/7?= =?us-ascii?Q?/sWsgcwbJpoC5/mr9VjUIL/9vqAPVpcUs105526tcSzP0h4DxVq62T1fGwxd?= =?us-ascii?Q?I1IvKdtncfpNmeV3WRGrmsFm+idqO0/OZY0T79pIv336wzSysdBrnWPP4g8r?= =?us-ascii?Q?58T+?= 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: 07 Jan 2021 18:51:13.0070 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: 3de10d0f-0176-4489-3b4f-08d8b33d34a4 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: kRXwRfGeV1HkRXzX5EgKwY9ugojS06xbm5AygsVua/95ofg/jI2r6I9m3Lbd67r0lTJfkfl+kKOOR5nSvDCC/w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR1201MB0121 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 Acked-by: Laszlo Ersek Signed-off-by: Tom Lendacky --- OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 1 + OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf | 1 + OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf | 1 + OvmfPkg/Include/Library/MemEncryptSevLib.h | 33 ++++ OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h | 35 +++- OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c | 31 ++- OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 32 ++- OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 19 +- OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c | 20 ++ OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c | 207 +++++= +++++++++++++++ 10 files changed, 368 insertions(+), 12 deletions(-) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b= /OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf index 4480e4cc7c89..8e3b8ddd5a95 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf @@ -36,6 +36,7 @@ [Sources] [Sources.X64] X64/MemEncryptSevLib.c X64/PeiDxeVirtualMemory.c + X64/VirtualMemory.c X64/VirtualMemory.h =20 [Sources.IA32] diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b= /OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf index 0697f1dab502..03a78c32df28 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf @@ -36,6 +36,7 @@ [Sources] [Sources.X64] X64/MemEncryptSevLib.c X64/PeiDxeVirtualMemory.c + X64/VirtualMemory.c X64/VirtualMemory.h =20 [Sources.IA32] diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf b= /OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf index 7cd0111fe47b..279c38bfbc2c 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf @@ -35,6 +35,7 @@ [Sources] [Sources.X64] 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 872abe6725dc..ec470b8d0363 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.30.0