From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 78DB9740035 for ; Fri, 26 Jan 2024 22:14:27 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=cHwqBbMO6oElQmtN35iJ8tiyHycSdwipbaHm8ufq8D8=; 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=1706307266; v=1; b=W3vFDiRZ6JOvMjiPPVOC9i6/zTxLMQ1oIQvQaHnBwgcv9V6ktNV+DJpNWEN1iEd+u7FX7jqU NtcGuCuNHpYTPXWuYIrfCKUfqgTaXWByAFCG7narYZDN/lbLx1y9hdXty3EAMr67uS4C4XXELTk nsMII3HSpXnllFOBX6MerpZo= X-Received: by 127.0.0.2 with SMTP id Y5uZYY7687511xzApes6DzdO; Fri, 26 Jan 2024 14:14:26 -0800 X-Received: from NAM11-DM6-obe.outbound.protection.outlook.com (NAM11-DM6-obe.outbound.protection.outlook.com [40.107.223.83]) by mx.groups.io with SMTP id smtpd.web10.2874.1706307265490579827 for ; Fri, 26 Jan 2024 14:14:25 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R2obC7yeTgXoIq5dIJm+rElzTbznbGzL1p2y9mYealt/8Sz9/IJvcfFu2ncBvGcwJpAKDSpFvT0Uqw9L54WwFw1EfYNEImS7u1Fpbm04KS1liA3ecF3RRxMXjkgn1evPDBvhADxpz9Tj0plg6izgcDtdumPCI/sZTsqI81L/mUAM5z9Ts4AZwldWpU9pe5+C0yLktk77WeYbyOTS043KcJ/NiDBqCeDRADpveLdVmPunL16QjRjf7Jexh1E/24P0I2BIR5BkKYNM1HgChweILXF8wJciUh/4KIrP1xFJNnDypsUezxPqFnWTY9xPJT7E6p7yQEgL/siyOqaxolryrw== 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=DqPx6ZSC04otMvvPX67Iuftyh37GPt0u0NFQX+AHE0w=; b=eXsl/sVhTmLA1lvK59V9XSn+7HdU30qntpltlzc59pJEFXJB8HO5IMCX759b36hxAvpaAfLbHmN1O22oBk55Z9gg2P91XZZQ1+CWiRbzC0fCp+J4/qaWXbcI3iHwCgshH6j3imBxE8s336jLZ59fABDUDT6dUAt1q5J/mvtr151LOFxUZmUEGrSiFZcgHJFubVAiz9FEXGM9bVIbjS8OkLMxuc8F9H05nq6ibDEyxh0aphnYMshOaoOdSUKCk36HiJXTY0wvOvPpL83fLkBlTEmFPbvv9hg6E1yAvPQ7P+8VAUz0Y8HeLxDRlyAiW1d9YmjcR1ShQvEwivQ7UNBeGw== 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 DM6PR03CA0088.namprd03.prod.outlook.com (2603:10b6:5:333::21) by CH2PR12MB4119.namprd12.prod.outlook.com (2603:10b6:610:aa::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.27; Fri, 26 Jan 2024 22:14:21 +0000 X-Received: from DS2PEPF0000343E.namprd02.prod.outlook.com (2603:10b6:5:333:cafe::6) by DM6PR03CA0088.outlook.office365.com (2603:10b6:5:333::21) 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:14:20 +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 (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 DS2PEPF0000343E.mail.protection.outlook.com (10.167.18.41) 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:14:20 +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:14:19 -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 07/16] OvmfPkg/CcExitLib: Add support for the SVSM_CORE_PVALIDATE call Date: Fri, 26 Jan 2024 16:13:06 -0600 Message-ID: <7bd1171077a547173d35f95a89387d13abdc8301.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: DS2PEPF0000343E:EE_|CH2PR12MB4119:EE_ X-MS-Office365-Filtering-Correlation-Id: 7813e664-0b06-4eba-2da6-08dc1ebc2550 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: baVsMnvkrpEIY1O/uOcjUlMmMkAssn/8GfAqvFa+VxPO+1T+TcRy88hEoBDbOxYC21cdGzBXsepnrHx455ruR5OjlnfhoRSxUt6893jjLfkpRJOpBfoQ3lQ1T/ihd6y/cGeawF7mgB+gN8InlxljsTxYwV1swCFlxn2qPnb+GXkZ4mu6mJQriZfMTB7w6dtMNmTaqp6GTj+oAzxX6KD3Z94yT2jzS0wRqVwsXE0179Cn+i3kr8zmVLG1Cay9BXDtQlz+o4vP3IGKlDIAjibg4FU7gfs39xmjaNJ83PNPhxVgxVp7aiJUf7K1ZDABgdyRQqS7oJhIOsAw1dClTid3QwX/MOWjkfHT5j7VAd7tN9epVC5BXOyctH16SliKkuHpufzA0WqJxiuEqRO2dRnVbbR23/sz0bFkj2M2dCXlVKX7jF8C6TblO88tX1dwZDwLN+CNX4XqPh517zszNiTM4GuUmuNuY7pTkoAluRY9O7FenvUq4ggYVmy1OVtJtJXbjmXgFeMOm5grBLOVKK++nqmKYreXon6xI1PH84Of/064PkrfEVWHTCnXw93FG0mf12XfFzP0mu9zlH5LKCbrAcx8cZWut+vSmVgk0UAiibDvmqh5PxNOQjD0DpyE3hLYWIcJ5dZXBXSUR0CvEQj1I7t1sYdcNJkpyLwjW9kPAyF9UNrkkWZihNVeJ9vu7A3aSICZfI8ucnpRF8FqSWXbZPbH1WZW/OMfhl2RJl1Z9pv7vASgTt9T91J0vHo10H8DO++VFOKO67tIGVpCPCtWQQ== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jan 2024 22:14:20.7683 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7813e664-0b06-4eba-2da6-08dc1ebc2550 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: DS2PEPF0000343E.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR12MB4119 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: pyWvLPEXhiS2qW6jZmDmombkx7686176AA= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=W3vFDiRZ; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}") BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4654 The PVALIDATE instruction can only be performed at VMPL0. An SVSM will be present when running at VMPL1 or higher. When an SVSM is present, use the SVSM_CORE_PVALIDATE call to perform memory validation instead of issuing the PVALIDATE instruction directly. This moves the current PVALIDATE functionality into the CcExitLib library, where it can be determined whether an SVSM is present and perform the proper operation. Signed-off-by: Tom Lendacky --- OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 8= 2 +----- OvmfPkg/Library/CcExitLib/CcExitSvsm.c | 31= 1 ++++++++++++++++++++ 2 files changed, 321 insertions(+), 72 deletions(-) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInt= ernal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeIntern= al.c index f8bbe4d6f46b..60d47ce090fe 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c @@ -17,11 +17,10 @@ =20 #include #include +#include =20 #include "SnpPageStateChange.h" =20 -#define PAGES_PER_LARGE_ENTRY 512 - STATIC UINTN MemoryStateToGhcbOp ( @@ -63,73 +62,6 @@ SnpPageStateFailureTerminate ( CpuDeadLoop (); } =20 -/** - This function issues the PVALIDATE instruction to validate or invalidate = the memory - range specified. If PVALIDATE returns size mismatch then it retry validat= ing with - smaller page size. - - */ -STATIC -VOID -PvalidateRange ( - IN SNP_PAGE_STATE_CHANGE_INFO *Info - ) -{ - 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; - - for ( ; StartIndex <=3D EndIndex; StartIndex++) { - // - // Get the address and the page size from the Info. - // - 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; - - Ret =3D AsmPvalidate (RmpPageSize, Validate, Address); - - // - // If we fail to validate due to size mismatch then try with the - // smaller page size. This senario will occur if the backing page in - // 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 (Index =3D 0; Index < PAGES_PER_LARGE_ENTRY; Index++) { - Ret =3D AsmPvalidate (PvalidatePageSize4K, Validate, Address); - if (Ret) { - break; - } - - Address =3D Address + EFI_PAGE_SIZE; - } - } - - // - // If validation failed then do not continue. - // - if (Ret) { - DEBUG (( - DEBUG_ERROR, - "%a:%a: Failed to %a address 0x%Lx Error code %d\n", - gEfiCallerBaseName, - __func__, - Validate ? "Validate" : "Invalidate", - Address, - Ret - )); - SnpPageStateFailureTerminate (); - } - } -} - STATIC EFI_PHYSICAL_ADDRESS BuildPageStateBuffer ( @@ -145,6 +77,7 @@ BuildPageStateBuffer ( UINTN Index; UINTN IndexMax; UINTN PscIndexMax; + UINTN SvsmIndexMax; UINTN RmpPageSize; =20 // Clear the page state structure @@ -159,11 +92,16 @@ BuildPageStateBuffer ( // 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; + PscIndexMax =3D (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * SNP_PAGE_STATE_= MAX_ENTRY; + SvsmIndexMax =3D (IndexMax / SVSM_PVALIDATE_MAX_ENTRY) * SVSM_PVALIDATE_= MAX_ENTRY; if (PscIndexMax > 0) { IndexMax =3D MIN (IndexMax, PscIndexMax); } =20 + if (SvsmIndexMax > 0) { + IndexMax =3D MIN (IndexMax, SvsmIndexMax); + } + // // Populate the page state entry structure // @@ -328,7 +266,7 @@ InternalSetPageState ( // invalidate the pages before making the page shared in the RMP table= . // if (State =3D=3D SevSnpPageShared) { - PvalidateRange (Info); + CcExitSnpPvalidate (Info); } =20 // @@ -341,7 +279,7 @@ InternalSetPageState ( // validate the pages after it has been added in the RMP table. // if (State =3D=3D SevSnpPagePrivate) { - PvalidateRange (Info); + CcExitSnpPvalidate (Info); } } } diff --git a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c b/OvmfPkg/Library/CcExi= tLib/CcExitSvsm.c index fb8b762caadc..43e0a357efa5 100644 --- a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c +++ b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c @@ -13,6 +13,312 @@ #include #include =20 +#define PAGES_PER_2MB_ENTRY 512 + +/** + Terminate the guest using the GHCB MSR protocol. + + Uses the GHCB MSR protocol to request that the guest be termiated. + +**/ +STATIC +VOID +SvsmTerminate ( + VOID + ) +{ + MSR_SEV_ES_GHCB_REGISTER Msr; + + // + // Use the GHCB MSR Protocol to request termination by the hypervisor + // + Msr.Uint64 =3D 0; + Msr.GhcbTerminate.Function =3D GHCB_INFO_TERMINATE_REQUEST; + Msr.GhcbTerminate.ReasonCodeSet =3D GHCB_TERMINATE_GHCB; + Msr.GhcbTerminate.ReasonCode =3D GHCB_TERMINATE_GHCB_GENERAL; + AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.Uint64); + + AsmVmgExit (); + + ASSERT (FALSE); + CpuDeadLoop (); +} + +/** + Return the address of SVSM Call Area (CAA). + + Determines the address of the SVSM CAA. + + @return The address of the SVSM CAA + +**/ +STATIC +SVSM_CAA * +SvsmGetCaa ( + VOID + ) +{ + SVSM_INFORMATION *SvsmInfo; + + SvsmInfo =3D (SVSM_INFORMATION *)(UINTN)PcdGet32 (PcdOvmfSnpSecretsBase)= ; + + return CcExitSnpSvsmPresent () ? (SVSM_CAA *)SvsmInfo->SvsmCaa : NULL; +} + +/** + Issue an SVSM request. + + Invokes the SVSM to process a request on behalf of the guest. + + @param[in,out] SvsmCallData Pointer to the SVSM call data + + @return Contents of RAX upon return from VMGEXIT +**/ +STATIC +UINTN +SvsmMsrProtocol ( + IN OUT SVSM_CALL_DATA *SvsmCallData + ) +{ + MSR_SEV_ES_GHCB_REGISTER Msr; + UINT64 CurrentMsr; + UINT8 Pending; + BOOLEAN InterruptState; + UINTN Ret; + + do { + // + // Be sure that an interrupt can't cause a #VC while the GHCB MSR prot= ocol + // is being used (#VC handler will ASSERT if lower 12-bits are not zer= o). + // + InterruptState =3D GetInterruptState (); + if (InterruptState) { + DisableInterrupts (); + } + + Pending =3D 0; + SvsmCallData->CallPending =3D &Pending; + + CurrentMsr =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); + + Msr.Uint64 =3D 0; + Msr.SnpVmplRequest.Function =3D GHCB_INFO_SNP_VMPL_REQUEST; + Msr.SnpVmplRequest.Vmpl =3D 0; + AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.Uint64); + + // + // Guest memory is used for the guest-SVSM communication, so fence the + // invocation of the VMGEXIT instruction to ensure VMSA accesses are + // synchronized properly. + // + MemoryFence (); + Ret =3D AsmVmgExitSvsm (SvsmCallData); + MemoryFence (); + + Msr.Uint64 =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); + + AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr); + + if (InterruptState) { + EnableInterrupts (); + } + + if (Pending !=3D 0) { + SvsmTerminate (); + } + + if ((Msr.SnpVmplResponse.Function !=3D GHCB_INFO_SNP_VMPL_RESPONSE) || + (Msr.SnpVmplResponse.ErrorCode !=3D 0)) + { + SvsmTerminate (); + } + } while (Ret =3D=3D SVSM_ERR_INCOMPLETE || Ret =3D=3D SVSM_ERR_BUSY); + + return Ret; +} + +/** + Issue an SVSM request to perform the PVALIDATE instruction. + + Invokes the SVSM to process the PVALIDATE instruction on behalf of the + guest to validate or invalidate the memory range specified. + + @param[in] Info Pointer to a page state change structure + +**/ +STATIC +VOID +SvsmPvalidate ( + IN SNP_PAGE_STATE_CHANGE_INFO *Info + ) +{ + SVSM_CALL_DATA SvsmCallData; + SVSM_CAA *Caa; + SVSM_PVALIDATE_REQUEST *Request; + SVSM_FUNCTION Function; + BOOLEAN Validate; + UINTN Entry; + UINTN EntryLimit; + UINTN Index; + UINTN EndIndex; + UINT64 Gfn; + UINT64 GfnEnd; + UINTN Ret; + + Caa =3D SvsmGetCaa (); + SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0); + + Function.Id.Protocol =3D 0; + Function.Id.CallId =3D 1; + + Request =3D (SVSM_PVALIDATE_REQUEST *)Caa->SvsmBuffer; + EntryLimit =3D ((sizeof (Caa->SvsmBuffer) - sizeof (*Request)) / + sizeof (Request->Entry[0])) - 1; + + SvsmCallData.Caa =3D Caa; + SvsmCallData.RaxIn =3D Function.Uint64; + SvsmCallData.RcxIn =3D (UINT64)(UINTN)Request; + + Entry =3D 0; + Index =3D Info->Header.CurrentEntry; + EndIndex =3D Info->Header.EndEntry; + + while (Index <=3D EndIndex) { + Validate =3D Info->Entry[Index].Operation =3D=3D SNP_PAGE_STATE_PRIVAT= E; + + Request->Header.Entries++; + Request->Entry[Entry].Bits.PageSize =3D Info->Entry[Index].PageSize; + Request->Entry[Entry].Bits.Action =3D (Validate =3D=3D TRUE) ? 1 : 0= ; + Request->Entry[Entry].Bits.IgnoreCf =3D 0; + Request->Entry[Entry].Bits.Address =3D Info->Entry[Index].GuestFrameN= umber; + + Entry++; + if ((Entry > EntryLimit) || (Index =3D=3D EndIndex)) { + Ret =3D SvsmMsrProtocol (&SvsmCallData); + if ((Ret =3D=3D SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH) && + (Request->Entry[Request->Header.Next].Bits.PageSize !=3D 0)) + { + // Calculate the Index of the entry after the entry that failed + // before clearing the buffer so that processing can continue + // from that point + Index =3D Index - (Entry - Request->Header.Next) + 2; + + // Obtain the failing GFN before clearing the buffer + Gfn =3D Request->Entry[Request->Header.Next].Bits.Address; + + // Clear the buffer in prep for creating all new entries + SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0); + Entry =3D 0; + + GfnEnd =3D Gfn + 511; + for ( ; Gfn <=3D GfnEnd; Gfn++) { + Request->Header.Entries++; + Request->Entry[Entry].Bits.PageSize =3D 0; + Request->Entry[Entry].Bits.Action =3D (Validate =3D=3D TRUE) ?= 1 : 0; + Request->Entry[Entry].Bits.IgnoreCf =3D 0; + Request->Entry[Entry].Bits.Address =3D Gfn; + + Entry++; + if ((Entry > EntryLimit) || (Gfn =3D=3D GfnEnd)) { + Ret =3D SvsmMsrProtocol (&SvsmCallData); + if (Ret !=3D 0) { + SvsmTerminate (); + } + + SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0); + Entry =3D 0; + } + } + + continue; + } + + if (Ret !=3D 0) { + SvsmTerminate (); + } + + SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0); + Entry =3D 0; + } + + Index++; + } +} + +/** + Perform the PVALIDATE instruction. + + Performs the PVALIDATE instruction to validate or invalidate the memory + range specified. + + @param[in] Info Pointer to a page state change structure + +**/ +STATIC +VOID +BasePvalidate ( + IN SNP_PAGE_STATE_CHANGE_INFO *Info + ) +{ + UINTN Index; + UINTN EndIndex; + UINTN Address; + UINTN RmpPageSize; + BOOLEAN Validate; + UINTN Ret; + + Index =3D Info->Header.CurrentEntry; + EndIndex =3D Info->Header.EndEntry; + while (Index <=3D EndIndex) { + // + // Get the address and the page size from the Info. + // + Address =3D Info->Entry[Index].GuestFrameNumber << EFI_PAGE_SHIFT; + RmpPageSize =3D Info->Entry[Index].PageSize; + Validate =3D Info->Entry[Index].Operation =3D=3D SNP_PAGE_STATE_PRI= VATE; + + Ret =3D AsmPvalidate (RmpPageSize, Validate, Address); + + // + // If PVALIDATE of a 2M page fails due to a size mismatch, then retry + // the full 2M range using a page size of 4K. This can occur if RMP en= try + // has a page size of 4K. + // + if ((Ret =3D=3D PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize =3D=3D Pv= alidatePageSize2MB)) { + UINTN EndAddress; + + EndAddress =3D Address + (PAGES_PER_2MB_ENTRY * SIZE_4KB); + while (Address < EndAddress) { + Ret =3D AsmPvalidate (PvalidatePageSize4K, Validate, Address); + if (Ret) { + break; + } + + Address +=3D SIZE_4KB; + } + } + + // + // If validation failed then do not continue. + // + if (Ret) { + DEBUG (( + DEBUG_ERROR, + "%a:%a: Failed to %a address 0x%Lx Error code %d\n", + gEfiCallerBaseName, + __func__, + Validate ? "Validate" : "Invalidate", + Address, + Ret + )); + + SvsmTerminate (); + } + + Index++; + } +} + /** Report the presence of an Secure Virtual Services Module (SVSM). =20 @@ -72,6 +378,11 @@ CcExitSnpPvalidate ( IN SNP_PAGE_STATE_CHANGE_INFO *Info ) { + if (CcExitSnpSvsmPresent ()) { + SvsmPvalidate (Info); + } else { + BasePvalidate (Info); + } } =20 /** --=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 (#114633): https://edk2.groups.io/g/devel/message/114633 Mute This Topic: https://groups.io/mt/103986455/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-