From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.43, mailfrom: ray.ni@intel.com) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by groups.io with SMTP; Mon, 19 Aug 2019 14:47:50 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Aug 2019 14:47:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,406,1559545200"; d="scan'208";a="180491620" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by orsmga003.jf.intel.com with ESMTP; 19 Aug 2019 14:47:46 -0700 Received: from fmsmsx124.amr.corp.intel.com (10.18.125.39) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 19 Aug 2019 14:47:46 -0700 Received: from shsmsx108.ccr.corp.intel.com (10.239.4.97) by fmsmsx124.amr.corp.intel.com (10.18.125.39) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 19 Aug 2019 14:47:45 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.112]) by SHSMSX108.ccr.corp.intel.com ([169.254.8.163]) with mapi id 14.03.0439.000; Tue, 20 Aug 2019 05:47:43 +0800 From: "Ni, Ray" To: "Lendacky, Thomas" , "devel@edk2.groups.io" CC: "Justen, Jordan L" , Laszlo Ersek , Ard Biesheuvel , "Kinney, Michael D" , "Gao, Liming" , "Dong, Eric" , "Singh, Brijesh" Subject: Re: [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support Thread-Topic: [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support Thread-Index: AQHVVtYdU3H6Cbe140mWPslbTNUFiKcDARqA Date: Mon, 19 Aug 2019 21:47:42 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C28D765@SHSMSX104.ccr.corp.intel.com> References: In-Reply-To: Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMzZhNzk5YTEtYjFjNS00OWI2LWIyNGQtNTZkOGU5OWZjMWQ5IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiOVRkT0dpQWdrRjhRZ3M4alEzcGpHS2M3dHZCWVN3cmhJQWdTU1JoeExHSzdxdGZkeWZ1dHZnZ0tJTlBuWHVhTiJ9 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: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Tom, 1. It's not a common practice to have static inline functions defined in he= ader file. Who is going to call them? 2. Recently I made a change to move the AMD registers definitions to MdePkg= /Include/Register/Amd from UefiCpuPkg. Do you think that's a good idea and = can you please put your new register definitions to MdePkg as well? 3. What happens if the "rep; vmmcall" is executed in Intel processor? Thanks, Ray > -----Original Message----- > From: Lendacky, Thomas > Sent: Monday, August 19, 2019 2:36 PM > To: devel@edk2.groups.io > Cc: Justen, Jordan L ; Laszlo Ersek ; Ard Biesheuvel > ; Kinney, Michael D ; Gao, Liming ; Dong, > Eric ; Ni, Ray ; Singh, Brijesh > Subject: [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support >=20 > From: Tom Lendacky >=20 > VMGEXIT is a new instruction used for Hypervisor/Guest communication when > running as an SEV-ES guest. A VMGEXIT will cause an automatic exit (AE) > to occur, resulting in a #VMEXIT with an exit code value of 0x403. >=20 > To support VMGEXIT, define the VMGEXIT assember routine to issue the > instruction (rep; vmmcall), the GHCB structure and some helper functions > for communicating register information to and from the hypervisor and the > guest. >=20 > Signed-off-by: Tom Lendacky > --- > MdePkg/Library/BaseLib/BaseLib.inf | 1 + > MdePkg/Include/Library/BaseLib.h | 14 ++ > UefiCpuPkg/Include/Register/Amd/Ghcb.h | 197 ++++++++++++++++++++++++ > MdePkg/Library/BaseLib/X64/GccInline.c | 17 ++ > MdePkg/Library/BaseLib/X64/VmgExit.nasm | 38 +++++ > 5 files changed, 267 insertions(+) > create mode 100644 UefiCpuPkg/Include/Register/Amd/Ghcb.h > create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm >=20 > diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/= BaseLib.inf > index 3586beb0ab5c..a41401340f95 100644 > --- a/MdePkg/Library/BaseLib/BaseLib.inf > +++ b/MdePkg/Library/BaseLib/BaseLib.inf > @@ -286,6 +286,7 @@ [Sources.X64] > X64/ReadCr2.nasm| MSFT > X64/ReadCr0.nasm| MSFT > X64/ReadEflags.nasm| MSFT > + X64/VmgExit.nasm | MSFT >=20 >=20 > X64/Non-existing.c > diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/Ba= seLib.h > index 2a75bc023f56..80bd5cf57a72 100644 > --- a/MdePkg/Include/Library/BaseLib.h > +++ b/MdePkg/Include/Library/BaseLib.h > @@ -7880,6 +7880,20 @@ AsmLfence ( > VOID > ); >=20 > +/** > + Executes a VMGEXIT instruction (VMMCALL with a REP prefix) > + > + Executes a VMGEXIT instruction. This function is only available on IA-= 32 and > + x64. > + > +**/ > +VOID > +EFIAPI > +AsmVmgExit ( > + VOID > + ); > + > + > /** > Patch the immediate operand of an IA32 or X64 instruction such that th= e byte, > word, dword or qword operand is encoded at the end of the instruction'= s > diff --git a/UefiCpuPkg/Include/Register/Amd/Ghcb.h b/UefiCpuPkg/Include/= Register/Amd/Ghcb.h > new file mode 100644 > index 000000000000..e9fd116fac25 > --- /dev/null > +++ b/UefiCpuPkg/Include/Register/Amd/Ghcb.h > @@ -0,0 +1,197 @@ > + > +#ifndef __GHCB_H__ > +#define __GHCB_H__ > + > +#include > +#include > +#include > + > +#define UD_EXCEPTION 6 > +#define GP_EXCEPTION 13 > + > +#define GHCB_VERSION_MIN 1 > +#define GHCB_VERSION_MAX 1 > + > +#define GHCB_STANDARD_USAGE 0 > + > +typedef enum { > + SvmExitDr7Read =3D 0x27, > + SvmExitDr7Write =3D 0x37, > + SvmExitRdtsc =3D 0x6E, > + SvmExitRdpmc, > + SvmExitCpuid =3D 0x72, > + SvmExitInvd =3D 0x76, > + SvmExitIoioProt =3D 0x7B, > + SvmExitMsr, > + SvmExitVmmCall =3D 0x81, > + SvmExitRdtscp =3D 0x87, > + SvmExitWbinvd =3D 0x89, > + SvmExitMonitor, > + SvmExitMwait, > + SvmExitNpf =3D 0x400, > + > + // VMG special exits > + SvmExitMmioRead =3D 0x80000001, > + SvmExitMmioWrite, > + SvmExitNmiComplete, > + SvmExitApResetHold, > + > + SvmExitUnsupported =3D 0x8000FFFF, > +} SVM_EXITCODE; > + > +typedef enum { > + GhcbCpl =3D 25, > + GhcbRflags =3D 46, > + GhcbRip, > + GhcbRsp =3D 59, > + GhcbRax =3D 63, > + GhcbRcx =3D 97, > + GhcbRdx, > + GhcbRbx, > + GhcbRbp =3D 101, > + GhcbRsi, > + GhcbRdi, > + GhcbR8, > + GhcbR9, > + GhcbR10, > + GhcbR11, > + GhcbR12, > + GhcbR13, > + GhcbR14, > + GhcbR15, > + GhcbXCr0 =3D 125, > +} GHCB_REGISTER; > + > +typedef struct { > + UINT8 Reserved1[203]; > + UINT8 Cpl; > + UINT8 Reserved2[148]; > + UINT64 Dr7; > + UINT8 Reserved3[144]; > + UINT64 Rax; > + UINT8 Reserved4[264]; > + UINT64 Rcx; > + UINT64 Rdx; > + UINT64 Rbx; > + UINT8 Reserved5[112]; > + UINT64 SwExitCode; > + UINT64 SwExitInfo1; > + UINT64 SwExitInfo2; > + UINT64 SwScratch; > + UINT8 Reserved6[56]; > + UINT64 XCr0; > + UINT8 ValidBitmap[16]; > + UINT64 X87StateGpa; > + UINT8 Reserved7[1016]; > +} __attribute__ ((__packed__)) GHCB_SAVE_AREA; > + > +typedef struct { > + GHCB_SAVE_AREA SaveArea; > + UINT8 SharedBuffer[2032]; > + UINT8 Reserved1[10]; > + UINT16 ProtocolVersion; > + UINT32 GhcbUsage; > +} __attribute__ ((__packed__)) __attribute__ ((aligned(SIZE_4KB))) GHCB; > + > +typedef union { > + struct { > + UINT32 Lower32Bits; > + UINT32 Upper32Bits; > + } Elements; > + > + UINT64 Uint64; > +} GHCB_EXIT_INFO; > + > +static inline > +BOOLEAN > +GhcbIsRegValid( > + GHCB *Ghcb, > + GHCB_REGISTER Reg > + ) > +{ > + UINT32 RegIndex =3D Reg / 8; > + UINT32 RegBit =3D Reg & 0x07; > + > + return (Ghcb->SaveArea.ValidBitmap[RegIndex] & (1 << RegBit)); > +} > + > +static inline > +VOID > +GhcbSetRegValid( > + GHCB *Ghcb, > + GHCB_REGISTER Reg > + ) > +{ > + UINT32 RegIndex =3D Reg / 8; > + UINT32 RegBit =3D Reg & 0x07; > + > + Ghcb->SaveArea.ValidBitmap[RegIndex] |=3D (1 << RegBit); > +} > + > +static inline > +VOID > +VmgException( > + UINTN Exception > + ) > +{ > + switch (Exception) { > + case UD_EXCEPTION: > + case GP_EXCEPTION: > + break; > + default: > + ASSERT (0); > + } > +} > + > +static inline > +UINTN > +VmgExit( > + GHCB *Ghcb, > + UINT64 ExitCode, > + UINT64 ExitInfo1, > + UINT64 ExitInfo2 > + ) > +{ > + GHCB_EXIT_INFO ExitInfo; > + UINTN Reason, Action; > + > + Ghcb->SaveArea.SwExitCode =3D ExitCode; > + Ghcb->SaveArea.SwExitInfo1 =3D ExitInfo1; > + Ghcb->SaveArea.SwExitInfo2 =3D ExitInfo2; > + AsmVmgExit (); > + > + if (!Ghcb->SaveArea.SwExitInfo1) { > + return 0; > + } > + > + ExitInfo.Uint64 =3D Ghcb->SaveArea.SwExitInfo1; > + Reason =3D ExitInfo.Elements.Upper32Bits; > + Action =3D ExitInfo.Elements.Lower32Bits; > + switch (Action) { > + case 1: > + VmgException (Reason); > + break; > + default: > + ASSERT (0); > + } > + > + return Reason; > +} > + > +static inline > +VOID > +VmgInit( > + GHCB *Ghcb > + ) > +{ > + SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0); > +} > + > +static inline > +VOID > +VmgDone( > + GHCB *Ghcb > + ) > +{ > +} > +#endif > diff --git a/MdePkg/Library/BaseLib/X64/GccInline.c b/MdePkg/Library/Base= Lib/X64/GccInline.c > index 154ce1f57e92..17539caa0798 100644 > --- a/MdePkg/Library/BaseLib/X64/GccInline.c > +++ b/MdePkg/Library/BaseLib/X64/GccInline.c > @@ -1798,3 +1798,20 @@ AsmFlushCacheLine ( > } >=20 >=20 > +/** > + Executes a VMGEXIT instruction. > + > + Executes a VMGEXIT instruction. This function is only available on IA-= 32 and > + X64. > + > +**/ > +VOID > +EFIAPI > +AsmVmgExit ( > + VOID > + ) > +{ > + __asm__ __volatile__ ("rep; vmmcall":::"memory"); > +} > + > + > diff --git a/MdePkg/Library/BaseLib/X64/VmgExit.nasm b/MdePkg/Library/Bas= eLib/X64/VmgExit.nasm > new file mode 100644 > index 000000000000..b673bb94b60d > --- /dev/null > +++ b/MdePkg/Library/BaseLib/X64/VmgExit.nasm > @@ -0,0 +1,38 @@ > +;-----------------------------------------------------------------------= ------- > +; > +; Copyright (c) 2019, Advanced Micro Device, Inc. All rights reserved. > +; This program and the accompanying materials > +; are licensed and made available under the terms and conditions of the = BSD License > +; which accompanies this distribution. The full text of the license may= be found at > +; http://opensource.org/licenses/bsd-license.php. > +; > +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +; > +; Module Name: > +; > +; VmgExit.Asm > +; > +; Abstract: > +; > +; AsmVmgExit function > +; > +; Notes: > +; > +;-----------------------------------------------------------------------= ------- > + > + DEFAULT REL > + SECTION .text > + > +;-----------------------------------------------------------------------= ------- > +; VOID > +; EFIAPI > +; AsmVmgExit ( > +; VOID > +; ); > +;-----------------------------------------------------------------------= ------- > +global ASM_PFX(AsmVmgExit) > +ASM_PFX(AsmVmgExit): > + rep; vmmcall > + ret > + > -- > 2.17.1