From: "Ni, Ray" <ray.ni@intel.com>
To: "Lendacky, Thomas" <Thomas.Lendacky@amd.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Justen, Jordan L" <jordan.l.justen@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
"Kinney, Michael D" <michael.d.kinney@intel.com>,
"Gao, Liming" <liming.gao@intel.com>,
"Dong, Eric" <eric.dong@intel.com>,
"Singh, Brijesh" <brijesh.singh@amd.com>
Subject: Re: [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support
Date: Mon, 19 Aug 2019 21:47:42 +0000 [thread overview]
Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C28D765@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <adf7bab8b01544a8cc8c66e59caf63561d6ecdf9.1566250534.git.thomas.lendacky@amd.com>
Tom,
1. It's not a common practice to have static inline functions defined in header 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 <Thomas.Lendacky@amd.com>
> Sent: Monday, August 19, 2019 2:36 PM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Singh, Brijesh <brijesh.singh@amd.com>
> Subject: [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support
>
> From: Tom Lendacky <thomas.lendacky@amd.com>
>
> 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.
>
> 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.
>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> 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
>
> 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
>
>
> X64/Non-existing.c
> diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
> index 2a75bc023f56..80bd5cf57a72 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -7880,6 +7880,20 @@ AsmLfence (
> VOID
> );
>
> +/**
> + 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 the 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 <Protocol/DebugSupport.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +#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 = 0x27,
> + SvmExitDr7Write = 0x37,
> + SvmExitRdtsc = 0x6E,
> + SvmExitRdpmc,
> + SvmExitCpuid = 0x72,
> + SvmExitInvd = 0x76,
> + SvmExitIoioProt = 0x7B,
> + SvmExitMsr,
> + SvmExitVmmCall = 0x81,
> + SvmExitRdtscp = 0x87,
> + SvmExitWbinvd = 0x89,
> + SvmExitMonitor,
> + SvmExitMwait,
> + SvmExitNpf = 0x400,
> +
> + // VMG special exits
> + SvmExitMmioRead = 0x80000001,
> + SvmExitMmioWrite,
> + SvmExitNmiComplete,
> + SvmExitApResetHold,
> +
> + SvmExitUnsupported = 0x8000FFFF,
> +} SVM_EXITCODE;
> +
> +typedef enum {
> + GhcbCpl = 25,
> + GhcbRflags = 46,
> + GhcbRip,
> + GhcbRsp = 59,
> + GhcbRax = 63,
> + GhcbRcx = 97,
> + GhcbRdx,
> + GhcbRbx,
> + GhcbRbp = 101,
> + GhcbRsi,
> + GhcbRdi,
> + GhcbR8,
> + GhcbR9,
> + GhcbR10,
> + GhcbR11,
> + GhcbR12,
> + GhcbR13,
> + GhcbR14,
> + GhcbR15,
> + GhcbXCr0 = 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 = Reg / 8;
> + UINT32 RegBit = Reg & 0x07;
> +
> + return (Ghcb->SaveArea.ValidBitmap[RegIndex] & (1 << RegBit));
> +}
> +
> +static inline
> +VOID
> +GhcbSetRegValid(
> + GHCB *Ghcb,
> + GHCB_REGISTER Reg
> + )
> +{
> + UINT32 RegIndex = Reg / 8;
> + UINT32 RegBit = Reg & 0x07;
> +
> + Ghcb->SaveArea.ValidBitmap[RegIndex] |= (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 = ExitCode;
> + Ghcb->SaveArea.SwExitInfo1 = ExitInfo1;
> + Ghcb->SaveArea.SwExitInfo2 = ExitInfo2;
> + AsmVmgExit ();
> +
> + if (!Ghcb->SaveArea.SwExitInfo1) {
> + return 0;
> + }
> +
> + ExitInfo.Uint64 = Ghcb->SaveArea.SwExitInfo1;
> + Reason = ExitInfo.Elements.Upper32Bits;
> + Action = 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/BaseLib/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 (
> }
>
>
> +/**
> + 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/BaseLib/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.<BR>
> +; 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 IMPLIED.
> +;
> +; 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
next prev parent reply other threads:[~2019-08-19 21:47 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-19 21:35 [RFC PATCH 00/28] SEV-ES guest support thomas.lendacky
2019-08-19 21:35 ` [RFC PATCH 01/28] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
2019-08-21 14:21 ` [edk2-devel] " Laszlo Ersek
2019-08-21 21:25 ` Lendacky, Thomas
2019-08-21 21:51 ` Jordan Justen
2019-08-22 13:46 ` Laszlo Ersek
2019-08-22 20:44 ` Jordan Justen
2019-08-23 13:32 ` Laszlo Ersek
2019-08-19 21:35 ` [RFC PATCH 02/28] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
2019-08-19 21:35 ` [RFC PATCH 03/28] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
2019-08-19 21:35 ` [RFC PATCH 04/28] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
2019-08-21 14:25 ` [edk2-devel] " Laszlo Ersek
2019-08-21 21:29 ` Lendacky, Thomas
2019-08-19 21:35 ` [RFC PATCH 05/28] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
2019-08-21 14:31 ` [edk2-devel] " Laszlo Ersek
2019-08-21 21:42 ` Lendacky, Thomas
2019-08-22 14:12 ` Laszlo Ersek
2019-08-22 15:24 ` Lendacky, Thomas
2019-08-23 13:26 ` Laszlo Ersek
2019-08-19 21:35 ` [RFC PATCH 06/28] OvmfPkg: A per-CPU variable area for #VC usage Lendacky, Thomas
2019-08-19 21:35 ` [RFC PATCH 07/28] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
2019-08-21 15:44 ` [edk2-devel] " Laszlo Ersek
2019-08-19 21:35 ` [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support Lendacky, Thomas
2019-08-19 21:47 ` Ni, Ray [this message]
2019-08-19 22:25 ` Lendacky, Thomas
2019-08-19 21:35 ` [RFC PATCH 09/28] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
2019-08-19 21:35 ` [RFC PATCH 10/28] UefiCpuPkg/CpuExceptionHandler: Add base #VC exception handling support for Sec phase Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 11/28] UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 12/28] UefiCpuPkg/CpuExceptionHandler: Support string IO " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 13/28] UefiCpuPkg/CpuExceptionHandler: Add support for CPUID " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 14/28] UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 15/28] UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO) Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 16/28] UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 17/28] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 18/28] UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 19/28] UefiCpuPkg/CpuExceptionHandler: Add support for INVD " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 20/28] UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 21/28] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 22/28] UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 23/28] UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 24/28] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write " Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 25/28] UefiCpuPkg/CpuExceptionHandler: Add base #VC exception handling support for Pei/Dxe phases Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 26/28] UefiCpuPkg/MpInitLib: Update CPU MP data with a flag to indicate if SEV-ES is active Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 27/28] UefiCpuPkg/MpInitLib: Allow AP booting under SEV-ES Lendacky, Thomas
2019-08-19 21:36 ` [RFC PATCH 28/28] UefiCpuPkg/MpInitLib: Introduce an MP finalization routine to support SEV-ES Lendacky, Thomas
2019-08-21 14:17 ` [edk2-devel] [RFC PATCH 00/28] SEV-ES guest support Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=734D49CCEBEEF84792F5B80ED585239D5C28D765@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox