From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.52]) by mx.groups.io with SMTP id smtpd.web10.9881.1589033321737243281 for ; Sat, 09 May 2020 07:08:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=HIo2dl+W; spf=none, err=SPF record not found (domain: amd.com, ip: 40.107.93.52, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=knsNWINJw7pXqaiXMRK0LCM3ul0u0NUfCltc0lq4oeydbmQ9wmKrXAlgbAI2E74M9svjY7Ty1QbT+saajJFGNZoH5UXVLX/NgGKXSc6IH2l5b9DzLMN2Ar7jXzbUuaN1STwnc3TWD0BvP6EWfA55By9HpSPD853NENB0NS1qkYTqUK+sv7dDW0ycExd5wT7BmSfOY04wz4hrOZgGFtyDddBB32fT++3s/OsO9RIKfYxwVU4eDTXvSZu1ncYKRNUV41xlGpGi8KqrhfR6zGFj6tDVnIQrG/Qoh33KAy41vOPgC9wqRVgObRA/LKnrQasfJ328HvtorvC5AODX1YXqrA== 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=tUwUDbT7os03FPWHDFy7dpyA1LFRjUL1Qkcwk3e1f4o=; b=Ur0QI9wI5hK6yc5us+gkrgCp//oYaAP8U8/N7RsxVOH+roUEV5tqTtwGMCGszTgAlk+RhHxqrENDumzsYbLm82E4yRliE6/pxIiB28AitsgqwlLE4abhw+nkYo2lZKv8MdXi9ZN8mzWKpu2EyqOuxNbRrEBtjxfxs6xUkMT6JB+ZCkQ3B6C0pcjMDnx3LDW986VsLVdiG8ewi3qPwXhH5zUvvBowvdpS8NpBIk+fGLJRUYJVOkqmaY+Y4S67ysZircNaHEVO8W+nsVL/y12f2Gcew+himDt+9Dql5qaj06c7pfb9J7CnnlLg3sXQ6LCz0a6bwqyRhMGSU7ZlaNZLLw== 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=tUwUDbT7os03FPWHDFy7dpyA1LFRjUL1Qkcwk3e1f4o=; b=HIo2dl+WV3snNgCKKMkWrRDMFPAnvh9Vbhs7n1qh/j+hrU+zWWywqT9p2cYdQrjtehA6y8tTHIkg3C1yjAWqG3Gu9l+LJrg309M3rzMzDIPkaD0zwe3nR91qWJMEbLPzfGMRMAwx3q6MITj69NNoZaTsjCVN4yQ5hz2kyZ0Re5Y= Authentication-Results: amd.com; dkim=none (message not signed) header.d=none;amd.com; dmarc=none action=none header.from=amd.com; Received: from DM5PR12MB1355.namprd12.prod.outlook.com (2603:10b6:3:6e::7) by DM5PR12MB1690.namprd12.prod.outlook.com (2603:10b6:4:11::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.33; Sat, 9 May 2020 14:08:39 +0000 Received: from DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::4ce1:9947:9681:c8b1]) by DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::4ce1:9947:9681:c8b1%10]) with mapi id 15.20.2979.033; Sat, 9 May 2020 14:08:39 +0000 Subject: Re: [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT To: "Dong, Eric" , "devel@edk2.groups.io" Cc: "Justen, Jordan L" , Laszlo Ersek , Ard Biesheuvel , "Kinney, Michael D" , "Gao, Liming" , "Ni, Ray" , Brijesh Singh References: <555901ab0879836aa262f29db634a330208170fa.1587577317.git.thomas.lendacky@amd.com> From: "Lendacky, Thomas" Message-ID: Date: Sat, 9 May 2020 09:08:37 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 In-Reply-To: X-ClientProxiedBy: SN4PR0601CA0013.namprd06.prod.outlook.com (2603:10b6:803:2f::23) 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 office-linux.texastahm.com (67.79.209.213) by SN4PR0601CA0013.namprd06.prod.outlook.com (2603:10b6:803:2f::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28 via Frontend Transport; Sat, 9 May 2020 14:08:38 +0000 X-Originating-IP: [67.79.209.213] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: e9348690-de58-4801-b9ad-08d7f422791c X-MS-TrafficTypeDiagnostic: DM5PR12MB1690:|DM5PR12MB1690: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-Forefront-PRVS: 03982FDC1D X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: j5D0Qr90FZR+fK/3QWKvvDRzeOy9rz96ljh3OrmV0I9BLemQ7lbk2qnq1ByTMLUGB5Qk2C3F9HzX2mVu7/bU6zwLjJyYoMkpa7kE8+dyDuncBl2w6amccivYPBL136NSx1ubadM32wc36aNPImaMoUZ2ZwFlqo64WQzJMPYB1tE7IWre9XEijvwA5L2S4eJ+zaSYWxU8bdzI3b6gZoK1fGXX4swo1SZKUySHvzzKRhmLRRnSqhgSgohCE3wZhWJ0UYzgQ7yY7/Cs+40ffVU4US230Op2SrcmjtZBC9yKbYCAgtPZEPkhZjsxeMrDqppxWsNAQx4nrDopYSAWoZnNSbJYKir0jrul1ZFcTFQXJLKd4mqm/jv17RpvyX9SLu/57fpd1kOKfR7dGb0RC4a+WnN28GmrSDFp3dtOkqqqiTiiHZrCPQl/6TcHSW6om/8G+FccozLsLYDXr9YqT/Fpwn97y84CCcym/jWbg+ahnbiFYErYacaHteXpM0GbN/981juEeRRTIu/wAnsGwhHg4d5HNSNzEL/0H/PKHKFOz/cQ59P9X8AoA6nVE80CoGzFi3h5/6lXtDm7YQj2sKmboDWiuxAvbXTHptsMm+KUtcVVGrXw2YEw3/X1nztFPAn5xvb1uIp/2X/plhYJRmrKfA== 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;SFTY:;SFS:(4636009)(136003)(346002)(396003)(376002)(366004)(39860400002)(33430700001)(5660300002)(2616005)(186003)(45080400002)(8676002)(31686004)(36756003)(26005)(66556008)(16526019)(4326008)(66476007)(316002)(66946007)(110136005)(54906003)(8936002)(6512007)(30864003)(52116002)(86362001)(31696002)(6486002)(2906002)(6506007)(53546011)(33440700001)(966005)(956004)(478600001)(43740500002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: klpgGZXYTloMZhOZ7hoU5RCpunO0irtxvs3oMBX19VMBkwJWN0pHCt7n7KovfBG5jcm7wUyqASKiT4Sja1hlgChYKhDqR3TPvO90xgoqqEcCX/ZulpK+zxX8WvdqPdNVwtpATiH3oj5kjx5EPR7QUtUKLMcinliFxGx+GM3LLi38ggJxquYOXy3lnZQ8kEK0BxAtgwukouIUZ2Ge8kckMogdQFjC7bl7QuIvgYBh98k04ytQ/z/0CqrJbHJEMnrSUsdlNY98EauPL0xHqtAvdZE+ahcbbXLaom6HNQJw1wkm6nLhXd85b0lt4t8boJXj4qLuUaS+a+AbaS8Bwg/tX9uHwoYRpZp6yxYun/neYpa33QB3ZMQ0OfGcCxOyWQeAbaqxUrStuouUZhP/nDcEzmmcSwGxudfLOZgvcNPF7WvCOQq7GWyndq7LLsl6ltl+zDT80V7RPhjQvRWxLIAx3Bbp5+aIDnB4x4p0OTf+DSM= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: e9348690-de58-4801-b9ad-08d7f422791c X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 May 2020 14:08:39.7594 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: sa77lR6kaQ0L/XIfFagfC/sIrfSH4mSNm2ltvkoPcrL0/+m9AmEgb6Nq3wAp/NcdPnNznFQjkd8q0uhqhfgYLg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1690 Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit On 5/8/20 8:06 PM, Dong, Eric wrote: > Hi Tom, > >> -----Original Message----- >> From: Tom Lendacky >> Sent: Thursday, April 23, 2020 1:41 AM >> To: devel@edk2.groups.io >> Cc: Justen, Jordan L ; Laszlo Ersek >> ; Ard Biesheuvel ; Kinney, >> Michael D ; Gao, Liming >> ; Dong, Eric ; Ni, Ray >> ; Brijesh Singh >> Subject: [PATCH v7 08/43] UefiCpuPkg: Implement library support for >> VMGEXIT >> >> BZ: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Cthomas.lendacky%40amd.com%7C263f75f798c64b75e23508d7f3b53108%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637245831845366269&sdata=TndzK3JmXQFNGBHSfbsSPr%2BGY8NMVX%2B1Durfner4k1I%3D&reserved=0 >> >> To support issuing a VMGEXIT instruction, create a library that can be used to >> perform GHCB and VMGEXIT related operations and to issue the actual >> VMGEXIT instruction when using the GHCB. >> >> Additionally, two VMGEXIT / MMIO related functions are created to support >> flash emulation. Flash emulation currently is done by marking the flash area >> as read-only and taking a nested page fault to perform the emulation of the >> instruction. However, emulation cannot be performed because there is no >> instruction decode assist support when SEV-ES is enabled. Provide routines >> to initiate an MMIO request to perform actual writes to flash. >> >> Cc: Eric Dong >> Cc: Ray Ni >> Cc: Laszlo Ersek >> Acked-by: Laszlo Ersek >> Signed-off-by: Tom Lendacky >> --- >> UefiCpuPkg/UefiCpuPkg.dec | 3 + >> UefiCpuPkg/UefiCpuPkg.dsc | 2 + >> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +++ >> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++++++++ >> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 >> +++++++++++++++++++ >> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 + >> 6 files changed, 463 insertions(+) >> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf >> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h >> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c >> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni >> >> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec >> index df5d02bae6b4..cb92f34b6f55 100644 >> --- a/UefiCpuPkg/UefiCpuPkg.dec >> +++ b/UefiCpuPkg/UefiCpuPkg.dec >> @@ -53,6 +53,9 @@ [LibraryClasses.IA32, LibraryClasses.X64] >> ## >> MpInitLib|Include/Library/MpInitLib.h >> >> + ## @libraryclass Provides function to support VMGEXIT processing. >> + VmgExitLib|Include/Library/VmgExitLib.h >> + >> [Guids] >> gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, >> 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} >> gMsegSmramGuid = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, >> 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }} >> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index >> d28cb5cccb52..997840452218 100644 >> --- a/UefiCpuPkg/UefiCpuPkg.dsc >> +++ b/UefiCpuPkg/UefiCpuPkg.dsc >> @@ -56,6 +56,7 @@ [LibraryClasses] >> >> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/Base >> PeCoffGetEntryPointLib.inf >> >> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BaseP >> eCoffExtraActionLibNull.inf >> >> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp >> mMeasurementLibNull.inf >> + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf >> >> [LibraryClasses.common.SEC] >> >> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.i >> nf >> @@ -136,6 +137,7 @@ [Components.IA32, Components.X64] >> >> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib >> Null.inf >> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf >> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf >> + UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf >> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf >> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf >> UefiCpuPkg/SecCore/SecCore.inf >> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf >> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf >> new file mode 100644 >> index 000000000000..6acfa779e75a >> --- /dev/null >> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf >> @@ -0,0 +1,33 @@ >> +## @file >> +# VMGEXIT Support Library. >> +# >> +# Copyright (c) 2019, Advanced Micro Devices, Inc. All rights >> +reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## >> + >> +[Defines] >> + INF_VERSION = 0x00010005 >> + BASE_NAME = VmgExitLib >> + MODULE_UNI_FILE = VmgExitLib.uni >> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e >> + MODULE_TYPE = BASE >> + VERSION_STRING = 1.0 >> + LIBRARY_CLASS = VmgExitLib >> + >> +# >> +# The following information is for reference only and not required by the >> build tools. >> +# >> +# VALID_ARCHITECTURES = IA32 X64 >> +# >> + >> +[Sources] >> + VmgExitLib.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + UefiCpuPkg/UefiCpuPkg.dec >> + >> +[LibraryClasses] >> + BaseLib >> + >> diff --git a/UefiCpuPkg/Include/Library/VmgExitLib.h >> b/UefiCpuPkg/Include/Library/VmgExitLib.h >> new file mode 100644 >> index 000000000000..3bf05bebd326 >> --- /dev/null >> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h >> @@ -0,0 +1,117 @@ >> +/** @file >> + Public header file for the VMGEXIT Support library class. >> + >> + This library class defines some routines used when invoking the >> + VMGEXIT instruction in support of SEV-ES. >> + >> + Copyright (c) 2019, Advanced Micro Devices, Inc. All rights >> + reserved.
>> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef __VMG_EXIT_LIB_H__ >> +#define __VMG_EXIT_LIB_H__ >> + >> +#include >> + >> + >> +/** >> + Perform VMGEXIT. >> + >> + Sets the necessary fields of the GHCB, invokes the VMGEXIT >> + instruction and then handles the return actions. >> + >> + @param[in, out] Ghcb A pointer to the GHCB >> + @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode >> + field of the GHCB. >> + @param[in] ExitInfo1 VMGEXIT information to be assigned to the >> + SwExitInfo1 field of the GHCB. >> + @param[in] ExitInfo2 VMGEXIT information to be assigned to the >> + SwExitInfo2 field of the GHCB. >> + >> + @retval 0 VMGEXIT succeeded. >> + @retval Others VMGEXIT processing did not succeed. Exception >> + number to be propagated. >> + >> +**/ >> +UINT64 >> +EFIAPI >> +VmgExit ( >> + IN OUT GHCB *Ghcb, >> + IN UINT64 ExitCode, >> + IN UINT64 ExitInfo1, >> + IN UINT64 ExitInfo2 >> + ); >> + >> +/** >> + Perform pre-VMGEXIT initialization/preparation. >> + >> + Performs the necessary steps in preparation for invoking VMGEXIT. >> + Must be called before setting any fields within the GHCB. >> + >> + @param[in, out] Ghcb A pointer to the GHCB >> + >> +**/ >> +VOID >> +EFIAPI >> +VmgInit ( >> + IN OUT GHCB *Ghcb >> + ); >> + >> +/** >> + Perform post-VMGEXIT cleanup. >> + >> + Performs the necessary steps to cleanup after invoking VMGEXIT. Must >> + be called after obtaining needed fields within the GHCB. >> + >> + @param[in, out] Ghcb A pointer to the GHCB >> + >> +**/ >> +VOID >> +EFIAPI >> +VmgDone ( >> + IN OUT GHCB *Ghcb >> + ); >> + >> +#define VMGMMIO_READ False >> +#define VMGMMIO_WRITE True >> + >> +/** >> + Perform MMIO write of a buffer to a non-MMIO marked range. >> + >> + Performs an MMIO write without taking a #VC. This is useful for >> + Flash devices, which are marked read-only. >> + >> + @param[in, out] Dest A pointer to the destination buffer >> + @param[in] Src A pointer to the source data to be written >> + @param[in] Bytes Number of bytes to write >> + >> +**/ >> +VOID >> +EFIAPI >> +VmgMmioWrite ( >> + IN OUT UINT8 *Dest, >> + IN UINT8 *Src, >> + IN UINTN Bytes >> + ); >> + >> +/** >> + Issue the GHCB set AP Jump Table VMGEXIT. >> + >> + Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the >> + AP Jump Table address with the hypervisor for retrieval at a later time. >> + >> + @param[in] Address Physical address of the AP Jump Table >> + >> + @retval 0 VMGEXIT succeeded. >> + @retval Others VMGEXIT processing did not succeed. Exception >> + number to be propagated. >> + >> +**/ >> +UINT64 >> +EFIAPI >> +VmgExitSetAPJumpTable ( >> + IN EFI_PHYSICAL_ADDRESS Address >> + ); > > I think above two APIs should not been added to this library, they are not the basic actions for VmgExit. > Remove these two APIs will make the library more stable. > > Also, I check all the code in this patch series, only one caller for each API, so I think we can directly > move these codes to the caller. If later more and more callers need to use these two APIs, we can > create another service library to convenient the callers. Ok, let me check into that. It should be very doable, especially with the change to a NULL library implementation that I want for the general case. Thanks, Tom > > I ignore all the coding style related issues in this patch because I assume you have passed ECC > checks in your new patches. > > Thanks, > Eric >> + >> +#endif >> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c >> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c >> new file mode 100644 >> index 000000000000..6137b1a0eb64 >> --- /dev/null >> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c >> @@ -0,0 +1,293 @@ >> +/** @file >> + VMGEXIT Support Library. >> + >> + Copyright (c) 2019, Advanced Micro Devices, Inc. All rights >> + reserved.
>> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/** >> + Check for VMGEXIT error >> + >> + Check if the hypervisor has returned an error after completion of the >> + VMGEXIT by examining the SwExitInfo1 field of the GHCB. >> + >> + @param[in] Ghcb A pointer to the GHCB >> + >> + @retval 0 VMGEXIT succeeded. >> + @retval Others VMGEXIT processing did not succeed. Exception >> number to >> + be propagated. >> + >> +**/ >> +STATIC >> +UINT64 >> +VmgExitErrorCheck ( >> + IN GHCB *Ghcb >> + ) >> +{ >> + GHCB_EVENT_INJECTION Event; >> + GHCB_EXIT_INFO ExitInfo; >> + UINT64 Status; >> + >> + ExitInfo.Uint64 = Ghcb->SaveArea.SwExitInfo1; ASSERT >> + ((ExitInfo.Elements.Lower32Bits == 0) || >> + (ExitInfo.Elements.Lower32Bits == 1)); >> + >> + Status = 0; >> + if (ExitInfo.Elements.Lower32Bits == 0) { >> + return Status; >> + } >> + >> + if (ExitInfo.Elements.Lower32Bits == 1) { >> + ASSERT (Ghcb->SaveArea.SwExitInfo2 != 0); >> + >> + // Check that the return event is valid >> + Event.Uint64 = Ghcb->SaveArea.SwExitInfo2; >> + if (Event.Elements.Valid && >> + Event.Elements.Type == GHCB_EVENT_INJECTION_TYPE_EXCEPTION) { >> + switch (Event.Elements.Vector) { >> + case GP_EXCEPTION: >> + case UD_EXCEPTION: >> + // Use returned event as return code >> + Status = Event.Uint64; >> + } >> + } >> + } >> + >> + if (Status == 0) { >> + GHCB_EVENT_INJECTION Event; >> + >> + Event.Uint64 = 0; >> + Event.Elements.Vector = GP_EXCEPTION; >> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION; >> + Event.Elements.Valid = 1; >> + >> + Status = Event.Uint64; >> + } >> + >> + return Status; >> +} >> + >> +/** >> + Perform VMGEXIT. >> + >> + Sets the necessary fields of the GHCB, invokes the VMGEXIT >> + instruction and then handles the return actions. >> + >> + @param[in, out] Ghcb A pointer to the GHCB >> + @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode >> + field of the GHCB. >> + @param[in] ExitInfo1 VMGEXIT information to be assigned to the >> + SwExitInfo1 field of the GHCB. >> + @param[in] ExitInfo2 VMGEXIT information to be assigned to the >> + SwExitInfo2 field of the GHCB. >> + >> + @retval 0 VMGEXIT succeeded. >> + @retval Others VMGEXIT processing did not succeed. Exception >> + number to be propagated. >> + >> +**/ >> +UINT64 >> +EFIAPI >> +VmgExit ( >> + IN OUT GHCB *Ghcb, >> + IN UINT64 ExitCode, >> + IN UINT64 ExitInfo1, >> + IN UINT64 ExitInfo2 >> + ) >> +{ >> + Ghcb->SaveArea.SwExitCode = ExitCode; >> + Ghcb->SaveArea.SwExitInfo1 = ExitInfo1; >> + Ghcb->SaveArea.SwExitInfo2 = ExitInfo2; >> + >> + // >> + // Guest memory is used for the guest-hypervisor communication, so >> + fence // the invocation of the VMGEXIT instruction to ensure GHCB >> + accesses are // synchronized properly. >> + // >> + MemoryFence (); >> + AsmVmgExit (); >> + MemoryFence (); >> + >> + return VmgExitErrorCheck (Ghcb); >> +} >> + >> +/** >> + Perform pre-VMGEXIT initialization/preparation. >> + >> + Performs the necessary steps in preparation for invoking VMGEXIT. >> + Must be called before setting any fields within the GHCB. >> + >> + @param[in, out] Ghcb A pointer to the GHCB >> + >> +**/ >> +VOID >> +EFIAPI >> +VmgInit ( >> + IN OUT GHCB *Ghcb >> + ) >> +{ >> + SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0); } >> + >> +/** >> + Perform post-VMGEXIT cleanup. >> + >> + Performs the necessary steps to cleanup after invoking VMGEXIT. Must >> + be called after obtaining needed fields within the GHCB. >> + >> + @param[in, out] Ghcb A pointer to the GHCB >> + >> +**/ >> +VOID >> +EFIAPI >> +VmgDone ( >> + IN OUT GHCB *Ghcb >> + ) >> +{ >> +} >> + >> +/** >> + Perform VMGEXIT MMIO read or write. >> + >> + Performs the requested MMIO read or write using the VMGEXIT >> instruction. >> + >> + For an MMIO read, the data that has been read during the VMGEXIT is >> + placed in the SharedBuffer area of the GHCB. This is then copied to >> + the actual destination buffer within the guest. >> + >> + For an MMIO write, the data to be written is copied into the >> + SharedBuffer area of the GHCB by the guest. This is then copied to >> + the actual destination buffer by the hypervisor during the VMGEXIT. >> + >> + @param[in, out] MmioAddress A pointer to the MMIO buffer to be >> read/written >> + @param[in, out] Buffer A pointer to the buffer to hold the data thas >> + has been read or hold the data to be written >> + @param[in] Bytes Number of bytes to read or write >> + @param[in] Write If set, the request is for an MMIO write, else >> + it is an MMIO read. >> + >> + @retval 0 VMGEXIT succeeded. >> + @retval Others VMGEXIT processing did not succeed. Exception >> + number to be propagated. >> + >> +**/ >> +STATIC >> +UINT64 >> +EFIAPI >> +VmgMmio ( >> + IN OUT UINT8 *MmioAddress, >> + IN OUT UINT8 *Buffer, >> + IN UINTN Bytes, >> + IN BOOLEAN Write >> + ) >> +{ >> + UINT64 MmioOp, ExitInfo1, ExitInfo2, Status; >> + GHCB *Ghcb; >> + MSR_SEV_ES_GHCB_REGISTER Msr; >> + >> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb >> = >> + Msr.Ghcb; >> + >> + // >> + // This function is about to set fields in the GHCB. Do not execute >> + // anything that will cause a #VC before issuing the VmgExit(). Any >> + #VC // will result in all GHCB settings being overwritten (this >> + means, e.g., // do not add DEBUG() statements). >> + // >> + VmgInit (Ghcb); >> + >> + if (Write) { >> + MmioOp = SvmExitMmioWrite; >> + } else { >> + MmioOp = SvmExitMmioRead; >> + } >> + >> + ExitInfo1 = (UINT64) (UINTN) MmioAddress; >> + ExitInfo2 = Bytes; >> + >> + if (Write) { >> + CopyMem (Ghcb->SharedBuffer, Buffer, Bytes); } >> + >> + Ghcb->SaveArea.SwScratch = (UINT64) (UINTN) Ghcb->SharedBuffer; >> + Status = VmgExit (Ghcb, MmioOp, ExitInfo1, ExitInfo2); if (Status != >> + 0) { >> + return Status; >> + } >> + >> + if (!Write) { >> + CopyMem (Buffer, Ghcb->SharedBuffer, Bytes); } >> + >> + VmgDone (Ghcb); >> + >> + return 0; >> +} >> + >> +/** >> + Perform MMIO write of a buffer to a non-MMIO marked range. >> + >> + Performs an MMIO write without taking a #VC. This is useful for >> + Flash devices, which are marked read-only. >> + >> + @param[in, out] Dest A pointer to the destination buffer >> + @param[in] Src A pointer to the source data to be written >> + @param[in] Bytes Number of bytes to write >> + >> +**/ >> +VOID >> +EFIAPI >> +VmgMmioWrite ( >> + IN OUT UINT8 *Dest, >> + IN UINT8 *Src, >> + IN UINTN Bytes >> + ) >> +{ >> + VmgMmio (Dest, Src, Bytes, TRUE); >> +} >> + >> +/** >> + Issue the GHCB set AP Jump Table VMGEXIT. >> + >> + Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the >> + AP Jump Table address with the hypervisor for retrieval at a later time. >> + >> + @param[in] Address Physical address of the AP Jump Table >> + >> + @retval 0 VMGEXIT succeeded. >> + @retval Others VMGEXIT processing did not succeed. Exception >> + number to be propagated. >> + >> +**/ >> +UINT64 >> +EFIAPI >> +VmgExitSetAPJumpTable ( >> + IN EFI_PHYSICAL_ADDRESS Address >> + ) >> +{ >> + UINT64 ExitInfo1, ExitInfo2, Status; >> + GHCB *Ghcb; >> + MSR_SEV_ES_GHCB_REGISTER Msr; >> + >> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb >> = >> + Msr.Ghcb; >> + >> + VmgInit (Ghcb); >> + >> + ExitInfo1 = 0; >> + ExitInfo2 = (UINT64) (UINTN) Address; >> + >> + Status = VmgExit (Ghcb, SvmExitApJumpTable, ExitInfo1, ExitInfo2); >> + >> + VmgDone (Ghcb); >> + >> + return Status; >> +} >> + >> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni >> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni >> new file mode 100644 >> index 000000000000..e8656aae4726 >> --- /dev/null >> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni >> @@ -0,0 +1,15 @@ >> +// /** @file >> +// VMGEXIT support library instance. >> +// >> +// VMGEXIT support library instance. >> +// >> +// Copyright (c) 2019, Advanced Micro Devices, Inc. All rights >> +reserved.
// SPDX-License-Identifier: BSD-2-Clause-Patent // // **/ >> + >> + >> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT >> Support Library." >> + >> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT >> Support Library." >> + >> -- >> 2.17.1 >