From: "Lendacky, Thomas" <thomas.lendacky@amd.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Jordan Justen <jordan.l.justen@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
Michael D Kinney <michael.d.kinney@intel.com>,
Liming Gao <liming.gao@intel.com>,
Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
"Singh, Brijesh" <brijesh.singh@amd.com>
Subject: [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support
Date: Mon, 19 Aug 2019 21:35:56 +0000 [thread overview]
Message-ID: <adf7bab8b01544a8cc8c66e59caf63561d6ecdf9.1566250534.git.thomas.lendacky@amd.com> (raw)
In-Reply-To: <cover.1566250534.git.thomas.lendacky@amd.com>
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:35 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 ` Lendacky, Thomas [this message]
2019-08-19 21:47 ` [RFC PATCH 08/28] MdePkg/BaseLib: Implement the VMGEXIT support Ni, Ray
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=adf7bab8b01544a8cc8c66e59caf63561d6ecdf9.1566250534.git.thomas.lendacky@amd.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