From nobody Mon Sep 16 19:34:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114627+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706307222447117.35227453051675; Fri, 26 Jan 2024 14:13:42 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=T9NgzZFxwinY25gOfjd0bhRFt1GAxHn2CYV/RDqJ6Xs=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1706307222; v=1; b=cjQuhSB5sTMqo4MA/NEFsao4gfCqSZ0zpmyRBL31stmbHZxDKmGSBYlmwVCIkAXRE6ghHmwU bqHj74Avh6OvH0scsD+koCfMiFb81JOD/z5OtoDFfcF+DEH+BKHxYCU1psbE/k4UMj4Q52Nib60 O094jztz/WJxFBeO9rYgQ2qo= X-Received: by 127.0.0.2 with SMTP id ZCr3YY1788612xVF5CFCg5gQ; Fri, 26 Jan 2024 14:13:42 -0800 X-Received: from NAM11-BN8-obe.outbound.protection.outlook.com (NAM11-BN8-obe.outbound.protection.outlook.com [40.107.236.40]) by mx.groups.io with SMTP id smtpd.web11.2930.1706307221235836996 for ; Fri, 26 Jan 2024 14:13:41 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=QuBzByDKQZeP87kxpLk3PR7euVDz2MfaXtwUjvNkathty5a1dS/5MisH1TKnqtVBgeirVTZ/QB0p912VipkgOhbnzJu/2UH7lmESHtbumx68C9JRqzBGPpc8a+mBXxR/uPkTAnTVAFko/jv3DuiWiOUJnySkXkatOTc35Z40wBzGB4zRDV2GeXKhhr2dWnMZkeaAgQyuD7XfGYz70Vf0oEqV2Y70LAi/s8twpfDUVEBmK5b3NuHwxVZcDkSmx44MUkzKDeun95qzGrfV3v4lrJr7W0hzjN2OdkXOFhT0v3f0z3pK42NruUZgxIVRc13LzNgi759s0PSXXfgVOZeExw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gWAfnpJUCRbjVBRbN04prcO079lOfyTiu6oN/A/YiOo=; b=Fn3B5/qewbeThsjQGFsUsUjTH1hAKG11Hwbl25KJVVwKiCFtarRQwCz1g4e0Jbr7JagUGSjcIvBr/867f4JcJv2JJHIjpMOHilWMiGzKcJtIsygzfaSHyQiRVK3uaLfJLOfzcZhGz6xup8mc4uUT6BsUk+/keWtvZvqaQl/qijuJq7dP+XRRYc3LYGqWqZIM+qKNEdlbxOtQwJiymC5oTmwov8U/UhsQSluRvyOn33oIWqkcsqWODKJJnJ3au0VEfPQ+LLqkjppEU+Yqpsb4BPTwFFQnQ2M9fyzExbJch7P/EpArKDBzvUsmfU4jGxI1732OPGJd3wpNOa517ON/Dw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) X-Received: from CY5PR18CA0030.namprd18.prod.outlook.com (2603:10b6:930:5::32) by LV8PR12MB9405.namprd12.prod.outlook.com (2603:10b6:408:1fa::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.26; Fri, 26 Jan 2024 22:13:38 +0000 X-Received: from CY4PEPF0000E9D1.namprd03.prod.outlook.com (2603:10b6:930:5:cafe::2a) by CY5PR18CA0030.outlook.office365.com (2603:10b6:930:5::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.27 via Frontend Transport; Fri, 26 Jan 2024 22:13:37 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114627+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000E9D1.mail.protection.outlook.com (10.167.241.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7228.16 via Frontend Transport; Fri, 26 Jan 2024 22:13:37 +0000 X-Received: from tlendack-t1.amdoffice.net (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Fri, 26 Jan 2024 16:13:36 -0600 From: "Lendacky, Thomas via groups.io" To: CC: Ard Biesheuvel , Erdem Aktas , Gerd Hoffmann , Jiewen Yao , Laszlo Ersek , Liming Gao , Michael D Kinney , Min Xu , Zhiguang Liu , "Rahul Kumar" , Ray Ni , Michael Roth Subject: [edk2-devel] [PATCH 01/16] OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support Date: Fri, 26 Jan 2024 16:13:00 -0600 Message-ID: <7289d8c5217907e711038e92cdec0c38ffe2f727.1706307195.git.thomas.lendacky@amd.com> In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000E9D1:EE_|LV8PR12MB9405:EE_ X-MS-Office365-Filtering-Correlation-Id: 888ab72e-df20-449d-4148-08dc1ebc0bab X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: g36xh2KQMuJFEQe79mnoZO6MKOD+tdIO/JXxtG1pswqigrRzdokNofSrB5KNdCRXGub3Vib9EvJT+0/422Mel7zlIsze7buQZBXzPemGTUQKRy/qwxU8mwJKBv8SFzn0sp6JpUuidawF108I8YoWf6J7QXM3LPP3h5gvqm3PWQ+vrfVdGbM/JLZuVe7BEIwRndR2VmARKDWU+fmX0/beiWDvrFFP+3HNmgtUDMhEiQtG8zWAjsvz3R28bLf3dPlNuUZsVuVsIMXSD4r++VmS7v4w05g+k7fe4igUnRjt54IlhhyilS/HgW2VpcR4yIKLCuaCZ1HW+EtPmS5Ncu7IguMuOs4wyjiDl8WmQ+HbBkYM9TXx8w1FMTnq0XbOooe0G86cREbYegnXUhU9o8FAEGbbmMX6PLrXREfsA2WXO5ALvcQoHjHYddxt/bzru6p+D0AZSh/6d+RrmBY0oFML+pDMJHnGvNJ9cvpMNBqKgvO6Ps0pC7zanBc0rbaGIo0VRYU/PPPJiQeuy31M1Is1UlAsHAcKyyCft3ZIAcsht3vziucEy77f7DDDHENi09Ep9Zj8x7StzpM6Tlhx3vnPm2xi87bsbXkMbj4FmI51Xg4sfr/arWtptaxQR6rAT9S/zNZPIbLLfjtqvj7aLve1v69i/Ev9+f7pcqpWbqiCaKZHaljW4hdiB6ihs3Sgmg626OWMJVjGg+RMWXUlCU2hfCHUsiyr6wAMmVgo5CYrZ0BjSfCsc7voVpp0T7iMeSwLXNfQe60sAo7IG7OsMFkxqojcpHo80vNe/gGeXbp9pY8= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jan 2024 22:13:37.7131 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 888ab72e-df20-449d-4148-08dc1ebc0bab X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000E9D1.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV8PR12MB9405 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,thomas.lendacky@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 7ISJRzQgwdziFEISLXYasd2ix1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706307223495100001 Content-Type: text/plain; charset="utf-8" BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4654 In preparation for running under an SVSM at VMPL1 or higher (higher numerically, lower privilege), re-organize the way a page state change is performed in order to free up the GHCB for use by the SVSM support. Currently, the page state change logic directly uses the GHCB shared buffer to build the page state change structures. However, this will be in conflict with the use of the GHCB should an SVSM call be required. Instead, use a separate buffer (an area in the workarea during SEC and an allocated page during PEI/DXE) to hold the page state change request and only update the GHCB shared buffer as needed. Since the information is copied to, and operated on, in the GHCB shared buffer this has the added benefit of not requiring to save the start and end entries for use when validating the memory during the page state change sequence. Signed-off-by: Tom Lendacky --- MdePkg/Include/Register/Amd/Ghcb.h | = 9 +- OvmfPkg/Include/WorkArea.h | = 7 + OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h | = 4 +- OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c | 1= 6 ++- OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 2= 5 +++- OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c | 2= 0 ++- OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c | 1= 4 +- OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 15= 1 +++++++++++++------- 8 files changed, 183 insertions(+), 63 deletions(-) diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/A= md/Ghcb.h index dab396f3ede8..29b2e45d0163 100644 --- a/MdePkg/Include/Register/Amd/Ghcb.h +++ b/MdePkg/Include/Register/Amd/Ghcb.h @@ -4,7 +4,7 @@ Provides data types allowing an SEV-ES guest to interact with the hyperv= isor using the GHCB protocol. =20 - Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights reser= ved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Specification Reference: @@ -195,13 +195,14 @@ typedef struct { UINT32 Reserved; } SNP_PAGE_STATE_HEADER; =20 -#define SNP_PAGE_STATE_MAX_ENTRY 253 - typedef struct { SNP_PAGE_STATE_HEADER Header; - SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY]; + SNP_PAGE_STATE_ENTRY Entry[]; } SNP_PAGE_STATE_CHANGE_INFO; =20 +#define SNP_PAGE_STATE_MAX_ENTRY \ + ((sizeof (((GHCB *)0)->SharedBuffer) - sizeof (SNP_PAGE_STATE_HEADER)) /= sizeof (SNP_PAGE_STATE_ENTRY)) + // // SEV-ES save area mapping structures used for SEV-SNP AP Creation. // Only the fields required to be set to a non-zero value are defined. diff --git a/OvmfPkg/Include/WorkArea.h b/OvmfPkg/Include/WorkArea.h index b1c7045ce18c..87d2063f6d13 100644 --- a/OvmfPkg/Include/WorkArea.h +++ b/OvmfPkg/Include/WorkArea.h @@ -54,6 +54,13 @@ typedef struct _SEC_SEV_ES_WORK_AREA { // detection in OvmfPkg/ResetVector/Ia32/AmdSev.c // UINT8 ReceivedVc; + UINT8 Reserved[7]; + + // Used by SEC to generate Page State Change requests. This should be + // sized less than an equal to the GHCB shared buffer area to allow a + // single call to the hypervisor. + // + UINT8 WorkBuffer[1024]; } SEC_SEV_ES_WORK_AREA; =20 // diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h = b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h index 43319cc9ed17..516d0eae91d7 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h @@ -24,7 +24,9 @@ InternalSetPageState ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages, IN SEV_SNP_PAGE_STATE State, - IN BOOLEAN UseLargeEntry + IN BOOLEAN UseLargeEntry, + IN VOID *PscBuffer, + IN UINTN PscBufferSize ); =20 VOID diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValida= te.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c index cbcdd46f528f..c8e8478a30d4 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c @@ -16,6 +16,8 @@ #include "SnpPageStateChange.h" #include "VirtualMemory.h" =20 +STATIC VOID *mPscBuffer =3D NULL; + /** Pre-validate the system RAM when SEV-SNP is enabled in the guest VM. =20 @@ -52,5 +54,17 @@ MemEncryptSevSnpPreValidateSystemRam ( } } =20 - InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE); + if (mPscBuffer =3D=3D NULL) { + mPscBuffer =3D AllocateReservedPages (1); + ASSERT (mPscBuffer !=3D NULL); + } + + InternalSetPageState ( + BaseAddress, + NumPages, + SevSnpPagePrivate, + TRUE, + mPscBuffer, + EFI_PAGE_SIZE + ); } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c= b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c index dee3fb8914ca..df367341d1ac 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c @@ -23,6 +23,8 @@ STATIC BOOLEAN mAddressEncMaskChecked =3D FALSE; STATIC UINT64 mAddressEncMask; STATIC PAGE_TABLE_POOL *mPageTablePool =3D NULL; =20 +STATIC VOID *mPscBuffer =3D NULL; + typedef enum { SetCBit, ClearCBit @@ -786,7 +788,19 @@ SetMemoryEncDec ( // The InternalSetPageState() is used for setting the page state in the = RMP table. // if (!Mmio && (Mode =3D=3D ClearCBit) && MemEncryptSevSnpIsEnabled ()) { - InternalSetPageState (PhysicalAddress, EFI_SIZE_TO_PAGES (Length), Sev= SnpPageShared, FALSE); + if (mPscBuffer =3D=3D NULL) { + mPscBuffer =3D AllocateReservedPages (1); + ASSERT (mPscBuffer !=3D NULL); + } + + InternalSetPageState ( + PhysicalAddress, + EFI_SIZE_TO_PAGES (Length), + SevSnpPageShared, + FALSE, + mPscBuffer, + EFI_PAGE_SIZE + ); } =20 // @@ -975,11 +989,18 @@ SetMemoryEncDec ( // The InternalSetPageState() is used for setting the page state in the = RMP table. // if ((Mode =3D=3D SetCBit) && MemEncryptSevSnpIsEnabled ()) { + if (mPscBuffer =3D=3D NULL) { + mPscBuffer =3D AllocateReservedPages (1); + ASSERT (mPscBuffer !=3D NULL); + } + InternalSetPageState ( OrigPhysicalAddress, EFI_SIZE_TO_PAGES (OrigLength), SevSnpPagePrivate, - FALSE + FALSE, + mPscBuffer, + EFI_PAGE_SIZE ); } =20 diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValida= te.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c index 497016544482..46fc4994bfa4 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c @@ -17,6 +17,8 @@ #include "SnpPageStateChange.h" #include "VirtualMemory.h" =20 +STATIC UINT8 mPscBufferPage[EFI_PAGE_SIZE]; + typedef struct { UINT64 StartAddress; UINT64 EndAddress; @@ -113,7 +115,14 @@ MemEncryptSevSnpPreValidateSystemRam ( if (BaseAddress < OverlapRange.StartAddress) { NumPages =3D EFI_SIZE_TO_PAGES (OverlapRange.StartAddress - BaseAd= dress); =20 - InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TR= UE); + InternalSetPageState ( + BaseAddress, + NumPages, + SevSnpPagePrivate, + TRUE, + mPscBufferPage, + sizeof (mPscBufferPage) + ); } =20 BaseAddress =3D OverlapRange.EndAddress; @@ -122,7 +131,14 @@ MemEncryptSevSnpPreValidateSystemRam ( =20 // Validate the remaining pages. NumPages =3D EFI_SIZE_TO_PAGES (EndAddress - BaseAddress); - InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE); + InternalSetPageState ( + BaseAddress, + NumPages, + SevSnpPagePrivate, + TRUE, + mPscBufferPage, + sizeof (mPscBufferPage) + ); BaseAddress =3D EndAddress; } } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValida= te.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c index 7797febb8ac6..86af2ba0356e 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c @@ -10,6 +10,7 @@ =20 #include #include +#include #include =20 #include "SnpPageStateChange.h" @@ -65,6 +66,8 @@ MemEncryptSevSnpPreValidateSystemRam ( IN UINTN NumPages ) { + SEC_SEV_ES_WORK_AREA *SevEsWorkArea; + if (!MemEncryptSevSnpIsEnabled ()) { return; } @@ -78,5 +81,14 @@ MemEncryptSevSnpPreValidateSystemRam ( SnpPageStateFailureTerminate (); } =20 - InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE); + SevEsWorkArea =3D (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAre= aBase); + + InternalSetPageState ( + BaseAddress, + NumPages, + SevSnpPagePrivate, + TRUE, + SevEsWorkArea->WorkBuffer, + sizeof (SevEsWorkArea->WorkBuffer) + ); } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInt= ernal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeIntern= al.c index 46c6682760d5..f8bbe4d6f46b 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c @@ -72,14 +72,19 @@ SnpPageStateFailureTerminate ( STATIC VOID PvalidateRange ( - IN SNP_PAGE_STATE_CHANGE_INFO *Info, - IN UINTN StartIndex, - IN UINTN EndIndex, - IN BOOLEAN Validate + IN SNP_PAGE_STATE_CHANGE_INFO *Info ) { - UINTN RmpPageSize, Ret, i; + UINTN RmpPageSize; + UINTN StartIndex; + UINTN EndIndex; + UINTN Index; + UINTN Ret; EFI_PHYSICAL_ADDRESS Address; + BOOLEAN Validate; + + StartIndex =3D Info->Header.CurrentEntry; + EndIndex =3D Info->Header.EndEntry; =20 for ( ; StartIndex <=3D EndIndex; StartIndex++) { // @@ -87,6 +92,7 @@ PvalidateRange ( // Address =3D ((EFI_PHYSICAL_ADDRESS)Info->Entry[StartIndex].GuestFr= ameNumber) << EFI_PAGE_SHIFT; RmpPageSize =3D Info->Entry[StartIndex].PageSize; + Validate =3D Info->Entry[StartIndex].Operation =3D=3D SNP_PAGE_STAT= E_PRIVATE; =20 Ret =3D AsmPvalidate (RmpPageSize, Validate, Address); =20 @@ -96,7 +102,7 @@ PvalidateRange ( // the RMP entry is 4K and we are validating it as a 2MB. // if ((Ret =3D=3D PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize =3D=3D Pv= alidatePageSize2MB)) { - for (i =3D 0; i < PAGES_PER_LARGE_ENTRY; i++) { + for (Index =3D 0; Index < PAGES_PER_LARGE_ENTRY; Index++) { Ret =3D AsmPvalidate (PvalidatePageSize4K, Validate, Address); if (Ret) { break; @@ -131,22 +137,37 @@ BuildPageStateBuffer ( IN EFI_PHYSICAL_ADDRESS EndAddress, IN SEV_SNP_PAGE_STATE State, IN BOOLEAN UseLargeEntry, - IN SNP_PAGE_STATE_CHANGE_INFO *Info + IN SNP_PAGE_STATE_CHANGE_INFO *Info, + IN UINTN InfoSize ) { EFI_PHYSICAL_ADDRESS NextAddress; - UINTN i, RmpPageSize; + UINTN Index; + UINTN IndexMax; + UINTN PscIndexMax; + UINTN RmpPageSize; =20 // Clear the page state structure - SetMem (Info, sizeof (*Info), 0); + SetMem (Info, InfoSize, 0); =20 - i =3D 0; + Index =3D 0; + IndexMax =3D (InfoSize - sizeof (Info->Header)) / sizeof (Info->Entry= [0]); NextAddress =3D EndAddress; =20 + // + // Make the use of the work area as efficient as possible relative to + // exiting from the guest to the hypervisor. Maximize the number of entr= ies + // that can be processed per exit. + // + PscIndexMax =3D (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * SNP_PAGE_STATE_M= AX_ENTRY; + if (PscIndexMax > 0) { + IndexMax =3D MIN (IndexMax, PscIndexMax); + } + // // Populate the page state entry structure // - while ((BaseAddress < EndAddress) && (i < SNP_PAGE_STATE_MAX_ENTRY)) { + while ((BaseAddress < EndAddress) && (Index < IndexMax)) { // // Is this a 2MB aligned page? Check if we can use the Large RMP entry. // @@ -160,14 +181,14 @@ BuildPageStateBuffer ( NextAddress =3D BaseAddress + EFI_PAGE_SIZE; } =20 - Info->Entry[i].GuestFrameNumber =3D BaseAddress >> EFI_PAGE_SHIFT; - Info->Entry[i].PageSize =3D RmpPageSize; - Info->Entry[i].Operation =3D MemoryStateToGhcbOp (State); - Info->Entry[i].CurrentPage =3D 0; - Info->Header.EndEntry =3D (UINT16)i; + Info->Entry[Index].GuestFrameNumber =3D BaseAddress >> EFI_PAGE_SHIFT; + Info->Entry[Index].PageSize =3D RmpPageSize; + Info->Entry[Index].Operation =3D MemoryStateToGhcbOp (State); + Info->Entry[Index].CurrentPage =3D 0; + Info->Header.EndEntry =3D (UINT16)Index; =20 BaseAddress =3D NextAddress; - i++; + Index++; } =20 return NextAddress; @@ -176,11 +197,29 @@ BuildPageStateBuffer ( STATIC VOID PageStateChangeVmgExit ( - IN GHCB *Ghcb, - IN SNP_PAGE_STATE_CHANGE_INFO *Info + IN GHCB *Ghcb, + IN SNP_PAGE_STATE_ENTRY *Start, + IN UINT16 Count ) { - EFI_STATUS Status; + SNP_PAGE_STATE_CHANGE_INFO *GhcbInfo; + EFI_STATUS Status; + BOOLEAN InterruptState; + + ASSERT (Count <=3D SNP_PAGE_STATE_MAX_ENTRY); + if (Count > SNP_PAGE_STATE_MAX_ENTRY) { + SnpPageStateFailureTerminate (); + } + + // + // Initialize the GHCB + // + CcExitVmgInit (Ghcb, &InterruptState); + + GhcbInfo =3D (SNP_PAGE_STATE_CHANGE_INFO *)Ghcb->Sh= aredBuffer; + GhcbInfo->Header.CurrentEntry =3D 0; + GhcbInfo->Header.EndEntry =3D Count - 1; + CopyMem (GhcbInfo->Entry, Start, sizeof (*Start) * Count); =20 // // As per the GHCB specification, the hypervisor can resume the guest be= fore @@ -191,7 +230,7 @@ PageStateChangeVmgExit ( // page state was not successful, then later memory access will result // in the crash. // - while (Info->Header.CurrentEntry <=3D Info->Header.EndEntry) { + while (GhcbInfo->Header.CurrentEntry <=3D GhcbInfo->Header.EndEntry) { Ghcb->SaveArea.SwScratch =3D (UINT64)Ghcb->SharedBuffer; CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch); =20 @@ -205,6 +244,34 @@ PageStateChangeVmgExit ( SnpPageStateFailureTerminate (); } } + + CcExitVmgDone (Ghcb, InterruptState); +} + +STATIC +VOID +PageStateChange ( + IN SNP_PAGE_STATE_CHANGE_INFO *Info + ) +{ + GHCB *Ghcb; + MSR_SEV_ES_GHCB_REGISTER Msr; + SNP_PAGE_STATE_HEADER *Header; + UINT16 Index; + UINT16 Count; + + Msr.GhcbPhysicalAddress =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); + Ghcb =3D Msr.Ghcb; + + Header =3D &Info->Header; + + for (Index =3D Header->CurrentEntry; Index <=3D Header->EndEntry;) { + Count =3D MIN (Header->EndEntry - Index + 1, SNP_PAGE_STATE_MAX_ENTRY); + + PageStateChangeVmgExit (Ghcb, &Info->Entry[Index], Count); + + Index +=3D Count; + } } =20 /** @@ -220,18 +287,14 @@ InternalSetPageState ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages, IN SEV_SNP_PAGE_STATE State, - IN BOOLEAN UseLargeEntry + IN BOOLEAN UseLargeEntry, + IN VOID *PscBuffer, + IN UINTN PscBufferSize ) { - GHCB *Ghcb; EFI_PHYSICAL_ADDRESS NextAddress, EndAddress; - MSR_SEV_ES_GHCB_REGISTER Msr; - BOOLEAN InterruptState; SNP_PAGE_STATE_CHANGE_INFO *Info; =20 - Msr.GhcbPhysicalAddress =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); - Ghcb =3D Msr.Ghcb; - EndAddress =3D BaseAddress + EFI_PAGES_TO_SIZE (NumPages); =20 DEBUG (( @@ -245,56 +308,40 @@ InternalSetPageState ( UseLargeEntry )); =20 - while (BaseAddress < EndAddress) { - UINTN CurrentEntry, EndEntry; - - // - // Initialize the GHCB - // - CcExitVmgInit (Ghcb, &InterruptState); + Info =3D (SNP_PAGE_STATE_CHANGE_INFO *)PscBuffer; =20 + for (NextAddress =3D BaseAddress; NextAddress < EndAddress;) { // // Build the page state structure // - Info =3D (SNP_PAGE_STATE_CHANGE_INFO *)Ghcb->SharedBuffer; NextAddress =3D BuildPageStateBuffer ( - BaseAddress, + NextAddress, EndAddress, State, UseLargeEntry, - Info + PscBuffer, + PscBufferSize ); =20 - // - // Save the current and end entry from the page state structure. We ne= ed - // it later. - // - CurrentEntry =3D Info->Header.CurrentEntry; - EndEntry =3D Info->Header.EndEntry; - // // If the caller requested to change the page state to shared then // invalidate the pages before making the page shared in the RMP table. // if (State =3D=3D SevSnpPageShared) { - PvalidateRange (Info, CurrentEntry, EndEntry, FALSE); + PvalidateRange (Info); } =20 // // Invoke the page state change VMGEXIT. // - PageStateChangeVmgExit (Ghcb, Info); + PageStateChange (Info); =20 // // If the caller requested to change the page state to private then // validate the pages after it has been added in the RMP table. // if (State =3D=3D SevSnpPagePrivate) { - PvalidateRange (Info, CurrentEntry, EndEntry, TRUE); + PvalidateRange (Info); } - - CcExitVmgDone (Ghcb, InterruptState); - - BaseAddress =3D NextAddress; } } --=20 2.42.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114627): https://edk2.groups.io/g/devel/message/114627 Mute This Topic: https://groups.io/mt/103986437/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-