From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mx.groups.io with SMTP id smtpd.web10.358.1581640938620071586 for ; Thu, 13 Feb 2020 16:42:18 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.43, mailfrom: eric.dong@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Feb 2020 16:42:18 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,438,1574150400"; d="scan'208";a="238209916" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga006.jf.intel.com with ESMTP; 13 Feb 2020 16:42:17 -0800 Received: from fmsmsx124.amr.corp.intel.com (10.18.125.39) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 13 Feb 2020 16:42:17 -0800 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by fmsmsx124.amr.corp.intel.com (10.18.125.39) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 13 Feb 2020 16:42:17 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.126]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.5]) with mapi id 14.03.0439.000; Fri, 14 Feb 2020 08:42:15 +0800 From: "Dong, Eric" To: "devel@edk2.groups.io" , "thomas.lendacky@amd.com" CC: "Justen, Jordan L" , Laszlo Ersek , Ard Biesheuvel , "Kinney, Michael D" , "Gao, Liming" , "Ni, Ray" , Brijesh Singh Subject: Re: [edk2-devel] [PATCH v4 07/40] UefiCpuPkg: Implement library support for VMGEXIT Thread-Topic: [edk2-devel] [PATCH v4 07/40] UefiCpuPkg: Implement library support for VMGEXIT Thread-Index: AQHV268nwIJ2CtHloUW15MRmXRAxXKgZ5zIg Date: Fri, 14 Feb 2020 00:42:14 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZThiNTA4Y2YtMWQ5ZC00YWRjLWIxNmItY2NlNmEwYTIzNWRkIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiNXpYYUkxOGNsSGlXUHo4NUh5dnJuMkV3azkwUVhhRlhmOUtqUVBCd3VOdStIS3EzcGdlN29TSEt4T1BNMmJzbCJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: eric.dong@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Tom, For this patch, I found the function implementations not have function hea= der comments for them. This is not follow edk2 coding style, please update = them. Thanks, Eric -----Original Message----- From: devel@edk2.groups.io On Behalf Of Lendacky, T= homas Sent: Wednesday, February 5, 2020 7:01 AM To: devel@edk2.groups.io Cc: Justen, Jordan L ; Laszlo Ersek ; Ard Biesheuvel ; Kinney, Michael D ; Gao, Liming ; Dong, Eric <= eric.dong@intel.com>; Ni, Ray ; Brijesh Singh Subject: [edk2-devel] [PATCH v4 07/40] UefiCpuPkg: Implement library suppo= rt for VMGEXIT BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2198 To support issuing a VMGEXIT instruction, create a library that can be use= d to perform GHCB and VMGEXIT related operations and to issue the actual VM= GEXIT 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 are= a as read-only and taking a nested page fault to perform the emulation of t= he 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 | 5 + UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 ++++ UefiCpuPkg/Include/Library/VmgExitLib.h | 111 +++++++++++ UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 187 +++++++++++++++++++ UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 ++ 6 files changed, 354 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 0= 05703d8a3e7..893d2d06b0f2 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -53,6 +53,9 @@ [LibraryClasses.IA32, LibraryClasses.X64] ## MpInitLib|Include/Library/MpInitLib.h =20 + ## @libraryclass Provides function to support VMGEXIT processing. + VmgExitLib|Include/Library/VmgExitLib.h + [Guids] gUefiCpuPkgTokenSpaceGuid =3D { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa= , 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} gMsegSmramGuid =3D { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1= , 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }} diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index d= 28cb5cccb52..5ab7e423e8ab 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -63,6 +63,7 @@ [LibraryClasses.common.SEC] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt= /PeiServicesTablePointerLibIdt.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllo= cationLib.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf =20 [LibraryClasses.common.PEIM] MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllo= cationLib.inf @@ -74,6 +75,7 @@ [LibraryClasses.common.PEIM] [LibraryClasses.IA32.PEIM,= LibraryClasses.X64.PEIM] PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt= /PeiServicesTablePointerLibIdt.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpu= ExceptionHandlerLib.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf =20 [LibraryClasses.common.DXE_DRIVER] MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAl= locationLib.inf @@ -81,12 +83,14 @@ [LibraryClasses.common.DXE_DRIVER] CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpu= ExceptionHandlerLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeReg= isterCpuFeaturesLib.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf =20 [LibraryClasses.common.DXE_SMM_DRIVER] SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTable= Lib.inf MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllo= cationLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpu= ExceptionHandlerLib.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf =20 [LibraryClasses.common.UEFI_APPLICATION] UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/Uefi= ApplicationEntryPoint.inf @@ -136,6 +140,7 @@ [Components.IA32, Components.X64] UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.= 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/Lib= rary/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=20 +reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D VmgExitLib + MODULE_UNI_FILE =3D VmgExitLib.uni + FILE_GUID =3D 3cd7368f-ef9b-4a9b-9571-2ed93813677e + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D VmgExitLib + +# +# The following information is for reference only and not required by the= build tools. +# +# VALID_ARCHITECTURES =3D 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..602b213f1f63 --- /dev/null +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h @@ -0,0 +1,111 @@ +/** @file + Public header file for the VMGEXIT Support library class. + + This library class defines some routines used when invoking the=20 + VMGEXIT instruction in support of SEV-ES. + + Copyright (c) 2019, Advanced Micro Devices, Inc. All rights=20 + 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=20 + instruction and then handles the return actions. + + @param[in] GHCB A pointer to the GHCB + @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode fi= eld of + the GHCB. + @param[in] ExitInfo1 VMGEXIT information to be assigned to the SwExit= Info1 + field of the GHCB. + @param[in] ExitInfo2 VMGEXIT information to be assigned to the SwExit= Info2 + field of the GHCB. + + @retval 0 VMGEXIT succeeded. + @retval Others VMGEXIT processing did not succeed. Exception number t= o + be issued. + +**/ +UINTN +EFIAPI +VmgExit ( + GHCB *Ghcb, + UINT64 ExitCode, + UINT64 ExitInfo1, + UINT64 ExitInfo2 + ); + +/** + Perform pre-VMGEXIT initialization/preparation. + + Performs the necessary steps in preparation for invoking VMGEXIT. + + @param[in] GHCB A pointer to the GHCB + +**/ +VOID +EFIAPI +VmgInit ( + GHCB *Ghcb + ); + +/** + Perform post-VMGEXIT cleanup. + + Performs the necessary steps to cleanup after invoking VMGEXIT. + + @param[in] GHCB A pointer to the GHCB + +**/ +VOID +EFIAPI +VmgDone ( + 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=20 + Flash devices, which are marked read-only. + + @param[in] UINT8 A pointer to the destination buffer + @param[in] UINTN The immediate value to write + @param[in] UINTN Number of bytes to write + +**/ +VOID +EFIAPI +VmgMmioWrite ( + UINT8 *Dest, + UINT8 *Src, + 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] EFI_PHYSICAL_ADDRESS Physical address of the AP Jump=20 + Table + +**/ +UINTN +EFIAPI +VmgExitSetAPJumpTable ( + EFI_PHYSICAL_ADDRESS Address + ); + +#endif diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c b/UefiCpuPkg/Libra= ry/VmgExitLib/VmgExitLib.c new file mode 100644 index 000000000000..4e7315a58202 --- /dev/null +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c @@ -0,0 +1,187 @@ +/** @file + VMGEXIT Support Library. + + Copyright (c) 2019, Advanced Micro Devices, Inc. All rights=20 + reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +STATIC +UINT64 +VmgExitErrorCheck ( + GHCB *Ghcb + ) +{ + GHCB_EVENT_INJECTION Event; + GHCB_EXIT_INFO ExitInfo; + UINT64 Status; + + ExitInfo.Uint64 =3D Ghcb->SaveArea.SwExitInfo1; ASSERT=20 + ((ExitInfo.Elements.Lower32Bits =3D=3D 0) || + (ExitInfo.Elements.Lower32Bits =3D=3D 1)); + + Status =3D 0; + if (ExitInfo.Elements.Lower32Bits =3D=3D 0) { + return Status; + } + + if (ExitInfo.Elements.Lower32Bits =3D=3D 1) { + ASSERT (Ghcb->SaveArea.SwExitInfo2 !=3D 0); + + // Check that the return event is valid + Event.Uint64 =3D Ghcb->SaveArea.SwExitInfo2; + if (Event.Elements.Valid && + Event.Elements.Type =3D=3D GHCB_EVENT_INJECTION_TYPE_EXCEPTION) { + switch (Event.Elements.Vector) { + case GP_EXCEPTION: + case UD_EXCEPTION: + // Use returned event as return code + Status =3D Event.Uint64; + } + } + } + + if (Status =3D=3D 0) { + GHCB_EVENT_INJECTION Event; + + Event.Uint64 =3D 0; + Event.Elements.Vector =3D GP_EXCEPTION; + Event.Elements.Type =3D GHCB_EVENT_INJECTION_TYPE_EXCEPTION; + Event.Elements.Valid =3D 1; + + Status =3D Event.Uint64; + } + + return Status; +} + +UINT64 +EFIAPI +VmgExit ( + GHCB *Ghcb, + UINT64 ExitCode, + UINT64 ExitInfo1, + UINT64 ExitInfo2 + ) +{ + Ghcb->SaveArea.SwExitCode =3D ExitCode; + Ghcb->SaveArea.SwExitInfo1 =3D ExitInfo1; + Ghcb->SaveArea.SwExitInfo2 =3D ExitInfo2; + + // + // Guest memory is used for the guest-hypervisor communication, so=20 + fence // the invocation of the VMGEXIT instruction to ensure GHCB=20 + accesses are // synchronized properly. + // + MemoryFence (); + AsmVmgExit (); + MemoryFence (); + + return VmgExitErrorCheck (Ghcb); +} + +VOID +EFIAPI +VmgInit ( + GHCB *Ghcb + ) +{ + SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0); } + +VOID +EFIAPI +VmgDone ( + GHCB *Ghcb + ) +{ +} + +UINTN +EFIAPI +VmgMmio ( + UINT8 *MmioAddress, + UINT8 *Buffer, + UINTN Bytes, + BOOLEAN Write + ) +{ + UINT64 MmioOp, ExitInfo1, ExitInfo2, Status; + GHCB *Ghcb; + MSR_SEV_ES_GHCB_REGISTER Msr; + + Msr.GhcbPhysicalAddress =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb =3D= =20 + Msr.Ghcb; + + VmgInit (Ghcb); + + if (Write) { + MmioOp =3D SvmExitMmioWrite; + } else { + MmioOp =3D SvmExitMmioRead; + } + + ExitInfo1 =3D (UINT64) (UINTN) MmioAddress; + ExitInfo2 =3D Bytes; + + if (Write) { + CopyMem (Ghcb->SharedBuffer, Buffer, Bytes); } + + Ghcb->SaveArea.SwScratch =3D (UINT64) (UINTN) Ghcb->SharedBuffer; + Status =3D VmgExit (Ghcb, MmioOp, ExitInfo1, ExitInfo2); if (Status != =3D=20 + 0) { + return Status; + } + + if (!Write) { + CopyMem (Buffer, Ghcb->SharedBuffer, Bytes); } + + VmgDone (Ghcb); + + return 0; +} + +VOID +EFIAPI +VmgMmioWrite ( + UINT8 *Dest, + UINT8 *Src, + UINTN Bytes + ) +{ + VmgMmio (Dest, Src, Bytes, TRUE); +} + +UINTN +EFIAPI +VmgExitSetAPJumpTable ( + EFI_PHYSICAL_ADDRESS Address + ) +{ + UINT64 ExitInfo1, ExitInfo2, Status; + GHCB *Ghcb; + MSR_SEV_ES_GHCB_REGISTER Msr; + + Msr.GhcbPhysicalAddress =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb =3D= =20 + Msr.Ghcb; + + VmgInit (Ghcb); + + ExitInfo1 =3D 0; + ExitInfo2 =3D (UINT64) (UINTN) Address; + + Status =3D VmgExit (Ghcb, SvmExitApJumpTable, ExitInfo1, ExitInfo2); + + VmgDone (Ghcb); + + return Status; +} + diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni b/UefiCpuPkg/Lib= rary/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=20 +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