* [PATCH v9 01/46] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 02/46] UefiCpuPkg: Create PCD " Lendacky, Thomas
` (44 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni, Jian J Wang,
Hao A Wu
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Two new dynamic MdeModulePkg PCDs are needed to support SEV-ES under OVMF:
- PcdGhcbBase: UINT64 value that is the base address of the GHCB
allocation.
- PcdGhcbSize: UINT64 value that is the size, in bytes, of the
GHCB allocation (size is dependent on the number of
APs).
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
MdeModulePkg/MdeModulePkg.dec | 9 +++++++++
MdeModulePkg/MdeModulePkg.uni | 8 ++++++++
2 files changed, 17 insertions(+)
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 4f44af694862..8085e761bbeb 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -2051,6 +2051,15 @@ [PcdsDynamic, PcdsDynamicEx]
# @Prompt If there is any test key used by the platform.
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed|FALSE|BOOLEAN|0x00030003
+ ## This dynamic PCD holds the base address of the GHCB pool allocation.
+ # @Prompt GHCB Pool Base Address
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0|UINT64|0x00030007
+
+ ## This dynamic PCD holds the total size of the GHCB pool allocation.
+ # The amount of memory allocated for GHCBs is dependent on the number of APs.
+ # @Prompt GHCB Pool Size
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0|UINT64|0x00030008
+
[PcdsDynamicEx]
## This dynamic PCD enables the default variable setting.
# Its value is the default store ID value. The default value is zero as Standard default.
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni
index 2007e0596c4f..2f8cca03e527 100644
--- a/MdeModulePkg/MdeModulePkg.uni
+++ b/MdeModulePkg/MdeModulePkg.uni
@@ -1297,3 +1297,11 @@
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdTcgPfpMeasurementRevision_PROMPT #language en-US "TCG Platform Firmware Profile revision"
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdTcgPfpMeasurementRevision_HELP #language en-US "Indicates which TCG Platform Firmware Profile revision the EDKII firmware follows."
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdGhcbBase_PROMPT #language en-US "GHCB Pool Base Address"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdGhcbBase_HELP #language en-US "Used with SEV-ES support to identify an address range that is not to be encrypted."
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdGhcbSize_PROMPT #language en-US "GHCB Pool Base Size"
+
+#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdGhcbSize_HELP #language en-US "Used with SEV-ES support to identify the size of the address range that is not to be encrypted."
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 02/46] UefiCpuPkg: Create PCD to be used in support of SEV-ES
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 01/46] MdeModulePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-12 0:50 ` [edk2-devel] " Dong, Eric
2020-06-05 13:26 ` [PATCH v9 03/46] MdePkg: Add the MSR definition for the GHCB register Lendacky, Thomas
` (43 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
A new dynamic UefiCpuPkg PCD is needed to support SEV-ES under OVMF:
- PcdSevEsIsEnabled: BOOLEAN value used to indicate if SEV-ES is enabled
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/UefiCpuPkg.dec | 6 ++++++
UefiCpuPkg/UefiCpuPkg.uni | 3 +++
2 files changed, 9 insertions(+)
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 762badf5d239..df5d02bae6b4 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -370,5 +370,11 @@ [PcdsDynamic, PcdsDynamicEx]
# @ValidRange 0x80000001 | 0 - 1
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme|0x0|UINT8|0x60000015
+ ## This dynamic PCD indicates whether SEV-ES is enabled
+ # TRUE - SEV-ES is enabled
+ # FALSE - SEV-ES is not enabled
+ # @Prompt SEV-ES Status
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000016
+
[UserExtensions.TianoCore."ExtraFiles"]
UefiCpuPkgExtra.uni
diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni
index 1780dfdc126d..f4a0c72f6293 100644
--- a/UefiCpuPkg/UefiCpuPkg.uni
+++ b/UefiCpuPkg/UefiCpuPkg.uni
@@ -278,3 +278,6 @@
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStatusCheckIntervalInMicroSeconds_PROMPT #language en-US "Periodic interval value in microseconds for AP status check in DXE.\n"
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStatusCheckIntervalInMicroSeconds_HELP #language en-US "Periodic interval value in microseconds for the status check of APs for StartupAllAPs() and StartupThisAP() executed in non-blocking mode in DXE phase.\n"
+
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_PROMPT #language en-US "Specifies whether SEV-ES is enabled"
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_HELP #language en-US "Set to TRUE when running as an SEV-ES guest, FALSE otherwise."
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 02/46] UefiCpuPkg: Create PCD to be used in support of SEV-ES
2020-06-05 13:26 ` [PATCH v9 02/46] UefiCpuPkg: Create PCD " Lendacky, Thomas
@ 2020-06-12 0:50 ` Dong, Eric
0 siblings, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-12 0:50 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Reviewed-by: Eric Dong <eric.dong@intel.com>
Thanks,
Eric
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Friday, June 5, 2020 9:27 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH v9 02/46] UefiCpuPkg: Create PCD to be used
> in support of SEV-ES
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> A new dynamic UefiCpuPkg PCD is needed to support SEV-ES under OVMF:
> - PcdSevEsIsEnabled: BOOLEAN value used to indicate if SEV-ES is enabled
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 6 ++++++
> UefiCpuPkg/UefiCpuPkg.uni | 3 +++
> 2 files changed, 9 insertions(+)
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index 762badf5d239..df5d02bae6b4 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -370,5 +370,11 @@ [PcdsDynamic, PcdsDynamicEx]
> # @ValidRange 0x80000001 | 0 - 1
>
> gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme|0x0|UINT8|
> 0x60000015
>
> + ## This dynamic PCD indicates whether SEV-ES is enabled
> + # TRUE - SEV-ES is enabled
> + # FALSE - SEV-ES is not enabled
> + # @Prompt SEV-ES Status
> +
> gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|FALSE|BOOLEAN|0x60000
> 016
> +
> [UserExtensions.TianoCore."ExtraFiles"]
> UefiCpuPkgExtra.uni
> diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni index
> 1780dfdc126d..f4a0c72f6293 100644
> --- a/UefiCpuPkg/UefiCpuPkg.uni
> +++ b/UefiCpuPkg/UefiCpuPkg.uni
> @@ -278,3 +278,6 @@
>
> #string
> STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStatusCheckIntervalInMicroSe
> conds_PROMPT #language en-US "Periodic interval value in microseconds
> for AP status check in DXE.\n"
> #string
> STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuApStatusCheckIntervalInMicroSe
> conds_HELP #language en-US "Periodic interval value in microseconds for
> the status check of APs for StartupAllAPs() and StartupThisAP() executed in
> non-blocking mode in DXE phase.\n"
> +
> +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_PROMPT
> #language en-US "Specifies whether SEV-ES is enabled"
> +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_HELP
> #language en-US "Set to TRUE when running as an SEV-ES guest, FALSE
> otherwise."
> --
> 2.27.0
>
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 03/46] MdePkg: Add the MSR definition for the GHCB register
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 01/46] MdeModulePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 02/46] UefiCpuPkg: Create PCD " Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 04/46] MdePkg: Add a structure definition for the GHCB Lendacky, Thomas
` (42 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
For SEV-ES, the GHCB page address is stored in the GHCB MSR register
(0xc0010130). Define the register and the format used for register
during GHCB protocol negotiation.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
MdePkg/Include/Register/Amd/Fam17Msr.h | 42 ++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index 6ef45a9b21d3..466a3143599c 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -17,6 +17,48 @@
#ifndef __FAM17_MSR_H__
#define __FAM17_MSR_H__
+/**
+ Secure Encrypted Virtualization - Encrypted State (SEV-ES) GHCB register
+
+**/
+#define MSR_SEV_ES_GHCB 0xc0010130
+
+/**
+ MSR information returned for #MSR_SEV_ES_GHCB
+**/
+typedef union {
+ struct {
+ UINT64 Function:12;
+ } GhcbInfo;
+
+ struct {
+ UINT8 Reserved[3];
+ UINT8 SevEncryptionBitPos;
+ UINT16 SevEsProtocolMin;
+ UINT16 SevEsProtocolMax;
+ } GhcbProtocol;
+
+ struct {
+ UINT64 Function:12;
+ UINT64 ReasonCodeSet:4;
+ UINT64 ReasonCode:8;
+ } GhcbTerminate;
+
+ VOID *Ghcb;
+
+ UINT64 GhcbPhysicalAddress;
+} MSR_SEV_ES_GHCB_REGISTER;
+
+#define GHCB_INFO_SEV_INFO 1
+#define GHCB_INFO_SEV_INFO_GET 2
+#define GHCB_INFO_CPUID_REQUEST 4
+#define GHCB_INFO_CPUID_RESPONSE 5
+#define GHCB_INFO_TERMINATE_REQUEST 256
+
+#define GHCB_TERMINATE_GHCB 0
+#define GHCB_TERMINATE_GHCB_GENERAL 0
+#define GHCB_TERMINATE_GHCB_PROTOCOL 1
+
/**
Secure Encrypted Virtualization (SEV) status register
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 04/46] MdePkg: Add a structure definition for the GHCB
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (2 preceding siblings ...)
2020-06-05 13:26 ` [PATCH v9 03/46] MdePkg: Add the MSR definition for the GHCB register Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 05/46] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables Lendacky, Thomas
` (41 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
The GHCB is used by an SEV-ES guest for communicating between the guest
and the hypervisor. Create the GHCB definition as defined by the GHCB
protocol definition.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
MdePkg/Include/Register/Amd/Ghcb.h | 166 ++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
new file mode 100644
index 000000000000..54a80da0f6d7
--- /dev/null
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -0,0 +1,166 @@
+/** @file
+ Guest-Hypervisor Communication Block (GHCB) Definition.
+
+ Provides data types allowing an SEV-ES guest to interact with the hypervisor
+ using the GHCB protocol.
+
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Specification Reference:
+ SEV-ES Guest-Hypervisor Communication Block Standardization
+
+**/
+
+#ifndef __GHCB_H__
+#define __GHCB_H__
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#define UD_EXCEPTION 6
+#define GP_EXCEPTION 13
+#define VC_EXCEPTION 29
+
+#define GHCB_VERSION_MIN 1
+#define GHCB_VERSION_MAX 1
+
+#define GHCB_STANDARD_USAGE 0
+
+//
+// SVM Exit Codes
+//
+#define SVM_EXIT_DR7_READ 0x27ULL
+#define SVM_EXIT_DR7_WRITE 0x37ULL
+#define SVM_EXIT_RDTSC 0x6EULL
+#define SVM_EXIT_RDPMC 0x6FULL
+#define SVM_EXIT_CPUID 0x72ULL
+#define SVM_EXIT_INVD 0x76ULL
+#define SVM_EXIT_IOIO_PROT 0x7BULL
+#define SVM_EXIT_MSR 0x7CULL
+#define SVM_EXIT_VMMCALL 0x81ULL
+#define SVM_EXIT_RDTSCP 0x87ULL
+#define SVM_EXIT_WBINVD 0x89ULL
+#define SVM_EXIT_MONITOR 0x8AULL
+#define SVM_EXIT_MWAIT 0x8BULL
+#define SVM_EXIT_NPF 0x400ULL
+
+//
+// VMG Special Exit Codes
+//
+#define SVM_EXIT_MMIO_READ 0x80000001ULL
+#define SVM_EXIT_MMIO_WRITE 0x80000002ULL
+#define SVM_EXIT_NMI_COMPLETE 0x80000003ULL
+#define SVM_EXIT_AP_RESET_HOLD 0x80000004ULL
+#define SVM_EXIT_AP_JUMP_TABLE 0x80000005ULL
+#define SVM_EXIT_UNSUPPORTED 0x8000FFFFULL
+
+//
+// IOIO Exit Information
+//
+#define IOIO_TYPE_STR BIT2
+#define IOIO_TYPE_IN 1
+#define IOIO_TYPE_INS (IOIO_TYPE_IN | IOIO_TYPE_STR)
+#define IOIO_TYPE_OUT 0
+#define IOIO_TYPE_OUTS (IOIO_TYPE_OUT | IOIO_TYPE_STR)
+
+#define IOIO_REP BIT3
+
+#define IOIO_ADDR_64 BIT9
+#define IOIO_ADDR_32 BIT8
+#define IOIO_ADDR_16 BIT7
+
+#define IOIO_DATA_32 BIT6
+#define IOIO_DATA_16 BIT5
+#define IOIO_DATA_8 BIT4
+#define IOIO_DATA_MASK (BIT6 | BIT5 | BIT4)
+#define IOIO_DATA_OFFSET 4
+#define IOIO_DATA_BYTES(x) (((x) & IOIO_DATA_MASK) >> IOIO_DATA_OFFSET)
+
+#define IOIO_SEG_ES 0
+#define IOIO_SEG_DS (BIT11 | BIT10)
+
+
+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 PACKED 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];
+} GHCB_SAVE_AREA;
+
+typedef PACKED struct {
+ GHCB_SAVE_AREA SaveArea;
+ UINT8 SharedBuffer[2032];
+ UINT8 Reserved1[10];
+ UINT16 ProtocolVersion;
+ UINT32 GhcbUsage;
+} GHCB;
+
+typedef union {
+ struct {
+ UINT32 Lower32Bits;
+ UINT32 Upper32Bits;
+ } Elements;
+
+ UINT64 Uint64;
+} GHCB_EXIT_INFO;
+
+typedef union {
+ struct {
+ UINT32 Vector:8;
+ UINT32 Type:3;
+ UINT32 ErrorCodeValid:1;
+ UINT32 Rsvd:19;
+ UINT32 Valid:1;
+ UINT32 ErrorCode;
+ } Elements;
+
+ UINT64 Uint64;
+} GHCB_EVENT_INJECTION;
+
+#define GHCB_EVENT_INJECTION_TYPE_INT 0
+#define GHCB_EVENT_INJECTION_TYPE_NMI 2
+#define GHCB_EVENT_INJECTION_TYPE_EXCEPTION 3
+#define GHCB_EVENT_INJECTION_TYPE_SOFT_INT 4
+
+#endif
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 05/46] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (3 preceding siblings ...)
2020-06-05 13:26 ` [PATCH v9 04/46] MdePkg: Add a structure definition for the GHCB Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
` (40 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni, Jian J Wang,
Hao A Wu, Dandan Bi
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
GHCB pages must be mapped as shared pages, so modify the process of
creating identity mapped pagetable entries so that GHCB entries are
created without the encryption bit set. The GHCB range consists of
two pages per CPU, the first being the GHCB and the second being a
per-CPU variable page. Only the GHCB page is mapped as shared.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h | 12 ++++-
MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +++-
MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 57 ++++++++++++++++----
5 files changed, 70 insertions(+), 16 deletions(-)
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 3f1702854660..19b8a4c8aefa 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -115,6 +115,8 @@ [Pcd.IA32,Pcd.X64]
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES
[Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
index 2d0493f109e8..6b7c38a441d6 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
@@ -201,6 +201,8 @@ EnableExecuteDisableBit (
@param[in, out] PageEntry2M Pointer to 2M page entry.
@param[in] StackBase Stack base address.
@param[in] StackSize Stack size.
+ @param[in] GhcbBase GHCB page area base address.
+ @param[in] GhcbSize GHCB page area size.
**/
VOID
@@ -208,7 +210,9 @@ Split2MPageTo4K (
IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
IN OUT UINT64 *PageEntry2M,
IN EFI_PHYSICAL_ADDRESS StackBase,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,
+ IN UINTN GhcbSize
);
/**
@@ -217,6 +221,8 @@ Split2MPageTo4K (
@param[in] StackBase Stack base address.
@param[in] StackSize Stack size.
+ @param[in] GhcbBase GHCB page area base address.
+ @param[in] GhcbSize GHCB page area size.
@return The address of 4 level page map.
@@ -224,7 +230,9 @@ Split2MPageTo4K (
UINTN
CreateIdentityMappingPageTables (
IN EFI_PHYSICAL_ADDRESS StackBase,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,
+ IN UINTN GhcbkSize
);
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index 6e8ca824d469..284b34818ca7 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -123,7 +123,7 @@ Create4GPageTablesIa32Pae (
//
// Need to split this 2M page that covers stack range.
//
- Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+ Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize, 0, 0);
} else {
//
// Fill in the Page Directory entries
@@ -282,7 +282,7 @@ HandOffToDxeCore (
//
// Create page table and save PageMapLevel4 to CR3
//
- PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE);
+ PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE, 0, 0);
//
// End of PEI phase signal
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index f465eb1d8ac4..156a477d8467 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
@@ -35,6 +35,8 @@ HandOffToDxeCore (
UINT32 Index;
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
+ VOID *GhcbBase;
+ UINTN GhcbSize;
//
// Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
@@ -81,12 +83,19 @@ HandOffToDxeCore (
TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+ //
+ // Get the address and size of the GHCB pages
+ //
+ GhcbBase = (VOID *) PcdGet64 (PcdGhcbBase);
+ GhcbSize = PcdGet64 (PcdGhcbSize);
+
PageTables = 0;
if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
//
// Create page table and save PageMapLevel4 to CR3
//
- PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE);
+ PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) GhcbBase, GhcbSize);
} else {
//
// Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
index 516cf908bc88..6831946c54d3 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
@@ -181,6 +181,8 @@ EnableExecuteDisableBit (
@param Size Size of the given physical memory.
@param StackBase Base address of stack.
@param StackSize Size of stack.
+ @param GhcbBase Base address of GHCB pages.
+ @param GhcbSize Size of GHCB area.
@retval TRUE Page table should be split.
@retval FALSE Page table should not be split.
@@ -190,7 +192,9 @@ ToSplitPageTable (
IN EFI_PHYSICAL_ADDRESS Address,
IN UINTN Size,
IN EFI_PHYSICAL_ADDRESS StackBase,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,
+ IN UINTN GhcbSize
)
{
if (IsNullDetectionEnabled () && Address == 0) {
@@ -209,6 +213,12 @@ ToSplitPageTable (
}
}
+ if (GhcbBase != 0) {
+ if ((Address < GhcbBase + GhcbSize) && ((Address + Size) > GhcbBase)) {
+ return TRUE;
+ }
+ }
+
return FALSE;
}
/**
@@ -322,6 +332,8 @@ AllocatePageTableMemory (
@param[in, out] PageEntry2M Pointer to 2M page entry.
@param[in] StackBase Stack base address.
@param[in] StackSize Stack size.
+ @param[in] GhcbBase GHCB page area base address.
+ @param[in] GhcbSize GHCB page area size.
**/
VOID
@@ -329,7 +341,9 @@ Split2MPageTo4K (
IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
IN OUT UINT64 *PageEntry2M,
IN EFI_PHYSICAL_ADDRESS StackBase,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,
+ IN UINTN GhcbSize
)
{
EFI_PHYSICAL_ADDRESS PhysicalAddress4K;
@@ -355,7 +369,20 @@ Split2MPageTo4K (
//
// Fill in the Page Table entries
//
- PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;
+ PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K;
+
+ //
+ // The GHCB range consists of two pages per CPU, the GHCB and a
+ // per-CPU variable page. The GHCB page needs to be mapped as an
+ // unencrypted page while the per-CPU variable page needs to be
+ // mapped encrypted. These pages alternate in assignment.
+ //
+ if ((GhcbBase == 0)
+ || (PhysicalAddress4K < GhcbBase)
+ || (PhysicalAddress4K >= GhcbBase + GhcbSize)
+ || (((PhysicalAddress4K - GhcbBase) & SIZE_4KB) != 0)) {
+ PageTableEntry->Uint64 |= AddressEncMask;
+ }
PageTableEntry->Bits.ReadWrite = 1;
if ((IsNullDetectionEnabled () && PhysicalAddress4K == 0) ||
@@ -383,6 +410,8 @@ Split2MPageTo4K (
@param[in, out] PageEntry1G Pointer to 1G page entry.
@param[in] StackBase Stack base address.
@param[in] StackSize Stack size.
+ @param[in] GhcbBase GHCB page area base address.
+ @param[in] GhcbSize GHCB page area size.
**/
VOID
@@ -390,7 +419,9 @@ Split1GPageTo2M (
IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
IN OUT UINT64 *PageEntry1G,
IN EFI_PHYSICAL_ADDRESS StackBase,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,
+ IN UINTN GhcbSize
)
{
EFI_PHYSICAL_ADDRESS PhysicalAddress2M;
@@ -413,11 +444,11 @@ Split1GPageTo2M (
PhysicalAddress2M = PhysicalAddress;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
- if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize)) {
+ if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) {
//
// Need to split this 2M page that covers NULL or stack range.
//
- Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+ Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize, GhcbBase, GhcbSize);
} else {
//
// Fill in the Page Directory entries
@@ -616,6 +647,8 @@ EnablePageTableProtection (
@param[in] StackBase Stack base address.
@param[in] StackSize Stack size.
+ @param[in] GhcbBase GHCB base address.
+ @param[in] GhcbSize GHCB size.
@return The address of 4 level page map.
@@ -623,7 +656,9 @@ EnablePageTableProtection (
UINTN
CreateIdentityMappingPageTables (
IN EFI_PHYSICAL_ADDRESS StackBase,
- IN UINTN StackSize
+ IN UINTN StackSize,
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,
+ IN UINTN GhcbSize
)
{
UINT32 RegEax;
@@ -809,8 +844,8 @@ CreateIdentityMappingPageTables (
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
- if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)) {
- Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);
+ if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize, GhcbBase, GhcbSize)) {
+ Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize, GhcbBase, GhcbSize);
} else {
//
// Fill in the Page Directory entries
@@ -840,11 +875,11 @@ CreateIdentityMappingPageTables (
PageDirectoryPointerEntry->Bits.Present = 1;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
- if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize)) {
+ if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) {
//
// Need to split this 2M page that covers NULL or stack range.
//
- Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+ Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize, GhcbBase, GhcbSize);
} else {
//
// Fill in the Page Directory entries
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (4 preceding siblings ...)
2020-06-05 13:26 ` [PATCH v9 05/46] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-07-03 2:39 ` [edk2-devel] " Zhiguang Liu
2020-06-05 13:26 ` [PATCH v9 07/46] MdePkg/BaseLib: Add support for the VMGEXIT instruction Lendacky, Thomas
` (39 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a CPUID instruction requires the current value of the XCR0
register. In order to retrieve that value, the XGETBV instruction needs
to be executed.
Provide the necessary support to execute the XGETBV instruction.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
MdePkg/Library/BaseLib/BaseLib.inf | 2 ++
MdePkg/Include/Library/BaseLib.h | 17 ++++++++++
MdePkg/Library/BaseLib/Ia32/GccInline.c | 28 ++++++++++++++++
MdePkg/Library/BaseLib/X64/GccInline.c | 30 +++++++++++++++++
MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 ++++++++++++++++++
MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 ++++++++++++++++++++
6 files changed, 142 insertions(+)
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index a57ae2da31f3..da6bc22a3e2b 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -153,6 +153,7 @@ [Sources.Ia32]
Ia32/ARShiftU64.c | MSFT
Ia32/EnableCache.c | MSFT
Ia32/DisableCache.c | MSFT
+ Ia32/XGetBv.nasm | MSFT
Ia32/GccInline.c | GCC
@@ -287,6 +288,7 @@ [Sources.X64]
X64/ReadCr2.nasm| MSFT
X64/ReadCr0.nasm| MSFT
X64/ReadEflags.nasm| MSFT
+ X64/XGetBv.nasm | MSFT
X64/Non-existing.c
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 8e7b87cbda4e..7edf0051a0a0 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7831,6 +7831,23 @@ AsmLfence (
VOID
);
+/**
+ Executes a XGETBV instruction
+
+ Executes a XGETBV instruction. This function is only available on IA-32 and
+ x64.
+
+ @param[in] Index Extended control register index
+
+ @return The current value of the extended control register
+**/
+UINT64
+EFIAPI
+AsmXGetBv (
+ IN UINT32 Index
+ );
+
+
/**
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/MdePkg/Library/BaseLib/Ia32/GccInline.c b/MdePkg/Library/BaseLib/Ia32/GccInline.c
index 5287200f8754..c962bcfa4617 100644
--- a/MdePkg/Library/BaseLib/Ia32/GccInline.c
+++ b/MdePkg/Library/BaseLib/Ia32/GccInline.c
@@ -1763,3 +1763,31 @@ AsmFlushCacheLine (
}
+/**
+ Executes a XGETBV instruction
+
+ Executes a XGETBV instruction. This function is only available on IA-32 and
+ x64.
+
+ @param[in] Index Extended control register index
+
+ @return The current value of the extended control register
+**/
+UINT64
+EFIAPI
+AsmXGetBv (
+ IN UINT32 Index
+ )
+{
+ UINT64 Data;
+
+ __asm__ __volatile__ (
+ "xgetbv"
+ : "=A" (Data)
+ : "c" (Index)
+ );
+
+ return Data;
+}
+
+
diff --git a/MdePkg/Library/BaseLib/X64/GccInline.c b/MdePkg/Library/BaseLib/X64/GccInline.c
index 154ce1f57e92..915555198f9f 100644
--- a/MdePkg/Library/BaseLib/X64/GccInline.c
+++ b/MdePkg/Library/BaseLib/X64/GccInline.c
@@ -1798,3 +1798,33 @@ AsmFlushCacheLine (
}
+/**
+ Executes a XGETBV instruction
+
+ Executes a XGETBV instruction. This function is only available on IA-32 and
+ x64.
+
+ @param[in] Index Extended control register index
+
+ @return The current value of the extended control register
+**/
+UINT64
+EFIAPI
+AsmXGetBv (
+ IN UINT32 Index
+ )
+{
+ UINT32 LowData;
+ UINT32 HighData;
+
+ __asm__ __volatile__ (
+ "xgetbv"
+ : "=a" (LowData),
+ "=d" (HighData)
+ : "c" (Index)
+ );
+
+ return (((UINT64)HighData) << 32) | LowData;
+}
+
+
diff --git a/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm b/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
new file mode 100644
index 000000000000..9f7b03bbff35
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
@@ -0,0 +1,31 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; XGetBv.Asm
+;
+; Abstract:
+;
+; AsmXgetBv function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; UINT64
+; EFIAPI
+; AsmXGetBv (
+; IN UINT32 Index
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmXGetBv)
+ASM_PFX(AsmXGetBv):
+ mov ecx, [esp + 4]
+ xgetbv
+ ret
diff --git a/MdePkg/Library/BaseLib/X64/XGetBv.nasm b/MdePkg/Library/BaseLib/X64/XGetBv.nasm
new file mode 100644
index 000000000000..09f3be8ae0a8
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/XGetBv.nasm
@@ -0,0 +1,34 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; XGetBv.Asm
+;
+; Abstract:
+;
+; AsmXgetBv function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; UINT64
+; EFIAPI
+; AsmXGetBv (
+; IN UINT32 Index
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmXGetBv)
+ASM_PFX(AsmXGetBv):
+ xgetbv
+ shl rdx, 32
+ or rax, rdx
+ ret
+
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction
2020-06-05 13:26 ` [PATCH v9 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
@ 2020-07-03 2:39 ` Zhiguang Liu
2020-07-06 20:13 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Zhiguang Liu @ 2020-07-03 2:39 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Brijesh Singh, Ard Biesheuvel, Dong, Eric, Justen, Jordan L,
Laszlo Ersek, Gao, Liming, Kinney, Michael D, Ni, Ray
Hi Tom,
I notice that you create a nasm file, which is good for cross-OS.
Why do you need to create a c file for the same function for GCC compiler when we can use nasm file in Linux?
Thanks
Zhiguang
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Friday, June 5, 2020 9:27 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH v9 06/46] MdePkg/BaseLib: Add support for
> the XGETBV instruction
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a CPUID instruction requires the current value of the XCR0
> register. In order to retrieve that value, the XGETBV instruction needs
> to be executed.
>
> Provide the necessary support to execute the XGETBV instruction.
>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> MdePkg/Library/BaseLib/BaseLib.inf | 2 ++
> MdePkg/Include/Library/BaseLib.h | 17 ++++++++++
> MdePkg/Library/BaseLib/Ia32/GccInline.c | 28 ++++++++++++++++
> MdePkg/Library/BaseLib/X64/GccInline.c | 30 +++++++++++++++++
> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 ++++++++++++++++++
> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 ++++++++++++++++++++
> 6 files changed, 142 insertions(+)
>
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> b/MdePkg/Library/BaseLib/BaseLib.inf
> index a57ae2da31f3..da6bc22a3e2b 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -153,6 +153,7 @@ [Sources.Ia32]
> Ia32/ARShiftU64.c | MSFT
>
>
> Ia32/EnableCache.c | MSFT
>
>
> Ia32/DisableCache.c | MSFT
>
>
> + Ia32/XGetBv.nasm | MSFT
>
>
>
>
>
>
>
>
> Ia32/GccInline.c | GCC
>
>
> @@ -287,6 +288,7 @@ [Sources.X64]
> X64/ReadCr2.nasm| MSFT
>
>
> X64/ReadCr0.nasm| MSFT
>
>
> X64/ReadEflags.nasm| MSFT
>
>
> + X64/XGetBv.nasm | MSFT
>
>
>
>
>
>
>
>
> X64/Non-existing.c
>
>
> diff --git a/MdePkg/Include/Library/BaseLib.h
> b/MdePkg/Include/Library/BaseLib.h
> index 8e7b87cbda4e..7edf0051a0a0 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -7831,6 +7831,23 @@ AsmLfence (
> VOID
>
>
> );
>
>
>
>
>
> +/**
>
>
> + Executes a XGETBV instruction
>
>
> +
>
>
> + Executes a XGETBV instruction. This function is only available on IA-32 and
>
>
> + x64.
>
>
> +
>
>
> + @param[in] Index Extended control register index
>
>
> +
>
>
> + @return The current value of the extended control register
>
>
> +**/
>
>
> +UINT64
>
>
> +EFIAPI
>
>
> +AsmXGetBv (
>
>
> + IN UINT32 Index
>
>
> + );
>
>
> +
>
>
> +
>
>
> /**
>
>
> 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/MdePkg/Library/BaseLib/Ia32/GccInline.c
> b/MdePkg/Library/BaseLib/Ia32/GccInline.c
> index 5287200f8754..c962bcfa4617 100644
> --- a/MdePkg/Library/BaseLib/Ia32/GccInline.c
> +++ b/MdePkg/Library/BaseLib/Ia32/GccInline.c
> @@ -1763,3 +1763,31 @@ AsmFlushCacheLine (
> }
>
>
>
>
>
>
>
>
> +/**
>
>
> + Executes a XGETBV instruction
>
>
> +
>
>
> + Executes a XGETBV instruction. This function is only available on IA-32 and
>
>
> + x64.
>
>
> +
>
>
> + @param[in] Index Extended control register index
>
>
> +
>
>
> + @return The current value of the extended control register
>
>
> +**/
>
>
> +UINT64
>
>
> +EFIAPI
>
>
> +AsmXGetBv (
>
>
> + IN UINT32 Index
>
>
> + )
>
>
> +{
>
>
> + UINT64 Data;
>
>
> +
>
>
> + __asm__ __volatile__ (
>
>
> + "xgetbv"
>
>
> + : "=A" (Data)
>
>
> + : "c" (Index)
>
>
> + );
>
>
> +
>
>
> + return Data;
>
>
> +}
>
>
> +
>
>
> +
>
>
> diff --git a/MdePkg/Library/BaseLib/X64/GccInline.c
> b/MdePkg/Library/BaseLib/X64/GccInline.c
> index 154ce1f57e92..915555198f9f 100644
> --- a/MdePkg/Library/BaseLib/X64/GccInline.c
> +++ b/MdePkg/Library/BaseLib/X64/GccInline.c
> @@ -1798,3 +1798,33 @@ AsmFlushCacheLine (
> }
>
>
>
>
>
>
>
>
> +/**
>
>
> + Executes a XGETBV instruction
>
>
> +
>
>
> + Executes a XGETBV instruction. This function is only available on IA-32 and
>
>
> + x64.
>
>
> +
>
>
> + @param[in] Index Extended control register index
>
>
> +
>
>
> + @return The current value of the extended control register
>
>
> +**/
>
>
> +UINT64
>
>
> +EFIAPI
>
>
> +AsmXGetBv (
>
>
> + IN UINT32 Index
>
>
> + )
>
>
> +{
>
>
> + UINT32 LowData;
>
>
> + UINT32 HighData;
>
>
> +
>
>
> + __asm__ __volatile__ (
>
>
> + "xgetbv"
>
>
> + : "=a" (LowData),
>
>
> + "=d" (HighData)
>
>
> + : "c" (Index)
>
>
> + );
>
>
> +
>
>
> + return (((UINT64)HighData) << 32) | LowData;
>
>
> +}
>
>
> +
>
>
> +
>
>
> diff --git a/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> b/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> new file mode 100644
> index 000000000000..9f7b03bbff35
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> @@ -0,0 +1,31 @@
> +;------------------------------------------------------------------------------
>
>
> +;
>
>
> +; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
> +;
>
>
> +; Module Name:
>
>
> +;
>
>
> +; XGetBv.Asm
>
>
> +;
>
>
> +; Abstract:
>
>
> +;
>
>
> +; AsmXgetBv function
>
>
> +;
>
>
> +; Notes:
>
>
> +;
>
>
> +;------------------------------------------------------------------------------
>
>
> +
>
>
> + SECTION .text
>
>
> +
>
>
> +;------------------------------------------------------------------------------
>
>
> +; UINT64
>
>
> +; EFIAPI
>
>
> +; AsmXGetBv (
>
>
> +; IN UINT32 Index
>
>
> +; );
>
>
> +;------------------------------------------------------------------------------
>
>
> +global ASM_PFX(AsmXGetBv)
>
>
> +ASM_PFX(AsmXGetBv):
>
>
> + mov ecx, [esp + 4]
>
>
> + xgetbv
>
>
> + ret
>
>
> diff --git a/MdePkg/Library/BaseLib/X64/XGetBv.nasm
> b/MdePkg/Library/BaseLib/X64/XGetBv.nasm
> new file mode 100644
> index 000000000000..09f3be8ae0a8
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/X64/XGetBv.nasm
> @@ -0,0 +1,34 @@
> +;------------------------------------------------------------------------------
>
>
> +;
>
>
> +; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
> +;
>
>
> +; Module Name:
>
>
> +;
>
>
> +; XGetBv.Asm
>
>
> +;
>
>
> +; Abstract:
>
>
> +;
>
>
> +; AsmXgetBv function
>
>
> +;
>
>
> +; Notes:
>
>
> +;
>
>
> +;------------------------------------------------------------------------------
>
>
> +
>
>
> + DEFAULT REL
>
>
> + SECTION .text
>
>
> +
>
>
> +;------------------------------------------------------------------------------
>
>
> +; UINT64
>
>
> +; EFIAPI
>
>
> +; AsmXGetBv (
>
>
> +; IN UINT32 Index
>
>
> +; );
>
>
> +;------------------------------------------------------------------------------
>
>
> +global ASM_PFX(AsmXGetBv)
>
>
> +ASM_PFX(AsmXGetBv):
>
>
> + xgetbv
>
>
> + shl rdx, 32
>
>
> + or rax, rdx
>
>
> + ret
>
>
> +
>
>
> --
> 2.27.0
>
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction
2020-07-03 2:39 ` [edk2-devel] " Zhiguang Liu
@ 2020-07-06 20:13 ` Lendacky, Thomas
0 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-07-06 20:13 UTC (permalink / raw)
To: Liu, Zhiguang, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Dong, Eric, Justen, Jordan L,
Laszlo Ersek, Gao, Liming, Kinney, Michael D, Ni, Ray
On 7/2/20 9:39 PM, Liu, Zhiguang wrote:
> Hi Tom,
Hi Zhiguang,
> I notice that you create a nasm file, which is good for cross-OS.
> Why do you need to create a c file for the same function for GCC compiler when we can use nasm file in Linux?
I was just following convention. I noticed that many of the instructions
are implemented in both a nasm file and added to the GccInline.c file, so
I did the same. On my Linux builds, the GccInline.c file is used.
Thanks,
Tom
> Thanks
> Zhiguang
>
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Friday, June 5, 2020 9:27 PM
>> To: devel@edk2.groups.io
>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
>> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
>> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: [edk2-devel] [PATCH v9 06/46] MdePkg/BaseLib: Add support for
>> the XGETBV instruction
>>
>> 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%7C2372d38165954f1aa53908d81efa4f45%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637293407713911481&sdata=DDC3mR7wrER3vL9xKLBKnyrXJRxm4BUqqehksVLieD4%3D&reserved=0
>>
>> Under SEV-ES, a CPUID instruction requires the current value of the XCR0
>> register. In order to retrieve that value, the XGETBV instruction needs
>> to be executed.
>>
>> Provide the necessary support to execute the XGETBV instruction.
>>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Liming Gao <liming.gao@intel.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> MdePkg/Library/BaseLib/BaseLib.inf | 2 ++
>> MdePkg/Include/Library/BaseLib.h | 17 ++++++++++
>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 28 ++++++++++++++++
>> MdePkg/Library/BaseLib/X64/GccInline.c | 30 +++++++++++++++++
>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 ++++++++++++++++++
>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 ++++++++++++++++++++
>> 6 files changed, 142 insertions(+)
>>
>> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
>> b/MdePkg/Library/BaseLib/BaseLib.inf
>> index a57ae2da31f3..da6bc22a3e2b 100644
>> --- a/MdePkg/Library/BaseLib/BaseLib.inf
>> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
>> @@ -153,6 +153,7 @@ [Sources.Ia32]
>> Ia32/ARShiftU64.c | MSFT
>>
>>
>> Ia32/EnableCache.c | MSFT
>>
>>
>> Ia32/DisableCache.c | MSFT
>>
>>
>> + Ia32/XGetBv.nasm | MSFT
>>
>>
>>
>>
>>
>>
>>
>>
>> Ia32/GccInline.c | GCC
>>
>>
>> @@ -287,6 +288,7 @@ [Sources.X64]
>> X64/ReadCr2.nasm| MSFT
>>
>>
>> X64/ReadCr0.nasm| MSFT
>>
>>
>> X64/ReadEflags.nasm| MSFT
>>
>>
>> + X64/XGetBv.nasm | MSFT
>>
>>
>>
>>
>>
>>
>>
>>
>> X64/Non-existing.c
>>
>>
>> diff --git a/MdePkg/Include/Library/BaseLib.h
>> b/MdePkg/Include/Library/BaseLib.h
>> index 8e7b87cbda4e..7edf0051a0a0 100644
>> --- a/MdePkg/Include/Library/BaseLib.h
>> +++ b/MdePkg/Include/Library/BaseLib.h
>> @@ -7831,6 +7831,23 @@ AsmLfence (
>> VOID
>>
>>
>> );
>>
>>
>>
>>
>>
>> +/**
>>
>>
>> + Executes a XGETBV instruction
>>
>>
>> +
>>
>>
>> + Executes a XGETBV instruction. This function is only available on IA-32 and
>>
>>
>> + x64.
>>
>>
>> +
>>
>>
>> + @param[in] Index Extended control register index
>>
>>
>> +
>>
>>
>> + @return The current value of the extended control register
>>
>>
>> +**/
>>
>>
>> +UINT64
>>
>>
>> +EFIAPI
>>
>>
>> +AsmXGetBv (
>>
>>
>> + IN UINT32 Index
>>
>>
>> + );
>>
>>
>> +
>>
>>
>> +
>>
>>
>> /**
>>
>>
>> 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/MdePkg/Library/BaseLib/Ia32/GccInline.c
>> b/MdePkg/Library/BaseLib/Ia32/GccInline.c
>> index 5287200f8754..c962bcfa4617 100644
>> --- a/MdePkg/Library/BaseLib/Ia32/GccInline.c
>> +++ b/MdePkg/Library/BaseLib/Ia32/GccInline.c
>> @@ -1763,3 +1763,31 @@ AsmFlushCacheLine (
>> }
>>
>>
>>
>>
>>
>>
>>
>>
>> +/**
>>
>>
>> + Executes a XGETBV instruction
>>
>>
>> +
>>
>>
>> + Executes a XGETBV instruction. This function is only available on IA-32 and
>>
>>
>> + x64.
>>
>>
>> +
>>
>>
>> + @param[in] Index Extended control register index
>>
>>
>> +
>>
>>
>> + @return The current value of the extended control register
>>
>>
>> +**/
>>
>>
>> +UINT64
>>
>>
>> +EFIAPI
>>
>>
>> +AsmXGetBv (
>>
>>
>> + IN UINT32 Index
>>
>>
>> + )
>>
>>
>> +{
>>
>>
>> + UINT64 Data;
>>
>>
>> +
>>
>>
>> + __asm__ __volatile__ (
>>
>>
>> + "xgetbv"
>>
>>
>> + : "=A" (Data)
>>
>>
>> + : "c" (Index)
>>
>>
>> + );
>>
>>
>> +
>>
>>
>> + return Data;
>>
>>
>> +}
>>
>>
>> +
>>
>>
>> +
>>
>>
>> diff --git a/MdePkg/Library/BaseLib/X64/GccInline.c
>> b/MdePkg/Library/BaseLib/X64/GccInline.c
>> index 154ce1f57e92..915555198f9f 100644
>> --- a/MdePkg/Library/BaseLib/X64/GccInline.c
>> +++ b/MdePkg/Library/BaseLib/X64/GccInline.c
>> @@ -1798,3 +1798,33 @@ AsmFlushCacheLine (
>> }
>>
>>
>>
>>
>>
>>
>>
>>
>> +/**
>>
>>
>> + Executes a XGETBV instruction
>>
>>
>> +
>>
>>
>> + Executes a XGETBV instruction. This function is only available on IA-32 and
>>
>>
>> + x64.
>>
>>
>> +
>>
>>
>> + @param[in] Index Extended control register index
>>
>>
>> +
>>
>>
>> + @return The current value of the extended control register
>>
>>
>> +**/
>>
>>
>> +UINT64
>>
>>
>> +EFIAPI
>>
>>
>> +AsmXGetBv (
>>
>>
>> + IN UINT32 Index
>>
>>
>> + )
>>
>>
>> +{
>>
>>
>> + UINT32 LowData;
>>
>>
>> + UINT32 HighData;
>>
>>
>> +
>>
>>
>> + __asm__ __volatile__ (
>>
>>
>> + "xgetbv"
>>
>>
>> + : "=a" (LowData),
>>
>>
>> + "=d" (HighData)
>>
>>
>> + : "c" (Index)
>>
>>
>> + );
>>
>>
>> +
>>
>>
>> + return (((UINT64)HighData) << 32) | LowData;
>>
>>
>> +}
>>
>>
>> +
>>
>>
>> +
>>
>>
>> diff --git a/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>> b/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>> new file mode 100644
>> index 000000000000..9f7b03bbff35
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>> @@ -0,0 +1,31 @@
>> +;------------------------------------------------------------------------------
>>
>>
>> +;
>>
>>
>> +; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>>
>>
>> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>>
>> +;
>>
>>
>> +; Module Name:
>>
>>
>> +;
>>
>>
>> +; XGetBv.Asm
>>
>>
>> +;
>>
>>
>> +; Abstract:
>>
>>
>> +;
>>
>>
>> +; AsmXgetBv function
>>
>>
>> +;
>>
>>
>> +; Notes:
>>
>>
>> +;
>>
>>
>> +;------------------------------------------------------------------------------
>>
>>
>> +
>>
>>
>> + SECTION .text
>>
>>
>> +
>>
>>
>> +;------------------------------------------------------------------------------
>>
>>
>> +; UINT64
>>
>>
>> +; EFIAPI
>>
>>
>> +; AsmXGetBv (
>>
>>
>> +; IN UINT32 Index
>>
>>
>> +; );
>>
>>
>> +;------------------------------------------------------------------------------
>>
>>
>> +global ASM_PFX(AsmXGetBv)
>>
>>
>> +ASM_PFX(AsmXGetBv):
>>
>>
>> + mov ecx, [esp + 4]
>>
>>
>> + xgetbv
>>
>>
>> + ret
>>
>>
>> diff --git a/MdePkg/Library/BaseLib/X64/XGetBv.nasm
>> b/MdePkg/Library/BaseLib/X64/XGetBv.nasm
>> new file mode 100644
>> index 000000000000..09f3be8ae0a8
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseLib/X64/XGetBv.nasm
>> @@ -0,0 +1,34 @@
>> +;------------------------------------------------------------------------------
>>
>>
>> +;
>>
>>
>> +; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>>
>>
>> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>>
>> +;
>>
>>
>> +; Module Name:
>>
>>
>> +;
>>
>>
>> +; XGetBv.Asm
>>
>>
>> +;
>>
>>
>> +; Abstract:
>>
>>
>> +;
>>
>>
>> +; AsmXgetBv function
>>
>>
>> +;
>>
>>
>> +; Notes:
>>
>>
>> +;
>>
>>
>> +;------------------------------------------------------------------------------
>>
>>
>> +
>>
>>
>> + DEFAULT REL
>>
>>
>> + SECTION .text
>>
>>
>> +
>>
>>
>> +;------------------------------------------------------------------------------
>>
>>
>> +; UINT64
>>
>>
>> +; EFIAPI
>>
>>
>> +; AsmXGetBv (
>>
>>
>> +; IN UINT32 Index
>>
>>
>> +; );
>>
>>
>> +;------------------------------------------------------------------------------
>>
>>
>> +global ASM_PFX(AsmXGetBv)
>>
>>
>> +ASM_PFX(AsmXGetBv):
>>
>>
>> + xgetbv
>>
>>
>> + shl rdx, 32
>>
>>
>> + or rax, rdx
>>
>>
>> + ret
>>
>>
>> +
>>
>>
>> --
>> 2.27.0
>>
>>
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 07/46] MdePkg/BaseLib: Add support for the VMGEXIT instruction
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (5 preceding siblings ...)
2020-06-05 13:26 ` [PATCH v9 06/46] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-05 13:26 ` [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
` (38 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
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.
Provide the necessary support to execute the VMGEXIT instruction, which
is "rep; vmmcall".
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
MdePkg/Library/BaseLib/BaseLib.inf | 2 ++
MdePkg/Include/Library/BaseLib.h | 14 ++++++++
MdePkg/Library/BaseLib/Ia32/GccInline.c | 17 +++++++++
MdePkg/Library/BaseLib/X64/GccInline.c | 17 +++++++++
MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 ++++++++++++++++++++
MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +++++++++++++++++
6 files changed, 119 insertions(+)
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index da6bc22a3e2b..7cf6467fa77b 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -154,6 +154,7 @@ [Sources.Ia32]
Ia32/EnableCache.c | MSFT
Ia32/DisableCache.c | MSFT
Ia32/XGetBv.nasm | MSFT
+ Ia32/VmgExit.nasm | MSFT
Ia32/GccInline.c | GCC
@@ -289,6 +290,7 @@ [Sources.X64]
X64/ReadCr0.nasm| MSFT
X64/ReadEflags.nasm| MSFT
X64/XGetBv.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 7edf0051a0a0..04fb329eaabb 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7848,6 +7848,20 @@ AsmXGetBv (
);
+/**
+ 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/MdePkg/Library/BaseLib/Ia32/GccInline.c b/MdePkg/Library/BaseLib/Ia32/GccInline.c
index c962bcfa4617..d6a7581b36f6 100644
--- a/MdePkg/Library/BaseLib/Ia32/GccInline.c
+++ b/MdePkg/Library/BaseLib/Ia32/GccInline.c
@@ -1791,3 +1791,20 @@ AsmXGetBv (
}
+/**
+ 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/GccInline.c b/MdePkg/Library/BaseLib/X64/GccInline.c
index 915555198f9f..0685337bbb56 100644
--- a/MdePkg/Library/BaseLib/X64/GccInline.c
+++ b/MdePkg/Library/BaseLib/X64/GccInline.c
@@ -1828,3 +1828,20 @@ AsmXGetBv (
}
+/**
+ 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/Ia32/VmgExit.nasm b/MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
new file mode 100644
index 000000000000..a4b37385cc7a
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; VmgExit.Asm
+;
+; Abstract:
+;
+; AsmVmgExit function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmVmgExit (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmVmgExit)
+ASM_PFX(AsmVmgExit):
+;
+; NASM doesn't support the vmmcall instruction in 32-bit mode, so work around
+; this by temporarily switching to 64-bit mode.
+;
+BITS 64
+ rep vmmcall
+BITS 32
+ ret
+
diff --git a/MdePkg/Library/BaseLib/X64/VmgExit.nasm b/MdePkg/Library/BaseLib/X64/VmgExit.nasm
new file mode 100644
index 000000000000..26f034593c67
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/VmgExit.nasm
@@ -0,0 +1,32 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; 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.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (6 preceding siblings ...)
2020-06-05 13:26 ` [PATCH v9 07/46] MdePkg/BaseLib: Add support for the VMGEXIT instruction Lendacky, Thomas
@ 2020-06-05 13:26 ` Lendacky, Thomas
2020-06-12 0:56 ` Dong, Eric
2020-06-18 7:23 ` Dong, Eric
2020-06-05 13:27 ` [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
` (37 subsequent siblings)
45 siblings, 2 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:26 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
To support handling #VC exceptions and issuing VMGEXIT instructions,
create a library with functions that can be used to perform these
#VC/VMGEXIT related operations. This includes functions for:
- Handling #VC exceptions
- Preparing for and issuing a VMGEXIT
- Performing MMIO-related write operations to support flash emulation
- Performing AP related boot opeations
The base functions in this driver will not do anything and will return
an error if a return value is required. It is expected that other packages
(like OvmfPkg) will create a version of the library to fully support an
SEV-ES guest.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/UefiCpuPkg.dec | 3 +
UefiCpuPkg/UefiCpuPkg.dsc | 2 +
UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
UefiCpuPkg/Include/Library/VmgExitLib.h | 103 +++++++++++++++++
UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121 ++++++++++++++++++++
UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
6 files changed, 271 insertions(+)
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 afa304128221..f0e58b90ff0a 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -56,6 +56,7 @@ [LibraryClasses]
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.SEC]
PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
@@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
+ UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
UefiCpuPkg/SecCore/SecCore.inf
diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
new file mode 100644
index 000000000000..d8770a21c355
--- /dev/null
+++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
@@ -0,0 +1,27 @@
+## @file
+# VMGEXIT Support Library.
+#
+# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = VmgExitLibNull
+ MODULE_UNI_FILE = VmgExitLibNull.uni
+ FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = VmgExitLib
+
+[Sources.common]
+ VmgExitLibNull.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..0b2f39026a4a
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
@@ -0,0 +1,103 @@
+/** @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 and to handle #VC exceptions.
+
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __VMG_EXIT_LIB_H__
+#define __VMG_EXIT_LIB_H__
+
+#include <Protocol/DebugSupport.h>
+#include <Register/Amd/Ghcb.h>
+
+
+/**
+ 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.
+
+ @return 0 VMGEXIT succeeded.
+ @return 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
+ );
+
+/**
+ Handle a #VC exception.
+
+ Performs the necessary processing to handle a #VC exception.
+
+ The base library function returns an error equal to VC_EXCEPTION,
+ to be propagated to the standard exception handling stack.
+
+ @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
+ as value to use on error.
+ @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
+
+ @retval EFI_SUCCESS Exception handled
+ @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
+ propagate provided
+ @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
+ propagate provided
+
+**/
+EFI_STATUS
+EFIAPI
+VmgExitHandleVc (
+ IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+#endif
diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
new file mode 100644
index 000000000000..30a239df298e
--- /dev/null
+++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
@@ -0,0 +1,121 @@
+/** @file
+ VMGEXIT Base Support Library.
+
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/VmgExitLib.h>
+
+/**
+ Perform VMGEXIT.
+
+ Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and
+ then handles the return actions.
+
+ The base library function returns an error in the form of a
+ GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
+
+ @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.
+
+ @return 0 VMGEXIT succeeded.
+ @return Others VMGEXIT processing did not succeed. Exception
+ event to be propagated.
+
+**/
+UINT64
+EFIAPI
+VmgExit (
+ IN OUT GHCB *Ghcb,
+ IN UINT64 ExitCode,
+ IN UINT64 ExitInfo1,
+ IN UINT64 ExitInfo2
+ )
+{
+ GHCB_EVENT_INJECTION Event;
+
+ Event.Uint64 = 0;
+ Event.Elements.Vector = GP_EXCEPTION;
+ Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
+ Event.Elements.Valid = 1;
+
+ return Event.Uint64;
+}
+
+/**
+ Perform pre-VMGEXIT initialization/preparation.
+
+ Performs the necessary steps in preparation for invoking VMGEXIT. Must be
+ called before setting any fields within the GHCB.
+
+ The base library function does nothing.
+
+ @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.
+
+ The base library function does nothing.
+
+ @param[in, out] Ghcb A pointer to the GHCB
+
+**/
+VOID
+EFIAPI
+VmgDone (
+ IN OUT GHCB *Ghcb
+ )
+{
+}
+
+/**
+ Handle a #VC exception.
+
+ Performs the necessary processing to handle a #VC exception.
+
+ The base library function returns an error equal to VC_EXCEPTION,
+ to be propagated to the standard exception handling stack.
+
+ @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
+ as value to use on error.
+ @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
+
+ @retval EFI_SUCCESS Exception handled
+ @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
+ propagate provided
+ @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
+ propagate provided
+
+**/
+EFI_STATUS
+EFIAPI
+VmgExitHandleVc (
+ IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ *ExceptionType = VC_EXCEPTION;
+
+ return EFI_UNSUPPORTED;
+}
diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
new file mode 100644
index 000000000000..8639bc0e8ce9
--- /dev/null
+++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
@@ -0,0 +1,15 @@
+// /** @file
+// VMGEXIT support library instance.
+//
+// VMGEXIT support library instance.
+//
+// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT support NULL library instance"
+
+#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT support NULL library instance."
+
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-05 13:26 ` [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
@ 2020-06-12 0:56 ` Dong, Eric
2020-06-18 7:23 ` Dong, Eric
1 sibling, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-12 0:56 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Reviewed-by: Eric Dong <eric.dong@intel.com>
Thanks,
Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:27 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 08/46] UefiCpuPkg: Implement library support for
> VMGEXIT
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> To support handling #VC exceptions and issuing VMGEXIT instructions,
> create a library with functions that can be used to perform these
> #VC/VMGEXIT related operations. This includes functions for:
> - Handling #VC exceptions
> - Preparing for and issuing a VMGEXIT
> - Performing MMIO-related write operations to support flash emulation
> - Performing AP related boot opeations
>
> The base functions in this driver will not do anything and will return
> an error if a return value is required. It is expected that other packages
> (like OvmfPkg) will create a version of the library to fully support an
> SEV-ES guest.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 3 +
> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
> UefiCpuPkg/Include/Library/VmgExitLib.h | 103 +++++++++++++++++
> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121
> ++++++++++++++++++++
> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
> 6 files changed, 271 insertions(+)
>
> 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 afa304128221..f0e58b90ff0a 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/VmgExitLibNull/VmgExitLibNull.inf
>
>
>
> [LibraryClasses.common.SEC]
>
>
> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.i
> nf
>
> @@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
>
> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
> Null.inf
>
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
>
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
>
> + UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
>
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
>
> UefiCpuPkg/SecCore/SecCore.inf
>
> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> new file mode 100644
> index 000000000000..d8770a21c355
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> @@ -0,0 +1,27 @@
> +## @file
>
> +# VMGEXIT Support Library.
>
> +#
>
> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = VmgExitLibNull
>
> + MODULE_UNI_FILE = VmgExitLibNull.uni
>
> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
>
> + MODULE_TYPE = BASE
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = VmgExitLib
>
> +
>
> +[Sources.common]
>
> + VmgExitLibNull.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..0b2f39026a4a
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
> @@ -0,0 +1,103 @@
> +/** @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 and to handle #VC exceptions.
>
> +
>
> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef __VMG_EXIT_LIB_H__
>
> +#define __VMG_EXIT_LIB_H__
>
> +
>
> +#include <Protocol/DebugSupport.h>
>
> +#include <Register/Amd/Ghcb.h>
>
> +
>
> +
>
> +/**
>
> + 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.
>
> +
>
> + @return 0 VMGEXIT succeeded.
>
> + @return 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
>
> + );
>
> +
>
> +/**
>
> + Handle a #VC exception.
>
> +
>
> + Performs the necessary processing to handle a #VC exception.
>
> +
>
> + The base library function returns an error equal to VC_EXCEPTION,
>
> + to be propagated to the standard exception handling stack.
>
> +
>
> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be
> set
>
> + as value to use on error.
>
> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>
> +
>
> + @retval EFI_SUCCESS Exception handled
>
> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
> value to
>
> + propagate provided
>
> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
> value to
>
> + propagate provided
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +VmgExitHandleVc (
>
> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>
> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>
> + );
>
> +
>
> +#endif
>
> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> new file mode 100644
> index 000000000000..30a239df298e
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> @@ -0,0 +1,121 @@
> +/** @file
>
> + VMGEXIT Base Support Library.
>
> +
>
> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <Base.h>
>
> +#include <Uefi.h>
>
> +#include <Library/VmgExitLib.h>
>
> +
>
> +/**
>
> + Perform VMGEXIT.
>
> +
>
> + Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction
> and
>
> + then handles the return actions.
>
> +
>
> + The base library function returns an error in the form of a
>
> + GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
>
> +
>
> + @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.
>
> +
>
> + @return 0 VMGEXIT succeeded.
>
> + @return Others VMGEXIT processing did not succeed. Exception
>
> + event to be propagated.
>
> +
>
> +**/
>
> +UINT64
>
> +EFIAPI
>
> +VmgExit (
>
> + IN OUT GHCB *Ghcb,
>
> + IN UINT64 ExitCode,
>
> + IN UINT64 ExitInfo1,
>
> + IN UINT64 ExitInfo2
>
> + )
>
> +{
>
> + GHCB_EVENT_INJECTION Event;
>
> +
>
> + Event.Uint64 = 0;
>
> + Event.Elements.Vector = GP_EXCEPTION;
>
> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
>
> + Event.Elements.Valid = 1;
>
> +
>
> + return Event.Uint64;
>
> +}
>
> +
>
> +/**
>
> + Perform pre-VMGEXIT initialization/preparation.
>
> +
>
> + Performs the necessary steps in preparation for invoking VMGEXIT. Must
> be
>
> + called before setting any fields within the GHCB.
>
> +
>
> + The base library function does nothing.
>
> +
>
> + @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.
>
> +
>
> + The base library function does nothing.
>
> +
>
> + @param[in, out] Ghcb A pointer to the GHCB
>
> +
>
> +**/
>
> +VOID
>
> +EFIAPI
>
> +VmgDone (
>
> + IN OUT GHCB *Ghcb
>
> + )
>
> +{
>
> +}
>
> +
>
> +/**
>
> + Handle a #VC exception.
>
> +
>
> + Performs the necessary processing to handle a #VC exception.
>
> +
>
> + The base library function returns an error equal to VC_EXCEPTION,
>
> + to be propagated to the standard exception handling stack.
>
> +
>
> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be
> set
>
> + as value to use on error.
>
> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>
> +
>
> + @retval EFI_SUCCESS Exception handled
>
> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
> value to
>
> + propagate provided
>
> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
> value to
>
> + propagate provided
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +VmgExitHandleVc (
>
> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>
> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>
> + )
>
> +{
>
> + *ExceptionType = VC_EXCEPTION;
>
> +
>
> + return EFI_UNSUPPORTED;
>
> +}
>
> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> new file mode 100644
> index 000000000000..8639bc0e8ce9
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> @@ -0,0 +1,15 @@
> +// /** @file
>
> +// VMGEXIT support library instance.
>
> +//
>
> +// VMGEXIT support library instance.
>
> +//
>
> +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +//
>
> +// **/
>
> +
>
> +
>
> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT support
> NULL library instance"
>
> +
>
> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
> support NULL library instance."
>
> +
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-05 13:26 ` [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
2020-06-12 0:56 ` Dong, Eric
@ 2020-06-18 7:23 ` Dong, Eric
2020-06-18 14:09 ` Lendacky, Thomas
1 sibling, 1 reply; 103+ messages in thread
From: Dong, Eric @ 2020-06-18 7:23 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Hi Tom,
When use VS2015 to build this code, it reports below error. Please help to fix it.
k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220: warning treated as error - no 'object' file generated
k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335: Mac file format detected: please convert the source file to either DOS or UNIX format
Thanks,
Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:27 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 08/46] UefiCpuPkg: Implement library support for
> VMGEXIT
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> To support handling #VC exceptions and issuing VMGEXIT instructions,
> create a library with functions that can be used to perform these
> #VC/VMGEXIT related operations. This includes functions for:
> - Handling #VC exceptions
> - Preparing for and issuing a VMGEXIT
> - Performing MMIO-related write operations to support flash emulation
> - Performing AP related boot opeations
>
> The base functions in this driver will not do anything and will return
> an error if a return value is required. It is expected that other packages
> (like OvmfPkg) will create a version of the library to fully support an
> SEV-ES guest.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 3 +
> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
> UefiCpuPkg/Include/Library/VmgExitLib.h | 103 +++++++++++++++++
> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121
> ++++++++++++++++++++
> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
> 6 files changed, 271 insertions(+)
>
> 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 afa304128221..f0e58b90ff0a 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/VmgExitLibNull/VmgExitLibNull.inf
>
>
>
> [LibraryClasses.common.SEC]
>
>
> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.i
> nf
>
> @@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
>
> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
> Null.inf
>
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
>
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
>
> + UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
>
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
>
> UefiCpuPkg/SecCore/SecCore.inf
>
> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> new file mode 100644
> index 000000000000..d8770a21c355
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> @@ -0,0 +1,27 @@
> +## @file
>
> +# VMGEXIT Support Library.
>
> +#
>
> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = VmgExitLibNull
>
> + MODULE_UNI_FILE = VmgExitLibNull.uni
>
> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
>
> + MODULE_TYPE = BASE
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = VmgExitLib
>
> +
>
> +[Sources.common]
>
> + VmgExitLibNull.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..0b2f39026a4a
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
> @@ -0,0 +1,103 @@
> +/** @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 and to handle #VC exceptions.
>
> +
>
> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef __VMG_EXIT_LIB_H__
>
> +#define __VMG_EXIT_LIB_H__
>
> +
>
> +#include <Protocol/DebugSupport.h>
>
> +#include <Register/Amd/Ghcb.h>
>
> +
>
> +
>
> +/**
>
> + 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.
>
> +
>
> + @return 0 VMGEXIT succeeded.
>
> + @return 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
>
> + );
>
> +
>
> +/**
>
> + Handle a #VC exception.
>
> +
>
> + Performs the necessary processing to handle a #VC exception.
>
> +
>
> + The base library function returns an error equal to VC_EXCEPTION,
>
> + to be propagated to the standard exception handling stack.
>
> +
>
> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be
> set
>
> + as value to use on error.
>
> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>
> +
>
> + @retval EFI_SUCCESS Exception handled
>
> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
> value to
>
> + propagate provided
>
> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
> value to
>
> + propagate provided
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +VmgExitHandleVc (
>
> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>
> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>
> + );
>
> +
>
> +#endif
>
> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> new file mode 100644
> index 000000000000..30a239df298e
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> @@ -0,0 +1,121 @@
> +/** @file
>
> + VMGEXIT Base Support Library.
>
> +
>
> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <Base.h>
>
> +#include <Uefi.h>
>
> +#include <Library/VmgExitLib.h>
>
> +
>
> +/**
>
> + Perform VMGEXIT.
>
> +
>
> + Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction
> and
>
> + then handles the return actions.
>
> +
>
> + The base library function returns an error in the form of a
>
> + GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
>
> +
>
> + @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.
>
> +
>
> + @return 0 VMGEXIT succeeded.
>
> + @return Others VMGEXIT processing did not succeed. Exception
>
> + event to be propagated.
>
> +
>
> +**/
>
> +UINT64
>
> +EFIAPI
>
> +VmgExit (
>
> + IN OUT GHCB *Ghcb,
>
> + IN UINT64 ExitCode,
>
> + IN UINT64 ExitInfo1,
>
> + IN UINT64 ExitInfo2
>
> + )
>
> +{
>
> + GHCB_EVENT_INJECTION Event;
>
> +
>
> + Event.Uint64 = 0;
>
> + Event.Elements.Vector = GP_EXCEPTION;
>
> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
>
> + Event.Elements.Valid = 1;
>
> +
>
> + return Event.Uint64;
>
> +}
>
> +
>
> +/**
>
> + Perform pre-VMGEXIT initialization/preparation.
>
> +
>
> + Performs the necessary steps in preparation for invoking VMGEXIT. Must
> be
>
> + called before setting any fields within the GHCB.
>
> +
>
> + The base library function does nothing.
>
> +
>
> + @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.
>
> +
>
> + The base library function does nothing.
>
> +
>
> + @param[in, out] Ghcb A pointer to the GHCB
>
> +
>
> +**/
>
> +VOID
>
> +EFIAPI
>
> +VmgDone (
>
> + IN OUT GHCB *Ghcb
>
> + )
>
> +{
>
> +}
>
> +
>
> +/**
>
> + Handle a #VC exception.
>
> +
>
> + Performs the necessary processing to handle a #VC exception.
>
> +
>
> + The base library function returns an error equal to VC_EXCEPTION,
>
> + to be propagated to the standard exception handling stack.
>
> +
>
> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be
> set
>
> + as value to use on error.
>
> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>
> +
>
> + @retval EFI_SUCCESS Exception handled
>
> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
> value to
>
> + propagate provided
>
> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
> value to
>
> + propagate provided
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +VmgExitHandleVc (
>
> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>
> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>
> + )
>
> +{
>
> + *ExceptionType = VC_EXCEPTION;
>
> +
>
> + return EFI_UNSUPPORTED;
>
> +}
>
> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> new file mode 100644
> index 000000000000..8639bc0e8ce9
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> @@ -0,0 +1,15 @@
> +// /** @file
>
> +// VMGEXIT support library instance.
>
> +//
>
> +// VMGEXIT support library instance.
>
> +//
>
> +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +//
>
> +// **/
>
> +
>
> +
>
> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT support
> NULL library instance"
>
> +
>
> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
> support NULL library instance."
>
> +
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-18 7:23 ` Dong, Eric
@ 2020-06-18 14:09 ` Lendacky, Thomas
2020-06-19 7:47 ` [edk2-devel] " Dong, Eric
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-18 14:09 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
On 6/18/20 2:23 AM, Dong, Eric wrote:
> Hi Tom,
>
> When use VS2015 to build this code, it reports below error. Please help to fix it.
>
> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220: warning treated as error - no 'object' file generated
> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335: Mac file format detected: please convert the source file to either DOS or UNIX format
That is strange... I didn't see this when I ran through the CI. When I do
a file command against the file it reports:
UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with CRLF line terminators
I'll investigate this and try and figure out what's going on, but if
anyone else has some ideas, please let me know.
Thanks,
Tom
>
> Thanks,
> Eric
>
>> -----Original Message-----
>> From: Tom Lendacky <thomas.lendacky@amd.com>
>> Sent: Friday, June 5, 2020 9:27 PM
>> To: devel@edk2.groups.io
>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
>> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
>> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: [PATCH v9 08/46] 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%7Cd75554da4959407c967608d8135877be%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637280617975250842&sdata=fBlK2BFkRdAS5EWcM8YShf1ZswfRN%2F41L7XeUsb4ZCs%3D&reserved=0
>>
>> To support handling #VC exceptions and issuing VMGEXIT instructions,
>> create a library with functions that can be used to perform these
>> #VC/VMGEXIT related operations. This includes functions for:
>> - Handling #VC exceptions
>> - Preparing for and issuing a VMGEXIT
>> - Performing MMIO-related write operations to support flash emulation
>> - Performing AP related boot opeations
>>
>> The base functions in this driver will not do anything and will return
>> an error if a return value is required. It is expected that other packages
>> (like OvmfPkg) will create a version of the library to fully support an
>> SEV-ES guest.
>>
>> Cc: Eric Dong <eric.dong@intel.com>
>> Cc: Ray Ni <ray.ni@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> UefiCpuPkg/UefiCpuPkg.dec | 3 +
>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
>> UefiCpuPkg/Include/Library/VmgExitLib.h | 103 +++++++++++++++++
>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121
>> ++++++++++++++++++++
>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
>> 6 files changed, 271 insertions(+)
>>
>> 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 afa304128221..f0e58b90ff0a 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/VmgExitLibNull/VmgExitLibNull.inf
>>
>>
>>
>> [LibraryClasses.common.SEC]
>>
>>
>> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.i
>> nf
>>
>> @@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
>>
>> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
>> Null.inf
>>
>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
>>
>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
>>
>> + UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>
>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
>>
>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
>>
>> UefiCpuPkg/SecCore/SecCore.inf
>>
>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>> new file mode 100644
>> index 000000000000..d8770a21c355
>> --- /dev/null
>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>> @@ -0,0 +1,27 @@
>> +## @file
>>
>> +# VMGEXIT Support Library.
>>
>> +#
>>
>> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>>
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>> +#
>>
>> +##
>>
>> +
>>
>> +[Defines]
>>
>> + INF_VERSION = 0x00010005
>>
>> + BASE_NAME = VmgExitLibNull
>>
>> + MODULE_UNI_FILE = VmgExitLibNull.uni
>>
>> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
>>
>> + MODULE_TYPE = BASE
>>
>> + VERSION_STRING = 1.0
>>
>> + LIBRARY_CLASS = VmgExitLib
>>
>> +
>>
>> +[Sources.common]
>>
>> + VmgExitLibNull.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..0b2f39026a4a
>> --- /dev/null
>> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
>> @@ -0,0 +1,103 @@
>> +/** @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 and to handle #VC exceptions.
>>
>> +
>>
>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>>
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>> +
>>
>> +**/
>>
>> +
>>
>> +#ifndef __VMG_EXIT_LIB_H__
>>
>> +#define __VMG_EXIT_LIB_H__
>>
>> +
>>
>> +#include <Protocol/DebugSupport.h>
>>
>> +#include <Register/Amd/Ghcb.h>
>>
>> +
>>
>> +
>>
>> +/**
>>
>> + 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.
>>
>> +
>>
>> + @return 0 VMGEXIT succeeded.
>>
>> + @return 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
>>
>> + );
>>
>> +
>>
>> +/**
>>
>> + Handle a #VC exception.
>>
>> +
>>
>> + Performs the necessary processing to handle a #VC exception.
>>
>> +
>>
>> + The base library function returns an error equal to VC_EXCEPTION,
>>
>> + to be propagated to the standard exception handling stack.
>>
>> +
>>
>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be
>> set
>>
>> + as value to use on error.
>>
>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>>
>> +
>>
>> + @retval EFI_SUCCESS Exception handled
>>
>> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
>> value to
>>
>> + propagate provided
>>
>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
>> value to
>>
>> + propagate provided
>>
>> +
>>
>> +**/
>>
>> +EFI_STATUS
>>
>> +EFIAPI
>>
>> +VmgExitHandleVc (
>>
>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>>
>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>>
>> + );
>>
>> +
>>
>> +#endif
>>
>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
>> new file mode 100644
>> index 000000000000..30a239df298e
>> --- /dev/null
>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
>> @@ -0,0 +1,121 @@
>> +/** @file
>>
>> + VMGEXIT Base Support Library.
>>
>> +
>>
>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>>
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>> +
>>
>> +**/
>>
>> +
>>
>> +#include <Base.h>
>>
>> +#include <Uefi.h>
>>
>> +#include <Library/VmgExitLib.h>
>>
>> +
>>
>> +/**
>>
>> + Perform VMGEXIT.
>>
>> +
>>
>> + Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction
>> and
>>
>> + then handles the return actions.
>>
>> +
>>
>> + The base library function returns an error in the form of a
>>
>> + GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
>>
>> +
>>
>> + @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.
>>
>> +
>>
>> + @return 0 VMGEXIT succeeded.
>>
>> + @return Others VMGEXIT processing did not succeed. Exception
>>
>> + event to be propagated.
>>
>> +
>>
>> +**/
>>
>> +UINT64
>>
>> +EFIAPI
>>
>> +VmgExit (
>>
>> + IN OUT GHCB *Ghcb,
>>
>> + IN UINT64 ExitCode,
>>
>> + IN UINT64 ExitInfo1,
>>
>> + IN UINT64 ExitInfo2
>>
>> + )
>>
>> +{
>>
>> + GHCB_EVENT_INJECTION Event;
>>
>> +
>>
>> + Event.Uint64 = 0;
>>
>> + Event.Elements.Vector = GP_EXCEPTION;
>>
>> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
>>
>> + Event.Elements.Valid = 1;
>>
>> +
>>
>> + return Event.Uint64;
>>
>> +}
>>
>> +
>>
>> +/**
>>
>> + Perform pre-VMGEXIT initialization/preparation.
>>
>> +
>>
>> + Performs the necessary steps in preparation for invoking VMGEXIT. Must
>> be
>>
>> + called before setting any fields within the GHCB.
>>
>> +
>>
>> + The base library function does nothing.
>>
>> +
>>
>> + @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.
>>
>> +
>>
>> + The base library function does nothing.
>>
>> +
>>
>> + @param[in, out] Ghcb A pointer to the GHCB
>>
>> +
>>
>> +**/
>>
>> +VOID
>>
>> +EFIAPI
>>
>> +VmgDone (
>>
>> + IN OUT GHCB *Ghcb
>>
>> + )
>>
>> +{
>>
>> +}
>>
>> +
>>
>> +/**
>>
>> + Handle a #VC exception.
>>
>> +
>>
>> + Performs the necessary processing to handle a #VC exception.
>>
>> +
>>
>> + The base library function returns an error equal to VC_EXCEPTION,
>>
>> + to be propagated to the standard exception handling stack.
>>
>> +
>>
>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be
>> set
>>
>> + as value to use on error.
>>
>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>>
>> +
>>
>> + @retval EFI_SUCCESS Exception handled
>>
>> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
>> value to
>>
>> + propagate provided
>>
>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
>> value to
>>
>> + propagate provided
>>
>> +
>>
>> +**/
>>
>> +EFI_STATUS
>>
>> +EFIAPI
>>
>> +VmgExitHandleVc (
>>
>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>>
>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>>
>> + )
>>
>> +{
>>
>> + *ExceptionType = VC_EXCEPTION;
>>
>> +
>>
>> + return EFI_UNSUPPORTED;
>>
>> +}
>>
>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
>> new file mode 100644
>> index 000000000000..8639bc0e8ce9
>> --- /dev/null
>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
>> @@ -0,0 +1,15 @@
>> +// /** @file
>>
>> +// VMGEXIT support library instance.
>>
>> +//
>>
>> +// VMGEXIT support library instance.
>>
>> +//
>>
>> +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>>
>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>> +//
>>
>> +// **/
>>
>> +
>>
>> +
>>
>> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT support
>> NULL library instance"
>>
>> +
>>
>> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
>> support NULL library instance."
>>
>> +
>>
>> --
>> 2.27.0
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-18 14:09 ` Lendacky, Thomas
@ 2020-06-19 7:47 ` Dong, Eric
2020-06-19 13:50 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Dong, Eric @ 2020-06-19 7:47 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Thursday, June 18, 2020 10:09 PM
> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
> support for VMGEXIT
>
> On 6/18/20 2:23 AM, Dong, Eric wrote:
> > Hi Tom,
> >
> > When use VS2015 to build this code, it reports below error. Please help to
> fix it.
> >
> > k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220: warning
> > treated as error - no 'object' file generated
> > k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335: Mac
> > file format detected: please convert the source file to either DOS or
> > UNIX format
>
> That is strange... I didn't see this when I ran through the CI. When I do a file
> command against the file it reports:
>
> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with CRLF
> line terminators
>
> I'll investigate this and try and figure out what's going on, but if anyone else
> has some ideas, please let me know.
Hi Tom,
I met this error again when I trig below patch from AMD again for CPU change.
"UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to BaseUefiCpuLib"
I'm not sure whether this is patch issue, or our internal test sever issue. I have reported this error to our internal team to check also.
Please check it from your side and make sure no error from your side. I will update the status from my side when I get the update.
Thanks,
Eric
>
> Thanks,
> Tom
>
> >
> > Thanks,
> > Eric
> >
> >> -----Original Message-----
> >> From: Tom Lendacky <thomas.lendacky@amd.com>
> >> Sent: Friday, June 5, 2020 9:27 PM
> >> To: devel@edk2.groups.io
> >> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> >> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
> >> <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
> >> Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> >> Subject: [PATCH v9 08/46] UefiCpuPkg: Implement library support for
> >> VMGEXIT
> >>
> >> BZ:
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbug
> >>
> zilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Ct
> ho
> >>
> mas.lendacky%40amd.com%7Cd75554da4959407c967608d8135877be%7C3dd
> 8961fe
> >>
> 4884e608e11a82d994e183d%7C0%7C0%7C637280617975250842&sdata=
> fBlK2B
> >> FkRdAS5EWcM8YShf1ZswfRN%2F41L7XeUsb4ZCs%3D&reserved=0
> >>
> >> To support handling #VC exceptions and issuing VMGEXIT instructions,
> >> create a library with functions that can be used to perform these
> >> #VC/VMGEXIT related operations. This includes functions for:
> >> - Handling #VC exceptions
> >> - Preparing for and issuing a VMGEXIT
> >> - Performing MMIO-related write operations to support flash emulation
> >> - Performing AP related boot opeations
> >>
> >> The base functions in this driver will not do anything and will
> >> return an error if a return value is required. It is expected that
> >> other packages (like OvmfPkg) will create a version of the library to
> >> fully support an SEV-ES guest.
> >>
> >> Cc: Eric Dong <eric.dong@intel.com>
> >> Cc: Ray Ni <ray.ni@intel.com>
> >> Cc: Laszlo Ersek <lersek@redhat.com>
> >> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> >> ---
> >> UefiCpuPkg/UefiCpuPkg.dec | 3 +
> >> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> >> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
> >> UefiCpuPkg/Include/Library/VmgExitLib.h | 103
> +++++++++++++++++
> >> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121
> >> ++++++++++++++++++++
> >> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
> >> 6 files changed, 271 insertions(+)
> >>
> >> 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 afa304128221..f0e58b90ff0a 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/Base
> >> PeCoffExtraActionLib|P
> >> eCoffExtraActionLibNull.inf
> >>
> >>
> >>
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> >> mMeasurementLibNull.inf
> >>
> >> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>
> >>
> >>
> >> [LibraryClasses.common.SEC]
> >>
> >>
> >>
> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNu
> >> PlatformSecLib|ll.i
> >> nf
> >>
> >> @@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
> >>
> >>
> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
> >> Null.inf
> >>
> >> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> >>
> >> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> >>
> >> + UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>
> >> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
> >>
> >> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> >>
> >> UefiCpuPkg/SecCore/SecCore.inf
> >>
> >> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >> new file mode 100644
> >> index 000000000000..d8770a21c355
> >> --- /dev/null
> >> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >> @@ -0,0 +1,27 @@
> >> +## @file
> >>
> >> +# VMGEXIT Support Library.
> >>
> >> +#
> >>
> >> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >> +reserved.<BR>
> >>
> >> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +#
> >>
> >> +##
> >>
> >> +
> >>
> >> +[Defines]
> >>
> >> + INF_VERSION = 0x00010005
> >>
> >> + BASE_NAME = VmgExitLibNull
> >>
> >> + MODULE_UNI_FILE = VmgExitLibNull.uni
> >>
> >> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
> >>
> >> + MODULE_TYPE = BASE
> >>
> >> + VERSION_STRING = 1.0
> >>
> >> + LIBRARY_CLASS = VmgExitLib
> >>
> >> +
> >>
> >> +[Sources.common]
> >>
> >> + VmgExitLibNull.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..0b2f39026a4a
> >> --- /dev/null
> >> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
> >> @@ -0,0 +1,103 @@
> >> +/** @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 and to handle #VC exceptions.
> >>
> >> +
> >>
> >> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >> + reserved.<BR>
> >>
> >> + SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +
> >>
> >> +**/
> >>
> >> +
> >>
> >> +#ifndef __VMG_EXIT_LIB_H__
> >>
> >> +#define __VMG_EXIT_LIB_H__
> >>
> >> +
> >>
> >> +#include <Protocol/DebugSupport.h>
> >>
> >> +#include <Register/Amd/Ghcb.h>
> >>
> >> +
> >>
> >> +
> >>
> >> +/**
> >>
> >> + 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.
> >>
> >> +
> >>
> >> + @return 0 VMGEXIT succeeded.
> >>
> >> + @return 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
> >>
> >> + );
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Handle a #VC exception.
> >>
> >> +
> >>
> >> + Performs the necessary processing to handle a #VC exception.
> >>
> >> +
> >>
> >> + The base library function returns an error equal to VC_EXCEPTION,
> >>
> >> + to be propagated to the standard exception handling stack.
> >>
> >> +
> >>
> >> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE
> >> + to be
> >> set
> >>
> >> + as value to use on error.
> >>
> >> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS Exception handled
> >>
> >> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
> >> value to
> >>
> >> + propagate provided
> >>
> >> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
> >> value to
> >>
> >> + propagate provided
> >>
> >> +
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +VmgExitHandleVc (
> >>
> >> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
> >>
> >> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
> >>
> >> + );
> >>
> >> +
> >>
> >> +#endif
> >>
> >> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> >> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> >> new file mode 100644
> >> index 000000000000..30a239df298e
> >> --- /dev/null
> >> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> >> @@ -0,0 +1,121 @@
> >> +/** @file
> >>
> >> + VMGEXIT Base Support Library.
> >>
> >> +
> >>
> >> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >> + reserved.<BR>
> >>
> >> + SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +
> >>
> >> +**/
> >>
> >> +
> >>
> >> +#include <Base.h>
> >>
> >> +#include <Uefi.h>
> >>
> >> +#include <Library/VmgExitLib.h>
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Perform VMGEXIT.
> >>
> >> +
> >>
> >> + Sets the necessary fields of the GHCB, invokes the VMGEXIT
> >> + instruction
> >> and
> >>
> >> + then handles the return actions.
> >>
> >> +
> >>
> >> + The base library function returns an error in the form of a
> >>
> >> + GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
> >>
> >> +
> >>
> >> + @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.
> >>
> >> +
> >>
> >> + @return 0 VMGEXIT succeeded.
> >>
> >> + @return Others VMGEXIT processing did not succeed. Exception
> >>
> >> + event to be propagated.
> >>
> >> +
> >>
> >> +**/
> >>
> >> +UINT64
> >>
> >> +EFIAPI
> >>
> >> +VmgExit (
> >>
> >> + IN OUT GHCB *Ghcb,
> >>
> >> + IN UINT64 ExitCode,
> >>
> >> + IN UINT64 ExitInfo1,
> >>
> >> + IN UINT64 ExitInfo2
> >>
> >> + )
> >>
> >> +{
> >>
> >> + GHCB_EVENT_INJECTION Event;
> >>
> >> +
> >>
> >> + Event.Uint64 = 0;
> >>
> >> + Event.Elements.Vector = GP_EXCEPTION;
> >>
> >> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
> >>
> >> + Event.Elements.Valid = 1;
> >>
> >> +
> >>
> >> + return Event.Uint64;
> >>
> >> +}
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Perform pre-VMGEXIT initialization/preparation.
> >>
> >> +
> >>
> >> + Performs the necessary steps in preparation for invoking VMGEXIT.
> >> + Must
> >> be
> >>
> >> + called before setting any fields within the GHCB.
> >>
> >> +
> >>
> >> + The base library function does nothing.
> >>
> >> +
> >>
> >> + @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.
> >>
> >> +
> >>
> >> + The base library function does nothing.
> >>
> >> +
> >>
> >> + @param[in, out] Ghcb A pointer to the GHCB
> >>
> >> +
> >>
> >> +**/
> >>
> >> +VOID
> >>
> >> +EFIAPI
> >>
> >> +VmgDone (
> >>
> >> + IN OUT GHCB *Ghcb
> >>
> >> + )
> >>
> >> +{
> >>
> >> +}
> >>
> >> +
> >>
> >> +/**
> >>
> >> + Handle a #VC exception.
> >>
> >> +
> >>
> >> + Performs the necessary processing to handle a #VC exception.
> >>
> >> +
> >>
> >> + The base library function returns an error equal to VC_EXCEPTION,
> >>
> >> + to be propagated to the standard exception handling stack.
> >>
> >> +
> >>
> >> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE
> >> + to be
> >> set
> >>
> >> + as value to use on error.
> >>
> >> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
> >>
> >> +
> >>
> >> + @retval EFI_SUCCESS Exception handled
> >>
> >> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
> >> value to
> >>
> >> + propagate provided
> >>
> >> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
> >> value to
> >>
> >> + propagate provided
> >>
> >> +
> >>
> >> +**/
> >>
> >> +EFI_STATUS
> >>
> >> +EFIAPI
> >>
> >> +VmgExitHandleVc (
> >>
> >> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
> >>
> >> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
> >>
> >> + )
> >>
> >> +{
> >>
> >> + *ExceptionType = VC_EXCEPTION;
> >>
> >> +
> >>
> >> + return EFI_UNSUPPORTED;
> >>
> >> +}
> >>
> >> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> >> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> >> new file mode 100644
> >> index 000000000000..8639bc0e8ce9
> >> --- /dev/null
> >> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> >> @@ -0,0 +1,15 @@
> >> +// /** @file
> >>
> >> +// VMGEXIT support library instance.
> >>
> >> +//
> >>
> >> +// VMGEXIT support library instance.
> >>
> >> +//
> >>
> >> +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >> +reserved.<BR>
> >>
> >> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +//
> >>
> >> +// **/
> >>
> >> +
> >>
> >> +
> >>
> >> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT
> support
> >> NULL library instance"
> >>
> >> +
> >>
> >> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
> >> support NULL library instance."
> >>
> >> +
> >>
> >> --
> >> 2.27.0
> >
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-19 7:47 ` [edk2-devel] " Dong, Eric
@ 2020-06-19 13:50 ` Lendacky, Thomas
2020-06-19 14:21 ` Dong, Eric
2020-06-19 15:38 ` Laszlo Ersek
0 siblings, 2 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-19 13:50 UTC (permalink / raw)
To: devel, eric.dong
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
>
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Thursday, June 18, 2020 10:09 PM
>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
>> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
>> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
>> support for VMGEXIT
>>
>> On 6/18/20 2:23 AM, Dong, Eric wrote:
>>> Hi Tom,
>>>
>>> When use VS2015 to build this code, it reports below error. Please help to
>> fix it.
>>>
>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220: warning
>>> treated as error - no 'object' file generated
>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335: Mac
>>> file format detected: please convert the source file to either DOS or
>>> UNIX format
>>
>> That is strange... I didn't see this when I ran through the CI. When I do a file
>> command against the file it reports:
>>
>> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with CRLF
>> line terminators
>>
>> I'll investigate this and try and figure out what's going on, but if anyone else
>> has some ideas, please let me know.
>
> Hi Tom,
>
> I met this error again when I trig below patch from AMD again for CPU change.
> "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to BaseUefiCpuLib"
Hmmm... I think we could be running into issues with sending patches
through our mail servers. Let me send you the patch series directly using
some changes I made to my git config file to see if that helps. Would that
be ok?
Thanks,
Tom
>
> I'm not sure whether this is patch issue, or our internal test sever issue. I have reported this error to our internal team to check also.
> Please check it from your side and make sure no error from your side. I will update the status from my side when I get the update.
>
> Thanks,
> Eric
>
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Eric
>>>
>>>> -----Original Message-----
>>>> From: Tom Lendacky <thomas.lendacky@amd.com>
>>>> Sent: Friday, June 5, 2020 9:27 PM
>>>> To: devel@edk2.groups.io
>>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
>>>> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>>>> <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
>>>> Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>>>> Subject: [PATCH v9 08/46] UefiCpuPkg: Implement library support for
>>>> VMGEXIT
>>>>
>>>> BZ:
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbug
>>>>
>> zilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Ct
>> ho
>>>>
>> mas.lendacky%40amd.com%7Cd75554da4959407c967608d8135877be%7C3dd
>> 8961fe
>>>>
>> 4884e608e11a82d994e183d%7C0%7C0%7C637280617975250842&sdata=
>> fBlK2B
>>>> FkRdAS5EWcM8YShf1ZswfRN%2F41L7XeUsb4ZCs%3D&reserved=0
>>>>
>>>> To support handling #VC exceptions and issuing VMGEXIT instructions,
>>>> create a library with functions that can be used to perform these
>>>> #VC/VMGEXIT related operations. This includes functions for:
>>>> - Handling #VC exceptions
>>>> - Preparing for and issuing a VMGEXIT
>>>> - Performing MMIO-related write operations to support flash emulation
>>>> - Performing AP related boot opeations
>>>>
>>>> The base functions in this driver will not do anything and will
>>>> return an error if a return value is required. It is expected that
>>>> other packages (like OvmfPkg) will create a version of the library to
>>>> fully support an SEV-ES guest.
>>>>
>>>> Cc: Eric Dong <eric.dong@intel.com>
>>>> Cc: Ray Ni <ray.ni@intel.com>
>>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>>> ---
>>>> UefiCpuPkg/UefiCpuPkg.dec | 3 +
>>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
>>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 103
>> +++++++++++++++++
>>>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121
>>>> ++++++++++++++++++++
>>>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
>>>> 6 files changed, 271 insertions(+)
>>>>
>>>> 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 afa304128221..f0e58b90ff0a 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/Base
>>>> PeCoffExtraActionLib|P
>>>> eCoffExtraActionLibNull.inf
>>>>
>>>>
>>>>
>> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
>>>> mMeasurementLibNull.inf
>>>>
>>>> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>>>
>>>>
>>>>
>>>> [LibraryClasses.common.SEC]
>>>>
>>>>
>>>>
>> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNu
>>>> PlatformSecLib|ll.i
>>>> nf
>>>>
>>>> @@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
>>>>
>>>>
>> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
>>>> Null.inf
>>>>
>>>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
>>>>
>>>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
>>>>
>>>> + UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>>>
>>>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
>>>>
>>>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
>>>>
>>>> UefiCpuPkg/SecCore/SecCore.inf
>>>>
>>>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>>> new file mode 100644
>>>> index 000000000000..d8770a21c355
>>>> --- /dev/null
>>>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>>> @@ -0,0 +1,27 @@
>>>> +## @file
>>>>
>>>> +# VMGEXIT Support Library.
>>>>
>>>> +#
>>>>
>>>> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
>>>> +reserved.<BR>
>>>>
>>>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>>>>
>>>> +#
>>>>
>>>> +##
>>>>
>>>> +
>>>>
>>>> +[Defines]
>>>>
>>>> + INF_VERSION = 0x00010005
>>>>
>>>> + BASE_NAME = VmgExitLibNull
>>>>
>>>> + MODULE_UNI_FILE = VmgExitLibNull.uni
>>>>
>>>> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
>>>>
>>>> + MODULE_TYPE = BASE
>>>>
>>>> + VERSION_STRING = 1.0
>>>>
>>>> + LIBRARY_CLASS = VmgExitLib
>>>>
>>>> +
>>>>
>>>> +[Sources.common]
>>>>
>>>> + VmgExitLibNull.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..0b2f39026a4a
>>>> --- /dev/null
>>>> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
>>>> @@ -0,0 +1,103 @@
>>>> +/** @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 and to handle #VC exceptions.
>>>>
>>>> +
>>>>
>>>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
>>>> + reserved.<BR>
>>>>
>>>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>>>>
>>>> +
>>>>
>>>> +**/
>>>>
>>>> +
>>>>
>>>> +#ifndef __VMG_EXIT_LIB_H__
>>>>
>>>> +#define __VMG_EXIT_LIB_H__
>>>>
>>>> +
>>>>
>>>> +#include <Protocol/DebugSupport.h>
>>>>
>>>> +#include <Register/Amd/Ghcb.h>
>>>>
>>>> +
>>>>
>>>> +
>>>>
>>>> +/**
>>>>
>>>> + 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.
>>>>
>>>> +
>>>>
>>>> + @return 0 VMGEXIT succeeded.
>>>>
>>>> + @return 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
>>>>
>>>> + );
>>>>
>>>> +
>>>>
>>>> +/**
>>>>
>>>> + Handle a #VC exception.
>>>>
>>>> +
>>>>
>>>> + Performs the necessary processing to handle a #VC exception.
>>>>
>>>> +
>>>>
>>>> + The base library function returns an error equal to VC_EXCEPTION,
>>>>
>>>> + to be propagated to the standard exception handling stack.
>>>>
>>>> +
>>>>
>>>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE
>>>> + to be
>>>> set
>>>>
>>>> + as value to use on error.
>>>>
>>>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>>>>
>>>> +
>>>>
>>>> + @retval EFI_SUCCESS Exception handled
>>>>
>>>> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
>>>> value to
>>>>
>>>> + propagate provided
>>>>
>>>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
>>>> value to
>>>>
>>>> + propagate provided
>>>>
>>>> +
>>>>
>>>> +**/
>>>>
>>>> +EFI_STATUS
>>>>
>>>> +EFIAPI
>>>>
>>>> +VmgExitHandleVc (
>>>>
>>>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>>>>
>>>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>>>>
>>>> + );
>>>>
>>>> +
>>>>
>>>> +#endif
>>>>
>>>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
>>>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
>>>> new file mode 100644
>>>> index 000000000000..30a239df298e
>>>> --- /dev/null
>>>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
>>>> @@ -0,0 +1,121 @@
>>>> +/** @file
>>>>
>>>> + VMGEXIT Base Support Library.
>>>>
>>>> +
>>>>
>>>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
>>>> + reserved.<BR>
>>>>
>>>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>>>>
>>>> +
>>>>
>>>> +**/
>>>>
>>>> +
>>>>
>>>> +#include <Base.h>
>>>>
>>>> +#include <Uefi.h>
>>>>
>>>> +#include <Library/VmgExitLib.h>
>>>>
>>>> +
>>>>
>>>> +/**
>>>>
>>>> + Perform VMGEXIT.
>>>>
>>>> +
>>>>
>>>> + Sets the necessary fields of the GHCB, invokes the VMGEXIT
>>>> + instruction
>>>> and
>>>>
>>>> + then handles the return actions.
>>>>
>>>> +
>>>>
>>>> + The base library function returns an error in the form of a
>>>>
>>>> + GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
>>>>
>>>> +
>>>>
>>>> + @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.
>>>>
>>>> +
>>>>
>>>> + @return 0 VMGEXIT succeeded.
>>>>
>>>> + @return Others VMGEXIT processing did not succeed. Exception
>>>>
>>>> + event to be propagated.
>>>>
>>>> +
>>>>
>>>> +**/
>>>>
>>>> +UINT64
>>>>
>>>> +EFIAPI
>>>>
>>>> +VmgExit (
>>>>
>>>> + IN OUT GHCB *Ghcb,
>>>>
>>>> + IN UINT64 ExitCode,
>>>>
>>>> + IN UINT64 ExitInfo1,
>>>>
>>>> + IN UINT64 ExitInfo2
>>>>
>>>> + )
>>>>
>>>> +{
>>>>
>>>> + GHCB_EVENT_INJECTION Event;
>>>>
>>>> +
>>>>
>>>> + Event.Uint64 = 0;
>>>>
>>>> + Event.Elements.Vector = GP_EXCEPTION;
>>>>
>>>> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
>>>>
>>>> + Event.Elements.Valid = 1;
>>>>
>>>> +
>>>>
>>>> + return Event.Uint64;
>>>>
>>>> +}
>>>>
>>>> +
>>>>
>>>> +/**
>>>>
>>>> + Perform pre-VMGEXIT initialization/preparation.
>>>>
>>>> +
>>>>
>>>> + Performs the necessary steps in preparation for invoking VMGEXIT.
>>>> + Must
>>>> be
>>>>
>>>> + called before setting any fields within the GHCB.
>>>>
>>>> +
>>>>
>>>> + The base library function does nothing.
>>>>
>>>> +
>>>>
>>>> + @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.
>>>>
>>>> +
>>>>
>>>> + The base library function does nothing.
>>>>
>>>> +
>>>>
>>>> + @param[in, out] Ghcb A pointer to the GHCB
>>>>
>>>> +
>>>>
>>>> +**/
>>>>
>>>> +VOID
>>>>
>>>> +EFIAPI
>>>>
>>>> +VmgDone (
>>>>
>>>> + IN OUT GHCB *Ghcb
>>>>
>>>> + )
>>>>
>>>> +{
>>>>
>>>> +}
>>>>
>>>> +
>>>>
>>>> +/**
>>>>
>>>> + Handle a #VC exception.
>>>>
>>>> +
>>>>
>>>> + Performs the necessary processing to handle a #VC exception.
>>>>
>>>> +
>>>>
>>>> + The base library function returns an error equal to VC_EXCEPTION,
>>>>
>>>> + to be propagated to the standard exception handling stack.
>>>>
>>>> +
>>>>
>>>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE
>>>> + to be
>>>> set
>>>>
>>>> + as value to use on error.
>>>>
>>>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>>>>
>>>> +
>>>>
>>>> + @retval EFI_SUCCESS Exception handled
>>>>
>>>> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception
>>>> value to
>>>>
>>>> + propagate provided
>>>>
>>>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception
>>>> value to
>>>>
>>>> + propagate provided
>>>>
>>>> +
>>>>
>>>> +**/
>>>>
>>>> +EFI_STATUS
>>>>
>>>> +EFIAPI
>>>>
>>>> +VmgExitHandleVc (
>>>>
>>>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>>>>
>>>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>>>>
>>>> + )
>>>>
>>>> +{
>>>>
>>>> + *ExceptionType = VC_EXCEPTION;
>>>>
>>>> +
>>>>
>>>> + return EFI_UNSUPPORTED;
>>>>
>>>> +}
>>>>
>>>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
>>>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
>>>> new file mode 100644
>>>> index 000000000000..8639bc0e8ce9
>>>> --- /dev/null
>>>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
>>>> @@ -0,0 +1,15 @@
>>>> +// /** @file
>>>>
>>>> +// VMGEXIT support library instance.
>>>>
>>>> +//
>>>>
>>>> +// VMGEXIT support library instance.
>>>>
>>>> +//
>>>>
>>>> +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
>>>> +reserved.<BR>
>>>>
>>>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>>>>
>>>> +//
>>>>
>>>> +// **/
>>>>
>>>> +
>>>>
>>>> +
>>>>
>>>> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT
>> support
>>>> NULL library instance"
>>>>
>>>> +
>>>>
>>>> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
>>>> support NULL library instance."
>>>>
>>>> +
>>>>
>>>> --
>>>> 2.27.0
>>>
>>
>>
>
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-19 13:50 ` Lendacky, Thomas
@ 2020-06-19 14:21 ` Dong, Eric
2020-06-19 15:38 ` Laszlo Ersek
1 sibling, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-19 14:21 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Friday, June 19, 2020 9:51 PM
> To: devel@edk2.groups.io; Dong, Eric <eric.dong@intel.com>
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
> support for VMGEXIT
>
> On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
> >
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> >> Lendacky, Thomas
> >> Sent: Thursday, June 18, 2020 10:09 PM
> >> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
> >> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >> <ard.biesheuvel@arm.com>; Justen, Jordan L
> >> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Gao,
> >> Liming <liming.gao@intel.com>; Kinney, Michael D
> >> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> >> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
> >> library support for VMGEXIT
> >>
> >> On 6/18/20 2:23 AM, Dong, Eric wrote:
> >>> Hi Tom,
> >>>
> >>> When use VS2015 to build this code, it reports below error. Please
> >>> help to
> >> fix it.
> >>>
> >>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220:
> >>> warning treated as error - no 'object' file generated
> >>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335: Mac
> >>> file format detected: please convert the source file to either DOS
> >>> or UNIX format
> >>
> >> That is strange... I didn't see this when I ran through the CI. When
> >> I do a file command against the file it reports:
> >>
> >> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with
> >> CRLF line terminators
> >>
> >> I'll investigate this and try and figure out what's going on, but if
> >> anyone else has some ideas, please let me know.
> >
> > Hi Tom,
> >
> > I met this error again when I trig below patch from AMD again for CPU
> change.
> > "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to BaseUefiCpuLib"
>
> Hmmm... I think we could be running into issues with sending patches
> through our mail servers. Let me send you the patch series directly using
> some changes I made to my git config file to see if that helps. Would that be
> ok?
Yes, please do it.
Thanks,
Eric
>
> Thanks,
> Tom
>
> >
> > I'm not sure whether this is patch issue, or our internal test sever issue. I
> have reported this error to our internal team to check also.
> > Please check it from your side and make sure no error from your side. I will
> update the status from my side when I get the update.
> >
> > Thanks,
> > Eric
> >
> >>
> >> Thanks,
> >> Tom
> >>
> >>>
> >>> Thanks,
> >>> Eric
> >>>
> >>>> -----Original Message-----
> >>>> From: Tom Lendacky <thomas.lendacky@amd.com>
> >>>> Sent: Friday, June 5, 2020 9:27 PM
> >>>> To: devel@edk2.groups.io
> >>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >>>> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> >>>> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
> >>>> <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
> >>>> Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> >>>> Subject: [PATCH v9 08/46] UefiCpuPkg: Implement library support for
> >>>> VMGEXIT
> >>>>
> >>>> BZ:
> >>>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbug
> >>>>
> >>
> zilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Ct
> >> ho
> >>>>
> >>
> mas.lendacky%40amd.com%7Cd75554da4959407c967608d8135877be%7C3dd
> >> 8961fe
> >>>>
> >>
> 4884e608e11a82d994e183d%7C0%7C0%7C637280617975250842&sdata=
> >> fBlK2B
> >>>>
> FkRdAS5EWcM8YShf1ZswfRN%2F41L7XeUsb4ZCs%3D&reserved=0
> >>>>
> >>>> To support handling #VC exceptions and issuing VMGEXIT
> >>>> instructions, create a library with functions that can be used to
> >>>> perform these #VC/VMGEXIT related operations. This includes
> functions for:
> >>>> - Handling #VC exceptions
> >>>> - Preparing for and issuing a VMGEXIT
> >>>> - Performing MMIO-related write operations to support flash
> emulation
> >>>> - Performing AP related boot opeations
> >>>>
> >>>> The base functions in this driver will not do anything and will
> >>>> return an error if a return value is required. It is expected that
> >>>> other packages (like OvmfPkg) will create a version of the library
> >>>> to fully support an SEV-ES guest.
> >>>>
> >>>> Cc: Eric Dong <eric.dong@intel.com>
> >>>> Cc: Ray Ni <ray.ni@intel.com>
> >>>> Cc: Laszlo Ersek <lersek@redhat.com>
> >>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> >>>> ---
> >>>> UefiCpuPkg/UefiCpuPkg.dec | 3 +
> >>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> >>>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf | 27 +++++
> >>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 103
> >> +++++++++++++++++
> >>>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c | 121
> >>>> ++++++++++++++++++++
> >>>> UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni | 15 +++
> >>>> 6 files changed, 271 insertions(+)
> >>>>
> >>>> 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 afa304128221..f0e58b90ff0a 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/Base
> >>>> PeCoffExtraActionLib|P
> >>>> eCoffExtraActionLibNull.inf
> >>>>
> >>>>
> >>>>
> >>
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> >>>> mMeasurementLibNull.inf
> >>>>
> >>>> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>>>
> >>>>
> >>>>
> >>>> [LibraryClasses.common.SEC]
> >>>>
> >>>>
> >>>>
> >>
> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNu
> >>>> PlatformSecLib|ll.i
> >>>> nf
> >>>>
> >>>> @@ -143,6 +144,7 @@ [Components.IA32, Components.X64]
> >>>>
> >>>>
> >>
> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
> >>>> Null.inf
> >>>>
> >>>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> >>>>
> >>>>
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> >>>>
> >>>> + UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>>>
> >>>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
> >>>>
> >>>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> >>>>
> >>>> UefiCpuPkg/SecCore/SecCore.inf
> >>>>
> >>>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>>> new file mode 100644
> >>>> index 000000000000..d8770a21c355
> >>>> --- /dev/null
> >>>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> >>>> @@ -0,0 +1,27 @@
> >>>> +## @file
> >>>>
> >>>> +# VMGEXIT Support Library.
> >>>>
> >>>> +#
> >>>>
> >>>> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >>>> +reserved.<BR>
> >>>>
> >>>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> >>>>
> >>>> +#
> >>>>
> >>>> +##
> >>>>
> >>>> +
> >>>>
> >>>> +[Defines]
> >>>>
> >>>> + INF_VERSION = 0x00010005
> >>>>
> >>>> + BASE_NAME = VmgExitLibNull
> >>>>
> >>>> + MODULE_UNI_FILE = VmgExitLibNull.uni
> >>>>
> >>>> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
> >>>>
> >>>> + MODULE_TYPE = BASE
> >>>>
> >>>> + VERSION_STRING = 1.0
> >>>>
> >>>> + LIBRARY_CLASS = VmgExitLib
> >>>>
> >>>> +
> >>>>
> >>>> +[Sources.common]
> >>>>
> >>>> + VmgExitLibNull.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..0b2f39026a4a
> >>>> --- /dev/null
> >>>> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
> >>>> @@ -0,0 +1,103 @@
> >>>> +/** @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 and to handle #VC exceptions.
> >>>>
> >>>> +
> >>>>
> >>>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >>>> + reserved.<BR>
> >>>>
> >>>> + SPDX-License-Identifier: BSD-2-Clause-Patent
> >>>>
> >>>> +
> >>>>
> >>>> +**/
> >>>>
> >>>> +
> >>>>
> >>>> +#ifndef __VMG_EXIT_LIB_H__
> >>>>
> >>>> +#define __VMG_EXIT_LIB_H__
> >>>>
> >>>> +
> >>>>
> >>>> +#include <Protocol/DebugSupport.h>
> >>>>
> >>>> +#include <Register/Amd/Ghcb.h>
> >>>>
> >>>> +
> >>>>
> >>>> +
> >>>>
> >>>> +/**
> >>>>
> >>>> + 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.
> >>>>
> >>>> +
> >>>>
> >>>> + @return 0 VMGEXIT succeeded.
> >>>>
> >>>> + @return 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
> >>>>
> >>>> + );
> >>>>
> >>>> +
> >>>>
> >>>> +/**
> >>>>
> >>>> + Handle a #VC exception.
> >>>>
> >>>> +
> >>>>
> >>>> + Performs the necessary processing to handle a #VC exception.
> >>>>
> >>>> +
> >>>>
> >>>> + The base library function returns an error equal to
> >>>> + VC_EXCEPTION,
> >>>>
> >>>> + to be propagated to the standard exception handling stack.
> >>>>
> >>>> +
> >>>>
> >>>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE
> >>>> + to be
> >>>> set
> >>>>
> >>>> + as value to use on error.
> >>>>
> >>>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
> >>>>
> >>>> +
> >>>>
> >>>> + @retval EFI_SUCCESS Exception handled
> >>>>
> >>>> + @retval EFI_UNSUPPORTED #VC not supported, (new)
> exception
> >>>> value to
> >>>>
> >>>> + propagate provided
> >>>>
> >>>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new)
> exception
> >>>> value to
> >>>>
> >>>> + propagate provided
> >>>>
> >>>> +
> >>>>
> >>>> +**/
> >>>>
> >>>> +EFI_STATUS
> >>>>
> >>>> +EFIAPI
> >>>>
> >>>> +VmgExitHandleVc (
> >>>>
> >>>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
> >>>>
> >>>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
> >>>>
> >>>> + );
> >>>>
> >>>> +
> >>>>
> >>>> +#endif
> >>>>
> >>>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> >>>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> >>>> new file mode 100644
> >>>> index 000000000000..30a239df298e
> >>>> --- /dev/null
> >>>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
> >>>> @@ -0,0 +1,121 @@
> >>>> +/** @file
> >>>>
> >>>> + VMGEXIT Base Support Library.
> >>>>
> >>>> +
> >>>>
> >>>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >>>> + reserved.<BR>
> >>>>
> >>>> + SPDX-License-Identifier: BSD-2-Clause-Patent
> >>>>
> >>>> +
> >>>>
> >>>> +**/
> >>>>
> >>>> +
> >>>>
> >>>> +#include <Base.h>
> >>>>
> >>>> +#include <Uefi.h>
> >>>>
> >>>> +#include <Library/VmgExitLib.h>
> >>>>
> >>>> +
> >>>>
> >>>> +/**
> >>>>
> >>>> + Perform VMGEXIT.
> >>>>
> >>>> +
> >>>>
> >>>> + Sets the necessary fields of the GHCB, invokes the VMGEXIT
> >>>> + instruction
> >>>> and
> >>>>
> >>>> + then handles the return actions.
> >>>>
> >>>> +
> >>>>
> >>>> + The base library function returns an error in the form of a
> >>>>
> >>>> + GHCB_EVENT_INJECTION representing a GP_EXCEPTION.
> >>>>
> >>>> +
> >>>>
> >>>> + @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.
> >>>>
> >>>> +
> >>>>
> >>>> + @return 0 VMGEXIT succeeded.
> >>>>
> >>>> + @return Others VMGEXIT processing did not succeed.
> Exception
> >>>>
> >>>> + event to be propagated.
> >>>>
> >>>> +
> >>>>
> >>>> +**/
> >>>>
> >>>> +UINT64
> >>>>
> >>>> +EFIAPI
> >>>>
> >>>> +VmgExit (
> >>>>
> >>>> + IN OUT GHCB *Ghcb,
> >>>>
> >>>> + IN UINT64 ExitCode,
> >>>>
> >>>> + IN UINT64 ExitInfo1,
> >>>>
> >>>> + IN UINT64 ExitInfo2
> >>>>
> >>>> + )
> >>>>
> >>>> +{
> >>>>
> >>>> + GHCB_EVENT_INJECTION Event;
> >>>>
> >>>> +
> >>>>
> >>>> + Event.Uint64 = 0;
> >>>>
> >>>> + Event.Elements.Vector = GP_EXCEPTION;
> >>>>
> >>>> + Event.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
> >>>>
> >>>> + Event.Elements.Valid = 1;
> >>>>
> >>>> +
> >>>>
> >>>> + return Event.Uint64;
> >>>>
> >>>> +}
> >>>>
> >>>> +
> >>>>
> >>>> +/**
> >>>>
> >>>> + Perform pre-VMGEXIT initialization/preparation.
> >>>>
> >>>> +
> >>>>
> >>>> + Performs the necessary steps in preparation for invoking VMGEXIT.
> >>>> + Must
> >>>> be
> >>>>
> >>>> + called before setting any fields within the GHCB.
> >>>>
> >>>> +
> >>>>
> >>>> + The base library function does nothing.
> >>>>
> >>>> +
> >>>>
> >>>> + @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.
> >>>>
> >>>> +
> >>>>
> >>>> + The base library function does nothing.
> >>>>
> >>>> +
> >>>>
> >>>> + @param[in, out] Ghcb A pointer to the GHCB
> >>>>
> >>>> +
> >>>>
> >>>> +**/
> >>>>
> >>>> +VOID
> >>>>
> >>>> +EFIAPI
> >>>>
> >>>> +VmgDone (
> >>>>
> >>>> + IN OUT GHCB *Ghcb
> >>>>
> >>>> + )
> >>>>
> >>>> +{
> >>>>
> >>>> +}
> >>>>
> >>>> +
> >>>>
> >>>> +/**
> >>>>
> >>>> + Handle a #VC exception.
> >>>>
> >>>> +
> >>>>
> >>>> + Performs the necessary processing to handle a #VC exception.
> >>>>
> >>>> +
> >>>>
> >>>> + The base library function returns an error equal to
> >>>> + VC_EXCEPTION,
> >>>>
> >>>> + to be propagated to the standard exception handling stack.
> >>>>
> >>>> +
> >>>>
> >>>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE
> >>>> + to be
> >>>> set
> >>>>
> >>>> + as value to use on error.
> >>>>
> >>>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
> >>>>
> >>>> +
> >>>>
> >>>> + @retval EFI_SUCCESS Exception handled
> >>>>
> >>>> + @retval EFI_UNSUPPORTED #VC not supported, (new)
> exception
> >>>> value to
> >>>>
> >>>> + propagate provided
> >>>>
> >>>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new)
> exception
> >>>> value to
> >>>>
> >>>> + propagate provided
> >>>>
> >>>> +
> >>>>
> >>>> +**/
> >>>>
> >>>> +EFI_STATUS
> >>>>
> >>>> +EFIAPI
> >>>>
> >>>> +VmgExitHandleVc (
> >>>>
> >>>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
> >>>>
> >>>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
> >>>>
> >>>> + )
> >>>>
> >>>> +{
> >>>>
> >>>> + *ExceptionType = VC_EXCEPTION;
> >>>>
> >>>> +
> >>>>
> >>>> + return EFI_UNSUPPORTED;
> >>>>
> >>>> +}
> >>>>
> >>>> diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> >>>> b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> >>>> new file mode 100644
> >>>> index 000000000000..8639bc0e8ce9
> >>>> --- /dev/null
> >>>> +++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.uni
> >>>> @@ -0,0 +1,15 @@
> >>>> +// /** @file
> >>>>
> >>>> +// VMGEXIT support library instance.
> >>>>
> >>>> +//
> >>>>
> >>>> +// VMGEXIT support library instance.
> >>>>
> >>>> +//
> >>>>
> >>>> +// Copyright (C) 2020, Advanced Micro Devices, Inc. All rights
> >>>> +reserved.<BR>
> >>>>
> >>>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> >>>>
> >>>> +//
> >>>>
> >>>> +// **/
> >>>>
> >>>> +
> >>>>
> >>>> +
> >>>>
> >>>> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT
> >> support
> >>>> NULL library instance"
> >>>>
> >>>> +
> >>>>
> >>>> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
> >>>> support NULL library instance."
> >>>>
> >>>> +
> >>>>
> >>>> --
> >>>> 2.27.0
> >>>
> >>
> >>
> >
> >
> >
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-19 13:50 ` Lendacky, Thomas
2020-06-19 14:21 ` Dong, Eric
@ 2020-06-19 15:38 ` Laszlo Ersek
2020-06-23 1:16 ` Dong, Eric
1 sibling, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-19 15:38 UTC (permalink / raw)
To: Tom Lendacky, devel, eric.dong
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 06/19/20 15:50, Tom Lendacky wrote:
> On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
>>
>>
>>> -----Original Message-----
>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>> Lendacky, Thomas
>>> Sent: Thursday, June 18, 2020 10:09 PM
>>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>>> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
>>> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
>>> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray
>>> <ray.ni@intel.com>
>>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
>>> support for VMGEXIT
>>>
>>> On 6/18/20 2:23 AM, Dong, Eric wrote:
>>>> Hi Tom,
>>>>
>>>> When use VS2015 to build this code, it reports below error. Please
>>>> help to
>>> fix it.
>>>>
>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220: warning
>>>> treated as error - no 'object' file generated
>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335: Mac
>>>> file format detected: please convert the source file to either DOS or
>>>> UNIX format
>>>
>>> That is strange... I didn't see this when I ran through the CI. When
>>> I do a file
>>> command against the file it reports:
>>>
>>> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with CRLF
>>> line terminators
>>>
>>> I'll investigate this and try and figure out what's going on, but if
>>> anyone else
>>> has some ideas, please let me know.
>>
>> Hi Tom,
>>
>> I met this error again when I trig below patch from AMD again for CPU
>> change.
>> "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to BaseUefiCpuLib"
>
> Hmmm... I think we could be running into issues with sending patches
> through our mail servers. Let me send you the patch series directly
> using some changes I made to my git config file to see if that helps.
> Would that be ok?
both sender and recipient git clones should have
[core]
whitespace = cr-at-eol
and the recipient clone should have
[am]
keepcr = true
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-05
These are also set by "BaseTools/Scripts/SetupGit.py".
Thanks
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-19 15:38 ` Laszlo Ersek
@ 2020-06-23 1:16 ` Dong, Eric
2020-06-23 12:58 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Dong, Eric @ 2020-06-23 1:16 UTC (permalink / raw)
To: devel@edk2.groups.io, lersek@redhat.com, Tom Lendacky
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo
> Ersek
> Sent: Friday, June 19, 2020 11:39 PM
> To: Tom Lendacky <thomas.lendacky@amd.com>; devel@edk2.groups.io;
> Dong, Eric <eric.dong@intel.com>
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
> support for VMGEXIT
>
> On 06/19/20 15:50, Tom Lendacky wrote:
> > On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
> >>
> >>
> >>> -----Original Message-----
> >>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> >>> Lendacky, Thomas
> >>> Sent: Thursday, June 18, 2020 10:09 PM
> >>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
> >>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >>> <ard.biesheuvel@arm.com>; Justen, Jordan L
> <jordan.l.justen@intel.com>;
> >>> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
> >>> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray
> >>> <ray.ni@intel.com>
> >>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
> library
> >>> support for VMGEXIT
> >>>
> >>> On 6/18/20 2:23 AM, Dong, Eric wrote:
> >>>> Hi Tom,
> >>>>
> >>>> When use VS2015 to build this code, it reports below error. Please
> >>>> help to
> >>> fix it.
> >>>>
> >>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220:
> warning
> >>>> treated as error - no 'object' file generated
> >>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335:
> Mac
> >>>> file format detected: please convert the source file to either DOS or
> >>>> UNIX format
> >>>
> >>> That is strange... I didn't see this when I ran through the CI. When
> >>> I do a file
> >>> command against the file it reports:
> >>>
> >>> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with
> CRLF
> >>> line terminators
> >>>
> >>> I'll investigate this and try and figure out what's going on, but if
> >>> anyone else
> >>> has some ideas, please let me know.
> >>
> >> Hi Tom,
> >>
> >> I met this error again when I trig below patch from AMD again for CPU
> >> change.
> >> "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to
> BaseUefiCpuLib"
> >
> > Hmmm... I think we could be running into issues with sending patches
> > through our mail servers. Let me send you the patch series directly
> > using some changes I made to my git config file to see if that helps.
> > Would that be ok?
>
> both sender and recipient git clones should have
>
> [core]
> whitespace = cr-at-eol
>
> and the recipient clone should have
>
> [am]
> keepcr = true
>
> https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-
> guide-for-edk2-contributors-and-maintainers#contrib-05
>
> These are also set by "BaseTools/Scripts/SetupGit.py".
>
Hi Tom,
I see below context in another mail thread and base on the latest status, this solution works and that patch has fixed the issue. Can you follow below suggest fixing your issue?
Hi Garrett,
I encounter below error when build
UefiCpuPkg\Library\BaseUefiCpuLib\BaseUefiCpuLib.c: warning C4335: Mac file format detected: please convert the source file to either DOS or UNIX format'
I encounter the issue ever, it result by mail encoding.
To resolve this issue, you can run [BaseTools\ Scripts\SetupGit.py] first, and then send the patch again.
Could you try it and send the patch again?
Thanks,
Eric
> Thanks
> Laszlo
>
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-23 1:16 ` Dong, Eric
@ 2020-06-23 12:58 ` Lendacky, Thomas
2020-07-02 7:04 ` Dong, Eric
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-23 12:58 UTC (permalink / raw)
To: devel, eric.dong, lersek@redhat.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 6/22/20 8:16 PM, Dong, Eric via groups.io wrote:
>
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo
>> Ersek
>> Sent: Friday, June 19, 2020 11:39 PM
>> To: Tom Lendacky <thomas.lendacky@amd.com>; devel@edk2.groups.io;
>> Dong, Eric <eric.dong@intel.com>
>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
>> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
>> support for VMGEXIT
>>
>> On 06/19/20 15:50, Tom Lendacky wrote:
>>> On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>>> Lendacky, Thomas
>>>>> Sent: Thursday, June 18, 2020 10:09 PM
>>>>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
>>>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>>>>> <ard.biesheuvel@arm.com>; Justen, Jordan L
>> <jordan.l.justen@intel.com>;
>>>>> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
>>>>> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray
>>>>> <ray.ni@intel.com>
>>>>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
>> library
>>>>> support for VMGEXIT
>>>>>
>>>>> On 6/18/20 2:23 AM, Dong, Eric wrote:
>>>>>> Hi Tom,
>>>>>>
>>>>>> When use VS2015 to build this code, it reports below error. Please
>>>>>> help to
>>>>> fix it.
>>>>>>
>>>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220:
>> warning
>>>>>> treated as error - no 'object' file generated
>>>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335:
>> Mac
>>>>>> file format detected: please convert the source file to either DOS or
>>>>>> UNIX format
>>>>>
>>>>> That is strange... I didn't see this when I ran through the CI. When
>>>>> I do a file
>>>>> command against the file it reports:
>>>>>
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text, with
>> CRLF
>>>>> line terminators
>>>>>
>>>>> I'll investigate this and try and figure out what's going on, but if
>>>>> anyone else
>>>>> has some ideas, please let me know.
>>>>
>>>> Hi Tom,
>>>>
>>>> I met this error again when I trig below patch from AMD again for CPU
>>>> change.
>>>> "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to
>> BaseUefiCpuLib"
>>>
>>> Hmmm... I think we could be running into issues with sending patches
>>> through our mail servers. Let me send you the patch series directly
>>> using some changes I made to my git config file to see if that helps.
>>> Would that be ok?
>>
>> both sender and recipient git clones should have
>>
>> [core]
>> whitespace = cr-at-eol
>>
>> and the recipient clone should have
>>
>> [am]
>> keepcr = true
>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FLaszlo%27s-unkempt-git-&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cd461956236264e4a6d3a08d81713205d%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637284718210751789&sdata=ftFiRZkC3n2n2MZyL6t9HKnp1fYgzUQV4FRBvVNQ4%2FA%3D&reserved=0
>> guide-for-edk2-contributors-and-maintainers#contrib-05
>>
>> These are also set by "BaseTools/Scripts/SetupGit.py".
>>
>
> Hi Tom,
>
> I see below context in another mail thread and base on the latest status, this solution works and that patch has fixed the issue. Can you follow below suggest fixing your issue?
>
> Hi Garrett,
>
> I encounter below error when build
> UefiCpuPkg\Library\BaseUefiCpuLib\BaseUefiCpuLib.c: warning C4335: Mac file format detected: please convert the source file to either DOS or UNIX format'
>
> I encounter the issue ever, it result by mail encoding.
> To resolve this issue, you can run [BaseTools\ Scripts\SetupGit.py] first, and then send the patch again.
>
> Could you try it and send the patch again?
Hi Eric,
I already had those settings in my git config file, so I'm thinking it was
still something else. I sent you a direct set of patches with some other
setting tweaks. Let me know how those work out for you.
Thanks,
Tom
>
> Thanks,
> Eric
>
>> Thanks
>> Laszlo
>>
>>
>>
>
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-06-23 12:58 ` Lendacky, Thomas
@ 2020-07-02 7:04 ` Dong, Eric
2020-07-06 20:03 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Dong, Eric @ 2020-07-02 7:04 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com, lersek@redhat.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
Hi Tom,
We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
PeCoffLoaderEx.c
g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
Thanks,
Eric
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Tuesday, June 23, 2020 8:58 PM
> To: devel@edk2.groups.io; Dong, Eric <eric.dong@intel.com>;
> lersek@redhat.com
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
> support for VMGEXIT
>
> On 6/22/20 8:16 PM, Dong, Eric via groups.io wrote:
> >
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Laszlo
> >> Ersek
> >> Sent: Friday, June 19, 2020 11:39 PM
> >> To: Tom Lendacky <thomas.lendacky@amd.com>; devel@edk2.groups.io;
> >> Dong, Eric <eric.dong@intel.com>
> >> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >> <ard.biesheuvel@arm.com>; Justen, Jordan L
> >> <jordan.l.justen@intel.com>; Gao, Liming <liming.gao@intel.com>;
> >> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray
> >> <ray.ni@intel.com>
> >> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
> >> library support for VMGEXIT
> >>
> >> On 06/19/20 15:50, Tom Lendacky wrote:
> >>> On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
> >>>>
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> >>>>> Lendacky, Thomas
> >>>>> Sent: Thursday, June 18, 2020 10:09 PM
> >>>>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
> >>>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >>>>> <ard.biesheuvel@arm.com>; Justen, Jordan L
> >> <jordan.l.justen@intel.com>;
> >>>>> Laszlo Ersek <lersek@redhat.com>; Gao, Liming
> >>>>> <liming.gao@intel.com>; Kinney, Michael D
> >>>>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> >>>>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
> >> library
> >>>>> support for VMGEXIT
> >>>>>
> >>>>> On 6/18/20 2:23 AM, Dong, Eric wrote:
> >>>>>> Hi Tom,
> >>>>>>
> >>>>>> When use VS2015 to build this code, it reports below error.
> >>>>>> Please help to
> >>>>> fix it.
> >>>>>>
> >>>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220:
> >> warning
> >>>>>> treated as error - no 'object' file generated
> >>>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335:
> >> Mac
> >>>>>> file format detected: please convert the source file to either
> >>>>>> DOS or UNIX format
> >>>>>
> >>>>> That is strange... I didn't see this when I ran through the CI.
> >>>>> When I do a file command against the file it reports:
> >>>>>
> >>>>> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text,
> >>>>> with
> >> CRLF
> >>>>> line terminators
> >>>>>
> >>>>> I'll investigate this and try and figure out what's going on, but
> >>>>> if anyone else has some ideas, please let me know.
> >>>>
> >>>> Hi Tom,
> >>>>
> >>>> I met this error again when I trig below patch from AMD again for
> >>>> CPU change.
> >>>> "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to
> >> BaseUefiCpuLib"
> >>>
> >>> Hmmm... I think we could be running into issues with sending patches
> >>> through our mail servers. Let me send you the patch series directly
> >>> using some changes I made to my git config file to see if that helps.
> >>> Would that be ok?
> >>
> >> both sender and recipient git clones should have
> >>
> >> [core]
> >> whitespace = cr-at-eol
> >>
> >> and the recipient clone should have
> >>
> >> [am]
> >> keepcr = true
> >>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FLaszlo%27s-
> unkempt
> >> -git-
> &data=02%7C01%7Cthomas.lendacky%40amd.com%7Cd461956236264e
> 4a
> >>
> 6d3a08d81713205d%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6
> 372847
> >>
> 18210751789&sdata=ftFiRZkC3n2n2MZyL6t9HKnp1fYgzUQV4FRBvVNQ4
> %2FA%3
> >> D&reserved=0
> >> guide-for-edk2-contributors-and-maintainers#contrib-05
> >>
> >> These are also set by "BaseTools/Scripts/SetupGit.py".
> >>
> >
> > Hi Tom,
> >
> > I see below context in another mail thread and base on the latest status,
> this solution works and that patch has fixed the issue. Can you follow below
> suggest fixing your issue?
> >
> > Hi Garrett,
> >
> > I encounter below error when build
> > UefiCpuPkg\Library\BaseUefiCpuLib\BaseUefiCpuLib.c: warning C4335:
> Mac file format detected: please convert the source file to either DOS or
> UNIX format'
> >
> > I encounter the issue ever, it result by mail encoding.
> > To resolve this issue, you can run [BaseTools\ Scripts\SetupGit.py] first,
> and then send the patch again.
> >
> > Could you try it and send the patch again?
>
> Hi Eric,
>
> I already had those settings in my git config file, so I'm thinking it was still
> something else. I sent you a direct set of patches with some other setting
> tweaks. Let me know how those work out for you.
>
> Thanks,
> Tom
>
> >
> > Thanks,
> > Eric
> >
> >> Thanks
> >> Laszlo
> >>
> >>
> >>
> >
> >
> >
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-07-02 7:04 ` Dong, Eric
@ 2020-07-06 20:03 ` Lendacky, Thomas
2020-07-07 15:36 ` Laszlo Ersek
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-07-06 20:03 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io, lersek@redhat.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 7/2/20 2:04 AM, Dong, Eric wrote:
> Hi Tom,
Hi Eric,
>
> We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
Good to know, thanks!
>
> With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
>
> Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
> PeCoffLoaderEx.c
> g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
> NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
Yup, looks like that needs to be a "1ULL <<" instead of "1 <<".
I have verified that fixes the issue.
One thing I noticed is that the 32-bit builds
(PlatformCI_OvmfPkg_Windows_VS2019_PR, Platform_CI OVMF_IA32_NOOPT and
Platform_CI OVMF_IA32X64_NOOPT) encounter an error:
ERROR - Linker #2001 from SecMain.lib(SecMain.obj) : unresolved external symbol __allshl
ERROR - Linker #1120 from d:\a\1\s\Build\Ovmf3264\NOOPT_VS2019\IA32\OvmfPkg\Sec\SecMain\DEBUG\SecMain.dll : fatal 1 unresolved externals
ERROR - Compiler #1077 from NMAKE : fatal '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x86\link.exe"' : return code '0x460'
Any idea what is causing this error?
Thanks,
Tom
>
> Thanks,
> Eric
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Tuesday, June 23, 2020 8:58 PM
>> To: devel@edk2.groups.io; Dong, Eric <eric.dong@intel.com>;
>> lersek@redhat.com
>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
>> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library
>> support for VMGEXIT
>>
>> On 6/22/20 8:16 PM, Dong, Eric via groups.io wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Laszlo
>>>> Ersek
>>>> Sent: Friday, June 19, 2020 11:39 PM
>>>> To: Tom Lendacky <thomas.lendacky@amd.com>; devel@edk2.groups.io;
>>>> Dong, Eric <eric.dong@intel.com>
>>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@arm.com>; Justen, Jordan L
>>>> <jordan.l.justen@intel.com>; Gao, Liming <liming.gao@intel.com>;
>>>> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray
>>>> <ray.ni@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
>>>> library support for VMGEXIT
>>>>
>>>> On 06/19/20 15:50, Tom Lendacky wrote:
>>>>> On 6/19/20 2:47 AM, Dong, Eric via groups.io wrote:
>>>>>>
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>>>>> Lendacky, Thomas
>>>>>>> Sent: Thursday, June 18, 2020 10:09 PM
>>>>>>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
>>>>>>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>>>>>>> <ard.biesheuvel@arm.com>; Justen, Jordan L
>>>> <jordan.l.justen@intel.com>;
>>>>>>> Laszlo Ersek <lersek@redhat.com>; Gao, Liming
>>>>>>> <liming.gao@intel.com>; Kinney, Michael D
>>>>>>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>>>>>>> Subject: Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement
>>>> library
>>>>>>> support for VMGEXIT
>>>>>>>
>>>>>>> On 6/18/20 2:23 AM, Dong, Eric wrote:
>>>>>>>> Hi Tom,
>>>>>>>>
>>>>>>>> When use VS2015 to build this code, it reports below error.
>>>>>>>> Please help to
>>>>>>> fix it.
>>>>>>>>
>>>>>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: error C2220:
>>>> warning
>>>>>>>> treated as error - no 'object' file generated
>>>>>>>> k:\edk2\UefiCpuPkg\Include\Library/VmgExitLib.h: warning C4335:
>>>> Mac
>>>>>>>> file format detected: please convert the source file to either
>>>>>>>> DOS or UNIX format
>>>>>>>
>>>>>>> That is strange... I didn't see this when I ran through the CI.
>>>>>>> When I do a file command against the file it reports:
>>>>>>>
>>>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h: C source, ASCII text,
>>>>>>> with
>>>> CRLF
>>>>>>> line terminators
>>>>>>>
>>>>>>> I'll investigate this and try and figure out what's going on, but
>>>>>>> if anyone else has some ideas, please let me know.
>>>>>>
>>>>>> Hi Tom,
>>>>>>
>>>>>> I met this error again when I trig below patch from AMD again for
>>>>>> CPU change.
>>>>>> "UefiCpuPkg: Move StandardSignatureIsAuthenticAMD to
>>>> BaseUefiCpuLib"
>>>>>
>>>>> Hmmm... I think we could be running into issues with sending patches
>>>>> through our mail servers. Let me send you the patch series directly
>>>>> using some changes I made to my git config file to see if that helps.
>>>>> Would that be ok?
>>>>
>>>> both sender and recipient git clones should have
>>>>
>>>> [core]
>>>> whitespace = cr-at-eol
>>>>
>>>> and the recipient clone should have
>>>>
>>>> [am]
>>>> keepcr = true
>>>>
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
>>>> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FLaszlo%27s-
>> unkempt
>>>> -git-
>> &data=02%7C01%7Cthomas.lendacky%40amd.com%7Cd461956236264e
>> 4a
>>>>
>> 6d3a08d81713205d%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6
>> 372847
>>>>
>> 18210751789&sdata=ftFiRZkC3n2n2MZyL6t9HKnp1fYgzUQV4FRBvVNQ4
>> %2FA%3
>>>> D&reserved=0
>>>> guide-for-edk2-contributors-and-maintainers#contrib-05
>>>>
>>>> These are also set by "BaseTools/Scripts/SetupGit.py".
>>>>
>>>
>>> Hi Tom,
>>>
>>> I see below context in another mail thread and base on the latest status,
>> this solution works and that patch has fixed the issue. Can you follow below
>> suggest fixing your issue?
>>>
>>> Hi Garrett,
>>>
>>> I encounter below error when build
>>> UefiCpuPkg\Library\BaseUefiCpuLib\BaseUefiCpuLib.c: warning C4335:
>> Mac file format detected: please convert the source file to either DOS or
>> UNIX format'
>>>
>>> I encounter the issue ever, it result by mail encoding.
>>> To resolve this issue, you can run [BaseTools\ Scripts\SetupGit.py] first,
>> and then send the patch again.
>>>
>>> Could you try it and send the patch again?
>>
>> Hi Eric,
>>
>> I already had those settings in my git config file, so I'm thinking it was still
>> something else. I sent you a direct set of patches with some other setting
>> tweaks. Let me know how those work out for you.
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Eric
>>>
>>>> Thanks
>>>> Laszlo
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-07-06 20:03 ` Lendacky, Thomas
@ 2020-07-07 15:36 ` Laszlo Ersek
2020-07-07 15:50 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-07-07 15:36 UTC (permalink / raw)
To: Tom Lendacky, Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 07/06/20 22:03, Tom Lendacky wrote:
> On 7/2/20 2:04 AM, Dong, Eric wrote:
>> Hi Tom,
>
> Hi Eric,
>
>>
>> We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
>
> Good to know, thanks!
>
>>
>> With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
>>
>> Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
>> PeCoffLoaderEx.c
>> g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
>> NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
This is for the line
Displacement *= (1 << Ext->Sib.Scale);
from
[edk2-devel] [PATCH v9 17/46]
OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
>
> Yup, looks like that needs to be a "1ULL <<" instead of "1 <<".
> I have verified that fixes the issue.
I disagree.
At that point, Displacement is of type INT64, and it may well be a
negative value. We definitely want to multiply it by a signed int
(values 1, 2, 4, 8).
I commented on this before. Please see:
(i) my comment block (10) here -- especially comment (10c):
https://edk2.groups.io/g/devel/message/60144
(alternative link:
<http://mid.mail-archive.com/169e44cb-2c1c-6d9a-342a-2a1f618e3753@redhat.com>)
(ii) and my comment here:
https://edk2.groups.io/g/devel/message/60146
(alternative link:
<http://mid.mail-archive.com/139ce789-b938-c8b9-030e-c1b6c67e47ea@redhat.com>).
The compiler warning is well-meaning, but unnecessary. A 64-bit shift is
*NOT* intended. We want to end up with one of the signed int (aka INT32)
values 1, 2, 4 or 8. And then multiply the INT64 Displacement with that
value. For the multiplication, the INT32 value 1, 2, 4 or 8 will be
implicitly converted to INT64. That's entirely intentional.
If we want to suppress the warning, while keeping the logic intact, we
should employ an explicit cast:
Displacement *= (INT64)(1 << Ext->Sib.Scale);
>
> One thing I noticed is that the 32-bit builds
> (PlatformCI_OvmfPkg_Windows_VS2019_PR, Platform_CI OVMF_IA32_NOOPT and
> Platform_CI OVMF_IA32X64_NOOPT) encounter an error:
>
> ERROR - Linker #2001 from SecMain.lib(SecMain.obj) : unresolved external symbol __allshl
> ERROR - Linker #1120 from d:\a\1\s\Build\Ovmf3264\NOOPT_VS2019\IA32\OvmfPkg\Sec\SecMain\DEBUG\SecMain.dll : fatal 1 unresolved externals
> ERROR - Compiler #1077 from NMAKE : fatal '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x86\link.exe"' : return code '0x460'
>
> Any idea what is causing this error?
A left-shift operator (<<) applied to a 64-bit operand is somehow
finding its way into the 32-bit SEC build.
That is indeed wrong (for such cases, we're supposed to use LShiftU64()
from BaseLib).
What I don't understand however is that all of the "<<" operator uses,
on 64-bit operands, should already be limited to code that is *only*
built for X64!
For example, with this series applied, SecMain in OVMF consumes
"UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf".
And the latter consumes VmgExitLib.
But VmgExitLib is resolved to
"UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf", in the IA32 and
IA32X64 DSC files. This Null instance contains no left-shifts.
Therefore any << operators, applied to 64-bit operands, present in
"OvmfPkg/Library/VmgExitLib", should never be compiled for IA32 and IA32X64.
So I don't know where the problematic "<<" comes from. It does not come
from VmgExitLib, as far as I can tell.
Thanks,
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-07-07 15:36 ` Laszlo Ersek
@ 2020-07-07 15:50 ` Lendacky, Thomas
2020-07-07 17:11 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-07-07 15:50 UTC (permalink / raw)
To: Laszlo Ersek, Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 7/7/20 10:36 AM, Laszlo Ersek wrote:
> On 07/06/20 22:03, Tom Lendacky wrote:
>> On 7/2/20 2:04 AM, Dong, Eric wrote:
>>> Hi Tom,
>>
>> Hi Eric,
>>
>>>
>>> We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
>>
>> Good to know, thanks!
>>
>>>
>>> With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
>>>
>>> Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
>>> PeCoffLoaderEx.c
>>> g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
>>> NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
>
> This is for the line
>
> Displacement *= (1 << Ext->Sib.Scale);
>
> from
>
> [edk2-devel] [PATCH v9 17/46]
> OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
>
>>
>> Yup, looks like that needs to be a "1ULL <<" instead of "1 <<".
>> I have verified that fixes the issue.
>
> I disagree.
>
> At that point, Displacement is of type INT64, and it may well be a
> negative value. We definitely want to multiply it by a signed int
> (values 1, 2, 4, 8).
>
> I commented on this before. Please see:
>
> (i) my comment block (10) here -- especially comment (10c):
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60144&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=g%2BGooY1Sv0G7ydr11Jh%2BTXxo4Wy6ZWcT5Mq9VmWddi8%3D&reserved=0
>
> (alternative link:
> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F169e44cb-2c1c-6d9a-342a-2a1f618e3753%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=6p91db%2F6oz%2FHc65Sq4fvH%2FcPmiAfdS8MImsaznaoaXA%3D&reserved=0>)
>
> (ii) and my comment here:
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60146&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=iNIBJCIlfEEsY37cdwUbH27tx5HvXVs3PZiOQfaGeLQ%3D&reserved=0
>
> (alternative link:
> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F139ce789-b938-c8b9-030e-c1b6c67e47ea%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=mWCAHqTOpp7B9nWUJjTRJ9VZ74iwdElRTOoNhEpFs%2Bc%3D&reserved=0>).
>
>
> The compiler warning is well-meaning, but unnecessary. A 64-bit shift is
> *NOT* intended. We want to end up with one of the signed int (aka INT32)
> values 1, 2, 4 or 8. And then multiply the INT64 Displacement with that
> value. For the multiplication, the INT32 value 1, 2, 4 or 8 will be
> implicitly converted to INT64. That's entirely intentional.
>
> If we want to suppress the warning, while keeping the logic intact, we
> should employ an explicit cast:
>
> Displacement *= (INT64)(1 << Ext->Sib.Scale);
Ok, that makes sense. I'll use the explicit cast.
>
>>
>> One thing I noticed is that the 32-bit builds
>> (PlatformCI_OvmfPkg_Windows_VS2019_PR, Platform_CI OVMF_IA32_NOOPT and
>> Platform_CI OVMF_IA32X64_NOOPT) encounter an error:
>>
>> ERROR - Linker #2001 from SecMain.lib(SecMain.obj) : unresolved external symbol __allshl
>> ERROR - Linker #1120 from d:\a\1\s\Build\Ovmf3264\NOOPT_VS2019\IA32\OvmfPkg\Sec\SecMain\DEBUG\SecMain.dll : fatal 1 unresolved externals
>> ERROR - Compiler #1077 from NMAKE : fatal '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x86\link.exe"' : return code '0x460'
>>
>> Any idea what is causing this error?
>
> A left-shift operator (<<) applied to a 64-bit operand is somehow
> finding its way into the 32-bit SEC build.
>
> That is indeed wrong (for such cases, we're supposed to use LShiftU64()
> from BaseLib).
>
> What I don't understand however is that all of the "<<" operator uses,
> on 64-bit operands, should already be limited to code that is *only*
> built for X64!
>
> For example, with this series applied, SecMain in OVMF consumes
> "UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf".
> And the latter consumes VmgExitLib.
>
> But VmgExitLib is resolved to
> "UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf", in the IA32 and
> IA32X64 DSC files. This Null instance contains no left-shifts.
>
> Therefore any << operators, applied to 64-bit operands, present in
> "OvmfPkg/Library/VmgExitLib", should never be compiled for IA32 and IA32X64.
>
> So I don't know where the problematic "<<" comes from. It does not come
> from VmgExitLib, as far as I can tell.
Yes, I don't think it's coming from VmgExitLib, either.
I wonder if it somehow might be coming from the MSR_SEV_ES_GHCB_REGISTER
struct and the bit fields that are used within it? That code, while not
executed in non-X64 builds because SEV-ES is not active, is still built
and maybe the bit fields result in implicit shifts occurring, specifically
in SevEsProtocolFailure()?
I'll experiment with some things and see if that is the issue.
Thanks,
Tom
>
> Thanks,
> Laszlo
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-07-07 15:50 ` Lendacky, Thomas
@ 2020-07-07 17:11 ` Lendacky, Thomas
2020-07-08 13:07 ` Lendacky, Thomas
2020-07-08 15:24 ` bit-fields [was: PATCH v9 08/46 UefiCpuPkg: Implement library support for VMGEXIT] Laszlo Ersek
0 siblings, 2 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-07-07 17:11 UTC (permalink / raw)
To: Laszlo Ersek, Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 7/7/20 10:50 AM, Tom Lendacky wrote:
> On 7/7/20 10:36 AM, Laszlo Ersek wrote:
>> On 07/06/20 22:03, Tom Lendacky wrote:
>>> On 7/2/20 2:04 AM, Dong, Eric wrote:
>>>> Hi Tom,
>>>
>>> Hi Eric,
>>>
>>>>
>>>> We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
>>>
>>> Good to know, thanks!
>>>
>>>>
>>>> With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
>>>>
>>>> Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
>>>> PeCoffLoaderEx.c
>>>> g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
>>>> NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
>>
>> This is for the line
>>
>> Displacement *= (1 << Ext->Sib.Scale);
>>
>> from
>>
>> [edk2-devel] [PATCH v9 17/46]
>> OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
>>
>>>
>>> Yup, looks like that needs to be a "1ULL <<" instead of "1 <<".
>>> I have verified that fixes the issue.
>>
>> I disagree.
>>
>> At that point, Displacement is of type INT64, and it may well be a
>> negative value. We definitely want to multiply it by a signed int
>> (values 1, 2, 4, 8).
>>
>> I commented on this before. Please see:
>>
>> (i) my comment block (10) here -- especially comment (10c):
>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60144&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=g%2BGooY1Sv0G7ydr11Jh%2BTXxo4Wy6ZWcT5Mq9VmWddi8%3D&reserved=0
>>
>> (alternative link:
>> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F169e44cb-2c1c-6d9a-342a-2a1f618e3753%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=6p91db%2F6oz%2FHc65Sq4fvH%2FcPmiAfdS8MImsaznaoaXA%3D&reserved=0>)
>>
>> (ii) and my comment here:
>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60146&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=iNIBJCIlfEEsY37cdwUbH27tx5HvXVs3PZiOQfaGeLQ%3D&reserved=0
>>
>> (alternative link:
>> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F139ce789-b938-c8b9-030e-c1b6c67e47ea%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=mWCAHqTOpp7B9nWUJjTRJ9VZ74iwdElRTOoNhEpFs%2Bc%3D&reserved=0>).
>>
>>
>> The compiler warning is well-meaning, but unnecessary. A 64-bit shift is
>> *NOT* intended. We want to end up with one of the signed int (aka INT32)
>> values 1, 2, 4 or 8. And then multiply the INT64 Displacement with that
>> value. For the multiplication, the INT32 value 1, 2, 4 or 8 will be
>> implicitly converted to INT64. That's entirely intentional.
>>
>> If we want to suppress the warning, while keeping the logic intact, we
>> should employ an explicit cast:
>>
>> Displacement *= (INT64)(1 << Ext->Sib.Scale);
>
> Ok, that makes sense. I'll use the explicit cast.
>
>>
>>>
>>> One thing I noticed is that the 32-bit builds
>>> (PlatformCI_OvmfPkg_Windows_VS2019_PR, Platform_CI OVMF_IA32_NOOPT and
>>> Platform_CI OVMF_IA32X64_NOOPT) encounter an error:
>>>
>>> ERROR - Linker #2001 from SecMain.lib(SecMain.obj) : unresolved external symbol __allshl
>>> ERROR - Linker #1120 from d:\a\1\s\Build\Ovmf3264\NOOPT_VS2019\IA32\OvmfPkg\Sec\SecMain\DEBUG\SecMain.dll : fatal 1 unresolved externals
>>> ERROR - Compiler #1077 from NMAKE : fatal '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x86\link.exe"' : return code '0x460'
>>>
>>> Any idea what is causing this error?
>>
>> A left-shift operator (<<) applied to a 64-bit operand is somehow
>> finding its way into the 32-bit SEC build.
>>
>> That is indeed wrong (for such cases, we're supposed to use LShiftU64()
>> from BaseLib).
>>
>> What I don't understand however is that all of the "<<" operator uses,
>> on 64-bit operands, should already be limited to code that is *only*
>> built for X64!
>>
>> For example, with this series applied, SecMain in OVMF consumes
>> "UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf".
>> And the latter consumes VmgExitLib.
>>
>> But VmgExitLib is resolved to
>> "UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf", in the IA32 and
>> IA32X64 DSC files. This Null instance contains no left-shifts.
>>
>> Therefore any << operators, applied to 64-bit operands, present in
>> "OvmfPkg/Library/VmgExitLib", should never be compiled for IA32 and IA32X64.
>>
>> So I don't know where the problematic "<<" comes from. It does not come
>> from VmgExitLib, as far as I can tell.
>
> Yes, I don't think it's coming from VmgExitLib, either.
>
> I wonder if it somehow might be coming from the MSR_SEV_ES_GHCB_REGISTER
> struct and the bit fields that are used within it? That code, while not
> executed in non-X64 builds because SEV-ES is not active, is still built
> and maybe the bit fields result in implicit shifts occurring, specifically
> in SevEsProtocolFailure()?
>
> I'll experiment with some things and see if that is the issue.
I commented out the setting of the GhcbTerminate fields in the
SevEsProtocolFailure() routine of OvmfPkg/Sec/SecMain.c and the error
disappeared. I'll see if changing from using UINT64 to multiple UINT32
entries fixes the problem, but I wouldn't think that the bit fields
would/should cause an issue here with 32-bit builds.
Thanks,
Tom
>
> Thanks,
> Tom
>
>>
>> Thanks,
>> Laszlo
>>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-07-07 17:11 ` Lendacky, Thomas
@ 2020-07-08 13:07 ` Lendacky, Thomas
2020-07-08 16:25 ` Laszlo Ersek
2020-07-08 15:24 ` bit-fields [was: PATCH v9 08/46 UefiCpuPkg: Implement library support for VMGEXIT] Laszlo Ersek
1 sibling, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-07-08 13:07 UTC (permalink / raw)
To: Laszlo Ersek, Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 7/7/20 12:11 PM, Tom Lendacky wrote:
> On 7/7/20 10:50 AM, Tom Lendacky wrote:
>> On 7/7/20 10:36 AM, Laszlo Ersek wrote:
>>> On 07/06/20 22:03, Tom Lendacky wrote:
>>>> On 7/2/20 2:04 AM, Dong, Eric wrote:
>>>>> Hi Tom,
>>>>
>>>> Hi Eric,
>>>>
>>>>>
>>>>> We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
>>>>
>>>> Good to know, thanks!
>>>>
>>>>>
>>>>> With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
>>>>>
>>>>> Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
>>>>> PeCoffLoaderEx.c
>>>>> g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
>>>>> NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
>>>
>>> This is for the line
>>>
>>> Displacement *= (1 << Ext->Sib.Scale);
>>>
>>> from
>>>
>>> [edk2-devel] [PATCH v9 17/46]
>>> OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
>>>
>>>>
>>>> Yup, looks like that needs to be a "1ULL <<" instead of "1 <<".
>>>> I have verified that fixes the issue.
>>>
>>> I disagree.
>>>
>>> At that point, Displacement is of type INT64, and it may well be a
>>> negative value. We definitely want to multiply it by a signed int
>>> (values 1, 2, 4, 8).
>>>
>>> I commented on this before. Please see:
>>>
>>> (i) my comment block (10) here -- especially comment (10c):
>>>
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60144&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=g%2BGooY1Sv0G7ydr11Jh%2BTXxo4Wy6ZWcT5Mq9VmWddi8%3D&reserved=0
>>>
>>> (alternative link:
>>> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F169e44cb-2c1c-6d9a-342a-2a1f618e3753%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=6p91db%2F6oz%2FHc65Sq4fvH%2FcPmiAfdS8MImsaznaoaXA%3D&reserved=0>)
>>>
>>> (ii) and my comment here:
>>>
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60146&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=iNIBJCIlfEEsY37cdwUbH27tx5HvXVs3PZiOQfaGeLQ%3D&reserved=0
>>>
>>> (alternative link:
>>> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F139ce789-b938-c8b9-030e-c1b6c67e47ea%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=mWCAHqTOpp7B9nWUJjTRJ9VZ74iwdElRTOoNhEpFs%2Bc%3D&reserved=0>).
>>>
>>>
>>> The compiler warning is well-meaning, but unnecessary. A 64-bit shift is
>>> *NOT* intended. We want to end up with one of the signed int (aka INT32)
>>> values 1, 2, 4 or 8. And then multiply the INT64 Displacement with that
>>> value. For the multiplication, the INT32 value 1, 2, 4 or 8 will be
>>> implicitly converted to INT64. That's entirely intentional.
>>>
>>> If we want to suppress the warning, while keeping the logic intact, we
>>> should employ an explicit cast:
>>>
>>> Displacement *= (INT64)(1 << Ext->Sib.Scale);
>>
>> Ok, that makes sense. I'll use the explicit cast.
>>
>>>
>>>>
>>>> One thing I noticed is that the 32-bit builds
>>>> (PlatformCI_OvmfPkg_Windows_VS2019_PR, Platform_CI OVMF_IA32_NOOPT and
>>>> Platform_CI OVMF_IA32X64_NOOPT) encounter an error:
>>>>
>>>> ERROR - Linker #2001 from SecMain.lib(SecMain.obj) : unresolved external symbol __allshl
>>>> ERROR - Linker #1120 from d:\a\1\s\Build\Ovmf3264\NOOPT_VS2019\IA32\OvmfPkg\Sec\SecMain\DEBUG\SecMain.dll : fatal 1 unresolved externals
>>>> ERROR - Compiler #1077 from NMAKE : fatal '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x86\link.exe"' : return code '0x460'
>>>>
>>>> Any idea what is causing this error?
>>>
>>> A left-shift operator (<<) applied to a 64-bit operand is somehow
>>> finding its way into the 32-bit SEC build.
>>>
>>> That is indeed wrong (for such cases, we're supposed to use LShiftU64()
>>> from BaseLib).
>>>
>>> What I don't understand however is that all of the "<<" operator uses,
>>> on 64-bit operands, should already be limited to code that is *only*
>>> built for X64!
>>>
>>> For example, with this series applied, SecMain in OVMF consumes
>>> "UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf".
>>> And the latter consumes VmgExitLib.
>>>
>>> But VmgExitLib is resolved to
>>> "UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf", in the IA32 and
>>> IA32X64 DSC files. This Null instance contains no left-shifts.
>>>
>>> Therefore any << operators, applied to 64-bit operands, present in
>>> "OvmfPkg/Library/VmgExitLib", should never be compiled for IA32 and IA32X64.
>>>
>>> So I don't know where the problematic "<<" comes from. It does not come
>>> from VmgExitLib, as far as I can tell.
>>
>> Yes, I don't think it's coming from VmgExitLib, either.
>>
>> I wonder if it somehow might be coming from the MSR_SEV_ES_GHCB_REGISTER
>> struct and the bit fields that are used within it? That code, while not
>> executed in non-X64 builds because SEV-ES is not active, is still built
>> and maybe the bit fields result in implicit shifts occurring, specifically
>> in SevEsProtocolFailure()?
>>
>> I'll experiment with some things and see if that is the issue.
>
> I commented out the setting of the GhcbTerminate fields in the
> SevEsProtocolFailure() routine of OvmfPkg/Sec/SecMain.c and the error
> disappeared. I'll see if changing from using UINT64 to multiple UINT32
> entries fixes the problem, but I wouldn't think that the bit fields
> would/should cause an issue here with 32-bit builds.
Changing the bit fields from UINT64 to UINT32 fixed the error and SEV-ES
support continues to function properly. Since the architecture is little
endian, there was no need to pad out to the full UINT64 size for the
structs (the union takes care of that in general). The change looks like
this:
diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
index 466a3143599c..3cbe593868d4 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -28,7 +28,7 @@
**/
typedef union {
struct {
- UINT64 Function:12;
+ UINT32 Function:12;
} GhcbInfo;
struct {
@@ -39,9 +39,9 @@ typedef union {
} GhcbProtocol;
struct {
- UINT64 Function:12;
- UINT64 ReasonCodeSet:4;
- UINT64 ReasonCode:8;
+ UINT32 Function:12;
+ UINT32 ReasonCodeSet:4;
+ UINT32 ReasonCode:8;
} GhcbTerminate;
VOID *Ghcb;
Unless there are any concerns, I'll incorporate this change.
Thanks,
Tom
>
> Thanks,
> Tom
>
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Laszlo
>>>
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT
2020-07-08 13:07 ` Lendacky, Thomas
@ 2020-07-08 16:25 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-07-08 16:25 UTC (permalink / raw)
To: Tom Lendacky, Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 07/08/20 15:07, Tom Lendacky wrote:
> On 7/7/20 12:11 PM, Tom Lendacky wrote:
>> On 7/7/20 10:50 AM, Tom Lendacky wrote:
>>> On 7/7/20 10:36 AM, Laszlo Ersek wrote:
>>>> On 07/06/20 22:03, Tom Lendacky wrote:
>>>>> On 7/2/20 2:04 AM, Dong, Eric wrote:
>>>>>> Hi Tom,
>>>>>
>>>>> Hi Eric,
>>>>>
>>>>>>
>>>>>> We have root cause this Mac file format issue. The patch mail from your side include extra two "=0D=0D" , and our test tool convert them to "\r\r". This is Mac file line ending format. So this issue been reported. We have updated our tool to handle this special case.
>>>>>
>>>>> Good to know, thanks!
>>>>>
>>>>>>
>>>>>> With that change, now I met below error when use VS2015 tool chain. Can you help to fix it?
>>>>>>
>>>>>> Building ... g:\edk2-open-source\edk2\MdePkg\Library\PeiCoreEntryPoint\PeiCoreEntryPoint.inf [X64]
>>>>>> PeCoffLoaderEx.c
>>>>>> g:\edk2-open-source\edk2\OvmfPkg\Library\VmgExitLib\VmgExitVcHandler.c(386): warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
>>>>>> NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\cl.exe"' : return code '0x2'
>>>>
>>>> This is for the line
>>>>
>>>> Displacement *= (1 << Ext->Sib.Scale);
>>>>
>>>> from
>>>>
>>>> [edk2-devel] [PATCH v9 17/46]
>>>> OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
>>>>
>>>>>
>>>>> Yup, looks like that needs to be a "1ULL <<" instead of "1 <<".
>>>>> I have verified that fixes the issue.
>>>>
>>>> I disagree.
>>>>
>>>> At that point, Displacement is of type INT64, and it may well be a
>>>> negative value. We definitely want to multiply it by a signed int
>>>> (values 1, 2, 4, 8).
>>>>
>>>> I commented on this before. Please see:
>>>>
>>>> (i) my comment block (10) here -- especially comment (10c):
>>>>
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60144&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=g%2BGooY1Sv0G7ydr11Jh%2BTXxo4Wy6ZWcT5Mq9VmWddi8%3D&reserved=0
>>>>
>>>> (alternative link:
>>>> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F169e44cb-2c1c-6d9a-342a-2a1f618e3753%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=6p91db%2F6oz%2FHc65Sq4fvH%2FcPmiAfdS8MImsaznaoaXA%3D&reserved=0>)
>>>>
>>>> (ii) and my comment here:
>>>>
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60146&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=iNIBJCIlfEEsY37cdwUbH27tx5HvXVs3PZiOQfaGeLQ%3D&reserved=0
>>>>
>>>> (alternative link:
>>>> <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F139ce789-b938-c8b9-030e-c1b6c67e47ea%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cec0cb2ad96694b66d8ff08d8228b7c8e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637297329772337705&sdata=mWCAHqTOpp7B9nWUJjTRJ9VZ74iwdElRTOoNhEpFs%2Bc%3D&reserved=0>).
>>>>
>>>>
>>>> The compiler warning is well-meaning, but unnecessary. A 64-bit shift is
>>>> *NOT* intended. We want to end up with one of the signed int (aka INT32)
>>>> values 1, 2, 4 or 8. And then multiply the INT64 Displacement with that
>>>> value. For the multiplication, the INT32 value 1, 2, 4 or 8 will be
>>>> implicitly converted to INT64. That's entirely intentional.
>>>>
>>>> If we want to suppress the warning, while keeping the logic intact, we
>>>> should employ an explicit cast:
>>>>
>>>> Displacement *= (INT64)(1 << Ext->Sib.Scale);
>>>
>>> Ok, that makes sense. I'll use the explicit cast.
>>>
>>>>
>>>>>
>>>>> One thing I noticed is that the 32-bit builds
>>>>> (PlatformCI_OvmfPkg_Windows_VS2019_PR, Platform_CI OVMF_IA32_NOOPT and
>>>>> Platform_CI OVMF_IA32X64_NOOPT) encounter an error:
>>>>>
>>>>> ERROR - Linker #2001 from SecMain.lib(SecMain.obj) : unresolved external symbol __allshl
>>>>> ERROR - Linker #1120 from d:\a\1\s\Build\Ovmf3264\NOOPT_VS2019\IA32\OvmfPkg\Sec\SecMain\DEBUG\SecMain.dll : fatal 1 unresolved externals
>>>>> ERROR - Compiler #1077 from NMAKE : fatal '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x86\link.exe"' : return code '0x460'
>>>>>
>>>>> Any idea what is causing this error?
>>>>
>>>> A left-shift operator (<<) applied to a 64-bit operand is somehow
>>>> finding its way into the 32-bit SEC build.
>>>>
>>>> That is indeed wrong (for such cases, we're supposed to use LShiftU64()
>>>> from BaseLib).
>>>>
>>>> What I don't understand however is that all of the "<<" operator uses,
>>>> on 64-bit operands, should already be limited to code that is *only*
>>>> built for X64!
>>>>
>>>> For example, with this series applied, SecMain in OVMF consumes
>>>> "UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf".
>>>> And the latter consumes VmgExitLib.
>>>>
>>>> But VmgExitLib is resolved to
>>>> "UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf", in the IA32 and
>>>> IA32X64 DSC files. This Null instance contains no left-shifts.
>>>>
>>>> Therefore any << operators, applied to 64-bit operands, present in
>>>> "OvmfPkg/Library/VmgExitLib", should never be compiled for IA32 and IA32X64.
>>>>
>>>> So I don't know where the problematic "<<" comes from. It does not come
>>>> from VmgExitLib, as far as I can tell.
>>>
>>> Yes, I don't think it's coming from VmgExitLib, either.
>>>
>>> I wonder if it somehow might be coming from the MSR_SEV_ES_GHCB_REGISTER
>>> struct and the bit fields that are used within it? That code, while not
>>> executed in non-X64 builds because SEV-ES is not active, is still built
>>> and maybe the bit fields result in implicit shifts occurring, specifically
>>> in SevEsProtocolFailure()?
>>>
>>> I'll experiment with some things and see if that is the issue.
>>
>> I commented out the setting of the GhcbTerminate fields in the
>> SevEsProtocolFailure() routine of OvmfPkg/Sec/SecMain.c and the error
>> disappeared. I'll see if changing from using UINT64 to multiple UINT32
>> entries fixes the problem, but I wouldn't think that the bit fields
>> would/should cause an issue here with 32-bit builds.
>
> Changing the bit fields from UINT64 to UINT32 fixed the error and SEV-ES
> support continues to function properly. Since the architecture is little
> endian, there was no need to pad out to the full UINT64 size for the
> structs (the union takes care of that in general). The change looks like
> this:
>
> diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h b/MdePkg/Include/Register/Amd/Fam17Msr.h
> index 466a3143599c..3cbe593868d4 100644
> --- a/MdePkg/Include/Register/Amd/Fam17Msr.h
> +++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
> @@ -28,7 +28,7 @@
> **/
> typedef union {
> struct {
> - UINT64 Function:12;
> + UINT32 Function:12;
> } GhcbInfo;
>
> struct {
> @@ -39,9 +39,9 @@ typedef union {
> } GhcbProtocol;
>
> struct {
> - UINT64 Function:12;
> - UINT64 ReasonCodeSet:4;
> - UINT64 ReasonCode:8;
> + UINT32 Function:12;
> + UINT32 ReasonCodeSet:4;
> + UINT32 ReasonCode:8;
> } GhcbTerminate;
>
> VOID *Ghcb;
>
> Unless there are any concerns, I'll incorporate this change.
Right, my general disapproval of bit-fields notwithstanding, this looks
consistent with most of the bit-fields under MdePkg!
Thanks
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* bit-fields [was: PATCH v9 08/46 UefiCpuPkg: Implement library support for VMGEXIT]
2020-07-07 17:11 ` Lendacky, Thomas
2020-07-08 13:07 ` Lendacky, Thomas
@ 2020-07-08 15:24 ` Laszlo Ersek
1 sibling, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-07-08 15:24 UTC (permalink / raw)
To: Tom Lendacky, Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Gao, Liming,
Kinney, Michael D, Ni, Ray
On 07/07/20 19:11, Tom Lendacky wrote:
> I commented out the setting of the GhcbTerminate fields in the
> SevEsProtocolFailure() routine of OvmfPkg/Sec/SecMain.c and the error
> disappeared. I'll see if changing from using UINT64 to multiple UINT32
> entries fixes the problem, but I wouldn't think that the bit fields
> would/should cause an issue here with 32-bit builds.
For two examples from
"MdePkg/Include/Register/Intel/ArchitecturalMsr.h": the
- MSR_IA32_FEATURE_CONTROL_REGISTER
- MSR_IA32_EFER_REGISTER
types use UINT32 bit-field members.
--*--
I've always disliked bit-fields. Consider:
C99 "6.7.2 Type specifiers"
5 [...] for bit-fields, it is implementation-defined whether the
specifier int designates the same type as signed int or the same
type as unsigned int.
C99 "6.7.2.1 Structure and union specifiers":
4 A bit-field shall have a type that is a qualified or unqualified
version of _Bool, signed int, unsigned int, or some other
implementation-defined type.
10 An implementation may allocate any addressable storage unit large
enough to hold a bit-field. If enough space remains, a bit-field
that immediately follows another bit-field in a structure shall be
packed into adjacent bits of the same unit. If insufficient space
remains, whether a bit-field that does not fit is put into the next
unit or overlaps adjacent units is implementation-defined. The
order of allocation of bit-fields within a unit (high-order to
low-order or low-order to high-order) is implementation-defined.
The alignment of the addressable storage unit is unspecified.
The C99 *Rationale* says under "6.7.2.1. Structure and union
specifiers",
Three types of bit-fields are now defined: plain int calls for
implementation-defined signedness (as in K&R), signed int calls for
assuredly signed fields, and unsigned int calls for unsigned fields.
The old constraints on bit-fields crossing word boundaries have been
relaxed, since so many properties of bit-fields are implementation
dependent anyway.
This means that bit-fields are entirely non-portable.
--*--
The UEFI spec only says, in "Table 5. Common UEFI Data Types":
Bitfields are ordered such that bit 0 is the least significant bit.
So that removes only one variable (order of allocation of bit-fields).
Consider the following type:
typedef struct {
UINT16 Hello;
UINT16 Foo:15;
UINT32 Bar:27;
} FOOBAR;
Even considering the UEFI spec rules that structure members are
"naturally alined", plus the above order of allocation of bit-fields, we
still can't tell whether Bar starts at:
(a) bit 31,
(b) bit 32,
(c) bit 47,
(d) bit 64,
(e) bit 79.
- In case (a), the structure consists of the following units:
- UINT16 (Hello),
- UINT16 (Foo, plus one bit of Bar),
- UINT32 (all bits of Bar except the least significant one).
The implementation chooses to overlap adjacent units, for storing Bar.
Bar starts at bit 31.
- In case (b), the structure consists of the following units:
- UINT16 (Hello),
- UINT16 (Foo),
- UINT32 (Bar).
The imlementation chooses not to overlap adjacent units, for storing
Bar. Bar starts at bit 32.
- In case (c), the structure consists of the following units:
- UINT16 (Hello),
- UINT16 (padding),
- UINT32 (Foo, plus 17 low order bits of Bar),
- UINT32 (10 high order bits of Bar).
The padding is inserted because the implementation chooses UINT32 for
storing Foo, and said UINT32 has to be naturally aligned (per UEFI
spec). Furthermore, the implementation chooses to overlap adjacent
UINT32 units, for storing Bar. Bar starts at bit 47.
- In case (d), the structure consists of the following units:
- UINT16 (Hello),
- UINT16 (padding),
- UINT32 (Foo),
- UINT32 (Bar).
The padding is inserted because the implementation chooses UINT32 for
storing Foo, and said UINT32 has to be naturally aligned (per UEFI
spec). Furthermore, the implementation chooses not to overlap adjacent
UINT32 units, for storing Bar. Bar starts at bit 64.
- In case (e), the structure consists of the following units:
- UINT16 (Hello),
- UINT16[3] (padding),
- UINT64 (Foo and Bar).
The padding is inserted because the implementation chooses UINT64 for
storing Foo, and said UINT64 has to be naturally aligned (per UEFI
spec). And because 15+27=42, both Foo and Bar fit into UINT64, and so
the implementation must pack them both into that unit. Bar starts at
bit 79.
--*--
The edk2 C Coding Standards have a section on bit-fields:
https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/56_declarations_and_types#5-6-3-4-bit-fields
Some part of that section are worth quoting:
> - Bit fields may only be of type INT32, signed INT32, UINT32, or a
> typedef name defined as one of the three INT32 variants.
Unfortunately, the edk2 codebase readily violates this; the following
"grep" confirms there are many UINT64 bit-fields:
$ git grep -E 'UINT64 *[A-Za-z0-9_]+ *: *[0-9]+ *;'
> - The order of allocation of bit-fields within a storage unit is
> compiler defined.
This conflicts with the UEFI spec, as the UEFI spec does define the
order of allocation.
> - A bit-field may not extend from one storage unit into another.
Overlapping adjacent units is up to the implementation, according to the
C standard.
So, is the programmer supposed to prevent that, by using unnamed ":0"
bitfields (per C99 6.7.2.1 p11)?
Then, further CCS sections:
https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/56_declarations_and_types#5-6-3-4-1-visual-c-specific
https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/56_declarations_and_types#5-6-3-4-2-gcc-specific
make toolchain / ABI specific notes. But I think ABI quirks and versions
are not what we should be thinking about when writing C source code. :(
I'm quite unhappy that bit-fields are so widely used in edk2. We should
always use unsigned integers and bitmask macros instead. That way at
least we're honest about the accesses. The bit-field types seem to work
mainly through sheer luck. (If there are ABI assumptions, they don't
seem to be clearly documented, anyway.)
Thanks
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (7 preceding siblings ...)
2020-06-05 13:26 ` [PATCH v9 08/46] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-10 12:08 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 10/46] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
` (36 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni,
Anthony Perard, Julien Grall
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Various CpuExceptionHandlerLib libraries will updated to use the new
VmgExitLib library. To prevent any build breakage, update the OvmfPkg
DSC files that use a form of the CpuExceptionHandlerLib library to
include the VmgExitLib library.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/OvmfXen.dsc | 1 +
4 files changed, 4 insertions(+)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index d0df9cbbfb2b..7d7297aa1cd8 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -228,6 +228,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index b3ae62fee92b..c85e988372ec 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -232,6 +232,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index f7fe75ebf531..0b9189ab1e38 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -232,6 +232,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 3af0ee705407..a3ba96f7002a 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -213,6 +213,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.SEC]
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
2020-06-05 13:27 ` [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
@ 2020-06-10 12:08 ` Laszlo Ersek
2020-06-10 14:15 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-10 12:08 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni, Anthony Perard,
Julien Grall
Hi Tom,
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Various CpuExceptionHandlerLib libraries will updated to use the new
> VmgExitLib library. To prevent any build breakage, update the OvmfPkg
> DSC files that use a form of the CpuExceptionHandlerLib library to
> include the VmgExitLib library.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Julien Grall <julien@xen.org>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/OvmfPkgIa32.dsc | 1 +
> OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
> OvmfPkg/OvmfPkgX64.dsc | 1 +
> OvmfPkg/OvmfXen.dsc | 1 +
> 4 files changed, 4 insertions(+)
not a code comment, but a process comment.
I'm comparing this v9 series against v8, with git-range-diff. For the comparison, I'm using your "sev-es-v16" branch (v8 on the list) versus "sev-es-v17" (v9 on the list -- this series).
For this patch, git-range-diff tells me:
9: 557f9c473fe6 ! 9: 63aae4b9cc75 OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
@@ -11,7 +11,9 @@
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
- Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
+ Cc: Anthony Perard <anthony.perard@citrix.com>
+ Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
meaning that you updated the CC list from v8 to v9.
That's OK, in itself.
However, if I look at the actual v8 message on-list:
http://mid.mail-archive.com/2fd73ece7e6cfc0212b31646f4ea4bae6f6d51a8.1589925074.git.thomas.lendacky@amd.com
https://edk2.groups.io/g/devel/message/59865
that shows that the v8 posting *already* included the longer CC list.
The one explanation I can find for this is that you posted a different series with subject prefix "v8" than the one pushed as branch "sev-es-v16". Is that correct?
Please do not introduce any changes between the pushed and the posted versions. They must be *completely identical*.
The on-list versions are the authoritative ones (that's where the series will be applied from). We're using the pushed branches only as a convenience tool for review. But if the on-list version differs from the pushed version, how can I rely on the pushed version, for review?
Thanks
Laszlo
>
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index d0df9cbbfb2b..7d7297aa1cd8 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -228,6 +228,7 @@ [LibraryClasses]
>
> [LibraryClasses.common]
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>
> [LibraryClasses.common.SEC]
> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
> index b3ae62fee92b..c85e988372ec 100644
> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
> @@ -232,6 +232,7 @@ [LibraryClasses]
>
> [LibraryClasses.common]
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>
> [LibraryClasses.common.SEC]
> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index f7fe75ebf531..0b9189ab1e38 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -232,6 +232,7 @@ [LibraryClasses]
>
> [LibraryClasses.common]
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>
> [LibraryClasses.common.SEC]
> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
> index 3af0ee705407..a3ba96f7002a 100644
> --- a/OvmfPkg/OvmfXen.dsc
> +++ b/OvmfPkg/OvmfXen.dsc
> @@ -213,6 +213,7 @@ [LibraryClasses]
>
> [LibraryClasses.common]
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>
> [LibraryClasses.common.SEC]
> QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
2020-06-10 12:08 ` Laszlo Ersek
@ 2020-06-10 14:15 ` Lendacky, Thomas
2020-06-11 14:20 ` Laszlo Ersek
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-10 14:15 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni, Anthony Perard,
Julien Grall
On 6/10/20 7:08 AM, Laszlo Ersek wrote:
> Hi Tom,
>
> On 06/05/20 15:27, Tom Lendacky wrote:
>> 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%7Cae12d2d0f5c94ee905c708d80d3711e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273877466672474&sdata=SNfXYJYwNPKmYyWq5xNrIY7PWSbBZkLNWIQ%2B2vtJk3c%3D&reserved=0
>>
>> Various CpuExceptionHandlerLib libraries will updated to use the new
>> VmgExitLib library. To prevent any build breakage, update the OvmfPkg
>> DSC files that use a form of the CpuExceptionHandlerLib library to
>> include the VmgExitLib library.
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Cc: Anthony Perard <anthony.perard@citrix.com>
>> Cc: Julien Grall <julien@xen.org>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/OvmfPkgIa32.dsc | 1 +
>> OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
>> OvmfPkg/OvmfPkgX64.dsc | 1 +
>> OvmfPkg/OvmfXen.dsc | 1 +
>> 4 files changed, 4 insertions(+)
>
> not a code comment, but a process comment.
>
> I'm comparing this v9 series against v8, with git-range-diff. For the comparison, I'm using your "sev-es-v16" branch (v8 on the list) versus "sev-es-v17" (v9 on the list -- this series).
>
> For this patch, git-range-diff tells me:
>
> 9: 557f9c473fe6 ! 9: 63aae4b9cc75 OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
> @@ -11,7 +11,9 @@
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> - Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> + Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> + Cc: Anthony Perard <anthony.perard@citrix.com>
> + Cc: Julien Grall <julien@xen.org>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>
> meaning that you updated the CC list from v8 to v9.
>
> That's OK, in itself.
>
> However, if I look at the actual v8 message on-list:
>
> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F2fd73ece7e6cfc0212b31646f4ea4bae6f6d51a8.1589925074.git.thomas.lendacky%40amd.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cae12d2d0f5c94ee905c708d80d3711e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273877466672474&sdata=qb6rUyivqq0kPKYUtGeTgcvlNUe8B8h7vKmeOZLvjK4%3D&reserved=0
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F59865&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cae12d2d0f5c94ee905c708d80d3711e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273877466672474&sdata=mmZt3%2Fdc37OKtNaDoYGysZTut35BfKih0u3w2FrcFeI%3D&reserved=0
>
> that shows that the v8 posting *already* included the longer CC list.
>
> The one explanation I can find for this is that you posted a different series with subject prefix "v8" than the one pushed as branch "sev-es-v16". Is that correct?
Looks like I made some final changes to the CC lists after re-running the
get maintainers script and forgot to push that to github. Also missing
from github is the final patch with the change to the maintainers list.
Code-wise, though, everything is identical.
>
> Please do not introduce any changes between the pushed and the posted versions. They must be *completely identical*.
A miss on my end to do the final push to github before sending out the
patches. I can do a force push for the sev-es-v16 branch to match what was
submitted if that will help you (of course you'll have to reset your
branch if I do that), your call.
Thanks,
Tom
>
> The on-list versions are the authoritative ones (that's where the series will be applied from). We're using the pushed branches only as a convenience tool for review. But if the on-list version differs from the pushed version, how can I rely on the pushed version, for review?>
> Thanks
> Laszlo
>
>
>
>>
>> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
>> index d0df9cbbfb2b..7d7297aa1cd8 100644
>> --- a/OvmfPkg/OvmfPkgIa32.dsc
>> +++ b/OvmfPkg/OvmfPkgIa32.dsc
>> @@ -228,6 +228,7 @@ [LibraryClasses]
>>
>> [LibraryClasses.common]
>> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>
>> [LibraryClasses.common.SEC]
>> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
>> diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
>> index b3ae62fee92b..c85e988372ec 100644
>> --- a/OvmfPkg/OvmfPkgIa32X64.dsc
>> +++ b/OvmfPkg/OvmfPkgIa32X64.dsc
>> @@ -232,6 +232,7 @@ [LibraryClasses]
>>
>> [LibraryClasses.common]
>> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>
>> [LibraryClasses.common.SEC]
>> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>> index f7fe75ebf531..0b9189ab1e38 100644
>> --- a/OvmfPkg/OvmfPkgX64.dsc
>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>> @@ -232,6 +232,7 @@ [LibraryClasses]
>>
>> [LibraryClasses.common]
>> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>
>> [LibraryClasses.common.SEC]
>> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
>> diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
>> index 3af0ee705407..a3ba96f7002a 100644
>> --- a/OvmfPkg/OvmfXen.dsc
>> +++ b/OvmfPkg/OvmfXen.dsc
>> @@ -213,6 +213,7 @@ [LibraryClasses]
>>
>> [LibraryClasses.common]
>> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>> + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>>
>> [LibraryClasses.common.SEC]
>> QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
2020-06-10 14:15 ` Lendacky, Thomas
@ 2020-06-11 14:20 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 14:20 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni, Anthony Perard,
Julien Grall
On 06/10/20 16:15, Tom Lendacky wrote:
> On 6/10/20 7:08 AM, Laszlo Ersek wrote:
>> Hi Tom,
>>
>> On 06/05/20 15:27, Tom Lendacky wrote:
>>> 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%7Cae12d2d0f5c94ee905c708d80d3711e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273877466672474&sdata=SNfXYJYwNPKmYyWq5xNrIY7PWSbBZkLNWIQ%2B2vtJk3c%3D&reserved=0
>>>
>>> Various CpuExceptionHandlerLib libraries will updated to use the new
>>> VmgExitLib library. To prevent any build breakage, update the OvmfPkg
>>> DSC files that use a form of the CpuExceptionHandlerLib library to
>>> include the VmgExitLib library.
>>>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>>> Cc: Anthony Perard <anthony.perard@citrix.com>
>>> Cc: Julien Grall <julien@xen.org>
>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>> ---
>>> OvmfPkg/OvmfPkgIa32.dsc | 1 +
>>> OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
>>> OvmfPkg/OvmfPkgX64.dsc | 1 +
>>> OvmfPkg/OvmfXen.dsc | 1 +
>>> 4 files changed, 4 insertions(+)
>>
>> not a code comment, but a process comment.
>>
>> I'm comparing this v9 series against v8, with git-range-diff. For the comparison, I'm using your "sev-es-v16" branch (v8 on the list) versus "sev-es-v17" (v9 on the list -- this series).
>>
>> For this patch, git-range-diff tells me:
>>
>> 9: 557f9c473fe6 ! 9: 63aae4b9cc75 OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>> @@ -11,7 +11,9 @@
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> - Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> + Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> + Cc: Anthony Perard <anthony.perard@citrix.com>
>> + Cc: Julien Grall <julien@xen.org>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>
>> meaning that you updated the CC list from v8 to v9.
>>
>> That's OK, in itself.
>>
>> However, if I look at the actual v8 message on-list:
>>
>> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F2fd73ece7e6cfc0212b31646f4ea4bae6f6d51a8.1589925074.git.thomas.lendacky%40amd.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cae12d2d0f5c94ee905c708d80d3711e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273877466672474&sdata=qb6rUyivqq0kPKYUtGeTgcvlNUe8B8h7vKmeOZLvjK4%3D&reserved=0
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F59865&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cae12d2d0f5c94ee905c708d80d3711e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273877466672474&sdata=mmZt3%2Fdc37OKtNaDoYGysZTut35BfKih0u3w2FrcFeI%3D&reserved=0
>>
>> that shows that the v8 posting *already* included the longer CC list.
>>
>> The one explanation I can find for this is that you posted a different series with subject prefix "v8" than the one pushed as branch "sev-es-v16". Is that correct?
>
> Looks like I made some final changes to the CC lists after re-running the
> get maintainers script and forgot to push that to github. Also missing
> from github is the final patch with the change to the maintainers list.
>
> Code-wise, though, everything is identical.
Good to know, thanks!
>
>>
>> Please do not introduce any changes between the pushed and the posted versions. They must be *completely identical*.
>
> A miss on my end to do the final push to github before sending out the
> patches. I can do a force push for the sev-es-v16 branch to match what was
> submitted if that will help you (of course you'll have to reset your
> branch if I do that), your call.
Since the branch reference has been posted publicly, I would not
recommend a force-push. I'm of the opinion that it's fine to force-push
a branch multiple times in preparation for posting the series, but once
it's been posted, the branch becomes (conceptually) read-only.
(Plus, I've reached the end of the v9 series in the review.)
Thanks!
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 10/46] UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (8 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 09/46] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 11/46] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
` (35 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni, Maurice Ma,
Guo Dong, Benjamin You
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Various CpuExceptionHandlerLib libraries will updated to use the new
VmgExitLib library. To prevent any build breakage, update the
UefiPayloadPkg DSC files that use a form of the CpuExceptionHandlerLib
library to include the VmgExitLib library.
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Reviewed-by: Guo Dong <guo.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 ++
UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 ++
2 files changed, 4 insertions(+)
diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
index d52945442e0e..810de274652c 100644
--- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
@@ -233,6 +233,7 @@ [LibraryClasses.common.DXE_CORE]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -245,6 +246,7 @@ [LibraryClasses.common.DXE_DRIVER]
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
index 0736cd995476..adb754b28baa 100644
--- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
@@ -234,6 +234,7 @@ [LibraryClasses.common.DXE_CORE]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -246,6 +247,7 @@ [LibraryClasses.common.DXE_DRIVER]
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 11/46] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (9 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 10/46] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-12 1:02 ` Dong, Eric
2020-06-05 13:27 ` [PATCH v9 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF Lendacky, Thomas
` (34 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Add base support to handle #VC exceptions. Update the common exception
handlers to invoke the VmgExitHandleVc () function of the VmgExitLib
library when a #VC is encountered. A non-zero return code will propagate
to the targeted exception handler.
Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
To avoid exception recursion, a #VC exception will not try to read and
push the actual debug registers into the EFI_SYSTEM_CONTEXT_X64 struct
and instead push zeroes. The #VC exception handler does not make use of
the debug registers from the saved context and the exception processing
exit code does not attempt to restore the debug register values.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf | 1 +
UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf | 1 +
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf | 1 +
UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf | 1 +
UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf | 1 +
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 10 +++++++++-
UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c | 20 +++++++++++++++++++-
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c | 19 +++++++++++++++++++
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm | 17 +++++++++++++++++
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm | 17 +++++++++++++++++
10 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
index 61e2ec30b089..07b34c92a892 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -57,3 +57,4 @@ [LibraryClasses]
PeCoffGetEntryPointLib
MemoryAllocationLib
DebugLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
index 093374944df6..feae7b3e06de 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
@@ -52,6 +52,7 @@ [LibraryClasses]
HobLib
MemoryAllocationLib
SynchronizationLib
+ VmgExitLib
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard # CONSUMES
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
index 6d25cafe2ca3..967cb61ba6d9 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -48,3 +48,4 @@ [LibraryClasses]
PrintLib
LocalApicLib
PeCoffGetEntryPointLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
index 2ffbbccc302f..4cdb11c04ea0 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
@@ -51,4 +51,5 @@ [LibraryClasses]
LocalApicLib
PeCoffGetEntryPointLib
DebugLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf
index 7e21beaab6f2..743c2aa76684 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHandlerLib.inf
@@ -53,3 +53,4 @@ [LibraryClasses]
PrintLib
LocalApicLib
PeCoffGetEntryPointLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 8adbd43fefb4..c9003b10e552 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -14,7 +14,7 @@
//
// 1 means an error code will be pushed, otherwise 0
//
-CONST UINT32 mErrorCodeFlag = 0x00227d00;
+CONST UINT32 mErrorCodeFlag = 0x20227d00;
//
// Define the maximum message length
@@ -45,6 +45,14 @@ CONST CHAR8 *mExceptionNameStr[] = {
"#XM - SIMD floating-point",
"#VE - Virtualization",
"#CP - Control Protection"
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "#VC - VMM Communication",
};
#define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) / sizeof (CHAR8 *))
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
index 6a2670d55918..892d349d4b37 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
@@ -6,8 +6,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "CpuExceptionCommon.h"
#include <Library/DebugLib.h>
+#include <Library/VmgExitLib.h>
+#include "CpuExceptionCommon.h"
/**
Internal worker function for common exception handler.
@@ -27,6 +28,23 @@ CommonExceptionHandlerWorker (
RESERVED_VECTORS_DATA *ReservedVectors;
EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;
+ if (ExceptionType == VC_EXCEPTION) {
+ EFI_STATUS Status;
+ //
+ // #VC needs to be handled immediately upon enabling exception handling
+ // and therefore can't use the RegisterCpuInterruptHandler() interface.
+ //
+ // Handle the #VC:
+ // On EFI_SUCCESS - Exception has been handled, return
+ // On other - ExceptionType contains (possibly new) exception
+ // value
+ //
+ Status = VmgExitHandleVc (&ExceptionType, SystemContext);
+ if (!EFI_ERROR (Status)) {
+ return;
+ }
+ }
+
ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);
ReservedVectors = ExceptionHandlerData->ReservedVectors;
ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler;
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index 20148db74cf8..52c6886f0372 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
+#include <Library/VmgExitLib.h>
#include "CpuExceptionCommon.h"
CONST UINTN mDoFarReturnFlag = 0;
@@ -24,6 +25,24 @@ CommonExceptionHandler (
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
+ if (ExceptionType == VC_EXCEPTION) {
+ EFI_STATUS Status;
+ //
+ // #VC needs to be handled immediately upon enabling exception handling
+ // and therefore can't use the RegisterCpuInterruptHandler() interface
+ // (which isn't supported under Sec and Pei anyway).
+ //
+ // Handle the #VC:
+ // On EFI_SUCCESS - Exception has been handled, return
+ // On other - ExceptionType contains (possibly new) exception
+ // value
+ //
+ Status = VmgExitHandleVc (&ExceptionType, SystemContext);
+ if (!EFI_ERROR (Status)) {
+ return;
+ }
+ }
+
//
// Initialize the serial port before dumping.
//
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
index 3814f9de3703..2a5545ecfd41 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
@@ -18,6 +18,8 @@
; CommonExceptionHandler()
;
+%define VC_EXCEPTION 29
+
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
extern ASM_PFX(CommonExceptionHandler)
@@ -224,6 +226,9 @@ HasErrorCode:
push rax
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ cmp qword [rbp + 8], VC_EXCEPTION
+ je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
+
mov rax, dr7
push rax
mov rax, dr6
@@ -236,7 +241,19 @@ HasErrorCode:
push rax
mov rax, dr0
push rax
+ jmp DrFinish
+VcDebugRegs:
+;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion
+ xor rax, rax
+ push rax
+ push rax
+ push rax
+ push rax
+ push rax
+ push rax
+
+DrFinish:
;; FX_SAVE_STATE_X64 FxSaveState;
sub rsp, 512
mov rdi, rsp
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
index 19198f273137..26cae56cc5cf 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm.nasm
@@ -18,6 +18,8 @@
; CommonExceptionHandler()
;
+%define VC_EXCEPTION 29
+
extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
extern ASM_PFX(CommonExceptionHandler)
@@ -225,6 +227,9 @@ HasErrorCode:
push rax
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ cmp qword [rbp + 8], VC_EXCEPTION
+ je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
+
mov rax, dr7
push rax
mov rax, dr6
@@ -237,7 +242,19 @@ HasErrorCode:
push rax
mov rax, dr0
push rax
+ jmp DrFinish
+VcDebugRegs:
+;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion
+ xor rax, rax
+ push rax
+ push rax
+ push rax
+ push rax
+ push rax
+ push rax
+
+DrFinish:
;; FX_SAVE_STATE_X64 FxSaveState;
sub rsp, 512
mov rdi, rsp
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 11/46] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
2020-06-05 13:27 ` [PATCH v9 11/46] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
@ 2020-06-12 1:02 ` Dong, Eric
0 siblings, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-12 1:02 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Reviewed-by: Eric Dong <eric.dong@intel.com>
Thanks,
Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:27 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 11/46] UefiCpuPkg/CpuExceptionHandler: Add base
> support for the #VC exception
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Add base support to handle #VC exceptions. Update the common exception
> handlers to invoke the VmgExitHandleVc () function of the VmgExitLib
> library when a #VC is encountered. A non-zero return code will propagate
> to the targeted exception handler.
>
> Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
> To avoid exception recursion, a #VC exception will not try to read and
> push the actual debug registers into the EFI_SYSTEM_CONTEXT_X64 struct
> and instead push zeroes. The #VC exception handler does not make use of
> the debug registers from the saved context and the exception processing
> exit code does not attempt to restore the debug register values.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.in
> f | 1 +
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
> | 1 +
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib
> .inf | 1 +
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.i
> nf | 1 +
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuExceptionHa
> ndlerLib.inf | 1 +
> UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
> | 10 +++++++++-
> UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
> | 20 +++++++++++++++++++-
> UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> | 19 +++++++++++++++++++
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nas
> m | 17 +++++++++++++++++
>
> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerA
> sm.nasm | 17 +++++++++++++++++
> 10 files changed, 86 insertions(+), 2 deletions(-)
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.
> inf
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib
> .inf
> index 61e2ec30b089..07b34c92a892 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.
> inf
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib
> .inf
> @@ -57,3 +57,4 @@ [LibraryClasses]
> PeCoffGetEntryPointLib
>
> MemoryAllocationLib
>
> DebugLib
>
> + VmgExitLib
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.i
> nf
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.i
> nf
> index 093374944df6..feae7b3e06de 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.i
> nf
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.i
> nf
> @@ -52,6 +52,7 @@ [LibraryClasses]
> HobLib
>
> MemoryAllocationLib
>
> SynchronizationLib
>
> + VmgExitLib
>
>
>
> [Pcd]
>
> gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard # CONSUMES
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandler
> Lib.inf
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandler
> Lib.inf
> index 6d25cafe2ca3..967cb61ba6d9 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandler
> Lib.inf
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandler
> Lib.inf
> @@ -48,3 +48,4 @@ [LibraryClasses]
> PrintLib
>
> LocalApicLib
>
> PeCoffGetEntryPointLib
>
> + VmgExitLib
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLi
> b.inf
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLi
> b.inf
> index 2ffbbccc302f..4cdb11c04ea0 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLi
> b.inf
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLi
> b.inf
> @@ -51,4 +51,5 @@ [LibraryClasses]
> LocalApicLib
>
> PeCoffGetEntryPointLib
>
> DebugLib
>
> + VmgExitLib
>
>
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuException
> HandlerLib.inf
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuException
> HandlerLib.inf
> index 7e21beaab6f2..743c2aa76684 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuException
> HandlerLib.inf
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Xcode5SecPeiCpuException
> HandlerLib.inf
> @@ -53,3 +53,4 @@ [LibraryClasses]
> PrintLib
>
> LocalApicLib
>
> PeCoffGetEntryPointLib
>
> + VmgExitLib
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
> index 8adbd43fefb4..c9003b10e552 100644
> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
> @@ -14,7 +14,7 @@
> //
>
> // 1 means an error code will be pushed, otherwise 0
>
> //
>
> -CONST UINT32 mErrorCodeFlag = 0x00227d00;
>
> +CONST UINT32 mErrorCodeFlag = 0x20227d00;
>
>
>
> //
>
> // Define the maximum message length
>
> @@ -45,6 +45,14 @@ CONST CHAR8 *mExceptionNameStr[] = {
> "#XM - SIMD floating-point",
>
> "#VE - Virtualization",
>
> "#CP - Control Protection"
>
> + "Reserved",
>
> + "Reserved",
>
> + "Reserved",
>
> + "Reserved",
>
> + "Reserved",
>
> + "Reserved",
>
> + "Reserved",
>
> + "#VC - VMM Communication",
>
> };
>
>
>
> #define EXCEPTION_KNOWN_NAME_NUM (sizeof (mExceptionNameStr) /
> sizeof (CHAR8 *))
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
> index 6a2670d55918..892d349d4b37 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
> @@ -6,8 +6,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>
>
> **/
>
>
>
> -#include "CpuExceptionCommon.h"
>
> #include <Library/DebugLib.h>
>
> +#include <Library/VmgExitLib.h>
>
> +#include "CpuExceptionCommon.h"
>
>
>
> /**
>
> Internal worker function for common exception handler.
>
> @@ -27,6 +28,23 @@ CommonExceptionHandlerWorker (
> RESERVED_VECTORS_DATA *ReservedVectors;
>
> EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;
>
>
>
> + if (ExceptionType == VC_EXCEPTION) {
>
> + EFI_STATUS Status;
>
> + //
>
> + // #VC needs to be handled immediately upon enabling exception
> handling
>
> + // and therefore can't use the RegisterCpuInterruptHandler() interface.
>
> + //
>
> + // Handle the #VC:
>
> + // On EFI_SUCCESS - Exception has been handled, return
>
> + // On other - ExceptionType contains (possibly new) exception
>
> + // value
>
> + //
>
> + Status = VmgExitHandleVc (&ExceptionType, SystemContext);
>
> + if (!EFI_ERROR (Status)) {
>
> + return;
>
> + }
>
> + }
>
> +
>
> ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN)
> (SystemContext.SystemContextIa32);
>
> ReservedVectors = ExceptionHandlerData->ReservedVectors;
>
> ExternalInterruptHandler = ExceptionHandlerData-
> >ExternalInterruptHandler;
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> index 20148db74cf8..52c6886f0372 100644
> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> @@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> **/
>
>
>
> #include <PiPei.h>
>
> +#include <Library/VmgExitLib.h>
>
> #include "CpuExceptionCommon.h"
>
>
>
> CONST UINTN mDoFarReturnFlag = 0;
>
> @@ -24,6 +25,24 @@ CommonExceptionHandler (
> IN EFI_SYSTEM_CONTEXT SystemContext
>
> )
>
> {
>
> + if (ExceptionType == VC_EXCEPTION) {
>
> + EFI_STATUS Status;
>
> + //
>
> + // #VC needs to be handled immediately upon enabling exception
> handling
>
> + // and therefore can't use the RegisterCpuInterruptHandler() interface
>
> + // (which isn't supported under Sec and Pei anyway).
>
> + //
>
> + // Handle the #VC:
>
> + // On EFI_SUCCESS - Exception has been handled, return
>
> + // On other - ExceptionType contains (possibly new) exception
>
> + // value
>
> + //
>
> + Status = VmgExitHandleVc (&ExceptionType, SystemContext);
>
> + if (!EFI_ERROR (Status)) {
>
> + return;
>
> + }
>
> + }
>
> +
>
> //
>
> // Initialize the serial port before dumping.
>
> //
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.n
> asm
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.n
> asm
> index 3814f9de3703..2a5545ecfd41 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.n
> asm
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.n
> asm
> @@ -18,6 +18,8 @@
> ; CommonExceptionHandler()
>
> ;
>
>
>
> +%define VC_EXCEPTION 29
>
> +
>
> extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
>
> extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
>
> extern ASM_PFX(CommonExceptionHandler)
>
> @@ -224,6 +226,9 @@ HasErrorCode:
> push rax
>
>
>
> ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
>
> + cmp qword [rbp + 8], VC_EXCEPTION
>
> + je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
>
> +
>
> mov rax, dr7
>
> push rax
>
> mov rax, dr6
>
> @@ -236,7 +241,19 @@ HasErrorCode:
> push rax
>
> mov rax, dr0
>
> push rax
>
> + jmp DrFinish
>
>
>
> +VcDebugRegs:
>
> +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception
> recursion
>
> + xor rax, rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> +
>
> +DrFinish:
>
> ;; FX_SAVE_STATE_X64 FxSaveState;
>
> sub rsp, 512
>
> mov rdi, rsp
>
> diff --git
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandle
> rAsm.nasm
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandle
> rAsm.nasm
> index 19198f273137..26cae56cc5cf 100644
> ---
> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandle
> rAsm.nasm
> +++
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandle
> rAsm.nasm
> @@ -18,6 +18,8 @@
> ; CommonExceptionHandler()
>
> ;
>
>
>
> +%define VC_EXCEPTION 29
>
> +
>
> extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions
>
> extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag
>
> extern ASM_PFX(CommonExceptionHandler)
>
> @@ -225,6 +227,9 @@ HasErrorCode:
> push rax
>
>
>
> ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
>
> + cmp qword [rbp + 8], VC_EXCEPTION
>
> + je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored
>
> +
>
> mov rax, dr7
>
> push rax
>
> mov rax, dr6
>
> @@ -237,7 +242,19 @@ HasErrorCode:
> push rax
>
> mov rax, dr0
>
> push rax
>
> + jmp DrFinish
>
>
>
> +VcDebugRegs:
>
> +;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception
> recursion
>
> + xor rax, rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> + push rax
>
> +
>
> +DrFinish:
>
> ;; FX_SAVE_STATE_X64 FxSaveState;
>
> sub rsp, 512
>
> mov rdi, rsp
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (10 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 11/46] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-10 12:26 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 13/46] OvmfPkg/VmgExitLib: Add support for IOIO_PROT NAE events Lendacky, Thomas
` (33 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
The base VmgExitLib library provides a default limited interface. As it
does not provide full support, create an OVMF version of this library to
begin the process of providing full support of SEV-ES within OVMF.
SEV-ES support is only provided for X64 builds, so only OvmfPkgX64.dsc is
updated to make use of the OvmfPkg version of the library.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/OvmfPkgX64.dsc | 2 +-
OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 36 +++++
OvmfPkg/Library/VmgExitLib/VmgExitLib.c | 159 ++++++++++++++++++++
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 81 ++++++++++
4 files changed, 277 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 0b9189ab1e38..b5f3859420d0 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -232,7 +232,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
- VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+ VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
new file mode 100644
index 000000000000..8acdee2349b4
--- /dev/null
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
@@ -0,0 +1,36 @@
+## @file
+# VMGEXIT Support Library.
+#
+# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = VmgExitLib
+ FILE_GUID = 0e923c25-13cd-430b-8714-ffe85652a97b
+ 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 = X64
+#
+
+[Sources.common]
+ VmgExitLib.c
+ VmgExitVcHandler.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
new file mode 100644
index 000000000000..0ca164a33eb4
--- /dev/null
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
@@ -0,0 +1,159 @@
+/** @file
+ VMGEXIT Support Library.
+
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/VmgExitLib.h>
+#include <Register/Amd/Msr.h>
+
+/**
+ 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
+
+ @return 0 VMGEXIT succeeded.
+ @return 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 GpEvent;
+
+ GpEvent.Uint64 = 0;
+ GpEvent.Elements.Vector = GP_EXCEPTION;
+ GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
+ GpEvent.Elements.Valid = 1;
+
+ Status = GpEvent.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.
+
+ @return 0 VMGEXIT succeeded.
+ @return Others VMGEXIT processing did not succeed. Exception
+ event 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
+ )
+{
+}
+
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
new file mode 100644
index 000000000000..b6a955ed8088
--- /dev/null
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -0,0 +1,81 @@
+/** @file
+ X64 #VC Exception Handler functon.
+
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/VmgExitLib.h>
+#include <Register/Amd/Msr.h>
+
+/**
+ Handle a #VC exception.
+
+ Performs the necessary processing to handle a #VC exception.
+
+ @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
+ as value to use on error.
+ @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
+
+ @retval EFI_SUCCESS Exception handled
+ @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
+ propagate provided
+ @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
+ propagate provided
+
+**/
+EFI_STATUS
+EFIAPI
+VmgExitHandleVc (
+ IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ EFI_SYSTEM_CONTEXT_X64 *Regs;
+ GHCB *Ghcb;
+ UINT64 ExitCode, Status;
+ EFI_STATUS VcRet;
+
+ VcRet = EFI_SUCCESS;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ ASSERT (Msr.GhcbInfo.Function == 0);
+ ASSERT (Msr.Ghcb != 0);
+
+ Regs = SystemContext.SystemContextX64;
+ Ghcb = Msr.Ghcb;
+
+ VmgInit (Ghcb);
+
+ ExitCode = Regs->ExceptionData;
+ switch (ExitCode) {
+ default:
+ Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
+ if (Status == 0) {
+ Regs->ExceptionData = 0;
+ *ExceptionType = GP_EXCEPTION;
+ } else {
+ GHCB_EVENT_INJECTION Event;
+
+ Event.Uint64 = Status;
+ if (Event.Elements.ErrorCodeValid != 0) {
+ Regs->ExceptionData = Event.Elements.ErrorCode;
+ } else {
+ Regs->ExceptionData = 0;
+ }
+
+ *ExceptionType = Event.Elements.Vector;
+ }
+
+ VcRet = EFI_PROTOCOL_ERROR;
+ }
+
+ VmgDone (Ghcb);
+
+ return VcRet;
+}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF
2020-06-05 13:27 ` [PATCH v9 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF Lendacky, Thomas
@ 2020-06-10 12:26 ` Laszlo Ersek
2020-06-10 14:54 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-10 12:26 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
Hi Tom,
On 06/05/20 15:27, Tom Lendacky wrote:
> The base VmgExitLib library provides a default limited interface. As it
> does not provide full support, create an OVMF version of this library to
> begin the process of providing full support of SEV-ES within OVMF.
>
> SEV-ES support is only provided for X64 builds, so only OvmfPkgX64.dsc is
> updated to make use of the OvmfPkg version of the library.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/OvmfPkgX64.dsc | 2 +-
> OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 36 +++++
> OvmfPkg/Library/VmgExitLib/VmgExitLib.c | 159 ++++++++++++++++++++
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 81 ++++++++++
> 4 files changed, 277 insertions(+), 1 deletion(-)
>
> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
> index 0b9189ab1e38..b5f3859420d0 100644
> --- a/OvmfPkg/OvmfPkgX64.dsc
> +++ b/OvmfPkg/OvmfPkgX64.dsc
> @@ -232,7 +232,7 @@ [LibraryClasses]
>
> [LibraryClasses.common]
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> - VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> + VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>
> [LibraryClasses.common.SEC]
> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
> new file mode 100644
> index 000000000000..8acdee2349b4
> --- /dev/null
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# VMGEXIT Support Library.
> +#
> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = VmgExitLib
> + FILE_GUID = 0e923c25-13cd-430b-8714-ffe85652a97b
> + 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 = X64
> +#
> +
> +[Sources.common]
> + VmgExitLib.c
> + VmgExitVcHandler.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + BaseMemoryLib
> +
(1) Please keep the individual sections sorted alphabetically.
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
> new file mode 100644
> index 000000000000..0ca164a33eb4
> --- /dev/null
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
> @@ -0,0 +1,159 @@
> +/** @file
> + VMGEXIT Support Library.
> +
> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/VmgExitLib.h>
> +#include <Register/Amd/Msr.h>
> +
> +/**
> + 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
> +
> + @return 0 VMGEXIT succeeded.
> + @return Others VMGEXIT processing did not succeed. Exception number to
> + be propagated.
(2) You misunderstood my @return / @retval explanation from v8:
http://mid.mail-archive.com/23c7dfb3-56ac-b080-2736-687cd11d51a0@redhat.com
https://edk2.groups.io/g/devel/message/60047
We have two formats.
(2a) "@return Natural language explanation"
In this format, there is *NO CONSTANT* in the documentation. The comment
only explains in natural language what the function returns. In the
message linked above, I brought the example:
@return IOIO event information values.
That was *not* a typo.
(2b) The other format is "@retval CONSTANT Natural language
explanation".
In this case, the exact return value is given, and then explained.
In the v8 review, I mentioned that "@retval Others" is wrong, even
though it is used in several places in the edk2 tree. That's because
"Others" is not a constant. The right way to put "@retval Others" is to
replace it with *just* "@return". In other words, *drop* the "Others"
non-constant, replace "@retval" with "@return", and reformulate the
natural language text.
In the v8 review, I also mentioned that "@retval Natural language
explanation" is also wrong, because it's either missing a constant, or
it should use "@return".
Unfortunately, in response, you seem to have replaced
@retval 0
@retval Others
with
@return 0
@return Others
(i.e., just replaced "@retval" with "@return"). And that update is
wrong, on *both* lines:
- "@retval 0" was correct. It should not have been updated.
- "@retval Others" was indeed wrong, but "@return Others" is *also*
wrong. It should be just "@return", not "@return Others".
Specifically, the right comment would be:
@retval 0 VMGEXIT succeeded.
@return Exception number to be propagated. VMGEXIT processing did
not succeed.
If you read it aloud, it will make sense.
Anyway, I'm exhausted. We can address this in a follow-up series, if we
want to. Keep the ACK, and no v10 is needed just for these comments.
Thanks
Laszlo
> +
> +**/
> +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 GpEvent;
> +
> + GpEvent.Uint64 = 0;
> + GpEvent.Elements.Vector = GP_EXCEPTION;
> + GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
> + GpEvent.Elements.Valid = 1;
> +
> + Status = GpEvent.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.
> +
> + @return 0 VMGEXIT succeeded.
> + @return Others VMGEXIT processing did not succeed. Exception
> + event 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
> + )
> +{
> +}
> +
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> new file mode 100644
> index 000000000000..b6a955ed8088
> --- /dev/null
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> @@ -0,0 +1,81 @@
> +/** @file
> + X64 #VC Exception Handler functon.
> +
> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/VmgExitLib.h>
> +#include <Register/Amd/Msr.h>
> +
> +/**
> + Handle a #VC exception.
> +
> + Performs the necessary processing to handle a #VC exception.
> +
> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
> + as value to use on error.
> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
> +
> + @retval EFI_SUCCESS Exception handled
> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
> + propagate provided
> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
> + propagate provided
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VmgExitHandleVc (
> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
> + )
> +{
> + MSR_SEV_ES_GHCB_REGISTER Msr;
> + EFI_SYSTEM_CONTEXT_X64 *Regs;
> + GHCB *Ghcb;
> + UINT64 ExitCode, Status;
> + EFI_STATUS VcRet;
> +
> + VcRet = EFI_SUCCESS;
> +
> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
> + ASSERT (Msr.GhcbInfo.Function == 0);
> + ASSERT (Msr.Ghcb != 0);
> +
> + Regs = SystemContext.SystemContextX64;
> + Ghcb = Msr.Ghcb;
> +
> + VmgInit (Ghcb);
> +
> + ExitCode = Regs->ExceptionData;
> + switch (ExitCode) {
> + default:
> + Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
> + if (Status == 0) {
> + Regs->ExceptionData = 0;
> + *ExceptionType = GP_EXCEPTION;
> + } else {
> + GHCB_EVENT_INJECTION Event;
> +
> + Event.Uint64 = Status;
> + if (Event.Elements.ErrorCodeValid != 0) {
> + Regs->ExceptionData = Event.Elements.ErrorCode;
> + } else {
> + Regs->ExceptionData = 0;
> + }
> +
> + *ExceptionType = Event.Elements.Vector;
> + }
> +
> + VcRet = EFI_PROTOCOL_ERROR;
> + }
> +
> + VmgDone (Ghcb);
> +
> + return VcRet;
> +}
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF
2020-06-10 12:26 ` Laszlo Ersek
@ 2020-06-10 14:54 ` Lendacky, Thomas
0 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-10 14:54 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 6/10/20 7:26 AM, Laszlo Ersek wrote:
> Hi Tom,
>
> On 06/05/20 15:27, Tom Lendacky wrote:
>> The base VmgExitLib library provides a default limited interface. As it
>> does not provide full support, create an OVMF version of this library to
>> begin the process of providing full support of SEV-ES within OVMF.
>>
>> SEV-ES support is only provided for X64 builds, so only OvmfPkgX64.dsc is
>> updated to make use of the OvmfPkg version of the library.
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Acked-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/OvmfPkgX64.dsc | 2 +-
>> OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 36 +++++
>> OvmfPkg/Library/VmgExitLib/VmgExitLib.c | 159 ++++++++++++++++++++
>> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 81 ++++++++++
>> 4 files changed, 277 insertions(+), 1 deletion(-)
>>
>> diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
>> index 0b9189ab1e38..b5f3859420d0 100644
>> --- a/OvmfPkg/OvmfPkgX64.dsc
>> +++ b/OvmfPkg/OvmfPkgX64.dsc
>> @@ -232,7 +232,7 @@ [LibraryClasses]
>>
>> [LibraryClasses.common]
>> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>> - VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
>> + VmgExitLib|OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>>
>> [LibraryClasses.common.SEC]
>> TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>> new file mode 100644
>> index 000000000000..8acdee2349b4
>> --- /dev/null
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf
>> @@ -0,0 +1,36 @@
>> +## @file
>> +# VMGEXIT Support Library.
>> +#
>> +# Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> + INF_VERSION = 0x00010005
>> + BASE_NAME = VmgExitLib
>> + FILE_GUID = 0e923c25-13cd-430b-8714-ffe85652a97b
>> + 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 = X64
>> +#
>> +
>> +[Sources.common]
>> + VmgExitLib.c
>> + VmgExitVcHandler.c
>> +
>> +[Packages]
>> + MdePkg/MdePkg.dec
>> + UefiCpuPkg/UefiCpuPkg.dec
>> + OvmfPkg/OvmfPkg.dec
>> +
>> +[LibraryClasses]
>> + BaseLib
>> + DebugLib
>> + BaseMemoryLib
>> +
>
> (1) Please keep the individual sections sorted alphabetically.
Will do.
>
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
>> new file mode 100644
>> index 000000000000..0ca164a33eb4
>> --- /dev/null
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
>> @@ -0,0 +1,159 @@
>> +/** @file
>> + VMGEXIT Support Library.
>> +
>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Base.h>
>> +#include <Uefi.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/VmgExitLib.h>
>> +#include <Register/Amd/Msr.h>
>> +
>> +/**
>> + 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
>> +
>> + @return 0 VMGEXIT succeeded.
>> + @return Others VMGEXIT processing did not succeed. Exception number to
>> + be propagated.
>
> (2) You misunderstood my @return / @retval explanation from v8:
>
> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F23c7dfb3-56ac-b080-2736-687cd11d51a0%40redhat.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7C23a76c28475f4b34b57208d80d39989b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273888322294989&sdata=bgpq7w3kRE4ZVgnu9vgSDxvbvrHmBUio3urYWP%2B5qWE%3D&reserved=0
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60047&data=02%7C01%7Cthomas.lendacky%40amd.com%7C23a76c28475f4b34b57208d80d39989b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637273888322294989&sdata=i7lzz2cYm3bdyC06bLBqwOguzMi%2BPHSeJV%2BU%2BzDqSOM%3D&reserved=0
>
> We have two formats.
>
> (2a) "@return Natural language explanation"
>
> In this format, there is *NO CONSTANT* in the documentation. The comment
> only explains in natural language what the function returns. In the
> message linked above, I brought the example:
>
> @return IOIO event information values.
>
> That was *not* a typo.
>
> (2b) The other format is "@retval CONSTANT Natural language
> explanation".
>
> In this case, the exact return value is given, and then explained.
>
>
> In the v8 review, I mentioned that "@retval Others" is wrong, even
> though it is used in several places in the edk2 tree. That's because
> "Others" is not a constant. The right way to put "@retval Others" is to
> replace it with *just* "@return". In other words, *drop* the "Others"
> non-constant, replace "@retval" with "@return", and reformulate the
> natural language text.
>
> In the v8 review, I also mentioned that "@retval Natural language
> explanation" is also wrong, because it's either missing a constant, or
> it should use "@return".
>
> Unfortunately, in response, you seem to have replaced
>
> @retval 0
> @retval Others
>
> with
>
> @return 0
> @return Others
>
> (i.e., just replaced "@retval" with "@return"). And that update is
> wrong, on *both* lines:
>
> - "@retval 0" was correct. It should not have been updated.
>
> - "@retval Others" was indeed wrong, but "@return Others" is *also*
> wrong. It should be just "@return", not "@return Others".
>
> Specifically, the right comment would be:
>
> @retval 0 VMGEXIT succeeded.
>
> @return Exception number to be propagated. VMGEXIT processing did
> not succeed.
>
> If you read it aloud, it will make sense.
>
> Anyway, I'm exhausted. We can address this in a follow-up series, if we
> want to. Keep the ACK, and no v10 is needed just for these comments.
Ok, I've made the changes throughout the series in the OvmfPkg library and
in the UefiCpuPkg NULL library. If there's a v10, then they'll be
incorporated.
Thanks,
Tom
>
> Thanks
> Laszlo
>
>
>> +
>> +**/
>> +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 GpEvent;
>> +
>> + GpEvent.Uint64 = 0;
>> + GpEvent.Elements.Vector = GP_EXCEPTION;
>> + GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
>> + GpEvent.Elements.Valid = 1;
>> +
>> + Status = GpEvent.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.
>> +
>> + @return 0 VMGEXIT succeeded.
>> + @return Others VMGEXIT processing did not succeed. Exception
>> + event 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
>> + )
>> +{
>> +}
>> +
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> new file mode 100644
>> index 000000000000..b6a955ed8088
>> --- /dev/null
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> @@ -0,0 +1,81 @@
>> +/** @file
>> + X64 #VC Exception Handler functon.
>> +
>> + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Base.h>
>> +#include <Uefi.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/VmgExitLib.h>
>> +#include <Register/Amd/Msr.h>
>> +
>> +/**
>> + Handle a #VC exception.
>> +
>> + Performs the necessary processing to handle a #VC exception.
>> +
>> + @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
>> + as value to use on error.
>> + @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
>> +
>> + @retval EFI_SUCCESS Exception handled
>> + @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
>> + propagate provided
>> + @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
>> + propagate provided
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +VmgExitHandleVc (
>> + IN OUT EFI_EXCEPTION_TYPE *ExceptionType,
>> + IN OUT EFI_SYSTEM_CONTEXT SystemContext
>> + )
>> +{
>> + MSR_SEV_ES_GHCB_REGISTER Msr;
>> + EFI_SYSTEM_CONTEXT_X64 *Regs;
>> + GHCB *Ghcb;
>> + UINT64 ExitCode, Status;
>> + EFI_STATUS VcRet;
>> +
>> + VcRet = EFI_SUCCESS;
>> +
>> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
>> + ASSERT (Msr.GhcbInfo.Function == 0);
>> + ASSERT (Msr.Ghcb != 0);
>> +
>> + Regs = SystemContext.SystemContextX64;
>> + Ghcb = Msr.Ghcb;
>> +
>> + VmgInit (Ghcb);
>> +
>> + ExitCode = Regs->ExceptionData;
>> + switch (ExitCode) {
>> + default:
>> + Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
>> + if (Status == 0) {
>> + Regs->ExceptionData = 0;
>> + *ExceptionType = GP_EXCEPTION;
>> + } else {
>> + GHCB_EVENT_INJECTION Event;
>> +
>> + Event.Uint64 = Status;
>> + if (Event.Elements.ErrorCodeValid != 0) {
>> + Regs->ExceptionData = Event.Elements.ErrorCode;
>> + } else {
>> + Regs->ExceptionData = 0;
>> + }
>> +
>> + *ExceptionType = Event.Elements.Vector;
>> + }
>> +
>> + VcRet = EFI_PROTOCOL_ERROR;
>> + }
>> +
>> + VmgDone (Ghcb);
>> +
>> + return VcRet;
>> +}
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 13/46] OvmfPkg/VmgExitLib: Add support for IOIO_PROT NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (11 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 12/46] OvmfPkg/VmgExitLib: Implement library support for VmgExitLib in OVMF Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-10 12:34 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 14/46] OvmfPkg/VmgExitLib: Support string IO " Lendacky, Thomas
` (32 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a IOIO_PROT intercept generates a #VC exception. VMGEXIT
must be used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support a IOIO_PROT
NAE event. Parse the instruction that generated the #VC exception,
setting the required register values in the GHCB and creating the proper
SW_EXITINFO1 value in the GHCB.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Include/IndustryStandard/InstructionParsing.h | 83 +++
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 560 +++++++++++++++++++-
2 files changed, 629 insertions(+), 14 deletions(-)
diff --git a/OvmfPkg/Include/IndustryStandard/InstructionParsing.h b/OvmfPkg/Include/IndustryStandard/InstructionParsing.h
new file mode 100644
index 000000000000..149ff328e06c
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/InstructionParsing.h
@@ -0,0 +1,83 @@
+/** @file
+ Instruction parsing support definitions.
+
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __INSTRUCTION_PARSING_H__
+#define __INSTRUCTION_PARSING_H__
+
+#include <Base.h>
+#include <Uefi.h>
+
+//
+// Instruction REX prefix definition
+//
+typedef union {
+ struct {
+ UINT8 BitB:1;
+ UINT8 BitX:1;
+ UINT8 BitR:1;
+ UINT8 BitW:1;
+ UINT8 Rex:4;
+ } Bits;
+
+ UINT8 Uint8;
+} INSTRUCTION_REX_PREFIX;
+
+//
+// Instruction ModRM definition
+//
+typedef union {
+ struct {
+ UINT8 Rm:3;
+ UINT8 Reg:3;
+ UINT8 Mod:2;
+ } Bits;
+
+ UINT8 Uint8;
+} INSTRUCTION_MODRM;
+
+//
+// Instruction SIB definition
+//
+typedef union {
+ struct {
+ UINT8 Base:3;
+ UINT8 Index:3;
+ UINT8 Scale:2;
+ } Bits;
+
+ UINT8 Uint8;
+} INSTRUCTION_SIB;
+
+//
+// Legacy Instruction Prefixes
+//
+#define OVERRIDE_SEGMENT_CS 0x2E
+#define OVERRIDE_SEGMENT_DS 0x3E
+#define OVERRIDE_SEGMENT_ES 0x26
+#define OVERRIDE_SEGMENT_SS 0x36
+#define OVERRIDE_SEGMENT_FS 0x64
+#define OVERRIDE_SEGMENT_GS 0x65
+#define OVERRIDE_OPERAND_SIZE 0x66
+#define OVERRIDE_ADDRESS_SIZE 0x67
+#define LOCK_PREFIX 0xF0
+#define REPNZ_PREFIX 0xF2
+#define REPZ_PREFIX 0xF3
+
+//
+// REX Prefixes
+//
+#define REX_PREFIX_START 0x40
+#define REX_PREFIX_STOP 0x4F
+#define REX_64BIT_OPERAND_SIZE_MASK 0x08
+
+//
+// Two-byte Opcode Flag
+//
+#define TWO_BYTE_OPCODE_ESCAPE 0x0F
+
+#endif
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index b6a955ed8088..7c2bb12df10a 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -11,6 +11,529 @@
#include <Library/BaseMemoryLib.h>
#include <Library/VmgExitLib.h>
#include <Register/Amd/Msr.h>
+#include <IndustryStandard/InstructionParsing.h>
+
+//
+// Instruction execution mode definition
+//
+typedef enum {
+ LongMode64Bit = 0,
+ LongModeCompat32Bit,
+ LongModeCompat16Bit,
+} SEV_ES_INSTRUCTION_MODE;
+
+//
+// Instruction size definition (for operand and address)
+//
+typedef enum {
+ Size8Bits = 0,
+ Size16Bits,
+ Size32Bits,
+ Size64Bits,
+} SEV_ES_INSTRUCTION_SIZE;
+
+//
+// Intruction segment definition
+//
+typedef enum {
+ SegmentEs = 0,
+ SegmentCs,
+ SegmentSs,
+ SegmentDs,
+ SegmentFs,
+ SegmentGs,
+} SEV_ES_INSTRUCTION_SEGMENT;
+
+//
+// Instruction rep function definition
+//
+typedef enum {
+ RepNone = 0,
+ RepZ,
+ RepNZ,
+} SEV_ES_INSTRUCTION_REP;
+
+typedef struct {
+ UINT8 Rm;
+ UINT8 Reg;
+ UINT8 Mod;
+} SEV_ES_INSTRUCTION_MODRM_EXT;
+
+typedef struct {
+ UINT8 Base;
+ UINT8 Index;
+ UINT8 Scale;
+} SEV_ES_INSTRUCTION_SIB_EXT;
+
+//
+// Instruction opcode definition
+//
+typedef struct {
+ SEV_ES_INSTRUCTION_MODRM_EXT ModRm;
+
+ SEV_ES_INSTRUCTION_SIB_EXT Sib;
+
+ UINTN RegData;
+ UINTN RmData;
+} SEV_ES_INSTRUCTION_OPCODE_EXT;
+
+//
+// Instruction parsing context definition
+//
+typedef struct {
+ GHCB *Ghcb;
+
+ SEV_ES_INSTRUCTION_MODE Mode;
+ SEV_ES_INSTRUCTION_SIZE DataSize;
+ SEV_ES_INSTRUCTION_SIZE AddrSize;
+ BOOLEAN SegmentSpecified;
+ SEV_ES_INSTRUCTION_SEGMENT Segment;
+ SEV_ES_INSTRUCTION_REP RepMode;
+
+ UINT8 *Begin;
+ UINT8 *End;
+
+ UINT8 *Prefixes;
+ UINT8 *OpCodes;
+ UINT8 *Displacement;
+ UINT8 *Immediate;
+
+ INSTRUCTION_REX_PREFIX RexPrefix;
+
+ BOOLEAN ModRmPresent;
+ INSTRUCTION_MODRM ModRm;
+
+ BOOLEAN SibPresent;
+ INSTRUCTION_SIB Sib;
+
+ UINTN PrefixSize;
+ UINTN OpCodeSize;
+ UINTN DisplacementSize;
+ UINTN ImmediateSize;
+
+ SEV_ES_INSTRUCTION_OPCODE_EXT Ext;
+} SEV_ES_INSTRUCTION_DATA;
+
+//
+// Non-automatic Exit function prototype
+//
+typedef
+UINT64
+(*NAE_EXIT) (
+ GHCB *Ghcb,
+ EFI_SYSTEM_CONTEXT_X64 *Regs,
+ SEV_ES_INSTRUCTION_DATA *InstructionData
+ );
+
+
+/**
+ Checks the GHCB to determine if the specified register has been marked valid.
+
+ The ValidBitmap area represents the areas of the GHCB that have been marked
+ valid. Return an indication of whether the area of the GHCB that holds the
+ specified register has been marked valid.
+
+ @param[in] Ghcb Pointer to the Guest-Hypervisor Communication Block
+ @param[in] Reg Offset in the GHCB of the register to check
+
+ @retval TRUE Register has been marked vald in the GHCB
+ @retval FALSE Register has not been marked valid in the GHCB
+
+**/
+STATIC
+BOOLEAN
+GhcbIsRegValid (
+ IN GHCB *Ghcb,
+ IN GHCB_REGISTER Reg
+ )
+{
+ UINT32 RegIndex;
+ UINT32 RegBit;
+
+ RegIndex = Reg / 8;
+ RegBit = Reg & 0x07;
+
+ return ((Ghcb->SaveArea.ValidBitmap[RegIndex] & (1 << RegBit)) != 0);
+}
+
+/**
+ Marks a register as valid in the GHCB.
+
+ The ValidBitmap area represents the areas of the GHCB that have been marked
+ valid. Set the area of the GHCB that holds the specified register as valid.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block
+ @param[in] Reg Offset in the GHCB of the register to mark valid
+
+**/
+STATIC
+VOID
+GhcbSetRegValid (
+ IN OUT GHCB *Ghcb,
+ IN GHCB_REGISTER Reg
+ )
+{
+ UINT32 RegIndex;
+ UINT32 RegBit;
+
+ RegIndex = Reg / 8;
+ RegBit = Reg & 0x07;
+
+ Ghcb->SaveArea.ValidBitmap[RegIndex] |= (1 << RegBit);
+}
+
+/**
+ Decode instruction prefixes.
+
+ Parse the instruction data to track the instruction prefixes that have
+ been used.
+
+ @param[in] Regs x64 processor context
+ @param[in, out] InstructionData Instruction parsing context
+
+**/
+STATIC
+VOID
+DecodePrefixes (
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_MODE Mode;
+ SEV_ES_INSTRUCTION_SIZE ModeDataSize;
+ SEV_ES_INSTRUCTION_SIZE ModeAddrSize;
+ UINT8 *Byte;
+
+ //
+ // Always in 64-bit mode
+ //
+ Mode = LongMode64Bit;
+ ModeDataSize = Size32Bits;
+ ModeAddrSize = Size64Bits;
+
+ InstructionData->Mode = Mode;
+ InstructionData->DataSize = ModeDataSize;
+ InstructionData->AddrSize = ModeAddrSize;
+
+ InstructionData->Prefixes = InstructionData->Begin;
+
+ Byte = InstructionData->Prefixes;
+ for ( ; ; Byte++, InstructionData->PrefixSize++) {
+ //
+ // Check the 0x40 to 0x4F range using an if statement here since some
+ // compilers don't like the "case 0x40 ... 0x4F:" syntax. This avoids
+ // 16 case statements below.
+ //
+ if ((*Byte >= REX_PREFIX_START) && (*Byte <= REX_PREFIX_STOP)) {
+ InstructionData->RexPrefix.Uint8 = *Byte;
+ if ((*Byte & REX_64BIT_OPERAND_SIZE_MASK) != 0) {
+ InstructionData->DataSize = Size64Bits;
+ }
+ continue;
+ }
+
+ switch (*Byte) {
+ case OVERRIDE_SEGMENT_CS:
+ case OVERRIDE_SEGMENT_DS:
+ case OVERRIDE_SEGMENT_ES:
+ case OVERRIDE_SEGMENT_SS:
+ if (Mode != LongMode64Bit) {
+ InstructionData->SegmentSpecified = TRUE;
+ InstructionData->Segment = (*Byte >> 3) & 3;
+ }
+ break;
+
+ case OVERRIDE_SEGMENT_FS:
+ case OVERRIDE_SEGMENT_GS:
+ InstructionData->SegmentSpecified = TRUE;
+ InstructionData->Segment = *Byte & 7;
+ break;
+
+ case OVERRIDE_OPERAND_SIZE:
+ if (InstructionData->RexPrefix.Uint8 == 0) {
+ InstructionData->DataSize =
+ (Mode == LongMode64Bit) ? Size16Bits :
+ (Mode == LongModeCompat32Bit) ? Size16Bits :
+ (Mode == LongModeCompat16Bit) ? Size32Bits : 0;
+ }
+ break;
+
+ case OVERRIDE_ADDRESS_SIZE:
+ InstructionData->AddrSize =
+ (Mode == LongMode64Bit) ? Size32Bits :
+ (Mode == LongModeCompat32Bit) ? Size16Bits :
+ (Mode == LongModeCompat16Bit) ? Size32Bits : 0;
+ break;
+
+ case LOCK_PREFIX:
+ break;
+
+ case REPZ_PREFIX:
+ InstructionData->RepMode = RepZ;
+ break;
+
+ case REPNZ_PREFIX:
+ InstructionData->RepMode = RepNZ;
+ break;
+
+ default:
+ InstructionData->OpCodes = Byte;
+ InstructionData->OpCodeSize = (*Byte == TWO_BYTE_OPCODE_ESCAPE) ? 2 : 1;
+
+ InstructionData->End = Byte + InstructionData->OpCodeSize;
+ InstructionData->Displacement = InstructionData->End;
+ InstructionData->Immediate = InstructionData->End;
+ return;
+ }
+ }
+}
+
+/**
+ Determine instruction length
+
+ Return the total length of the parsed instruction.
+
+ @param[in] InstructionData Instruction parsing context
+
+ @return Length of parsed instruction
+
+**/
+STATIC
+UINT64
+InstructionLength (
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ return (UINT64) (InstructionData->End - InstructionData->Begin);
+}
+
+/**
+ Initialize the instruction parsing context.
+
+ Initialize the instruction parsing context, which includes decoding the
+ instruction prefixes.
+
+ @param[in, out] InstructionData Instruction parsing context
+ @param[in] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in] Regs x64 processor context
+
+**/
+STATIC
+VOID
+InitInstructionData (
+ IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData,
+ IN GHCB *Ghcb,
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs
+ )
+{
+ SetMem (InstructionData, sizeof (*InstructionData), 0);
+ InstructionData->Ghcb = Ghcb;
+ InstructionData->Begin = (UINT8 *) Regs->Rip;
+ InstructionData->End = (UINT8 *) Regs->Rip;
+
+ DecodePrefixes (Regs, InstructionData);
+}
+
+/**
+ Report an unsupported event to the hypervisor
+
+ Use the VMGEXIT support to report an unsupported event to the hypervisor.
+
+ @param[in] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return New exception value to propagate
+
+**/
+STATIC
+UINT64
+UnsupportedExit (
+ IN GHCB *Ghcb,
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 Status;
+
+ Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, Regs->ExceptionData, 0);
+ 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;
+}
+
+/**
+ Build the IOIO event information.
+
+ The IOIO event information identifies the type of IO operation to be performed
+ by the hypervisor. Build this information based on the instruction data.
+
+ @param[in] Regs x64 processor context
+ @param[in, out] InstructionData Instruction parsing context
+
+ @return IOIO event information value
+
+**/
+STATIC
+UINT64
+IoioExitInfo (
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 ExitInfo;
+
+ ExitInfo = 0;
+
+ switch (*(InstructionData->OpCodes)) {
+ //
+ // IN immediate opcodes
+ //
+ case 0xE4:
+ case 0xE5:
+ InstructionData->ImmediateSize = 1;
+ InstructionData->End++;
+ ExitInfo |= IOIO_TYPE_IN;
+ ExitInfo |= ((*(InstructionData->OpCodes + 1)) << 16);
+ break;
+
+ //
+ // OUT immediate opcodes
+ //
+ case 0xE6:
+ case 0xE7:
+ InstructionData->ImmediateSize = 1;
+ InstructionData->End++;
+ ExitInfo |= IOIO_TYPE_OUT;
+ ExitInfo |= ((*(InstructionData->OpCodes + 1)) << 16) | IOIO_TYPE_OUT;
+ break;
+
+ //
+ // IN register opcodes
+ //
+ case 0xEC:
+ case 0xED:
+ ExitInfo |= IOIO_TYPE_IN;
+ ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
+ break;
+
+ //
+ // OUT register opcodes
+ //
+ case 0xEE:
+ case 0xEF:
+ ExitInfo |= IOIO_TYPE_OUT;
+ ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
+ break;
+
+ default:
+ return 0;
+ }
+
+ switch (*(InstructionData->OpCodes)) {
+ //
+ // Single-byte opcodes
+ //
+ case 0xE4:
+ case 0xE6:
+ case 0xEC:
+ case 0xEE:
+ ExitInfo |= IOIO_DATA_8;
+ break;
+
+ //
+ // Length determined by instruction parsing
+ //
+ default:
+ ExitInfo |= (InstructionData->DataSize == Size16Bits) ? IOIO_DATA_16
+ : IOIO_DATA_32;
+ }
+
+ switch (InstructionData->AddrSize) {
+ case Size16Bits:
+ ExitInfo |= IOIO_ADDR_16;
+ break;
+
+ case Size32Bits:
+ ExitInfo |= IOIO_ADDR_32;
+ break;
+
+ case Size64Bits:
+ ExitInfo |= IOIO_ADDR_64;
+ break;
+
+ default:
+ break;
+ }
+
+ if (InstructionData->RepMode != 0) {
+ ExitInfo |= IOIO_REP;
+ }
+
+ return ExitInfo;
+}
+
+/**
+ Handle an IOIO event.
+
+ Use the VMGEXIT instruction to handle an IOIO event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+IoioExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 ExitInfo1, Status;
+
+ ExitInfo1 = IoioExitInfo (Regs, InstructionData);
+ if (ExitInfo1 == 0) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
+ if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
+ Ghcb->SaveArea.Rax = 0;
+ } else {
+ CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+ GhcbSetRegValid (Ghcb, GhcbRax);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
+ if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+
+ return 0;
+}
/**
Handle a #VC exception.
@@ -38,6 +561,8 @@ VmgExitHandleVc (
MSR_SEV_ES_GHCB_REGISTER Msr;
EFI_SYSTEM_CONTEXT_X64 *Regs;
GHCB *Ghcb;
+ NAE_EXIT NaeExit;
+ SEV_ES_INSTRUCTION_DATA InstructionData;
UINT64 ExitCode, Status;
EFI_STATUS VcRet;
@@ -54,24 +579,31 @@ VmgExitHandleVc (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SVM_EXIT_IOIO_PROT:
+ NaeExit = IoioExit;
+ break;
+
default:
- Status = VmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, ExitCode, 0);
- if (Status == 0) {
- Regs->ExceptionData = 0;
- *ExceptionType = GP_EXCEPTION;
+ NaeExit = UnsupportedExit;
+ }
+
+ InitInstructionData (&InstructionData, Ghcb, Regs);
+
+ Status = NaeExit (Ghcb, Regs, &InstructionData);
+ if (Status == 0) {
+ Regs->Rip += InstructionLength (&InstructionData);
+ } else {
+ GHCB_EVENT_INJECTION Event;
+
+ Event.Uint64 = Status;
+ if (Event.Elements.ErrorCodeValid != 0) {
+ Regs->ExceptionData = Event.Elements.ErrorCode;
} else {
- GHCB_EVENT_INJECTION Event;
-
- Event.Uint64 = Status;
- if (Event.Elements.ErrorCodeValid != 0) {
- Regs->ExceptionData = Event.Elements.ErrorCode;
- } else {
- Regs->ExceptionData = 0;
- }
-
- *ExceptionType = Event.Elements.Vector;
+ Regs->ExceptionData = 0;
}
+ *ExceptionType = Event.Elements.Vector;
+
VcRet = EFI_PROTOCOL_ERROR;
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 13/46] OvmfPkg/VmgExitLib: Add support for IOIO_PROT NAE events
2020-06-05 13:27 ` [PATCH v9 13/46] OvmfPkg/VmgExitLib: Add support for IOIO_PROT NAE events Lendacky, Thomas
@ 2020-06-10 12:34 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-10 12:34 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a IOIO_PROT intercept generates a #VC exception. VMGEXIT
> must be used to allow the hypervisor to handle this intercept.
>
> Add support to construct the required GHCB values to support a IOIO_PROT
> NAE event. Parse the instruction that generated the #VC exception,
> setting the required register values in the GHCB and creating the proper
> SW_EXITINFO1 value in the GHCB.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Include/IndustryStandard/InstructionParsing.h | 83 +++
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 560 +++++++++++++++++++-
> 2 files changed, 629 insertions(+), 14 deletions(-)
Looks good, thanks for the updates.
Acked-by: Laszlo Ersek <lersek@redhat.com>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 14/46] OvmfPkg/VmgExitLib: Support string IO for IOIO_PROT NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (12 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 13/46] OvmfPkg/VmgExitLib: Add support for IOIO_PROT NAE events Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-10 12:39 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 15/46] OvmfPkg/VmgExitLib: Add support for CPUID " Lendacky, Thomas
` (31 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Add support to the #VC exception handler to handle string IO. This
requires expanding the IO instruction parsing to recognize string based
IO instructions as well as preparing an un-encrypted buffer to be used
to transfer (either to or from the guest) the string contents for the IO
operation. The SW_EXITINFO2 and SW_SCRATCH fields of the GHCB are set
appropriately for the operation. Multiple VMGEXIT invocations may be
needed to complete the string IO operation.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 90 +++++++++++++++++---
1 file changed, 76 insertions(+), 14 deletions(-)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 7c2bb12df10a..b74b13045cfd 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -397,6 +397,26 @@ IoioExitInfo (
ExitInfo = 0;
switch (*(InstructionData->OpCodes)) {
+ //
+ // INS opcodes
+ //
+ case 0x6C:
+ case 0x6D:
+ ExitInfo |= IOIO_TYPE_INS;
+ ExitInfo |= IOIO_SEG_ES;
+ ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
+ break;
+
+ //
+ // OUTS opcodes
+ //
+ case 0x6E:
+ case 0x6F:
+ ExitInfo |= IOIO_TYPE_OUTS;
+ ExitInfo |= IOIO_SEG_DS;
+ ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
+ break;
+
//
// IN immediate opcodes
//
@@ -445,6 +465,8 @@ IoioExitInfo (
//
// Single-byte opcodes
//
+ case 0x6C:
+ case 0x6E:
case 0xE4:
case 0xE6:
case 0xEC:
@@ -506,30 +528,70 @@ IoioExit (
IN SEV_ES_INSTRUCTION_DATA *InstructionData
)
{
- UINT64 ExitInfo1, Status;
+ UINT64 ExitInfo1, ExitInfo2, Status;
+ BOOLEAN IsString;
ExitInfo1 = IoioExitInfo (Regs, InstructionData);
if (ExitInfo1 == 0) {
return UnsupportedExit (Ghcb, Regs, InstructionData);
}
- if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
- Ghcb->SaveArea.Rax = 0;
+ IsString = ((ExitInfo1 & IOIO_TYPE_STR) != 0) ? TRUE : FALSE;
+ if (IsString) {
+ UINTN IoBytes, VmgExitBytes;
+ UINTN GhcbCount, OpCount;
+
+ Status = 0;
+
+ IoBytes = IOIO_DATA_BYTES(ExitInfo1);
+ GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes;
+
+ OpCount = ((ExitInfo1 & IOIO_REP) != 0) ? Regs->Rcx : 1;
+ while (OpCount) {
+ ExitInfo2 = MIN (OpCount, GhcbCount);
+ VmgExitBytes = ExitInfo2 * IoBytes;
+
+ if ((ExitInfo1 & IOIO_TYPE_IN) == 0) {
+ CopyMem (Ghcb->SharedBuffer, (VOID *) Regs->Rsi, VmgExitBytes);
+ Regs->Rsi += VmgExitBytes;
+ }
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
+ CopyMem ((VOID *) Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes);
+ Regs->Rdi += VmgExitBytes;
+ }
+
+ if ((ExitInfo1 & IOIO_REP) != 0) {
+ Regs->Rcx -= ExitInfo2;
+ }
+
+ OpCount -= ExitInfo2;
+ }
} else {
- CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
- }
- GhcbSetRegValid (Ghcb, GhcbRax);
+ if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
+ Ghcb->SaveArea.Rax = 0;
+ } else {
+ CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+ GhcbSetRegValid (Ghcb, GhcbRax);
- Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0);
- if (Status != 0) {
- return Status;
- }
+ Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0);
+ if (Status != 0) {
+ return Status;
+ }
- if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
- if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
- return UnsupportedExit (Ghcb, Regs, InstructionData);
+ if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
+ if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
}
- CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
}
return 0;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 14/46] OvmfPkg/VmgExitLib: Support string IO for IOIO_PROT NAE events
2020-06-05 13:27 ` [PATCH v9 14/46] OvmfPkg/VmgExitLib: Support string IO " Lendacky, Thomas
@ 2020-06-10 12:39 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-10 12:39 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Add support to the #VC exception handler to handle string IO. This
> requires expanding the IO instruction parsing to recognize string based
> IO instructions as well as preparing an un-encrypted buffer to be used
> to transfer (either to or from the guest) the string contents for the IO
> operation. The SW_EXITINFO2 and SW_SCRATCH fields of the GHCB are set
> appropriately for the operation. Multiple VMGEXIT invocations may be
> needed to complete the string IO operation.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 90 +++++++++++++++++---
> 1 file changed, 76 insertions(+), 14 deletions(-)
>
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> index 7c2bb12df10a..b74b13045cfd 100644
> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> @@ -397,6 +397,26 @@ IoioExitInfo (
> ExitInfo = 0;
>
> switch (*(InstructionData->OpCodes)) {
> + //
> + // INS opcodes
> + //
> + case 0x6C:
> + case 0x6D:
> + ExitInfo |= IOIO_TYPE_INS;
> + ExitInfo |= IOIO_SEG_ES;
> + ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
> + break;
> +
> + //
> + // OUTS opcodes
> + //
> + case 0x6E:
> + case 0x6F:
> + ExitInfo |= IOIO_TYPE_OUTS;
> + ExitInfo |= IOIO_SEG_DS;
> + ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
> + break;
> +
> //
> // IN immediate opcodes
> //
> @@ -445,6 +465,8 @@ IoioExitInfo (
> //
> // Single-byte opcodes
> //
> + case 0x6C:
> + case 0x6E:
> case 0xE4:
> case 0xE6:
> case 0xEC:
> @@ -506,30 +528,70 @@ IoioExit (
> IN SEV_ES_INSTRUCTION_DATA *InstructionData
> )
> {
> - UINT64 ExitInfo1, Status;
> + UINT64 ExitInfo1, ExitInfo2, Status;
> + BOOLEAN IsString;
>
> ExitInfo1 = IoioExitInfo (Regs, InstructionData);
> if (ExitInfo1 == 0) {
> return UnsupportedExit (Ghcb, Regs, InstructionData);
> }
>
> - if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
> - Ghcb->SaveArea.Rax = 0;
> + IsString = ((ExitInfo1 & IOIO_TYPE_STR) != 0) ? TRUE : FALSE;
> + if (IsString) {
> + UINTN IoBytes, VmgExitBytes;
> + UINTN GhcbCount, OpCount;
> +
> + Status = 0;
> +
> + IoBytes = IOIO_DATA_BYTES(ExitInfo1);
(1) missing space before the opening paren, but we're at v9. So my ACK
stands.
Thanks
Laszlo
> + GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes;
> +
> + OpCount = ((ExitInfo1 & IOIO_REP) != 0) ? Regs->Rcx : 1;
> + while (OpCount) {
> + ExitInfo2 = MIN (OpCount, GhcbCount);
> + VmgExitBytes = ExitInfo2 * IoBytes;
> +
> + if ((ExitInfo1 & IOIO_TYPE_IN) == 0) {
> + CopyMem (Ghcb->SharedBuffer, (VOID *) Regs->Rsi, VmgExitBytes);
> + Regs->Rsi += VmgExitBytes;
> + }
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, ExitInfo2);
> + if (Status != 0) {
> + return Status;
> + }
> +
> + if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
> + CopyMem ((VOID *) Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes);
> + Regs->Rdi += VmgExitBytes;
> + }
> +
> + if ((ExitInfo1 & IOIO_REP) != 0) {
> + Regs->Rcx -= ExitInfo2;
> + }
> +
> + OpCount -= ExitInfo2;
> + }
> } else {
> - CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
> - }
> - GhcbSetRegValid (Ghcb, GhcbRax);
> + if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
> + Ghcb->SaveArea.Rax = 0;
> + } else {
> + CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
> + }
> + GhcbSetRegValid (Ghcb, GhcbRax);
>
> - Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0);
> - if (Status != 0) {
> - return Status;
> - }
> + Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0);
> + if (Status != 0) {
> + return Status;
> + }
>
> - if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
> - if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
> - return UnsupportedExit (Ghcb, Regs, InstructionData);
> + if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
> + if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
> + return UnsupportedExit (Ghcb, Regs, InstructionData);
> + }
> + CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
> }
> - CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
> }
>
> return 0;
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 15/46] OvmfPkg/VmgExitLib: Add support for CPUID NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (13 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 14/46] OvmfPkg/VmgExitLib: Support string IO " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-10 12:41 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 16/46] OvmfPkg/VmgExitLib: Add support for MSR_PROT " Lendacky, Thomas
` (30 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a CPUID intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support a CPUID NAE
event. Additionally, CPUID 0x0000_000d (CPUID_EXTENDED_STATE) requires
XCR0 to be supplied in the GHCB, so add support to issue the XGETBV
instruction.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 60 ++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index b74b13045cfd..1e0b2bf399da 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -11,6 +11,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/VmgExitLib.h>
#include <Register/Amd/Msr.h>
+#include <Register/Intel/Cpuid.h>
#include <IndustryStandard/InstructionParsing.h>
//
@@ -597,6 +598,61 @@ IoioExit (
return 0;
}
+/**
+ Handle a CPUID event.
+
+ Use the VMGEXIT instruction to handle a CPUID event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+CpuidExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 Status;
+
+ Ghcb->SaveArea.Rax = Regs->Rax;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+ if (Regs->Rax == CPUID_EXTENDED_STATE) {
+ IA32_CR4 Cr4;
+
+ Cr4.UintN = AsmReadCr4 ();
+ Ghcb->SaveArea.XCr0 = (Cr4.Bits.OSXSAVE == 1) ? AsmXGetBv (0) : 1;
+ GhcbSetRegValid (Ghcb, GhcbXCr0);
+ }
+
+ Status = VmgExit (Ghcb, SVM_EXIT_CPUID, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||
+ !GhcbIsRegValid (Ghcb, GhcbRbx) ||
+ !GhcbIsRegValid (Ghcb, GhcbRcx) ||
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+ Regs->Rbx = Ghcb->SaveArea.Rbx;
+ Regs->Rcx = Ghcb->SaveArea.Rcx;
+ Regs->Rdx = Ghcb->SaveArea.Rdx;
+
+ return 0;
+}
+
/**
Handle a #VC exception.
@@ -641,6 +697,10 @@ VmgExitHandleVc (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SVM_EXIT_CPUID:
+ NaeExit = CpuidExit;
+ break;
+
case SVM_EXIT_IOIO_PROT:
NaeExit = IoioExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 15/46] OvmfPkg/VmgExitLib: Add support for CPUID NAE events
2020-06-05 13:27 ` [PATCH v9 15/46] OvmfPkg/VmgExitLib: Add support for CPUID " Lendacky, Thomas
@ 2020-06-10 12:41 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-10 12:41 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a CPUID intercept generates a #VC exception. VMGEXIT must be
> used to allow the hypervisor to handle this intercept.
>
> Add support to construct the required GHCB values to support a CPUID NAE
> event. Additionally, CPUID 0x0000_000d (CPUID_EXTENDED_STATE) requires
> XCR0 to be supplied in the GHCB, so add support to issue the XGETBV
> instruction.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 60 ++++++++++++++++++++
> 1 file changed, 60 insertions(+)
Looks fine, thanks
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 16/46] OvmfPkg/VmgExitLib: Add support for MSR_PROT NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (14 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 15/46] OvmfPkg/VmgExitLib: Add support for CPUID " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-10 12:43 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO) Lendacky, Thomas
` (29 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a MSR_PROT intercept generates a #VC exception. VMGEXIT must
be used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support an MSR_PROT
NAE event. Parse the instruction that generated the #VC exception to
determine whether it is RDMSR or WRMSR, setting the required register
register values in the GHCB and creating the proper SW_EXIT_INFO1 value in
the GHCB.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 65 ++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 1e0b2bf399da..009eb48cd468 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -374,6 +374,67 @@ UnsupportedExit (
return Status;
}
+/**
+ Handle an MSR event.
+
+ Use the VMGEXIT instruction to handle either a RDMSR or WRMSR event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+MsrExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 ExitInfo1, Status;
+
+ ExitInfo1 = 0;
+
+ switch (*(InstructionData->OpCodes + 1)) {
+ case 0x30: // WRMSR
+ ExitInfo1 = 1;
+ Ghcb->SaveArea.Rax = Regs->Rax;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+ Ghcb->SaveArea.Rdx = Regs->Rdx;
+ GhcbSetRegValid (Ghcb, GhcbRdx);
+ //
+ // fall through
+ //
+ case 0x32: // RDMSR
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+ break;
+ default:
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
+ Status = VmgExit (Ghcb, SVM_EXIT_MSR, ExitInfo1, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (ExitInfo1 == 0) {
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+ Regs->Rdx = Ghcb->SaveArea.Rdx;
+ }
+
+ return 0;
+}
+
/**
Build the IOIO event information.
@@ -705,6 +766,10 @@ VmgExitHandleVc (
NaeExit = IoioExit;
break;
+ case SVM_EXIT_MSR:
+ NaeExit = MsrExit;
+ break;
+
default:
NaeExit = UnsupportedExit;
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 16/46] OvmfPkg/VmgExitLib: Add support for MSR_PROT NAE events
2020-06-05 13:27 ` [PATCH v9 16/46] OvmfPkg/VmgExitLib: Add support for MSR_PROT " Lendacky, Thomas
@ 2020-06-10 12:43 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-10 12:43 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a MSR_PROT intercept generates a #VC exception. VMGEXIT must
> be used to allow the hypervisor to handle this intercept.
>
> Add support to construct the required GHCB values to support an MSR_PROT
> NAE event. Parse the instruction that generated the #VC exception to
> determine whether it is RDMSR or WRMSR, setting the required register
> register values in the GHCB and creating the proper SW_EXIT_INFO1 value in
> the GHCB.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 65 ++++++++++++++++++++
> 1 file changed, 65 insertions(+)
Thanks for the updates.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (15 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 16/46] OvmfPkg/VmgExitLib: Add support for MSR_PROT " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 8:30 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 18/46] OvmfPkg/VmgExitLib: Add support for WBINVD NAE events Lendacky, Thomas
` (28 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a NPF intercept for an NPT entry with a reserved bit set
generates a #VC exception. This condition is assumed to be an MMIO access.
VMGEXIT must be used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support a NPF NAE
event for MMIO. Parse the instruction that generated the #VC exception,
setting the required register values in the GHCB and creating the proper
SW_EXIT_INFO1, SW_EXITINFO2 and SW_SCRATCH values in the GHCB.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 484 ++++++++++++++++++++
1 file changed, 484 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 009eb48cd468..c2646d45506a 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -183,6 +183,279 @@ GhcbSetRegValid (
Ghcb->SaveArea.ValidBitmap[RegIndex] |= (1 << RegBit);
}
+/**
+ Return a pointer to the contents of the specified register.
+
+ Based upon the input register, return a pointer to the registers contents
+ in the x86 processor context.
+
+ @param[in] Regs x64 processor context
+ @param[in] Register Register to obtain pointer for
+
+ @return Pointer to the contents of the requested register
+
+**/
+STATIC
+UINT64 *
+GetRegisterPointer (
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN UINT8 Register
+ )
+{
+ UINT64 *Reg;
+
+ switch (Register) {
+ case 0:
+ Reg = &Regs->Rax;
+ break;
+ case 1:
+ Reg = &Regs->Rcx;
+ break;
+ case 2:
+ Reg = &Regs->Rdx;
+ break;
+ case 3:
+ Reg = &Regs->Rbx;
+ break;
+ case 4:
+ Reg = &Regs->Rsp;
+ break;
+ case 5:
+ Reg = &Regs->Rbp;
+ break;
+ case 6:
+ Reg = &Regs->Rsi;
+ break;
+ case 7:
+ Reg = &Regs->Rdi;
+ break;
+ case 8:
+ Reg = &Regs->R8;
+ break;
+ case 9:
+ Reg = &Regs->R9;
+ break;
+ case 10:
+ Reg = &Regs->R10;
+ break;
+ case 11:
+ Reg = &Regs->R11;
+ break;
+ case 12:
+ Reg = &Regs->R12;
+ break;
+ case 13:
+ Reg = &Regs->R13;
+ break;
+ case 14:
+ Reg = &Regs->R14;
+ break;
+ case 15:
+ Reg = &Regs->R15;
+ break;
+ default:
+ Reg = NULL;
+ }
+ ASSERT (Reg != NULL);
+
+ return Reg;
+}
+
+/**
+ Update the instruction parsing context for displacement bytes.
+
+ @param[in, out] InstructionData Instruction parsing context
+ @param[in] Size The instruction displacement size
+
+**/
+STATIC
+VOID
+UpdateForDisplacement (
+ IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData,
+ IN UINTN Size
+ )
+{
+ InstructionData->DisplacementSize = Size;
+ InstructionData->Immediate += Size;
+ InstructionData->End += Size;
+}
+
+/**
+ Determine if an instruction address if RIP relative.
+
+ Examine the instruction parsing context to determine if the address offset
+ is relative to the instruction pointer.
+
+ @param[in] InstructionData Instruction parsing context
+
+ @retval TRUE Instruction addressing is RIP relative
+ @retval FALSE Instruction addressing is not RIP relative
+
+**/
+STATIC
+BOOLEAN
+IsRipRelative (
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+
+ Ext = &InstructionData->Ext;
+
+ return ((InstructionData->Mode == LongMode64Bit) &&
+ (Ext->ModRm.Mod == 0) &&
+ (Ext->ModRm.Rm == 5) &&
+ (InstructionData->SibPresent == FALSE));
+}
+
+/**
+ Return the effective address of a memory operand.
+
+ Examine the instruction parsing context to obtain the effective memory
+ address of a memory operand.
+
+ @param[in] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return The memory operand effective address
+
+**/
+STATIC
+UINT64
+GetEffectiveMemoryAddress (
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ UINT64 EffectiveAddress;
+
+ Ext = &InstructionData->Ext;
+ EffectiveAddress = 0;
+
+ if (IsRipRelative (InstructionData)) {
+ //
+ // RIP-relative displacement is a 32-bit signed value
+ //
+ INT32 RipRelative;
+
+ RipRelative = *(INT32 *) InstructionData->Displacement;
+
+ UpdateForDisplacement (InstructionData, 4);
+
+ //
+ // Negative displacement is handled by standard UINT64 wrap-around.
+ //
+ return Regs->Rip + (UINT64) RipRelative;
+ }
+
+ switch (Ext->ModRm.Mod) {
+ case 1:
+ UpdateForDisplacement (InstructionData, 1);
+ EffectiveAddress += (UINT64) (*(INT8 *) (InstructionData->Displacement));
+ break;
+ case 2:
+ switch (InstructionData->AddrSize) {
+ case Size16Bits:
+ UpdateForDisplacement (InstructionData, 2);
+ EffectiveAddress += (UINT64) (*(INT16 *) (InstructionData->Displacement));
+ break;
+ default:
+ UpdateForDisplacement (InstructionData, 4);
+ EffectiveAddress += (UINT64) (*(INT32 *) (InstructionData->Displacement));
+ break;
+ }
+ break;
+ }
+
+ if (InstructionData->SibPresent) {
+ INT64 Displacement;
+
+ if (Ext->Sib.Index != 4) {
+ CopyMem (&Displacement,
+ GetRegisterPointer (Regs, Ext->Sib.Index),
+ sizeof (Displacement));
+ Displacement *= (1 << Ext->Sib.Scale);
+
+ //
+ // Negative displacement is handled by standard UINT64 wrap-around.
+ //
+ EffectiveAddress += (UINT64) Displacement;
+ }
+
+ if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) {
+ EffectiveAddress += *GetRegisterPointer (Regs, Ext->Sib.Base);
+ } else {
+ UpdateForDisplacement (InstructionData, 4);
+ EffectiveAddress += (UINT64) (*(INT32 *) (InstructionData->Displacement));
+ }
+ } else {
+ EffectiveAddress += *GetRegisterPointer (Regs, Ext->ModRm.Rm);
+ }
+
+ return EffectiveAddress;
+}
+
+/**
+ Decode a ModRM byte.
+
+ Examine the instruction parsing context to decode a ModRM byte and the SIB
+ byte, if present.
+
+ @param[in] Regs x64 processor context
+ @param[in, out] InstructionData Instruction parsing context
+
+**/
+STATIC
+VOID
+DecodeModRm (
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ INSTRUCTION_REX_PREFIX *RexPrefix;
+ INSTRUCTION_MODRM *ModRm;
+ INSTRUCTION_SIB *Sib;
+
+ RexPrefix = &InstructionData->RexPrefix;
+ Ext = &InstructionData->Ext;
+ ModRm = &InstructionData->ModRm;
+ Sib = &InstructionData->Sib;
+
+ InstructionData->ModRmPresent = TRUE;
+ ModRm->Uint8 = *(InstructionData->End);
+
+ InstructionData->Displacement++;
+ InstructionData->Immediate++;
+ InstructionData->End++;
+
+ Ext->ModRm.Mod = ModRm->Bits.Mod;
+ Ext->ModRm.Reg = (RexPrefix->Bits.BitR << 3) | ModRm->Bits.Reg;
+ Ext->ModRm.Rm = (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm;
+
+ Ext->RegData = *GetRegisterPointer (Regs, Ext->ModRm.Reg);
+
+ if (Ext->ModRm.Mod == 3) {
+ Ext->RmData = *GetRegisterPointer (Regs, Ext->ModRm.Rm);
+ } else {
+ if (ModRm->Bits.Rm == 4) {
+ InstructionData->SibPresent = TRUE;
+ Sib->Uint8 = *(InstructionData->End);
+
+ InstructionData->Displacement++;
+ InstructionData->Immediate++;
+ InstructionData->End++;
+
+ Ext->Sib.Scale = Sib->Bits.Scale;
+ Ext->Sib.Index = (RexPrefix->Bits.BitX << 3) | Sib->Bits.Index;
+ Ext->Sib.Base = (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base;
+ }
+
+ Ext->RmData = GetEffectiveMemoryAddress (Regs, InstructionData);
+ }
+}
+
/**
Decode instruction prefixes.
@@ -374,6 +647,213 @@ UnsupportedExit (
return Status;
}
+/**
+ Handle an MMIO event.
+
+ Use the VMGEXIT instruction to handle either an MMIO read or an MMIO write.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in, out] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+MmioExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 ExitInfo1, ExitInfo2, Status;
+ UINTN Bytes;
+ UINT64 *Register;
+ UINT8 OpCode, SignByte;
+
+ Bytes = 0;
+
+ OpCode = *(InstructionData->OpCodes);
+ if (OpCode == TWO_BYTE_OPCODE_ESCAPE) {
+ OpCode = *(InstructionData->OpCodes + 1);
+ }
+
+ switch (OpCode) {
+ //
+ // MMIO write (MOV reg/memX, regX)
+ //
+ case 0x88:
+ Bytes = 1;
+ //
+ // fall through
+ //
+ case 0x89:
+ DecodeModRm (Regs, InstructionData);
+ Bytes = ((Bytes != 0) ? Bytes :
+ (InstructionData->DataSize == Size16Bits) ? 2 :
+ (InstructionData->DataSize == Size32Bits) ? 4 :
+ (InstructionData->DataSize == Size64Bits) ? 8 :
+ 0);
+
+ if (InstructionData->Ext.ModRm.Mod == 3) {
+ //
+ // NPF on two register operands???
+ //
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+ CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes);
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+ break;
+
+ //
+ // MMIO write (MOV reg/memX, immX)
+ //
+ case 0xC6:
+ Bytes = 1;
+ //
+ // fall through
+ //
+ case 0xC7:
+ DecodeModRm (Regs, InstructionData);
+ Bytes = ((Bytes != 0) ? Bytes :
+ (InstructionData->DataSize == Size16Bits) ? 2 :
+ (InstructionData->DataSize == Size32Bits) ? 4 :
+ 0);
+
+ InstructionData->ImmediateSize = Bytes;
+ InstructionData->End += Bytes;
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+ CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes);
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+ break;
+
+ //
+ // MMIO read (MOV regX, reg/memX)
+ //
+ case 0x8A:
+ Bytes = 1;
+ //
+ // fall through
+ //
+ case 0x8B:
+ DecodeModRm (Regs, InstructionData);
+ Bytes = ((Bytes != 0) ? Bytes :
+ (InstructionData->DataSize == Size16Bits) ? 2 :
+ (InstructionData->DataSize == Size32Bits) ? 4 :
+ (InstructionData->DataSize == Size64Bits) ? 8 :
+ 0);
+ if (InstructionData->Ext.ModRm.Mod == 3) {
+ //
+ // NPF on two register operands???
+ //
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+
+ Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
+ if (Bytes == 4) {
+ //
+ // Zero-extend for 32-bit operation
+ //
+ *Register = 0;
+ }
+ CopyMem (Register, Ghcb->SharedBuffer, Bytes);
+ break;
+
+ //
+ // MMIO read w/ zero-extension ((MOVZX regX, reg/memX)
+ //
+ case 0xB6:
+ Bytes = 1;
+ //
+ // fall through
+ //
+ case 0xB7:
+ Bytes = (Bytes != 0) ? Bytes : 2;
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+
+ Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
+ SetMem (Register, InstructionData->DataSize, 0);
+ CopyMem (Register, Ghcb->SharedBuffer, Bytes);
+ break;
+
+ //
+ // MMIO read w/ sign-extension (MOVSX regX, reg/memX)
+ //
+ case 0xBE:
+ Bytes = 1;
+ //
+ // fall through
+ //
+ case 0xBF:
+ Bytes = (Bytes != 0) ? Bytes : 2;
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (Bytes == 1) {
+ UINT8 *Data = (UINT8 *) Ghcb->SharedBuffer;
+
+ SignByte = ((*Data & BIT7) != 0) ? 0xFF : 0x00;
+ } else {
+ UINT16 *Data = (UINT16 *) Ghcb->SharedBuffer;
+
+ SignByte = ((*Data & BIT15) != 0) ? 0xFF : 0x00;
+ }
+
+ Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
+ SetMem (Register, InstructionData->DataSize, SignByte);
+ CopyMem (Register, Ghcb->SharedBuffer, Bytes);
+ break;
+
+ default:
+ Status = GP_EXCEPTION;
+ ASSERT (FALSE);
+ }
+
+ return Status;
+}
+
/**
Handle an MSR event.
@@ -770,6 +1250,10 @@ VmgExitHandleVc (
NaeExit = MsrExit;
break;
+ case SVM_EXIT_NPF:
+ NaeExit = MmioExit;
+ break;
+
default:
NaeExit = UnsupportedExit;
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
2020-06-05 13:27 ` [PATCH v9 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO) Lendacky, Thomas
@ 2020-06-11 8:30 ` Laszlo Ersek
2020-06-11 15:09 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 8:30 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a NPF intercept for an NPT entry with a reserved bit set
> generates a #VC exception. This condition is assumed to be an MMIO access.
> VMGEXIT must be used to allow the hypervisor to handle this intercept.
>
> Add support to construct the required GHCB values to support a NPF NAE
> event for MMIO. Parse the instruction that generated the #VC exception,
> setting the required register values in the GHCB and creating the proper
> SW_EXIT_INFO1, SW_EXITINFO2 and SW_SCRATCH values in the GHCB.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 484 ++++++++++++++++++++
> 1 file changed, 484 insertions(+)
>
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> index 009eb48cd468..c2646d45506a 100644
> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> @@ -183,6 +183,279 @@ GhcbSetRegValid (
> Ghcb->SaveArea.ValidBitmap[RegIndex] |= (1 << RegBit);
> }
>
> +/**
> + Return a pointer to the contents of the specified register.
> +
> + Based upon the input register, return a pointer to the registers contents
> + in the x86 processor context.
> +
> + @param[in] Regs x64 processor context
> + @param[in] Register Register to obtain pointer for
> +
> + @return Pointer to the contents of the requested register
> +
> +**/
> +STATIC
> +UINT64 *
> +GetRegisterPointer (
> + IN EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN UINT8 Register
> + )
> +{
> + UINT64 *Reg;
> +
> + switch (Register) {
> + case 0:
> + Reg = &Regs->Rax;
> + break;
> + case 1:
> + Reg = &Regs->Rcx;
> + break;
> + case 2:
> + Reg = &Regs->Rdx;
> + break;
> + case 3:
> + Reg = &Regs->Rbx;
> + break;
> + case 4:
> + Reg = &Regs->Rsp;
> + break;
> + case 5:
> + Reg = &Regs->Rbp;
> + break;
> + case 6:
> + Reg = &Regs->Rsi;
> + break;
> + case 7:
> + Reg = &Regs->Rdi;
> + break;
> + case 8:
> + Reg = &Regs->R8;
> + break;
> + case 9:
> + Reg = &Regs->R9;
> + break;
> + case 10:
> + Reg = &Regs->R10;
> + break;
> + case 11:
> + Reg = &Regs->R11;
> + break;
> + case 12:
> + Reg = &Regs->R12;
> + break;
> + case 13:
> + Reg = &Regs->R13;
> + break;
> + case 14:
> + Reg = &Regs->R14;
> + break;
> + case 15:
> + Reg = &Regs->R15;
> + break;
> + default:
> + Reg = NULL;
> + }
> + ASSERT (Reg != NULL);
> +
> + return Reg;
> +}
> +
> +/**
> + Update the instruction parsing context for displacement bytes.
> +
> + @param[in, out] InstructionData Instruction parsing context
> + @param[in] Size The instruction displacement size
> +
> +**/
> +STATIC
> +VOID
> +UpdateForDisplacement (
> + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData,
> + IN UINTN Size
> + )
> +{
> + InstructionData->DisplacementSize = Size;
> + InstructionData->Immediate += Size;
> + InstructionData->End += Size;
> +}
> +
> +/**
> + Determine if an instruction address if RIP relative.
> +
> + Examine the instruction parsing context to determine if the address offset
> + is relative to the instruction pointer.
> +
> + @param[in] InstructionData Instruction parsing context
> +
> + @retval TRUE Instruction addressing is RIP relative
> + @retval FALSE Instruction addressing is not RIP relative
> +
> +**/
> +STATIC
> +BOOLEAN
> +IsRipRelative (
> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
> +
> + Ext = &InstructionData->Ext;
> +
> + return ((InstructionData->Mode == LongMode64Bit) &&
> + (Ext->ModRm.Mod == 0) &&
> + (Ext->ModRm.Rm == 5) &&
> + (InstructionData->SibPresent == FALSE));
> +}
> +
> +/**
> + Return the effective address of a memory operand.
> +
> + Examine the instruction parsing context to obtain the effective memory
> + address of a memory operand.
> +
> + @param[in] Regs x64 processor context
> + @param[in] InstructionData Instruction parsing context
> +
> + @return The memory operand effective address
> +
> +**/
> +STATIC
> +UINT64
> +GetEffectiveMemoryAddress (
> + IN EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
> + UINT64 EffectiveAddress;
> +
> + Ext = &InstructionData->Ext;
> + EffectiveAddress = 0;
> +
> + if (IsRipRelative (InstructionData)) {
> + //
> + // RIP-relative displacement is a 32-bit signed value
> + //
> + INT32 RipRelative;
> +
> + RipRelative = *(INT32 *) InstructionData->Displacement;
> +
> + UpdateForDisplacement (InstructionData, 4);
> +
> + //
> + // Negative displacement is handled by standard UINT64 wrap-around.
> + //
> + return Regs->Rip + (UINT64) RipRelative;
> + }
> +
> + switch (Ext->ModRm.Mod) {
> + case 1:
> + UpdateForDisplacement (InstructionData, 1);
> + EffectiveAddress += (UINT64) (*(INT8 *) (InstructionData->Displacement));
> + break;
> + case 2:
> + switch (InstructionData->AddrSize) {
> + case Size16Bits:
> + UpdateForDisplacement (InstructionData, 2);
> + EffectiveAddress += (UINT64) (*(INT16 *) (InstructionData->Displacement));
> + break;
> + default:
> + UpdateForDisplacement (InstructionData, 4);
> + EffectiveAddress += (UINT64) (*(INT32 *) (InstructionData->Displacement));
> + break;
> + }
> + break;
> + }
> +
> + if (InstructionData->SibPresent) {
> + INT64 Displacement;
> +
> + if (Ext->Sib.Index != 4) {
> + CopyMem (&Displacement,
> + GetRegisterPointer (Regs, Ext->Sib.Index),
> + sizeof (Displacement));
(1) The indentation is not idiomatic. Please either use the style I
proposed in the v8 review, or the more verbose
CopyMem (
&Displacement,
GetRegisterPointer (Regs, Ext->Sib.Index),
sizeof (Displacement)
);
Anyway, this alone does not justify a v10.
> + Displacement *= (1 << Ext->Sib.Scale);
> +
> + //
> + // Negative displacement is handled by standard UINT64 wrap-around.
> + //
> + EffectiveAddress += (UINT64) Displacement;
> + }
> +
> + if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) {
> + EffectiveAddress += *GetRegisterPointer (Regs, Ext->Sib.Base);
> + } else {
> + UpdateForDisplacement (InstructionData, 4);
> + EffectiveAddress += (UINT64) (*(INT32 *) (InstructionData->Displacement));
> + }
> + } else {
> + EffectiveAddress += *GetRegisterPointer (Regs, Ext->ModRm.Rm);
> + }
> +
> + return EffectiveAddress;
> +}
> +
> +/**
> + Decode a ModRM byte.
> +
> + Examine the instruction parsing context to decode a ModRM byte and the SIB
> + byte, if present.
> +
> + @param[in] Regs x64 processor context
> + @param[in, out] InstructionData Instruction parsing context
> +
> +**/
> +STATIC
> +VOID
> +DecodeModRm (
> + IN EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
> + INSTRUCTION_REX_PREFIX *RexPrefix;
> + INSTRUCTION_MODRM *ModRm;
> + INSTRUCTION_SIB *Sib;
> +
> + RexPrefix = &InstructionData->RexPrefix;
> + Ext = &InstructionData->Ext;
> + ModRm = &InstructionData->ModRm;
> + Sib = &InstructionData->Sib;
> +
> + InstructionData->ModRmPresent = TRUE;
> + ModRm->Uint8 = *(InstructionData->End);
> +
> + InstructionData->Displacement++;
> + InstructionData->Immediate++;
> + InstructionData->End++;
> +
> + Ext->ModRm.Mod = ModRm->Bits.Mod;
> + Ext->ModRm.Reg = (RexPrefix->Bits.BitR << 3) | ModRm->Bits.Reg;
> + Ext->ModRm.Rm = (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm;
> +
> + Ext->RegData = *GetRegisterPointer (Regs, Ext->ModRm.Reg);
> +
> + if (Ext->ModRm.Mod == 3) {
> + Ext->RmData = *GetRegisterPointer (Regs, Ext->ModRm.Rm);
> + } else {
> + if (ModRm->Bits.Rm == 4) {
> + InstructionData->SibPresent = TRUE;
> + Sib->Uint8 = *(InstructionData->End);
> +
> + InstructionData->Displacement++;
> + InstructionData->Immediate++;
> + InstructionData->End++;
> +
> + Ext->Sib.Scale = Sib->Bits.Scale;
> + Ext->Sib.Index = (RexPrefix->Bits.BitX << 3) | Sib->Bits.Index;
> + Ext->Sib.Base = (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base;
> + }
> +
> + Ext->RmData = GetEffectiveMemoryAddress (Regs, InstructionData);
> + }
> +}
> +
> /**
> Decode instruction prefixes.
>
> @@ -374,6 +647,213 @@ UnsupportedExit (
> return Status;
> }
>
> +/**
> + Handle an MMIO event.
> +
> + Use the VMGEXIT instruction to handle either an MMIO read or an MMIO write.
> +
> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
> + Block
> + @param[in, out] Regs x64 processor context
> + @param[in, out] InstructionData Instruction parsing context
> +
> + @return 0 Event handled successfully
> + @return Others New exception value to propagate
> +
> +**/
> +STATIC
> +UINT64
> +MmioExit (
> + IN OUT GHCB *Ghcb,
> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + UINT64 ExitInfo1, ExitInfo2, Status;
> + UINTN Bytes;
> + UINT64 *Register;
> + UINT8 OpCode, SignByte;
> +
> + Bytes = 0;
> +
> + OpCode = *(InstructionData->OpCodes);
> + if (OpCode == TWO_BYTE_OPCODE_ESCAPE) {
> + OpCode = *(InstructionData->OpCodes + 1);
> + }
> +
> + switch (OpCode) {
> + //
> + // MMIO write (MOV reg/memX, regX)
> + //
> + case 0x88:
> + Bytes = 1;
> + //
> + // fall through
> + //
> + case 0x89:
> + DecodeModRm (Regs, InstructionData);
> + Bytes = ((Bytes != 0) ? Bytes :
> + (InstructionData->DataSize == Size16Bits) ? 2 :
> + (InstructionData->DataSize == Size32Bits) ? 4 :
> + (InstructionData->DataSize == Size64Bits) ? 8 :
> + 0);
(2) The final argument "0" should be un-indented ("out-dented"?) by 1
space character.
Address it only if a v10 becomes necessary for a more important reason.
> +
> + if (InstructionData->Ext.ModRm.Mod == 3) {
> + //
> + // NPF on two register operands???
> + //
> + return UnsupportedExit (Ghcb, Regs, InstructionData);
> + }
> +
> + ExitInfo1 = InstructionData->Ext.RmData;
> + ExitInfo2 = Bytes;
> + CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes);
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
> + if (Status != 0) {
> + return Status;
> + }
> + break;
> +
> + //
> + // MMIO write (MOV reg/memX, immX)
> + //
> + case 0xC6:
> + Bytes = 1;
> + //
> + // fall through
> + //
> + case 0xC7:
> + DecodeModRm (Regs, InstructionData);
> + Bytes = ((Bytes != 0) ? Bytes :
> + (InstructionData->DataSize == Size16Bits) ? 2 :
> + (InstructionData->DataSize == Size32Bits) ? 4 :
> + 0);
(3) Same as (2). (No need to repost just because of this.)
> +
> + InstructionData->ImmediateSize = Bytes;
> + InstructionData->End += Bytes;
> +
> + ExitInfo1 = InstructionData->Ext.RmData;
> + ExitInfo2 = Bytes;
> + CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes);
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
> + if (Status != 0) {
> + return Status;
> + }
> + break;
> +
> + //
> + // MMIO read (MOV regX, reg/memX)
> + //
> + case 0x8A:
> + Bytes = 1;
> + //
> + // fall through
> + //
> + case 0x8B:
> + DecodeModRm (Regs, InstructionData);
> + Bytes = ((Bytes != 0) ? Bytes :
> + (InstructionData->DataSize == Size16Bits) ? 2 :
> + (InstructionData->DataSize == Size32Bits) ? 4 :
> + (InstructionData->DataSize == Size64Bits) ? 8 :
> + 0);
(4) Same as (2). (No need to repost just because of this.)
Thank you very much for the updates in this patch!
Acked-by: Laszlo Ersek <lersek@redhat.com>
Laszlo
> + if (InstructionData->Ext.ModRm.Mod == 3) {
> + //
> + // NPF on two register operands???
> + //
> + return UnsupportedExit (Ghcb, Regs, InstructionData);
> + }
> +
> + ExitInfo1 = InstructionData->Ext.RmData;
> + ExitInfo2 = Bytes;
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
> + if (Status != 0) {
> + return Status;
> + }
> +
> + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
> + if (Bytes == 4) {
> + //
> + // Zero-extend for 32-bit operation
> + //
> + *Register = 0;
> + }
> + CopyMem (Register, Ghcb->SharedBuffer, Bytes);
> + break;
> +
> + //
> + // MMIO read w/ zero-extension ((MOVZX regX, reg/memX)
> + //
> + case 0xB6:
> + Bytes = 1;
> + //
> + // fall through
> + //
> + case 0xB7:
> + Bytes = (Bytes != 0) ? Bytes : 2;
> +
> + ExitInfo1 = InstructionData->Ext.RmData;
> + ExitInfo2 = Bytes;
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
> + if (Status != 0) {
> + return Status;
> + }
> +
> + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
> + SetMem (Register, InstructionData->DataSize, 0);
> + CopyMem (Register, Ghcb->SharedBuffer, Bytes);
> + break;
> +
> + //
> + // MMIO read w/ sign-extension (MOVSX regX, reg/memX)
> + //
> + case 0xBE:
> + Bytes = 1;
> + //
> + // fall through
> + //
> + case 0xBF:
> + Bytes = (Bytes != 0) ? Bytes : 2;
> +
> + ExitInfo1 = InstructionData->Ext.RmData;
> + ExitInfo2 = Bytes;
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
> + if (Status != 0) {
> + return Status;
> + }
> +
> + if (Bytes == 1) {
> + UINT8 *Data = (UINT8 *) Ghcb->SharedBuffer;
> +
> + SignByte = ((*Data & BIT7) != 0) ? 0xFF : 0x00;
> + } else {
> + UINT16 *Data = (UINT16 *) Ghcb->SharedBuffer;
> +
> + SignByte = ((*Data & BIT15) != 0) ? 0xFF : 0x00;
> + }
> +
> + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
> + SetMem (Register, InstructionData->DataSize, SignByte);
> + CopyMem (Register, Ghcb->SharedBuffer, Bytes);
> + break;
> +
> + default:
> + Status = GP_EXCEPTION;
> + ASSERT (FALSE);
> + }
> +
> + return Status;
> +}
> +
> /**
> Handle an MSR event.
>
> @@ -770,6 +1250,10 @@ VmgExitHandleVc (
> NaeExit = MsrExit;
> break;
>
> + case SVM_EXIT_NPF:
> + NaeExit = MmioExit;
> + break;
> +
> default:
> NaeExit = UnsupportedExit;
> }
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO)
2020-06-11 8:30 ` Laszlo Ersek
@ 2020-06-11 15:09 ` Lendacky, Thomas
0 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-11 15:09 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 6/11/20 3:30 AM, Laszlo Ersek wrote:
> On 06/05/20 15:27, Tom Lendacky wrote:
>> 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%7C54ee9d68728e43f1e0b608d80de1bb4c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274610447371952&sdata=4c9uyhXu269S2d9EPt%2Bt45eNMVipU8YDicGK24LOtUk%3D&reserved=0
>>
>> Under SEV-ES, a NPF intercept for an NPT entry with a reserved bit set
>> generates a #VC exception. This condition is assumed to be an MMIO access.
>> VMGEXIT must be used to allow the hypervisor to handle this intercept.
>>
>> Add support to construct the required GHCB values to support a NPF NAE
>> event for MMIO. Parse the instruction that generated the #VC exception,
>> setting the required register values in the GHCB and creating the proper
>> SW_EXIT_INFO1, SW_EXITINFO2 and SW_SCRATCH values in the GHCB.
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 484 ++++++++++++++++++++
>> 1 file changed, 484 insertions(+)
>>
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> index 009eb48cd468..c2646d45506a 100644
>> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> @@ -183,6 +183,279 @@ GhcbSetRegValid (
>> Ghcb->SaveArea.ValidBitmap[RegIndex] |= (1 << RegBit);
>> }
>>
>> +/**
>> + Return a pointer to the contents of the specified register.
>> +
>> + Based upon the input register, return a pointer to the registers contents
>> + in the x86 processor context.
>> +
>> + @param[in] Regs x64 processor context
>> + @param[in] Register Register to obtain pointer for
>> +
>> + @return Pointer to the contents of the requested register
>> +
>> +**/
>> +STATIC
>> +UINT64 *
>> +GetRegisterPointer (
>> + IN EFI_SYSTEM_CONTEXT_X64 *Regs,
>> + IN UINT8 Register
>> + )
>> +{
>> + UINT64 *Reg;
>> +
>> + switch (Register) {
>> + case 0:
>> + Reg = &Regs->Rax;
>> + break;
>> + case 1:
>> + Reg = &Regs->Rcx;
>> + break;
>> + case 2:
>> + Reg = &Regs->Rdx;
>> + break;
>> + case 3:
>> + Reg = &Regs->Rbx;
>> + break;
>> + case 4:
>> + Reg = &Regs->Rsp;
>> + break;
>> + case 5:
>> + Reg = &Regs->Rbp;
>> + break;
>> + case 6:
>> + Reg = &Regs->Rsi;
>> + break;
>> + case 7:
>> + Reg = &Regs->Rdi;
>> + break;
>> + case 8:
>> + Reg = &Regs->R8;
>> + break;
>> + case 9:
>> + Reg = &Regs->R9;
>> + break;
>> + case 10:
>> + Reg = &Regs->R10;
>> + break;
>> + case 11:
>> + Reg = &Regs->R11;
>> + break;
>> + case 12:
>> + Reg = &Regs->R12;
>> + break;
>> + case 13:
>> + Reg = &Regs->R13;
>> + break;
>> + case 14:
>> + Reg = &Regs->R14;
>> + break;
>> + case 15:
>> + Reg = &Regs->R15;
>> + break;
>> + default:
>> + Reg = NULL;
>> + }
>> + ASSERT (Reg != NULL);
>> +
>> + return Reg;
>> +}
>> +
>> +/**
>> + Update the instruction parsing context for displacement bytes.
>> +
>> + @param[in, out] InstructionData Instruction parsing context
>> + @param[in] Size The instruction displacement size
>> +
>> +**/
>> +STATIC
>> +VOID
>> +UpdateForDisplacement (
>> + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData,
>> + IN UINTN Size
>> + )
>> +{
>> + InstructionData->DisplacementSize = Size;
>> + InstructionData->Immediate += Size;
>> + InstructionData->End += Size;
>> +}
>> +
>> +/**
>> + Determine if an instruction address if RIP relative.
>> +
>> + Examine the instruction parsing context to determine if the address offset
>> + is relative to the instruction pointer.
>> +
>> + @param[in] InstructionData Instruction parsing context
>> +
>> + @retval TRUE Instruction addressing is RIP relative
>> + @retval FALSE Instruction addressing is not RIP relative
>> +
>> +**/
>> +STATIC
>> +BOOLEAN
>> +IsRipRelative (
>> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
>> + )
>> +{
>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>> +
>> + Ext = &InstructionData->Ext;
>> +
>> + return ((InstructionData->Mode == LongMode64Bit) &&
>> + (Ext->ModRm.Mod == 0) &&
>> + (Ext->ModRm.Rm == 5) &&
>> + (InstructionData->SibPresent == FALSE));
>> +}
>> +
>> +/**
>> + Return the effective address of a memory operand.
>> +
>> + Examine the instruction parsing context to obtain the effective memory
>> + address of a memory operand.
>> +
>> + @param[in] Regs x64 processor context
>> + @param[in] InstructionData Instruction parsing context
>> +
>> + @return The memory operand effective address
>> +
>> +**/
>> +STATIC
>> +UINT64
>> +GetEffectiveMemoryAddress (
>> + IN EFI_SYSTEM_CONTEXT_X64 *Regs,
>> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
>> + )
>> +{
>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>> + UINT64 EffectiveAddress;
>> +
>> + Ext = &InstructionData->Ext;
>> + EffectiveAddress = 0;
>> +
>> + if (IsRipRelative (InstructionData)) {
>> + //
>> + // RIP-relative displacement is a 32-bit signed value
>> + //
>> + INT32 RipRelative;
>> +
>> + RipRelative = *(INT32 *) InstructionData->Displacement;
>> +
>> + UpdateForDisplacement (InstructionData, 4);
>> +
>> + //
>> + // Negative displacement is handled by standard UINT64 wrap-around.
>> + //
>> + return Regs->Rip + (UINT64) RipRelative;
>> + }
>> +
>> + switch (Ext->ModRm.Mod) {
>> + case 1:
>> + UpdateForDisplacement (InstructionData, 1);
>> + EffectiveAddress += (UINT64) (*(INT8 *) (InstructionData->Displacement));
>> + break;
>> + case 2:
>> + switch (InstructionData->AddrSize) {
>> + case Size16Bits:
>> + UpdateForDisplacement (InstructionData, 2);
>> + EffectiveAddress += (UINT64) (*(INT16 *) (InstructionData->Displacement));
>> + break;
>> + default:
>> + UpdateForDisplacement (InstructionData, 4);
>> + EffectiveAddress += (UINT64) (*(INT32 *) (InstructionData->Displacement));
>> + break;
>> + }
>> + break;
>> + }
>> +
>> + if (InstructionData->SibPresent) {
>> + INT64 Displacement;
>> +
>> + if (Ext->Sib.Index != 4) {
>> + CopyMem (&Displacement,
>> + GetRegisterPointer (Regs, Ext->Sib.Index),
>> + sizeof (Displacement));
>
> (1) The indentation is not idiomatic. Please either use the style I
> proposed in the v8 review, or the more verbose
>
> CopyMem (
> &Displacement,
> GetRegisterPointer (Regs, Ext->Sib.Index),
> sizeof (Displacement)
> );
>
> Anyway, this alone does not justify a v10.
This is what happens when I switch back and forth between coding
standards, sorry. If there's a v10, this and the ones below will be fixed.
Thanks!
Tom
>
>> + Displacement *= (1 << Ext->Sib.Scale);
>> +
>> + //
>> + // Negative displacement is handled by standard UINT64 wrap-around.
>> + //
>> + EffectiveAddress += (UINT64) Displacement;
>> + }
>> +
>> + if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) {
>> + EffectiveAddress += *GetRegisterPointer (Regs, Ext->Sib.Base);
>> + } else {
>> + UpdateForDisplacement (InstructionData, 4);
>> + EffectiveAddress += (UINT64) (*(INT32 *) (InstructionData->Displacement));
>> + }
>> + } else {
>> + EffectiveAddress += *GetRegisterPointer (Regs, Ext->ModRm.Rm);
>> + }
>> +
>> + return EffectiveAddress;
>> +}
>> +
>> +/**
>> + Decode a ModRM byte.
>> +
>> + Examine the instruction parsing context to decode a ModRM byte and the SIB
>> + byte, if present.
>> +
>> + @param[in] Regs x64 processor context
>> + @param[in, out] InstructionData Instruction parsing context
>> +
>> +**/
>> +STATIC
>> +VOID
>> +DecodeModRm (
>> + IN EFI_SYSTEM_CONTEXT_X64 *Regs,
>> + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
>> + )
>> +{
>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>> + INSTRUCTION_REX_PREFIX *RexPrefix;
>> + INSTRUCTION_MODRM *ModRm;
>> + INSTRUCTION_SIB *Sib;
>> +
>> + RexPrefix = &InstructionData->RexPrefix;
>> + Ext = &InstructionData->Ext;
>> + ModRm = &InstructionData->ModRm;
>> + Sib = &InstructionData->Sib;
>> +
>> + InstructionData->ModRmPresent = TRUE;
>> + ModRm->Uint8 = *(InstructionData->End);
>> +
>> + InstructionData->Displacement++;
>> + InstructionData->Immediate++;
>> + InstructionData->End++;
>> +
>> + Ext->ModRm.Mod = ModRm->Bits.Mod;
>> + Ext->ModRm.Reg = (RexPrefix->Bits.BitR << 3) | ModRm->Bits.Reg;
>> + Ext->ModRm.Rm = (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm;
>> +
>> + Ext->RegData = *GetRegisterPointer (Regs, Ext->ModRm.Reg);
>> +
>> + if (Ext->ModRm.Mod == 3) {
>> + Ext->RmData = *GetRegisterPointer (Regs, Ext->ModRm.Rm);
>> + } else {
>> + if (ModRm->Bits.Rm == 4) {
>> + InstructionData->SibPresent = TRUE;
>> + Sib->Uint8 = *(InstructionData->End);
>> +
>> + InstructionData->Displacement++;
>> + InstructionData->Immediate++;
>> + InstructionData->End++;
>> +
>> + Ext->Sib.Scale = Sib->Bits.Scale;
>> + Ext->Sib.Index = (RexPrefix->Bits.BitX << 3) | Sib->Bits.Index;
>> + Ext->Sib.Base = (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base;
>> + }
>> +
>> + Ext->RmData = GetEffectiveMemoryAddress (Regs, InstructionData);
>> + }
>> +}
>> +
>> /**
>> Decode instruction prefixes.
>>
>> @@ -374,6 +647,213 @@ UnsupportedExit (
>> return Status;
>> }
>>
>> +/**
>> + Handle an MMIO event.
>> +
>> + Use the VMGEXIT instruction to handle either an MMIO read or an MMIO write.
>> +
>> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
>> + Block
>> + @param[in, out] Regs x64 processor context
>> + @param[in, out] InstructionData Instruction parsing context
>> +
>> + @return 0 Event handled successfully
>> + @return Others New exception value to propagate
>> +
>> +**/
>> +STATIC
>> +UINT64
>> +MmioExit (
>> + IN OUT GHCB *Ghcb,
>> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
>> + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData
>> + )
>> +{
>> + UINT64 ExitInfo1, ExitInfo2, Status;
>> + UINTN Bytes;
>> + UINT64 *Register;
>> + UINT8 OpCode, SignByte;
>> +
>> + Bytes = 0;
>> +
>> + OpCode = *(InstructionData->OpCodes);
>> + if (OpCode == TWO_BYTE_OPCODE_ESCAPE) {
>> + OpCode = *(InstructionData->OpCodes + 1);
>> + }
>> +
>> + switch (OpCode) {
>> + //
>> + // MMIO write (MOV reg/memX, regX)
>> + //
>> + case 0x88:
>> + Bytes = 1;
>> + //
>> + // fall through
>> + //
>> + case 0x89:
>> + DecodeModRm (Regs, InstructionData);
>> + Bytes = ((Bytes != 0) ? Bytes :
>> + (InstructionData->DataSize == Size16Bits) ? 2 :
>> + (InstructionData->DataSize == Size32Bits) ? 4 :
>> + (InstructionData->DataSize == Size64Bits) ? 8 :
>> + 0);
>
> (2) The final argument "0" should be un-indented ("out-dented"?) by 1
> space character.
>
> Address it only if a v10 becomes necessary for a more important reason.
>
>> +
>> + if (InstructionData->Ext.ModRm.Mod == 3) {
>> + //
>> + // NPF on two register operands???
>> + //
>> + return UnsupportedExit (Ghcb, Regs, InstructionData);
>> + }
>> +
>> + ExitInfo1 = InstructionData->Ext.RmData;
>> + ExitInfo2 = Bytes;
>> + CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes);
>> +
>> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
>> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
>> + if (Status != 0) {
>> + return Status;
>> + }
>> + break;
>> +
>> + //
>> + // MMIO write (MOV reg/memX, immX)
>> + //
>> + case 0xC6:
>> + Bytes = 1;
>> + //
>> + // fall through
>> + //
>> + case 0xC7:
>> + DecodeModRm (Regs, InstructionData);
>> + Bytes = ((Bytes != 0) ? Bytes :
>> + (InstructionData->DataSize == Size16Bits) ? 2 :
>> + (InstructionData->DataSize == Size32Bits) ? 4 :
>> + 0);
>
> (3) Same as (2). (No need to repost just because of this.)
>
>> +
>> + InstructionData->ImmediateSize = Bytes;
>> + InstructionData->End += Bytes;
>> +
>> + ExitInfo1 = InstructionData->Ext.RmData;
>> + ExitInfo2 = Bytes;
>> + CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes);
>> +
>> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
>> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
>> + if (Status != 0) {
>> + return Status;
>> + }
>> + break;
>> +
>> + //
>> + // MMIO read (MOV regX, reg/memX)
>> + //
>> + case 0x8A:
>> + Bytes = 1;
>> + //
>> + // fall through
>> + //
>> + case 0x8B:
>> + DecodeModRm (Regs, InstructionData);
>> + Bytes = ((Bytes != 0) ? Bytes :
>> + (InstructionData->DataSize == Size16Bits) ? 2 :
>> + (InstructionData->DataSize == Size32Bits) ? 4 :
>> + (InstructionData->DataSize == Size64Bits) ? 8 :
>> + 0);
>
> (4) Same as (2). (No need to repost just because of this.)
>
> Thank you very much for the updates in this patch!
>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
>
> Laszlo
>
>> + if (InstructionData->Ext.ModRm.Mod == 3) {
>> + //
>> + // NPF on two register operands???
>> + //
>> + return UnsupportedExit (Ghcb, Regs, InstructionData);
>> + }
>> +
>> + ExitInfo1 = InstructionData->Ext.RmData;
>> + ExitInfo2 = Bytes;
>> +
>> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
>> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
>> + if (Status != 0) {
>> + return Status;
>> + }
>> +
>> + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
>> + if (Bytes == 4) {
>> + //
>> + // Zero-extend for 32-bit operation
>> + //
>> + *Register = 0;
>> + }
>> + CopyMem (Register, Ghcb->SharedBuffer, Bytes);
>> + break;
>> +
>> + //
>> + // MMIO read w/ zero-extension ((MOVZX regX, reg/memX)
>> + //
>> + case 0xB6:
>> + Bytes = 1;
>> + //
>> + // fall through
>> + //
>> + case 0xB7:
>> + Bytes = (Bytes != 0) ? Bytes : 2;
>> +
>> + ExitInfo1 = InstructionData->Ext.RmData;
>> + ExitInfo2 = Bytes;
>> +
>> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
>> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
>> + if (Status != 0) {
>> + return Status;
>> + }
>> +
>> + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
>> + SetMem (Register, InstructionData->DataSize, 0);
>> + CopyMem (Register, Ghcb->SharedBuffer, Bytes);
>> + break;
>> +
>> + //
>> + // MMIO read w/ sign-extension (MOVSX regX, reg/memX)
>> + //
>> + case 0xBE:
>> + Bytes = 1;
>> + //
>> + // fall through
>> + //
>> + case 0xBF:
>> + Bytes = (Bytes != 0) ? Bytes : 2;
>> +
>> + ExitInfo1 = InstructionData->Ext.RmData;
>> + ExitInfo2 = Bytes;
>> +
>> + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
>> + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
>> + if (Status != 0) {
>> + return Status;
>> + }
>> +
>> + if (Bytes == 1) {
>> + UINT8 *Data = (UINT8 *) Ghcb->SharedBuffer;
>> +
>> + SignByte = ((*Data & BIT7) != 0) ? 0xFF : 0x00;
>> + } else {
>> + UINT16 *Data = (UINT16 *) Ghcb->SharedBuffer;
>> +
>> + SignByte = ((*Data & BIT15) != 0) ? 0xFF : 0x00;
>> + }
>> +
>> + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
>> + SetMem (Register, InstructionData->DataSize, SignByte);
>> + CopyMem (Register, Ghcb->SharedBuffer, Bytes);
>> + break;
>> +
>> + default:
>> + Status = GP_EXCEPTION;
>> + ASSERT (FALSE);
>> + }
>> +
>> + return Status;
>> +}
>> +
>> /**
>> Handle an MSR event.
>>
>> @@ -770,6 +1250,10 @@ VmgExitHandleVc (
>> NaeExit = MsrExit;
>> break;
>>
>> + case SVM_EXIT_NPF:
>> + NaeExit = MmioExit;
>> + break;
>> +
>> default:
>> NaeExit = UnsupportedExit;
>> }
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 18/46] OvmfPkg/VmgExitLib: Add support for WBINVD NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (16 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO) Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 8:33 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 19/46] OvmfPkg/VmgExitLib: Add support for RDTSC " Lendacky, Thomas
` (27 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a WBINVD intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 29 ++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index c2646d45506a..37c15c4f6240 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -854,6 +854,31 @@ MmioExit (
return Status;
}
+/**
+ Handle a WBINVD event.
+
+ Use the VMGEXIT instruction to handle a WBINVD event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+WbinvdExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ return VmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0);
+}
+
/**
Handle an MSR event.
@@ -1250,6 +1275,10 @@ VmgExitHandleVc (
NaeExit = MsrExit;
break;
+ case SVM_EXIT_WBINVD:
+ NaeExit = WbinvdExit;
+ break;
+
case SVM_EXIT_NPF:
NaeExit = MmioExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 18/46] OvmfPkg/VmgExitLib: Add support for WBINVD NAE events
2020-06-05 13:27 ` [PATCH v9 18/46] OvmfPkg/VmgExitLib: Add support for WBINVD NAE events Lendacky, Thomas
@ 2020-06-11 8:33 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 8:33 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a WBINVD intercept generates a #VC exception. VMGEXIT must be
> used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 29 ++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> index c2646d45506a..37c15c4f6240 100644
> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> @@ -854,6 +854,31 @@ MmioExit (
> return Status;
> }
>
> +/**
> + Handle a WBINVD event.
> +
> + Use the VMGEXIT instruction to handle a WBINVD event.
> +
> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
> + Block
> + @param[in, out] Regs x64 processor context
> + @param[in] InstructionData Instruction parsing context
> +
> + @return 0 Event handled successfully
> + @return Others New exception value to propagate
> +
> +**/
> +STATIC
> +UINT64
> +WbinvdExit (
> + IN OUT GHCB *Ghcb,
> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + return VmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0);
> +}
> +
> /**
> Handle an MSR event.
>
> @@ -1250,6 +1275,10 @@ VmgExitHandleVc (
> NaeExit = MsrExit;
> break;
>
> + case SVM_EXIT_WBINVD:
> + NaeExit = WbinvdExit;
> + break;
> +
> case SVM_EXIT_NPF:
> NaeExit = MmioExit;
> break;
>
Looks good, thanks!
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 19/46] OvmfPkg/VmgExitLib: Add support for RDTSC NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (17 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 18/46] OvmfPkg/VmgExitLib: Add support for WBINVD NAE events Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 8:35 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 20/46] OvmfPkg/VmgExitLib: Add support for RDPMC " Lendacky, Thomas
` (26 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a RDTSC intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 43 ++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 37c15c4f6240..7cea2e067688 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -1219,6 +1219,45 @@ CpuidExit (
return 0;
}
+/**
+ Handle a RDTSC event.
+
+ Use the VMGEXIT instruction to handle a RDTSC event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+RdtscExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 Status;
+
+ Status = VmgExit (Ghcb, SVM_EXIT_RDTSC, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+ Regs->Rdx = Ghcb->SaveArea.Rdx;
+
+ return 0;
+}
+
/**
Handle a #VC exception.
@@ -1263,6 +1302,10 @@ VmgExitHandleVc (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SVM_EXIT_RDTSC:
+ NaeExit = RdtscExit;
+ break;
+
case SVM_EXIT_CPUID:
NaeExit = CpuidExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 19/46] OvmfPkg/VmgExitLib: Add support for RDTSC NAE events
2020-06-05 13:27 ` [PATCH v9 19/46] OvmfPkg/VmgExitLib: Add support for RDTSC " Lendacky, Thomas
@ 2020-06-11 8:35 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 8:35 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a RDTSC intercept generates a #VC exception. VMGEXIT must be
> used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 43 ++++++++++++++++++++
> 1 file changed, 43 insertions(+)
My ACK stands, thanks.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 20/46] OvmfPkg/VmgExitLib: Add support for RDPMC NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (18 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 19/46] OvmfPkg/VmgExitLib: Add support for RDTSC " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:05 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 21/46] OvmfPkg/VmgExitLib: Add support for INVD " Lendacky, Thomas
` (25 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a RDPMC intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 46 ++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 7cea2e067688..0dbb10eee85c 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -1219,6 +1219,48 @@ CpuidExit (
return 0;
}
+/**
+ Handle a RDPMC event.
+
+ Use the VMGEXIT instruction to handle a RDPMC event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+RdpmcExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 Status;
+
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_RDPMC, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+ Regs->Rdx = Ghcb->SaveArea.Rdx;
+
+ return 0;
+}
+
/**
Handle a RDTSC event.
@@ -1306,6 +1348,10 @@ VmgExitHandleVc (
NaeExit = RdtscExit;
break;
+ case SVM_EXIT_RDPMC:
+ NaeExit = RdpmcExit;
+ break;
+
case SVM_EXIT_CPUID:
NaeExit = CpuidExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 20/46] OvmfPkg/VmgExitLib: Add support for RDPMC NAE events
2020-06-05 13:27 ` [PATCH v9 20/46] OvmfPkg/VmgExitLib: Add support for RDPMC " Lendacky, Thomas
@ 2020-06-11 9:05 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:05 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a RDPMC intercept generates a #VC exception. VMGEXIT must be
> used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 46 ++++++++++++++++++++
> 1 file changed, 46 insertions(+)
Thanks!
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 21/46] OvmfPkg/VmgExitLib: Add support for INVD NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (19 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 20/46] OvmfPkg/VmgExitLib: Add support for RDPMC " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:06 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 22/46] OvmfPkg/VmgExitLib: Add support for VMMCALL " Lendacky, Thomas
` (24 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a INVD intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 29 ++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 0dbb10eee85c..9419651fea2e 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -1164,6 +1164,31 @@ IoioExit (
return 0;
}
+/**
+ Handle a INVD event.
+
+ Use the VMGEXIT instruction to handle a INVD event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+InvdExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ return VmgExit (Ghcb, SVM_EXIT_INVD, 0, 0);
+}
+
/**
Handle a CPUID event.
@@ -1356,6 +1381,10 @@ VmgExitHandleVc (
NaeExit = CpuidExit;
break;
+ case SVM_EXIT_INVD:
+ NaeExit = InvdExit;
+ break;
+
case SVM_EXIT_IOIO_PROT:
NaeExit = IoioExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 21/46] OvmfPkg/VmgExitLib: Add support for INVD NAE events
2020-06-05 13:27 ` [PATCH v9 21/46] OvmfPkg/VmgExitLib: Add support for INVD " Lendacky, Thomas
@ 2020-06-11 9:06 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:06 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a INVD intercept generates a #VC exception. VMGEXIT must be
> used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 29 ++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> index 0dbb10eee85c..9419651fea2e 100644
> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> @@ -1164,6 +1164,31 @@ IoioExit (
> return 0;
> }
>
> +/**
> + Handle a INVD event.
> +
> + Use the VMGEXIT instruction to handle a INVD event.
> +
> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
> + Block
> + @param[in, out] Regs x64 processor context
> + @param[in] InstructionData Instruction parsing context
> +
> + @return 0 Event handled successfully
> + @return Others New exception value to propagate
> +
> +**/
> +STATIC
> +UINT64
> +InvdExit (
> + IN OUT GHCB *Ghcb,
> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + return VmgExit (Ghcb, SVM_EXIT_INVD, 0, 0);
> +}
> +
> /**
> Handle a CPUID event.
>
> @@ -1356,6 +1381,10 @@ VmgExitHandleVc (
> NaeExit = CpuidExit;
> break;
>
> + case SVM_EXIT_INVD:
> + NaeExit = InvdExit;
> + break;
> +
> case SVM_EXIT_IOIO_PROT:
> NaeExit = IoioExit;
> break;
>
looks good, thanks
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 22/46] OvmfPkg/VmgExitLib: Add support for VMMCALL NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (20 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 21/46] OvmfPkg/VmgExitLib: Add support for INVD " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:08 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP " Lendacky, Thomas
` (23 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a VMMCALL intercept generates a #VC exception. VMGEXIT must
be used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 48 ++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 9419651fea2e..b77821d2f989 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -879,6 +879,50 @@ WbinvdExit (
return VmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0);
}
+/**
+ Handle a VMMCALL event.
+
+ Use the VMGEXIT instruction to handle a VMMCALL event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+VmmCallExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 Status;
+
+ DecodeModRm (Regs, InstructionData);
+
+ Ghcb->SaveArea.Rax = Regs->Rax;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+ Ghcb->SaveArea.Cpl = (UINT8) (Regs->Cs & 0x3);
+ GhcbSetRegValid (Ghcb, GhcbCpl);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+
+ return 0;
+}
+
/**
Handle an MSR event.
@@ -1393,6 +1437,10 @@ VmgExitHandleVc (
NaeExit = MsrExit;
break;
+ case SVM_EXIT_VMMCALL:
+ NaeExit = VmmCallExit;
+ break;
+
case SVM_EXIT_WBINVD:
NaeExit = WbinvdExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 22/46] OvmfPkg/VmgExitLib: Add support for VMMCALL NAE events
2020-06-05 13:27 ` [PATCH v9 22/46] OvmfPkg/VmgExitLib: Add support for VMMCALL " Lendacky, Thomas
@ 2020-06-11 9:08 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:08 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a VMMCALL intercept generates a #VC exception. VMGEXIT must
> be used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 48 ++++++++++++++++++++
> 1 file changed, 48 insertions(+)
looks OK
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (21 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 22/46] OvmfPkg/VmgExitLib: Add support for VMMCALL " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:09 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX " Lendacky, Thomas
` (22 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a RDTSCP intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 47 ++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index b77821d2f989..8c2b34c4a83b 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -879,6 +879,49 @@ WbinvdExit (
return VmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0);
}
+/**
+ Handle a RDTSCP event.
+
+ Use the VMGEXIT instruction to handle a RDTSCP event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+RdtscpExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ UINT64 Status;
+
+ DecodeModRm (Regs, InstructionData);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_RDTSCP, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||
+ !GhcbIsRegValid (Ghcb, GhcbRcx) ||
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+ Regs->Rcx = Ghcb->SaveArea.Rcx;
+ Regs->Rdx = Ghcb->SaveArea.Rdx;
+
+ return 0;
+}
+
/**
Handle a VMMCALL event.
@@ -1441,6 +1484,10 @@ VmgExitHandleVc (
NaeExit = VmmCallExit;
break;
+ case SVM_EXIT_RDTSCP:
+ NaeExit = RdtscpExit;
+ break;
+
case SVM_EXIT_WBINVD:
NaeExit = WbinvdExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP NAE events
2020-06-05 13:27 ` [PATCH v9 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP " Lendacky, Thomas
@ 2020-06-11 9:09 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:09 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a RDTSCP intercept generates a #VC exception. VMGEXIT must be
> used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 47 ++++++++++++++++++++
> 1 file changed, 47 insertions(+)
OK
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (22 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 23/46] OvmfPkg/VmgExitLib: Add support for RDTSCP " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:10 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX " Lendacky, Thomas
` (21 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a MONITOR/MONITORX intercept generates a #VC exception.
VMGEXIT must be used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 38 ++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 8c2b34c4a83b..bb068a45ae00 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -854,6 +854,40 @@ MmioExit (
return Status;
}
+/**
+ Handle a MONITOR event.
+
+ Use the VMGEXIT instruction to handle a MONITOR event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+MonitorExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ DecodeModRm (Regs, InstructionData);
+
+ Ghcb->SaveArea.Rax = Regs->Rax; // Identity mapped, so VA = PA
+ GhcbSetRegValid (Ghcb, GhcbRax);
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+ Ghcb->SaveArea.Rdx = Regs->Rdx;
+ GhcbSetRegValid (Ghcb, GhcbRdx);
+
+ return VmgExit (Ghcb, SVM_EXIT_MONITOR, 0, 0);
+}
+
/**
Handle a WBINVD event.
@@ -1492,6 +1526,10 @@ VmgExitHandleVc (
NaeExit = WbinvdExit;
break;
+ case SVM_EXIT_MONITOR:
+ NaeExit = MonitorExit;
+ break;
+
case SVM_EXIT_NPF:
NaeExit = MmioExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX NAE events
2020-06-05 13:27 ` [PATCH v9 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX " Lendacky, Thomas
@ 2020-06-11 9:10 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:10 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a MONITOR/MONITORX intercept generates a #VC exception.
> VMGEXIT must be used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 38 ++++++++++++++++++++
> 1 file changed, 38 insertions(+)
OK
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (23 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 24/46] OvmfPkg/VmgExitLib: Add support for MONITOR/MONITORX " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:10 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write " Lendacky, Thomas
` (20 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a MWAIT/MWAITX intercept generates a #VC exception.
VMGEXIT must be used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 36 ++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index bb068a45ae00..9d93e30a8ea4 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -854,6 +854,38 @@ MmioExit (
return Status;
}
+/**
+ Handle a MWAIT event.
+
+ Use the VMGEXIT instruction to handle a MWAIT event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+MwaitExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ DecodeModRm (Regs, InstructionData);
+
+ Ghcb->SaveArea.Rax = Regs->Rax;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+
+ return VmgExit (Ghcb, SVM_EXIT_MWAIT, 0, 0);
+}
+
/**
Handle a MONITOR event.
@@ -1530,6 +1562,10 @@ VmgExitHandleVc (
NaeExit = MonitorExit;
break;
+ case SVM_EXIT_MWAIT:
+ NaeExit = MwaitExit;
+ break;
+
case SVM_EXIT_NPF:
NaeExit = MmioExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX NAE events
2020-06-05 13:27 ` [PATCH v9 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX " Lendacky, Thomas
@ 2020-06-11 9:10 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:10 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a MWAIT/MWAITX intercept generates a #VC exception.
> VMGEXIT must be used to allow the hypervisor to handle this intercept.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 36 ++++++++++++++++++++
> 1 file changed, 36 insertions(+)
OK
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write NAE events
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (24 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 25/46] OvmfPkg/VmgExitLib: Add support for MWAIT/MWAITX " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:24 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 27/46] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
` (19 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
The #VC handler must provide special support to the guest for this. On
a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
to notify the hypervisor of the write. However, the #VC handler must
not actually set the value of the DR7 register. On a DR7 read, the #VC
handler must return the cached value of the DR7 register to the guest.
VMGEXIT is not invoked for a DR7 register read.
The caching of the DR7 values will make use of the per-CPU data pages
that are allocated along with the GHCB pages. The per-CPU page for a
vCPU is the page that immediately follows the vCPU's GHCB page. Since
each GHCB page is unique for a vCPU, the page that follows becomes
unique for that vCPU. The SEC phase will reserves an area of memory for
a single GHCB and per-CPU page for use by the BSP. After transitioning
to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
and all APs.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 114 ++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 9d93e30a8ea4..e8f9d3fa01a8 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -126,6 +126,14 @@ UINT64
SEV_ES_INSTRUCTION_DATA *InstructionData
);
+//
+// Per-CPU data mapping structure
+//
+typedef struct {
+ BOOLEAN Dr7Cached;
+ UINT64 Dr7;
+} SEV_ES_PER_CPU_DATA;
+
/**
Checks the GHCB to determine if the specified register has been marked valid.
@@ -1478,6 +1486,104 @@ RdtscExit (
return 0;
}
+/**
+ Handle a DR7 register write event.
+
+ Use the VMGEXIT instruction to handle a DR7 write event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+ @return Others New exception value to propagate
+
+**/
+STATIC
+UINT64
+Dr7WriteExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINT64 *Register;
+ UINT64 Status;
+
+ Ext = &InstructionData->Ext;
+ SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
+
+ DecodeModRm (Regs, InstructionData);
+
+ //
+ // MOV DRn always treats MOD == 3 no matter how encoded
+ //
+ Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
+
+ //
+ // Using a value of 0 for ExitInfo1 means RAX holds the value
+ //
+ Ghcb->SaveArea.Rax = *Register;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+
+ Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
+ if (Status != 0) {
+ return Status;
+ }
+
+ SevEsData->Dr7 = *Register;
+ SevEsData->Dr7Cached = TRUE;
+
+ return 0;
+}
+
+/**
+ Handle a DR7 register read event.
+
+ Use the VMGEXIT instruction to handle a DR7 read event.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
+ Block
+ @param[in, out] Regs x64 processor context
+ @param[in] InstructionData Instruction parsing context
+
+ @return 0 Event handled successfully
+
+**/
+STATIC
+UINT64
+Dr7ReadExit (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_PER_CPU_DATA *SevEsData;
+ UINT64 *Register;
+
+ Ext = &InstructionData->Ext;
+ SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
+
+ DecodeModRm (Regs, InstructionData);
+
+ //
+ // MOV DRn always treats MOD == 3 no matter how encoded
+ //
+ Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
+
+ //
+ // If there is a cached valued for DR7, return that. Otherwise return the
+ // DR7 standard reset value of 0x400 (no debug breakpoints set).
+ //
+ *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : 0x400;
+
+ return 0;
+}
+
/**
Handle a #VC exception.
@@ -1522,6 +1628,14 @@ VmgExitHandleVc (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SVM_EXIT_DR7_READ:
+ NaeExit = Dr7ReadExit;
+ break;
+
+ case SVM_EXIT_DR7_WRITE:
+ NaeExit = Dr7WriteExit;
+ break;
+
case SVM_EXIT_RDTSC:
NaeExit = RdtscExit;
break;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write NAE events
2020-06-05 13:27 ` [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write " Lendacky, Thomas
@ 2020-06-11 9:24 ` Laszlo Ersek
2020-06-11 9:31 ` Laszlo Ersek
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:24 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
> The #VC handler must provide special support to the guest for this. On
> a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
> to notify the hypervisor of the write. However, the #VC handler must
> not actually set the value of the DR7 register. On a DR7 read, the #VC
> handler must return the cached value of the DR7 register to the guest.
> VMGEXIT is not invoked for a DR7 register read.
>
> The caching of the DR7 values will make use of the per-CPU data pages
> that are allocated along with the GHCB pages. The per-CPU page for a
> vCPU is the page that immediately follows the vCPU's GHCB page. Since
> each GHCB page is unique for a vCPU, the page that follows becomes
> unique for that vCPU. The SEC phase will reserves an area of memory for
> a single GHCB and per-CPU page for use by the BSP. After transitioning
> to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
> and all APs.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 114 ++++++++++++++++++++
> 1 file changed, 114 insertions(+)
The patch looks good to me:
Acked-by: Laszlo Ersek <lersek@redhat.com>
Just one question: in the v8 review, I wrote:
"""
With your explanation above, about platform reset, I think I'm happy
with the current handling of "Dr7Cached". So I'd like to leave the
choice to you: please either add the clearing, or document in the commit
message and/or the code that platform reset will not happen. Whichever
you like more.
"""
So what have you chosen ultimately? I haven't found a comment to the
effect of "An SEV-ES guest can't be rebooted/reset without restarting
Qemu" in this patch, in the commit message or in the code. Did you
implement the clearing, in the end? (Sorry if I should have noticed it
already!)
Thanks,
Laszlo
> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> index 9d93e30a8ea4..e8f9d3fa01a8 100644
> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
> @@ -126,6 +126,14 @@ UINT64
> SEV_ES_INSTRUCTION_DATA *InstructionData
> );
>
> +//
> +// Per-CPU data mapping structure
> +//
> +typedef struct {
> + BOOLEAN Dr7Cached;
> + UINT64 Dr7;
> +} SEV_ES_PER_CPU_DATA;
> +
>
> /**
> Checks the GHCB to determine if the specified register has been marked valid.
> @@ -1478,6 +1486,104 @@ RdtscExit (
> return 0;
> }
>
> +/**
> + Handle a DR7 register write event.
> +
> + Use the VMGEXIT instruction to handle a DR7 write event.
> +
> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
> + Block
> + @param[in, out] Regs x64 processor context
> + @param[in] InstructionData Instruction parsing context
> +
> + @return 0 Event handled successfully
> + @return Others New exception value to propagate
> +
> +**/
> +STATIC
> +UINT64
> +Dr7WriteExit (
> + IN OUT GHCB *Ghcb,
> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
> + SEV_ES_PER_CPU_DATA *SevEsData;
> + UINT64 *Register;
> + UINT64 Status;
> +
> + Ext = &InstructionData->Ext;
> + SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
> +
> + DecodeModRm (Regs, InstructionData);
> +
> + //
> + // MOV DRn always treats MOD == 3 no matter how encoded
> + //
> + Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
> +
> + //
> + // Using a value of 0 for ExitInfo1 means RAX holds the value
> + //
> + Ghcb->SaveArea.Rax = *Register;
> + GhcbSetRegValid (Ghcb, GhcbRax);
> +
> + Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
> + if (Status != 0) {
> + return Status;
> + }
> +
> + SevEsData->Dr7 = *Register;
> + SevEsData->Dr7Cached = TRUE;
> +
> + return 0;
> +}
> +
> +/**
> + Handle a DR7 register read event.
> +
> + Use the VMGEXIT instruction to handle a DR7 read event.
> +
> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
> + Block
> + @param[in, out] Regs x64 processor context
> + @param[in] InstructionData Instruction parsing context
> +
> + @return 0 Event handled successfully
> +
> +**/
> +STATIC
> +UINT64
> +Dr7ReadExit (
> + IN OUT GHCB *Ghcb,
> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
> + )
> +{
> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
> + SEV_ES_PER_CPU_DATA *SevEsData;
> + UINT64 *Register;
> +
> + Ext = &InstructionData->Ext;
> + SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
> +
> + DecodeModRm (Regs, InstructionData);
> +
> + //
> + // MOV DRn always treats MOD == 3 no matter how encoded
> + //
> + Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
> +
> + //
> + // If there is a cached valued for DR7, return that. Otherwise return the
> + // DR7 standard reset value of 0x400 (no debug breakpoints set).
> + //
> + *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : 0x400;
> +
> + return 0;
> +}
> +
> /**
> Handle a #VC exception.
>
> @@ -1522,6 +1628,14 @@ VmgExitHandleVc (
>
> ExitCode = Regs->ExceptionData;
> switch (ExitCode) {
> + case SVM_EXIT_DR7_READ:
> + NaeExit = Dr7ReadExit;
> + break;
> +
> + case SVM_EXIT_DR7_WRITE:
> + NaeExit = Dr7WriteExit;
> + break;
> +
> case SVM_EXIT_RDTSC:
> NaeExit = RdtscExit;
> break;
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write NAE events
2020-06-11 9:24 ` Laszlo Ersek
@ 2020-06-11 9:31 ` Laszlo Ersek
2020-06-11 15:16 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:31 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/11/20 11:24, Laszlo Ersek wrote:
> On 06/05/20 15:27, Tom Lendacky wrote:
>> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>>
>> Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
>> The #VC handler must provide special support to the guest for this. On
>> a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
>> to notify the hypervisor of the write. However, the #VC handler must
>> not actually set the value of the DR7 register. On a DR7 read, the #VC
>> handler must return the cached value of the DR7 register to the guest.
>> VMGEXIT is not invoked for a DR7 register read.
>>
>> The caching of the DR7 values will make use of the per-CPU data pages
>> that are allocated along with the GHCB pages. The per-CPU page for a
>> vCPU is the page that immediately follows the vCPU's GHCB page. Since
>> each GHCB page is unique for a vCPU, the page that follows becomes
>> unique for that vCPU. The SEC phase will reserves an area of memory for
>> a single GHCB and per-CPU page for use by the BSP. After transitioning
>> to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
>> and all APs.
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 114 ++++++++++++++++++++
>> 1 file changed, 114 insertions(+)
>
> The patch looks good to me:
>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
>
> Just one question: in the v8 review, I wrote:
>
> """
> With your explanation above, about platform reset, I think I'm happy
> with the current handling of "Dr7Cached". So I'd like to leave the
> choice to you: please either add the clearing, or document in the commit
> message and/or the code that platform reset will not happen. Whichever
> you like more.
> """
>
> So what have you chosen ultimately? I haven't found a comment to the
> effect of "An SEV-ES guest can't be rebooted/reset without restarting
> Qemu" in this patch, in the commit message or in the code. Did you
> implement the clearing, in the end? (Sorry if I should have noticed it
> already!)
If I understand correctly, it's the clearGhcbMemoryLoop part (moved to
the new, correct, location) in patch#29. (For SEC.)
For PEI, we have a ZeroMem() call in patch#31.
I'm happy with those. (Hopefully I understand the code enough to be
*justifiedly* happy. :))
Thanks!
Laszlo
>
>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> index 9d93e30a8ea4..e8f9d3fa01a8 100644
>> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>> @@ -126,6 +126,14 @@ UINT64
>> SEV_ES_INSTRUCTION_DATA *InstructionData
>> );
>>
>> +//
>> +// Per-CPU data mapping structure
>> +//
>> +typedef struct {
>> + BOOLEAN Dr7Cached;
>> + UINT64 Dr7;
>> +} SEV_ES_PER_CPU_DATA;
>> +
>>
>> /**
>> Checks the GHCB to determine if the specified register has been marked valid.
>> @@ -1478,6 +1486,104 @@ RdtscExit (
>> return 0;
>> }
>>
>> +/**
>> + Handle a DR7 register write event.
>> +
>> + Use the VMGEXIT instruction to handle a DR7 write event.
>> +
>> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
>> + Block
>> + @param[in, out] Regs x64 processor context
>> + @param[in] InstructionData Instruction parsing context
>> +
>> + @return 0 Event handled successfully
>> + @return Others New exception value to propagate
>> +
>> +**/
>> +STATIC
>> +UINT64
>> +Dr7WriteExit (
>> + IN OUT GHCB *Ghcb,
>> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
>> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
>> + )
>> +{
>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>> + SEV_ES_PER_CPU_DATA *SevEsData;
>> + UINT64 *Register;
>> + UINT64 Status;
>> +
>> + Ext = &InstructionData->Ext;
>> + SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
>> +
>> + DecodeModRm (Regs, InstructionData);
>> +
>> + //
>> + // MOV DRn always treats MOD == 3 no matter how encoded
>> + //
>> + Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
>> +
>> + //
>> + // Using a value of 0 for ExitInfo1 means RAX holds the value
>> + //
>> + Ghcb->SaveArea.Rax = *Register;
>> + GhcbSetRegValid (Ghcb, GhcbRax);
>> +
>> + Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
>> + if (Status != 0) {
>> + return Status;
>> + }
>> +
>> + SevEsData->Dr7 = *Register;
>> + SevEsData->Dr7Cached = TRUE;
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + Handle a DR7 register read event.
>> +
>> + Use the VMGEXIT instruction to handle a DR7 read event.
>> +
>> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
>> + Block
>> + @param[in, out] Regs x64 processor context
>> + @param[in] InstructionData Instruction parsing context
>> +
>> + @return 0 Event handled successfully
>> +
>> +**/
>> +STATIC
>> +UINT64
>> +Dr7ReadExit (
>> + IN OUT GHCB *Ghcb,
>> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
>> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
>> + )
>> +{
>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>> + SEV_ES_PER_CPU_DATA *SevEsData;
>> + UINT64 *Register;
>> +
>> + Ext = &InstructionData->Ext;
>> + SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
>> +
>> + DecodeModRm (Regs, InstructionData);
>> +
>> + //
>> + // MOV DRn always treats MOD == 3 no matter how encoded
>> + //
>> + Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
>> +
>> + //
>> + // If there is a cached valued for DR7, return that. Otherwise return the
>> + // DR7 standard reset value of 0x400 (no debug breakpoints set).
>> + //
>> + *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : 0x400;
>> +
>> + return 0;
>> +}
>> +
>> /**
>> Handle a #VC exception.
>>
>> @@ -1522,6 +1628,14 @@ VmgExitHandleVc (
>>
>> ExitCode = Regs->ExceptionData;
>> switch (ExitCode) {
>> + case SVM_EXIT_DR7_READ:
>> + NaeExit = Dr7ReadExit;
>> + break;
>> +
>> + case SVM_EXIT_DR7_WRITE:
>> + NaeExit = Dr7WriteExit;
>> + break;
>> +
>> case SVM_EXIT_RDTSC:
>> NaeExit = RdtscExit;
>> break;
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write NAE events
2020-06-11 9:31 ` Laszlo Ersek
@ 2020-06-11 15:16 ` Lendacky, Thomas
0 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-11 15:16 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 6/11/20 4:31 AM, Laszlo Ersek wrote:
> On 06/11/20 11:24, Laszlo Ersek wrote:
>> On 06/05/20 15:27, Tom Lendacky wrote:
>>> 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%7C63ef262427d14f35c62008d80dea363f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274646869954992&sdata=xoYJQgjiyxcaXK46nNrrbx1qEEVnvispzNgtL1%2BYIxg%3D&reserved=0
>>>
>>> Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
>>> The #VC handler must provide special support to the guest for this. On
>>> a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
>>> to notify the hypervisor of the write. However, the #VC handler must
>>> not actually set the value of the DR7 register. On a DR7 read, the #VC
>>> handler must return the cached value of the DR7 register to the guest.
>>> VMGEXIT is not invoked for a DR7 register read.
>>>
>>> The caching of the DR7 values will make use of the per-CPU data pages
>>> that are allocated along with the GHCB pages. The per-CPU page for a
>>> vCPU is the page that immediately follows the vCPU's GHCB page. Since
>>> each GHCB page is unique for a vCPU, the page that follows becomes
>>> unique for that vCPU. The SEC phase will reserves an area of memory for
>>> a single GHCB and per-CPU page for use by the BSP. After transitioning
>>> to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
>>> and all APs.
>>>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>> ---
>>> OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 114 ++++++++++++++++++++
>>> 1 file changed, 114 insertions(+)
>>
>> The patch looks good to me:
>>
>> Acked-by: Laszlo Ersek <lersek@redhat.com>
>>
>> Just one question: in the v8 review, I wrote:
>>
>> """
>> With your explanation above, about platform reset, I think I'm happy
>> with the current handling of "Dr7Cached". So I'd like to leave the
>> choice to you: please either add the clearing, or document in the commit
>> message and/or the code that platform reset will not happen. Whichever
>> you like more.
>> """
>>
>> So what have you chosen ultimately? I haven't found a comment to the
>> effect of "An SEV-ES guest can't be rebooted/reset without restarting
>> Qemu" in this patch, in the commit message or in the code. Did you
>> implement the clearing, in the end? (Sorry if I should have noticed it
>> already!)
>
> If I understand correctly, it's the clearGhcbMemoryLoop part (moved to
> the new, correct, location) in patch#29. (For SEC.)
Yup, that's the SEC one.
>
> For PEI, we have a ZeroMem() call in patch#31.
Yup, right again.
>
> I'm happy with those. (Hopefully I understand the code enough to be
> *justifiedly* happy. :))
Yes, you understand the code very well!
Thanks,
Tom
>
> Thanks!
> Laszlo
>
>>
>>> diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>>> index 9d93e30a8ea4..e8f9d3fa01a8 100644
>>> --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>>> +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
>>> @@ -126,6 +126,14 @@ UINT64
>>> SEV_ES_INSTRUCTION_DATA *InstructionData
>>> );
>>>
>>> +//
>>> +// Per-CPU data mapping structure
>>> +//
>>> +typedef struct {
>>> + BOOLEAN Dr7Cached;
>>> + UINT64 Dr7;
>>> +} SEV_ES_PER_CPU_DATA;
>>> +
>>>
>>> /**
>>> Checks the GHCB to determine if the specified register has been marked valid.
>>> @@ -1478,6 +1486,104 @@ RdtscExit (
>>> return 0;
>>> }
>>>
>>> +/**
>>> + Handle a DR7 register write event.
>>> +
>>> + Use the VMGEXIT instruction to handle a DR7 write event.
>>> +
>>> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
>>> + Block
>>> + @param[in, out] Regs x64 processor context
>>> + @param[in] InstructionData Instruction parsing context
>>> +
>>> + @return 0 Event handled successfully
>>> + @return Others New exception value to propagate
>>> +
>>> +**/
>>> +STATIC
>>> +UINT64
>>> +Dr7WriteExit (
>>> + IN OUT GHCB *Ghcb,
>>> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
>>> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
>>> + )
>>> +{
>>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>>> + SEV_ES_PER_CPU_DATA *SevEsData;
>>> + UINT64 *Register;
>>> + UINT64 Status;
>>> +
>>> + Ext = &InstructionData->Ext;
>>> + SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
>>> +
>>> + DecodeModRm (Regs, InstructionData);
>>> +
>>> + //
>>> + // MOV DRn always treats MOD == 3 no matter how encoded
>>> + //
>>> + Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
>>> +
>>> + //
>>> + // Using a value of 0 for ExitInfo1 means RAX holds the value
>>> + //
>>> + Ghcb->SaveArea.Rax = *Register;
>>> + GhcbSetRegValid (Ghcb, GhcbRax);
>>> +
>>> + Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
>>> + if (Status != 0) {
>>> + return Status;
>>> + }
>>> +
>>> + SevEsData->Dr7 = *Register;
>>> + SevEsData->Dr7Cached = TRUE;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +/**
>>> + Handle a DR7 register read event.
>>> +
>>> + Use the VMGEXIT instruction to handle a DR7 read event.
>>> +
>>> + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication
>>> + Block
>>> + @param[in, out] Regs x64 processor context
>>> + @param[in] InstructionData Instruction parsing context
>>> +
>>> + @return 0 Event handled successfully
>>> +
>>> +**/
>>> +STATIC
>>> +UINT64
>>> +Dr7ReadExit (
>>> + IN OUT GHCB *Ghcb,
>>> + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,
>>> + IN SEV_ES_INSTRUCTION_DATA *InstructionData
>>> + )
>>> +{
>>> + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
>>> + SEV_ES_PER_CPU_DATA *SevEsData;
>>> + UINT64 *Register;
>>> +
>>> + Ext = &InstructionData->Ext;
>>> + SevEsData = (SEV_ES_PER_CPU_DATA *) (Ghcb + 1);
>>> +
>>> + DecodeModRm (Regs, InstructionData);
>>> +
>>> + //
>>> + // MOV DRn always treats MOD == 3 no matter how encoded
>>> + //
>>> + Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);
>>> +
>>> + //
>>> + // If there is a cached valued for DR7, return that. Otherwise return the
>>> + // DR7 standard reset value of 0x400 (no debug breakpoints set).
>>> + //
>>> + *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : 0x400;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> /**
>>> Handle a #VC exception.
>>>
>>> @@ -1522,6 +1628,14 @@ VmgExitHandleVc (
>>>
>>> ExitCode = Regs->ExceptionData;
>>> switch (ExitCode) {
>>> + case SVM_EXIT_DR7_READ:
>>> + NaeExit = Dr7ReadExit;
>>> + break;
>>> +
>>> + case SVM_EXIT_DR7_WRITE:
>>> + NaeExit = Dr7WriteExit;
>>> + break;
>>> +
>>> case SVM_EXIT_RDTSC:
>>> NaeExit = RdtscExit;
>>> break;
>>>
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 27/46] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (25 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 26/46] OvmfPkg/VmgExitLib: Add support for DR7 Read/Write " Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 28/46] OvmfPkg: Add support to perform SEV-ES initialization Lendacky, Thomas
` (18 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Create a function that can be used to determine if the VM is running
as an SEV-ES guest.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++
OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c | 75 +++++++++++++-------
2 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 64dd6977b0f8..a50a0de9c870 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -13,6 +13,18 @@
#include <Base.h>
+/**
+ Returns a boolean to indicate whether SEV-ES is enabled
+
+ @retval TRUE SEV-ES is enabled
+ @retval FALSE SEV-ES is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsIsEnabled (
+ VOID
+ );
+
/**
Returns a boolean to indicate whether SEV is enabled
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c
index 96a66e373f11..3301c5c2862f 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/MemEncryptSevLibInternal.c
@@ -20,19 +20,17 @@
#include <Uefi/UefiBaseType.h>
STATIC BOOLEAN mSevStatus = FALSE;
+STATIC BOOLEAN mSevEsStatus = FALSE;
STATIC BOOLEAN mSevStatusChecked = FALSE;
/**
+ Reads and sets the status of SEV features
- Returns a boolean to indicate whether SEV is enabled
-
- @retval TRUE SEV is enabled
- @retval FALSE SEV is not enabled
**/
STATIC
-BOOLEAN
+VOID
EFIAPI
-InternalMemEncryptSevIsEnabled (
+InternalMemEncryptSevStatus (
VOID
)
{
@@ -56,32 +54,55 @@ InternalMemEncryptSevIsEnabled (
//
Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);
if (Msr.Bits.SevBit) {
- return TRUE;
+ mSevStatus = TRUE;
+ }
+
+ //
+ // Check MSR_0xC0010131 Bit 1 (Sev-Es Enabled)
+ //
+ if (Msr.Bits.SevEsBit) {
+ mSevEsStatus = TRUE;
}
}
}
- return FALSE;
-}
-
-/**
- Returns a boolean to indicate whether SEV is enabled
-
- @retval TRUE SEV is enabled
- @retval FALSE SEV is not enabled
-**/
-BOOLEAN
-EFIAPI
-MemEncryptSevIsEnabled (
- VOID
- )
-{
- if (mSevStatusChecked) {
- return mSevStatus;
- }
-
- mSevStatus = InternalMemEncryptSevIsEnabled();
mSevStatusChecked = TRUE;
+}
+
+/**
+ Returns a boolean to indicate whether SEV-ES is enabled
+
+ @retval TRUE SEV-ES is enabled
+ @retval FALSE SEV-ES is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsIsEnabled (
+ VOID
+ )
+{
+ if (!mSevStatusChecked) {
+ InternalMemEncryptSevStatus ();
+ }
+
+ return mSevEsStatus;
+}
+
+/**
+ Returns a boolean to indicate whether SEV is enabled
+
+ @retval TRUE SEV is enabled
+ @retval FALSE SEV is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevIsEnabled (
+ VOID
+ )
+{
+ if (!mSevStatusChecked) {
+ InternalMemEncryptSevStatus ();
+ }
return mSevStatus;
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 28/46] OvmfPkg: Add support to perform SEV-ES initialization
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (26 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 27/46] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
` (17 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
When SEV-ES is enabled, then SEV is also enabled. Add support to the SEV
initialization function to also check for SEV-ES being enabled, and if
enabled, set the SEV-ES enabled PCD (PcdSevEsIsEnabled).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/OvmfPkgIa32.dsc | 3 +++
OvmfPkg/OvmfPkgIa32X64.dsc | 3 +++
OvmfPkg/OvmfPkgX64.dsc | 3 +++
OvmfPkg/PlatformPei/PlatformPei.inf | 1 +
OvmfPkg/PlatformPei/AmdSev.c | 26 ++++++++++++++++++++
5 files changed, 36 insertions(+)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 7d7297aa1cd8..b289260c1f2d 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -610,6 +610,9 @@ [PcdsDynamicDefault]
# Set memory encryption mask
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+ # Set SEV-ES defaults
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
+
!if $(SMM_REQUIRE) == TRUE
gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index c85e988372ec..00faf5036670 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -622,6 +622,9 @@ [PcdsDynamicDefault]
# Set memory encryption mask
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+ # Set SEV-ES defaults
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
+
!if $(SMM_REQUIRE) == TRUE
gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index b5f3859420d0..58671828c5fe 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -620,6 +620,9 @@ [PcdsDynamicDefault]
# Set memory encryption mask
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
+ # Set SEV-ES defaults
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
+
!if $(SMM_REQUIRE) == TRUE
gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index ff397b3ee9d7..00feb96c9308 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -103,6 +103,7 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
[FixedPcd]
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index e484f4b311fe..4dc5340caa7a 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -21,6 +21,27 @@
#include "Platform.h"
+/**
+
+ Initialize SEV-ES support if running as an SEV-ES guest.
+
+ **/
+STATIC
+VOID
+AmdSevEsInitialize (
+ VOID
+ )
+{
+ RETURN_STATUS PcdStatus;
+
+ if (!MemEncryptSevEsIsEnabled ()) {
+ return;
+ }
+
+ PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
+ ASSERT_RETURN_ERROR (PcdStatus);
+}
+
/**
Function checks if SEV support is available, if present then it sets
@@ -103,4 +124,9 @@ AmdSevInitialize (
);
}
}
+
+ //
+ // Check and perform SEV-ES initialization if required.
+ //
+ AmdSevEsInitialize ();
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (27 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 28/46] OvmfPkg: Add support to perform SEV-ES initialization Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 9:56 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 30/46] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported Lendacky, Thomas
` (16 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
A GHCB page is needed during the Sec phase, so this new page must be
created. Since the #VC exception handler routines assume that a per-CPU
variable area is immediately after the GHCB, this per-CPU variable area
must also be created. Since the GHCB must be marked as an un-encrypted,
or shared, page, an additional pagetable page is required to break down
the 2MB region where the GHCB page lives into 4K pagetable entries.
Create a new entry in the OVMF memory layout for the new page table
page and for the SEC GHCB and per-CPU variable pages. After breaking down
the 2MB page, update the GHCB page table entry to remove the encryption
mask.
The GHCB page will be used by the SEC #VC exception handler. The #VC
exception handler will fill in the necessary fields of the GHCB and exit
to the hypervisor using the VMGEXIT instruction. The hypervisor then
accesses the GHCB in order to perform the requested function.
Four new fixed PCDs are needed to support the SEC GHCB page:
- PcdOvmfSecGhcbBase UINT32 value that is the base address of the
GHCB used during the SEC phase.
- PcdOvmfSecGhcbSize UINT32 value that is the size, in bytes, of the
GHCB area used during the SEC phase.
- PcdOvmfSecGhcbPageTableBase UINT32 value that is address of a page
table page used to break down the 2MB page into
512 4K pages.
- PcdOvmfSecGhcbPageTableSize UINT32 value that is the size, in bytes,
of the page table page.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/OvmfPkg.dec | 9 +++
OvmfPkg/OvmfPkgX64.fdf | 6 ++
OvmfPkg/ResetVector/ResetVector.inf | 5 ++
OvmfPkg/ResetVector/Ia32/PageTables64.asm | 76 ++++++++++++++++++++
OvmfPkg/ResetVector/ResetVector.nasmb | 17 +++++
5 files changed, 113 insertions(+)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 65bb2bb0eb4c..02ad62ed9f43 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -281,6 +281,15 @@ [PcdsFixedAtBuild]
## Number of page frames to use for storing grant table entries.
gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33
+ ## Specify the extra page table needed to mark the GHCB as unencrypted.
+ # The value should be a multiple of 4KB for each.
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x3a
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3b
+
+ ## The base address of the SEC GHCB page used by SEV-ES.
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x3c
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x3d
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index bfca1eff9e83..88b1e880e603 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -76,6 +76,12 @@ [FD.MEMFD]
0x007000|0x001000
gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+0x008000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+
+0x009000|0x002000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+
0x010000|0x010000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index b0ddfa5832a2..483fd90fe785 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -26,6 +26,7 @@ [Sources]
[Packages]
OvmfPkg/OvmfPkg.dec
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
[BuildOptions]
@@ -33,5 +34,9 @@ [BuildOptions]
*_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index abad009f20f5..9f86ddf6f08f 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -21,6 +21,11 @@ BITS 32
%define PAGE_2M_MBO 0x080
%define PAGE_2M_PAT 0x01000
+%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
+ PAGE_DIRTY + \
+ PAGE_READ_WRITE + \
+ PAGE_PRESENT)
+
%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
PAGE_ACCESSED + \
PAGE_DIRTY + \
@@ -75,6 +80,37 @@ NoSev:
SevExit:
OneTimeCallRet CheckSevFeature
+; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
+; is enabled.
+;
+; Modified: EAX, EBX, ECX
+;
+; If SEV-ES is enabled then EAX will be non-zero.
+; If SEV-ES is disabled then EAX will be zero.
+;
+CheckSevEsFeature:
+ xor eax, eax
+
+ ; SEV-ES can't be enabled if SEV isn't, so first check the encryption
+ ; mask.
+ test edx, edx
+ jz NoSevEs
+
+ ; Save current value of encryption mask
+ mov ebx, edx
+
+ ; Check if SEV-ES is enabled
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+ and eax, 2
+
+ ; Restore encryption mask
+ mov edx, ebx
+
+NoSevEs:
+ OneTimeCallRet CheckSevEsFeature
+
;
; Modified: EAX, EBX, ECX, EDX
;
@@ -139,6 +175,46 @@ pageTableEntriesLoop:
mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
loop pageTableEntriesLoop
+ OneTimeCall CheckSevEsFeature
+ test eax, eax
+ jz SetCr3
+
+ ;
+ ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.
+ ; This requires the 2MB page for this range be broken down into 512 4KB
+ ; pages. All will be marked encrypted, except for the GHCB.
+ ;
+ mov ecx, (GHCB_BASE >> 21)
+ mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR
+ mov [ecx * 8 + PT_ADDR (0x2000)], eax
+
+ ;
+ ; Page Table Entries (512 * 4KB entries => 2MB)
+ ;
+ mov ecx, 512
+pageTableEntries4kLoop:
+ mov eax, ecx
+ dec eax
+ shl eax, 12
+ add eax, GHCB_BASE & 0xFFE0_0000
+ add eax, PAGE_4K_PDE_ATTR
+ mov [ecx * 8 + GHCB_PT_ADDR - 8], eax
+ mov [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx
+ loop pageTableEntries4kLoop
+
+ ;
+ ; Clear the encryption bit from the GHCB entry
+ ;
+ mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12
+ mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0
+
+ mov ecx, GHCB_SIZE / 4
+ xor eax, eax
+clearGhcbMemoryLoop:
+ mov dword[ecx * 4 + GHCB_BASE - 4], eax
+ loop clearGhcbMemoryLoop
+
+SetCr3:
;
; Set CR3 now that the paging structures are available
;
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 75cfe16654b1..bfb77e439105 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -53,8 +53,25 @@
%error "This implementation inherently depends on PcdOvmfSecPageTablesSize"
%endif
+ %if (FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) != 0x1000)
+ %error "This implementation inherently depends on PcdOvmfSecGhcbPageTableSize"
+ %endif
+
+ %if (FixedPcdGet32 (PcdOvmfSecGhcbSize) != 0x2000)
+ %error "This implementation inherently depends on PcdOvmfSecGhcbSize"
+ %endif
+
+ %if ((FixedPcdGet32 (PcdOvmfSecGhcbBase) >> 21) != \
+ ((FixedPcdGet32 (PcdOvmfSecGhcbBase) + FixedPcdGet32 (PcdOvmfSecGhcbSize) - 1) >> 21))
+ %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary"
+ %endif
+
%define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
%include "Ia32/Flat32ToFlat64.asm"
+
+ %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
+ %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
+ %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
%include "Ia32/PageTables64.asm"
%endif
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase
2020-06-05 13:27 ` [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
@ 2020-06-11 9:56 ` Laszlo Ersek
2020-06-11 15:25 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 9:56 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
Hi Tom,
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> A GHCB page is needed during the Sec phase, so this new page must be
> created. Since the #VC exception handler routines assume that a per-CPU
> variable area is immediately after the GHCB, this per-CPU variable area
> must also be created. Since the GHCB must be marked as an un-encrypted,
> or shared, page, an additional pagetable page is required to break down
> the 2MB region where the GHCB page lives into 4K pagetable entries.
>
> Create a new entry in the OVMF memory layout for the new page table
> page and for the SEC GHCB and per-CPU variable pages. After breaking down
> the 2MB page, update the GHCB page table entry to remove the encryption
> mask.
>
> The GHCB page will be used by the SEC #VC exception handler. The #VC
> exception handler will fill in the necessary fields of the GHCB and exit
> to the hypervisor using the VMGEXIT instruction. The hypervisor then
> accesses the GHCB in order to perform the requested function.
>
> Four new fixed PCDs are needed to support the SEC GHCB page:
> - PcdOvmfSecGhcbBase UINT32 value that is the base address of the
> GHCB used during the SEC phase.
> - PcdOvmfSecGhcbSize UINT32 value that is the size, in bytes, of the
> GHCB area used during the SEC phase.
>
> - PcdOvmfSecGhcbPageTableBase UINT32 value that is address of a page
> table page used to break down the 2MB page into
> 512 4K pages.
> - PcdOvmfSecGhcbPageTableSize UINT32 value that is the size, in bytes,
> of the page table page.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/OvmfPkg.dec | 9 +++
> OvmfPkg/OvmfPkgX64.fdf | 6 ++
> OvmfPkg/ResetVector/ResetVector.inf | 5 ++
> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 76 ++++++++++++++++++++
> OvmfPkg/ResetVector/ResetVector.nasmb | 17 +++++
> 5 files changed, 113 insertions(+)
>
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 65bb2bb0eb4c..02ad62ed9f43 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -281,6 +281,15 @@ [PcdsFixedAtBuild]
> ## Number of page frames to use for storing grant table entries.
> gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33
>
> + ## Specify the extra page table needed to mark the GHCB as unencrypted.
> + # The value should be a multiple of 4KB for each.
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x3a
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3b
> +
> + ## The base address of the SEC GHCB page used by SEV-ES.
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x3c
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x3d
> +
> [PcdsDynamic, PcdsDynamicEx]
> gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
> index bfca1eff9e83..88b1e880e603 100644
> --- a/OvmfPkg/OvmfPkgX64.fdf
> +++ b/OvmfPkg/OvmfPkgX64.fdf
> @@ -76,6 +76,12 @@ [FD.MEMFD]
> 0x007000|0x001000
> gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
>
> +0x008000|0x001000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
> +
> +0x009000|0x002000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
> +
> 0x010000|0x010000
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>
> diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
> index b0ddfa5832a2..483fd90fe785 100644
> --- a/OvmfPkg/ResetVector/ResetVector.inf
> +++ b/OvmfPkg/ResetVector/ResetVector.inf
> @@ -26,6 +26,7 @@ [Sources]
> [Packages]
> OvmfPkg/OvmfPkg.dec
> MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> UefiCpuPkg/UefiCpuPkg.dec
>
> [BuildOptions]
> @@ -33,5 +34,9 @@ [BuildOptions]
> *_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
>
> [Pcd]
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> index abad009f20f5..9f86ddf6f08f 100644
> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
> @@ -21,6 +21,11 @@ BITS 32
> %define PAGE_2M_MBO 0x080
> %define PAGE_2M_PAT 0x01000
>
> +%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
> + PAGE_DIRTY + \
> + PAGE_READ_WRITE + \
> + PAGE_PRESENT)
> +
> %define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
> PAGE_ACCESSED + \
> PAGE_DIRTY + \
> @@ -75,6 +80,37 @@ NoSev:
> SevExit:
> OneTimeCallRet CheckSevFeature
>
> +; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
> +; is enabled.
> +;
> +; Modified: EAX, EBX, ECX
> +;
> +; If SEV-ES is enabled then EAX will be non-zero.
> +; If SEV-ES is disabled then EAX will be zero.
> +;
> +CheckSevEsFeature:
> + xor eax, eax
> +
> + ; SEV-ES can't be enabled if SEV isn't, so first check the encryption
> + ; mask.
> + test edx, edx
> + jz NoSevEs
> +
> + ; Save current value of encryption mask
> + mov ebx, edx
> +
> + ; Check if SEV-ES is enabled
> + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
> + mov ecx, 0xc0010131
> + rdmsr
> + and eax, 2
> +
> + ; Restore encryption mask
> + mov edx, ebx
> +
> +NoSevEs:
> + OneTimeCallRet CheckSevEsFeature
> +
> ;
> ; Modified: EAX, EBX, ECX, EDX
> ;
> @@ -139,6 +175,46 @@ pageTableEntriesLoop:
> mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
> loop pageTableEntriesLoop
>
> + OneTimeCall CheckSevEsFeature
> + test eax, eax
> + jz SetCr3
> +
> + ;
> + ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.
> + ; This requires the 2MB page for this range be broken down into 512 4KB
> + ; pages. All will be marked encrypted, except for the GHCB.
> + ;
> + mov ecx, (GHCB_BASE >> 21)
> + mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR
> + mov [ecx * 8 + PT_ADDR (0x2000)], eax
> +
> + ;
> + ; Page Table Entries (512 * 4KB entries => 2MB)
> + ;
> + mov ecx, 512
> +pageTableEntries4kLoop:
> + mov eax, ecx
> + dec eax
> + shl eax, 12
> + add eax, GHCB_BASE & 0xFFE0_0000
> + add eax, PAGE_4K_PDE_ATTR
> + mov [ecx * 8 + GHCB_PT_ADDR - 8], eax
> + mov [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx
> + loop pageTableEntries4kLoop
> +
> + ;
> + ; Clear the encryption bit from the GHCB entry
> + ;
> + mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12
> + mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0
> +
> + mov ecx, GHCB_SIZE / 4
> + xor eax, eax
> +clearGhcbMemoryLoop:
> + mov dword[ecx * 4 + GHCB_BASE - 4], eax
> + loop clearGhcbMemoryLoop
> +
This patch is now identical to v6, modulo some (welcome) commit message
updates, and the PCD token value updates. Therefore, we can re-add my:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
from v6.
However, in the v8 discussion of the patch, you indicated that the
clearing loop had been in the wrong spot (in v6) -- it should have been
placed after the CR3 setting, apparently:
http://mid.mail-archive.com/1177217e-74d9-ddb5-fd38-c5ffb02de3f3@amd.com
https://edk2.groups.io/g/devel/message/60284
But in this update (v9), the clearing loop has not been moved, relative
to v6; it's been re-instated in the same spot. (IIUC.)
So what is the right spot for the clearing loop after all?
Thanks,
Laszlo
> +SetCr3:
> ;
> ; Set CR3 now that the paging structures are available
> ;
> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
> index 75cfe16654b1..bfb77e439105 100644
> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
> @@ -53,8 +53,25 @@
> %error "This implementation inherently depends on PcdOvmfSecPageTablesSize"
> %endif
>
> + %if (FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) != 0x1000)
> + %error "This implementation inherently depends on PcdOvmfSecGhcbPageTableSize"
> + %endif
> +
> + %if (FixedPcdGet32 (PcdOvmfSecGhcbSize) != 0x2000)
> + %error "This implementation inherently depends on PcdOvmfSecGhcbSize"
> + %endif
> +
> + %if ((FixedPcdGet32 (PcdOvmfSecGhcbBase) >> 21) != \
> + ((FixedPcdGet32 (PcdOvmfSecGhcbBase) + FixedPcdGet32 (PcdOvmfSecGhcbSize) - 1) >> 21))
> + %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary"
> + %endif
> +
> %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
> %include "Ia32/Flat32ToFlat64.asm"
> +
> + %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
> + %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
> + %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
> %include "Ia32/PageTables64.asm"
> %endif
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase
2020-06-11 9:56 ` Laszlo Ersek
@ 2020-06-11 15:25 ` Lendacky, Thomas
2020-06-11 17:52 ` Laszlo Ersek
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-11 15:25 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 6/11/20 4:56 AM, Laszlo Ersek wrote:
> Hi Tom,
>
> On 06/05/20 15:27, Tom Lendacky wrote:
>> 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%7C38f855613c974b9f23e108d80dedc415%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274662138263584&sdata=QfK586IbkE%2B8zOieyD4nQJ6ALvmzE2YlsNOnB9o7lpQ%3D&reserved=0
>>
>> A GHCB page is needed during the Sec phase, so this new page must be
>> created. Since the #VC exception handler routines assume that a per-CPU
>> variable area is immediately after the GHCB, this per-CPU variable area
>> must also be created. Since the GHCB must be marked as an un-encrypted,
>> or shared, page, an additional pagetable page is required to break down
>> the 2MB region where the GHCB page lives into 4K pagetable entries.
>>
>> Create a new entry in the OVMF memory layout for the new page table
>> page and for the SEC GHCB and per-CPU variable pages. After breaking down
>> the 2MB page, update the GHCB page table entry to remove the encryption
>> mask.
>>
>> The GHCB page will be used by the SEC #VC exception handler. The #VC
>> exception handler will fill in the necessary fields of the GHCB and exit
>> to the hypervisor using the VMGEXIT instruction. The hypervisor then
>> accesses the GHCB in order to perform the requested function.
>>
>> Four new fixed PCDs are needed to support the SEC GHCB page:
>> - PcdOvmfSecGhcbBase UINT32 value that is the base address of the
>> GHCB used during the SEC phase.
>> - PcdOvmfSecGhcbSize UINT32 value that is the size, in bytes, of the
>> GHCB area used during the SEC phase.
>>
>> - PcdOvmfSecGhcbPageTableBase UINT32 value that is address of a page
>> table page used to break down the 2MB page into
>> 512 4K pages.
>> - PcdOvmfSecGhcbPageTableSize UINT32 value that is the size, in bytes,
>> of the page table page.
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/OvmfPkg.dec | 9 +++
>> OvmfPkg/OvmfPkgX64.fdf | 6 ++
>> OvmfPkg/ResetVector/ResetVector.inf | 5 ++
>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 76 ++++++++++++++++++++
>> OvmfPkg/ResetVector/ResetVector.nasmb | 17 +++++
>> 5 files changed, 113 insertions(+)
>>
>> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
>> index 65bb2bb0eb4c..02ad62ed9f43 100644
>> --- a/OvmfPkg/OvmfPkg.dec
>> +++ b/OvmfPkg/OvmfPkg.dec
>> @@ -281,6 +281,15 @@ [PcdsFixedAtBuild]
>> ## Number of page frames to use for storing grant table entries.
>> gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33
>>
>> + ## Specify the extra page table needed to mark the GHCB as unencrypted.
>> + # The value should be a multiple of 4KB for each.
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x3a
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3b
>> +
>> + ## The base address of the SEC GHCB page used by SEV-ES.
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x3c
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x3d
>> +
>> [PcdsDynamic, PcdsDynamicEx]
>> gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>> index bfca1eff9e83..88b1e880e603 100644
>> --- a/OvmfPkg/OvmfPkgX64.fdf
>> +++ b/OvmfPkg/OvmfPkgX64.fdf
>> @@ -76,6 +76,12 @@ [FD.MEMFD]
>> 0x007000|0x001000
>> gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
>>
>> +0x008000|0x001000
>> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
>> +
>> +0x009000|0x002000
>> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
>> +
>> 0x010000|0x010000
>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>>
>> diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
>> index b0ddfa5832a2..483fd90fe785 100644
>> --- a/OvmfPkg/ResetVector/ResetVector.inf
>> +++ b/OvmfPkg/ResetVector/ResetVector.inf
>> @@ -26,6 +26,7 @@ [Sources]
>> [Packages]
>> OvmfPkg/OvmfPkg.dec
>> MdePkg/MdePkg.dec
>> + MdeModulePkg/MdeModulePkg.dec
>> UefiCpuPkg/UefiCpuPkg.dec
>>
>> [BuildOptions]
>> @@ -33,5 +34,9 @@ [BuildOptions]
>> *_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
>>
>> [Pcd]
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> index abad009f20f5..9f86ddf6f08f 100644
>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>> @@ -21,6 +21,11 @@ BITS 32
>> %define PAGE_2M_MBO 0x080
>> %define PAGE_2M_PAT 0x01000
>>
>> +%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
>> + PAGE_DIRTY + \
>> + PAGE_READ_WRITE + \
>> + PAGE_PRESENT)
>> +
>> %define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
>> PAGE_ACCESSED + \
>> PAGE_DIRTY + \
>> @@ -75,6 +80,37 @@ NoSev:
>> SevExit:
>> OneTimeCallRet CheckSevFeature
>>
>> +; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
>> +; is enabled.
>> +;
>> +; Modified: EAX, EBX, ECX
>> +;
>> +; If SEV-ES is enabled then EAX will be non-zero.
>> +; If SEV-ES is disabled then EAX will be zero.
>> +;
>> +CheckSevEsFeature:
>> + xor eax, eax
>> +
>> + ; SEV-ES can't be enabled if SEV isn't, so first check the encryption
>> + ; mask.
>> + test edx, edx
>> + jz NoSevEs
>> +
>> + ; Save current value of encryption mask
>> + mov ebx, edx
>> +
>> + ; Check if SEV-ES is enabled
>> + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
>> + mov ecx, 0xc0010131
>> + rdmsr
>> + and eax, 2
>> +
>> + ; Restore encryption mask
>> + mov edx, ebx
>> +
>> +NoSevEs:
>> + OneTimeCallRet CheckSevEsFeature
>> +
>> ;
>> ; Modified: EAX, EBX, ECX, EDX
>> ;
>> @@ -139,6 +175,46 @@ pageTableEntriesLoop:
>> mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
>> loop pageTableEntriesLoop
>>
>> + OneTimeCall CheckSevEsFeature
>> + test eax, eax
>> + jz SetCr3
>> +
>> + ;
>> + ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.
>> + ; This requires the 2MB page for this range be broken down into 512 4KB
>> + ; pages. All will be marked encrypted, except for the GHCB.
>> + ;
>> + mov ecx, (GHCB_BASE >> 21)
>> + mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR
>> + mov [ecx * 8 + PT_ADDR (0x2000)], eax
>> +
>> + ;
>> + ; Page Table Entries (512 * 4KB entries => 2MB)
>> + ;
>> + mov ecx, 512
>> +pageTableEntries4kLoop:
>> + mov eax, ecx
>> + dec eax
>> + shl eax, 12
>> + add eax, GHCB_BASE & 0xFFE0_0000
>> + add eax, PAGE_4K_PDE_ATTR
>> + mov [ecx * 8 + GHCB_PT_ADDR - 8], eax
>> + mov [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx
>> + loop pageTableEntries4kLoop
>> +
>> + ;
>> + ; Clear the encryption bit from the GHCB entry
>> + ;
>> + mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12
>> + mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0
>> +
>> + mov ecx, GHCB_SIZE / 4
>> + xor eax, eax
>> +clearGhcbMemoryLoop:
>> + mov dword[ecx * 4 + GHCB_BASE - 4], eax
>> + loop clearGhcbMemoryLoop
>> +
>
> This patch is now identical to v6, modulo some (welcome) commit message
> updates, and the PCD token value updates. Therefore, we can re-add my:
>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>
> from v6.
>
> However, in the v8 discussion of the patch, you indicated that the
> clearing loop had been in the wrong spot (in v6) -- it should have been
> placed after the CR3 setting, apparently:
>
> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F1177217e-74d9-ddb5-fd38-c5ffb02de3f3%40amd.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7C38f855613c974b9f23e108d80dedc415%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274662138263584&sdata=lV7Ou2%2F047pUTLpbutO3sXwCoxDWQrKIPDXhRh9aOqM%3D&reserved=0
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60284&data=02%7C01%7Cthomas.lendacky%40amd.com%7C38f855613c974b9f23e108d80dedc415%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274662138263584&sdata=GwGXhDbxjafSgjYLP8kDI7fvkijNKgZBbgqgVuVVHOM%3D&reserved=0
>
> But in this update (v9), the clearing loop has not been moved, relative
> to v6; it's been re-instated in the same spot. (IIUC.)
>
> So what is the right spot for the clearing loop after all?
After looking at the code more closely, even though the CR3 register is
loaded, paging hasn't been enabled (it's enabled on return from this
function/area). So the location of the clearing loop didn't matter in the
end and so I left it in the original location. The net effect is that
per-CPU page for the DR7 value still ends up zeroed out.
Thanks,
Tom
>
> Thanks,
> Laszlo
>
>> +SetCr3:
>> ;
>> ; Set CR3 now that the paging structures are available
>> ;
>> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
>> index 75cfe16654b1..bfb77e439105 100644
>> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
>> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
>> @@ -53,8 +53,25 @@
>> %error "This implementation inherently depends on PcdOvmfSecPageTablesSize"
>> %endif
>>
>> + %if (FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) != 0x1000)
>> + %error "This implementation inherently depends on PcdOvmfSecGhcbPageTableSize"
>> + %endif
>> +
>> + %if (FixedPcdGet32 (PcdOvmfSecGhcbSize) != 0x2000)
>> + %error "This implementation inherently depends on PcdOvmfSecGhcbSize"
>> + %endif
>> +
>> + %if ((FixedPcdGet32 (PcdOvmfSecGhcbBase) >> 21) != \
>> + ((FixedPcdGet32 (PcdOvmfSecGhcbBase) + FixedPcdGet32 (PcdOvmfSecGhcbSize) - 1) >> 21))
>> + %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary"
>> + %endif
>> +
>> %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
>> %include "Ia32/Flat32ToFlat64.asm"
>> +
>> + %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
>> + %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
>> + %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
>> %include "Ia32/PageTables64.asm"
>> %endif
>>
>>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase
2020-06-11 15:25 ` Lendacky, Thomas
@ 2020-06-11 17:52 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 17:52 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/11/20 17:25, Tom Lendacky wrote:
> On 6/11/20 4:56 AM, Laszlo Ersek wrote:
>> Hi Tom,
>>
>> On 06/05/20 15:27, Tom Lendacky wrote:
>>> 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%7C38f855613c974b9f23e108d80dedc415%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274662138263584&sdata=QfK586IbkE%2B8zOieyD4nQJ6ALvmzE2YlsNOnB9o7lpQ%3D&reserved=0
>>>
>>>
>>> A GHCB page is needed during the Sec phase, so this new page must be
>>> created. Since the #VC exception handler routines assume that a per-CPU
>>> variable area is immediately after the GHCB, this per-CPU variable area
>>> must also be created. Since the GHCB must be marked as an un-encrypted,
>>> or shared, page, an additional pagetable page is required to break down
>>> the 2MB region where the GHCB page lives into 4K pagetable entries.
>>>
>>> Create a new entry in the OVMF memory layout for the new page table
>>> page and for the SEC GHCB and per-CPU variable pages. After breaking
>>> down
>>> the 2MB page, update the GHCB page table entry to remove the encryption
>>> mask.
>>>
>>> The GHCB page will be used by the SEC #VC exception handler. The #VC
>>> exception handler will fill in the necessary fields of the GHCB and exit
>>> to the hypervisor using the VMGEXIT instruction. The hypervisor then
>>> accesses the GHCB in order to perform the requested function.
>>>
>>> Four new fixed PCDs are needed to support the SEC GHCB page:
>>> - PcdOvmfSecGhcbBase UINT32 value that is the base address of the
>>> GHCB used during the SEC phase.
>>> - PcdOvmfSecGhcbSize UINT32 value that is the size, in bytes, of the
>>> GHCB area used during the SEC phase.
>>>
>>> - PcdOvmfSecGhcbPageTableBase UINT32 value that is address of a page
>>> table page used to break down the 2MB page into
>>> 512 4K pages.
>>> - PcdOvmfSecGhcbPageTableSize UINT32 value that is the size, in
>>> bytes,
>>> of the page table page.
>>>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>> ---
>>> OvmfPkg/OvmfPkg.dec | 9 +++
>>> OvmfPkg/OvmfPkgX64.fdf | 6 ++
>>> OvmfPkg/ResetVector/ResetVector.inf | 5 ++
>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 76 ++++++++++++++++++++
>>> OvmfPkg/ResetVector/ResetVector.nasmb | 17 +++++
>>> 5 files changed, 113 insertions(+)
>>>
>>> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
>>> index 65bb2bb0eb4c..02ad62ed9f43 100644
>>> --- a/OvmfPkg/OvmfPkg.dec
>>> +++ b/OvmfPkg/OvmfPkg.dec
>>> @@ -281,6 +281,15 @@ [PcdsFixedAtBuild]
>>> ## Number of page frames to use for storing grant table entries.
>>> gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33
>>> + ## Specify the extra page table needed to mark the GHCB as
>>> unencrypted.
>>> + # The value should be a multiple of 4KB for each.
>>> +
>>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x3a
>>> +
>>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3b
>>> +
>>> + ## The base address of the SEC GHCB page used by SEV-ES.
>>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x3c
>>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x3d
>>> +
>>> [PcdsDynamic, PcdsDynamicEx]
>>> gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
>>>
>>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
>>>
>>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>>> index bfca1eff9e83..88b1e880e603 100644
>>> --- a/OvmfPkg/OvmfPkgX64.fdf
>>> +++ b/OvmfPkg/OvmfPkgX64.fdf
>>> @@ -76,6 +76,12 @@ [FD.MEMFD]
>>> 0x007000|0x001000
>>>
>>> gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
>>>
>>> +0x008000|0x001000
>>> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
>>>
>>> +
>>> +0x009000|0x002000
>>> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
>>>
>>> +
>>> 0x010000|0x010000
>>>
>>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
>>>
>>> diff --git a/OvmfPkg/ResetVector/ResetVector.inf
>>> b/OvmfPkg/ResetVector/ResetVector.inf
>>> index b0ddfa5832a2..483fd90fe785 100644
>>> --- a/OvmfPkg/ResetVector/ResetVector.inf
>>> +++ b/OvmfPkg/ResetVector/ResetVector.inf
>>> @@ -26,6 +26,7 @@ [Sources]
>>> [Packages]
>>> OvmfPkg/OvmfPkg.dec
>>> MdePkg/MdePkg.dec
>>> + MdeModulePkg/MdeModulePkg.dec
>>> UefiCpuPkg/UefiCpuPkg.dec
>>> [BuildOptions]
>>> @@ -33,5 +34,9 @@ [BuildOptions]
>>> *_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
>>> [Pcd]
>>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
>>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
>>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
>>> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
>>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
>>> gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
>>> diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> index abad009f20f5..9f86ddf6f08f 100644
>>> --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>> @@ -21,6 +21,11 @@ BITS 32
>>> %define PAGE_2M_MBO 0x080
>>> %define PAGE_2M_PAT 0x01000
>>> +%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \
>>> + PAGE_DIRTY + \
>>> + PAGE_READ_WRITE + \
>>> + PAGE_PRESENT)
>>> +
>>> %define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
>>> PAGE_ACCESSED + \
>>> PAGE_DIRTY + \
>>> @@ -75,6 +80,37 @@ NoSev:
>>> SevExit:
>>> OneTimeCallRet CheckSevFeature
>>> +; Check if Secure Encrypted Virtualization - Encrypted State
>>> (SEV-ES) feature
>>> +; is enabled.
>>> +;
>>> +; Modified: EAX, EBX, ECX
>>> +;
>>> +; If SEV-ES is enabled then EAX will be non-zero.
>>> +; If SEV-ES is disabled then EAX will be zero.
>>> +;
>>> +CheckSevEsFeature:
>>> + xor eax, eax
>>> +
>>> + ; SEV-ES can't be enabled if SEV isn't, so first check the
>>> encryption
>>> + ; mask.
>>> + test edx, edx
>>> + jz NoSevEs
>>> +
>>> + ; Save current value of encryption mask
>>> + mov ebx, edx
>>> +
>>> + ; Check if SEV-ES is enabled
>>> + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
>>> + mov ecx, 0xc0010131
>>> + rdmsr
>>> + and eax, 2
>>> +
>>> + ; Restore encryption mask
>>> + mov edx, ebx
>>> +
>>> +NoSevEs:
>>> + OneTimeCallRet CheckSevEsFeature
>>> +
>>> ;
>>> ; Modified: EAX, EBX, ECX, EDX
>>> ;
>>> @@ -139,6 +175,46 @@ pageTableEntriesLoop:
>>> mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
>>> loop pageTableEntriesLoop
>>> + OneTimeCall CheckSevEsFeature
>>> + test eax, eax
>>> + jz SetCr3
>>> +
>>> + ;
>>> + ; The initial GHCB will live at GHCB_BASE and needs to be
>>> un-encrypted.
>>> + ; This requires the 2MB page for this range be broken down into
>>> 512 4KB
>>> + ; pages. All will be marked encrypted, except for the GHCB.
>>> + ;
>>> + mov ecx, (GHCB_BASE >> 21)
>>> + mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR
>>> + mov [ecx * 8 + PT_ADDR (0x2000)], eax
>>> +
>>> + ;
>>> + ; Page Table Entries (512 * 4KB entries => 2MB)
>>> + ;
>>> + mov ecx, 512
>>> +pageTableEntries4kLoop:
>>> + mov eax, ecx
>>> + dec eax
>>> + shl eax, 12
>>> + add eax, GHCB_BASE & 0xFFE0_0000
>>> + add eax, PAGE_4K_PDE_ATTR
>>> + mov [ecx * 8 + GHCB_PT_ADDR - 8], eax
>>> + mov [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx
>>> + loop pageTableEntries4kLoop
>>> +
>>> + ;
>>> + ; Clear the encryption bit from the GHCB entry
>>> + ;
>>> + mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12
>>> + mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0
>>> +
>>> + mov ecx, GHCB_SIZE / 4
>>> + xor eax, eax
>>> +clearGhcbMemoryLoop:
>>> + mov dword[ecx * 4 + GHCB_BASE - 4], eax
>>> + loop clearGhcbMemoryLoop
>>> +
>>
>> This patch is now identical to v6, modulo some (welcome) commit message
>> updates, and the PCD token value updates. Therefore, we can re-add my:
>>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>
>> from v6.
>>
>> However, in the v8 discussion of the patch, you indicated that the
>> clearing loop had been in the wrong spot (in v6) -- it should have been
>> placed after the CR3 setting, apparently:
>>
>> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmid.mail-archive.com%2F1177217e-74d9-ddb5-fd38-c5ffb02de3f3%40amd.com&data=02%7C01%7Cthomas.lendacky%40amd.com%7C38f855613c974b9f23e108d80dedc415%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274662138263584&sdata=lV7Ou2%2F047pUTLpbutO3sXwCoxDWQrKIPDXhRh9aOqM%3D&reserved=0
>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60284&data=02%7C01%7Cthomas.lendacky%40amd.com%7C38f855613c974b9f23e108d80dedc415%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274662138263584&sdata=GwGXhDbxjafSgjYLP8kDI7fvkijNKgZBbgqgVuVVHOM%3D&reserved=0
>>
>>
>> But in this update (v9), the clearing loop has not been moved, relative
>> to v6; it's been re-instated in the same spot. (IIUC.)
>>
>> So what is the right spot for the clearing loop after all?
>
> After looking at the code more closely, even though the CR3 register is
> loaded, paging hasn't been enabled (it's enabled on return from this
> function/area). So the location of the clearing loop didn't matter in
> the end and so I left it in the original location. The net effect is
> that per-CPU page for the DR7 value still ends up zeroed out.
Awesome, thanks!
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 30/46] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (28 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 29/46] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 31/46] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
` (15 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni,
Anthony Perard, Julien Grall
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Protect the memory used by an SEV-ES guest when S3 is supported. This
includes the page table used to break down the 2MB page that contains
the GHCB so that it can be marked un-encrypted, as well as the GHCB
area.
Regarding the lifecycle of the GHCB-related memory areas:
PcdOvmfSecGhcbPageTableBase
PcdOvmfSecGhcbBase
(a) when and how it is initialized after first boot of the VM
If SEV-ES is enabled, the GHCB-related areas are initialized during
the SEC phase [OvmfPkg/ResetVector/Ia32/PageTables64.asm].
(b) how it is protected from memory allocations during DXE
If S3 and SEV-ES are enabled, then InitializeRamRegions()
[OvmfPkg/PlatformPei/MemDetect.c] protects the ranges with an AcpiNVS
memory allocation HOB, in PEI.
If S3 is disabled, then these ranges are not protected. DXE's own page
tables are first built while still in PEI (see HandOffToDxeCore()
[MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c]). Those tables are
located in permanent PEI memory. After CR3 is switched over to them
(which occurs before jumping to the DXE core entry point), we don't have
to preserve PcdOvmfSecGhcbPageTableBase. PEI switches to GHCB pages in
permanent PEI memory and DXE will use these PEI GHCB pages, so we don't
have to preserve PcdOvmfSecGhcbBase.
(c) how it is protected from the OS
If S3 is enabled, then (b) reserves it from the OS too.
If S3 is disabled, then the range needs no protection.
(d) how it is accessed on the S3 resume path
It is rewritten same as in (a), which is fine because (b) reserved it.
(e) how it is accessed on the warm reset path
It is rewritten same as in (a).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/PlatformPei/PlatformPei.inf | 4 ++++
OvmfPkg/PlatformPei/MemDetect.c | 23 ++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 00feb96c9308..a54d10ba90d5 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -75,6 +75,10 @@ [Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 3b46ea431ade..6b5fee166b5d 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -27,6 +27,7 @@ Module Name:
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/IoLib.h>
+#include <Library/MemEncryptSevLib.h>
#include <Library/PcdLib.h>
#include <Library/PciLib.h>
#include <Library/PeimEntryPoint.h>
@@ -866,6 +867,28 @@ InitializeRamRegions (
(UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),
EfiACPIMemoryNVS
);
+
+ if (MemEncryptSevEsIsEnabled ()) {
+ //
+ // If SEV-ES is enabled, reserve the GHCB-related memory area. This
+ // includes the extra page table used to break down the 2MB page
+ // mapping into 4KB page entries where the GHCB resides and the
+ // GHCB area itself.
+ //
+ // Since this memory range will be used by the Reset Vector on S3
+ // resume, it must be reserved as ACPI NVS.
+ //
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecGhcbPageTableBase),
+ (UINT64)(UINTN) PcdGet32 (PcdOvmfSecGhcbPageTableSize),
+ EfiACPIMemoryNVS
+ );
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecGhcbBase),
+ (UINT64)(UINTN) PcdGet32 (PcdOvmfSecGhcbSize),
+ EfiACPIMemoryNVS
+ );
+ }
#endif
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 31/46] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (29 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 30/46] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 32/46] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
` (14 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Allocate memory for the GHCB pages and the per-CPU variable pages during
SEV initialization for use during Pei and Dxe phases. The GHCB page(s)
must be shared pages, so clear the encryption mask from the current page
table entries. Upon successful allocation, set the GHCB PCDs (PcdGhcbBase
and PcdGhcbSize).
The per-CPU variable page needs to be unique per AP. Using the page after
the GHCB ensures that it is unique per AP. Only the GHCB page is marked as
shared, keeping the per-CPU variable page encyrpted. The same logic is
used in DXE using CreateIdentityMappingPageTables() before switching to
the DXE pagetables.
The GHCB pages (one per vCPU) will be used by the PEI and DXE #VC
exception handlers. The #VC exception handler will fill in the necessary
fields of the GHCB and exit to the hypervisor using the VMGEXIT
instruction. The hypervisor then accesses the GHCB associated with the
vCPU in order to perform the requested function.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/OvmfPkgIa32.dsc | 2 +
OvmfPkg/OvmfPkgIa32X64.dsc | 2 +
OvmfPkg/OvmfPkgX64.dsc | 2 +
OvmfPkg/PlatformPei/PlatformPei.inf | 2 +
OvmfPkg/PlatformPei/AmdSev.c | 45 +++++++++++++++++++-
5 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index b289260c1f2d..f849a7d698cd 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -611,6 +611,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
# Set SEV-ES defaults
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0
gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
!if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 00faf5036670..d1b4ffedc6af 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -623,6 +623,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
# Set SEV-ES defaults
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0
gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
!if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 58671828c5fe..ebc903d922cf 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -621,6 +621,8 @@ [PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0
# Set SEV-ES defaults
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0
gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled|0
!if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index a54d10ba90d5..4742e1bdf42b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -102,6 +102,8 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 4dc5340caa7a..4fd4534cabea 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -10,12 +10,15 @@
// The package level header files this module uses
//
#include <IndustryStandard/Q35MchIch9.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/MemEncryptSevLib.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <PiPei.h>
#include <Register/Amd/Cpuid.h>
+#include <Register/Amd/Msr.h>
#include <Register/Cpuid.h>
#include <Register/Intel/SmramSaveStateMap.h>
@@ -32,7 +35,10 @@ AmdSevEsInitialize (
VOID
)
{
- RETURN_STATUS PcdStatus;
+ VOID *GhcbBase;
+ PHYSICAL_ADDRESS GhcbBasePa;
+ UINTN GhcbPageCount, PageCount;
+ RETURN_STATUS PcdStatus, DecryptStatus;
if (!MemEncryptSevEsIsEnabled ()) {
return;
@@ -40,6 +46,43 @@ AmdSevEsInitialize (
PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
ASSERT_RETURN_ERROR (PcdStatus);
+
+ //
+ // Allocate GHCB and per-CPU variable pages.
+ //
+ GhcbPageCount = mMaxCpuCount * 2;
+ GhcbBase = AllocatePages (GhcbPageCount);
+ ASSERT (GhcbBase != NULL);
+
+ GhcbBasePa = (PHYSICAL_ADDRESS)(UINTN) GhcbBase;
+
+ //
+ // Each vCPU gets two consecutive pages, the first is the GHCB and the
+ // second is the per-CPU variable page. Loop through the allocation and
+ // only clear the encryption mask for the GHCB pages.
+ //
+ for (PageCount = 0; PageCount < GhcbPageCount; PageCount += 2) {
+ DecryptStatus = MemEncryptSevClearPageEncMask (
+ 0,
+ GhcbBasePa + EFI_PAGES_TO_SIZE (PageCount),
+ 1,
+ TRUE
+ );
+ ASSERT_RETURN_ERROR (DecryptStatus);
+ }
+
+ ZeroMem (GhcbBase, EFI_PAGES_TO_SIZE (GhcbPageCount));
+
+ PcdStatus = PcdSet64S (PcdGhcbBase, GhcbBasePa);
+ ASSERT_RETURN_ERROR (PcdStatus);
+ PcdStatus = PcdSet64S (PcdGhcbSize, EFI_PAGES_TO_SIZE (GhcbPageCount));
+ ASSERT_RETURN_ERROR (PcdStatus);
+
+ DEBUG ((DEBUG_INFO,
+ "SEV-ES is enabled, %lu GHCB pages allocated starting at 0x%p\n",
+ (UINT64)GhcbPageCount, GhcbBase));
+
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);
}
/**
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 32/46] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (30 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 31/46] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
` (13 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
The SEV support will clear the C-bit from non-RAM areas. The early GDT
lives in a non-RAM area, so when an exception occurs (like a #VC) the GDT
will be read as un-encrypted even though it is encrypted. This will result
in a failure to be able to handle the exception.
Move the GDT into RAM so it can be accessed without error when running as
an SEV-ES guest.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/PlatformPei/AmdSev.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 4fd4534cabea..a2b38c591236 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -39,6 +39,8 @@ AmdSevEsInitialize (
PHYSICAL_ADDRESS GhcbBasePa;
UINTN GhcbPageCount, PageCount;
RETURN_STATUS PcdStatus, DecryptStatus;
+ IA32_DESCRIPTOR Gdtr;
+ VOID *Gdt;
if (!MemEncryptSevEsIsEnabled ()) {
return;
@@ -83,6 +85,22 @@ AmdSevEsInitialize (
(UINT64)GhcbPageCount, GhcbBase));
AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);
+
+ //
+ // The SEV support will clear the C-bit from non-RAM areas. The early GDT
+ // lives in a non-RAM area, so when an exception occurs (like a #VC) the GDT
+ // will be read as un-encrypted even though it was created before the C-bit
+ // was cleared (encrypted). This will result in a failure to be able to
+ // handle the exception.
+ //
+ AsmReadGdtr (&Gdtr);
+
+ Gdt = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN) Gdtr.Limit + 1));
+ ASSERT (Gdt != NULL);
+
+ CopyMem (Gdt, (VOID *) Gdtr.Base, Gdtr.Limit + 1);
+ Gdtr.Base = (UINTN) Gdt;
+ AsmWriteGdtr (&Gdtr);
}
/**
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (31 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 32/46] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-12 1:03 ` Dong, Eric
2020-06-05 13:27 ` [PATCH v9 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
` (12 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Create an SEV-ES workarea PCD. This PCD will be used for BSP communication
during SEC and for AP startup during PEI and DXE phases, the latter is the
reason for creating it in the UefiCpuPkg.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/UefiCpuPkg.dec | 8 ++++++++
UefiCpuPkg/UefiCpuPkg.uni | 8 ++++++++
2 files changed, 16 insertions(+)
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index cb92f34b6f55..8c614f9b42bd 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -161,6 +161,14 @@ [PcdsFixedAtBuild]
# @Prompt Specify the count of pre allocated SMM MP tokens per chunk.
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk|64|UINT32|0x30002002
+ ## Area of memory where the SEV-ES work area block lives.
+ # @Prompt Configure the SEV-ES work area base
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase|0x0|UINT32|0x30002005
+
+ ## Size of teh area of memory where the SEV-ES work area block lives.
+ # @Prompt Configure the SEV-ES work area base
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize|0x0|UINT32|0x30002006
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
## This value is the CPU Local APIC base address, which aligns the address on a 4-KByte boundary.
# @Prompt Configure base address of CPU Local APIC
diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni
index f4a0c72f6293..219c1963bf08 100644
--- a/UefiCpuPkg/UefiCpuPkg.uni
+++ b/UefiCpuPkg/UefiCpuPkg.uni
@@ -281,3 +281,11 @@
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_PROMPT #language en-US "Specifies whether SEV-ES is enabled"
#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_HELP #language en-US "Set to TRUE when running as an SEV-ES guest, FALSE otherwise."
+
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaBase_PROMPT #language en-US "Specify the address of the SEV-ES work area"
+
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaBase_HELP #language en-US "Specifies the address of the work area used by an SEV-ES guest."
+
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaSize_PROMPT #language en-US "Specify the size of the SEV-ES work area"
+
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaSize_HELP #language en-US "Specifies the size of the work area used by an SEV-ES guest."
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD
2020-06-05 13:27 ` [PATCH v9 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
@ 2020-06-12 1:03 ` Dong, Eric
0 siblings, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-12 1:03 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Reviewed-by: Eric Dong <eric.dong@intel.com>
Thanks,
Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:27 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Create an SEV-ES workarea PCD. This PCD will be used for BSP
> communication
> during SEC and for AP startup during PEI and DXE phases, the latter is the
> reason for creating it in the UefiCpuPkg.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 8 ++++++++
> UefiCpuPkg/UefiCpuPkg.uni | 8 ++++++++
> 2 files changed, 16 insertions(+)
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index cb92f34b6f55..8c614f9b42bd 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -161,6 +161,14 @@ [PcdsFixedAtBuild]
> # @Prompt Specify the count of pre allocated SMM MP tokens per chunk.
>
>
> gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk|64|UI
> NT32|0x30002002
>
>
>
> + ## Area of memory where the SEV-ES work area block lives.
>
> + # @Prompt Configure the SEV-ES work area base
>
> +
> gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase|0x0|UINT32|0x30002
> 005
>
> +
>
> + ## Size of teh area of memory where the SEV-ES work area block lives.
>
> + # @Prompt Configure the SEV-ES work area base
>
> +
> gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize|0x0|UINT32|0x30002
> 006
>
> +
>
> [PcdsFixedAtBuild, PcdsPatchableInModule]
>
> ## This value is the CPU Local APIC base address, which aligns the address
> on a 4-KByte boundary.
>
> # @Prompt Configure base address of CPU Local APIC
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni
> index f4a0c72f6293..219c1963bf08 100644
> --- a/UefiCpuPkg/UefiCpuPkg.uni
> +++ b/UefiCpuPkg/UefiCpuPkg.uni
> @@ -281,3 +281,11 @@
>
>
> #string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_PROMPT
> #language en-US "Specifies whether SEV-ES is enabled"
>
> #string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsIsEnabled_HELP
> #language en-US "Set to TRUE when running as an SEV-ES guest, FALSE
> otherwise."
>
> +
>
> +#string
> STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaBase_PROMPT
> #language en-US "Specify the address of the SEV-ES work area"
>
> +
>
> +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaBase_HELP
> #language en-US "Specifies the address of the work area used by an SEV-ES
> guest."
>
> +
>
> +#string
> STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaSize_PROMPT
> #language en-US "Specify the size of the SEV-ES work area"
>
> +
>
> +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaSize_HELP
> #language en-US "Specifies the size of the work area used by an SEV-ES
> guest."
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (32 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 33/46] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 10:03 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 35/46] OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported Lendacky, Thomas
` (11 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Reserve a fixed area of memory for SEV-ES use and set a fixed PCD,
PcdSevEsWorkAreaBase, to this value.
This area will be used by SEV-ES support for two purposes:
1. Communicating the SEV-ES status during BSP boot to SEC:
Using a byte of memory from the page, the BSP reset vector code can
communicate the SEV-ES status to SEC for use before exception
handling can be enabled in SEC. After SEC, this field is no longer
valid and the standard way of determine if SEV-ES is active should
be used.
2. Establishing an area of memory for AP boot support:
A hypervisor is not allowed to update an SEV-ES guest's register
state, so when booting an SEV-ES guest AP, the hypervisor is not
allowed to set the RIP to the guest requested value. Instead an
SEV-ES AP must be re-directed from within the guest to the actual
requested staring location as specified in the INIT-SIPI-SIPI
sequence.
Use this memory for reset vector code that can be programmed to have
the AP jump to the desired RIP location after starting the AP. This
is required for only the very first AP reset.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
This patch has been reverted to the previous v6 version.
---
OvmfPkg/OvmfPkgX64.fdf | 3 +++
1 file changed, 3 insertions(+)
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 88b1e880e603..8836b30a0cef 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -82,6 +82,9 @@ [FD.MEMFD]
0x009000|0x002000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+0x00B000|0x001000
+gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase|gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize
+
0x010000|0x010000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-06-05 13:27 ` [PATCH v9 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
@ 2020-06-11 10:03 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 10:03 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> Reserve a fixed area of memory for SEV-ES use and set a fixed PCD,
> PcdSevEsWorkAreaBase, to this value.
>
> This area will be used by SEV-ES support for two purposes:
> 1. Communicating the SEV-ES status during BSP boot to SEC:
> Using a byte of memory from the page, the BSP reset vector code can
> communicate the SEV-ES status to SEC for use before exception
> handling can be enabled in SEC. After SEC, this field is no longer
> valid and the standard way of determine if SEV-ES is active should
> be used.
>
> 2. Establishing an area of memory for AP boot support:
> A hypervisor is not allowed to update an SEV-ES guest's register
> state, so when booting an SEV-ES guest AP, the hypervisor is not
> allowed to set the RIP to the guest requested value. Instead an
> SEV-ES AP must be re-directed from within the guest to the actual
> requested staring location as specified in the INIT-SIPI-SIPI
> sequence.
>
> Use this memory for reset vector code that can be programmed to have
> the AP jump to the desired RIP location after starting the AP. This
> is required for only the very first AP reset.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>
> This patch has been reverted to the previous v6 version.
Thanks!
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 35/46] OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (33 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 34/46] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
` (10 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni,
Anthony Perard, Julien Grall
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Protect the SEV-ES work area memory used by an SEV-ES guest.
Regarding the lifecycle of the SEV-ES memory area:
PcdSevEsWorkArea
(a) when and how it is initialized after first boot of the VM
If SEV-ES is enabled, the SEV-ES area is initialized during
the SEC phase [OvmfPkg/ResetVector/Ia32/PageTables64.asm].
(b) how it is protected from memory allocations during DXE
If SEV-ES is enabled, then InitializeRamRegions()
[OvmfPkg/PlatformPei/MemDetect.c] protects the ranges with either
an AcpiNVS (S3 enabled) or BootServicesData (S3 disabled) memory
allocation HOB, in PEI.
(c) how it is protected from the OS
If S3 is enabled, then (b) reserves it from the OS too.
If S3 is disabled, then the range needs no protection.
(d) how it is accessed on the S3 resume path
It is rewritten same as in (a), which is fine because (b) reserved it.
(e) how it is accessed on the warm reset path
It is rewritten same as in (a).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
OvmfPkg/PlatformPei/MemDetect.c | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 4742e1bdf42b..c53be2f4925c 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -118,6 +118,8 @@ [FixedPcd]
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaSize
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 6b5fee166b5d..ffbbef891a11 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -940,5 +940,25 @@ InitializeRamRegions (
);
}
}
+
+#ifdef MDE_CPU_X64
+ if (MemEncryptSevEsIsEnabled ()) {
+ //
+ // If SEV-ES is enabled, reserve the SEV-ES work area.
+ //
+ // Since this memory range will be used by the Reset Vector on S3
+ // resume, it must be reserved as ACPI NVS.
+ //
+ // If S3 is unsupported, then various drivers might still write to the
+ // work area. We ought to prevent DXE from serving allocation requests
+ // such that they would overlap the work area.
+ //
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdSevEsWorkAreaBase),
+ (UINT64)(UINTN) FixedPcdGet32 (PcdSevEsWorkAreaSize),
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+ }
+#endif
}
}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (34 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 35/46] OvmfPkg/PlatformPei: Reserve SEV-ES work area if S3 is supported Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-11 10:08 ` Laszlo Ersek
2020-06-05 13:27 ` [PATCH v9 37/46] OvmfPkg/Sec: Add #VC exception handling for Sec phase Lendacky, Thomas
` (9 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
During BSP startup, the reset vector code will issue a CPUID instruction
while in 32-bit mode. When running as an SEV-ES guest, this will trigger
a #VC exception.
Add exception handling support to the early reset vector code to catch
these exceptions. Also, since the guest is in 32-bit mode at this point,
writes to the GHCB will be encrypted and thus not able to be read by the
hypervisor, so use the GHCB CPUID request/response protocol to obtain the
requested CPUID function values and provide these to the guest.
The exception handling support is active during the SEV check and uses the
OVMF temporary RAM space for a stack. After the SEV check is complete, the
exception handling support is removed and the stack pointer cleared.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
This patch has been reverted to the previous v6 version.
---
OvmfPkg/ResetVector/ResetVector.inf | 3 +
OvmfPkg/ResetVector/Ia32/PageTables64.asm | 275 +++++++++++++++++++-
OvmfPkg/ResetVector/ResetVector.nasmb | 2 +
3 files changed, 277 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf
index 483fd90fe785..a53ae6c194ae 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -34,9 +34,12 @@ [BuildOptions]
*_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 9f86ddf6f08f..7c72128a84d6 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -36,13 +36,58 @@ BITS 32
PAGE_READ_WRITE + \
PAGE_PRESENT)
+;
+; SEV-ES #VC exception handler support
+;
+; #VC handler local variable locations
+;
+%define VC_CPUID_RESULT_EAX 0
+%define VC_CPUID_RESULT_EBX 4
+%define VC_CPUID_RESULT_ECX 8
+%define VC_CPUID_RESULT_EDX 12
+%define VC_GHCB_MSR_EDX 16
+%define VC_GHCB_MSR_EAX 20
+%define VC_CPUID_REQUEST_REGISTER 24
+%define VC_CPUID_FUNCTION 28
+
+; #VC handler total local variable size
+;
+%define VC_VARIABLE_SIZE 32
+
+; #VC handler GHCB CPUID request/response protocol values
+;
+%define GHCB_CPUID_REQUEST 4
+%define GHCB_CPUID_RESPONSE 5
+%define GHCB_CPUID_REGISTER_SHIFT 30
+%define CPUID_INSN_LEN 2
+
+
; Check if Secure Encrypted Virtualization (SEV) feature is enabled
;
-; If SEV is enabled then EAX will be at least 32
+; Modified: EAX, EBX, ECX, EDX, ESP
+;
+; If SEV is enabled then EAX will be at least 32.
; If SEV is disabled then EAX will be zero.
;
CheckSevFeature:
+ ; Set the first byte of the workarea to zero to communicate to the SEC
+ ; phase that SEV-ES is not enabled. If SEV-ES is enabled, the CPUID
+ ; instruction will trigger a #VC exception where the first byte of the
+ ; workarea will be set to one.
+ mov byte[SEV_ES_WORK_AREA], 0
+
+ ;
+ ; Set up exception handlers to check for SEV-ES
+ ; Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
+ ; stack usage)
+ ; Establish exception handlers
+ ;
+ mov esp, SEV_ES_VC_TOP_OF_STACK
+ mov eax, ADDR_OF(Idtr)
+ lidt [cs:eax]
+
; Check if we have a valid (0x8000_001F) CPUID leaf
+ ; CPUID raises a #VC exception if running as an SEV-ES guest
mov eax, 0x80000000
cpuid
@@ -53,8 +98,8 @@ CheckSevFeature:
jl NoSev
; Check for memory encryption feature:
- ; CPUID Fn8000_001F[EAX] - Bit 1
- ;
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ; CPUID raises a #VC exception if running as an SEV-ES guest
mov eax, 0x8000001f
cpuid
bt eax, 1
@@ -78,6 +123,15 @@ NoSev:
xor eax, eax
SevExit:
+ ;
+ ; Clear exception handlers and stack
+ ;
+ push eax
+ mov eax, ADDR_OF(IdtrClear)
+ lidt [cs:eax]
+ pop eax
+ mov esp, 0
+
OneTimeCallRet CheckSevFeature
; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
@@ -222,3 +276,218 @@ SetCr3:
mov cr3, eax
OneTimeCallRet SetCr3ForPageTables64
+
+;
+; Start of #VC exception handling routines
+;
+
+SevEsIdtNotCpuid:
+ ;
+ ; Use VMGEXIT to request termination.
+ ; 1 - #VC was not for CPUID
+ ;
+ mov eax, 1
+ jmp SevEsIdtTerminate
+
+SevEsIdtNoCpuidResponse:
+ ;
+ ; Use VMGEXIT to request termination.
+ ; 2 - GHCB_CPUID_RESPONSE not received
+ ;
+ mov eax, 2
+
+SevEsIdtTerminate:
+ ;
+ ; Use VMGEXIT to request termination. At this point the reason code is
+ ; located in EAX, so shift it left 16 bits to the proper location.
+ ;
+ ; EAX[11:0] => 0x100 - request termination
+ ; EAX[15:12] => 0x1 - OVMF
+ ; EAX[23:16] => 0xXX - REASON CODE
+ ;
+ shl eax, 16
+ or eax, 0x1100
+ xor edx, edx
+ mov ecx, 0xc0010130
+ wrmsr
+ ;
+ ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+ ; mode, so work around this by temporarily switching to 64-bit mode.
+ ;
+BITS 64
+ rep vmmcall
+BITS 32
+
+ ;
+ ; We shouldn't come back from the VMGEXIT, but if we do, just loop.
+ ;
+SevEsIdtHlt:
+ hlt
+ jmp SevEsIdtHlt
+ iret
+
+ ;
+ ; Total stack usage for the #VC handler is 44 bytes:
+ ; - 12 bytes for the exception IRET (after popping error code)
+ ; - 32 bytes for the local variables.
+ ;
+SevEsIdtVmmComm:
+ ;
+ ; If we're here, then we are an SEV-ES guest and this
+ ; was triggered by a CPUID instruction
+ ;
+ ; Set the first byte of the workarea to one to communicate to the SEC
+ ; phase that SEV-ES is enabled.
+ mov byte[SEV_ES_WORK_AREA], 1
+
+ pop ecx ; Error code
+ cmp ecx, 0x72 ; Be sure it was CPUID
+ jne SevEsIdtNotCpuid
+
+ ; Set up local variable room on the stack
+ ; CPUID function : + 28
+ ; CPUID request register : + 24
+ ; GHCB MSR (EAX) : + 20
+ ; GHCB MSR (EDX) : + 16
+ ; CPUID result (EDX) : + 12
+ ; CPUID result (ECX) : + 8
+ ; CPUID result (EBX) : + 4
+ ; CPUID result (EAX) : + 0
+ sub esp, VC_VARIABLE_SIZE
+
+ ; Save the CPUID function being requested
+ mov [esp + VC_CPUID_FUNCTION], eax
+
+ ; The GHCB CPUID protocol uses the following mapping to request
+ ; a specific register:
+ ; 0 => EAX, 1 => EBX, 2 => ECX, 3 => EDX
+ ;
+ ; Set EAX as the first register to request. This will also be used as a
+ ; loop variable to request all register values (EAX to EDX).
+ xor eax, eax
+ mov [esp + VC_CPUID_REQUEST_REGISTER], eax
+
+ ; Save current GHCB MSR value
+ mov ecx, 0xc0010130
+ rdmsr
+ mov [esp + VC_GHCB_MSR_EAX], eax
+ mov [esp + VC_GHCB_MSR_EDX], edx
+
+NextReg:
+ ;
+ ; Setup GHCB MSR
+ ; GHCB_MSR[63:32] = CPUID function
+ ; GHCB_MSR[31:30] = CPUID register
+ ; GHCB_MSR[11:0] = CPUID request protocol
+ ;
+ mov eax, [esp + VC_CPUID_REQUEST_REGISTER]
+ cmp eax, 4
+ jge VmmDone
+
+ shl eax, GHCB_CPUID_REGISTER_SHIFT
+ or eax, GHCB_CPUID_REQUEST
+ mov edx, [esp + VC_CPUID_FUNCTION]
+ mov ecx, 0xc0010130
+ wrmsr
+
+ ;
+ ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+ ; mode, so work around this by temporarily switching to 64-bit mode.
+ ;
+BITS 64
+ rep vmmcall
+BITS 32
+
+ ;
+ ; Read GHCB MSR
+ ; GHCB_MSR[63:32] = CPUID register value
+ ; GHCB_MSR[31:30] = CPUID register
+ ; GHCB_MSR[11:0] = CPUID response protocol
+ ;
+ mov ecx, 0xc0010130
+ rdmsr
+ mov ecx, eax
+ and ecx, 0xfff
+ cmp ecx, GHCB_CPUID_RESPONSE
+ jne SevEsIdtNoCpuidResponse
+
+ ; Save returned value
+ shr eax, GHCB_CPUID_REGISTER_SHIFT
+ mov [esp + eax * 4], edx
+
+ ; Next register
+ inc word [esp + VC_CPUID_REQUEST_REGISTER]
+
+ jmp NextReg
+
+VmmDone:
+ ;
+ ; At this point we have all CPUID register values. Restore the GHCB MSR,
+ ; set the return register values and return.
+ ;
+ mov eax, [esp + VC_GHCB_MSR_EAX]
+ mov edx, [esp + VC_GHCB_MSR_EDX]
+ mov ecx, 0xc0010130
+ wrmsr
+
+ mov eax, [esp + VC_CPUID_RESULT_EAX]
+ mov ebx, [esp + VC_CPUID_RESULT_EBX]
+ mov ecx, [esp + VC_CPUID_RESULT_ECX]
+ mov edx, [esp + VC_CPUID_RESULT_EDX]
+
+ add esp, VC_VARIABLE_SIZE
+
+ ; Update the EIP value to skip over the now handled CPUID instruction
+ ; (the CPUID instruction has a length of 2)
+ add word [esp], CPUID_INSN_LEN
+ iret
+
+ALIGN 2
+
+Idtr:
+ dw IDT_END - IDT_BASE - 1 ; Limit
+ dd ADDR_OF(IDT_BASE) ; Base
+
+IdtrClear:
+ dw 0 ; Limit
+ dd 0 ; Base
+
+ALIGN 16
+
+;
+; The Interrupt Descriptor Table (IDT)
+; This will be used to determine if SEV-ES is enabled. Upon execution
+; of the CPUID instruction, a VMM Communication Exception will occur.
+; This will tell us if SEV-ES is enabled. We can use the current value
+; of the GHCB MSR to determine the SEV attributes.
+;
+IDT_BASE:
+;
+; Vectors 0 - 28 (No handlers)
+;
+%rep 29
+ dw 0 ; Offset low bits 15..0
+ dw 0x10 ; Selector
+ db 0 ; Reserved
+ db 0x8E ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32)
+ dw 0 ; Offset high bits 31..16
+%endrep
+;
+; Vector 29 (VMM Communication Exception)
+;
+ dw (ADDR_OF(SevEsIdtVmmComm) & 0xffff) ; Offset low bits 15..0
+ dw 0x10 ; Selector
+ db 0 ; Reserved
+ db 0x8E ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32)
+ dw (ADDR_OF(SevEsIdtVmmComm) >> 16) ; Offset high bits 31..16
+;
+; Vectors 30 - 31 (No handlers)
+;
+%rep 2
+ dw 0 ; Offset low bits 15..0
+ dw 0x10 ; Selector
+ db 0 ; Reserved
+ db 0x8E ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32)
+ dw 0 ; Offset high bits 31..16
+%endrep
+IDT_END:
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index bfb77e439105..762661115d50 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -72,6 +72,8 @@
%define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
%define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))
%define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))
+ %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))
+ %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
%include "Ia32/PageTables64.asm"
%endif
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check
2020-06-05 13:27 ` [PATCH v9 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
@ 2020-06-11 10:08 ` Laszlo Ersek
0 siblings, 0 replies; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 10:08 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni
On 06/05/20 15:27, Tom Lendacky wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> During BSP startup, the reset vector code will issue a CPUID instruction
> while in 32-bit mode. When running as an SEV-ES guest, this will trigger
> a #VC exception.
>
> Add exception handling support to the early reset vector code to catch
> these exceptions. Also, since the guest is in 32-bit mode at this point,
> writes to the GHCB will be encrypted and thus not able to be read by the
> hypervisor, so use the GHCB CPUID request/response protocol to obtain the
> requested CPUID function values and provide these to the guest.
>
> The exception handling support is active during the SEV check and uses the
> OVMF temporary RAM space for a stack. After the SEV check is complete, the
> exception handling support is removed and the stack pointer cleared.
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>
> This patch has been reverted to the previous v6 version.
> ---
> OvmfPkg/ResetVector/ResetVector.inf | 3 +
> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 275 +++++++++++++++++++-
> OvmfPkg/ResetVector/ResetVector.nasmb | 2 +
> 3 files changed, 277 insertions(+), 3 deletions(-)
Thanks!
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 37/46] OvmfPkg/Sec: Add #VC exception handling for Sec phase
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (35 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 36/46] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 38/46] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
` (8 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
An SEV-ES guest will generate a #VC exception when it encounters a
non-automatic exit (NAE) event. It is expected that the #VC exception
handler will communicate with the hypervisor using the GHCB to handle
the NAE event.
NAE events can occur during the Sec phase, so initialize exception
handling early in the OVMF Sec support.
Before establishing the exception handling, validate that the supported
version of the SEV-ES protocol in OVMF is supported by the hypervisor.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Sec/SecMain.inf | 4 +
OvmfPkg/Sec/SecMain.c | 181 ++++++++++++++++++--
2 files changed, 172 insertions(+), 13 deletions(-)
diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
index 63ba4cb555fb..7f78dcee2772 100644
--- a/OvmfPkg/Sec/SecMain.inf
+++ b/OvmfPkg/Sec/SecMain.inf
@@ -50,15 +50,19 @@ [LibraryClasses]
PeCoffExtraActionLib
ExtractGuidedSectionLib
LocalApicLib
+ CpuExceptionHandlerLib
[Ppis]
gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 6dea6e771a29..c2a35463dce4 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -24,6 +24,9 @@
#include <Library/PeCoffExtraActionLib.h>
#include <Library/ExtractGuidedSectionLib.h>
#include <Library/LocalApicLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Register/Amd/Ghcb.h>
+#include <Register/Amd/Msr.h>
#include <Ppi/TemporaryRamSupport.h>
@@ -34,6 +37,10 @@ typedef struct _SEC_IDT_TABLE {
IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
} SEC_IDT_TABLE;
+typedef struct _SEC_SEV_ES_WORK_AREA {
+ UINT8 SevEsEnabled;
+} SEC_SEV_ES_WORK_AREA;
+
VOID
EFIAPI
SecStartupPhase2 (
@@ -712,6 +719,120 @@ FindAndReportEntryPoints (
return;
}
+/**
+ Handle an SEV-ES/GHCB protocol check failure.
+
+ Notify the hypervisor using the VMGEXIT instruction that the SEV-ES guest
+ wishes to be terminated.
+
+ @param[in] ReasonCode Reason code to provide to the hypervisor for the
+ termination request.
+
+**/
+STATIC
+VOID
+SevEsProtocolFailure (
+ IN UINT8 ReasonCode
+ )
+{
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+
+ //
+ // Use the GHCB MSR Protocol to request termination by the hypervisor
+ //
+ Msr.GhcbPhysicalAddress = 0;
+ Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
+ Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
+ Msr.GhcbTerminate.ReasonCode = ReasonCode;
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+ AsmVmgExit ();
+
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/**
+ Validate the SEV-ES/GHCB protocol level.
+
+ Verify that the level of SEV-ES/GHCB protocol supported by the hypervisor
+ and the guest intersect. If they don't intersect, request termination.
+
+**/
+STATIC
+VOID
+SevEsProtocolCheck (
+ VOID
+ )
+{
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
+
+ //
+ // Use the GHCB MSR Protocol to obtain the GHCB SEV-ES Information for
+ // protocol checking
+ //
+ Msr.GhcbPhysicalAddress = 0;
+ Msr.GhcbInfo.Function = GHCB_INFO_SEV_INFO_GET;
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+ AsmVmgExit ();
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+ if (Msr.GhcbInfo.Function != GHCB_INFO_SEV_INFO) {
+ SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);
+ }
+
+ if (Msr.GhcbProtocol.SevEsProtocolMin > Msr.GhcbProtocol.SevEsProtocolMax) {
+ SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
+ }
+
+ if ((Msr.GhcbProtocol.SevEsProtocolMin > GHCB_VERSION_MAX) ||
+ (Msr.GhcbProtocol.SevEsProtocolMax < GHCB_VERSION_MIN)) {
+ SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);
+ }
+
+ //
+ // SEV-ES protocol checking succeeded, set the initial GHCB address
+ //
+ Msr.GhcbPhysicalAddress = FixedPcdGet32 (PcdOvmfSecGhcbBase);
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);
+
+ Ghcb = Msr.Ghcb;
+ SetMem (Ghcb, sizeof (*Ghcb), 0);
+
+ //
+ // Set the version to the maximum that can be supported
+ //
+ Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);
+ Ghcb->GhcbUsage = GHCB_STANDARD_USAGE;
+}
+
+/**
+ Determine if SEV-ES is active.
+
+ During early booting, SEV-ES support code will set a flag to indicate that
+ SEV-ES is enabled. Return the value of this flag as an indicator that SEV-ES
+ is enabled.
+
+ @retval TRUE SEV-ES is enabled
+ @retval FALSE SEV-ES is not enabled
+
+**/
+STATIC
+BOOLEAN
+SevEsIsEnabled (
+ VOID
+ )
+{
+ SEC_SEV_ES_WORK_AREA *SevEsWorkArea;
+
+ SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+
+ return ((SevEsWorkArea != NULL) && (SevEsWorkArea->SevEsEnabled != 0));
+}
+
VOID
EFIAPI
SecCoreStartupWithStack (
@@ -737,8 +858,55 @@ SecCoreStartupWithStack (
Table[Index] = 0;
}
+ //
+ // Initialize IDT - Since this is before library constructors are called,
+ // we use a loop rather than CopyMem.
+ //
+ IdtTableInStack.PeiService = NULL;
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+ UINT8 *Src, *Dst;
+ UINTN Byte;
+
+ Src = (UINT8 *) &mIdtEntryTemplate;
+ Dst = (UINT8 *) &IdtTableInStack.IdtTable[Index];
+ for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {
+ Dst[Byte] = Src[Byte];
+ }
+ }
+
+ IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ if (SevEsIsEnabled ()) {
+ SevEsProtocolCheck ();
+
+ //
+ // For SEV-ES guests, the exception handler is needed before calling
+ // ProcessLibraryConstructorList() because some of the library constructors
+ // perform some functions that result in #VC exceptions being generated.
+ //
+ // Due to this code executing before library constructors, *all* library
+ // API calls are theoretically interface contract violations. However,
+ // because this is SEC (executing in flash), those constructors cannot
+ // write variables with static storage duration anyway. Furthermore, only
+ // a small, restricted set of APIs, such as AsmWriteIdtr() and
+ // InitializeCpuExceptionHandlers(), are called, where we require that the
+ // underlying library not require constructors to have been invoked and
+ // that the library instance not trigger any #VC exceptions.
+ //
+ AsmWriteIdtr (&IdtDescriptor);
+ InitializeCpuExceptionHandlers (NULL);
+ }
+
ProcessLibraryConstructorList (NULL, NULL);
+ if (!SevEsIsEnabled ()) {
+ //
+ // For non SEV-ES guests, just load the IDTR.
+ //
+ AsmWriteIdtr (&IdtDescriptor);
+ }
+
DEBUG ((DEBUG_INFO,
"SecCoreStartupWithStack(0x%x, 0x%x)\n",
(UINT32)(UINTN)BootFv,
@@ -751,19 +919,6 @@ SecCoreStartupWithStack (
//
InitializeFloatingPointUnits ();
- //
- // Initialize IDT
- //
- IdtTableInStack.PeiService = NULL;
- for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
- CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
- }
-
- IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
- IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
-
- AsmWriteIdtr (&IdtDescriptor);
-
#if defined (MDE_CPU_X64)
//
// ASSERT that the Page Tables were set by the reset vector code to
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 38/46] OvmfPkg/Sec: Enable cache early to speed up booting
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (36 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 37/46] OvmfPkg/Sec: Add #VC exception handling for Sec phase Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 13:27 ` [PATCH v9 39/46] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES Lendacky, Thomas
` (7 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Currently, the OVMF code relies on the hypervisor to enable the cache
support on the processor in order to improve the boot speed. However,
with SEV-ES, the hypervisor is not allowed to change the CR0 register
to enable caching.
Update the OVMF Sec support to enable caching in order to improve the
boot speed when running as an SEV-ES guest.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Sec/SecMain.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index c2a35463dce4..271a06348ed8 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -905,6 +905,13 @@ SecCoreStartupWithStack (
// For non SEV-ES guests, just load the IDTR.
//
AsmWriteIdtr (&IdtDescriptor);
+ } else {
+ //
+ // Under SEV-ES, the hypervisor can't modify CR0 and so can't enable
+ // caching in order to speed up the boot. Enable caching early for
+ // an SEV-ES guest.
+ //
+ AsmEnableCache ();
}
DEBUG ((DEBUG_INFO,
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 39/46] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (37 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 38/46] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
@ 2020-06-05 13:27 ` Lendacky, Thomas
2020-06-05 17:58 ` [PATCH v9 40/46] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
` (6 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 13:27 UTC (permalink / raw)
To: devel
Cc: Brijesh Singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Laszlo Ersek, Liming Gao, Michael D Kinney, Ray Ni
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
The flash detection routine will attempt to determine how the flash
device behaves (e.g. ROM, RAM, Flash). But when SEV-ES is enabled and
the flash device behaves as a ROM device (meaning it is marked read-only
by the hypervisor), this check may result in an infinite nested page fault
because of the attempted write. Since the instruction cannot be emulated
when SEV-ES is enabled, the RIP is never advanced, resulting in repeated
nested page faults.
When SEV-ES is enabled, exit the flash detection early and assume that
the FD behaves as Flash. This will result in QemuFlashWrite() being called
to store EFI variables, which will also result in an infinite nested page
fault when the write is performed. In this case, update QemuFlashWrite()
to use the VMGEXIT MMIO write support to have the hypervisor perform the
write without having to emulate the instruction.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf | 2 +
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h | 13 +++++++
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c | 23 +++++++++--
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c | 40 ++++++++++++++++++++
OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c | 16 ++++++++
5 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
index 72cabba4357d..8bb2325157ea 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
@@ -38,6 +38,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
@@ -52,6 +53,7 @@ [LibraryClasses]
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeLib
+ VmgExitLib
[Guids]
gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h
index f1afabcbe6ae..219d0d6e83cf 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h
@@ -89,5 +89,18 @@ QemuFlashBeforeProbe (
IN UINTN FdBlockCount
);
+/**
+ Write to QEMU Flash
+
+ @param[in] Ptr Pointer to the location to write.
+ @param[in] Value The value to write.
+
+**/
+VOID
+QemuFlashPtrWrite (
+ IN volatile UINT8 *Ptr,
+ IN UINT8 Value
+ );
+
#endif
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
index 1b0d6c053f1a..0d29bf701aca 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
@@ -9,6 +9,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/MemEncryptSevLib.h>
#include <Library/PcdLib.h>
#include "QemuFlash.h"
@@ -80,6 +81,21 @@ QemuFlashDetected (
DEBUG ((DEBUG_INFO, "QEMU Flash: Attempting flash detection at %p\n", Ptr));
+ if (MemEncryptSevEsIsEnabled ()) {
+ //
+ // When SEV-ES is enabled, the check below can result in an infinite
+ // loop with respect to a nested page fault. When the memslot is mapped
+ // read-only, the nested page table entry is read-only. The check below
+ // will cause a nested page fault that cannot be emulated, causing
+ // the instruction to retried over and over. For SEV-ES, acknowledge that
+ // the FD appears as ROM and not as FLASH, but report FLASH anyway because
+ // FLASH behavior can be simulated using VMGEXIT.
+ //
+ DEBUG ((DEBUG_INFO,
+ "QEMU Flash: SEV-ES enabled, assuming FD behaves as FLASH\n"));
+ return TRUE;
+ }
+
OriginalUint8 = *Ptr;
*Ptr = CLEAR_STATUS_CMD;
ProbeUint8 = *Ptr;
@@ -181,8 +197,9 @@ QemuFlashWrite (
//
Ptr = QemuFlashPtr (Lba, Offset);
for (Loop = 0; Loop < *NumBytes; Loop++) {
- *Ptr = WRITE_BYTE_CMD;
- *Ptr = Buffer[Loop];
+ QemuFlashPtrWrite (Ptr, WRITE_BYTE_CMD);
+ QemuFlashPtrWrite (Ptr, Buffer[Loop]);
+
Ptr++;
}
@@ -190,7 +207,7 @@ QemuFlashWrite (
// Restore flash to read mode
//
if (*NumBytes > 0) {
- *(Ptr - 1) = READ_ARRAY_CMD;
+ QemuFlashPtrWrite (Ptr - 1, READ_ARRAY_CMD);
}
return EFI_SUCCESS;
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
index 5aabe9d7b59c..565383ee26d2 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
@@ -10,6 +10,9 @@
**/
#include <Library/UefiRuntimeLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/VmgExitLib.h>
+#include <Register/Amd/Msr.h>
#include "QemuFlash.h"
@@ -32,3 +35,40 @@ QemuFlashBeforeProbe (
// Do nothing
//
}
+
+/**
+ Write to QEMU Flash
+
+ @param[in] Ptr Pointer to the location to write.
+ @param[in] Value The value to write.
+
+**/
+VOID
+QemuFlashPtrWrite (
+ IN volatile UINT8 *Ptr,
+ IN UINT8 Value
+ )
+{
+ if (MemEncryptSevEsIsEnabled ()) {
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ //
+ // Writing to flash is emulated by the hypervisor through the use of write
+ // protection. This won't work for an SEV-ES guest because the write won't
+ // be recognized as a true MMIO write, which would result in the required
+ // #VC exception. Instead, use the the VMGEXIT MMIO write support directly
+ // to perform the update.
+ //
+ VmgInit (Ghcb);
+ Ghcb->SharedBuffer[0] = Value;
+ Ghcb->SaveArea.SwScratch = (UINT64) (UINTN) Ghcb->SharedBuffer;
+ VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, (UINT64) (UINTN) Ptr, 1);
+ VmgDone (Ghcb);
+ } else {
+ *Ptr = Value;
+ }
+}
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c
index 7eb426e03855..7eb80bfeffae 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c
@@ -46,3 +46,19 @@ QemuFlashBeforeProbe (
);
ASSERT_EFI_ERROR (Status);
}
+
+/**
+ Write to QEMU Flash
+
+ @param[in] Ptr Pointer to the location to write.
+ @param[in] Value The value to write.
+
+**/
+VOID
+QemuFlashPtrWrite (
+ IN volatile UINT8 *Ptr,
+ IN UINT8 Value
+ )
+{
+ *Ptr = Value;
+}
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 40/46] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (38 preceding siblings ...)
2020-06-05 13:27 ` [PATCH v9 39/46] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-16 8:24 ` Dong, Eric
2020-06-05 17:58 ` [PATCH v9 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
` (5 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
A hypervisor is not allowed to update an SEV-ES guests register state,
so when booting an SEV-ES guest AP, the hypervisor is not allowed to
set the RIP to the guest requested value. Instead, an SEV-ES AP must be
transition from 64-bit long mode to 16-bit real mode in response to an
INIT-SIPI-SIPI sequence. This requires a 16-bit code segment descriptor.
For PEI, create this descriptor in the reset vector GDT table. For DXE,
create this descriptor from the newly reserved entry at location 0x28.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/CpuDxe/CpuGdt.h | 4 ++--
UefiCpuPkg/CpuDxe/CpuGdt.c | 8 ++++----
UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +++++++++
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.h b/UefiCpuPkg/CpuDxe/CpuGdt.h
index 3a0210b2f172..1c94487cbee8 100644
--- a/UefiCpuPkg/CpuDxe/CpuGdt.h
+++ b/UefiCpuPkg/CpuDxe/CpuGdt.h
@@ -36,7 +36,7 @@ struct _GDT_ENTRIES {
GDT_ENTRY LinearCode;
GDT_ENTRY SysData;
GDT_ENTRY SysCode;
- GDT_ENTRY Spare4;
+ GDT_ENTRY SysCode16;
GDT_ENTRY LinearData64;
GDT_ENTRY LinearCode64;
GDT_ENTRY Spare5;
@@ -49,7 +49,7 @@ struct _GDT_ENTRIES {
#define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode)
#define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData)
#define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode)
-#define SPARE4_SEL OFFSET_OF (GDT_ENTRIES, Spare4)
+#define SYS_CODE16_SEL OFFSET_OF (GDT_ENTRIES, SysCode16)
#define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64)
#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64)
#define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5)
diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.c b/UefiCpuPkg/CpuDxe/CpuGdt.c
index 64efadeba601..a1ab543f2da5 100644
--- a/UefiCpuPkg/CpuDxe/CpuGdt.c
+++ b/UefiCpuPkg/CpuDxe/CpuGdt.c
@@ -70,14 +70,14 @@ STATIC GDT_ENTRIES GdtTemplate = {
0x0,
},
//
- // SPARE4_SEL
+ // SYS_CODE16_SEL
//
{
- 0x0, // limit 15:0
+ 0x0FFFF, // limit 15:0
0x0, // base 15:0
0x0, // base 23:16
- 0x0, // type
- 0x0, // limit 19:16, flags
+ 0x09A, // present, ring 0, code, execute/read
+ 0x08F, // page-granular, 16-bit
0x0, // base 31:24
},
//
diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
index ce4ebfffb688..0e79a3984b16 100644
--- a/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
+++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
@@ -129,5 +129,14 @@ LINEAR_CODE64_SEL equ $-GDT_BASE
DB 0 ; base 31:24
%endif
+; linear code segment descriptor
+LINEAR_CODE16_SEL equ $-GDT_BASE
+ DW 0xffff ; limit 15:0
+ DW 0 ; base 15:0
+ DB 0 ; base 23:16
+ DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)
+ DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+ DB 0 ; base 31:24
+
GDT_END:
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 40/46] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
2020-06-05 17:58 ` [PATCH v9 40/46] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
@ 2020-06-16 8:24 ` Dong, Eric
0 siblings, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-16 8:24 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Reviewed-by: Eric Dong <eric.dong@intel.com>
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:28 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 40/46] UefiCpuPkg: Add a 16-bit protected mode code
> segment descriptor
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> A hypervisor is not allowed to update an SEV-ES guests register state, so
> when booting an SEV-ES guest AP, the hypervisor is not allowed to set the
> RIP to the guest requested value. Instead, an SEV-ES AP must be transition
> from 64-bit long mode to 16-bit real mode in response to an INIT-SIPI-SIPI
> sequence. This requires a 16-bit code segment descriptor.
> For PEI, create this descriptor in the reset vector GDT table. For DXE, create
> this descriptor from the newly reserved entry at location 0x28.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 ++--
> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 ++++----
> UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +++++++++
> 3 files changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.h b/UefiCpuPkg/CpuDxe/CpuGdt.h
> index 3a0210b2f172..1c94487cbee8 100644
> --- a/UefiCpuPkg/CpuDxe/CpuGdt.h
> +++ b/UefiCpuPkg/CpuDxe/CpuGdt.h
> @@ -36,7 +36,7 @@ struct _GDT_ENTRIES {
> GDT_ENTRY LinearCode; GDT_ENTRY SysData; GDT_ENTRY SysCode;-
> GDT_ENTRY Spare4;+ GDT_ENTRY SysCode16; GDT_ENTRY LinearData64;
> GDT_ENTRY LinearCode64; GDT_ENTRY Spare5;@@ -49,7 +49,7 @@ struct
> _GDT_ENTRIES {
> #define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode)
> #define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData) #define
> SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode)-#define SPARE4_SEL
> OFFSET_OF (GDT_ENTRIES, Spare4)+#define SYS_CODE16_SEL OFFSET_OF
> (GDT_ENTRIES, SysCode16) #define LINEAR_DATA64_SEL OFFSET_OF
> (GDT_ENTRIES, LinearData64) #define LINEAR_CODE64_SEL OFFSET_OF
> (GDT_ENTRIES, LinearCode64) #define SPARE5_SEL OFFSET_OF
> (GDT_ENTRIES, Spare5)diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.c
> b/UefiCpuPkg/CpuDxe/CpuGdt.c
> index 64efadeba601..a1ab543f2da5 100644
> --- a/UefiCpuPkg/CpuDxe/CpuGdt.c
> +++ b/UefiCpuPkg/CpuDxe/CpuGdt.c
> @@ -70,14 +70,14 @@ STATIC GDT_ENTRIES GdtTemplate = {
> 0x0, }, //- // SPARE4_SEL+ // SYS_CODE16_SEL // {- 0x0, // limit
> 15:0+ 0x0FFFF, // limit 15:0 0x0, // base 15:0 0x0, // base
> 23:16- 0x0, // type- 0x0, // limit 19:16, flags+ 0x09A, //
> present, ring 0, code, execute/read+ 0x08F, // page-granular, 16-bit
> 0x0, // base 31:24 }, //diff --git
> a/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
> b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
> index ce4ebfffb688..0e79a3984b16 100644
> --- a/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
> +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
> @@ -129,5 +129,14 @@ LINEAR_CODE64_SEL equ $-GDT_BASE
> DB 0 ; base 31:24 %endif +; linear code segment
> descriptor+LINEAR_CODE16_SEL equ $-GDT_BASE+ DW 0xffff ; limit
> 15:0+ DW 0 ; base 15:0+ DB 0 ; base 23:16+ DB
> PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)+
> DB
> GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(0)|UPPER_LIMI
> T(0xf)+ DB 0 ; base 31:24+ GDT_END: --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (39 preceding siblings ...)
2020-06-05 17:58 ` [PATCH v9 40/46] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-12 1:03 ` Dong, Eric
2020-06-05 17:58 ` [PATCH v9 42/46] UefiCpuPkg: Allow AP booting under SEV-ES Lendacky, Thomas
` (4 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
When starting APs in an SMP configuration, the AP needs to know if it is
running as an SEV-ES guest in order to assign a GHCB page.
Add a field to the CPU_MP_DATA structure that will indicate if SEV-ES is
enabled. This new field is set during MP library initialization with the
PCD value PcdSevEsIsEnabled. This flag can then be used to determine if
SEV-ES is enabled.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 +
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 1 +
UefiCpuPkg/Library/MpInitLib/MpLib.h | 2 ++
UefiCpuPkg/Library/MpInitLib/MpLib.c | 1 +
4 files changed, 5 insertions(+)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 9907f4157b09..583276595619 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -71,4 +71,5 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 89ee9a79d8c5..4b3d39fbf36c 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -61,6 +61,7 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## CONSUMES
[Ppis]
gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a8ca03efb8e3..5b46c295b6b2 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -276,6 +276,8 @@ struct _CPU_MP_DATA {
// driver.
//
BOOLEAN WakeUpByInitSipiSipi;
+
+ BOOLEAN SevEsIsEnabled;
};
extern EFI_GUID mCpuInitMpLibHobGuid;
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index ab7a8ed6633a..a8b605f569bf 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1727,6 +1727,7 @@ MpInitLibInitialize (
CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock(&CpuMpData->MpLock);
+ CpuMpData->SevEsIsEnabled = PcdGetBool (PcdSevEsIsEnabled);
//
// Make sure no memory usage outside of the allocated buffer.
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled
2020-06-05 17:58 ` [PATCH v9 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
@ 2020-06-12 1:03 ` Dong, Eric
0 siblings, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-12 1:03 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Reviewed-by: Eric Dong <eric.dong@intel.com>
Thanks,
Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:28 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to
> indicate if SEV-ES is enabled
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> When starting APs in an SMP configuration, the AP needs to know if it is
> running as an SEV-ES guest in order to assign a GHCB page.
>
> Add a field to the CPU_MP_DATA structure that will indicate if SEV-ES is
> enabled. This new field is set during MP library initialization with the
> PCD value PcdSevEsIsEnabled. This flag can then be used to determine if
> SEV-ES is enabled.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 +
> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 1 +
> UefiCpuPkg/Library/MpInitLib/MpLib.h | 2 ++
> UefiCpuPkg/Library/MpInitLib/MpLib.c | 1 +
> 4 files changed, 5 insertions(+)
>
> diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> index 9907f4157b09..583276595619 100644
> --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> @@ -71,4 +71,5 @@ [Pcd]
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ##
> CONSUMES
>
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ##
> SOMETIMES_CONSUMES
>
>
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds
> ## CONSUMES
>
> + gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ##
> CONSUMES
>
> gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ##
> CONSUMES
>
> diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> index 89ee9a79d8c5..4b3d39fbf36c 100644
> --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> @@ -61,6 +61,7 @@ [Pcd]
> gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ##
> CONSUMES
>
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ##
> CONSUMES
>
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ##
> SOMETIMES_CONSUMES
>
> + gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ##
> CONSUMES
>
>
>
> [Ppis]
>
> gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES
>
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h
> b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> index a8ca03efb8e3..5b46c295b6b2 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
> @@ -276,6 +276,8 @@ struct _CPU_MP_DATA {
> // driver.
>
> //
>
> BOOLEAN WakeUpByInitSipiSipi;
>
> +
>
> + BOOLEAN SevEsIsEnabled;
>
> };
>
>
>
> extern EFI_GUID mCpuInitMpLibHobGuid;
>
> diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> index ab7a8ed6633a..a8b605f569bf 100644
> --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
> +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
> @@ -1727,6 +1727,7 @@ MpInitLibInitialize (
> CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);
>
> CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData
> + MaxLogicalProcessorNumber);
>
> InitializeSpinLock(&CpuMpData->MpLock);
>
> + CpuMpData->SevEsIsEnabled = PcdGetBool (PcdSevEsIsEnabled);
>
>
>
> //
>
> // Make sure no memory usage outside of the allocated buffer.
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 42/46] UefiCpuPkg: Allow AP booting under SEV-ES
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (40 preceding siblings ...)
2020-06-05 17:58 ` [PATCH v9 41/46] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-05 17:58 ` [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
` (3 subsequent siblings)
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Typically, an AP is booted using the INIT-SIPI-SIPI sequence. This
sequence is intercepted by the hypervisor, which sets the AP's registers
to the values requested by the sequence. At that point, the hypervisor can
start the AP, which will then begin execution at the appropriate location.
Under SEV-ES, AP booting presents some challenges since the hypervisor is
not allowed to alter the AP's register state. In this situation, we have
to distinguish between the AP's first boot and AP's subsequent boots.
First boot:
Once the AP's register state has been defined (which is before the guest
is first booted) it cannot be altered. Should the hypervisor attempt to
alter the register state, the change would be detected by the hardware
and the VMRUN instruction would fail. Given this, the first boot for the
AP is required to begin execution with this initial register state, which
is typically the reset vector. This prevents the BSP from directing the
AP startup location through the INIT-SIPI-SIPI sequence.
To work around this, the firmware will provide a build time reserved area
that can be used as the initial IP value. The hypervisor can extract this
location value by checking for the SEV-ES reset block GUID that must be
located 48-bytes from the end of the firmware. The format of the SEV-ES
reset block area is:
0x00 - 0x01 - SEV-ES Reset IP
0x02 - 0x03 - SEV-ES Reset CS Segment Base[31:16]
0x04 - 0x05 - Size of the SEV-ES reset block
0x06 - 0x15 - SEV-ES Reset Block GUID
(00f771de-1a7e-4fcb-890e-68c77e2fb44e)
The total size is 22 bytes. Any expansion to this block must be done
by adding new values before existing values.
The hypervisor will use the IP and CS values obtained from the SEV-ES
reset block to set as the AP's initial values. The CS Segment Base
represents the upper 16 bits of the CS segment base and must be left
shifted by 16 bits to form the complete CS segment base value.
Before booting the AP for the first time, the BSP must initialize the
SEV-ES reset area. This consists of programming a FAR JMP instruction
to the contents of a memory location that is also located in the SEV-ES
reset area. The BSP must program the IP and CS values for the FAR JMP
based on values drived from the INIT-SIPI-SIPI sequence.
Subsequent boots:
Again, the hypervisor cannot alter the AP register state, so a method is
required to take the AP out of halt state and redirect it to the desired
IP location. If it is determined that the AP is running in an SEV-ES
guest, then instead of calling CpuSleep(), a VMGEXIT is issued with the
AP Reset Hold exit code (0x80000004). The hypervisor will put the AP in
a halt state, waiting for an INIT-SIPI-SIPI sequence. Once the sequence
is recognized, the hypervisor will resume the AP. At this point the AP
must transition from the current 64-bit long mode down to 16-bit real
mode and begin executing at the derived location from the INIT-SIPI-SIPI
sequence.
Another change is around the area of obtaining the (x2)APIC ID during AP
startup. During AP startup, the AP can't take a #VC exception before the
AP has established a stack. However, the AP stack is set by using the
(x2)APIC ID, which is obtained through CPUID instructions. A CPUID
instruction will cause a #VC, so a different method must be used. The
GHCB protocol supports a method to obtain CPUID information from the
hypervisor through the GHCB MSR. This method does not require a stack,
so it is used to obtain the necessary CPUID information to determine the
(x2)APIC ID.
The new 16-bit protected mode GDT entry is used in order to transition
from 64-bit long mode down to 16-bit real mode.
A new assembler routine is created that takes the AP from 64-bit long mode
to 16-bit real mode. This is located under 1MB in memory and transitions
from 64-bit long mode to 32-bit compatibility mode to 16-bit protected
mode and finally 16-bit real mode.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 3 +
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 3 +
UefiCpuPkg/Library/MpInitLib/MpLib.h | 60 ++++
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 70 +++-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 336 +++++++++++++++++++-
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 ++
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 239 ++++++++++++++
11 files changed, 738 insertions(+), 15 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 583276595619..1771575c69c1 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -52,6 +52,7 @@ [LibraryClasses]
DebugAgentLib
SynchronizationLib
PcdLib
+ VmgExitLib
[Protocols]
gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES
@@ -72,4 +73,6 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 4b3d39fbf36c..34abf25d43cd 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -51,6 +51,7 @@ [LibraryClasses]
SynchronizationLib
PeiServicesLib
PcdLib
+ VmgExitLib
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
@@ -62,6 +63,8 @@ [Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
[Ppis]
gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 5b46c295b6b2..b1a9d99cb3eb 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -173,6 +173,11 @@ typedef struct {
UINT8 *RelocateApLoopFuncAddress;
UINTN RelocateApLoopFuncSize;
UINTN ModeTransitionOffset;
+ UINTN SwitchToRealSize;
+ UINTN SwitchToRealOffset;
+ UINTN SwitchToRealNoNxOffset;
+ UINTN SwitchToRealPM16ModeOffset;
+ UINTN SwitchToRealPM16ModeSize;
} MP_ASSEMBLY_ADDRESS_MAP;
typedef struct _CPU_MP_DATA CPU_MP_DATA;
@@ -211,6 +216,8 @@ typedef struct {
// Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.
//
BOOLEAN Enable5LevelPaging;
+ BOOLEAN SevEsIsEnabled;
+ UINTN GhcbBase;
} MP_CPU_EXCHANGE_INFO;
#pragma pack()
@@ -257,6 +264,7 @@ struct _CPU_MP_DATA {
UINT8 ApLoopMode;
UINT8 ApTargetCState;
UINT16 PmCodeSegment;
+ UINT16 Pm16CodeSegment;
CPU_AP_DATA *CpuData;
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
@@ -278,8 +286,47 @@ struct _CPU_MP_DATA {
BOOLEAN WakeUpByInitSipiSipi;
BOOLEAN SevEsIsEnabled;
+ UINTN SevEsAPBuffer;
+ UINTN SevEsAPResetStackStart;
+ CPU_MP_DATA *NewCpuMpData;
+
+ UINT64 GhcbBase;
};
+#define AP_RESET_STACK_SIZE 64
+
+#pragma pack(1)
+
+typedef struct {
+ UINT8 InsnBuffer[8];
+ UINT16 Rip;
+ UINT16 Segment;
+} SEV_ES_AP_JMP_FAR;
+
+#pragma pack()
+
+/**
+ Assembly code to move an AP from long mode to real mode.
+
+ Move an AP from long mode to real mode in preparation to invoking
+ the reset vector. This is used for SEV-ES guests where a hypervisor
+ is not allowed to set the CS and RIP to point to the reset vector.
+
+ @param[in] BufferStart The reset vector target.
+ @param[in] Code16 16-bit protected mode code segment value.
+ @param[in] Code32 32-bit protected mode code segment value.
+ @param[in] StackStart The start of a stack to be used for transitioning
+ from long mode to real mode.
+**/
+typedef
+VOID
+(EFIAPI AP_RESET) (
+ IN UINTN BufferStart,
+ IN UINT16 Code16,
+ IN UINT16 Code32,
+ IN UINTN StackStart
+ );
+
extern EFI_GUID mCpuInitMpLibHobGuid;
/**
@@ -385,6 +432,19 @@ GetModeTransitionBuffer (
IN UINTN BufferSize
);
+/**
+ Return the address of the SEV-ES AP jump table.
+
+ This buffer is required in order for an SEV-ES guest to transition from
+ UEFI into an OS.
+
+ @return Return SEV-ES AP jump table buffer
+**/
+UINTN
+GetSevEsAPMemory (
+ VOID
+ );
+
/**
This function will be called by BSP to wakeup AP.
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 8ccddf8e9f9c..9115ff9e3e30 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -12,6 +12,8 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/DxeServicesTableLib.h>
+#include <Register/Amd/Fam17Msr.h>
+#include <Register/Amd/Ghcb.h>
#include <Protocol/Timer.h>
@@ -144,6 +146,39 @@ GetModeTransitionBuffer (
return (UINTN)StartAddress;
}
+/**
+ Return the address of the SEV-ES AP jump table.
+
+ This buffer is required in order for an SEV-ES guest to transition from
+ UEFI into an OS.
+
+ @return Return SEV-ES AP jump table buffer
+**/
+UINTN
+GetSevEsAPMemory (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS StartAddress;
+
+ //
+ // Allocate 1 page for AP jump table page
+ //
+ StartAddress = BASE_4GB - 1;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ 1,
+ &StartAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "Dxe: SevEsAPMemory = %lx\n", (UINTN) StartAddress));
+
+ return (UINTN) StartAddress;
+}
+
/**
Checks APs status and updates APs status if needed.
@@ -218,6 +253,38 @@ CheckApsStatus (
}
}
+/**
+ Get Protected mode code segment with 16-bit default addressing
+ from current GDT table.
+
+ @return Protected mode 16-bit code segment value.
+**/
+UINT16
+GetProtectedMode16CS (
+ VOID
+ )
+{
+ IA32_DESCRIPTOR GdtrDesc;
+ IA32_SEGMENT_DESCRIPTOR *GdtEntry;
+ UINTN GdtEntryCount;
+ UINT16 Index;
+
+ Index = (UINT16) -1;
+ AsmReadGdtr (&GdtrDesc);
+ GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
+ GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;
+ for (Index = 0; Index < GdtEntryCount; Index++) {
+ if (GdtEntry->Bits.L == 0) {
+ if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 0) {
+ break;
+ }
+ }
+ GdtEntry++;
+ }
+ ASSERT (Index != GdtEntryCount);
+ return Index * 8;
+}
+
/**
Get Protected mode code segment from current GDT table.
@@ -238,7 +305,7 @@ GetProtectedModeCS (
GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;
for (Index = 0; Index < GdtEntryCount; Index++) {
if (GdtEntry->Bits.L == 0) {
- if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.L == 0) {
+ if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 1) {
break;
}
}
@@ -300,6 +367,7 @@ MpInitChangeApLoopCallback (
CpuMpData = GetCpuMpData ();
CpuMpData->PmCodeSegment = GetProtectedModeCS ();
+ CpuMpData->Pm16CodeSegment = GetProtectedMode16CS ();
CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
mNumberToFinish = CpuMpData->CpuCount - 1;
WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE);
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index a8b605f569bf..7da686d634f8 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -9,6 +9,9 @@
**/
#include "MpLib.h"
+#include <Library/VmgExitLib.h>
+#include <Register/Amd/Fam17Msr.h>
+#include <Register/Amd/Ghcb.h>
EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
@@ -314,6 +317,14 @@ GetApLoopMode (
//
ApLoopMode = ApInHltLoop;
}
+
+ if (PcdGetBool (PcdSevEsIsEnabled)) {
+ //
+ // For SEV-ES, force AP in Hlt-loop mode in order to use the GHCB
+ // protocol for starting APs
+ //
+ ApLoopMode = ApInHltLoop;
+ }
}
if (ApLoopMode != ApInMwaitLoop) {
@@ -610,6 +621,112 @@ InitializeApData (
SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
}
+/**
+ Get Protected mode code segment with 16-bit default addressing
+ from current GDT table.
+
+ @return Protected mode 16-bit code segment value.
+**/
+STATIC
+UINT16
+GetProtectedMode16CS (
+ VOID
+ )
+{
+ IA32_DESCRIPTOR GdtrDesc;
+ IA32_SEGMENT_DESCRIPTOR *GdtEntry;
+ UINTN GdtEntryCount;
+ UINT16 Index;
+
+ Index = (UINT16) -1;
+ AsmReadGdtr (&GdtrDesc);
+ GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
+ GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;
+ for (Index = 0; Index < GdtEntryCount; Index++) {
+ if (GdtEntry->Bits.L == 0 &&
+ GdtEntry->Bits.DB == 0 &&
+ GdtEntry->Bits.Type > 8) {
+ break;
+ }
+ GdtEntry++;
+ }
+ ASSERT (Index != GdtEntryCount);
+ return Index * 8;
+}
+
+/**
+ Get Protected mode code segment with 32-bit default addressing
+ from current GDT table.
+
+ @return Protected mode 32-bit code segment value.
+**/
+STATIC
+UINT16
+GetProtectedMode32CS (
+ VOID
+ )
+{
+ IA32_DESCRIPTOR GdtrDesc;
+ IA32_SEGMENT_DESCRIPTOR *GdtEntry;
+ UINTN GdtEntryCount;
+ UINT16 Index;
+
+ Index = (UINT16) -1;
+ AsmReadGdtr (&GdtrDesc);
+ GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);
+ GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;
+ for (Index = 0; Index < GdtEntryCount; Index++) {
+ if (GdtEntry->Bits.L == 0 &&
+ GdtEntry->Bits.DB == 1 &&
+ GdtEntry->Bits.Type > 8) {
+ break;
+ }
+ GdtEntry++;
+ }
+ ASSERT (Index != GdtEntryCount);
+ return Index * 8;
+}
+
+/**
+ Reset an AP when in SEV-ES mode.
+
+ If successful, this function never returns.
+
+ @param[in] Ghcb Pointer to the GHCB
+ @param[in] CpuMpData Pointer to CPU MP Data
+
+**/
+STATIC
+VOID
+MpInitLibSevEsAPReset (
+ IN GHCB *Ghcb,
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
+ UINT16 Code16, Code32;
+ AP_RESET *APResetFn;
+ UINTN BufferStart;
+ UINTN StackStart;
+
+ Code16 = GetProtectedMode16CS ();
+ Code32 = GetProtectedMode32CS ();
+
+ if (CpuMpData->WakeupBufferHigh != 0) {
+ APResetFn = (AP_RESET *) (CpuMpData->WakeupBufferHigh + CpuMpData->AddressMap.SwitchToRealNoNxOffset);
+ } else {
+ APResetFn = (AP_RESET *) (CpuMpData->MpCpuExchangeInfo->BufferStart + CpuMpData->AddressMap.SwitchToRealOffset);
+ }
+
+ BufferStart = CpuMpData->MpCpuExchangeInfo->BufferStart;
+ StackStart = CpuMpData->SevEsAPResetStackStart -
+ (AP_RESET_STACK_SIZE * GetApicId ());
+
+ //
+ // This call never returns.
+ //
+ APResetFn (BufferStart, Code16, Code32, StackStart);
+}
+
/**
This function will be called from AP reset code if BSP uses WakeUpAP.
@@ -671,7 +788,14 @@ ApWakeupFunction (
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
- InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
+ //
+ // Delay decrementing the APs executing count when SEV-ES is enabled
+ // to allow the APs to issue an AP_RESET_HOLD before the BSP possibly
+ // performs another INIT-SIPI-SIPI sequence.
+ //
+ if (!CpuMpData->SevEsIsEnabled) {
+ InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
+ }
} else {
//
// Execute AP function if AP is ready
@@ -778,7 +902,52 @@ ApWakeupFunction (
//
while (TRUE) {
DisableInterrupts ();
- CpuSleep ();
+ if (CpuMpData->SevEsIsEnabled) {
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
+ UINT64 Status;
+ BOOLEAN DoDecrement;
+
+ if (CpuMpData->InitFlag == ApInitConfig) {
+ DoDecrement = TRUE;
+ }
+
+ while (TRUE) {
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ VmgInit (Ghcb);
+
+ if (DoDecrement) {
+ DoDecrement = FALSE;
+
+ //
+ // Perform the delayed decrement just before issuing the first
+ // VMGEXIT with AP_RESET_HOLD.
+ //
+ InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
+ }
+
+ Status = VmgExit (Ghcb, SVM_EXIT_AP_RESET_HOLD, 0, 0);
+ if ((Status == 0) && (Ghcb->SaveArea.SwExitInfo2 != 0)) {
+ VmgDone (Ghcb);
+ break;
+ }
+
+ VmgDone (Ghcb);
+ }
+
+ //
+ // Awakened in a new phase? Use the new CpuMpData
+ //
+ if (CpuMpData->NewCpuMpData != NULL) {
+ CpuMpData = CpuMpData->NewCpuMpData;
+ }
+
+ MpInitLibSevEsAPReset (Ghcb, CpuMpData);
+ } else {
+ CpuSleep ();
+ }
CpuPause ();
}
}
@@ -891,6 +1060,9 @@ FillExchangeInfoData (
ExchangeInfo->Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1);
DEBUG ((DEBUG_INFO, "%a: 5-Level Paging = %d\n", gEfiCallerBaseName, ExchangeInfo->Enable5LevelPaging));
+ ExchangeInfo->SevEsIsEnabled = CpuMpData->SevEsIsEnabled;
+ ExchangeInfo->GhcbBase = (UINTN) CpuMpData->GhcbBase;
+
//
// Get the BSP's data of GDT and IDT
//
@@ -917,8 +1089,9 @@ FillExchangeInfoData (
// EfiBootServicesCode to avoid page fault if NX memory protection is enabled.
//
if (CpuMpData->WakeupBufferHigh != 0) {
- Size = CpuMpData->AddressMap.RendezvousFunnelSize -
- CpuMpData->AddressMap.ModeTransitionOffset;
+ Size = CpuMpData->AddressMap.RendezvousFunnelSize +
+ CpuMpData->AddressMap.SwitchToRealSize -
+ CpuMpData->AddressMap.ModeTransitionOffset;
CopyMem (
(VOID *)CpuMpData->WakeupBufferHigh,
CpuMpData->AddressMap.RendezvousFunnelAddress +
@@ -971,7 +1144,8 @@ BackupAndPrepareWakeupBuffer(
CopyMem (
(VOID *) CpuMpData->WakeupBuffer,
(VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,
- CpuMpData->AddressMap.RendezvousFunnelSize
+ CpuMpData->AddressMap.RendezvousFunnelSize +
+ CpuMpData->AddressMap.SwitchToRealSize
);
}
@@ -992,6 +1166,44 @@ RestoreWakeupBuffer(
);
}
+/**
+ Calculate the size of the reset stack.
+
+ @return Total amount of memory required for stacks
+**/
+STATIC
+UINTN
+GetApResetStackSize (
+ VOID
+ )
+{
+ return AP_RESET_STACK_SIZE * PcdGet32(PcdCpuMaxLogicalProcessorNumber);
+}
+
+/**
+ Calculate the size of the reset vector.
+
+ @param[in] AddressMap The pointer to Address Map structure.
+
+ @return Total amount of memory required for the AP reset area
+**/
+STATIC
+UINTN
+GetApResetVectorSize (
+ IN MP_ASSEMBLY_ADDRESS_MAP *AddressMap
+ )
+{
+ UINTN Size;
+
+ Size = ALIGN_VALUE (AddressMap->RendezvousFunnelSize +
+ AddressMap->SwitchToRealSize +
+ sizeof (MP_CPU_EXCHANGE_INFO),
+ CPU_STACK_ALIGNMENT);
+ Size += GetApResetStackSize ();
+
+ return Size;
+}
+
/**
Allocate reset vector buffer.
@@ -1005,16 +1217,22 @@ AllocateResetVector (
UINTN ApResetVectorSize;
if (CpuMpData->WakeupBuffer == (UINTN) -1) {
- ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
- sizeof (MP_CPU_EXCHANGE_INFO);
+ ApResetVectorSize = GetApResetVectorSize (&CpuMpData->AddressMap);
CpuMpData->WakeupBuffer = GetWakeupBuffer (ApResetVectorSize);
CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)
- (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);
+ (CpuMpData->WakeupBuffer +
+ CpuMpData->AddressMap.RendezvousFunnelSize +
+ CpuMpData->AddressMap.SwitchToRealSize);
CpuMpData->WakeupBufferHigh = GetModeTransitionBuffer (
- CpuMpData->AddressMap.RendezvousFunnelSize -
+ CpuMpData->AddressMap.RendezvousFunnelSize +
+ CpuMpData->AddressMap.SwitchToRealSize -
CpuMpData->AddressMap.ModeTransitionOffset
);
+ //
+ // The reset stack starts at the end of the buffer.
+ //
+ CpuMpData->SevEsAPResetStackStart = CpuMpData->WakeupBuffer + ApResetVectorSize;
}
BackupAndPrepareWakeupBuffer (CpuMpData);
}
@@ -1029,7 +1247,80 @@ FreeResetVector (
IN CPU_MP_DATA *CpuMpData
)
{
- RestoreWakeupBuffer (CpuMpData);
+ //
+ // If SEV-ES is enabled, the reset area is needed for AP parking and
+ // and AP startup in the OS, so the reset area is reserved. Do not
+ // perform the restore as this will overwrite memory which has data
+ // needed by SEV-ES.
+ //
+ if (!CpuMpData->SevEsIsEnabled) {
+ RestoreWakeupBuffer (CpuMpData);
+ }
+}
+
+/**
+ Allocate the SEV-ES AP jump table buffer.
+
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.
+**/
+VOID
+AllocateSevEsAPMemory (
+ IN OUT CPU_MP_DATA *CpuMpData
+ )
+{
+ if (CpuMpData->SevEsAPBuffer == (UINTN) -1) {
+ CpuMpData->SevEsAPBuffer =
+ CpuMpData->SevEsIsEnabled ? GetSevEsAPMemory () : 0;
+ }
+}
+
+/**
+ Program the SEV-ES AP jump table buffer.
+
+ @param[in] SipiVector The SIPI vector used for the AP Reset
+**/
+VOID
+SetSevEsJumpTable (
+ IN UINTN SipiVector
+ )
+{
+ SEV_ES_AP_JMP_FAR *JmpFar;
+ UINT32 Offset, InsnByte;
+ UINT8 LoNib, HiNib;
+
+ JmpFar = (SEV_ES_AP_JMP_FAR *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+ ASSERT (JmpFar != NULL);
+
+ //
+ // Obtain the address of the Segment/Rip location in the workarea.
+ // This will be set to a value derived from the SIPI vector and will
+ // be the memory address used for the far jump below.
+ //
+ Offset = FixedPcdGet32 (PcdSevEsWorkAreaBase);
+ Offset += sizeof (JmpFar->InsnBuffer);
+ LoNib = (UINT8) Offset;
+ HiNib = (UINT8) (Offset >> 8);
+
+ //
+ // Program the workarea (which is the initial AP boot address) with
+ // far jump to the SIPI vector (where XX and YY represent the
+ // address of where the SIPI vector is stored.
+ //
+ // JMP FAR [CS:XXYY] => 2E FF 2E YY XX
+ //
+ InsnByte = 0;
+ JmpFar->InsnBuffer[InsnByte++] = 0x2E; // CS override prefix
+ JmpFar->InsnBuffer[InsnByte++] = 0xFF; // JMP (FAR)
+ JmpFar->InsnBuffer[InsnByte++] = 0x2E; // ModRM (JMP memory location)
+ JmpFar->InsnBuffer[InsnByte++] = LoNib; // YY offset ...
+ JmpFar->InsnBuffer[InsnByte++] = HiNib; // XX offset ...
+
+ //
+ // Program the Segment/Rip based on the SIPI vector (always at least
+ // 16-byte aligned, so Rip is set to 0).
+ //
+ JmpFar->Rip = 0;
+ JmpFar->Segment = (UINT16) (SipiVector >> 4);
}
/**
@@ -1066,6 +1357,7 @@ WakeUpAP (
CpuMpData->InitFlag != ApInitDone) {
ResetVectorRequired = TRUE;
AllocateResetVector (CpuMpData);
+ AllocateSevEsAPMemory (CpuMpData);
FillExchangeInfoData (CpuMpData);
SaveLocalApicTimerSetting (CpuMpData);
}
@@ -1102,6 +1394,15 @@ WakeUpAP (
}
}
if (ResetVectorRequired) {
+ //
+ // For SEV-ES, the initial AP boot address will be defined by
+ // PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address
+ // from the original INIT-SIPI-SIPI.
+ //
+ if (CpuMpData->SevEsIsEnabled) {
+ SetSevEsJumpTable (ExchangeInfo->BufferStart);
+ }
+
//
// Wakeup all APs
//
@@ -1193,6 +1494,16 @@ WakeUpAP (
*(UINT32 *) CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
if (ResetVectorRequired) {
CpuInfoInHob = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
+
+ //
+ // For SEV-ES, the initial AP boot address will be defined by
+ // PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address
+ // from the original INIT-SIPI-SIPI.
+ //
+ if (CpuMpData->SevEsIsEnabled) {
+ SetSevEsJumpTable (ExchangeInfo->BufferStart);
+ }
+
SendInitSipiSipi (
CpuInfoInHob[ProcessorNumber].ApicId,
(UINT32) ExchangeInfo->BufferStart
@@ -1669,7 +1980,7 @@ MpInitLibInitialize (
ASSERT (MaxLogicalProcessorNumber != 0);
AsmGetAddressMap (&AddressMap);
- ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ ApResetVectorSize = GetApResetVectorSize (&AddressMap);
ApStackSize = PcdGet32(PcdCpuApStackSize);
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
@@ -1728,6 +2039,8 @@ MpInitLibInitialize (
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock(&CpuMpData->MpLock);
CpuMpData->SevEsIsEnabled = PcdGetBool (PcdSevEsIsEnabled);
+ CpuMpData->SevEsAPBuffer = (UINTN) -1;
+ CpuMpData->GhcbBase = PcdGet64 (PcdGhcbBase);
//
// Make sure no memory usage outside of the allocated buffer.
@@ -1786,6 +2099,7 @@ MpInitLibInitialize (
// APs have been wakeup before, just get the CPU Information
// from HOB
//
+ OldCpuMpData->NewCpuMpData = CpuMpData;
CpuMpData->CpuCount = OldCpuMpData->CpuCount;
CpuMpData->BspNumber = OldCpuMpData->BspNumber;
CpuMpData->CpuInfoInHob = OldCpuMpData->CpuInfoInHob;
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
index a548fed23fa7..3989bd6a7a9f 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
@@ -280,6 +280,25 @@ GetModeTransitionBuffer (
return 0;
}
+/**
+ Return the address of the SEV-ES AP jump table.
+
+ This buffer is required in order for an SEV-ES guest to transition from
+ UEFI into an OS.
+
+ @return Return SEV-ES AP jump table buffer
+**/
+UINTN
+GetSevEsAPMemory (
+ VOID
+ )
+{
+ //
+ // PEI phase doesn't need to do such transition. So simply return 0.
+ //
+ return 0;
+}
+
/**
Checks APs status and updates APs status if needed.
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
index 6298571e29b2..28f8e8e133e5 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
@@ -121,7 +121,7 @@ GetProtectedModeCS (
GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;
for (Index = 0; Index < GdtEntryCount; Index++) {
if (GdtEntry->Bits.L == 0) {
- if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.L == 0) {
+ if (GdtEntry->Bits.Type > 8 && GdtEntry->Bits.DB == 1) {
break;
}
}
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
index efb1bc2bf7cb..4f5a7c859a56 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
@@ -19,7 +19,7 @@ CPU_SWITCH_STATE_IDLE equ 0
CPU_SWITCH_STATE_STORED equ 1
CPU_SWITCH_STATE_LOADED equ 2
-LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
+LockLocation equ (SwitchToRealProcEnd - RendezvousFunnelProcStart)
StackStartAddressLocation equ LockLocation + 04h
StackSizeLocation equ LockLocation + 08h
ApProcedureLocation equ LockLocation + 0Ch
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index b74046b76af3..309d53bf3b37 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -215,6 +215,16 @@ CProcedureInvoke:
jmp $ ; Never reach here
RendezvousFunnelProcEnd:
+;-------------------------------------------------------------------------------------
+;SwitchToRealProc procedure follows.
+;NOT USED IN 32 BIT MODE.
+;-------------------------------------------------------------------------------------
+global ASM_PFX(SwitchToRealProc)
+ASM_PFX(SwitchToRealProc):
+SwitchToRealProcStart:
+ jmp $ ; Never reach here
+SwitchToRealProcEnd:
+
;-------------------------------------------------------------------------------------
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish);
;-------------------------------------------------------------------------------------
@@ -263,6 +273,11 @@ ASM_PFX(AsmGetAddressMap):
mov dword [ebx + 0Ch], AsmRelocateApLoopStart
mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
mov dword [ebx + 14h], Flat32Start - RendezvousFunnelProcStart
+ mov dword [ebx + 18h], SwitchToRealProcEnd - SwitchToRealProcStart ; SwitchToRealSize
+ mov dword [ebx + 1Ch], SwitchToRealProcStart - RendezvousFunnelProcStart ; SwitchToRealOffset
+ mov dword [ebx + 20h], SwitchToRealProcStart - Flat32Start ; SwitchToRealNoNxOffset
+ mov dword [ebx + 24h], 0 ; SwitchToRealPM16ModeOffset
+ mov dword [ebx + 28h], 0 ; SwitchToRealPM16ModeSize
popad
ret
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
index 58ef369342a7..c92daaaffd6b 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
@@ -19,7 +19,7 @@ CPU_SWITCH_STATE_IDLE equ 0
CPU_SWITCH_STATE_STORED equ 1
CPU_SWITCH_STATE_LOADED equ 2
-LockLocation equ (RendezvousFunnelProcEnd - RendezvousFunnelProcStart)
+LockLocation equ (SwitchToRealProcEnd - RendezvousFunnelProcStart)
StackStartAddressLocation equ LockLocation + 08h
StackSizeLocation equ LockLocation + 10h
ApProcedureLocation equ LockLocation + 18h
@@ -41,3 +41,5 @@ ModeTransitionSegmentLocation equ LockLocation + 98h
ModeHighMemoryLocation equ LockLocation + 9Ah
ModeHighSegmentLocation equ LockLocation + 9Eh
Enable5LevelPagingLocation equ LockLocation + 0A0h
+SevEsIsEnabledLocation equ LockLocation + 0A1h
+GhcbBaseLocation equ LockLocation + 0A2h
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 87f2523e856f..6956b408d004 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -184,9 +184,97 @@ Releaselock:
add edi, StackStartAddressLocation
add rax, qword [edi]
mov rsp, rax
+
+ lea edi, [esi + SevEsIsEnabledLocation]
+ cmp byte [edi], 1 ; SevEsIsEnabled
+ jne CProcedureInvoke
+
+ ;
+ ; program GHCB
+ ; Each page after the GHCB is a per-CPU page, so the calculation programs
+ ; a GHCB to be every 8KB.
+ ;
+ mov eax, SIZE_4KB
+ shl eax, 1 ; EAX = SIZE_4K * 2
+ mov ecx, ebx
+ mul ecx ; EAX = SIZE_4K * 2 * CpuNumber
+ mov edi, esi
+ add edi, GhcbBaseLocation
+ add rax, qword [edi]
+ mov rdx, rax
+ shr rdx, 32
+ mov rcx, 0xc0010130
+ wrmsr
jmp CProcedureInvoke
GetApicId:
+ lea edi, [esi + SevEsIsEnabledLocation]
+ cmp byte [edi], 1 ; SevEsIsEnabled
+ jne DoCpuid
+
+ ;
+ ; Since we don't have a stack yet, we can't take a #VC
+ ; exception. Use the GHCB protocol to perform the CPUID
+ ; calls.
+ ;
+ mov rcx, 0xc0010130
+ rdmsr
+ shl rdx, 32
+ or rax, rdx
+ mov rdi, rax ; RDI now holds the original GHCB GPA
+
+ mov rdx, 0 ; CPUID function 0
+ mov rax, 0 ; RAX register requested
+ or rax, 4
+ wrmsr
+ rep vmmcall
+ rdmsr
+ cmp edx, 0bh
+ jb NoX2ApicSevEs ; CPUID level below CPUID_EXTENDED_TOPOLOGY
+
+ mov rdx, 0bh ; CPUID function 0x0b
+ mov rax, 040000000h ; RBX register requested
+ or rax, 4
+ wrmsr
+ rep vmmcall
+ rdmsr
+ test edx, 0ffffh
+ jz NoX2ApicSevEs ; CPUID.0BH:EBX[15:0] is zero
+
+ mov rdx, 0bh ; CPUID function 0x0b
+ mov rax, 0c0000000h ; RDX register requested
+ or rax, 4
+ wrmsr
+ rep vmmcall
+ rdmsr
+
+ ; Processor is x2APIC capable; 32-bit x2APIC ID is now in EDX
+ jmp RestoreGhcb
+
+NoX2ApicSevEs:
+ ; Processor is not x2APIC capable, so get 8-bit APIC ID
+ mov rdx, 1 ; CPUID function 1
+ mov rax, 040000000h ; RBX register requested
+ or rax, 4
+ wrmsr
+ rep vmmcall
+ rdmsr
+ shr edx, 24
+
+RestoreGhcb:
+ mov rbx, rdx ; Save x2APIC/APIC ID
+
+ mov rdx, rdi ; RDI holds the saved GHCB GPA
+ shr rdx, 32
+ mov eax, edi
+ wrmsr
+
+ mov rdx, rbx
+
+ ; x2APIC ID or APIC ID is in EDX
+ jmp GetProcessorNumber
+
+DoCpuid:
mov eax, 0
cpuid
cmp eax, 0bh
@@ -253,12 +341,158 @@ CProcedureInvoke:
RendezvousFunnelProcEnd:
+;-------------------------------------------------------------------------------------
+;SwitchToRealProc procedure follows.
+;ALSO THIS PROCEDURE IS EXECUTED BY APs TRANSITIONING TO 16 BIT MODE. HENCE THIS PROC
+;IS IN MACHINE CODE.
+; SwitchToRealProc (UINTN BufferStart, UINT16 Code16, UINT16 Code32, UINTN StackStart)
+; rcx - Buffer Start
+; rdx - Code16 Selector Offset
+; r8 - Code32 Selector Offset
+; r9 - Stack Start
+;-------------------------------------------------------------------------------------
+global ASM_PFX(SwitchToRealProc)
+ASM_PFX(SwitchToRealProc):
+SwitchToRealProcStart:
+BITS 64
+ cli
+
+ ;
+ ; Get RDX reset value before changing stacks since the
+ ; new stack won't be able to accomodate a #VC exception.
+ ;
+ push rax
+ push rbx
+ push rcx
+ push rdx
+
+ mov rax, 1
+ cpuid
+ mov rsi, rax ; Save off the reset value for RDX
+
+ pop rdx
+ pop rcx
+ pop rbx
+ pop rax
+
+ ;
+ ; Establish stack below 1MB
+ ;
+ mov rsp, r9
+
+ ;
+ ; Push ultimate Reset Vector onto the stack
+ ;
+ mov rax, rcx
+ shr rax, 4
+ push word 0x0002 ; RFLAGS
+ push ax ; CS
+ push word 0x0000 ; RIP
+ push word 0x0000 ; For alignment, will be discarded
+
+ ;
+ ; Get address of "16-bit operand size" label
+ ;
+ lea rbx, [PM16Mode]
+
+ ;
+ ; Push addresses used to change to compatibility mode
+ ;
+ lea rax, [CompatMode]
+ push r8
+ push rax
+
+ ;
+ ; Clear R8 - R15, for reset, before going into 32-bit mode
+ ;
+ xor r8, r8
+ xor r9, r9
+ xor r10, r10
+ xor r11, r11
+ xor r12, r12
+ xor r13, r13
+ xor r14, r14
+ xor r15, r15
+
+ ;
+ ; Far return into 32-bit mode
+ ;
+o64 retf
+
+BITS 32
+CompatMode:
+ ;
+ ; Set up stack to prepare for exiting protected mode
+ ;
+ push edx ; Code16 CS
+ push ebx ; PM16Mode label address
+
+ ;
+ ; Disable paging
+ ;
+ mov eax, cr0 ; Read CR0
+ btr eax, 31 ; Set PG=0
+ mov cr0, eax ; Write CR0
+
+ ;
+ ; Disable long mode
+ ;
+ mov ecx, 0c0000080h ; EFER MSR number
+ rdmsr ; Read EFER
+ btr eax, 8 ; Set LME=0
+ wrmsr ; Write EFER
+
+ ;
+ ; Disable PAE
+ ;
+ mov eax, cr4 ; Read CR4
+ btr eax, 5 ; Set PAE=0
+ mov cr4, eax ; Write CR4
+
+ mov edx, esi ; Restore RDX reset value
+
+ ;
+ ; Switch to 16-bit operand size
+ ;
+ retf
+
+BITS 16
+ ;
+ ; At entry to this label
+ ; - RDX will have its reset value
+ ; - On the top of the stack
+ ; - Alignment data (two bytes) to be discarded
+ ; - IP for Real Mode (two bytes)
+ ; - CS for Real Mode (two bytes)
+ ;
+PM16Mode:
+ mov eax, cr0 ; Read CR0
+ btr eax, 0 ; Set PE=0
+ mov cr0, eax ; Write CR0
+
+ pop ax ; Discard alignment data
+
+ ;
+ ; Clear registers (except RDX and RSP) before going into 16-bit mode
+ ;
+ xor eax, eax
+ xor ebx, ebx
+ xor ecx, ecx
+ xor esi, esi
+ xor edi, edi
+ xor ebp, ebp
+
+ iret
+
+SwitchToRealProcEnd:
+
;-------------------------------------------------------------------------------------
; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish);
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmRelocateApLoop)
ASM_PFX(AsmRelocateApLoop):
AsmRelocateApLoopStart:
+BITS 64
cli ; Disable interrupt before switching to 32-bit mode
mov rax, [rsp + 40] ; CountTofinish
lock dec dword [rax] ; (*CountTofinish)--
@@ -324,6 +558,11 @@ ASM_PFX(AsmGetAddressMap):
mov qword [rcx + 18h], rax
mov qword [rcx + 20h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
mov qword [rcx + 28h], Flat32Start - RendezvousFunnelProcStart
+ mov qword [rcx + 30h], SwitchToRealProcEnd - SwitchToRealProcStart ; SwitchToRealSize
+ mov qword [rcx + 38h], SwitchToRealProcStart - RendezvousFunnelProcStart ; SwitchToRealOffset
+ mov qword [rcx + 40h], SwitchToRealProcStart - Flat32Start ; SwitchToRealNoNxOffset
+ mov qword [rcx + 48h], PM16Mode - RendezvousFunnelProcStart ; SwitchToRealPM16ModeOffset
+ mov qword [rcx + 50h], SwitchToRealProcEnd - PM16Mode ; SwitchToRealPM16ModeSize
ret
;-------------------------------------------------------------------------------------
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (41 preceding siblings ...)
2020-06-05 17:58 ` [PATCH v9 42/46] UefiCpuPkg: Allow AP booting under SEV-ES Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-18 7:43 ` Dong, Eric
2020-06-05 17:58 ` [PATCH v9 44/46] OvmfPkg: Move the GHCB allocations into reserved memory Lendacky, Thomas
` (2 subsequent siblings)
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
A hypervisor is not allowed to update an SEV-ES guest's register state,
so when booting an SEV-ES guest AP, the hypervisor is not allowed to
set the RIP to the guest requested value. Instead an SEV-ES AP must be
re-directed from within the guest to the actual requested staring location
as specified in the INIT-SIPI-SIPI sequence.
Use the SEV-ES work area for the reset vector code that contains support
to jump to the desired RIP location after having been started. This is
required for only the very first AP reset.
This new OVMF source file, ResetVectorVtf0.asm, is used in place of the
original file through the use of the include path order set in
OvmfPkg/ResetVector/ResetVector.inf under "[BuildOptions]".
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 ++++++++++++++++++++
OvmfPkg/ResetVector/ResetVector.nasmb | 1 +
2 files changed, 101 insertions(+)
diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
new file mode 100644
index 000000000000..980e0138e7fe
--- /dev/null
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -0,0 +1,100 @@
+;------------------------------------------------------------------------------
+; @file
+; First code executed by processor after resetting.
+; Derived from UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
+;
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+BITS 16
+
+ALIGN 16
+
+;
+; Pad the image size to 4k when page tables are in VTF0
+;
+; If the VTF0 image has page tables built in, then we need to make
+; sure the end of VTF0 is 4k above where the page tables end.
+;
+; This is required so the page tables will be 4k aligned when VTF0 is
+; located just below 0x100000000 (4GB) in the firmware device.
+;
+%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
+ TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
+%endif
+
+;
+; SEV-ES Processor Reset support
+;
+; sevEsResetBlock:
+; For the initial boot of an AP under SEV-ES, the "reset" RIP must be
+; programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A known offset
+; and GUID will be used to locate this block in the firmware and extract
+; the build time RIP value. The GUID must always be 48 bytes from the
+; end of the firmware.
+;
+; 0xffffffca (-0x36) - IP value
+; 0xffffffcc (-0x34) - CS segment base [31:16]
+; 0xffffffce (-0x32) - Size of the SEV-ES reset block
+; 0xffffffd0 (-0x30) - SEV-ES reset block GUID
+; (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
+;
+; A hypervisor reads the CS segement base and IP value. The CS segment base
+; value represents the high order 16-bits of the CS segment base, so the
+; hypervisor must left shift the value of the CS segement base by 16 bits to
+; form the full CS segment base for the CS segment register. It would then
+; program the EIP register with the IP value as read.
+;
+
+TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
+
+sevEsResetBlockStart:
+ DD SEV_ES_AP_RESET_IP
+ DW sevEsResetBlockEnd - sevEsResetBlockStart
+ DB 0xDE, 0x71, 0xF7, 0x00, 0x7E, 0x1A, 0xCB, 0x4F
+ DB 0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
+sevEsResetBlockEnd:
+
+ALIGN 16
+
+applicationProcessorEntryPoint:
+;
+; Application Processors entry point
+;
+; GenFv generates code aligned on a 4k boundary which will jump to this
+; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
+; used to wake up the application processors.
+;
+ jmp EarlyApInitReal16
+
+ALIGN 8
+
+ DD 0
+
+;
+; The VTF signature
+;
+; VTF-0 means that the VTF (Volume Top File) code does not require
+; any fixups.
+;
+vtfSignature:
+ DB 'V', 'T', 'F', 0
+
+ALIGN 16
+
+resetVector:
+;
+; Reset Vector
+;
+; This is where the processor will begin execution
+;
+ nop
+ nop
+ jmp EarlyBspInitReal16
+
+ALIGN 16
+
+fourGigabytes:
+
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 762661115d50..4913b379a993 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -82,5 +82,6 @@
%include "Main.asm"
+ %define SEV_ES_AP_RESET_IP FixedPcdGet32 (PcdSevEsWorkAreaBase)
%include "Ia16/ResetVectorVtf0.asm"
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
2020-06-05 17:58 ` [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
@ 2020-06-18 7:43 ` Dong, Eric
2020-06-18 14:50 ` Lendacky, Thomas
0 siblings, 1 reply; 103+ messages in thread
From: Dong, Eric @ 2020-06-18 7:43 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
Hi Tom,
We use GCC5 to build the OVMF platform and report below errors, please help to check and fix it.
I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/MdeModulePkg/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/MdeModulePkg/Include/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/Include/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/ResetVector/Vtf0/ -o /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii
/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii:72: error: expression syntax error
/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii:74: error: label or instruction expected at start of line
Ia32/PageTables64.asm:27: error: label or instruction expected at start of line
Ia32/PageTables64.asm:29: error: label or instruction expected at start of line
Ia32/PageTables64.asm:30: error: label or instruction expected at start of line
Ia32/PageTables64.asm:369: error: expression syntax error
GNUmakefile:319: recipe for target '/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin' failed
make: *** [/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin] Error 1
build.py...
: error 7000: Failed to execute command
make tbuild [/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector]
build.py...
: error F002: Failed to build module
/opt/TCAgent/work/f9b29f3e80472c44/Edk2/OvmfPkg/ResetVector/ResetVector.inf [X64, GCC5, DEBUG]
====================================================
Related platform build configuration like below:
WORKSPACE = /opt/TCAgent/work/f9b29f3e80472c44/Edk2
EDK_TOOLS_PATH = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/BaseTools
CONF_PATH = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Conf
PYTHON_COMMAND = /usr/bin/python3.5
Architecture(s) = X64
Build target = DEBUG
Toolchain = GCC5
Active Platform = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/OvmfPkg/OvmfPkgX64.dsc
Thanks,
Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Friday, June 5, 2020 9:28 PM
> To: devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-
> ES AP reset vector
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> A hypervisor is not allowed to update an SEV-ES guest's register state,
> so when booting an SEV-ES guest AP, the hypervisor is not allowed to
> set the RIP to the guest requested value. Instead an SEV-ES AP must be
> re-directed from within the guest to the actual requested staring location
> as specified in the INIT-SIPI-SIPI sequence.
>
> Use the SEV-ES work area for the reset vector code that contains support
> to jump to the desired RIP location after having been started. This is
> required for only the very first AP reset.
>
> This new OVMF source file, ResetVectorVtf0.asm, is used in place of the
> original file through the use of the include path order set in
> OvmfPkg/ResetVector/ResetVector.inf under "[BuildOptions]".
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100
> ++++++++++++++++++++
> OvmfPkg/ResetVector/ResetVector.nasmb | 1 +
> 2 files changed, 101 insertions(+)
>
> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> new file mode 100644
> index 000000000000..980e0138e7fe
> --- /dev/null
> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> @@ -0,0 +1,100 @@
> +;------------------------------------------------------------------------------
>
> +; @file
>
> +; First code executed by processor after resetting.
>
> +; Derived from UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
>
> +;
>
> +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +;
>
> +;------------------------------------------------------------------------------
>
> +
>
> +BITS 16
>
> +
>
> +ALIGN 16
>
> +
>
> +;
>
> +; Pad the image size to 4k when page tables are in VTF0
>
> +;
>
> +; If the VTF0 image has page tables built in, then we need to make
>
> +; sure the end of VTF0 is 4k above where the page tables end.
>
> +;
>
> +; This is required so the page tables will be 4k aligned when VTF0 is
>
> +; located just below 0x100000000 (4GB) in the firmware device.
>
> +;
>
> +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
>
> + TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
>
> +%endif
>
> +
>
> +;
>
> +; SEV-ES Processor Reset support
>
> +;
>
> +; sevEsResetBlock:
>
> +; For the initial boot of an AP under SEV-ES, the "reset" RIP must be
>
> +; programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A
> known offset
>
> +; and GUID will be used to locate this block in the firmware and extract
>
> +; the build time RIP value. The GUID must always be 48 bytes from the
>
> +; end of the firmware.
>
> +;
>
> +; 0xffffffca (-0x36) - IP value
>
> +; 0xffffffcc (-0x34) - CS segment base [31:16]
>
> +; 0xffffffce (-0x32) - Size of the SEV-ES reset block
>
> +; 0xffffffd0 (-0x30) - SEV-ES reset block GUID
>
> +; (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
>
> +;
>
> +; A hypervisor reads the CS segement base and IP value. The CS segment
> base
>
> +; value represents the high order 16-bits of the CS segment base, so the
>
> +; hypervisor must left shift the value of the CS segement base by 16 bits to
>
> +; form the full CS segment base for the CS segment register. It would then
>
> +; program the EIP register with the IP value as read.
>
> +;
>
> +
>
> +TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
>
> +
>
> +sevEsResetBlockStart:
>
> + DD SEV_ES_AP_RESET_IP
>
> + DW sevEsResetBlockEnd - sevEsResetBlockStart
>
> + DB 0xDE, 0x71, 0xF7, 0x00, 0x7E, 0x1A, 0xCB, 0x4F
>
> + DB 0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
>
> +sevEsResetBlockEnd:
>
> +
>
> +ALIGN 16
>
> +
>
> +applicationProcessorEntryPoint:
>
> +;
>
> +; Application Processors entry point
>
> +;
>
> +; GenFv generates code aligned on a 4k boundary which will jump to this
>
> +; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
>
> +; used to wake up the application processors.
>
> +;
>
> + jmp EarlyApInitReal16
>
> +
>
> +ALIGN 8
>
> +
>
> + DD 0
>
> +
>
> +;
>
> +; The VTF signature
>
> +;
>
> +; VTF-0 means that the VTF (Volume Top File) code does not require
>
> +; any fixups.
>
> +;
>
> +vtfSignature:
>
> + DB 'V', 'T', 'F', 0
>
> +
>
> +ALIGN 16
>
> +
>
> +resetVector:
>
> +;
>
> +; Reset Vector
>
> +;
>
> +; This is where the processor will begin execution
>
> +;
>
> + nop
>
> + nop
>
> + jmp EarlyBspInitReal16
>
> +
>
> +ALIGN 16
>
> +
>
> +fourGigabytes:
>
> +
>
> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb
> b/OvmfPkg/ResetVector/ResetVector.nasmb
> index 762661115d50..4913b379a993 100644
> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
> @@ -82,5 +82,6 @@
>
>
> %include "Main.asm"
>
>
>
> + %define SEV_ES_AP_RESET_IP FixedPcdGet32 (PcdSevEsWorkAreaBase)
>
> %include "Ia16/ResetVectorVtf0.asm"
>
>
>
> --
> 2.27.0
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
2020-06-18 7:43 ` Dong, Eric
@ 2020-06-18 14:50 ` Lendacky, Thomas
2020-06-19 7:40 ` [edk2-devel] " Dong, Eric
0 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-18 14:50 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
On 6/18/20 2:43 AM, Dong, Eric wrote:
> Hi Tom,
Hi Eric,
>
> We use GCC5 to build the OVMF platform and report below errors, please help to check and fix it.
That's what I use when I build and have never encountered these errors. I
also ran the patches through the EDK2 CI and didn't get any errors.
I've noticed that the dependencies aren't always handle properly for these
files. Are you doing a clean build or an incremental build for this patch?
Can you delete your Build directory and rebuild and see if you still get
the errors?
>
>
> I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/MdeModulePkg/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/MdeModulePkg/Include/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/Include/ -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/ResetVector/Vtf0/ -o /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii:72: error: expression syntax error
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii:74: error: label or instruction expected at start of line > Ia32/PageTables64.asm:27: error: label or instruction expected at start
of line
> Ia32/PageTables64.asm:29: error: label or instruction expected at start of line
> Ia32/PageTables64.asm:30: error: label or instruction expected at start of line
> Ia32/PageTables64.asm:369: error: expression syntax error
Can you paste the relevant portion of these files in an email or send
copies of those files to me?
Thanks,
Tom
> GNUmakefile:319: recipe for target '/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin' failed
> make: *** [/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin] Error 1
>
>
> build.py...
> : error 7000: Failed to execute command
> make tbuild [/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/X64/OvmfPkg/ResetVector/ResetVector]
>
>
> build.py...
> : error F002: Failed to build module
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/OvmfPkg/ResetVector/ResetVector.inf [X64, GCC5, DEBUG]
>
> ====================================================
> Related platform build configuration like below:
>
> WORKSPACE = /opt/TCAgent/work/f9b29f3e80472c44/Edk2
> EDK_TOOLS_PATH = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/BaseTools
> CONF_PATH = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Conf
> PYTHON_COMMAND = /usr/bin/python3.5
>
> Architecture(s) = X64
> Build target = DEBUG
> Toolchain = GCC5
>
> Active Platform = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/OvmfPkg/OvmfPkgX64.dsc
>
>
> Thanks,
> Eric
>> -----Original Message-----
>> From: Tom Lendacky <thomas.lendacky@amd.com>
>> Sent: Friday, June 5, 2020 9:28 PM
>> To: devel@edk2.groups.io
>> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
>> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
>> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
>> Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-
>> ES AP reset vector
>>
>> 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%7C68b736db1acf4493c24308d8135b4a75%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637280630097752935&sdata=R8sYtSa7bQXgeW4tiSAxDdwcoZaldq4%2BoN2Xn378JMc%3D&reserved=0
>>
>> A hypervisor is not allowed to update an SEV-ES guest's register state,
>> so when booting an SEV-ES guest AP, the hypervisor is not allowed to
>> set the RIP to the guest requested value. Instead an SEV-ES AP must be
>> re-directed from within the guest to the actual requested staring location
>> as specified in the INIT-SIPI-SIPI sequence.
>>
>> Use the SEV-ES work area for the reset vector code that contains support
>> to jump to the desired RIP location after having been started. This is
>> required for only the very first AP reset.
>>
>> This new OVMF source file, ResetVectorVtf0.asm, is used in place of the
>> original file through the use of the include path order set in
>> OvmfPkg/ResetVector/ResetVector.inf under "[BuildOptions]".
>>
>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100
>> ++++++++++++++++++++
>> OvmfPkg/ResetVector/ResetVector.nasmb | 1 +
>> 2 files changed, 101 insertions(+)
>>
>> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>> b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>> new file mode 100644
>> index 000000000000..980e0138e7fe
>> --- /dev/null
>> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>> @@ -0,0 +1,100 @@
>> +;------------------------------------------------------------------------------
>>
>> +; @file
>>
>> +; First code executed by processor after resetting.
>>
>> +; Derived from UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
>>
>> +;
>>
>> +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
>>
>> +; SPDX-License-Identifier: BSD-2-Clause-Patent
>>
>> +;
>>
>> +;------------------------------------------------------------------------------
>>
>> +
>>
>> +BITS 16
>>
>> +
>>
>> +ALIGN 16
>>
>> +
>>
>> +;
>>
>> +; Pad the image size to 4k when page tables are in VTF0
>>
>> +;
>>
>> +; If the VTF0 image has page tables built in, then we need to make
>>
>> +; sure the end of VTF0 is 4k above where the page tables end.
>>
>> +;
>>
>> +; This is required so the page tables will be 4k aligned when VTF0 is
>>
>> +; located just below 0x100000000 (4GB) in the firmware device.
>>
>> +;
>>
>> +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
>>
>> + TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
>>
>> +%endif
>>
>> +
>>
>> +;
>>
>> +; SEV-ES Processor Reset support
>>
>> +;
>>
>> +; sevEsResetBlock:
>>
>> +; For the initial boot of an AP under SEV-ES, the "reset" RIP must be
>>
>> +; programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A
>> known offset
>>
>> +; and GUID will be used to locate this block in the firmware and extract
>>
>> +; the build time RIP value. The GUID must always be 48 bytes from the
>>
>> +; end of the firmware.
>>
>> +;
>>
>> +; 0xffffffca (-0x36) - IP value
>>
>> +; 0xffffffcc (-0x34) - CS segment base [31:16]
>>
>> +; 0xffffffce (-0x32) - Size of the SEV-ES reset block
>>
>> +; 0xffffffd0 (-0x30) - SEV-ES reset block GUID
>>
>> +; (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
>>
>> +;
>>
>> +; A hypervisor reads the CS segement base and IP value. The CS segment
>> base
>>
>> +; value represents the high order 16-bits of the CS segment base, so the
>>
>> +; hypervisor must left shift the value of the CS segement base by 16 bits to
>>
>> +; form the full CS segment base for the CS segment register. It would then
>>
>> +; program the EIP register with the IP value as read.
>>
>> +;
>>
>> +
>>
>> +TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
>>
>> +
>>
>> +sevEsResetBlockStart:
>>
>> + DD SEV_ES_AP_RESET_IP
>>
>> + DW sevEsResetBlockEnd - sevEsResetBlockStart
>>
>> + DB 0xDE, 0x71, 0xF7, 0x00, 0x7E, 0x1A, 0xCB, 0x4F
>>
>> + DB 0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
>>
>> +sevEsResetBlockEnd:
>>
>> +
>>
>> +ALIGN 16
>>
>> +
>>
>> +applicationProcessorEntryPoint:
>>
>> +;
>>
>> +; Application Processors entry point
>>
>> +;
>>
>> +; GenFv generates code aligned on a 4k boundary which will jump to this
>>
>> +; location. (0xffffffe0) This allows the Local APIC Startup IPI to be
>>
>> +; used to wake up the application processors.
>>
>> +;
>>
>> + jmp EarlyApInitReal16
>>
>> +
>>
>> +ALIGN 8
>>
>> +
>>
>> + DD 0
>>
>> +
>>
>> +;
>>
>> +; The VTF signature
>>
>> +;
>>
>> +; VTF-0 means that the VTF (Volume Top File) code does not require
>>
>> +; any fixups.
>>
>> +;
>>
>> +vtfSignature:
>>
>> + DB 'V', 'T', 'F', 0
>>
>> +
>>
>> +ALIGN 16
>>
>> +
>>
>> +resetVector:
>>
>> +;
>>
>> +; Reset Vector
>>
>> +;
>>
>> +; This is where the processor will begin execution
>>
>> +;
>>
>> + nop
>>
>> + nop
>>
>> + jmp EarlyBspInitReal16
>>
>> +
>>
>> +ALIGN 16
>>
>> +
>>
>> +fourGigabytes:
>>
>> +
>>
>> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb
>> b/OvmfPkg/ResetVector/ResetVector.nasmb
>> index 762661115d50..4913b379a993 100644
>> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
>> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
>> @@ -82,5 +82,6 @@
>>
>>
>> %include "Main.asm"
>>
>>
>>
>> + %define SEV_ES_AP_RESET_IP FixedPcdGet32 (PcdSevEsWorkAreaBase)
>>
>> %include "Ia16/ResetVectorVtf0.asm"
>>
>>
>>
>> --
>> 2.27.0
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [edk2-devel] [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
2020-06-18 14:50 ` Lendacky, Thomas
@ 2020-06-19 7:40 ` Dong, Eric
0 siblings, 0 replies; 103+ messages in thread
From: Dong, Eric @ 2020-06-19 7:40 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Brijesh Singh, Ard Biesheuvel, Justen, Jordan L, Laszlo Ersek,
Gao, Liming, Kinney, Michael D, Ni, Ray
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Thursday, June 18, 2020 10:51 PM
> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> <ard.biesheuvel@arm.com>; Justen, Jordan L <jordan.l.justen@intel.com>;
> Laszlo Ersek <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work
> area for the SEV-ES AP reset vector
>
> On 6/18/20 2:43 AM, Dong, Eric wrote:
> > Hi Tom,
>
> Hi Eric,
>
> >
> > We use GCC5 to build the OVMF platform and report below errors, please
> help to check and fix it.
>
> That's what I use when I build and have never encountered these errors. I
> also ran the patches through the EDK2 CI and didn't get any errors.
>
> I've noticed that the dependencies aren't always handle properly for these
> files. Are you doing a clean build or an incremental build for this patch?
> Can you delete your Build directory and rebuild and see if you still get the
> errors?
I trig internal server build with your change and the build server found this issue.
I think it should use clean build.
>
> >
> >
> > I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/MdeModulePkg/
> > -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/MdeModulePkg/Include/
> > -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/
> > -I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/Include/
> > -
> I/opt/TCAgent/work/f9b29f3e80472c44/Edk2/UefiCpuPkg/ResetVector/Vtf0
> /
> > -o
> >
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/
> X64/O
> > vmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin
> >
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/
> X64/O
> > vmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii
> >
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/
> X64/O
> > vmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii:72: error:
> > expression syntax error
> >
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/
> X64/O
> > vmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.iii:74: error: label
> > or instruction expected at start of line > Ia32/PageTables64.asm:27:
> > error: label or instruction expected at start
> of line
> > Ia32/PageTables64.asm:29: error: label or instruction expected at
> > start of line
> > Ia32/PageTables64.asm:30: error: label or instruction expected at
> > start of line
> > Ia32/PageTables64.asm:369: error: expression syntax error
>
> Can you paste the relevant portion of these files in an email or send copies of
> those files to me?
Because the build is in internal sever and I can't copy the build file from it.
If you think you have pass all the test, I can rerun the test and check the result again.
Thanks,
Eric
>
> Thanks,
> Tom
>
> > GNUmakefile:319: recipe for target
> >
> '/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5/
> X64/
> > OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin' failed
> > make: ***
> >
> [/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5
> /X64/
> > OvmfPkg/ResetVector/ResetVector/OUTPUT/ResetVector.bin] Error 1
> >
> >
> > build.py...
> > : error 7000: Failed to execute command
> > make tbuild
> >
> [/opt/TCAgent/work/f9b29f3e80472c44/Edk2/Build/OvmfX64/DEBUG_GCC5
> /X64/
> > OvmfPkg/ResetVector/ResetVector]
> >
> >
> > build.py...
> > : error F002: Failed to build module
> >
> >
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/OvmfPkg/ResetVector/ResetV
> ecto
> > r.inf [X64, GCC5, DEBUG]
> >
> > ====================================================
> > Related platform build configuration like below:
> >
> > WORKSPACE = /opt/TCAgent/work/f9b29f3e80472c44/Edk2
> > EDK_TOOLS_PATH =
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/BaseTools
> > CONF_PATH = /opt/TCAgent/work/f9b29f3e80472c44/Edk2/Conf
> > PYTHON_COMMAND = /usr/bin/python3.5
> >
> > Architecture(s) = X64
> > Build target = DEBUG
> > Toolchain = GCC5
> >
> > Active Platform =
> /opt/TCAgent/work/f9b29f3e80472c44/Edk2/OvmfPkg/OvmfPkgX64.dsc
> >
> >
> > Thanks,
> > Eric
> >> -----Original Message-----
> >> From: Tom Lendacky <thomas.lendacky@amd.com>
> >> Sent: Friday, June 5, 2020 9:28 PM
> >> To: devel@edk2.groups.io
> >> Cc: Brijesh Singh <brijesh.singh@amd.com>; Ard Biesheuvel
> >> <ard.biesheuvel@arm.com>; Dong, Eric <eric.dong@intel.com>; Justen,
> >> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
> >> <lersek@redhat.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
> >> Michael D <michael.d.kinney@intel.com>; Ni, Ray <ray.ni@intel.com>
> >> Subject: [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the
> >> SEV- ES AP reset vector
> >>
> >> BZ:
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbug
> >>
> zilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Ct
> ho
> >>
> mas.lendacky%40amd.com%7C68b736db1acf4493c24308d8135b4a75%7C3dd
> 8961fe
> >>
> 4884e608e11a82d994e183d%7C0%7C0%7C637280630097752935&sdata=
> R8sYtS
> >> a7bQXgeW4tiSAxDdwcoZaldq4%2BoN2Xn378JMc%3D&reserved=0
> >>
> >> A hypervisor is not allowed to update an SEV-ES guest's register
> >> state, so when booting an SEV-ES guest AP, the hypervisor is not
> >> allowed to set the RIP to the guest requested value. Instead an
> >> SEV-ES AP must be re-directed from within the guest to the actual
> >> requested staring location as specified in the INIT-SIPI-SIPI sequence.
> >>
> >> Use the SEV-ES work area for the reset vector code that contains
> >> support to jump to the desired RIP location after having been
> >> started. This is required for only the very first AP reset.
> >>
> >> This new OVMF source file, ResetVectorVtf0.asm, is used in place of
> >> the original file through the use of the include path order set in
> >> OvmfPkg/ResetVector/ResetVector.inf under "[BuildOptions]".
> >>
> >> Cc: Jordan Justen <jordan.l.justen@intel.com>
> >> Cc: Laszlo Ersek <lersek@redhat.com>
> >> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> >> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> >> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> >> ---
> >> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100
> >> ++++++++++++++++++++
> >> OvmfPkg/ResetVector/ResetVector.nasmb | 1 +
> >> 2 files changed, 101 insertions(+)
> >>
> >> diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> >> b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> >> new file mode 100644
> >> index 000000000000..980e0138e7fe
> >> --- /dev/null
> >> +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> >> @@ -0,0 +1,100 @@
> >> +;-------------------------------------------------------------------
> >> +-----------
> >>
> >> +; @file
> >>
> >> +; First code executed by processor after resetting.
> >>
> >> +; Derived from
> UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
> >>
> >> +;
> >>
> >> +; Copyright (c) 2008 - 2014, Intel Corporation. All rights
> >> +reserved.<BR>
> >>
> >> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> >>
> >> +;
> >>
> >> +;-------------------------------------------------------------------
> >> +-----------
> >>
> >> +
> >>
> >> +BITS 16
> >>
> >> +
> >>
> >> +ALIGN 16
> >>
> >> +
> >>
> >> +;
> >>
> >> +; Pad the image size to 4k when page tables are in VTF0
> >>
> >> +;
> >>
> >> +; If the VTF0 image has page tables built in, then we need to make
> >>
> >> +; sure the end of VTF0 is 4k above where the page tables end.
> >>
> >> +;
> >>
> >> +; This is required so the page tables will be 4k aligned when VTF0
> >> +is
> >>
> >> +; located just below 0x100000000 (4GB) in the firmware device.
> >>
> >> +;
> >>
> >> +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
> >>
> >> + TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0
> >>
> >> +%endif
> >>
> >> +
> >>
> >> +;
> >>
> >> +; SEV-ES Processor Reset support
> >>
> >> +;
> >>
> >> +; sevEsResetBlock:
> >>
> >> +; For the initial boot of an AP under SEV-ES, the "reset" RIP must be
> >>
> >> +; programmed to the RAM area defined by SEV_ES_AP_RESET_IP. A
> >> known offset
> >>
> >> +; and GUID will be used to locate this block in the firmware and extract
> >>
> >> +; the build time RIP value. The GUID must always be 48 bytes from the
> >>
> >> +; end of the firmware.
> >>
> >> +;
> >>
> >> +; 0xffffffca (-0x36) - IP value
> >>
> >> +; 0xffffffcc (-0x34) - CS segment base [31:16]
> >>
> >> +; 0xffffffce (-0x32) - Size of the SEV-ES reset block
> >>
> >> +; 0xffffffd0 (-0x30) - SEV-ES reset block GUID
> >>
> >> +; (00f771de-1a7e-4fcb-890e-68c77e2fb44e)
> >>
> >> +;
> >>
> >> +; A hypervisor reads the CS segement base and IP value. The CS
> segment
> >> base
> >>
> >> +; value represents the high order 16-bits of the CS segment base, so the
> >>
> >> +; hypervisor must left shift the value of the CS segement base by 16 bits
> to
> >>
> >> +; form the full CS segment base for the CS segment register. It would
> then
> >>
> >> +; program the EIP register with the IP value as read.
> >>
> >> +;
> >>
> >> +
> >>
> >> +TIMES (32 - (sevEsResetBlockEnd - sevEsResetBlockStart)) DB 0
> >>
> >> +
> >>
> >> +sevEsResetBlockStart:
> >>
> >> + DD SEV_ES_AP_RESET_IP
> >>
> >> + DW sevEsResetBlockEnd - sevEsResetBlockStart
> >>
> >> + DB 0xDE, 0x71, 0xF7, 0x00, 0x7E, 0x1A, 0xCB, 0x4F
> >>
> >> + DB 0x89, 0x0E, 0x68, 0xC7, 0x7E, 0x2F, 0xB4, 0x4E
> >>
> >> +sevEsResetBlockEnd:
> >>
> >> +
> >>
> >> +ALIGN 16
> >>
> >> +
> >>
> >> +applicationProcessorEntryPoint:
> >>
> >> +;
> >>
> >> +; Application Processors entry point
> >>
> >> +;
> >>
> >> +; GenFv generates code aligned on a 4k boundary which will jump to
> >> +this
> >>
> >> +; location. (0xffffffe0) This allows the Local APIC Startup IPI to
> >> +be
> >>
> >> +; used to wake up the application processors.
> >>
> >> +;
> >>
> >> + jmp EarlyApInitReal16
> >>
> >> +
> >>
> >> +ALIGN 8
> >>
> >> +
> >>
> >> + DD 0
> >>
> >> +
> >>
> >> +;
> >>
> >> +; The VTF signature
> >>
> >> +;
> >>
> >> +; VTF-0 means that the VTF (Volume Top File) code does not require
> >>
> >> +; any fixups.
> >>
> >> +;
> >>
> >> +vtfSignature:
> >>
> >> + DB 'V', 'T', 'F', 0
> >>
> >> +
> >>
> >> +ALIGN 16
> >>
> >> +
> >>
> >> +resetVector:
> >>
> >> +;
> >>
> >> +; Reset Vector
> >>
> >> +;
> >>
> >> +; This is where the processor will begin execution
> >>
> >> +;
> >>
> >> + nop
> >>
> >> + nop
> >>
> >> + jmp EarlyBspInitReal16
> >>
> >> +
> >>
> >> +ALIGN 16
> >>
> >> +
> >>
> >> +fourGigabytes:
> >>
> >> +
> >>
> >> diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb
> >> b/OvmfPkg/ResetVector/ResetVector.nasmb
> >> index 762661115d50..4913b379a993 100644
> >> --- a/OvmfPkg/ResetVector/ResetVector.nasmb
> >> +++ b/OvmfPkg/ResetVector/ResetVector.nasmb
> >> @@ -82,5 +82,6 @@
> >>
> >>
> >> %include "Main.asm"
> >>
> >>
> >>
> >> + %define SEV_ES_AP_RESET_IP FixedPcdGet32
> (PcdSevEsWorkAreaBase)
> >>
> >> %include "Ia16/ResetVectorVtf0.asm"
> >>
> >>
> >>
> >> --
> >> 2.27.0
> >
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v9 44/46] OvmfPkg: Move the GHCB allocations into reserved memory
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (42 preceding siblings ...)
2020-06-05 17:58 ` [PATCH v9 43/46] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-05 17:58 ` [PATCH v9 45/46] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use Lendacky, Thomas
2020-06-05 17:58 ` [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files Lendacky, Thomas
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
After having transitioned from UEFI to the OS, the OS will need to boot
the APs. For an SEV-ES guest, the APs will have been parked by UEFI using
GHCB pages allocated by UEFI. The hypervisor will write to the GHCB
SW_EXITINFO2 field of the GHCB when the AP is booted. As a result, the
GHCB pages must be marked reserved so that the OS does not attempt to use
them and experience memory corruption because of the hypervisor write.
Change the GHCB allocation from the default boot services memory to
reserved memory.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/PlatformPei/AmdSev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index a2b38c591236..4a515a484720 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -51,9 +51,11 @@ AmdSevEsInitialize (
//
// Allocate GHCB and per-CPU variable pages.
+ // Since the pages must survive across the UEFI to OS transition
+ // make them reserved.
//
GhcbPageCount = mMaxCpuCount * 2;
- GhcbBase = AllocatePages (GhcbPageCount);
+ GhcbBase = AllocateReservedPages (GhcbPageCount);
ASSERT (GhcbBase != NULL);
GhcbBasePa = (PHYSICAL_ADDRESS)(UINTN) GhcbBase;
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 45/46] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (43 preceding siblings ...)
2020-06-05 17:58 ` [PATCH v9 44/46] OvmfPkg: Move the GHCB allocations into reserved memory Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-05 17:58 ` [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files Lendacky, Thomas
45 siblings, 0 replies; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Before UEFI transfers control to the OS, it must park the AP. This is
done using the AsmRelocateApLoop function to transition into 32-bit
non-paging mode. For an SEV-ES guest, a few additional things must be
done:
- AsmRelocateApLoop must be updated to support SEV-ES. This means
performing a VMGEXIT AP Reset Hold instead of an MWAIT or HLT loop.
- Since the AP must transition to real mode, a small routine is copied
to the WakeupBuffer area. Since the WakeupBuffer will be used by
the AP during OS booting, it must be placed in reserved memory.
Additionally, the AP stack must be located where it can be accessed
in real mode.
- Once the AP is in real mode it will transfer control to the
destination specified by the OS in the SEV-ES AP Jump Table. The
SEV-ES AP Jump Table address is saved by the hypervisor for the OS
using the GHCB VMGEXIT AP Jump Table exit code.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/Library/MpInitLib/MpLib.h | 8 +-
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 54 +++++++-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 131 ++++++++++++++++++--
3 files changed, 175 insertions(+), 18 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index b1a9d99cb3eb..267aa5201c50 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -293,7 +293,8 @@ struct _CPU_MP_DATA {
UINT64 GhcbBase;
};
-#define AP_RESET_STACK_SIZE 64
+#define AP_SAFE_STACK_SIZE 128
+#define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE
#pragma pack(1)
@@ -349,8 +350,11 @@ VOID
IN BOOLEAN MwaitSupport,
IN UINTN ApTargetCState,
IN UINTN PmCodeSegment,
+ IN UINTN Pm16CodeSegment,
IN UINTN TopOfApStack,
- IN UINTN NumberToFinish
+ IN UINTN NumberToFinish,
+ IN UINTN SevEsAPJumpTable,
+ IN UINTN WakeupBuffer
);
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 9115ff9e3e30..7165bcf3124a 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -12,6 +12,7 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/DxeServicesTableLib.h>
+#include <Library/VmgExitLib.h>
#include <Register/Amd/Fam17Msr.h>
#include <Register/Amd/Ghcb.h>
@@ -85,6 +86,13 @@ GetWakeupBuffer (
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS StartAddress;
+ EFI_MEMORY_TYPE MemoryType;
+
+ if (PcdGetBool (PcdSevEsIsEnabled)) {
+ MemoryType = EfiReservedMemoryType;
+ } else {
+ MemoryType = EfiBootServicesData;
+ }
//
// Try to allocate buffer below 1M for waking vector.
@@ -97,7 +105,7 @@ GetWakeupBuffer (
StartAddress = 0x88000;
Status = gBS->AllocatePages (
AllocateMaxAddress,
- EfiBootServicesData,
+ MemoryType,
EFI_SIZE_TO_PAGES (WakeupBufferSize),
&StartAddress
);
@@ -159,8 +167,10 @@ GetSevEsAPMemory (
VOID
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS StartAddress;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS StartAddress;
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
//
// Allocate 1 page for AP jump table page
@@ -176,6 +186,16 @@ GetSevEsAPMemory (
DEBUG ((DEBUG_INFO, "Dxe: SevEsAPMemory = %lx\n", (UINTN) StartAddress));
+ //
+ // Save the SevEsAPMemory as the AP jump table.
+ //
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ VmgInit (Ghcb);
+ VmgExit (Ghcb, SVM_EXIT_AP_JUMP_TABLE, 0, (UINT64) (UINTN) StartAddress);
+ VmgDone (Ghcb);
+
return (UINTN) StartAddress;
}
@@ -330,17 +350,26 @@ RelocateApLoop (
BOOLEAN MwaitSupport;
ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc;
UINTN ProcessorNumber;
+ UINTN StackStart;
MpInitLibWhoAmI (&ProcessorNumber);
CpuMpData = GetCpuMpData ();
MwaitSupport = IsMwaitSupport ();
+ if (CpuMpData->SevEsIsEnabled) {
+ StackStart = CpuMpData->SevEsAPResetStackStart;
+ } else {
+ StackStart = mReservedTopOfApStack;
+ }
AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc;
AsmRelocateApLoopFunc (
MwaitSupport,
CpuMpData->ApTargetCState,
CpuMpData->PmCodeSegment,
- mReservedTopOfApStack - ProcessorNumber * AP_SAFE_STACK_SIZE,
- (UINTN) &mNumberToFinish
+ CpuMpData->Pm16CodeSegment,
+ StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
+ (UINTN) &mNumberToFinish,
+ CpuMpData->SevEsAPBuffer,
+ CpuMpData->WakeupBuffer
);
//
// It should never reach here
@@ -374,6 +403,21 @@ MpInitChangeApLoopCallback (
while (mNumberToFinish > 0) {
CpuPause ();
}
+
+ if (CpuMpData->SevEsIsEnabled && (CpuMpData->WakeupBuffer != (UINTN) -1)) {
+ //
+ // There are APs present. Re-use reserved memory area below 1MB from
+ // WakeupBuffer as the area to be used for transitioning to 16-bit mode
+ // in support of booting of the AP by an OS.
+ //
+ CopyMem (
+ (VOID *) CpuMpData->WakeupBuffer,
+ (VOID *) (CpuMpData->AddressMap.RendezvousFunnelAddress +
+ CpuMpData->AddressMap.SwitchToRealPM16ModeOffset),
+ CpuMpData->AddressMap.SwitchToRealPM16ModeSize
+ );
+ }
+
DEBUG ((DEBUG_INFO, "%a() done!\n", __FUNCTION__));
}
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 6956b408d004..3b8ec477b8b3 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -465,6 +465,10 @@ BITS 16
; - IP for Real Mode (two bytes)
; - CS for Real Mode (two bytes)
;
+ ; This label is also used with AsmRelocateApLoop. During MP finalization,
+ ; the code from PM16Mode to SwitchToRealProcEnd is copied to the start of
+ ; the WakeupBuffer, allowing a parked AP to be booted by an OS.
+ ;
PM16Mode:
mov eax, cr0 ; Read CR0
btr eax, 0 ; Set PE=0
@@ -487,32 +491,95 @@ PM16Mode:
SwitchToRealProcEnd:
;-------------------------------------------------------------------------------------
-; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish);
+; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, Pm16CodeSegment, TopOfApStack, CountTofinish, SevEsAPJumpTable, WakeupBuffer);
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmRelocateApLoop)
ASM_PFX(AsmRelocateApLoop):
AsmRelocateApLoopStart:
BITS 64
+ cmp qword [rsp + 56], 0
+ je NoSevEs
+
+ ;
+ ; Perform some SEV-ES related setup before leaving 64-bit mode
+ ;
+ push rcx
+ push rdx
+
+ ;
+ ; Get the RDX reset value using CPUID
+ ;
+ mov rax, 1
+ cpuid
+ mov rsi, rax ; Save off the reset value for RDX
+
+ ;
+ ; Prepare the GHCB for the AP_HLT_LOOP VMGEXIT call
+ ; - Must be done while in 64-bit long mode so that writes to
+ ; the GHCB memory will be unencrypted.
+ ; - No NAE events can be generated once this is set otherwise
+ ; the AP_RESET_HOLD SW_EXITCODE will be overwritten.
+ ;
+ mov rcx, 0xc0010130
+ rdmsr ; Retrieve current GHCB address
+ shl rdx, 32
+ or rdx, rax
+
+ mov rdi, rdx
+ xor rax, rax
+ mov rcx, 0x800
+ shr rcx, 3
+ rep stosq ; Clear the GHCB
+
+ mov rax, 0x80000004 ; VMGEXIT AP_RESET_HOLD
+ mov [rdx + 0x390], rax
+
+ pop rdx
+ pop rcx
+
+NoSevEs:
cli ; Disable interrupt before switching to 32-bit mode
- mov rax, [rsp + 40] ; CountTofinish
+ mov rax, [rsp + 48] ; CountTofinish
lock dec dword [rax] ; (*CountTofinish)--
- mov rsp, r9
- push rcx
- push rdx
- lea rsi, [PmEntry] ; rsi <- The start address of transition code
+ mov rax, [rsp + 56] ; SevEsAPJumpTable
+ mov rbx, [rsp + 64] ; WakeupBuffer
+ mov rsp, [rsp + 40] ; TopOfApStack
+
+ push rax ; Save SevEsAPJumpTable
+ push rbx ; Save WakeupBuffer
+ push r9 ; Save Pm16CodeSegment
+ push rcx ; Save MwaitSupport
+ push rdx ; Save ApTargetCState
+
+ lea rax, [PmEntry] ; rax <- The start address of transition code
push r8
- push rsi
- DB 0x48
- retf
+ push rax
+
+ ;
+ ; Clear R8 - R15, for reset, before going into 32-bit mode
+ ;
+ xor r8, r8
+ xor r9, r9
+ xor r10, r10
+ xor r11, r11
+ xor r12, r12
+ xor r13, r13
+ xor r14, r14
+ xor r15, r15
+
+ ;
+ ; Far return into 32-bit mode
+ ;
+o64 retf
+
BITS 32
PmEntry:
mov eax, cr0
btr eax, 31 ; Clear CR0.PG
mov cr0, eax ; Disable paging and caches
- mov ebx, edx ; Save EntryPoint to rbx, for rdmsr will overwrite rdx
mov ecx, 0xc0000080
rdmsr
and ah, ~ 1 ; Clear LME
@@ -525,6 +592,8 @@ PmEntry:
add esp, 4
pop ecx,
add esp, 4
+
+MwaitCheck:
cmp cl, 1 ; Check mwait-monitor support
jnz HltLoop
mov ebx, edx ; Save C-State to ebx
@@ -538,10 +607,50 @@ MwaitLoop:
shl eax, 4
mwait
jmp MwaitLoop
+
HltLoop:
+ pop edx ; PM16CodeSegment
+ add esp, 4
+ pop ebx ; WakeupBuffer
+ add esp, 4
+ pop eax ; SevEsAPJumpTable
+ add esp, 4
+ cmp eax, 0 ; Check for SEV-ES
+ je DoHlt
+
+ cli
+ ;
+ ; SEV-ES is enabled, use VMGEXIT (GHCB information already
+ ; set by caller)
+ ;
+BITS 64
+ rep vmmcall
+BITS 32
+
+ ;
+ ; Back from VMGEXIT AP_HLT_LOOP
+ ; Push the FLAGS/CS/IP values to use
+ ;
+ push word 0x0002 ; EFLAGS
+ xor ecx, ecx
+ mov cx, [eax + 2] ; CS
+ push cx
+ mov cx, [eax] ; IP
+ push cx
+ push word 0x0000 ; For alignment, will be discarded
+
+ push edx
+ push ebx
+
+ mov edx, esi ; Restore RDX reset value
+
+ retf
+
+DoHlt:
cli
hlt
- jmp HltLoop
+ jmp DoHlt
+
BITS 64
AsmRelocateApLoopEnd:
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files
2020-06-05 13:26 [PATCH v9 00/46] SEV-ES guest support Lendacky, Thomas
` (44 preceding siblings ...)
2020-06-05 17:58 ` [PATCH v9 45/46] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use Lendacky, Thomas
@ 2020-06-05 17:58 ` Lendacky, Thomas
2020-06-11 10:21 ` Laszlo Ersek
45 siblings, 1 reply; 103+ messages in thread
From: Lendacky, Thomas @ 2020-06-05 17:58 UTC (permalink / raw)
To: devel
Register reviewers for the SEV-related files in OvmfPkg.
Cc: Andrew Fish <afish@apple.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
Maintainers.txt | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Maintainers.txt b/Maintainers.txt
index 896ac5821fc6..2aa0148e9a97 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -441,6 +441,16 @@ F: OvmfPkg/PvScsiDxe/
R: Liran Alon <liran.alon@oracle.com>
R: Nikita Leshenko <nikita.leshchenko@oracle.com>
+OvmfPkg: SEV-related modules
+F: OvmfPkg/AmdSevDxe/
+F: OvmfPkg/Include/Library/MemEncryptSevLib.h
+F: OvmfPkg/IoMmuDxe/AmdSevIoMmu.*
+F: OvmfPkg/Library/BaseMemEncryptSevLib/
+F: OvmfPkg/Library/VmgExitLib/
+F: OvmfPkg/PlatformPei/AmdSev.c
+R: Tom Lendacky <thomas.lendacky@amd.com>
+R: Brijesh Singh <brijesh.singh@amd.com>
+
PcAtChipsetPkg
F: PcAtChipsetPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
--
2.27.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files
2020-06-05 17:58 ` [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files Lendacky, Thomas
@ 2020-06-11 10:21 ` Laszlo Ersek
2020-06-11 11:06 ` Brijesh Singh
0 siblings, 1 reply; 103+ messages in thread
From: Laszlo Ersek @ 2020-06-11 10:21 UTC (permalink / raw)
To: Tom Lendacky, devel, Brijesh Singh
Cc: Ard Biesheuvel, Eric Dong, Jordan Justen, Liming Gao,
Michael D Kinney, Ray Ni, Andrew Fish, Leif Lindholm
On 06/05/20 15:27, Tom Lendacky wrote:
> Register reviewers for the SEV-related files in OvmfPkg.
>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Brijesh Singh <brijesh.singh@amd.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> Maintainers.txt | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/Maintainers.txt b/Maintainers.txt
> index 896ac5821fc6..2aa0148e9a97 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -441,6 +441,16 @@ F: OvmfPkg/PvScsiDxe/
> R: Liran Alon <liran.alon@oracle.com>
> R: Nikita Leshenko <nikita.leshchenko@oracle.com>
>
> +OvmfPkg: SEV-related modules
> +F: OvmfPkg/AmdSevDxe/
> +F: OvmfPkg/Include/Library/MemEncryptSevLib.h
> +F: OvmfPkg/IoMmuDxe/AmdSevIoMmu.*
> +F: OvmfPkg/Library/BaseMemEncryptSevLib/
> +F: OvmfPkg/Library/VmgExitLib/
> +F: OvmfPkg/PlatformPei/AmdSev.c
> +R: Tom Lendacky <thomas.lendacky@amd.com>
> +R: Brijesh Singh <brijesh.singh@amd.com>
> +
> PcAtChipsetPkg
> F: PcAtChipsetPkg/
> W: https://github.com/tianocore/tianocore.github.io/wiki/PcAtChipsetPkg
>
Thanks!
Brijesh, can you please re-ACK this patch?
Thanks,
Laszlo
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v9 46/46] Maintainers.txt: Add reviewers for the OvmfPkg SEV-related files
2020-06-11 10:21 ` Laszlo Ersek
@ 2020-06-11 11:06 ` Brijesh Singh
0 siblings, 0 replies; 103+ messages in thread
From: Brijesh Singh @ 2020-06-11 11:06 UTC (permalink / raw)
To: Laszlo Ersek, Tom Lendacky, devel
Cc: brijesh.singh, Ard Biesheuvel, Eric Dong, Jordan Justen,
Liming Gao, Michael D Kinney, Ray Ni, Andrew Fish, Leif Lindholm
On 6/11/20 5:21 AM, Laszlo Ersek wrote:
> On 06/05/20 15:27, Tom Lendacky wrote:
>> Register reviewers for the SEV-related files in OvmfPkg.
>>
>> Cc: Andrew Fish <afish@apple.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Brijesh Singh <brijesh.singh@amd.com>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Brijesh Singh <brijesh.singh@amd.com>
thanks
>> ---
>> Maintainers.txt | 10 ++++++++++
>> 1 file changed, 10 insertions(+)
>>
>> diff --git a/Maintainers.txt b/Maintainers.txt
>> index 896ac5821fc6..2aa0148e9a97 100644
>> --- a/Maintainers.txt
>> +++ b/Maintainers.txt
>> @@ -441,6 +441,16 @@ F: OvmfPkg/PvScsiDxe/
>> R: Liran Alon <liran.alon@oracle.com>
>> R: Nikita Leshenko <nikita.leshchenko@oracle.com>
>>
>> +OvmfPkg: SEV-related modules
>> +F: OvmfPkg/AmdSevDxe/
>> +F: OvmfPkg/Include/Library/MemEncryptSevLib.h
>> +F: OvmfPkg/IoMmuDxe/AmdSevIoMmu.*
>> +F: OvmfPkg/Library/BaseMemEncryptSevLib/
>> +F: OvmfPkg/Library/VmgExitLib/
>> +F: OvmfPkg/PlatformPei/AmdSev.c
>> +R: Tom Lendacky <thomas.lendacky@amd.com>
>> +R: Brijesh Singh <brijesh.singh@amd.com>
>> +
>> PcAtChipsetPkg
>> F: PcAtChipsetPkg/
>> W: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FPcAtChipsetPkg&data=02%7C01%7Cbrijesh.singh%40amd.com%7Cff7dc0d284aa44d6ab0208d80df13eb2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637274677076483240&sdata=ugHFvw6wPpDVEMhms%2FXbvUyeSbTzyz7BaTHgOLSqnt8%3D&reserved=0
>>
> Thanks!
>
> Brijesh, can you please re-ACK this patch?
>
> Thanks,
> Laszlo
>
^ permalink raw reply [flat|nested] 103+ messages in thread