* [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-05-02 8:19 ` [edk2-devel] " Dong, Eric
2020-04-22 17:41 ` [PATCH v7 02/43] UefiCpuPkg: Create PCD " Lendacky, Thomas
` (42 subsequent siblings)
43 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh, 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 42ad21cf244d..642a4791d83c 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -2048,6 +2048,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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-04-22 17:41 ` [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
@ 2020-05-02 8:19 ` Dong, Eric
2020-05-04 13:34 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Dong, Eric @ 2020-05-02 8:19 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
Hi Tom,
Can you describe what tests have you done for this patch serial?
I just build the UefiCpupkg. Dsc with VS2015x86 and met below errors:
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(730): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(745): warning C4244: '=': conversion from 'UINTN' to 'UINT8', possible loss of data
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(753): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
Trim --asm-file -o g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\X64\SmiEntry.i -i g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\inc.lst g:\edk2-open-source\edk2\UefiCpuPkg\Library\SmmCpuFeaturesLib\X64\SmiEntry.nasm
PeiDxeSmmCpuException.c
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(778): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\lib.exe" /NOLOGO /LTCG /OUT:g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeModulePkg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\TpmMeasurementLibNull.lib @g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeModulePkg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\object_files.lst
Building ... g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuTimerLib\BaseCpuTimerLib.inf [X64]
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(801): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
CheckSum.c
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(821): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(837): warning C4244: 'function': conversion from 'UINTN' to 'UINT8', possible loss of data
Thanks,
Eric
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
Sent: Thursday, April 23, 2020 1:41 AM
To: devel@edk2.groups.io
Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
Subject: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
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 42ad21cf244d..642a4791d83c 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -2048,6 +2048,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.17.1
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-02 8:19 ` [edk2-devel] " Dong, Eric
@ 2020-05-04 13:34 ` Lendacky, Thomas
2020-05-04 13:47 ` Dong, Eric
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-04 13:34 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
On 5/2/20 3:19 AM, Dong, Eric wrote:
> Hi Tom,
Hi Eric,
>
> Can you describe what tests have you done for this patch serial?
I've built the OVMF package in 32, 32/64 and 64-bit configurations on
Linux using GCC as the compiler. These warnings were not emitted in those
configurations. I'll look into seeing if there is a compiler setting that
will provide these conversion warnings.
I don't have Visual Studio and so cannot test that. I can, however, fix
these warnings. Are these the only warnings you have seen?
Thanks,
Tom
>
> I just build the UefiCpupkg. Dsc with VS2015x86 and met below errors:
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(730): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(745): warning C4244: '=': conversion from 'UINTN' to 'UINT8', possible loss of data
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(753): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> Trim --asm-file -o g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\X64\SmiEntry.i -i g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\inc.lst g:\edk2-open-source\edk2\UefiCpuPkg\Library\SmmCpuFeaturesLib\X64\SmiEntry.nasm
> PeiDxeSmmCpuException.c
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(778): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Vc\bin\x86_amd64\lib.exe" /NOLOGO /LTCG /OUT:g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeModulePkg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\TpmMeasurementLibNull.lib @g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeModulePkg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\object_files.lst
> Building ... g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuTimerLib\BaseCpuTimerLib.inf [X64]
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(801): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> CheckSum.c
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(821): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(837): warning C4244: 'function': conversion from 'UINTN' to 'UINT8', possible loss of data
>
> Thanks,
> Eric
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
> Sent: Thursday, April 23, 2020 1:41 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
>
> 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%7Cfbe4f561e0234d8450fe08d7ee7186e2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637240043676140655&sdata=xdnfAfSLtPi3FE5olqjU7%2B4OHJBxgOTRAFR0%2BMkECLc%3D&reserved=0
>
> 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 42ad21cf244d..642a4791d83c 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -2048,6 +2048,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.17.1
>
>
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-04 13:34 ` Lendacky, Thomas
@ 2020-05-04 13:47 ` Dong, Eric
2020-05-04 16:41 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Dong, Eric @ 2020-05-04 13:47 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
Hi Tom,
Those errors are not the only errors I met. I also created a pull request to test your patch serial and it reported some errors. Please check the result, https://github.com/tianocore/edk2/pull/575.
Thanks,
Eric
-----Original Message-----
From: Tom Lendacky <thomas.lendacky@amd.com>
Sent: Monday, May 4, 2020 9:35 PM
To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
On 5/2/20 3:19 AM, Dong, Eric wrote:
> Hi Tom,
Hi Eric,
>
> Can you describe what tests have you done for this patch serial?
I've built the OVMF package in 32, 32/64 and 64-bit configurations on Linux using GCC as the compiler. These warnings were not emitted in those configurations. I'll look into seeing if there is a compiler setting that will provide these conversion warnings.
I don't have Visual Studio and so cannot test that. I can, however, fix these warnings. Are these the only warnings you have seen?
Thanks,
Tom
>
> I just build the UefiCpupkg. Dsc with VS2015x86 and met below errors:
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
> \ArchAMDSevVcHandler.c(730): warning C4245: 'function': conversion
> from 'int' to 'UINT64', signed/unsigned mismatch
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
> \ArchAMDSevVcHandler.c(745): warning C4244: '=': conversion from
> 'UINTN' to 'UINT8', possible loss of data
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(753): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> Trim --asm-file -o
> g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\
> Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\X64\SmiEntry.i
> -i
> g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\
> Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\inc.lst
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\SmmCpuFeaturesLib\X64\SmiE
> ntry.nasm
> PeiDxeSmmCpuException.c
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(778): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
> "C:\Program Files (x86)\Microsoft Visual Studio
> 14.0\Vc\bin\x86_amd64\lib.exe" /NOLOGO /LTCG
> /OUT:g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeMod
> ulePkg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\TpmM
> easurementLibNull.lib
> @g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeModuleP
> kg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\object_f
> iles.lst Building ...
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuTimerLib\BaseCpuTimerLi
> b.inf [X64]
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
> \ArchAMDSevVcHandler.c(801): warning C4245: 'function': conversion
> from 'int' to 'UINT64', signed/unsigned mismatch CheckSum.c
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
> \ArchAMDSevVcHandler.c(821): warning C4245: 'function': conversion
> from 'int' to 'UINT64', signed/unsigned mismatch
> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
> \ArchAMDSevVcHandler.c(837): warning C4244: 'function': conversion
> from 'UINTN' to 'UINT8', possible loss of data
>
> Thanks,
> Eric
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Thursday, April 23, 2020 1:41 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
> <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian
> J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be
> used in support of SEV-ES
>
> BZ:
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugz
> illa.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Cthoma
> s.lendacky%40amd.com%7Cfbe4f561e0234d8450fe08d7ee7186e2%7C3dd8961fe488
> 4e608e11a82d994e183d%7C0%7C0%7C637240043676140655&sdata=xdnfAfSLtP
> i3FE5olqjU7%2B4OHJBxgOTRAFR0%2BMkECLc%3D&reserved=0
>
> 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 42ad21cf244d..642a4791d83c
> 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -2048,6 +2048,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.17.1
>
>
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-04 13:47 ` Dong, Eric
@ 2020-05-04 16:41 ` Lendacky, Thomas
2020-05-05 15:29 ` Laszlo Ersek
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-04 16:41 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
On 5/4/20 8:47 AM, Dong, Eric wrote:
> Hi Tom,
Hi Eric,
>
> Those errors are not the only errors I met. I also created a pull request to test your patch serial and it reported some errors. Please check the result, https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2%2Fpull%2F575&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cfdf81d76452848b158f508d7f031c4b7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637241968853099793&sdata=woq74igmxH5a%2F4vhphtseDjy%2BWil1kPDX0U8auU2Exc%3D&reserved=0.
Is there an easy way to run everything that this link points, too? Is it
just creating a pull request that does this? I don't want to take up a lot
of your time, so if there's some documentation on how to run an
integration test to find and fix issues like this, just point me to it.
Thanks,
Tom
>
> Thanks,
> Eric
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Monday, May 4, 2020 9:35 PM
> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
>
> On 5/2/20 3:19 AM, Dong, Eric wrote:
>> Hi Tom,
>
> Hi Eric,
>
>>
>> Can you describe what tests have you done for this patch serial?
>
> I've built the OVMF package in 32, 32/64 and 64-bit configurations on Linux using GCC as the compiler. These warnings were not emitted in those configurations. I'll look into seeing if there is a compiler setting that will provide these conversion warnings.
>
> I don't have Visual Studio and so cannot test that. I can, however, fix these warnings. Are these the only warnings you have seen?
>
> Thanks,
> Tom
>
>>
>> I just build the UefiCpupkg. Dsc with VS2015x86 and met below errors:
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
>> \ArchAMDSevVcHandler.c(730): warning C4245: 'function': conversion
>> from 'int' to 'UINT64', signed/unsigned mismatch
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
>> \ArchAMDSevVcHandler.c(745): warning C4244: '=': conversion from
>> 'UINTN' to 'UINT8', possible loss of data
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(753): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
>> Trim --asm-file -o
>> g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\
>> Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\X64\SmiEntry.i
>> -i
>> g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\UefiCpuPkg\
>> Library\SmmCpuFeaturesLib\SmmCpuFeaturesLibStm\OUTPUT\inc.lst
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\SmmCpuFeaturesLib\X64\SmiE
>> ntry.nasm
>> PeiDxeSmmCpuException.c
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchAMDSevVcHandler.c(778): warning C4245: 'function': conversion from 'int' to 'UINT64', signed/unsigned mismatch
>> "C:\Program Files (x86)\Microsoft Visual Studio
>> 14.0\Vc\bin\x86_amd64\lib.exe" /NOLOGO /LTCG
>> /OUT:g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeMod
>> ulePkg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\TpmM
>> easurementLibNull.lib
>> @g:\edk2-open-source\edk2\Build\UefiCpu\DEBUG_VS2015x86\X64\MdeModuleP
>> kg\Library\TpmMeasurementLibNull\TpmMeasurementLibNull\OUTPUT\object_f
>> iles.lst Building ...
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuTimerLib\BaseCpuTimerLi
>> b.inf [X64]
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
>> \ArchAMDSevVcHandler.c(801): warning C4245: 'function': conversion
>> from 'int' to 'UINT64', signed/unsigned mismatch CheckSum.c
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
>> \ArchAMDSevVcHandler.c(821): warning C4245: 'function': conversion
>> from 'int' to 'UINT64', signed/unsigned mismatch
>> g:\edk2-open-source\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64
>> \ArchAMDSevVcHandler.c(837): warning C4244: 'function': conversion
>> from 'UINTN' to 'UINT8', possible loss of data
>>
>> Thanks,
>> Eric
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Thursday, April 23, 2020 1:41 AM
>> To: devel@edk2.groups.io
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>> <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>;
>> Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
>> <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray
>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian
>> J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>> Subject: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be
>> used in support of SEV-ES
>>
>> BZ:
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugz
>> illa.tianocore.org%2Fshow_bug.cgi%3Fid%3D2198&data=02%7C01%7Cthoma
>> s.lendacky%40amd.com%7Cfbe4f561e0234d8450fe08d7ee7186e2%7C3dd8961fe488
>> 4e608e11a82d994e183d%7C0%7C0%7C637240043676140655&sdata=xdnfAfSLtP
>> i3FE5olqjU7%2B4OHJBxgOTRAFR0%2BMkECLc%3D&reserved=0
>>
>> 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 42ad21cf244d..642a4791d83c
>> 100644
>> --- a/MdeModulePkg/MdeModulePkg.dec
>> +++ b/MdeModulePkg/MdeModulePkg.dec
>> @@ -2048,6 +2048,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.17.1
>>
>>
>>
>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-04 16:41 ` Lendacky, Thomas
@ 2020-05-05 15:29 ` Laszlo Ersek
2020-05-06 1:53 ` Dong, Eric
0 siblings, 1 reply; 81+ messages in thread
From: Laszlo Ersek @ 2020-05-05 15:29 UTC (permalink / raw)
To: Tom Lendacky, Dong, Eric, devel@edk2.groups.io
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
On 05/04/20 18:41, Tom Lendacky wrote:
> Is there an easy way to run everything that this link points, too? Is it
> just creating a pull request that does this? I don't want to take up a
> lot of your time, so if there's some documentation on how to run an
> integration test to find and fix issues like this, just point me to it.
Just create a pull request; it will set off CI, and you can review VS
build errors there (if any).
Your PR will automatically be closed (rejected) regardless of whether CI
succeeds or not. PRs are merged -- in fact, *auto*-merged, by the
"mergify bot" -- if and only if (a) the CI run succeeds, and (b) the PR
has the "push" label set.
And only edk2 maintainers have permission to set the "push" label. Any
PR without the "push" label qualifies as a "personal test build". So you
can freely experiment with PRs, because you can't (even unwittingly)
satisfy condition (b).
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Development-Process
Thanks,
Laszlo
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-05 15:29 ` Laszlo Ersek
@ 2020-05-06 1:53 ` Dong, Eric
2020-05-06 13:19 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Dong, Eric @ 2020-05-06 1:53 UTC (permalink / raw)
To: devel@edk2.groups.io, lersek@redhat.com, Tom Lendacky
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Laszlo Ersek
> Sent: Tuesday, May 5, 2020 11:30 PM
> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
> <eric.dong@intel.com>; devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
> be used in support of SEV-ES
>
> On 05/04/20 18:41, Tom Lendacky wrote:
>
> > Is there an easy way to run everything that this link points, too? Is
> > it just creating a pull request that does this? I don't want to take
> > up a lot of your time, so if there's some documentation on how to run
> > an integration test to find and fix issues like this, just point me to it.
>
> Just create a pull request; it will set off CI, and you can review VS build errors
> there (if any).
>
> Your PR will automatically be closed (rejected) regardless of whether CI
> succeeds or not. PRs are merged -- in fact, *auto*-merged, by the "mergify
> bot" -- if and only if (a) the CI run succeeds, and (b) the PR has the "push"
> label set.
>
> And only edk2 maintainers have permission to set the "push" label. Any PR
> without the "push" label qualifies as a "personal test build". So you can freely
> experiment with PRs, because you can't (even unwittingly) satisfy condition
> (b).
>
> https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Development-
> Process
>
Thanks Laszlo for your explanation.
I found this patch serial is incompatible for the existed platforms. Can you help to fix the build failure for these platforms in https://github.com/tianocore/edk2-platforms
I think you also needs to add an wiki page to explain what need to do if an platform needs to integrate your changes, also it's better to explain this feature in the page.
https://github.com/tianocore/tianocore.github.io/wiki
If you want to include this change in the next edk2 release, you need to add one item for it in the release plan page, sample can be found in below pages: https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Release-Planning
Thanks,
Eric
> Thanks,
> Laszlo
>
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-06 1:53 ` Dong, Eric
@ 2020-05-06 13:19 ` Lendacky, Thomas
2020-05-06 15:06 ` Dong, Eric
2020-05-06 16:24 ` Laszlo Ersek
0 siblings, 2 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-06 13:19 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io, lersek@redhat.com
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
On 5/5/20 8:53 PM, Dong, Eric wrote:
>
>
>> -----Original Message-----
>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>> Laszlo Ersek
>> Sent: Tuesday, May 5, 2020 11:30 PM
>> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
>> <eric.dong@intel.com>; devel@edk2.groups.io
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
>> be used in support of SEV-ES
>>
>> On 05/04/20 18:41, Tom Lendacky wrote:
>>
>>> Is there an easy way to run everything that this link points, too? Is
>>> it just creating a pull request that does this? I don't want to take
>>> up a lot of your time, so if there's some documentation on how to run
>>> an integration test to find and fix issues like this, just point me to it.
>>
>> Just create a pull request; it will set off CI, and you can review VS build errors
>> there (if any).
>>
>> Your PR will automatically be closed (rejected) regardless of whether CI
>> succeeds or not. PRs are merged -- in fact, *auto*-merged, by the "mergify
>> bot" -- if and only if (a) the CI run succeeds, and (b) the PR has the "push"
>> label set.
>>
>> And only edk2 maintainers have permission to set the "push" label. Any PR
>> without the "push" label qualifies as a "personal test build". So you can freely
>> experiment with PRs, because you can't (even unwittingly) satisfy condition
>> (b).
>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Development-&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYBc%3D&reserved=0
>> Process
>>
>
> Thanks Laszlo for your explanation.
>
> I found this patch serial is incompatible for the existed platforms. Can you help to fix the build failure for these platforms in https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-platforms&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6ZvFmPzjcxGo9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
>
I have fixed all of the build issues associated with the VS compiler using
the pull request method that Laszlo mentioned. I then successfully built
the RPi4 platform under GCC (build -n 32 -a AARCH64 -t GCC5 -p
Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
Is there a particular platform that experiences an issue or are the
failures related to the VS compiler errors that my next series will have
fixed?
> I think you also needs to add an wiki page to explain what need to do if an platform needs to integrate your changes, also it's better to explain this feature in the page.
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=xLkoV4zWhxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
I don't see any platform other than OVMF using this feature as it is a
virtualization feature. Having said that I can add an explanation of what
is needed should another virtualization platform be created under EDK2
that wants to support SEV-ES. And, as you said, I can also explain the
feature overall on the page.
>
>
> If you want to include this change in the next edk2 release, you need to add one item for it in the release plan page, sample can be found in below pages: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-Planning&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870I%3D&reserved=0
Thanks. Is there anyone in particular that I need to request this feature
be added?
Thanks,
Tom
>
>
> Thanks,
> Eric
>
>> Thanks,
>> Laszlo
>>
>>
>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-06 13:19 ` Lendacky, Thomas
@ 2020-05-06 15:06 ` Dong, Eric
2020-05-06 18:33 ` Lendacky, Thomas
2020-05-06 16:24 ` Laszlo Ersek
1 sibling, 1 reply; 81+ messages in thread
From: Dong, Eric @ 2020-05-06 15:06 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com, lersek@redhat.com
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
Hi Tom,
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Wednesday, May 6, 2020 9:20 PM
> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
> lersek@redhat.com
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
> be used in support of SEV-ES
>
> On 5/5/20 8:53 PM, Dong, Eric wrote:
> >
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> >> Laszlo Ersek
> >> Sent: Tuesday, May 5, 2020 11:30 PM
> >> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
> >> <eric.dong@intel.com>; devel@edk2.groups.io
> >> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> >> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> >> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni,
> >> Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang,
> >> Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> >> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs
> >> to be used in support of SEV-ES
> >>
> >> On 05/04/20 18:41, Tom Lendacky wrote:
> >>
> >>> Is there an easy way to run everything that this link points, too?
> >>> Is it just creating a pull request that does this? I don't want to
> >>> take up a lot of your time, so if there's some documentation on how
> >>> to run an integration test to find and fix issues like this, just point me to it.
> >>
> >> Just create a pull request; it will set off CI, and you can review VS
> >> build errors there (if any).
> >>
> >> Your PR will automatically be closed (rejected) regardless of whether
> >> CI succeeds or not. PRs are merged -- in fact, *auto*-merged, by the
> >> "mergify bot" -- if and only if (a) the CI run succeeds, and (b) the PR has
> the "push"
> >> label set.
> >>
> >> And only edk2 maintainers have permission to set the "push" label.
> >> Any PR without the "push" label qualifies as a "personal test build".
> >> So you can freely experiment with PRs, because you can't (even
> >> unwittingly) satisfy condition (b).
> >>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-
> Development
> >> -
> &data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a9
> 57285
> >>
> 08d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63724
> 326821
> >>
> 7382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYB
> c%3D&
> >> amp;reserved=0
> >> Process
> >>
> >
> > Thanks Laszlo for your explanation.
> >
> > I found this patch serial is incompatible for the existed platforms.
> > Can you help to fix the build failure for these platforms in
> >
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Ftianocore%2Fedk2-
> platforms&data=02%7C01%7Cthomas.lendacky
> > %40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e6
> 08e11a8
> >
> 2d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6Z
> vFmPzjcx
> > Go9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
> >
>
> I have fixed all of the build issues associated with the VS compiler using the
> pull request method that Laszlo mentioned. I then successfully built the RPi4
> platform under GCC (build -n 32 -a AARCH64 -t GCC5 -p
> Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
>
> Is there a particular platform that experiences an issue or are the failures
> related to the VS compiler errors that my next series will have fixed?
I used the KabylakeRvp3 platform with your changes in Edk2 and met failures.
KabylakeRvp3 code at Edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\
I used below command to build the code.
C:\Code\OpenSource\edk2-platforms\Platform\Intel>build_bios.py --platform KabylakeRvp3
You need clone below repositories to build the code.
Edk2: git@github.com:tianocore/edk2.git
Edk2-Platform git@github.com:tianocore/edk2-platforms.git
edk2-non-osi : git@github.com:tianocore/edk2-non-osi.git
FSP: git@github.com:IntelFsp/FSP.git
>
> > I think you also needs to add an wiki page to explain what need to do if an
> platform needs to integrate your changes, also it's better to explain this
> feature in the page.
> >
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> >
> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7
> Ctho
> >
> mas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd89
> 61fe4
> >
> 884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=x
> LkoV4zW
> > hxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
>
> I don't see any platform other than OVMF using this feature as it is a
> virtualization feature. Having said that I can add an explanation of what is
> needed should another virtualization platform be created under EDK2 that
> wants to support SEV-ES. And, as you said, I can also explain the feature
> overall on the page.
>
I think your page includes two parts, one is how to change the platform code to make the platform pass build,
the other is if the platform needs to enable the virtualization feature, how to enable it.
> >
> >
> > If you want to include this change in the next edk2 release, you need
> > to add one item for it in the release plan page, sample can be found
> > in below pages:
> >
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-
> Plann
> >
> ing&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84
> a95728
> >
> 508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6372
> 4326821
> >
> 7382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870
> I%3D&
> > ;reserved=0
>
> Thanks. Is there anyone in particular that I need to request this feature be
> added?
You can syn with Liming, he is the edk2 release manager. He owns edk2 stable tag release task.
Thanks,
Eric
>
> Thanks,
> Tom
>
> >
> >
> > Thanks,
> > Eric
> >
> >> Thanks,
> >> Laszlo
> >>
> >>
> >>
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-06 15:06 ` Dong, Eric
@ 2020-05-06 18:33 ` Lendacky, Thomas
2020-05-07 2:28 ` Dong, Eric
2020-05-07 2:38 ` Dong, Eric
0 siblings, 2 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-06 18:33 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io, lersek@redhat.com
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
Hi Eric,
On 5/6/20 10:06 AM, Dong, Eric wrote:
> Hi Tom,
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Wednesday, May 6, 2020 9:20 PM
>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
>> lersek@redhat.com
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
>> be used in support of SEV-ES
>>
>> On 5/5/20 8:53 PM, Dong, Eric wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>>>> Laszlo Ersek
>>>> Sent: Tuesday, May 5, 2020 11:30 PM
>>>> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
>>>> <eric.dong@intel.com>; devel@edk2.groups.io
>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni,
>>>> Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang,
>>>> Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs
>>>> to be used in support of SEV-ES
>>>>
>>>> On 05/04/20 18:41, Tom Lendacky wrote:
>>>>
>>>>> Is there an easy way to run everything that this link points, too?
>>>>> Is it just creating a pull request that does this? I don't want to
>>>>> take up a lot of your time, so if there's some documentation on how
>>>>> to run an integration test to find and fix issues like this, just point me to it.
>>>>
>>>> Just create a pull request; it will set off CI, and you can review VS
>>>> build errors there (if any).
>>>>
>>>> Your PR will automatically be closed (rejected) regardless of whether
>>>> CI succeeds or not. PRs are merged -- in fact, *auto*-merged, by the
>>>> "mergify bot" -- if and only if (a) the CI run succeeds, and (b) the PR has
>> the "push"
>>>> label set.
>>>>
>>>> And only edk2 maintainers have permission to set the "push" label.
>>>> Any PR without the "push" label qualifies as a "personal test build".
>>>> So you can freely experiment with PRs, because you can't (even
>>>> unwittingly) satisfy condition (b).
>>>>
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
>>>> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-
>> Development
>>>> -
>> &data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a9
>> 57285
>>>>
>> 08d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63724
>> 326821
>>>>
>> 7382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYB
>> c%3D&
>>>> amp;reserved=0
>>>> Process
>>>>
>>>
>>> Thanks Laszlo for your explanation.
>>>
>>> I found this patch serial is incompatible for the existed platforms.
>>> Can you help to fix the build failure for these platforms in
>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>> ub.com%2Ftianocore%2Fedk2-
>> platforms&data=02%7C01%7Cthomas.lendacky
>>> %40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e6
>> 08e11a8
>>>
>> 2d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6Z
>> vFmPzjcx
>>> Go9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
>>>
>>
>> I have fixed all of the build issues associated with the VS compiler using the
>> pull request method that Laszlo mentioned. I then successfully built the RPi4
>> platform under GCC (build -n 32 -a AARCH64 -t GCC5 -p
>> Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
>>
>> Is there a particular platform that experiences an issue or are the failures
>> related to the VS compiler errors that my next series will have fixed?
>
> I used the KabylakeRvp3 platform with your changes in Edk2 and met failures.
> KabylakeRvp3 code at Edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\
>
> I used below command to build the code.
> C:\Code\OpenSource\edk2-platforms\Platform\Intel>build_bios.py --platform KabylakeRvp3
>
> You need clone below repositories to build the code.
> Edk2: git@github.com:tianocore/edk2.git
> Edk2-Platform git@github.com:tianocore/edk2-platforms.git
> edk2-non-osi : git@github.com:tianocore/edk2-non-osi.git
> FSP: git@github.com:IntelFsp/FSP.git
On my Linux system, I cloned all the libraries and set the WORKSPACE and
PACKAGES_PATH env variables, sourced edksetup.sh and issued:
python3 edk2-platforms/Platform/Intel/build_bios.py --platform KabylakeRvp3
and got the following errors:
Traceback (most recent call last):
File "edk2-platforms/Platform/Intel/build_bios.py", line 1097, in <module>
main()
File "edk2-platforms/Platform/Intel/build_bios.py", line 1067, in main
platform_config = get_platform_config(arguments.platform, build_config)
File "edk2-platforms/Platform/Intel/build_bios.py", line 904, in get_platform_config
path = platform_data.get(platform_name)
AttributeError: 'NoneType' object has no attribute 'get'
I don't know what I'm missing as to why this error pops up. How is this
done on a Linux system?
Did your build fail because of the VmgExitLib library not being specified?
If the platform includes the CpuExceptionHandlerLib or MpInitLib libraries
then it will now also need to include the VmgExitLib library.
I wish the build system could figure out that because the VmgExitLib
library is specified in the various CpuExceptionHandlerLib INF files and
the various MpInitLib INF files, it would automatically know to include it
in whatever uses those libraries. It doesn't seem right that you would
have to know and specify the library requirements of a library you are
including when the system could figure it out.
Thanks,
Tom
>
>>
>>> I think you also needs to add an wiki page to explain what need to do if an
>> platform needs to integrate your changes, also it's better to explain this
>> feature in the page.
>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>>
>> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7
>> Ctho
>>>
>> mas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd89
>> 61fe4
>>>
>> 884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=x
>> LkoV4zW
>>> hxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
>>
>> I don't see any platform other than OVMF using this feature as it is a
>> virtualization feature. Having said that I can add an explanation of what is
>> needed should another virtualization platform be created under EDK2 that
>> wants to support SEV-ES. And, as you said, I can also explain the feature
>> overall on the page.
>>
>
> I think your page includes two parts, one is how to change the platform code to make the platform pass build,
> the other is if the platform needs to enable the virtualization feature, how to enable it.
>
>>>
>>>
>>> If you want to include this change in the next edk2 release, you need
>>> to add one item for it in the release plan page, sample can be found
>>> in below pages:
>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-
>> Plann
>>>
>> ing&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84
>> a95728
>>>
>> 508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6372
>> 4326821
>>>
>> 7382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870
>> I%3D&
>>> ;reserved=0
>>
>> Thanks. Is there anyone in particular that I need to request this feature be
>> added?
>
> You can syn with Liming, he is the edk2 release manager. He owns edk2 stable tag release task.
>
> Thanks,
> Eric
>>
>> Thanks,
>> Tom
>>
>>>
>>>
>>> Thanks,
>>> Eric
>>>
>>>> Thanks,
>>>> Laszlo
>>>>
>>>>
>>>>
>>
>>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-06 18:33 ` Lendacky, Thomas
@ 2020-05-07 2:28 ` Dong, Eric
2020-05-07 2:38 ` Dong, Eric
1 sibling, 0 replies; 81+ messages in thread
From: Dong, Eric @ 2020-05-07 2:28 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io, lersek@redhat.com
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
Hi Tom,
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Thursday, May 7, 2020 2:33 AM
> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
> lersek@redhat.com
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
> be used in support of SEV-ES
>
> Hi Eric,
>
> On 5/6/20 10:06 AM, Dong, Eric wrote:
> > Hi Tom,
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> >> Lendacky, Thomas
> >> Sent: Wednesday, May 6, 2020 9:20 PM
> >> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
> >> lersek@redhat.com
> >> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> >> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> >> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni,
> >> Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang,
> >> Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> >> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs
> >> to be used in support of SEV-ES
> >>
> >> On 5/5/20 8:53 PM, Dong, Eric wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf
> >>>> Of Laszlo Ersek
> >>>> Sent: Tuesday, May 5, 2020 11:30 PM
> >>>> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
> >>>> <eric.dong@intel.com>; devel@edk2.groups.io
> >>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> >>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> >>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
> >>>> Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
> >>>> Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A
> >>>> <hao.a.wu@intel.com>
> >>>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create
> >>>> PCDs to be used in support of SEV-ES
> >>>>
> >>>> On 05/04/20 18:41, Tom Lendacky wrote:
> >>>>
> >>>>> Is there an easy way to run everything that this link points, too?
> >>>>> Is it just creating a pull request that does this? I don't want to
> >>>>> take up a lot of your time, so if there's some documentation on
> >>>>> how to run an integration test to find and fix issues like this, just point
> me to it.
> >>>>
> >>>> Just create a pull request; it will set off CI, and you can review
> >>>> VS build errors there (if any).
> >>>>
> >>>> Your PR will automatically be closed (rejected) regardless of
> >>>> whether CI succeeds or not. PRs are merged -- in fact,
> >>>> *auto*-merged, by the "mergify bot" -- if and only if (a) the CI
> >>>> run succeeds, and (b) the PR has
> >> the "push"
> >>>> label set.
> >>>>
> >>>> And only edk2 maintainers have permission to set the "push" label.
> >>>> Any PR without the "push" label qualifies as a "personal test build".
> >>>> So you can freely experiment with PRs, because you can't (even
> >>>> unwittingly) satisfy condition (b).
> >>>>
> >>>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >>>> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-
> >> Development
> >>>> -
> >>
> &data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a9
> >> 57285
> >>>>
> >>
> 08d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63724
> >> 326821
> >>>>
> >>
> 7382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYB
> >> c%3D&
> >>>> amp;reserved=0
> >>>> Process
> >>>>
> >>>
> >>> Thanks Laszlo for your explanation.
> >>>
> >>> I found this patch serial is incompatible for the existed platforms.
> >>> Can you help to fix the build failure for these platforms in
> >>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >> h
> >>> ub.com%2Ftianocore%2Fedk2-
> >> platforms&data=02%7C01%7Cthomas.lendacky
> >>> %40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884
> e6
> >> 08e11a8
> >>>
> >>
> 2d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6Z
> >> vFmPzjcx
> >>> Go9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
> >>>
> >>
> >> I have fixed all of the build issues associated with the VS compiler
> >> using the pull request method that Laszlo mentioned. I then
> >> successfully built the RPi4 platform under GCC (build -n 32 -a
> >> AARCH64 -t GCC5 -p
> >> Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
> >>
> >> Is there a particular platform that experiences an issue or are the
> >> failures related to the VS compiler errors that my next series will have
> fixed?
> >
> > I used the KabylakeRvp3 platform with your changes in Edk2 and met
> failures.
> > KabylakeRvp3 code at
> > Edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\
> >
> > I used below command to build the code.
> > C:\Code\OpenSource\edk2-platforms\Platform\Intel>build_bios.py
> > --platform KabylakeRvp3
> >
> > You need clone below repositories to build the code.
> > Edk2: git@github.com:tianocore/edk2.git Edk2-Platform
> > git@github.com:tianocore/edk2-platforms.git
> > edk2-non-osi : git@github.com:tianocore/edk2-non-osi.git
> > FSP: git@github.com:IntelFsp/FSP.git
>
> On my Linux system, I cloned all the libraries and set the WORKSPACE and
> PACKAGES_PATH env variables, sourced edksetup.sh and issued:
>
> python3 edk2-platforms/Platform/Intel/build_bios.py --platform
> KabylakeRvp3
>
> and got the following errors:
>
> Traceback (most recent call last):
> File "edk2-platforms/Platform/Intel/build_bios.py", line 1097, in <module>
> main()
> File "edk2-platforms/Platform/Intel/build_bios.py", line 1067, in main
> platform_config = get_platform_config(arguments.platform, build_config)
> File "edk2-platforms/Platform/Intel/build_bios.py", line 904, in
> get_platform_config
> path = platform_data.get(platform_name)
> AttributeError: 'NoneType' object has no attribute 'get'
I build it in windows environment and I not met this error.
>
> I don't know what I'm missing as to why this error pops up. How is this done
> on a Linux system?
>
> Did your build fail because of the VmgExitLib library not being specified?
> If the platform includes the CpuExceptionHandlerLib or MpInitLib libraries
> then it will now also need to include the VmgExitLib library.
With your V7 patches, I also met other code errors. Just like I replied to you in other mails.
>
> I wish the build system could figure out that because the VmgExitLib library is
> specified in the various CpuExceptionHandlerLib INF files and the various
> MpInitLib INF files, it would automatically know to include it in whatever uses
> those libraries. It doesn't seem right that you would have to know and
> specify the library requirements of a library you are including when the
> system could figure it out.
Current build system not support this yet. So, this is the impact for the exited platforms. We need
to prepare the patches for the existed platforms we cared before push all your patches.
Thanks,
Eric
>
> Thanks,
> Tom
>
> >
> >>
> >>> I think you also needs to add an wiki page to explain what need to
> >>> do if an
> >> platform needs to integrate your changes, also it's better to explain
> >> this feature in the page.
> >>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >> h
> >>>
> >>
> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7
> >> Ctho
> >>>
> >>
> mas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd89
> >> 61fe4
> >>>
> >>
> 884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=x
> >> LkoV4zW
> >>> hxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
> >>
> >> I don't see any platform other than OVMF using this feature as it is
> >> a virtualization feature. Having said that I can add an explanation
> >> of what is needed should another virtualization platform be created
> >> under EDK2 that wants to support SEV-ES. And, as you said, I can also
> >> explain the feature overall on the page.
> >>
> >
> > I think your page includes two parts, one is how to change the
> > platform code to make the platform pass build, the other is if the platform
> needs to enable the virtualization feature, how to enable it.
> >
> >>>
> >>>
> >>> If you want to include this change in the next edk2 release, you
> >>> need to add one item for it in the release plan page, sample can be
> >>> found in below pages:
> >>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >> h
> >>> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-
> >> Plann
> >>>
> >>
> ing&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84
> >> a95728
> >>>
> >>
> 508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6372
> >> 4326821
> >>>
> >>
> 7382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870
> >> I%3D&
> >>> ;reserved=0
> >>
> >> Thanks. Is there anyone in particular that I need to request this
> >> feature be added?
> >
> > You can syn with Liming, he is the edk2 release manager. He owns edk2
> stable tag release task.
> >
> > Thanks,
> > Eric
> >>
> >> Thanks,
> >> Tom
> >>
> >>>
> >>>
> >>> Thanks,
> >>> Eric
> >>>
> >>>> Thanks,
> >>>> Laszlo
> >>>>
> >>>>
> >>>>
> >>
> >>
> >
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-06 18:33 ` Lendacky, Thomas
2020-05-07 2:28 ` Dong, Eric
@ 2020-05-07 2:38 ` Dong, Eric
2020-05-08 18:58 ` Lendacky, Thomas
1 sibling, 1 reply; 81+ messages in thread
From: Dong, Eric @ 2020-05-07 2:38 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io, lersek@redhat.com
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
Hi Tom,
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Thursday, May 7, 2020 2:33 AM
> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
> lersek@redhat.com
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
> be used in support of SEV-ES
>
> Hi Eric,
>
> On 5/6/20 10:06 AM, Dong, Eric wrote:
> > Hi Tom,
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> >> Lendacky, Thomas
> >> Sent: Wednesday, May 6, 2020 9:20 PM
> >> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
> >> lersek@redhat.com
> >> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> >> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> >> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni,
> Ray
> >> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian
> J
> >> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> >> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs
> to
> >> be used in support of SEV-ES
> >>
> >> On 5/5/20 8:53 PM, Dong, Eric wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf
> Of
> >>>> Laszlo Ersek
> >>>> Sent: Tuesday, May 5, 2020 11:30 PM
> >>>> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
> >>>> <eric.dong@intel.com>; devel@edk2.groups.io
> >>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
> >>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
> >>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Ni,
> >>>> Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
> Wang,
> >>>> Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> >>>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create
> PCDs
> >>>> to be used in support of SEV-ES
> >>>>
> >>>> On 05/04/20 18:41, Tom Lendacky wrote:
> >>>>
> >>>>> Is there an easy way to run everything that this link points, too?
> >>>>> Is it just creating a pull request that does this? I don't want to
> >>>>> take up a lot of your time, so if there's some documentation on how
> >>>>> to run an integration test to find and fix issues like this, just point me
> to it.
> >>>>
> >>>> Just create a pull request; it will set off CI, and you can review VS
> >>>> build errors there (if any).
> >>>>
> >>>> Your PR will automatically be closed (rejected) regardless of whether
> >>>> CI succeeds or not. PRs are merged -- in fact, *auto*-merged, by the
> >>>> "mergify bot" -- if and only if (a) the CI run succeeds, and (b) the PR has
> >> the "push"
> >>>> label set.
> >>>>
> >>>> And only edk2 maintainers have permission to set the "push" label.
> >>>> Any PR without the "push" label qualifies as a "personal test build".
> >>>> So you can freely experiment with PRs, because you can't (even
> >>>> unwittingly) satisfy condition (b).
> >>>>
> >>>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> >>>> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-
> >> Development
> >>>> -
> >>
> &data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a9
> >> 57285
> >>>>
> >>
> 08d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63724
> >> 326821
> >>>>
> >>
> 7382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYB
> >> c%3D&
> >>>> amp;reserved=0
> >>>> Process
> >>>>
> >>>
> >>> Thanks Laszlo for your explanation.
> >>>
> >>> I found this patch serial is incompatible for the existed platforms.
> >>> Can you help to fix the build failure for these platforms in
> >>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> >>> ub.com%2Ftianocore%2Fedk2-
> >> platforms&data=02%7C01%7Cthomas.lendacky
> >>> %40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884
> e6
> >> 08e11a8
> >>>
> >>
> 2d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6Z
> >> vFmPzjcx
> >>> Go9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
> >>>
> >>
> >> I have fixed all of the build issues associated with the VS compiler using
> the
> >> pull request method that Laszlo mentioned. I then successfully built the
> RPi4
> >> platform under GCC (build -n 32 -a AARCH64 -t GCC5 -p
> >> Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
> >>
> >> Is there a particular platform that experiences an issue or are the failures
> >> related to the VS compiler errors that my next series will have fixed?
> >
> > I used the KabylakeRvp3 platform with your changes in Edk2 and met
> failures.
> > KabylakeRvp3 code at Edk2-
> platforms\Platform\Intel\KabylakeOpenBoardPkg\
> >
> > I used below command to build the code.
> > C:\Code\OpenSource\edk2-platforms\Platform\Intel>build_bios.py --
> platform KabylakeRvp3
> >
> > You need clone below repositories to build the code.
> > Edk2: git@github.com:tianocore/edk2.git
> > Edk2-Platform git@github.com:tianocore/edk2-platforms.git
> > edk2-non-osi : git@github.com:tianocore/edk2-non-osi.git
> > FSP: git@github.com:IntelFsp/FSP.git
>
> On my Linux system, I cloned all the libraries and set the WORKSPACE and
> PACKAGES_PATH env variables, sourced edksetup.sh and issued:
>
> python3 edk2-platforms/Platform/Intel/build_bios.py --platform
> KabylakeRvp3
>
> and got the following errors:
>
> Traceback (most recent call last):
> File "edk2-platforms/Platform/Intel/build_bios.py", line 1097, in <module>
> main()
> File "edk2-platforms/Platform/Intel/build_bios.py", line 1067, in main
> platform_config = get_platform_config(arguments.platform, build_config)
> File "edk2-platforms/Platform/Intel/build_bios.py", line 904, in
> get_platform_config
> path = platform_data.get(platform_name)
> AttributeError: 'NoneType' object has no attribute 'get'
>
> I don't know what I'm missing as to why this error pops up. How is this
> done on a Linux system?
Can you run the command in Intel directory? Seems like you not run it in Intel directory now.
Change to Intel directory then run python3 build_bios.py --platform KabylakeRvp3
Thanks,
Eric
>
> Did your build fail because of the VmgExitLib library not being specified?
> If the platform includes the CpuExceptionHandlerLib or MpInitLib libraries
> then it will now also need to include the VmgExitLib library.
>
> I wish the build system could figure out that because the VmgExitLib
> library is specified in the various CpuExceptionHandlerLib INF files and
> the various MpInitLib INF files, it would automatically know to include it
> in whatever uses those libraries. It doesn't seem right that you would
> have to know and specify the library requirements of a library you are
> including when the system could figure it out.
>
> Thanks,
> Tom
>
> >
> >>
> >>> I think you also needs to add an wiki page to explain what need to do if
> an
> >> platform needs to integrate your changes, also it's better to explain this
> >> feature in the page.
> >>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> >>>
> >>
> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7
> >> Ctho
> >>>
> >>
> mas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd89
> >> 61fe4
> >>>
> >>
> 884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=x
> >> LkoV4zW
> >>> hxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
> >>
> >> I don't see any platform other than OVMF using this feature as it is a
> >> virtualization feature. Having said that I can add an explanation of what is
> >> needed should another virtualization platform be created under EDK2
> that
> >> wants to support SEV-ES. And, as you said, I can also explain the feature
> >> overall on the page.
> >>
> >
> > I think your page includes two parts, one is how to change the platform
> code to make the platform pass build,
> > the other is if the platform needs to enable the virtualization feature, how
> to enable it.
> >
> >>>
> >>>
> >>> If you want to include this change in the next edk2 release, you need
> >>> to add one item for it in the release plan page, sample can be found
> >>> in below pages:
> >>>
> >>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> >>> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-
> >> Plann
> >>>
> >>
> ing&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84
> >> a95728
> >>>
> >>
> 508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6372
> >> 4326821
> >>>
> >>
> 7382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870
> >> I%3D&
> >>> ;reserved=0
> >>
> >> Thanks. Is there anyone in particular that I need to request this feature be
> >> added?
> >
> > You can syn with Liming, he is the edk2 release manager. He owns edk2
> stable tag release task.
> >
> > Thanks,
> > Eric
> >>
> >> Thanks,
> >> Tom
> >>
> >>>
> >>>
> >>> Thanks,
> >>> Eric
> >>>
> >>>> Thanks,
> >>>> Laszlo
> >>>>
> >>>>
> >>>>
> >>
> >>
> >
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-07 2:38 ` Dong, Eric
@ 2020-05-08 18:58 ` Lendacky, Thomas
0 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-08 18:58 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io, lersek@redhat.com
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
On 5/6/20 9:38 PM, Dong, Eric wrote:
> Hi Tom,
Hi Eric,
>
>> -----Original Message-----
>> From: Tom Lendacky <thomas.lendacky@amd.com>
>> Sent: Thursday, May 7, 2020 2:33 AM
>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
>> lersek@redhat.com
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
>> be used in support of SEV-ES
>>
>> Hi Eric,
>>
>> On 5/6/20 10:06 AM, Dong, Eric wrote:
>>> Hi Tom,
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>> Lendacky, Thomas
>>>> Sent: Wednesday, May 6, 2020 9:20 PM
>>>> To: Dong, Eric <eric.dong@intel.com>; devel@edk2.groups.io;
>>>> lersek@redhat.com
>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni,
>> Ray
>>>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian
>> J
>>>> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs
>> to
>>>> be used in support of SEV-ES
>>>>
>>>> On 5/5/20 8:53 PM, Dong, Eric wrote:
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf
>> Of
>>>>>> Laszlo Ersek
>>>>>> Sent: Tuesday, May 5, 2020 11:30 PM
>>>>>> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
>>>>>> <eric.dong@intel.com>; devel@edk2.groups.io
>>>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>>>>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
>> Ni,
>>>>>> Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>> Wang,
>>>>>> Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>>>>>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create
>> PCDs
>>>>>> to be used in support of SEV-ES
>>>>>>
>>>>>> On 05/04/20 18:41, Tom Lendacky wrote:
>>>>>>
>>>>>>> Is there an easy way to run everything that this link points, too?
>>>>>>> Is it just creating a pull request that does this? I don't want to
>>>>>>> take up a lot of your time, so if there's some documentation on how
>>>>>>> to run an integration test to find and fix issues like this, just point me
>> to it.
>>>>>>
>>>>>> Just create a pull request; it will set off CI, and you can review VS
>>>>>> build errors there (if any).
>>>>>>
>>>>>> Your PR will automatically be closed (rejected) regardless of whether
>>>>>> CI succeeds or not. PRs are merged -- in fact, *auto*-merged, by the
>>>>>> "mergify bot" -- if and only if (a) the CI run succeeds, and (b) the PR has
>>>> the "push"
>>>>>> label set.
>>>>>>
>>>>>> And only edk2 maintainers have permission to set the "push" label.
>>>>>> Any PR without the "push" label qualifies as a "personal test build".
>>>>>> So you can freely experiment with PRs, because you can't (even
>>>>>> unwittingly) satisfy condition (b).
>>>>>>
>>>>>>
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
>>>>>> hub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-
>>>> Development
>>>>>> -
>>>>
>> &data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a9
>>>> 57285
>>>>>>
>>>>
>> 08d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63724
>>>> 326821
>>>>>>
>>>>
>> 7382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYB
>>>> c%3D&
>>>>>> amp;reserved=0
>>>>>> Process
>>>>>>
>>>>>
>>>>> Thanks Laszlo for your explanation.
>>>>>
>>>>> I found this patch serial is incompatible for the existed platforms.
>>>>> Can you help to fix the build failure for these platforms in
>>>>>
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>>>> ub.com%2Ftianocore%2Fedk2-
>>>> platforms&data=02%7C01%7Cthomas.lendacky
>>>>> %40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884
>> e6
>>>> 08e11a8
>>>>>
>>>>
>> 2d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6Z
>>>> vFmPzjcx
>>>>> Go9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
>>>>>
>>>>
>>>> I have fixed all of the build issues associated with the VS compiler using
>> the
>>>> pull request method that Laszlo mentioned. I then successfully built the
>> RPi4
>>>> platform under GCC (build -n 32 -a AARCH64 -t GCC5 -p
>>>> Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
>>>>
>>>> Is there a particular platform that experiences an issue or are the failures
>>>> related to the VS compiler errors that my next series will have fixed?
>>>
>>> I used the KabylakeRvp3 platform with your changes in Edk2 and met
>> failures.
>>> KabylakeRvp3 code at Edk2-
>> platforms\Platform\Intel\KabylakeOpenBoardPkg\
>>>
>>> I used below command to build the code.
>>> C:\Code\OpenSource\edk2-platforms\Platform\Intel>build_bios.py --
>> platform KabylakeRvp3
>>>
>>> You need clone below repositories to build the code.
>>> Edk2: git@github.com:tianocore/edk2.git
>>> Edk2-Platform git@github.com:tianocore/edk2-platforms.git
>>> edk2-non-osi : git@github.com:tianocore/edk2-non-osi.git
>>> FSP: git@github.com:IntelFsp/FSP.git
>>
>> On my Linux system, I cloned all the libraries and set the WORKSPACE and
>> PACKAGES_PATH env variables, sourced edksetup.sh and issued:
>>
>> python3 edk2-platforms/Platform/Intel/build_bios.py --platform
>> KabylakeRvp3
>>
>> and got the following errors:
>>
>> Traceback (most recent call last):
>> File "edk2-platforms/Platform/Intel/build_bios.py", line 1097, in <module>
>> main()
>> File "edk2-platforms/Platform/Intel/build_bios.py", line 1067, in main
>> platform_config = get_platform_config(arguments.platform, build_config)
>> File "edk2-platforms/Platform/Intel/build_bios.py", line 904, in
>> get_platform_config
>> path = platform_data.get(platform_name)
>> AttributeError: 'NoneType' object has no attribute 'get'
>>
>> I don't know what I'm missing as to why this error pops up. How is this
>> done on a Linux system?
>
> Can you run the command in Intel directory? Seems like you not run it in Intel directory now.
>
> Change to Intel directory then run python3 build_bios.py --platform KabylakeRvp3
Ok, running out of the Intel directory worked.
I have fixed all of the issues that were identified by the CI tool for VS
compiler and after modifying the platform DSC files to include the
VmgExitLib library, I was able to successfully build the KabylakeRvp3
platform.
Thanks,
Tom
>
> Thanks,
> Eric
>>
>> Did your build fail because of the VmgExitLib library not being specified?
>> If the platform includes the CpuExceptionHandlerLib or MpInitLib libraries
>> then it will now also need to include the VmgExitLib library.
>>
>> I wish the build system could figure out that because the VmgExitLib
>> library is specified in the various CpuExceptionHandlerLib INF files and
>> the various MpInitLib INF files, it would automatically know to include it
>> in whatever uses those libraries. It doesn't seem right that you would
>> have to know and specify the library requirements of a library you are
>> including when the system could figure it out.
>>
>> Thanks,
>> Tom
>>
>>>
>>>>
>>>>> I think you also needs to add an wiki page to explain what need to do if
>> an
>>>> platform needs to integrate your changes, also it's better to explain this
>>>> feature in the page.
>>>>>
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>>>>
>>>>
>> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7
>>>> Ctho
>>>>>
>>>>
>> mas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd89
>>>> 61fe4
>>>>>
>>>>
>> 884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=x
>>>> LkoV4zW
>>>>> hxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
>>>>
>>>> I don't see any platform other than OVMF using this feature as it is a
>>>> virtualization feature. Having said that I can add an explanation of what is
>>>> needed should another virtualization platform be created under EDK2
>> that
>>>> wants to support SEV-ES. And, as you said, I can also explain the feature
>>>> overall on the page.
>>>>
>>>
>>> I think your page includes two parts, one is how to change the platform
>> code to make the platform pass build,
>>> the other is if the platform needs to enable the virtualization feature, how
>> to enable it.
>>>
>>>>>
>>>>>
>>>>> If you want to include this change in the next edk2 release, you need
>>>>> to add one item for it in the release plan page, sample can be found
>>>>> in below pages:
>>>>>
>>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>>>> ub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-
>>>> Plann
>>>>>
>>>>
>> ing&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84
>>>> a95728
>>>>>
>>>>
>> 508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6372
>>>> 4326821
>>>>>
>>>>
>> 7382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870
>>>> I%3D&
>>>>> ;reserved=0
>>>>
>>>> Thanks. Is there anyone in particular that I need to request this feature be
>>>> added?
>>>
>>> You can syn with Liming, he is the edk2 release manager. He owns edk2
>> stable tag release task.
>>>
>>> Thanks,
>>> Eric
>>>>
>>>> Thanks,
>>>> Tom
>>>>
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Eric
>>>>>
>>>>>> Thanks,
>>>>>> Laszlo
>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES
2020-05-06 13:19 ` Lendacky, Thomas
2020-05-06 15:06 ` Dong, Eric
@ 2020-05-06 16:24 ` Laszlo Ersek
1 sibling, 0 replies; 81+ messages in thread
From: Laszlo Ersek @ 2020-05-06 16:24 UTC (permalink / raw)
To: Tom Lendacky, Dong, Eric, devel@edk2.groups.io
Cc: Justen, Jordan L, Ard Biesheuvel, Kinney, Michael D, Gao, Liming,
Ni, Ray, Brijesh Singh, Wang, Jian J, Wu, Hao A
On 05/06/20 15:19, Tom Lendacky wrote:
> On 5/5/20 8:53 PM, Dong, Eric wrote:
>>
>>
>>> -----Original Message-----
>>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>>> Laszlo Ersek
>>> Sent: Tuesday, May 5, 2020 11:30 PM
>>> To: Tom Lendacky <thomas.lendacky@amd.com>; Dong, Eric
>>> <eric.dong@intel.com>; devel@edk2.groups.io
>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Ard Biesheuvel
>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni,
>>> Ray
>>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; Wang, Jian J
>>> <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
>>> Subject: Re: [edk2-devel] [PATCH v7 01/43] MdeModulePkg: Create PCDs to
>>> be used in support of SEV-ES
>>>
>>> On 05/04/20 18:41, Tom Lendacky wrote:
>>>
>>>> Is there an easy way to run everything that this link points, too? Is
>>>> it just creating a pull request that does this? I don't want to take
>>>> up a lot of your time, so if there's some documentation on how to run
>>>> an integration test to find and fix issues like this, just point me
>>>> to it.
>>>
>>> Just create a pull request; it will set off CI, and you can review VS
>>> build errors
>>> there (if any).
>>>
>>> Your PR will automatically be closed (rejected) regardless of whether CI
>>> succeeds or not. PRs are merged -- in fact, *auto*-merged, by the
>>> "mergify
>>> bot" -- if and only if (a) the CI run succeeds, and (b) the PR has
>>> the "push"
>>> label set.
>>>
>>> And only edk2 maintainers have permission to set the "push" label.
>>> Any PR
>>> without the "push" label qualifies as a "personal test build". So you
>>> can freely
>>> experiment with PRs, because you can't (even unwittingly) satisfy
>>> condition
>>> (b).
>>>
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Development-&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=3%2FIKB174QaVLaqO0u1gdrL0izXmhEZ%2Byvj3iC13UYBc%3D&reserved=0
>>>
>>> Process
>>>
>>
>> Thanks Laszlo for your explanation.
>>
>> I found this patch serial is incompatible for the existed platforms.
>> Can you help to fix the build failure for these platforms in
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-platforms&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=jU0qrB%2BV6ZvFmPzjcxGo9o2Pu1%2FrhRW0gUZTMv%2BiXDQ%3D&reserved=0
>>
>>
>
> I have fixed all of the build issues associated with the VS compiler
> using the pull request method that Laszlo mentioned. I then successfully
> built the RPi4 platform under GCC (build -n 32 -a AARCH64 -t GCC5 -p
> Platform/RaspberryPi/RPi4/RPi4.dsc) using the AARCH64 cross compiler.
>
> Is there a particular platform that experiences an issue or are the
> failures related to the VS compiler errors that my next series will have
> fixed?
I think that Eric refers to various (as of yet, unspecified) platform
DSCs in the edk2-platforms tree, which consume edk2.
https://github.com/tianocore/edk2-platforms/
I don't fully agree with Eric on this observation. I agree somewhat.
I have always made the argument that *all* platform code should reside
in edk2; in other words, we should not have a separate edk2-platforms
repository. Then it is feasible for a contributor to adapt dependent
platform code in the same patch series that modifies core code.
But I have not been successful in arguing against the edk2-platforms
tree's existence, and so we have two projects now, with separate git
histories. Therefore, the pattern sometiems followed is to split the
edk2 (core) patch series into multiple sub-series, and to post an
edk2-platforms series in the middle, to help edk2-platforms cope with
the edk2 changes.
The question is of course how complicated this is. If the edk2-platforms
patches are not difficult, then I think the edk2-platforms maintainers
may ask the contributor to submit patches for edk2-platforms too, as a
*courtesy*. But if the edk2-platforms patches are many or complicated,
then I think it's *unfair* to block edk2 changes *only* due to
edk2-platforms dependencies. The edk2 contributor may not be familiar
with the edk2-platforms stuff at all; worse, firmware platforms in the
latter tree have often very quirky build instructions.
Inside a single git tree, a contributor is justifiedly expected to track
down dependencies and to update them (see for example Tom's patches for
UefiPayloadPkg!), but in other trees, that's not necessarily the case.
If we'd like Tom to adapt edk2-platforms to the edk2 changes, and maybe
even restructure the edk2 series in order to accommodate this, then the
*bare minimum* is to provide specific error messages and build instructions.
>
>> I think you also needs to add an wiki page to explain what need to do
>> if an platform needs to integrate your changes, also it's better to
>> explain this feature in the page.
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=xLkoV4zWhxtsbqszqPc0lEAl%2BYLL%2B2wg1nIXql8a64E%3D&reserved=0
>>
>
> I don't see any platform other than OVMF using this feature as it is a
> virtualization feature. Having said that I can add an explanation of
> what is needed should another virtualization platform be created under
> EDK2 that wants to support SEV-ES. And, as you said, I can also explain
> the feature overall on the page.
This should be approached from the "out of tree platform build errors"
angle described above.
For example, if there's a pre-existent / widely used library instance in
UefiCpuPkg, and you add a new library class dependency to it, such that
even the library class is entirely new in edk2, that will require
existent platforms to resolve the new lib class to a proper lib instence
in their DSC files -- otherwise they will get a build error. The wiki
page should basically explain such DSC updates in natural language.
If there are new PCDs in UefiCpuPkg.dec that a platform might want to
customize in its DSC file, that could be useful to mention in the Wiki
page too.
Because SEV-ES is only really relevant for OVMF at this point, I think
the wiki page should only help out of tree platform owners prevent build
errors, at this point.
But for that, Eric should please provide build instructions and error
messages for such out of tree platforms that actually break, with this
edk2 series applied.
>
>>
>>
>> If you want to include this change in the next edk2 release, you need
>> to add one item for it in the release plan page, sample can be found
>> in below pages:
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FEDK-II-Release-Planning&data=02%7C01%7Cthomas.lendacky%40amd.com%7C9cff3475aff84a95728508d7f1604c99%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637243268217382019&sdata=kcDVjYHMS9bRRZOlKEk5ynFNT39AnxchJAMak%2Bn870I%3D&reserved=0
>>
>
> Thanks. Is there anyone in particular that I need to request this
> feature be added?
Here's a general approach:
(1) Clone the git repository that is the edk2 wiki, locally:
git://github.com/tianocore/tianocore.github.io.wiki
or
https://github.com/tianocore/tianocore.github.io.wiki.git
(2) On a topic branch, implement your wiki changes.
In this case, the "EDK-II-Release-Planning.md" file should be updated.
Pick one of the upcoming stable releases, and list
<https://bugzilla.tianocore.org/show_bug.cgi?id=2198> under it. Use
existent items as example.
(3) In order to check a "rendered" view of your edk2 wiki changes, I
recommend having a personal fork of the edk2 project on github. Then,
you can use the wiki associated with *that* personal project as a
personal review space for your edk2 wiki changes.
For example, the personal wiki that I use for this purpose has the
following URL in my clone:
git@github.com:lersek/edk2.wiki.git
^^^^^^ ^^^^
and I use the following URL in my browser:
https://github.com/lersek/edk2/wiki
^^^^^^ ^^^^
(4) Push your local changes (on the local topic branch) to the remote
*master* branch (github.com ignores branches different from "master" in
wiki repositories). Verify the "rendered" view of your wiki changes.
(5) Post the patch to edk2-devel, using the subject prefix
"edk2-wiki PATCH"
and also include a URL to the "rendered view" from (4).
I don't know the exact set of people having push access to the wiki; CC
me on your wiki patch, and I'll push it.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 02/43] UefiCpuPkg: Create PCD to be used in support of SEV-ES
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 03/43] MdePkg: Add the MSR definition for the GHCB register Lendacky, Thomas
` (41 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 03/43] MdePkg: Add the MSR definition for the GHCB register
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 01/43] MdeModulePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 02/43] UefiCpuPkg: Create PCD " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 04/43] MdePkg: Add a structure definition for the GHCB Lendacky, Thomas
` (40 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 04/43] MdePkg: Add a structure definition for the GHCB
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (2 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 03/43] MdePkg: Add the MSR definition for the GHCB register Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 05/43] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables Lendacky, Thomas
` (39 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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 | 136 +++++++++++++++++++++++++++++
1 file changed, 136 insertions(+)
create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
diff --git a/MdePkg/Include/Register/Amd/Ghcb.h b/MdePkg/Include/Register/Amd/Ghcb.h
new file mode 100644
index 000000000000..6bdb79d5428d
--- /dev/null
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -0,0 +1,136 @@
+/** @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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#define UD_EXCEPTION 6
+#define GP_EXCEPTION 13
+
+#define GHCB_VERSION_MIN 1
+#define GHCB_VERSION_MAX 1
+
+#define GHCB_STANDARD_USAGE 0
+
+typedef enum {
+ SvmExitDr7Read = 0x27,
+ SvmExitDr7Write = 0x37,
+ SvmExitRdtsc = 0x6E,
+ SvmExitRdpmc,
+ SvmExitCpuid = 0x72,
+ SvmExitInvd = 0x76,
+ SvmExitIoioProt = 0x7B,
+ SvmExitMsr,
+ SvmExitVmmCall = 0x81,
+ SvmExitRdtscp = 0x87,
+ SvmExitWbinvd = 0x89,
+ SvmExitMonitor,
+ SvmExitMwait,
+ SvmExitNpf = 0x400,
+
+ // VMG special exits
+ SvmExitMmioRead = 0x80000001,
+ SvmExitMmioWrite,
+ SvmExitNmiComplete,
+ SvmExitApResetHold,
+ SvmExitApJumpTable,
+
+ SvmExitUnsupported = 0x8000FFFF,
+} SVM_EXITCODE;
+
+typedef enum {
+ GhcbCpl = 25,
+ GhcbRflags = 46,
+ GhcbRip,
+ GhcbRsp = 59,
+ GhcbRax = 63,
+ GhcbRcx = 97,
+ GhcbRdx,
+ GhcbRbx,
+ GhcbRbp = 101,
+ GhcbRsi,
+ GhcbRdi,
+ GhcbR8,
+ GhcbR9,
+ GhcbR10,
+ GhcbR11,
+ GhcbR12,
+ GhcbR13,
+ GhcbR14,
+ GhcbR15,
+ GhcbXCr0 = 125,
+} GHCB_REGISTER;
+
+typedef 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 05/43] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (3 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 04/43] MdePkg: Add a structure definition for the GHCB Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 06/43] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
` (38 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh, 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 +
.../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +++-
.../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
.../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +++-
.../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 98bc17fc9d1f..5e6b78e295e6 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -111,6 +111,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..e097508d72af 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) & 0x1000)) {
+ 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 06/43] MdePkg/BaseLib: Add support for the XGETBV instruction
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (4 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 05/43] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 07/43] MdePkg/BaseLib: Add support for the VMGEXIT instruction Lendacky, Thomas
` (37 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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(+)
create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 3586beb0ab5c..d7a1dd017e95 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -152,6 +152,7 @@ [Sources.Ia32]
Ia32/ARShiftU64.c | MSFT
Ia32/EnableCache.c | MSFT
Ia32/DisableCache.c | MSFT
+ Ia32/XGetBv.nasm | MSFT
Ia32/GccInline.c | GCC
@@ -286,6 +287,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 ecadff8b235e..d0cbb52ed8f9 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7889,6 +7889,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
+
+ @retval 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..591f0bb0e097 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
+
+ @retval 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..3eed1205adb2 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
+
+ @retval 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..b6dee38af029
--- /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..f3aec43e6813
--- /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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 07/43] MdePkg/BaseLib: Add support for the VMGEXIT instruction
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (5 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 06/43] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
` (36 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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(+)
create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index d7a1dd017e95..62a09197b8a8 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -153,6 +153,7 @@ [Sources.Ia32]
Ia32/EnableCache.c | MSFT
Ia32/DisableCache.c | MSFT
Ia32/XGetBv.nasm | MSFT
+ Ia32/VmgExit.nasm | MSFT
Ia32/GccInline.c | GCC
@@ -288,6 +289,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 d0cbb52ed8f9..99fff8af5a3c 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7906,6 +7906,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 591f0bb0e097..ee8c62c79c93 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 3eed1205adb2..277974eff9ee 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..cdf727825400
--- /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..6537a97b273c
--- /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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (6 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 07/43] MdePkg/BaseLib: Add support for the VMGEXIT instruction Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-05-09 1:06 ` Dong, Eric
2020-04-22 17:41 ` [PATCH v7 09/43] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
` (35 subsequent siblings)
43 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
To support issuing a VMGEXIT instruction, create a library that can be
used to perform GHCB and VMGEXIT related operations and to issue the
actual VMGEXIT instruction when using the GHCB.
Additionally, two VMGEXIT / MMIO related functions are created to support
flash emulation. Flash emulation currently is done by marking the flash
area as read-only and taking a nested page fault to perform the emulation
of the instruction. However, emulation cannot be performed because there
is no instruction decode assist support when SEV-ES is enabled. Provide
routines to initiate an MMIO request to perform actual writes to flash.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
UefiCpuPkg/UefiCpuPkg.dec | 3 +
UefiCpuPkg/UefiCpuPkg.dsc | 2 +
UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +++
UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++++++++
UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++++++++++++++++++
UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
6 files changed, 463 insertions(+)
create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 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 d28cb5cccb52..997840452218 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/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.SEC]
PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
@@ -136,6 +137,7 @@ [Components.IA32, Components.X64]
UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
+ UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
UefiCpuPkg/SecCore/SecCore.inf
diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
new file mode 100644
index 000000000000..6acfa779e75a
--- /dev/null
+++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
@@ -0,0 +1,33 @@
+## @file
+# VMGEXIT Support Library.
+#
+# Copyright (c) 2019, Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = VmgExitLib
+ MODULE_UNI_FILE = VmgExitLib.uni
+ FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
+ 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 = IA32 X64
+#
+
+[Sources]
+ VmgExitLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
diff --git a/UefiCpuPkg/Include/Library/VmgExitLib.h b/UefiCpuPkg/Include/Library/VmgExitLib.h
new file mode 100644
index 000000000000..3bf05bebd326
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
@@ -0,0 +1,117 @@
+/** @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.
+
+ Copyright (c) 2019, 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 <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.
+
+ @retval 0 VMGEXIT succeeded.
+ @retval 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
+ );
+
+#define VMGMMIO_READ False
+#define VMGMMIO_WRITE True
+
+/**
+ Perform MMIO write of a buffer to a non-MMIO marked range.
+
+ Performs an MMIO write without taking a #VC. This is useful
+ for Flash devices, which are marked read-only.
+
+ @param[in, out] Dest A pointer to the destination buffer
+ @param[in] Src A pointer to the source data to be written
+ @param[in] Bytes Number of bytes to write
+
+**/
+VOID
+EFIAPI
+VmgMmioWrite (
+ IN OUT UINT8 *Dest,
+ IN UINT8 *Src,
+ IN UINTN Bytes
+ );
+
+/**
+ Issue the GHCB set AP Jump Table VMGEXIT.
+
+ Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the
+ AP Jump Table address with the hypervisor for retrieval at a later time.
+
+ @param[in] Address Physical address of the AP Jump Table
+
+ @retval 0 VMGEXIT succeeded.
+ @retval Others VMGEXIT processing did not succeed. Exception
+ number to be propagated.
+
+**/
+UINT64
+EFIAPI
+VmgExitSetAPJumpTable (
+ IN EFI_PHYSICAL_ADDRESS Address
+ );
+
+#endif
diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
new file mode 100644
index 000000000000..6137b1a0eb64
--- /dev/null
+++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
@@ -0,0 +1,293 @@
+/** @file
+ VMGEXIT Support Library.
+
+ Copyright (c) 2019, 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 <Register/Amd/Ghcb.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
+
+ @retval 0 VMGEXIT succeeded.
+ @retval 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 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;
+}
+
+/**
+ 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.
+
+ @retval 0 VMGEXIT succeeded.
+ @retval 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
+ )
+{
+ 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
+ )
+{
+}
+
+/**
+ Perform VMGEXIT MMIO read or write.
+
+ Performs the requested MMIO read or write using the VMGEXIT instruction.
+
+ For an MMIO read, the data that has been read during the VMGEXIT is placed in
+ the SharedBuffer area of the GHCB. This is then copied to the actual
+ destination buffer within the guest.
+
+ For an MMIO write, the data to be written is copied into the SharedBuffer area
+ of the GHCB by the guest. This is then copied to the actual destination buffer
+ by the hypervisor during the VMGEXIT.
+
+ @param[in, out] MmioAddress A pointer to the MMIO buffer to be read/written
+ @param[in, out] Buffer A pointer to the buffer to hold the data thas
+ has been read or hold the data to be written
+ @param[in] Bytes Number of bytes to read or write
+ @param[in] Write If set, the request is for an MMIO write, else
+ it is an MMIO read.
+
+ @retval 0 VMGEXIT succeeded.
+ @retval Others VMGEXIT processing did not succeed. Exception
+ number to be propagated.
+
+**/
+STATIC
+UINT64
+EFIAPI
+VmgMmio (
+ IN OUT UINT8 *MmioAddress,
+ IN OUT UINT8 *Buffer,
+ IN UINTN Bytes,
+ IN BOOLEAN Write
+ )
+{
+ UINT64 MmioOp, ExitInfo1, ExitInfo2, Status;
+ GHCB *Ghcb;
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ //
+ // This function is about to set fields in the GHCB. Do not execute
+ // anything that will cause a #VC before issuing the VmgExit(). Any #VC
+ // will result in all GHCB settings being overwritten (this means, e.g.,
+ // do not add DEBUG() statements).
+ //
+ VmgInit (Ghcb);
+
+ if (Write) {
+ MmioOp = SvmExitMmioWrite;
+ } else {
+ MmioOp = SvmExitMmioRead;
+ }
+
+ ExitInfo1 = (UINT64) (UINTN) MmioAddress;
+ ExitInfo2 = Bytes;
+
+ if (Write) {
+ CopyMem (Ghcb->SharedBuffer, Buffer, Bytes);
+ }
+
+ Ghcb->SaveArea.SwScratch = (UINT64) (UINTN) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, MmioOp, ExitInfo1, ExitInfo2);
+ if (Status != 0) {
+ return Status;
+ }
+
+ if (!Write) {
+ CopyMem (Buffer, Ghcb->SharedBuffer, Bytes);
+ }
+
+ VmgDone (Ghcb);
+
+ return 0;
+}
+
+/**
+ Perform MMIO write of a buffer to a non-MMIO marked range.
+
+ Performs an MMIO write without taking a #VC. This is useful
+ for Flash devices, which are marked read-only.
+
+ @param[in, out] Dest A pointer to the destination buffer
+ @param[in] Src A pointer to the source data to be written
+ @param[in] Bytes Number of bytes to write
+
+**/
+VOID
+EFIAPI
+VmgMmioWrite (
+ IN OUT UINT8 *Dest,
+ IN UINT8 *Src,
+ IN UINTN Bytes
+ )
+{
+ VmgMmio (Dest, Src, Bytes, TRUE);
+}
+
+/**
+ Issue the GHCB set AP Jump Table VMGEXIT.
+
+ Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the
+ AP Jump Table address with the hypervisor for retrieval at a later time.
+
+ @param[in] Address Physical address of the AP Jump Table
+
+ @retval 0 VMGEXIT succeeded.
+ @retval Others VMGEXIT processing did not succeed. Exception
+ number to be propagated.
+
+**/
+UINT64
+EFIAPI
+VmgExitSetAPJumpTable (
+ IN EFI_PHYSICAL_ADDRESS Address
+ )
+{
+ UINT64 ExitInfo1, ExitInfo2, Status;
+ GHCB *Ghcb;
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ VmgInit (Ghcb);
+
+ ExitInfo1 = 0;
+ ExitInfo2 = (UINT64) (UINTN) Address;
+
+ Status = VmgExit (Ghcb, SvmExitApJumpTable, ExitInfo1, ExitInfo2);
+
+ VmgDone (Ghcb);
+
+ return Status;
+}
+
diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
new file mode 100644
index 000000000000..e8656aae4726
--- /dev/null
+++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
@@ -0,0 +1,15 @@
+// /** @file
+// VMGEXIT support library instance.
+//
+// VMGEXIT support library instance.
+//
+// Copyright (c) 2019, Advanced Micro Devices, Inc. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT Support Library."
+
+#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT Support Library."
+
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* Re: [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT
2020-04-22 17:41 ` [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
@ 2020-05-09 1:06 ` Dong, Eric
2020-05-09 14:08 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Dong, Eric @ 2020-05-09 1:06 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Ni, Ray, Brijesh Singh
Hi Tom,
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Thursday, April 23, 2020 1:41 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
> <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney,
> Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>
> Subject: [PATCH v7 08/43] UefiCpuPkg: Implement library support for
> VMGEXIT
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
>
> To support issuing a VMGEXIT instruction, create a library that can be used to
> perform GHCB and VMGEXIT related operations and to issue the actual
> VMGEXIT instruction when using the GHCB.
>
> Additionally, two VMGEXIT / MMIO related functions are created to support
> flash emulation. Flash emulation currently is done by marking the flash area
> as read-only and taking a nested page fault to perform the emulation of the
> instruction. However, emulation cannot be performed because there is no
> instruction decode assist support when SEV-ES is enabled. Provide routines
> to initiate an MMIO request to perform actual writes to flash.
>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> UefiCpuPkg/UefiCpuPkg.dec | 3 +
> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +++
> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++++++++
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293
> +++++++++++++++++++
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
> 6 files changed, 463 insertions(+)
> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index 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
> d28cb5cccb52..997840452218 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/VmgExitLib/VmgExitLib.inf
>
> [LibraryClasses.common.SEC]
>
> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.i
> nf
> @@ -136,6 +137,7 @@ [Components.IA32, Components.X64]
>
> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
> Null.inf
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> + UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
> UefiCpuPkg/SecCore/SecCore.inf
> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> new file mode 100644
> index 000000000000..6acfa779e75a
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +# VMGEXIT Support Library.
> +#
> +# Copyright (c) 2019, Advanced Micro Devices, Inc. All rights
> +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = VmgExitLib
> + MODULE_UNI_FILE = VmgExitLib.uni
> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
> + 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 = IA32 X64
> +#
> +
> +[Sources]
> + VmgExitLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> +
> diff --git a/UefiCpuPkg/Include/Library/VmgExitLib.h
> b/UefiCpuPkg/Include/Library/VmgExitLib.h
> new file mode 100644
> index 000000000000..3bf05bebd326
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
> @@ -0,0 +1,117 @@
> +/** @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.
> +
> + Copyright (c) 2019, 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 <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.
> +
> + @retval 0 VMGEXIT succeeded.
> + @retval 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
> + );
> +
> +#define VMGMMIO_READ False
> +#define VMGMMIO_WRITE True
> +
> +/**
> + Perform MMIO write of a buffer to a non-MMIO marked range.
> +
> + Performs an MMIO write without taking a #VC. This is useful for
> + Flash devices, which are marked read-only.
> +
> + @param[in, out] Dest A pointer to the destination buffer
> + @param[in] Src A pointer to the source data to be written
> + @param[in] Bytes Number of bytes to write
> +
> +**/
> +VOID
> +EFIAPI
> +VmgMmioWrite (
> + IN OUT UINT8 *Dest,
> + IN UINT8 *Src,
> + IN UINTN Bytes
> + );
> +
> +/**
> + Issue the GHCB set AP Jump Table VMGEXIT.
> +
> + Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the
> + AP Jump Table address with the hypervisor for retrieval at a later time.
> +
> + @param[in] Address Physical address of the AP Jump Table
> +
> + @retval 0 VMGEXIT succeeded.
> + @retval Others VMGEXIT processing did not succeed. Exception
> + number to be propagated.
> +
> +**/
> +UINT64
> +EFIAPI
> +VmgExitSetAPJumpTable (
> + IN EFI_PHYSICAL_ADDRESS Address
> + );
I think above two APIs should not been added to this library, they are not the basic actions for VmgExit.
Remove these two APIs will make the library more stable.
Also, I check all the code in this patch series, only one caller for each API, so I think we can directly
move these codes to the caller. If later more and more callers need to use these two APIs, we can
create another service library to convenient the callers.
I ignore all the coding style related issues in this patch because I assume you have passed ECC
checks in your new patches.
Thanks,
Eric
> +
> +#endif
> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> new file mode 100644
> index 000000000000..6137b1a0eb64
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> @@ -0,0 +1,293 @@
> +/** @file
> + VMGEXIT Support Library.
> +
> + Copyright (c) 2019, 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 <Register/Amd/Ghcb.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
> +
> + @retval 0 VMGEXIT succeeded.
> + @retval 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 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;
> +}
> +
> +/**
> + 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.
> +
> + @retval 0 VMGEXIT succeeded.
> + @retval 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
> + )
> +{
> + 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
> + )
> +{
> +}
> +
> +/**
> + Perform VMGEXIT MMIO read or write.
> +
> + Performs the requested MMIO read or write using the VMGEXIT
> instruction.
> +
> + For an MMIO read, the data that has been read during the VMGEXIT is
> + placed in the SharedBuffer area of the GHCB. This is then copied to
> + the actual destination buffer within the guest.
> +
> + For an MMIO write, the data to be written is copied into the
> + SharedBuffer area of the GHCB by the guest. This is then copied to
> + the actual destination buffer by the hypervisor during the VMGEXIT.
> +
> + @param[in, out] MmioAddress A pointer to the MMIO buffer to be
> read/written
> + @param[in, out] Buffer A pointer to the buffer to hold the data thas
> + has been read or hold the data to be written
> + @param[in] Bytes Number of bytes to read or write
> + @param[in] Write If set, the request is for an MMIO write, else
> + it is an MMIO read.
> +
> + @retval 0 VMGEXIT succeeded.
> + @retval Others VMGEXIT processing did not succeed. Exception
> + number to be propagated.
> +
> +**/
> +STATIC
> +UINT64
> +EFIAPI
> +VmgMmio (
> + IN OUT UINT8 *MmioAddress,
> + IN OUT UINT8 *Buffer,
> + IN UINTN Bytes,
> + IN BOOLEAN Write
> + )
> +{
> + UINT64 MmioOp, ExitInfo1, ExitInfo2, Status;
> + GHCB *Ghcb;
> + MSR_SEV_ES_GHCB_REGISTER Msr;
> +
> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb
> =
> + Msr.Ghcb;
> +
> + //
> + // This function is about to set fields in the GHCB. Do not execute
> + // anything that will cause a #VC before issuing the VmgExit(). Any
> + #VC // will result in all GHCB settings being overwritten (this
> + means, e.g., // do not add DEBUG() statements).
> + //
> + VmgInit (Ghcb);
> +
> + if (Write) {
> + MmioOp = SvmExitMmioWrite;
> + } else {
> + MmioOp = SvmExitMmioRead;
> + }
> +
> + ExitInfo1 = (UINT64) (UINTN) MmioAddress;
> + ExitInfo2 = Bytes;
> +
> + if (Write) {
> + CopyMem (Ghcb->SharedBuffer, Buffer, Bytes); }
> +
> + Ghcb->SaveArea.SwScratch = (UINT64) (UINTN) Ghcb->SharedBuffer;
> + Status = VmgExit (Ghcb, MmioOp, ExitInfo1, ExitInfo2); if (Status !=
> + 0) {
> + return Status;
> + }
> +
> + if (!Write) {
> + CopyMem (Buffer, Ghcb->SharedBuffer, Bytes); }
> +
> + VmgDone (Ghcb);
> +
> + return 0;
> +}
> +
> +/**
> + Perform MMIO write of a buffer to a non-MMIO marked range.
> +
> + Performs an MMIO write without taking a #VC. This is useful for
> + Flash devices, which are marked read-only.
> +
> + @param[in, out] Dest A pointer to the destination buffer
> + @param[in] Src A pointer to the source data to be written
> + @param[in] Bytes Number of bytes to write
> +
> +**/
> +VOID
> +EFIAPI
> +VmgMmioWrite (
> + IN OUT UINT8 *Dest,
> + IN UINT8 *Src,
> + IN UINTN Bytes
> + )
> +{
> + VmgMmio (Dest, Src, Bytes, TRUE);
> +}
> +
> +/**
> + Issue the GHCB set AP Jump Table VMGEXIT.
> +
> + Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the
> + AP Jump Table address with the hypervisor for retrieval at a later time.
> +
> + @param[in] Address Physical address of the AP Jump Table
> +
> + @retval 0 VMGEXIT succeeded.
> + @retval Others VMGEXIT processing did not succeed. Exception
> + number to be propagated.
> +
> +**/
> +UINT64
> +EFIAPI
> +VmgExitSetAPJumpTable (
> + IN EFI_PHYSICAL_ADDRESS Address
> + )
> +{
> + UINT64 ExitInfo1, ExitInfo2, Status;
> + GHCB *Ghcb;
> + MSR_SEV_ES_GHCB_REGISTER Msr;
> +
> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb
> =
> + Msr.Ghcb;
> +
> + VmgInit (Ghcb);
> +
> + ExitInfo1 = 0;
> + ExitInfo2 = (UINT64) (UINTN) Address;
> +
> + Status = VmgExit (Ghcb, SvmExitApJumpTable, ExitInfo1, ExitInfo2);
> +
> + VmgDone (Ghcb);
> +
> + return Status;
> +}
> +
> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
> new file mode 100644
> index 000000000000..e8656aae4726
> --- /dev/null
> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
> @@ -0,0 +1,15 @@
> +// /** @file
> +// VMGEXIT support library instance.
> +//
> +// VMGEXIT support library instance.
> +//
> +// Copyright (c) 2019, Advanced Micro Devices, Inc. All rights
> +reserved.<BR> // SPDX-License-Identifier: BSD-2-Clause-Patent // // **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT
> Support Library."
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
> Support Library."
> +
> --
> 2.17.1
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT
2020-05-09 1:06 ` Dong, Eric
@ 2020-05-09 14:08 ` Lendacky, Thomas
0 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-09 14:08 UTC (permalink / raw)
To: Dong, Eric, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Ni, Ray, Brijesh Singh
On 5/8/20 8:06 PM, Dong, Eric wrote:
> Hi Tom,
>
>> -----Original Message-----
>> From: Tom Lendacky <thomas.lendacky@amd.com>
>> Sent: Thursday, April 23, 2020 1:41 AM
>> To: devel@edk2.groups.io
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>> <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney,
>> Michael D <michael.d.kinney@intel.com>; Gao, Liming
>> <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray
>> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>
>> Subject: [PATCH v7 08/43] 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%7C263f75f798c64b75e23508d7f3b53108%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637245831845366269&sdata=TndzK3JmXQFNGBHSfbsSPr%2BGY8NMVX%2B1Durfner4k1I%3D&reserved=0
>>
>> To support issuing a VMGEXIT instruction, create a library that can be used to
>> perform GHCB and VMGEXIT related operations and to issue the actual
>> VMGEXIT instruction when using the GHCB.
>>
>> Additionally, two VMGEXIT / MMIO related functions are created to support
>> flash emulation. Flash emulation currently is done by marking the flash area
>> as read-only and taking a nested page fault to perform the emulation of the
>> instruction. However, emulation cannot be performed because there is no
>> instruction decode assist support when SEV-ES is enabled. Provide routines
>> to initiate an MMIO request to perform actual writes to flash.
>>
>> Cc: Eric Dong <eric.dong@intel.com>
>> Cc: Ray Ni <ray.ni@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Acked-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> UefiCpuPkg/UefiCpuPkg.dec | 3 +
>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +++
>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++++++++
>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293
>> +++++++++++++++++++
>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>> 6 files changed, 463 insertions(+)
>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>
>> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
>> index 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
>> d28cb5cccb52..997840452218 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/VmgExitLib/VmgExitLib.inf
>>
>> [LibraryClasses.common.SEC]
>>
>> PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.i
>> nf
>> @@ -136,6 +137,7 @@ [Components.IA32, Components.X64]
>>
>> UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib
>> Null.inf
>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
>> UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
>> + UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
>> UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
>> UefiCpuPkg/SecCore/SecCore.inf
>> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>> new file mode 100644
>> index 000000000000..6acfa779e75a
>> --- /dev/null
>> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>> @@ -0,0 +1,33 @@
>> +## @file
>> +# VMGEXIT Support Library.
>> +#
>> +# Copyright (c) 2019, Advanced Micro Devices, Inc. All rights
>> +reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # ##
>> +
>> +[Defines]
>> + INF_VERSION = 0x00010005
>> + BASE_NAME = VmgExitLib
>> + MODULE_UNI_FILE = VmgExitLib.uni
>> + FILE_GUID = 3cd7368f-ef9b-4a9b-9571-2ed93813677e
>> + 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 = IA32 X64
>> +#
>> +
>> +[Sources]
>> + VmgExitLib.c
>> +
>> +[Packages]
>> + MdePkg/MdePkg.dec
>> + UefiCpuPkg/UefiCpuPkg.dec
>> +
>> +[LibraryClasses]
>> + BaseLib
>> +
>> diff --git a/UefiCpuPkg/Include/Library/VmgExitLib.h
>> b/UefiCpuPkg/Include/Library/VmgExitLib.h
>> new file mode 100644
>> index 000000000000..3bf05bebd326
>> --- /dev/null
>> +++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
>> @@ -0,0 +1,117 @@
>> +/** @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.
>> +
>> + Copyright (c) 2019, 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 <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.
>> +
>> + @retval 0 VMGEXIT succeeded.
>> + @retval 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
>> + );
>> +
>> +#define VMGMMIO_READ False
>> +#define VMGMMIO_WRITE True
>> +
>> +/**
>> + Perform MMIO write of a buffer to a non-MMIO marked range.
>> +
>> + Performs an MMIO write without taking a #VC. This is useful for
>> + Flash devices, which are marked read-only.
>> +
>> + @param[in, out] Dest A pointer to the destination buffer
>> + @param[in] Src A pointer to the source data to be written
>> + @param[in] Bytes Number of bytes to write
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +VmgMmioWrite (
>> + IN OUT UINT8 *Dest,
>> + IN UINT8 *Src,
>> + IN UINTN Bytes
>> + );
>> +
>> +/**
>> + Issue the GHCB set AP Jump Table VMGEXIT.
>> +
>> + Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the
>> + AP Jump Table address with the hypervisor for retrieval at a later time.
>> +
>> + @param[in] Address Physical address of the AP Jump Table
>> +
>> + @retval 0 VMGEXIT succeeded.
>> + @retval Others VMGEXIT processing did not succeed. Exception
>> + number to be propagated.
>> +
>> +**/
>> +UINT64
>> +EFIAPI
>> +VmgExitSetAPJumpTable (
>> + IN EFI_PHYSICAL_ADDRESS Address
>> + );
>
> I think above two APIs should not been added to this library, they are not the basic actions for VmgExit.
> Remove these two APIs will make the library more stable.
>
> Also, I check all the code in this patch series, only one caller for each API, so I think we can directly
> move these codes to the caller. If later more and more callers need to use these two APIs, we can
> create another service library to convenient the callers.
Ok, let me check into that. It should be very doable, especially with the
change to a NULL library implementation that I want for the general case.
Thanks,
Tom
>
> I ignore all the coding style related issues in this patch because I assume you have passed ECC
> checks in your new patches.
>
> Thanks,
> Eric
>> +
>> +#endif
>> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>> new file mode 100644
>> index 000000000000..6137b1a0eb64
>> --- /dev/null
>> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>> @@ -0,0 +1,293 @@
>> +/** @file
>> + VMGEXIT Support Library.
>> +
>> + Copyright (c) 2019, 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 <Register/Amd/Ghcb.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
>> +
>> + @retval 0 VMGEXIT succeeded.
>> + @retval 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 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;
>> +}
>> +
>> +/**
>> + 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.
>> +
>> + @retval 0 VMGEXIT succeeded.
>> + @retval 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
>> + )
>> +{
>> + 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
>> + )
>> +{
>> +}
>> +
>> +/**
>> + Perform VMGEXIT MMIO read or write.
>> +
>> + Performs the requested MMIO read or write using the VMGEXIT
>> instruction.
>> +
>> + For an MMIO read, the data that has been read during the VMGEXIT is
>> + placed in the SharedBuffer area of the GHCB. This is then copied to
>> + the actual destination buffer within the guest.
>> +
>> + For an MMIO write, the data to be written is copied into the
>> + SharedBuffer area of the GHCB by the guest. This is then copied to
>> + the actual destination buffer by the hypervisor during the VMGEXIT.
>> +
>> + @param[in, out] MmioAddress A pointer to the MMIO buffer to be
>> read/written
>> + @param[in, out] Buffer A pointer to the buffer to hold the data thas
>> + has been read or hold the data to be written
>> + @param[in] Bytes Number of bytes to read or write
>> + @param[in] Write If set, the request is for an MMIO write, else
>> + it is an MMIO read.
>> +
>> + @retval 0 VMGEXIT succeeded.
>> + @retval Others VMGEXIT processing did not succeed. Exception
>> + number to be propagated.
>> +
>> +**/
>> +STATIC
>> +UINT64
>> +EFIAPI
>> +VmgMmio (
>> + IN OUT UINT8 *MmioAddress,
>> + IN OUT UINT8 *Buffer,
>> + IN UINTN Bytes,
>> + IN BOOLEAN Write
>> + )
>> +{
>> + UINT64 MmioOp, ExitInfo1, ExitInfo2, Status;
>> + GHCB *Ghcb;
>> + MSR_SEV_ES_GHCB_REGISTER Msr;
>> +
>> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb
>> =
>> + Msr.Ghcb;
>> +
>> + //
>> + // This function is about to set fields in the GHCB. Do not execute
>> + // anything that will cause a #VC before issuing the VmgExit(). Any
>> + #VC // will result in all GHCB settings being overwritten (this
>> + means, e.g., // do not add DEBUG() statements).
>> + //
>> + VmgInit (Ghcb);
>> +
>> + if (Write) {
>> + MmioOp = SvmExitMmioWrite;
>> + } else {
>> + MmioOp = SvmExitMmioRead;
>> + }
>> +
>> + ExitInfo1 = (UINT64) (UINTN) MmioAddress;
>> + ExitInfo2 = Bytes;
>> +
>> + if (Write) {
>> + CopyMem (Ghcb->SharedBuffer, Buffer, Bytes); }
>> +
>> + Ghcb->SaveArea.SwScratch = (UINT64) (UINTN) Ghcb->SharedBuffer;
>> + Status = VmgExit (Ghcb, MmioOp, ExitInfo1, ExitInfo2); if (Status !=
>> + 0) {
>> + return Status;
>> + }
>> +
>> + if (!Write) {
>> + CopyMem (Buffer, Ghcb->SharedBuffer, Bytes); }
>> +
>> + VmgDone (Ghcb);
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + Perform MMIO write of a buffer to a non-MMIO marked range.
>> +
>> + Performs an MMIO write without taking a #VC. This is useful for
>> + Flash devices, which are marked read-only.
>> +
>> + @param[in, out] Dest A pointer to the destination buffer
>> + @param[in] Src A pointer to the source data to be written
>> + @param[in] Bytes Number of bytes to write
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +VmgMmioWrite (
>> + IN OUT UINT8 *Dest,
>> + IN UINT8 *Src,
>> + IN UINTN Bytes
>> + )
>> +{
>> + VmgMmio (Dest, Src, Bytes, TRUE);
>> +}
>> +
>> +/**
>> + Issue the GHCB set AP Jump Table VMGEXIT.
>> +
>> + Performs a VMGEXIT using the GHCB AP Jump Table exit code to save the
>> + AP Jump Table address with the hypervisor for retrieval at a later time.
>> +
>> + @param[in] Address Physical address of the AP Jump Table
>> +
>> + @retval 0 VMGEXIT succeeded.
>> + @retval Others VMGEXIT processing did not succeed. Exception
>> + number to be propagated.
>> +
>> +**/
>> +UINT64
>> +EFIAPI
>> +VmgExitSetAPJumpTable (
>> + IN EFI_PHYSICAL_ADDRESS Address
>> + )
>> +{
>> + UINT64 ExitInfo1, ExitInfo2, Status;
>> + GHCB *Ghcb;
>> + MSR_SEV_ES_GHCB_REGISTER Msr;
>> +
>> + Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB); Ghcb
>> =
>> + Msr.Ghcb;
>> +
>> + VmgInit (Ghcb);
>> +
>> + ExitInfo1 = 0;
>> + ExitInfo2 = (UINT64) (UINTN) Address;
>> +
>> + Status = VmgExit (Ghcb, SvmExitApJumpTable, ExitInfo1, ExitInfo2);
>> +
>> + VmgDone (Ghcb);
>> +
>> + return Status;
>> +}
>> +
>> diff --git a/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>> b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>> new file mode 100644
>> index 000000000000..e8656aae4726
>> --- /dev/null
>> +++ b/UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>> @@ -0,0 +1,15 @@
>> +// /** @file
>> +// VMGEXIT support library instance.
>> +//
>> +// VMGEXIT support library instance.
>> +//
>> +// Copyright (c) 2019, Advanced Micro Devices, Inc. All rights
>> +reserved.<BR> // SPDX-License-Identifier: BSD-2-Clause-Patent // // **/
>> +
>> +
>> +#string STR_MODULE_ABSTRACT #language en-US "VMGEXIT
>> Support Library."
>> +
>> +#string STR_MODULE_DESCRIPTION #language en-US "VMGEXIT
>> Support Library."
>> +
>> --
>> 2.17.1
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 09/43] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (7 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 08/43] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 10/43] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
` (34 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.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 cbc5f0e583bc..65d87d4482eb 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -226,6 +226,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 6d69cc6cb56f..683f8c578741 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -230,6 +230,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 5ad4f461ce52..802caea63a8c 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -230,6 +230,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 47ee8db8b884..d94c18b901a4 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -208,6 +208,7 @@ [LibraryClasses]
[LibraryClasses.common]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.SEC]
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 10/43] UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (8 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 09/43] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:46 ` [edk2-devel] " Guo Dong
2020-04-22 17:41 ` [PATCH v7 11/43] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
` (33 subsequent siblings)
43 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
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..c2f7217c964e 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/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -244,6 +245,7 @@ [LibraryClasses.common.DXE_DRIVER]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
index 0736cd995476..b7cfeeff9b49 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/VmgExitLib/VmgExitLib.inf
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -245,6 +246,7 @@ [LibraryClasses.common.DXE_DRIVER]
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 10/43] UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
2020-04-22 17:41 ` [PATCH v7 10/43] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
@ 2020-04-22 17:46 ` Guo Dong
0 siblings, 0 replies; 81+ messages in thread
From: Guo Dong @ 2020-04-22 17:46 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Ni, Ray, Brijesh Singh
It looks good to me.
Reviewed-by: Guo Dong <guo.dong@intel.com>
Thanks,
Guo
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Lendacky, Thomas
> Sent: Wednesday, April 22, 2020 10:41 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
> <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney,
> Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>
> Subject: [edk2-devel] [PATCH v7 10/43] UefiPayloadPkg: Prepare
> UefiPayloadPkg to use the VmgExitLib library
>
> 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: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 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..c2f7217c964e 100644
> --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
> +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
> @@ -233,6 +233,7 @@ [LibraryClasses.common.DXE_CORE]
>
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> !endif
>
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>
> [LibraryClasses.common.DXE_DRIVER]
> PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> @@ -244,6 +245,7 @@ [LibraryClasses.common.DXE_DRIVER]
>
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> !endif
>
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
>
> [LibraryClasses.common.DXE_RUNTIME_DRIVER]
> diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> index 0736cd995476..b7cfeeff9b49 100644
> --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> @@ -234,6 +234,7 @@ [LibraryClasses.common.DXE_CORE]
>
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> !endif
>
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>
> [LibraryClasses.common.DXE_DRIVER]
> PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> @@ -245,6 +246,7 @@ [LibraryClasses.common.DXE_DRIVER]
>
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgen
> tLib.inf
> !endif
>
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC
> puExceptionHandlerLib.inf
> + VmgExitLib|UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
>
> [LibraryClasses.common.DXE_RUNTIME_DRIVER]
> --
> 2.17.1
>
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 11/43] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (9 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 10/43] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 12/43] UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events Lendacky, Thomas
` (32 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh, Maurice Ma,
Guo Dong, Benjamin You
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Add base support to handle #VC exceptions. This includes a stub routine
to invoke when a #VC exception occurs and special checks in the common
exception handlers to invoke the #VC exception handler routine.
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
.../DxeCpuExceptionHandlerLib.inf | 5 ++
.../PeiCpuExceptionHandlerLib.inf | 5 ++
.../SecPeiCpuExceptionHandlerLib.inf | 5 ++
.../SmmCpuExceptionHandlerLib.inf | 5 ++
.../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 ++++++++++++++
.../CpuExceptionCommon.h | 2 +
.../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 ++++++++++++
.../CpuExceptionCommon.c | 2 +-
.../Ia32/ArchAMDSevVcHandler.c | 38 +++++++++++
.../PeiDxeSmmCpuException.c | 16 +++++
.../SecPeiCpuException.c | 16 +++++
.../X64/ArchAMDSevVcHandler.c | 64 +++++++++++++++++++
12 files changed, 246 insertions(+), 1 deletion(-)
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
index e41383573043..4d79c4910b18 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -26,17 +26,21 @@ [Sources.Ia32]
Ia32/ExceptionTssEntryAsm.nasm
Ia32/ArchExceptionHandler.c
Ia32/ArchInterruptDefs.h
+ Ia32/ArchAMDSevVcHandler.c
[Sources.X64]
X64/ExceptionHandlerAsm.nasm
X64/ArchExceptionHandler.c
X64/ArchInterruptDefs.h
+ X64/ArchAMDSevVcHandler.c
[Sources.common]
CpuExceptionCommon.h
CpuExceptionCommon.c
PeiDxeSmmCpuException.c
DxeException.c
+ AMDSevVcHandler.c
+ AMDSevVcCommon.h
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
@@ -57,3 +61,4 @@ [LibraryClasses]
PeCoffGetEntryPointLib
MemoryAllocationLib
DebugLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
index f31423ac0f91..e8445e47eaa3 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
@@ -26,17 +26,21 @@ [Sources.Ia32]
Ia32/ExceptionTssEntryAsm.nasm
Ia32/ArchExceptionHandler.c
Ia32/ArchInterruptDefs.h
+ Ia32/ArchAMDSevVcHandler.c
[Sources.X64]
X64/ExceptionHandlerAsm.nasm
X64/ArchExceptionHandler.c
X64/ArchInterruptDefs.h
+ X64/ArchAMDSevVcHandler.c
[Sources.common]
CpuExceptionCommon.h
CpuExceptionCommon.c
PeiCpuException.c
PeiDxeSmmCpuException.c
+ AMDSevVcHandler.c
+ AMDSevVcCommon.h
[Packages]
MdePkg/MdePkg.dec
@@ -52,6 +56,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..a15bf71b4052 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -26,16 +26,20 @@ [Sources.Ia32]
Ia32/ExceptionTssEntryAsm.nasm
Ia32/ArchExceptionHandler.c
Ia32/ArchInterruptDefs.h
+ Ia32/ArchAMDSevVcHandler.c
[Sources.X64]
X64/ExceptionHandlerAsm.nasm
X64/ArchExceptionHandler.c
X64/ArchInterruptDefs.h
+ X64/ArchAMDSevVcHandler.c
[Sources.common]
CpuExceptionCommon.h
CpuExceptionCommon.c
SecPeiCpuException.c
+ AMDSevVcHandler.c
+ AMDSevVcCommon.h
[Packages]
MdePkg/MdePkg.dec
@@ -48,3 +52,4 @@ [LibraryClasses]
PrintLib
LocalApicLib
PeCoffGetEntryPointLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
index 66c7f59e3c91..190d7dfcd42a 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
@@ -26,17 +26,21 @@ [Sources.Ia32]
Ia32/ExceptionTssEntryAsm.nasm
Ia32/ArchExceptionHandler.c
Ia32/ArchInterruptDefs.h
+ Ia32/ArchAMDSevVcHandler.c
[Sources.X64]
X64/ExceptionHandlerAsm.nasm
X64/ArchExceptionHandler.c
X64/ArchInterruptDefs.h
+ X64/ArchAMDSevVcHandler.c
[Sources.common]
CpuExceptionCommon.h
CpuExceptionCommon.c
PeiDxeSmmCpuException.c
SmmException.c
+ AMDSevVcHandler.c
+ AMDSevVcCommon.h
[Packages]
MdePkg/MdePkg.dec
@@ -51,4 +55,5 @@ [LibraryClasses]
LocalApicLib
PeCoffGetEntryPointLib
DebugLib
+ VmgExitLib
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
new file mode 100644
index 000000000000..e4b8f3147add
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
@@ -0,0 +1,49 @@
+/** @file
+ Common header file for SEV-ES #VC Exception Handler Support.
+
+ Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _AMD_SEV_VC_COMMON_H_
+#define _AMD_SEV_VC_COMMON_H_
+
+#include <Protocol/DebugSupport.h>
+#include <Register/Amd/Ghcb.h>
+
+/**
+ #VC exception handling routine.
+
+ Called by the UefiCpuPkg exception handling support when a #VC is encountered.
+
+ @param[in, out] Context Pointer to EFI_SYSTEM_CONTEXT.
+
+ @retval 0 Exception handled
+ @retval Others New exception value to propagate
+
+**/
+UINTN
+DoVcException (
+ IN OUT EFI_SYSTEM_CONTEXT Context
+ );
+
+/**
+ Common #VC exception handling routine.
+
+ Used to bridge different phases of UEFI execution.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block
+ @param[in, out] Context Pointer to EFI_SYSTEM_CONTEXT.
+
+ @retval 0 Exception handled
+ @retval Others New exception value to propagate
+
+**/
+UINTN
+DoVcCommon (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT Context
+ );
+
+#endif
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 805dd9cbb4ff..0f274e7ea328 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -24,6 +24,8 @@
#define CPU_INTERRUPT_NUM 256
#define HOOKAFTER_STUB_SIZE 16
+#define VC_EXCEPTION 29
+
//
// Exception Error Code of Page-Fault Exception
//
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
new file mode 100644
index 000000000000..fc91cf119f3e
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
@@ -0,0 +1,40 @@
+/** @file
+ SEV-ES #VC Exception Handler functon.
+
+ Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Register/Amd/Msr.h>
+#include "CpuExceptionCommon.h"
+#include "AMDSevVcCommon.h"
+
+/**
+ #VC exception handling routine.
+
+ Called by the UefiCpuPkg exception handling support when a #VC is encountered.
+
+ @param[in, out] Context Pointer to EFI_SYSTEM_CONTEXT.
+
+ @retval 0 Exception handled
+ @retval Others New exception value to propagate
+
+**/
+UINTN
+DoVcException (
+ IN OUT EFI_SYSTEM_CONTEXT Context
+ )
+{
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ ASSERT (Msr.GhcbInfo.Function == 0);
+ ASSERT (Msr.Ghcb != 0);
+
+ Ghcb = Msr.Ghcb;
+
+ return DoVcCommon (Ghcb, Context);
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 8adbd43fefb4..39e4dd9e9417 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
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
new file mode 100644
index 000000000000..d988fe620d53
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
@@ -0,0 +1,38 @@
+/** @file
+ IA32 SEV-ES #VC Exception Handler functons.
+
+ Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include "AMDSevVcCommon.h"
+
+/**
+ Common #VC exception handling routine.
+
+ Used to bridge different phases of UEFI execution.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block
+ @param[in, out] Context Pointer to EFI_SYSTEM_CONTEXT.
+
+ @retval 0 Exception handled
+ @retval Others New exception value to propagate
+
+**/
+UINTN
+DoVcCommon (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT Context
+ )
+{
+ EFI_SYSTEM_CONTEXT_IA32 *Regs;
+
+ Regs = Context.SystemContextIa32;
+
+ Regs->ExceptionData = 0;
+
+ return GP_EXCEPTION;
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
index 6a2670d55918..d565db547808 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
@@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "CpuExceptionCommon.h"
+#include "AMDSevVcCommon.h"
#include <Library/DebugLib.h>
/**
@@ -86,6 +87,21 @@ CommonExceptionHandlerWorker (
break;
}
+ if (ExceptionType == VC_EXCEPTION) {
+ UINTN Status;
+ //
+ // #VC must be handled for an SEV-ES guest
+ //
+ Status = DoVcException (SystemContext);
+ if (Status) {
+ // Exception not handled - Status contains the desired exception now
+ ExceptionType = Status;
+ } else {
+ // Exception handled
+ return;
+ }
+ }
+
if (ExternalInterruptHandler != NULL &&
ExternalInterruptHandler[ExceptionType] != NULL) {
(ExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext);
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index 20148db74cf8..0716680d2f50 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <PiPei.h>
#include "CpuExceptionCommon.h"
+#include "AMDSevVcCommon.h"
CONST UINTN mDoFarReturnFlag = 0;
@@ -24,6 +25,21 @@ CommonExceptionHandler (
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
+ if (ExceptionType == VC_EXCEPTION) {
+ UINTN Status;
+ //
+ // #VC must be handled for an SEV-ES guest
+ //
+ Status = DoVcException (SystemContext);
+ if (Status) {
+ // Exception not handled - Status contains the desired exception now
+ ExceptionType = Status;
+ } else {
+ // Exception handled
+ return;
+ }
+ }
+
//
// Initialize the serial port before dumping.
//
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
new file mode 100644
index 000000000000..c0a0eee319bf
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -0,0 +1,64 @@
+/** @file
+ X64 SEV-ES #VC Exception Handler functons.
+
+ Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/VmgExitLib.h>
+#include "AMDSevVcCommon.h"
+
+/**
+ Common #VC exception handling routine.
+
+ Used to bridge different phases of UEFI execution.
+
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block
+ @param[in, out] Context Pointer to EFI_SYSTEM_CONTEXT.
+
+ @retval 0 Exception handled
+ @retval Others New exception value to propagate
+
+**/
+UINTN
+DoVcCommon (
+ IN OUT GHCB *Ghcb,
+ IN OUT EFI_SYSTEM_CONTEXT Context
+ )
+{
+ EFI_SYSTEM_CONTEXT_X64 *Regs;
+ UINT64 Status;
+ UINTN ExitCode, VcRet;
+
+ Regs = Context.SystemContextX64;
+
+ VmgInit (Ghcb);
+
+ ExitCode = Regs->ExceptionData;
+ switch (ExitCode) {
+ default:
+ Status = VmgExit (Ghcb, SvmExitUnsupported, ExitCode, 0);
+ if (Status == 0) {
+ Regs->ExceptionData = 0;
+ VcRet = GP_EXCEPTION;
+ } else {
+ GHCB_EVENT_INJECTION Event;
+
+ Event.Uint64 = Status;
+ if (Event.Elements.ErrorCodeValid) {
+ Regs->ExceptionData = Event.Elements.ErrorCode;
+ } else {
+ Regs->ExceptionData = 0;
+ }
+
+ VcRet = Event.Elements.Vector;
+ }
+ }
+
+ VmgDone (Ghcb);
+
+ return VcRet;
+}
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 12/43] UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (10 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 11/43] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 13/43] UefiCpuPkg/CpuExceptionHandler: Support string IO " Lendacky, Thomas
` (31 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 599 +++++++++++++++++-
1 file changed, 585 insertions(+), 14 deletions(-)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index c0a0eee319bf..588f2af572e1 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -11,6 +11,567 @@
#include <Library/VmgExitLib.h>
#include "AMDSevVcCommon.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;
+
+//
+// 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;
+} SEV_ES_INSTRUCTION_REX_PREFIX;
+
+//
+// Instruction ModRM definition
+//
+typedef union {
+ struct {
+ UINT8 Rm:3;
+ UINT8 Reg:3;
+ UINT8 Mod:2;
+ } Bits;
+
+ UINT8 Uint8;
+} SEV_ES_INSTRUCTION_MODRM;
+
+typedef struct {
+ UINT8 Rm;
+ UINT8 Reg;
+ UINT8 Mod;
+} SEV_ES_INSTRUCTION_MODRM_EXT;
+
+//
+// Instruction SIB definition
+//
+typedef union {
+ struct {
+ UINT8 Base:3;
+ UINT8 Index:3;
+ UINT8 Scale:2;
+ } Bits;
+
+ UINT8 Uint8;
+} SEV_ES_INSTRUCTION_SIB;
+
+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;
+
+ SEV_ES_INSTRUCTION_REX_PREFIX RexPrefix;
+
+ BOOLEAN ModRmPresent;
+ SEV_ES_INSTRUCTION_MODRM ModRm;
+
+ BOOLEAN SibPresent;
+ SEV_ES_INSTRUCTION_SIB Sib;
+
+ UINT8 PrefixSize;
+ UINT8 OpCodeSize;
+ UINT8 DisplacementSize;
+ UINT8 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));
+}
+
+/**
+ 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;
+
+ /*TODO: Determine current mode - 64-bit for now */
+ 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++) {
+ switch (*Byte) {
+ case 0x26:
+ case 0x2E:
+ case 0x36:
+ case 0x3E:
+ if (Mode != LongMode64Bit) {
+ InstructionData->SegmentSpecified = TRUE;
+ InstructionData->Segment = (*Byte >> 3) & 3;
+ }
+ break;
+
+ case 0x40 ... 0x4F:
+ InstructionData->RexPrefix.Uint8 = *Byte;
+ if (*Byte & 0x08)
+ InstructionData->DataSize = Size64Bits;
+ break;
+
+ case 0x64:
+ InstructionData->SegmentSpecified = TRUE;
+ InstructionData->Segment = *Byte & 7;
+ break;
+
+ case 0x66:
+ if (!InstructionData->RexPrefix.Uint8) {
+ InstructionData->DataSize =
+ (Mode == LongMode64Bit) ? Size16Bits :
+ (Mode == LongModeCompat32Bit) ? Size16Bits :
+ (Mode == LongModeCompat16Bit) ? Size32Bits : 0;
+ }
+ break;
+
+ case 0x67:
+ InstructionData->AddrSize =
+ (Mode == LongMode64Bit) ? Size32Bits :
+ (Mode == LongModeCompat32Bit) ? Size16Bits :
+ (Mode == LongModeCompat16Bit) ? Size32Bits : 0;
+ break;
+
+ case 0xF0:
+ break;
+
+ case 0xF2:
+ InstructionData->RepMode = RepZ;
+ break;
+
+ case 0xF3:
+ InstructionData->RepMode = RepNZ;
+ break;
+
+ default:
+ InstructionData->OpCodes = Byte;
+ InstructionData->OpCodeSize = (*Byte == 0x0F) ? 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
+
+ @retval 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
+
+ @retval 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, SvmExitUnsupported, 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;
+}
+
+#define IOIO_TYPE_STR (1 << 2)
+#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 (1 << 3)
+
+#define IOIO_ADDR_64 (1 << 9)
+#define IOIO_ADDR_32 (1 << 8)
+#define IOIO_ADDR_16 (1 << 7)
+
+#define IOIO_DATA_32 (1 << 6)
+#define IOIO_DATA_16 (1 << 5)
+#define IOIO_DATA_8 (1 << 4)
+#define IOIO_DATA_BYTES(x) (((x) & 0x70) >> 4)
+
+#define IOIO_SEG_ES (0 << 10)
+#define IOIO_SEG_DS (3 << 10)
+
+/**
+ 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
+
+ @retval Others 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)) {
+ case 0xE4:
+ case 0xE6:
+ case 0xEC:
+ case 0xEE:
+ // Single-byte opcodes
+ ExitInfo |= IOIO_DATA_8;
+ break;
+
+ default:
+ // Length determined by instruction parsing
+ 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) {
+ 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
+
+ @retval 0 Event handled successfully
+ @retval 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) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ Ghcb->SaveArea.Rax = 0;
+ } else {
+ CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+ GhcbSetRegValid (Ghcb, GhcbRax);
+
+ Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
+ if (Status) {
+ return Status;
+ }
+
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+
+ return 0;
+}
+
/**
Common #VC exception handling routine.
@@ -30,6 +591,8 @@ DoVcCommon (
)
{
EFI_SYSTEM_CONTEXT_X64 *Regs;
+ SEV_ES_INSTRUCTION_DATA InstructionData;
+ NAE_EXIT NaeExit;
UINT64 Status;
UINTN ExitCode, VcRet;
@@ -39,23 +602,31 @@ DoVcCommon (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SvmExitIoioProt:
+ NaeExit = IoioExit;
+ break;
+
default:
- Status = VmgExit (Ghcb, SvmExitUnsupported, ExitCode, 0);
- if (Status == 0) {
- Regs->ExceptionData = 0;
- VcRet = GP_EXCEPTION;
+ NaeExit = UnsupportedExit;
+ }
+
+ InitInstructionData (&InstructionData, Ghcb, Regs);
+
+ Status = NaeExit (Ghcb, Regs, &InstructionData);
+ if (Status == 0) {
+ Regs->Rip += InstructionLength (&InstructionData);
+ VcRet = 0;
+ } else {
+ GHCB_EVENT_INJECTION Event;
+
+ Event.Uint64 = Status;
+ if (Event.Elements.ErrorCodeValid) {
+ Regs->ExceptionData = Event.Elements.ErrorCode;
} else {
- GHCB_EVENT_INJECTION Event;
-
- Event.Uint64 = Status;
- if (Event.Elements.ErrorCodeValid) {
- Regs->ExceptionData = Event.Elements.ErrorCode;
- } else {
- Regs->ExceptionData = 0;
- }
-
- VcRet = Event.Elements.Vector;
+ Regs->ExceptionData = 0;
}
+
+ VcRet = Event.Elements.Vector;
}
VmgDone (Ghcb);
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 13/43] UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (11 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 12/43] UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 14/43] UefiCpuPkg/CpuExceptionHandler: Add support for CPUID " Lendacky, Thomas
` (30 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 86 ++++++++++++++++---
1 file changed, 72 insertions(+), 14 deletions(-)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 588f2af572e1..5fade675ad84 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -446,6 +446,22 @@ 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
case 0xE4:
case 0xE5:
@@ -483,6 +499,8 @@ IoioExitInfo (
}
switch (*(InstructionData->OpCodes)) {
+ case 0x6C:
+ case 0x6E:
case 0xE4:
case 0xE6:
case 0xEC:
@@ -543,30 +561,70 @@ IoioExit (
IN SEV_ES_INSTRUCTION_DATA *InstructionData
)
{
- UINT64 ExitInfo1, Status;
+ UINT64 ExitInfo1, ExitInfo2, Status;
+ BOOLEAN String;
ExitInfo1 = IoioExitInfo (Regs, InstructionData);
if (!ExitInfo1) {
return UnsupportedExit (Ghcb, Regs, InstructionData);
}
- if (ExitInfo1 & IOIO_TYPE_IN) {
- Ghcb->SaveArea.Rax = 0;
+ String = (ExitInfo1 & IOIO_TYPE_STR) ? TRUE : FALSE;
+ if (String) {
+ UINTN IoBytes, VmgExitBytes;
+ UINTN GhcbCount, OpCount;
+
+ Status = 0;
+
+ IoBytes = (ExitInfo1 >> 4) & 0x7;
+ GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes;
+
+ OpCount = (ExitInfo1 & IOIO_REP) ? Regs->Rcx : 1;
+ while (OpCount) {
+ ExitInfo2 = MIN (OpCount, GhcbCount);
+ VmgExitBytes = ExitInfo2 * IoBytes;
+
+ if (!(ExitInfo1 & IOIO_TYPE_IN)) {
+ CopyMem (Ghcb->SharedBuffer, (VOID *) Regs->Rsi, VmgExitBytes);
+ Regs->Rsi += VmgExitBytes;
+ }
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, ExitInfo2);
+ if (Status) {
+ return Status;
+ }
+
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ CopyMem ((VOID *) Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes);
+ Regs->Rdi += VmgExitBytes;
+ }
+
+ if (ExitInfo1 & IOIO_REP) {
+ Regs->Rcx -= ExitInfo2;
+ }
+
+ OpCount -= ExitInfo2;
+ }
} else {
- CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
- }
- GhcbSetRegValid (Ghcb, GhcbRax);
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ Ghcb->SaveArea.Rax = 0;
+ } else {
+ CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+ GhcbSetRegValid (Ghcb, GhcbRax);
- Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
- if (Status) {
- return Status;
- }
+ Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
+ if (Status) {
+ return Status;
+ }
- if (ExitInfo1 & IOIO_TYPE_IN) {
- if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
- return UnsupportedExit (Ghcb, Regs, InstructionData);
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 14/43] UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (12 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 13/43] UefiCpuPkg/CpuExceptionHandler: Support string IO " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 15/43] UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT " Lendacky, Thomas
` (29 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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 requires XCR0 to be supplied in
the GHCB, so add support to issue the XGETBV instruction.
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>
---
.../X64/ArchAMDSevVcHandler.c | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 5fade675ad84..4324de152b82 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -11,6 +11,8 @@
#include <Library/VmgExitLib.h>
#include "AMDSevVcCommon.h"
+#define CR4_OSXSAVE (1 << 18)
+
//
// Instruction execution mode definition
//
@@ -630,6 +632,58 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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 == 0x0000000d) {
+ Ghcb->SaveArea.XCr0 = (AsmReadCr4 () & CR4_OSXSAVE) ? AsmXGetBv (0) : 1;
+ GhcbSetRegValid (Ghcb, GhcbXCr0);
+ }
+
+ Status = VmgExit (Ghcb, SvmExitCpuid, 0, 0);
+ if (Status) {
+ 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;
+}
+
/**
Common #VC exception handling routine.
@@ -660,6 +714,10 @@ DoVcCommon (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SvmExitCpuid:
+ NaeExit = CpuidExit;
+ break;
+
case SvmExitIoioProt:
NaeExit = IoioExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 15/43] UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (13 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 14/43] UefiCpuPkg/CpuExceptionHandler: Add support for CPUID " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 16/43] UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO) Lendacky, Thomas
` (28 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 63 +++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 4324de152b82..8eae3633a31b 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -404,6 +404,65 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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);
+ /* Fallthrough */
+ case 0x32: // RDMSR
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+ break;
+ default:
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
+ Status = VmgExit (Ghcb, SvmExitMsr, ExitInfo1, 0);
+ if (Status) {
+ return Status;
+ }
+
+ if (!ExitInfo1) {
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+ Regs->Rdx = Ghcb->SaveArea.Rdx;
+ }
+
+ return 0;
+}
+
#define IOIO_TYPE_STR (1 << 2)
#define IOIO_TYPE_IN 1
#define IOIO_TYPE_INS (IOIO_TYPE_IN | IOIO_TYPE_STR)
@@ -722,6 +781,10 @@ DoVcCommon (
NaeExit = IoioExit;
break;
+ case SvmExitMsr:
+ NaeExit = MsrExit;
+ break;
+
default:
NaeExit = UnsupportedExit;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 16/43] UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (14 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 15/43] UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 17/43] UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events Lendacky, Thomas
` (27 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 436 ++++++++++++++++++
1 file changed, 436 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 8eae3633a31b..d3aba54b90fe 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -223,6 +223,263 @@ 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
+
+ @retval Pointer to the contents of the requested register
+
+**/
+STATIC
+INT64 *
+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 (INT64 *) 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 == 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
+
+ @retval The memory operand effective address
+
+**/
+STATIC
+UINTN
+GetEffectiveMemoryAddress (
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData
+ )
+{
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ INTN 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);
+ return (UINTN) ((INTN) Regs->Rip + RipRelative);
+ }
+
+ switch (Ext->ModRm.Mod) {
+ case 1:
+ UpdateForDisplacement (InstructionData, 1);
+ EffectiveAddress += (INT8) (*(INT8 *) (InstructionData->Displacement));
+ break;
+ case 2:
+ switch (InstructionData->AddrSize) {
+ case Size16Bits:
+ UpdateForDisplacement (InstructionData, 2);
+ EffectiveAddress += (INT16) (*(INT16 *) (InstructionData->Displacement));
+ break;
+ default:
+ UpdateForDisplacement (InstructionData, 4);
+ EffectiveAddress += (INT32) (*(INT32 *) (InstructionData->Displacement));
+ break;
+ }
+ break;
+ }
+
+ if (InstructionData->SibPresent) {
+ if (Ext->Sib.Index != 4) {
+ EffectiveAddress += (*GetRegisterPointer (Regs, Ext->Sib.Index) << Ext->Sib.Scale);
+ }
+
+ if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) {
+ EffectiveAddress += *GetRegisterPointer (Regs, Ext->Sib.Base);
+ } else {
+ UpdateForDisplacement (InstructionData, 4);
+ EffectiveAddress += (INT32) (*(INT32 *) (InstructionData->Displacement));
+ }
+ } else {
+ EffectiveAddress += *GetRegisterPointer (Regs, Ext->ModRm.Rm);
+ }
+
+ return (UINTN) 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_REX_PREFIX *RexPrefix;
+ SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;
+ SEV_ES_INSTRUCTION_MODRM *ModRm;
+ SEV_ES_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.
@@ -404,6 +661,181 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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, SignByte;
+ INTN *Register;
+ UINT8 OpCode;
+
+ Bytes = 0;
+
+ OpCode = *(InstructionData->OpCodes);
+ if (OpCode == 0x0F) {
+ OpCode = *(InstructionData->OpCodes + 1);
+ }
+
+ switch (OpCode) {
+ /* MMIO write */
+ case 0x88:
+ Bytes = 1;
+ case 0x89:
+ DecodeModRm (Regs, InstructionData);
+ Bytes = (Bytes) ? 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, SvmExitMmioWrite, ExitInfo1, ExitInfo2);
+ if (Status) {
+ return Status;
+ }
+ break;
+
+ case 0xC6:
+ Bytes = 1;
+ case 0xC7:
+ DecodeModRm (Regs, InstructionData);
+ Bytes = (Bytes) ? 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, SvmExitMmioWrite, ExitInfo1, ExitInfo2);
+ if (Status) {
+ return Status;
+ }
+ break;
+
+ /* MMIO read */
+ case 0x8A:
+ Bytes = 1;
+ case 0x8B:
+ DecodeModRm (Regs, InstructionData);
+ Bytes = (Bytes) ? 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, SvmExitMmioRead, ExitInfo1, ExitInfo2);
+ if (Status) {
+ 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 */
+ case 0xB6:
+ Bytes = 1;
+ case 0xB7:
+ Bytes = (Bytes) ? Bytes : 2;
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SvmExitMmioRead, ExitInfo1, ExitInfo2);
+ if (Status) {
+ 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 */
+ case 0xBE:
+ Bytes = 1;
+ case 0xBF:
+ Bytes = (Bytes) ? Bytes : 2;
+
+ ExitInfo1 = InstructionData->Ext.RmData;
+ ExitInfo2 = Bytes;
+
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+ Status = VmgExit (Ghcb, SvmExitMmioRead, ExitInfo1, ExitInfo2);
+ if (Status) {
+ return Status;
+ }
+
+ if (Bytes == 1) {
+ UINT8 *Data = (UINT8 *) Ghcb->SharedBuffer;
+
+ SignByte = (*Data & 0x80) ? 0xFF : 0x00;
+ } else {
+ UINT16 *Data = (UINT16 *) Ghcb->SharedBuffer;
+
+ SignByte = (*Data & 0x8000) ? 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.
@@ -785,6 +1217,10 @@ DoVcCommon (
NaeExit = MsrExit;
break;
+ case SvmExitNpf:
+ NaeExit = MmioExit;
+ break;
+
default:
NaeExit = UnsupportedExit;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 17/43] UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (15 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 16/43] UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO) Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 18/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC " Lendacky, Thomas
` (26 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index d3aba54b90fe..29e88147aab3 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -836,6 +836,38 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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
+ )
+{
+ UINT64 Status;
+
+ Status = VmgExit (Ghcb, SvmExitWbinvd, 0, 0);
+ if (Status) {
+ return Status;
+ }
+
+ return 0;
+}
+
/**
Handle an MSR event.
@@ -1217,6 +1249,10 @@ DoVcCommon (
NaeExit = MsrExit;
break;
+ case SvmExitWbinvd:
+ NaeExit = WbinvdExit;
+ break;
+
case SvmExitNpf:
NaeExit = MmioExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 18/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (16 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 17/43] UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 19/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC " Lendacky, Thomas
` (25 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 29e88147aab3..edd868c584a6 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -1207,6 +1207,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
+
+ @retval 0 Event handled successfully
+ @retval 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, SvmExitRdtsc, 0, 0);
+ if (Status) {
+ 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;
+}
+
/**
Common #VC exception handling routine.
@@ -1237,6 +1276,10 @@ DoVcCommon (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SvmExitRdtsc:
+ NaeExit = RdtscExit;
+ break;
+
case SvmExitCpuid:
NaeExit = CpuidExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 19/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (17 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 18/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 20/43] UefiCpuPkg/CpuExceptionHandler: Add support for INVD " Lendacky, Thomas
` (24 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index edd868c584a6..64db5eef128f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -1207,6 +1207,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
+
+ @retval 0 Event handled successfully
+ @retval 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, SvmExitRdpmc, 0, 0);
+ if (Status) {
+ 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.
@@ -1280,6 +1322,10 @@ DoVcCommon (
NaeExit = RdtscExit;
break;
+ case SvmExitRdpmc:
+ NaeExit = RdpmcExit;
+ break;
+
case SvmExitCpuid:
NaeExit = CpuidExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 20/43] UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (18 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 19/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 21/43] UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL " Lendacky, Thomas
` (23 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 64db5eef128f..d42d84608854 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -1155,6 +1155,38 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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
+ )
+{
+ UINT64 Status;
+
+ Status = VmgExit (Ghcb, SvmExitInvd, 0, 0);
+ if (Status) {
+ return Status;
+ }
+
+ return 0;
+}
+
/**
Handle a CPUID event.
@@ -1330,6 +1362,10 @@ DoVcCommon (
NaeExit = CpuidExit;
break;
+ case SvmExitInvd:
+ NaeExit = InvdExit;
+ break;
+
case SvmExitIoioProt:
NaeExit = IoioExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 21/43] UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (19 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 20/43] UefiCpuPkg/CpuExceptionHandler: Add support for INVD " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 22/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP " Lendacky, Thomas
` (22 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index d42d84608854..4b425696b345 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -868,6 +868,50 @@ WbinvdExit (
return 0;
}
+/**
+ Handle a VMMCALL event.
+
+ Use the VMGEXIT instruction to handle either 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
+
+ @retval 0 Event handled successfully
+ @retval 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, SvmExitVmmCall, 0, 0);
+ if (Status) {
+ return Status;
+ }
+
+ if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+ Regs->Rax = Ghcb->SaveArea.Rax;
+
+ return 0;
+}
+
/**
Handle an MSR event.
@@ -1374,6 +1418,10 @@ DoVcCommon (
NaeExit = MsrExit;
break;
+ case SvmExitVmmCall:
+ NaeExit = VmmCallExit;
+ break;
+
case SvmExitWbinvd:
NaeExit = WbinvdExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 22/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (20 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 21/43] UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 23/43] UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX " Lendacky, Thomas
` (21 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 4b425696b345..75272c47ba35 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -868,6 +868,49 @@ WbinvdExit (
return 0;
}
+/**
+ Handle a RDTSCP event.
+
+ Use the VMGEXIT instruction to handle either 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
+
+ @retval 0 Event handled successfully
+ @retval 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, SvmExitRdtscp, 0, 0);
+ if (Status) {
+ 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.
@@ -1422,6 +1465,10 @@ DoVcCommon (
NaeExit = VmmCallExit;
break;
+ case SvmExitRdtscp:
+ NaeExit = RdtscpExit;
+ break;
+
case SvmExitWbinvd:
NaeExit = WbinvdExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 23/43] UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (21 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 22/43] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 24/43] UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX " Lendacky, Thomas
` (20 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 45 +++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 75272c47ba35..890451ff97a2 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -836,6 +836,47 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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
+ )
+{
+ UINT64 Status;
+
+ 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);
+
+ Status = VmgExit (Ghcb, SvmExitMonitor, 0, 0);
+ if (Status) {
+ return Status;
+ }
+
+ return 0;
+}
+
/**
Handle a WBINVD event.
@@ -1473,6 +1514,10 @@ DoVcCommon (
NaeExit = WbinvdExit;
break;
+ case SvmExitMonitor:
+ NaeExit = MonitorExit;
+ break;
+
case SvmExitNpf:
NaeExit = MmioExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 24/43] UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (22 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 23/43] UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 25/43] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write " Lendacky, Thomas
` (19 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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: 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>
---
.../X64/ArchAMDSevVcHandler.c | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 890451ff97a2..023e7dc31202 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -836,6 +836,45 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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
+ )
+{
+ UINT64 Status;
+
+ DecodeModRm (Regs, InstructionData);
+
+ Ghcb->SaveArea.Rax = Regs->Rax;
+ GhcbSetRegValid (Ghcb, GhcbRax);
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
+ GhcbSetRegValid (Ghcb, GhcbRcx);
+
+ Status = VmgExit (Ghcb, SvmExitMwait, 0, 0);
+ if (Status) {
+ return Status;
+ }
+
+ return 0;
+}
+
/**
Handle a MONITOR event.
@@ -1518,6 +1557,10 @@ DoVcCommon (
NaeExit = MonitorExit;
break;
+ case SvmExitMwait:
+ NaeExit = MwaitExit;
+ break;
+
case SvmExitNpf:
NaeExit = MmioExit;
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 25/43] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE events
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (23 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 24/43] UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 26/43] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
` (18 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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.
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 saved context.
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>
---
.../X64/ArchAMDSevVcHandler.c | 105 ++++++++++++++++++
.../X64/ExceptionHandlerAsm.nasm | 17 +++
2 files changed, 122 insertions(+)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 023e7dc31202..af5567d85593 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -13,6 +13,16 @@
#define CR4_OSXSAVE (1 << 18)
+#define DR7_RESET_VALUE 0x400
+
+//
+// Per-CPU data mapping structure
+//
+typedef struct {
+ BOOLEAN Dr7Cached;
+ UINT64 Dr7;
+} SEV_ES_PER_CPU_DATA;
+
//
// Instruction execution mode definition
//
@@ -1487,6 +1497,93 @@ 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
+
+ @retval 0 Event handled successfully
+ @retval 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;
+ INTN *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, SvmExitDr7Write, 0, 0);
+ if (Status) {
+ 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
+
+ @retval 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;
+ INTN *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);
+ *Register = (SevEsData->Dr7Cached) ? SevEsData->Dr7 : DR7_RESET_VALUE;
+
+ return 0;
+}
+
/**
Common #VC exception handling routine.
@@ -1517,6 +1614,14 @@ DoVcCommon (
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
+ case SvmExitDr7Read:
+ NaeExit = Dr7ReadExit;
+ break;
+
+ case SvmExitDr7Write:
+ NaeExit = Dr7WriteExit;
+ break;
+
case SvmExitRdtsc:
NaeExit = RdtscExit;
break;
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
index 19198f273137..26cae56cc5cf 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)
@@ -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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 26/43] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (24 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 25/43] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write " Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 27/43] OvmfPkg: Add support to perform SEV-ES initialization Lendacky, Thomas
` (17 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +++
.../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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 27/43] OvmfPkg: Add support to perform SEV-ES initialization
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (25 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 26/43] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 28/43] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
` (16 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
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 65d87d4482eb..95423942101f 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -586,6 +586,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 683f8c578741..37bbf2073494 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -597,6 +597,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 802caea63a8c..5248e6fd92a8 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -596,6 +596,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 19f2424981bc..c90b5f7ae200 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -101,6 +101,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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 28/43] OvmfPkg: Create a GHCB page for use during Sec phase
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (26 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 27/43] OvmfPkg: Add support to perform SEV-ES initialization Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 29/43] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported Lendacky, Thomas
` (15 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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.
Two new fixed PCDs are needed to support the SEC GHCB page:
- PcdOvmfSecGhcbBase UINT64 value that is the base address of the
GHCB used during the SEC phase.
- PcdOvmfSecGhcbSize UINT64 value that is the size, in bytes, of the
GHCB area used during the SEC phase.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.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 | 70 +++++++++++++++++++++++
OvmfPkg/ResetVector/ResetVector.nasmb | 17 ++++++
5 files changed, 107 insertions(+)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 28030391cff2..4b450b878e44 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -270,6 +270,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|0x39
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3a
+
+ ## The base address of the SEC GHCB page used by SEV-ES.
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x3b
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x3c
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 25af9fbed48a..36414c1f8b49 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..c3587a1b7814 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,40 @@ 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
+
+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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 29/43] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (27 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 28/43] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 30/43] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
` (14 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh, 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@linaro.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
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 c90b5f7ae200..c5b92ab4afd8 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -73,6 +73,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 47dc9c543719..200021098161 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>
@@ -860,6 +861,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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 30/43] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (28 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 29/43] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 31/43] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
` (13 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
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 95423942101f..dfe8f0210b92 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -587,6 +587,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 37bbf2073494..b0ee4413581a 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -598,6 +598,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 5248e6fd92a8..39eceb422f42 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -597,6 +597,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 c5b92ab4afd8..fcab78e3d20c 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -100,6 +100,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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 31/43] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (29 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 30/43] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 32/43] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
` (12 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 32/43] UefiCpuPkg: Create an SEV-ES workarea PCD
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (30 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 31/43] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
` (11 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (31 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 32/43] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-30 18:58 ` [edk2-devel] " Laszlo Ersek
2020-04-22 17:41 ` [PATCH v7 34/43] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
` (10 subsequent siblings)
43 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/OvmfPkgX64.fdf | 3 +++
1 file changed, 3 insertions(+)
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 36414c1f8b49..a0bea86f9875 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-04-22 17:41 ` [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
@ 2020-04-30 18:58 ` Laszlo Ersek
2020-04-30 21:12 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Laszlo Ersek @ 2020-04-30 18:58 UTC (permalink / raw)
To: devel, thomas.lendacky
Cc: Jordan Justen, Ard Biesheuvel, Michael D Kinney, Liming Gao,
Eric Dong, Ray Ni, Brijesh Singh
Hi Tom,
On 04/22/20 19:41, Lendacky, Thomas 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@linaro.org>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/OvmfPkgX64.fdf | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
> index 36414c1f8b49..a0bea86f9875 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
>
>
in patch #28 ("OvmfPkg: Create a GHCB page for use during Sec phase"),
we carve out two ranges in FD.MEMFD, and introduce a matching set of 4 PCDs.
Then in patch #29 ("OvmfPkg/PlatformPei: Reserve GHCB-related areas if
S3 is supported"), we reserve those ranges from the OS, as AcpiNVS, if
S3 is supported. The reason we only reserve those ranges if S3 is
enabled because the ranges are only needed in SEC. (See the details in
the commit mesage of patch #29.)
In this patch (patch #33), we carve out a third region in FD.MEMFD. We
don't seem to ever reserve it. I think that's minimally a problem for
S3; the same argument should apply as to the other two areas. Do you agree?
Furthermore, I wonder if we should reserve this "work area" from the OS,
and even from the DXE phase (!), *regardless* of S3. I can't immediately
tell when it's the last time (with S3 disabled) when this area is used.
As I understand it, it is only used the first time the APs are booted
up. And that should happen still in the PEI phase, because CpuMpPei
boots up all the APs and counts them. Afterwards (still in the PEI
phase), the APs should be sleeping in ApWakeupFunction(), namely in the
code added by patch #40 ("UefiCpuPkg: Allow AP booting under SEV-ES").
If the AP is woken again, it is actually only "released" by the
hypervisor, and it goes through the special 64bit->16bit transition,
again implemented in patch#40.
So ultimately it shouldn't be necessary to reserve this third region (at
PcdSevEsWorkAreaBase), if S3 is disabled, because it is never used past
the very first AP boot (which happens when CpuMpPei counts the APs).
Do I understand right?
Thanks!
Laszlo
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-04-30 18:58 ` [edk2-devel] " Laszlo Ersek
@ 2020-04-30 21:12 ` Lendacky, Thomas
2020-04-30 22:09 ` Lendacky, Thomas
2020-05-05 15:15 ` Laszlo Ersek
0 siblings, 2 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-30 21:12 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Jordan Justen, Ard Biesheuvel, Michael D Kinney, Liming Gao,
Eric Dong, Ray Ni, Brijesh Singh
On 4/30/20 1:58 PM, Laszlo Ersek wrote:
> Hi Tom,
Hi Laszlo,
>
> On 04/22/20 19:41, Lendacky, Thomas 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%7Cce256f35aa2e4748e8e008d7ed3874ae%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637238699042461059&sdata=tXX8nkBo3fB4OVTs2avevW8pwL6AcqJHvFhvlshKySI%3D&reserved=0
>>
>> 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@linaro.org>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>> OvmfPkg/OvmfPkgX64.fdf | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>> index 36414c1f8b49..a0bea86f9875 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
>>
>>
>
> in patch #28 ("OvmfPkg: Create a GHCB page for use during Sec phase"),
> we carve out two ranges in FD.MEMFD, and introduce a matching set of 4 PCDs.
>
> Then in patch #29 ("OvmfPkg/PlatformPei: Reserve GHCB-related areas if
> S3 is supported"), we reserve those ranges from the OS, as AcpiNVS, if
> S3 is supported. The reason we only reserve those ranges if S3 is
> enabled because the ranges are only needed in SEC. (See the details in
> the commit mesage of patch #29.)
>
> In this patch (patch #33), we carve out a third region in FD.MEMFD. We
> don't seem to ever reserve it. I think that's minimally a problem for
> S3; the same argument should apply as to the other two areas. Do you agree?
Nice catch! Yes, I missed this one.
>
>
> Furthermore, I wonder if we should reserve this "work area" from the OS,
> and even from the DXE phase (!), *regardless* of S3. I can't immediately
> tell when it's the last time (with S3 disabled) when this area is used.
>
> As I understand it, it is only used the first time the APs are booted
> up. And that should happen still in the PEI phase, because CpuMpPei
> boots up all the APs and counts them. Afterwards (still in the PEI
> phase), the APs should be sleeping in ApWakeupFunction(), namely in the
> code added by patch #40 ("UefiCpuPkg: Allow AP booting under SEV-ES").
> If the AP is woken again, it is actually only "released" by the
> hypervisor, and it goes through the special 64bit->16bit transition,
> again implemented in patch#40.
>
> So ultimately it shouldn't be necessary to reserve this third region (at
> PcdSevEsWorkAreaBase), if S3 is disabled, because it is never used past
> the very first AP boot (which happens when CpuMpPei counts the APs).
>
> Do I understand right?
Yes, that is correct. So I just need to do the same thing for this area
that I did in patch #29.
I can probably shift patch #29 after #33 and have one patch for the S3
reservation instead of having two separate patches doing S3 reservation.
Thanks,
Tom
>
> Thanks!
> Laszlo
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-04-30 21:12 ` Lendacky, Thomas
@ 2020-04-30 22:09 ` Lendacky, Thomas
2020-05-05 15:25 ` Laszlo Ersek
2020-05-05 15:15 ` Laszlo Ersek
1 sibling, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-30 22:09 UTC (permalink / raw)
To: Laszlo Ersek, devel
Cc: Jordan Justen, Ard Biesheuvel, Michael D Kinney, Liming Gao,
Eric Dong, Ray Ni, Brijesh Singh
On 4/30/20 4:12 PM, Tom Lendacky wrote:
> On 4/30/20 1:58 PM, Laszlo Ersek wrote:
>> Hi Tom,
>
> Hi Laszlo,
>
>>
>> On 04/22/20 19:41, Lendacky, Thomas 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%7Cce256f35aa2e4748e8e008d7ed3874ae%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637238699042461059&sdata=tXX8nkBo3fB4OVTs2avevW8pwL6AcqJHvFhvlshKySI%3D&reserved=0
>>>
>>>
>>> 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@linaro.org>
>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>> ---
>>> OvmfPkg/OvmfPkgX64.fdf | 3 +++
>>> 1 file changed, 3 insertions(+)
>>>
>>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>>> index 36414c1f8b49..a0bea86f9875 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
>>>
>>>
>>
>> in patch #28 ("OvmfPkg: Create a GHCB page for use during Sec phase"),
>> we carve out two ranges in FD.MEMFD, and introduce a matching set of 4
>> PCDs.
>>
>> Then in patch #29 ("OvmfPkg/PlatformPei: Reserve GHCB-related areas if
>> S3 is supported"), we reserve those ranges from the OS, as AcpiNVS, if
>> S3 is supported. The reason we only reserve those ranges if S3 is
>> enabled because the ranges are only needed in SEC. (See the details in
>> the commit mesage of patch #29.)
>>
>> In this patch (patch #33), we carve out a third region in FD.MEMFD. We
>> don't seem to ever reserve it. I think that's minimally a problem for
>> S3; the same argument should apply as to the other two areas. Do you agree?
>
> Nice catch! Yes, I missed this one.
>
>>
>>
>> Furthermore, I wonder if we should reserve this "work area" from the OS,
>> and even from the DXE phase (!), *regardless* of S3. I can't immediately
>> tell when it's the last time (with S3 disabled) when this area is used.
>>
>> As I understand it, it is only used the first time the APs are booted
>> up. And that should happen still in the PEI phase, because CpuMpPei
>> boots up all the APs and counts them. Afterwards (still in the PEI
>> phase), the APs should be sleeping in ApWakeupFunction(), namely in the
>> code added by patch #40 ("UefiCpuPkg: Allow AP booting under SEV-ES").
>> If the AP is woken again, it is actually only "released" by the
>> hypervisor, and it goes through the special 64bit->16bit transition,
>> again implemented in patch#40.
>>
>> So ultimately it shouldn't be necessary to reserve this third region (at
>> PcdSevEsWorkAreaBase), if S3 is disabled, because it is never used past
>> the very first AP boot (which happens when CpuMpPei counts the APs).
>>
>> Do I understand right?
>
> Yes, that is correct. So I just need to do the same thing for this area
> that I did in patch #29.
I think I might want to protect the area from DXE allocations, too. Is
there an easy way to detect that PEI is active vs DXE? Even so, will it
*always* be the case that PEI will start the APs first? I'd hate to see a
change down the road where PEI doesn't start the APs and then things break.
Thanks,
Tom
>
> I can probably shift patch #29 after #33 and have one patch for the S3
> reservation instead of having two separate patches doing S3 reservation.
>
> Thanks,
> Tom
>
>>
>> Thanks!
>> Laszlo
>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-04-30 22:09 ` Lendacky, Thomas
@ 2020-05-05 15:25 ` Laszlo Ersek
0 siblings, 0 replies; 81+ messages in thread
From: Laszlo Ersek @ 2020-05-05 15:25 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Jordan Justen, Ard Biesheuvel, Michael D Kinney, Liming Gao,
Eric Dong, Ray Ni, Brijesh Singh
On 05/01/20 00:09, Tom Lendacky wrote:
> On 4/30/20 4:12 PM, Tom Lendacky wrote:
>> On 4/30/20 1:58 PM, Laszlo Ersek wrote:
>>> Hi Tom,
>>
>> Hi Laszlo,
>>
>>>
>>> On 04/22/20 19:41, Lendacky, Thomas 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%7Cce256f35aa2e4748e8e008d7ed3874ae%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637238699042461059&sdata=tXX8nkBo3fB4OVTs2avevW8pwL6AcqJHvFhvlshKySI%3D&reserved=0
>>>>
>>>>
>>>> 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@linaro.org>
>>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>>> ---
>>>> OvmfPkg/OvmfPkgX64.fdf | 3 +++
>>>> 1 file changed, 3 insertions(+)
>>>>
>>>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>>>> index 36414c1f8b49..a0bea86f9875 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
>>>>
>>>>
>>>
>>> in patch #28 ("OvmfPkg: Create a GHCB page for use during Sec phase"),
>>> we carve out two ranges in FD.MEMFD, and introduce a matching set of
>>> 4 PCDs.
>>>
>>> Then in patch #29 ("OvmfPkg/PlatformPei: Reserve GHCB-related areas if
>>> S3 is supported"), we reserve those ranges from the OS, as AcpiNVS, if
>>> S3 is supported. The reason we only reserve those ranges if S3 is
>>> enabled because the ranges are only needed in SEC. (See the details in
>>> the commit mesage of patch #29.)
>>>
>>> In this patch (patch #33), we carve out a third region in FD.MEMFD. We
>>> don't seem to ever reserve it. I think that's minimally a problem for
>>> S3; the same argument should apply as to the other two areas. Do you
>>> agree?
>>
>> Nice catch! Yes, I missed this one.
>>
>>>
>>>
>>> Furthermore, I wonder if we should reserve this "work area" from the OS,
>>> and even from the DXE phase (!), *regardless* of S3. I can't immediately
>>> tell when it's the last time (with S3 disabled) when this area is used.
>>>
>>> As I understand it, it is only used the first time the APs are booted
>>> up. And that should happen still in the PEI phase, because CpuMpPei
>>> boots up all the APs and counts them. Afterwards (still in the PEI
>>> phase), the APs should be sleeping in ApWakeupFunction(), namely in the
>>> code added by patch #40 ("UefiCpuPkg: Allow AP booting under SEV-ES").
>>> If the AP is woken again, it is actually only "released" by the
>>> hypervisor, and it goes through the special 64bit->16bit transition,
>>> again implemented in patch#40.
>>>
>>> So ultimately it shouldn't be necessary to reserve this third region (at
>>> PcdSevEsWorkAreaBase), if S3 is disabled, because it is never used past
>>> the very first AP boot (which happens when CpuMpPei counts the APs).
>>>
>>> Do I understand right?
>>
>> Yes, that is correct. So I just need to do the same thing for this
>> area that I did in patch #29.
>
> I think I might want to protect the area from DXE allocations, too.
OK. In such cases, the area in question is always covered with a memory
allocation HOB; what depends on S3 is only whether the memory type is
"boot services data" (S3 disabled on the QEMU cmdline) or AcpiNVS (S3
enabled). The region is then always kept away from DXE, and S3
enablement determines only whether the OS is told to stay away as well.
> Is
> there an easy way to detect that PEI is active vs DXE? Even so, will it
> *always* be the case that PEI will start the APs first? I'd hate to see
> a change down the road where PEI doesn't start the APs and then things
> break.
We'll have to continue including CpuMpPei, otherwise we couldn't re-set
the feature control MSR to the desired value at S3 resume. IOW, removing
CpuMpPei from OVMF would regress at least that feature:
https://bugzilla.tianocore.org/show_bug.cgi?id=86
Including CpuMpPei in OVMF was surprisingly quirky; I don't see it going
away anytime soon.
Thanks
Laszlo
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage
2020-04-30 21:12 ` Lendacky, Thomas
2020-04-30 22:09 ` Lendacky, Thomas
@ 2020-05-05 15:15 ` Laszlo Ersek
1 sibling, 0 replies; 81+ messages in thread
From: Laszlo Ersek @ 2020-05-05 15:15 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Jordan Justen, Ard Biesheuvel, Michael D Kinney, Liming Gao,
Eric Dong, Ray Ni, Brijesh Singh
On 04/30/20 23:12, Tom Lendacky wrote:
> On 4/30/20 1:58 PM, Laszlo Ersek wrote:
>> Hi Tom,
>
> Hi Laszlo,
>
>>
>> On 04/22/20 19:41, Lendacky, Thomas 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%7Cce256f35aa2e4748e8e008d7ed3874ae%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637238699042461059&sdata=tXX8nkBo3fB4OVTs2avevW8pwL6AcqJHvFhvlshKySI%3D&reserved=0
>>>
>>>
>>> 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@linaro.org>
>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>>> ---
>>> OvmfPkg/OvmfPkgX64.fdf | 3 +++
>>> 1 file changed, 3 insertions(+)
>>>
>>> diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
>>> index 36414c1f8b49..a0bea86f9875 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
>>>
>>>
>>
>> in patch #28 ("OvmfPkg: Create a GHCB page for use during Sec phase"),
>> we carve out two ranges in FD.MEMFD, and introduce a matching set of 4
>> PCDs.
>>
>> Then in patch #29 ("OvmfPkg/PlatformPei: Reserve GHCB-related areas if
>> S3 is supported"), we reserve those ranges from the OS, as AcpiNVS, if
>> S3 is supported. The reason we only reserve those ranges if S3 is
>> enabled because the ranges are only needed in SEC. (See the details in
>> the commit mesage of patch #29.)
>>
>> In this patch (patch #33), we carve out a third region in FD.MEMFD. We
>> don't seem to ever reserve it. I think that's minimally a problem for
>> S3; the same argument should apply as to the other two areas. Do you
>> agree?
>
> Nice catch! Yes, I missed this one.
>
>>
>>
>> Furthermore, I wonder if we should reserve this "work area" from the OS,
>> and even from the DXE phase (!), *regardless* of S3. I can't immediately
>> tell when it's the last time (with S3 disabled) when this area is used.
>>
>> As I understand it, it is only used the first time the APs are booted
>> up. And that should happen still in the PEI phase, because CpuMpPei
>> boots up all the APs and counts them. Afterwards (still in the PEI
>> phase), the APs should be sleeping in ApWakeupFunction(), namely in the
>> code added by patch #40 ("UefiCpuPkg: Allow AP booting under SEV-ES").
>> If the AP is woken again, it is actually only "released" by the
>> hypervisor, and it goes through the special 64bit->16bit transition,
>> again implemented in patch#40.
>>
>> So ultimately it shouldn't be necessary to reserve this third region (at
>> PcdSevEsWorkAreaBase), if S3 is disabled, because it is never used past
>> the very first AP boot (which happens when CpuMpPei counts the APs).
>>
>> Do I understand right?
>
> Yes, that is correct. So I just need to do the same thing for this area
> that I did in patch #29.
>
> I can probably shift patch #29 after #33 and have one patch for the S3
> reservation instead of having two separate patches doing S3 reservation.
Sounds good, thanks!
Laszlo
^ permalink raw reply [flat|nested] 81+ messages in thread
* [PATCH v7 34/43] OvmfPkg/ResetVector: Add support for a 32-bit SEV check
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (32 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 33/43] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 35/43] OvmfPkg/Sec: Add #VC exception handling for Sec phase Lendacky, Thomas
` (9 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
OvmfPkg/ResetVector/ResetVector.inf | 3 +
OvmfPkg/ResetVector/Ia32/PageTables64.asm | 320 ++++++++++++++++++++--
OvmfPkg/ResetVector/ResetVector.nasmb | 2 +
3 files changed, 298 insertions(+), 27 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 c3587a1b7814..a83569d4a4be 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -36,13 +36,58 @@ BITS 32
PAGE_READ_WRITE + \
PAGE_PRESENT)
-; Check if Secure Encrypted Virtualization (SEV) feature is enabled
;
-; If SEV is enabled then EAX will be at least 32
+; 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) features are enabled
+;
+; 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:
+CheckSevFeatures:
+ ; 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
@@ -67,6 +112,16 @@ CheckSevFeature:
bt eax, 0
jnc NoSev
+ ; Check if SEV-ES is enabled
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
+ bt eax, 1
+ jnc NoSevEs
+
+ ; 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
+
+NoSevEs:
; Get pte bit position to enable memory encryption
; CPUID Fn8000_001F[EBX] - Bits 5:0
;
@@ -78,45 +133,44 @@ NoSev:
xor eax, eax
SevExit:
- OneTimeCallRet CheckSevFeature
+ ;
+ ; Clear exception handlers and stack
+ ;
+ push eax
+ mov eax, ADDR_OF(IdtrClear)
+ lidt [cs:eax]
+ pop eax
+ mov esp, 0
+
+ OneTimeCallRet CheckSevFeatures
; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
; is enabled.
;
-; Modified: EAX, EBX, ECX
+; Modified: EAX
;
; If SEV-ES is enabled then EAX will be non-zero.
; If SEV-ES is disabled then EAX will be zero.
;
-CheckSevEsFeature:
+IsSevEsEnabled:
xor eax, eax
- ; SEV-ES can't be enabled if SEV isn't, so first check the encryption
- ; mask.
- test edx, edx
- jz NoSevEs
+ ; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if
+ ; SEV-ES is enabled.
+ cmp byte[SEV_ES_WORK_AREA], 0
+ jz SevEsDisabled
- ; Save current value of encryption mask
- mov ebx, edx
+ mov eax, 1
- ; 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
+SevEsDisabled:
+ OneTimeCallRet IsSevEsEnabled
;
; Modified: EAX, EBX, ECX, EDX
;
SetCr3ForPageTables64:
- OneTimeCall CheckSevFeature
+ OneTimeCall CheckSevFeatures
xor edx, edx
test eax, eax
jz SevNotActive
@@ -175,7 +229,7 @@ pageTableEntriesLoop:
mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
loop pageTableEntriesLoop
- OneTimeCall CheckSevEsFeature
+ OneTimeCall IsSevEsEnabled
test eax, eax
jz SetCr3
@@ -216,3 +270,215 @@ 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
+ ;
+
+ 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 35/43] OvmfPkg/Sec: Add #VC exception handling for Sec phase
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (33 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 34/43] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 36/43] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
` (8 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
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 bae9764577f0..4acfce8086e7 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 ((EFI_D_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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 36/43] OvmfPkg/Sec: Enable cache early to speed up booting
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (34 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 35/43] OvmfPkg/Sec: Add #VC exception handling for Sec phase Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 37/43] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES is enabled Lendacky, Thomas
` (7 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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@linaro.org>
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 4acfce8086e7..e0c81067e8c7 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 ((EFI_D_INFO,
--
2.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 37/43] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES is enabled
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (35 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 36/43] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 38/43] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
` (6 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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 VmgMmioWrite function from the VmgExitLib library 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@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
.../FvbServicesRuntimeDxe.inf | 2 ++
.../QemuFlash.h | 13 +++++++++++
.../QemuFlash.c | 23 ++++++++++++++++---
.../QemuFlashDxe.c | 22 ++++++++++++++++++
.../QemuFlashSmm.c | 16 +++++++++++++
5 files changed, 73 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 c81c58972bf2..358bce3336f2 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 ((EFI_D_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..4d51183fc956 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
@@ -10,6 +10,8 @@
**/
#include <Library/UefiRuntimeLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/VmgExitLib.h>
#include "QemuFlash.h"
@@ -32,3 +34,23 @@ 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 ()) {
+ VmgMmioWrite ((UINT8 *) Ptr, &Value, 1);
+ } 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 38/43] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (36 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 37/43] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES is enabled Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-22 17:41 ` [PATCH v7 39/43] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
` (5 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 39/43] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (37 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 38/43] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
@ 2020-04-22 17:41 ` Lendacky, Thomas
2020-04-23 4:33 ` [PATCH v7 40/43] UefiCpuPkg: Allow AP booting under SEV-ES Lendacky, Thomas
` (4 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-22 17:41 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh
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 a51a9ec1d28b..4ea94848dc11 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -70,4 +70,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 d78d328b4252..b4dc7e69d829 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -60,6 +60,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 74e919dae077..c320ad8334bb 100755
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -275,6 +275,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 64a4c3546e22..81c5b1a5b701 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1714,6 +1714,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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 40/43] UefiCpuPkg: Allow AP booting under SEV-ES
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (38 preceding siblings ...)
2020-04-22 17:41 ` [PATCH v7 39/43] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
@ 2020-04-23 4:33 ` Lendacky, Thomas
2020-04-23 4:33 ` [PATCH v7 41/43] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
` (3 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-23 4:33 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 | 264 +++++++++++++++++-
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 ++
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
.../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 239 ++++++++++++++++
11 files changed, 667 insertions(+), 14 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 4ea94848dc11..87cb63f83133 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -51,6 +51,7 @@ [LibraryClasses]
UefiBootServicesTableLib
DebugAgentLib
SynchronizationLib
+ VmgExitLib
[Protocols]
gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES
@@ -71,4 +72,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 b4dc7e69d829..c684bb4812c1 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -50,6 +50,7 @@ [LibraryClasses]
UefiCpuLib
SynchronizationLib
PeiServicesLib
+ VmgExitLib
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES
@@ -61,6 +62,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 c320ad8334bb..56726e26ef5b 100755
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -172,6 +172,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;
@@ -210,6 +215,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()
@@ -256,6 +263,7 @@ struct _CPU_MP_DATA {
UINT8 ApLoopMode;
UINT8 ApTargetCState;
UINT16 PmCodeSegment;
+ UINT16 Pm16CodeSegment;
CPU_AP_DATA *CpuData;
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
@@ -277,8 +285,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;
/**
@@ -384,6 +431,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.
+
+ @retval other 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..19527300ff3a 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.
+
+ @retval other 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 81c5b1a5b701..966b53045d22 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.
@@ -765,7 +882,28 @@ ApWakeupFunction (
//
while (TRUE) {
DisableInterrupts ();
- CpuSleep ();
+ if (CpuMpData->SevEsIsEnabled) {
+ MSR_SEV_ES_GHCB_REGISTER Msr;
+ GHCB *Ghcb;
+
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+ Ghcb = Msr.Ghcb;
+
+ VmgInit (Ghcb);
+ VmgExit (Ghcb, SvmExitApResetHold, 0, 0);
+ /*TODO: Check return value to verify SIPI issued */
+
+ //
+ // Awakened in a new phase? Use the new CpuMpData
+ //
+ if (CpuMpData->NewCpuMpData) {
+ CpuMpData = CpuMpData->NewCpuMpData;
+ }
+
+ MpInitLibSevEsAPReset (Ghcb, CpuMpData);
+ } else {
+ CpuSleep ();
+ }
CpuPause ();
}
}
@@ -878,6 +1016,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 = CpuMpData->GhcbBase;
+
//
// Get the BSP's data of GDT and IDT
//
@@ -904,8 +1045,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 +
@@ -958,7 +1100,8 @@ BackupAndPrepareWakeupBuffer(
CopyMem (
(VOID *) CpuMpData->WakeupBuffer,
(VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress,
- CpuMpData->AddressMap.RendezvousFunnelSize
+ CpuMpData->AddressMap.RendezvousFunnelSize +
+ CpuMpData->AddressMap.SwitchToRealSize
);
}
@@ -979,6 +1122,44 @@ RestoreWakeupBuffer(
);
}
+/**
+ Calculate the size of the reset stack.
+
+ @retval 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.
+
+ @retval 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.
@@ -992,16 +1173,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);
}
@@ -1016,7 +1203,31 @@ 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;
+ }
}
/**
@@ -1053,6 +1264,7 @@ WakeUpAP (
CpuMpData->InitFlag != ApInitDone) {
ResetVectorRequired = TRUE;
AllocateResetVector (CpuMpData);
+ AllocateSevEsAPMemory (CpuMpData);
FillExchangeInfoData (CpuMpData);
SaveLocalApicTimerSetting (CpuMpData);
}
@@ -1089,6 +1301,35 @@ 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) {
+ SEV_ES_AP_JMP_FAR *JmpFar;
+ UINT32 Offset, InsnByte;
+ UINT8 LoNib, HiNib;
+
+ JmpFar = (SEV_ES_AP_JMP_FAR *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+ ASSERT (JmpFar != NULL);
+
+ Offset = FixedPcdGet32 (PcdSevEsWorkAreaBase);
+ Offset += sizeof (JmpFar->InsnBuffer);
+ LoNib = (UINT8) Offset;
+ HiNib = (UINT8) (Offset >> 8);
+
+ // 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 ...
+
+ JmpFar->Rip = 0;
+ JmpFar->Segment = (UINT16) (ExchangeInfo->BufferStart >> 4);
+ }
//
// Wakeup all APs
//
@@ -1656,7 +1897,7 @@ MpInitLibInitialize (
ASSERT (MaxLogicalProcessorNumber != 0);
AsmGetAddressMap (&AddressMap);
- ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
+ ApResetVectorSize = GetApResetVectorSize (&AddressMap);
ApStackSize = PcdGet32(PcdCpuApStackSize);
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
@@ -1715,6 +1956,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.
@@ -1773,6 +2016,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..e17a351e5cfd 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.
+
+ @retval other 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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 41/43] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (39 preceding siblings ...)
2020-04-23 4:33 ` [PATCH v7 40/43] UefiCpuPkg: Allow AP booting under SEV-ES Lendacky, Thomas
@ 2020-04-23 4:33 ` Lendacky, Thomas
2020-04-23 4:33 ` [PATCH v7 42/43] OvmfPkg: Move the GHCB allocations into reserved memory Lendacky, Thomas
` (2 subsequent siblings)
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-23 4:33 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@linaro.org>
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(+)
create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 42/43] OvmfPkg: Move the GHCB allocations into reserved memory
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (40 preceding siblings ...)
2020-04-23 4:33 ` [PATCH v7 41/43] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
@ 2020-04-23 4:33 ` Lendacky, Thomas
2020-04-23 4:33 ` [PATCH v7 43/43] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use Lendacky, Thomas
2020-05-08 19:16 ` [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-23 4:33 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@linaro.org>
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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* [PATCH v7 43/43] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (41 preceding siblings ...)
2020-04-23 4:33 ` [PATCH v7 42/43] OvmfPkg: Move the GHCB allocations into reserved memory Lendacky, Thomas
@ 2020-04-23 4:33 ` Lendacky, Thomas
2020-05-08 19:16 ` [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
43 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-04-23 4:33 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 | 43 +++++-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 131 ++++++++++++++++--
3 files changed, 166 insertions(+), 16 deletions(-)
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 56726e26ef5b..63dca58fc827 100755
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -292,7 +292,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)
@@ -348,8 +349,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 19527300ff3a..9b72cd74113b 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
);
@@ -176,6 +184,11 @@ GetSevEsAPMemory (
DEBUG ((DEBUG_INFO, "Dxe: SevEsAPMemory = %lx\n", (UINTN) StartAddress));
+ //
+ // Save the SevEsAPMemory as the AP jump table.
+ //
+ VmgExitSetAPJumpTable (StartAddress);
+
return (UINTN) StartAddress;
}
@@ -330,17 +343,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 +396,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.17.1
^ permalink raw reply related [flat|nested] 81+ messages in thread
* Re: [PATCH v7 00/43] SEV-ES guest support
2020-04-22 17:41 [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
` (42 preceding siblings ...)
2020-04-23 4:33 ` [PATCH v7 43/43] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use Lendacky, Thomas
@ 2020-05-08 19:16 ` Lendacky, Thomas
2020-05-09 6:44 ` Ni, Ray
2020-05-11 15:37 ` Laszlo Ersek
43 siblings, 2 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-08 19:16 UTC (permalink / raw)
To: devel
Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Michael D Kinney,
Liming Gao, Eric Dong, Ray Ni, Brijesh Singh, Benjamin You,
Dandan Bi, Guo Dong, Hao A Wu, Jian J Wang, Maurice Ma
I was able to use the pull request method that Laszlo documented and fixed
up all of the issues identified by the VS compiler.
An additional change I'm planning to make for the next version (v8) of the
patches is to create a NULL library instance of the VmgExitLib that will
also include the #VC handler function. This will reduce the amount of code
associated with this feature for platforms that don't use/support SEV-ES.
Laszlo, this will mean that I will introduce a version of the VmgExitLib
under OvmfPkg that will provide the majority of the functionality that is
present today in UefiCpuPkg. In essence, the functionality in v7 patches 8
and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
this is the better way to do this. Let me know if you have any concerns.
Thanks,
Tom
On 4/22/20 12:41 PM, Tom Lendacky wrote:
> This patch series provides support for running EDK2/OVMF under SEV-ES.
>
> Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
> SEV support to protect the guest register state from the hypervisor. See
> "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
> section "15.35 Encrypted State (SEV-ES)" [1].
>
> In order to allow a hypervisor to perform functions on behalf of a guest,
> there is architectural support for notifying a guest's operating system
> when certain types of VMEXITs are about to occur. This allows the guest to
> selectively share information with the hypervisor to satisfy the requested
> function. The notification is performed using a new exception, the VMM
> Communication exception (#VC). The information is shared through the
> Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT instruction.
> The GHCB format and the protocol for using it is documented in "SEV-ES
> Guest-Hypervisor Communication Block Standardization" [2].
>
> The main areas of the EDK2 code that are updated to support SEV-ES are
> around the exception handling support and the AP boot support.
>
> Exception support is required starting in Sec, continuing through Pei
> and into Dxe in order to handle #VC exceptions that are generated. Each
> AP requires it's own GHCB page as well as a page to hold values specific
> to that AP.
>
> AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
> is typically used to boot the APs. However, the hypervisor is not allowed
> to update the guest registers. The GHCB document [2] talks about how SMP
> booting under SEV-ES is performed.
>
> Since the GHCB page must be a shared (unencrypted) page, the processor
> must be running in long mode in order for the guest and hypervisor to
> communicate with each other. As a result, SEV-ES is only supported under
> the X64 architecture.
>
> [1] https://www.amd.com/system/files/TechDocs/24593.pdf
> [2] https://developer.amd.com/wp-content/resources/56421.pdf
>
> ---
>
> These patches are based on commit:
> be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max failures")
>
> Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
>
> A version of the tree (with an extra patch to workaround Bugzilla 2340) can
> be found at:
> https://github.com/AMDESE/ovmf/tree/sev-es-v14
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Benjamin You <benjamin.you@intel.com>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Guo Dong <guo.dong@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Maurice Ma <maurice.ma@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
>
> Changes since v6:
> - Add function comments to all functions, including local functions
> - Add function parameter direction to all functions (in/out)
> - Add support for MMIO MOVZX/MOVSX instructions
> - Ensure the per-CPU variable page remains encrypted
> - Coding-style fixes as identified by Ecc
>
> Changes since v5:
> - Remove extraneous VmgExitLib usage
> - Miscellaneous changes to address feedback (coding style, etc.)
>
> Changes since v4:
> - Move the SEV-ES protocol negotiation out of the SEC exception handler
> and into the SecMain.c file. As a result:
> - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
> - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
> single AMDSevVcHandler.c
> - Consolidate VmgExitLib usage into common LibraryClasses sections
> - Add documentation comments to the VmgExitLib functions
>
> Changes since v3:
> - Remove the need for the MP library finalization routine. The AP
> jump table address will be held by the hypervisor rather than
> communicated via the GHCB MSR. This removes some fragility around
> the UEFI to OS transition.
> - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
> communicate the SEV-ES status, so that SEC CPU exception handling is
> only established for an SEV-ES guest.
> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
> - Fix SMM build breakage by adding VC exception support the SMM CPU
> exception handling.
> - Add memory fencing around the invocation of AsmVmgExit().
> - Clarify comments around the SEV-ES AP reset RIP values and usage.
> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
> - Remove the 16-bit code selector definition from MdeModulePkg
>
> Changes since v2:
> - Added a way to locate the SEV-ES fixed AP RIP address for starting
> AP's to avoid updating the actual flash image (build time location
> that is identified with a GUID value).
> - Create a VmgExit library to replace static inline functions.
> - Move some PCDs to the appropriate packages
> - Add support for writing to QEMU flash under SEV-ES
> - Add additional MMIO opcode support
> - Cleaned up the GHCB MSR CPUID protocol support
>
> Changes since v1:
> - Patches reworked to be more specific to the component/area being updated
> and order of definition/usage
> - Created a library for VMGEXIT-related functions to replace use of inline
> functions
> - Allocation method for GDT changed from AllocatePool to AllocatePages
> - Early caching only enabled for SEV-ES guests
> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
> - Reserved SEC GHCB-related memory areas when S3 is enabled
>
> Tom Lendacky (43):
> MdeModulePkg: Create PCDs to be used in support of SEV-ES
> UefiCpuPkg: Create PCD to be used in support of SEV-ES
> MdePkg: Add the MSR definition for the GHCB register
> MdePkg: Add a structure definition for the GHCB
> MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
> MdePkg/BaseLib: Add support for the XGETBV instruction
> MdePkg/BaseLib: Add support for the VMGEXIT instruction
> UefiCpuPkg: Implement library support for VMGEXIT
> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
> UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
> UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
> UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
> UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
> events
> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
> events
> UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
> events
> UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
> events
> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
> OvmfPkg: Add support to perform SEV-ES initialization
> OvmfPkg: Create a GHCB page for use during Sec phase
> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
> OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
> OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
> UefiCpuPkg: Create an SEV-ES workarea PCD
> OvmfPkg: Reserve a page in memory for the SEV-ES usage
> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
> OvmfPkg/Sec: Add #VC exception handling for Sec phase
> OvmfPkg/Sec: Enable cache early to speed up booting
> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
> SEV-ES is enabled
> UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
> enabled
> UefiCpuPkg: Allow AP booting under SEV-ES
> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
> OvmfPkg: Move the GHCB allocations into reserved memory
> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>
> MdeModulePkg/MdeModulePkg.dec | 9 +
> OvmfPkg/OvmfPkg.dec | 9 +
> UefiCpuPkg/UefiCpuPkg.dec | 17 +
> OvmfPkg/OvmfPkgIa32.dsc | 6 +
> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
> OvmfPkg/OvmfPkgX64.dsc | 6 +
> OvmfPkg/OvmfXen.dsc | 1 +
> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
> OvmfPkg/OvmfPkgX64.fdf | 9 +
> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
> .../FvbServicesRuntimeDxe.inf | 2 +
> OvmfPkg/ResetVector/ResetVector.inf | 8 +
> OvmfPkg/Sec/SecMain.inf | 4 +
> .../DxeCpuExceptionHandlerLib.inf | 5 +
> .../PeiCpuExceptionHandlerLib.inf | 5 +
> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
> .../SmmCpuExceptionHandlerLib.inf | 5 +
> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
> MdePkg/Include/Library/BaseLib.h | 31 +
> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
> .../QemuFlash.h | 13 +
> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
> .../CpuExceptionCommon.h | 2 +
> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
> .../MemEncryptSevLibInternal.c | 75 +-
> OvmfPkg/PlatformPei/AmdSev.c | 89 +
> OvmfPkg/PlatformPei/MemDetect.c | 23 +
> .../QemuFlash.c | 23 +-
> .../QemuFlashDxe.c | 22 +
> .../QemuFlashSmm.c | 16 +
> OvmfPkg/Sec/SecMain.c | 188 +-
> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
> .../CpuExceptionCommon.c | 2 +-
> .../Ia32/ArchAMDSevVcHandler.c | 38 +
> .../PeiDxeSmmCpuException.c | 16 +
> .../SecPeiCpuException.c | 16 +
> .../X64/ArchAMDSevVcHandler.c | 1699 +++++++++++++++++
> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
> MdeModulePkg/MdeModulePkg.uni | 8 +
> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
> .../X64/ExceptionHandlerAsm.nasm | 17 +
> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
> UefiCpuPkg/UefiCpuPkg.uni | 11 +
> 75 files changed, 4707 insertions(+), 102 deletions(-)
> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
> create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v7 00/43] SEV-ES guest support
2020-05-08 19:16 ` [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
@ 2020-05-09 6:44 ` Ni, Ray
2020-05-09 14:34 ` Lendacky, Thomas
2020-05-11 15:37 ` Laszlo Ersek
1 sibling, 1 reply; 81+ messages in thread
From: Ni, Ray @ 2020-05-09 6:44 UTC (permalink / raw)
To: Tom Lendacky, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
Tom,
I have a bit concern on your change that directly modifies CpuExceptionHandlerLib to handle
exception #29. Today's CpuExceptionHandlerLib simplify dumps the exception context for
every exception. Any component which wants to do specific handling of certain exceptions
should call RegisterCpuInterruptHandler(). Such as code in CpuDxe driver:
if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG, DebugExceptionHandler);
RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, PageFaultExceptionHandler);
}
Is it possible for your feature to follow the same pattern?
Thanks,
Ray
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com>
> Sent: Saturday, May 9, 2020 3:16 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin
> <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A
> <hao.a.wu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>
> I was able to use the pull request method that Laszlo documented and fixed
> up all of the issues identified by the VS compiler.
>
> An additional change I'm planning to make for the next version (v8) of the
> patches is to create a NULL library instance of the VmgExitLib that will
> also include the #VC handler function. This will reduce the amount of code
> associated with this feature for platforms that don't use/support SEV-ES.
>
> Laszlo, this will mean that I will introduce a version of the VmgExitLib
> under OvmfPkg that will provide the majority of the functionality that is
> present today in UefiCpuPkg. In essence, the functionality in v7 patches 8
> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
> this is the better way to do this. Let me know if you have any concerns.
>
> Thanks,
> Tom
>
> On 4/22/20 12:41 PM, Tom Lendacky wrote:
> > This patch series provides support for running EDK2/OVMF under SEV-ES.
> >
> > Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
> > SEV support to protect the guest register state from the hypervisor. See
> > "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
> > section "15.35 Encrypted State (SEV-ES)" [1].
> >
> > In order to allow a hypervisor to perform functions on behalf of a guest,
> > there is architectural support for notifying a guest's operating system
> > when certain types of VMEXITs are about to occur. This allows the guest to
> > selectively share information with the hypervisor to satisfy the requested
> > function. The notification is performed using a new exception, the VMM
> > Communication exception (#VC). The information is shared through the
> > Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT instruction.
> > The GHCB format and the protocol for using it is documented in "SEV-ES
> > Guest-Hypervisor Communication Block Standardization" [2].
> >
> > The main areas of the EDK2 code that are updated to support SEV-ES are
> > around the exception handling support and the AP boot support.
> >
> > Exception support is required starting in Sec, continuing through Pei
> > and into Dxe in order to handle #VC exceptions that are generated. Each
> > AP requires it's own GHCB page as well as a page to hold values specific
> > to that AP.
> >
> > AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
> > is typically used to boot the APs. However, the hypervisor is not allowed
> > to update the guest registers. The GHCB document [2] talks about how SMP
> > booting under SEV-ES is performed.
> >
> > Since the GHCB page must be a shared (unencrypted) page, the processor
> > must be running in long mode in order for the guest and hypervisor to
> > communicate with each other. As a result, SEV-ES is only supported under
> > the X64 architecture.
> >
> > [1] https://www.amd.com/system/files/TechDocs/24593.pdf
> > [2] https://developer.amd.com/wp-content/resources/56421.pdf
> >
> > ---
> >
> > These patches are based on commit:
> > be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max failures")
> >
> > Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
> >
> > A version of the tree (with an extra patch to workaround Bugzilla 2340) can
> > be found at:
> > https://github.com/AMDESE/ovmf/tree/sev-es-v14
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Benjamin You <benjamin.you@intel.com>
> > Cc: Dandan Bi <dandan.bi@intel.com>
> > Cc: Eric Dong <eric.dong@intel.com>
> > Cc: Guo Dong <guo.dong@intel.com>
> > Cc: Hao A Wu <hao.a.wu@intel.com>
> > Cc: Jian J Wang <jian.j.wang@intel.com>
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Maurice Ma <maurice.ma@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> >
> > Changes since v6:
> > - Add function comments to all functions, including local functions
> > - Add function parameter direction to all functions (in/out)
> > - Add support for MMIO MOVZX/MOVSX instructions
> > - Ensure the per-CPU variable page remains encrypted
> > - Coding-style fixes as identified by Ecc
> >
> > Changes since v5:
> > - Remove extraneous VmgExitLib usage
> > - Miscellaneous changes to address feedback (coding style, etc.)
> >
> > Changes since v4:
> > - Move the SEV-ES protocol negotiation out of the SEC exception handler
> > and into the SecMain.c file. As a result:
> > - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
> > - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
> > single AMDSevVcHandler.c
> > - Consolidate VmgExitLib usage into common LibraryClasses sections
> > - Add documentation comments to the VmgExitLib functions
> >
> > Changes since v3:
> > - Remove the need for the MP library finalization routine. The AP
> > jump table address will be held by the hypervisor rather than
> > communicated via the GHCB MSR. This removes some fragility around
> > the UEFI to OS transition.
> > - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
> > communicate the SEV-ES status, so that SEC CPU exception handling is
> > only established for an SEV-ES guest.
> > - Fix SMM build breakageAdd around QemuFlashPtrWrite().
> > - Fix SMM build breakage by adding VC exception support the SMM CPU
> > exception handling.
> > - Add memory fencing around the invocation of AsmVmgExit().
> > - Clarify comments around the SEV-ES AP reset RIP values and usage.
> > - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
> > - Remove the 16-bit code selector definition from MdeModulePkg
> >
> > Changes since v2:
> > - Added a way to locate the SEV-ES fixed AP RIP address for starting
> > AP's to avoid updating the actual flash image (build time location
> > that is identified with a GUID value).
> > - Create a VmgExit library to replace static inline functions.
> > - Move some PCDs to the appropriate packages
> > - Add support for writing to QEMU flash under SEV-ES
> > - Add additional MMIO opcode support
> > - Cleaned up the GHCB MSR CPUID protocol support
> >
> > Changes since v1:
> > - Patches reworked to be more specific to the component/area being updated
> > and order of definition/usage
> > - Created a library for VMGEXIT-related functions to replace use of inline
> > functions
> > - Allocation method for GDT changed from AllocatePool to AllocatePages
> > - Early caching only enabled for SEV-ES guests
> > - Ensure AP loop mode set to halt loop mode for SEV-ES guests
> > - Reserved SEC GHCB-related memory areas when S3 is enabled
> >
> > Tom Lendacky (43):
> > MdeModulePkg: Create PCDs to be used in support of SEV-ES
> > UefiCpuPkg: Create PCD to be used in support of SEV-ES
> > MdePkg: Add the MSR definition for the GHCB register
> > MdePkg: Add a structure definition for the GHCB
> > MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
> > MdePkg/BaseLib: Add support for the XGETBV instruction
> > MdePkg/BaseLib: Add support for the VMGEXIT instruction
> > UefiCpuPkg: Implement library support for VMGEXIT
> > OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
> > UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
> > UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
> > UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
> > UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
> > events
> > UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
> > UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
> > events
> > UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
> > events
> > UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
> > events
> > OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
> > OvmfPkg: Add support to perform SEV-ES initialization
> > OvmfPkg: Create a GHCB page for use during Sec phase
> > OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
> > OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
> > OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
> > UefiCpuPkg: Create an SEV-ES workarea PCD
> > OvmfPkg: Reserve a page in memory for the SEV-ES usage
> > OvmfPkg/ResetVector: Add support for a 32-bit SEV check
> > OvmfPkg/Sec: Add #VC exception handling for Sec phase
> > OvmfPkg/Sec: Enable cache early to speed up booting
> > OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
> > SEV-ES is enabled
> > UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
> > UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
> > enabled
> > UefiCpuPkg: Allow AP booting under SEV-ES
> > OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
> > OvmfPkg: Move the GHCB allocations into reserved memory
> > UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
> >
> > MdeModulePkg/MdeModulePkg.dec | 9 +
> > OvmfPkg/OvmfPkg.dec | 9 +
> > UefiCpuPkg/UefiCpuPkg.dec | 17 +
> > OvmfPkg/OvmfPkgIa32.dsc | 6 +
> > OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
> > OvmfPkg/OvmfPkgX64.dsc | 6 +
> > OvmfPkg/OvmfXen.dsc | 1 +
> > UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> > UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
> > UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
> > OvmfPkg/OvmfPkgX64.fdf | 9 +
> > MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
> > MdePkg/Library/BaseLib/BaseLib.inf | 4 +
> > OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
> > .../FvbServicesRuntimeDxe.inf | 2 +
> > OvmfPkg/ResetVector/ResetVector.inf | 8 +
> > OvmfPkg/Sec/SecMain.inf | 4 +
> > .../DxeCpuExceptionHandlerLib.inf | 5 +
> > .../PeiCpuExceptionHandlerLib.inf | 5 +
> > .../SecPeiCpuExceptionHandlerLib.inf | 5 +
> > .../SmmCpuExceptionHandlerLib.inf | 5 +
> > UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
> > UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
> > .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
> > MdePkg/Include/Library/BaseLib.h | 31 +
> > MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
> > MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
> > OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
> > .../QemuFlash.h | 13 +
> > UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
> > UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
> > .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
> > .../CpuExceptionCommon.h | 2 +
> > UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
> > .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
> > .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
> > .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
> > MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
> > MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
> > .../MemEncryptSevLibInternal.c | 75 +-
> > OvmfPkg/PlatformPei/AmdSev.c | 89 +
> > OvmfPkg/PlatformPei/MemDetect.c | 23 +
> > .../QemuFlash.c | 23 +-
> > .../QemuFlashDxe.c | 22 +
> > .../QemuFlashSmm.c | 16 +
> > OvmfPkg/Sec/SecMain.c | 188 +-
> > UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
> > .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
> > .../CpuExceptionCommon.c | 2 +-
> > .../Ia32/ArchAMDSevVcHandler.c | 38 +
> > .../PeiDxeSmmCpuException.c | 16 +
> > .../SecPeiCpuException.c | 16 +
> > .../X64/ArchAMDSevVcHandler.c | 1699 +++++++++++++++++
> > UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
> > UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
> > UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
> > UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
> > MdeModulePkg/MdeModulePkg.uni | 8 +
> > MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
> > MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
> > MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
> > MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
> > OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
> > OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
> > OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
> > .../X64/ExceptionHandlerAsm.nasm | 17 +
> > UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
> > .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
> > UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
> > UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
> > .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
> > UefiCpuPkg/UefiCpuPkg.uni | 11 +
> > 75 files changed, 4707 insertions(+), 102 deletions(-)
> > create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> > create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
> > create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
> > create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
> > create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
> > create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
> > create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
> > create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> > create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
> > create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> > create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
> > create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
> > create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> > create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
> >
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v7 00/43] SEV-ES guest support
2020-05-09 6:44 ` Ni, Ray
@ 2020-05-09 14:34 ` Lendacky, Thomas
2020-05-09 19:09 ` [edk2-devel] " Andrew Fish
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-09 14:34 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
On 5/9/20 1:44 AM, Ni, Ray wrote:
> Tom,
Hi Ray,
> I have a bit concern on your change that directly modifies CpuExceptionHandlerLib to handle
> exception #29. Today's CpuExceptionHandlerLib simplify dumps the exception context for
> every exception. Any component which wants to do specific handling of certain exceptions
> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe driver:
>
> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG, DebugExceptionHandler);
> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, PageFaultExceptionHandler);
> }
>
> Is it possible for your feature to follow the same pattern?
There are two problems:
The first is that RegisterCpuInterruptHandler() is not implemented for
both the SEC and PEI phases, so it is not currently possible to register a
handler that early.
The second is that I need to be able to propagate an exception request
from the hypervisor. With the current implementation there doesn't appear
to be an easy way to perform this propagation.
If there's a way to accomplish both of the above I wouldn't be opposed to
using RegisterCpuInterruptHandler() as long as there are no #VCs that can
occur between initializing exception handling and and registering the #VC
handler.
Thanks,
Tom
>
> Thanks,
> Ray
>
>> -----Original Message-----
>> From: Tom Lendacky <thomas.lendacky@amd.com>
>> Sent: Saturday, May 9, 2020 3:16 AM
>> To: devel@edk2.groups.io
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>> Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin
>> <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A
>> <hao.a.wu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>
>> I was able to use the pull request method that Laszlo documented and fixed
>> up all of the issues identified by the VS compiler.
>>
>> An additional change I'm planning to make for the next version (v8) of the
>> patches is to create a NULL library instance of the VmgExitLib that will
>> also include the #VC handler function. This will reduce the amount of code
>> associated with this feature for platforms that don't use/support SEV-ES.
>>
>> Laszlo, this will mean that I will introduce a version of the VmgExitLib
>> under OvmfPkg that will provide the majority of the functionality that is
>> present today in UefiCpuPkg. In essence, the functionality in v7 patches 8
>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
>> this is the better way to do this. Let me know if you have any concerns.
>>
>> Thanks,
>> Tom
>>
>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>> This patch series provides support for running EDK2/OVMF under SEV-ES.
>>>
>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
>>> SEV support to protect the guest register state from the hypervisor. See
>>> "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>
>>> In order to allow a hypervisor to perform functions on behalf of a guest,
>>> there is architectural support for notifying a guest's operating system
>>> when certain types of VMEXITs are about to occur. This allows the guest to
>>> selectively share information with the hypervisor to satisfy the requested
>>> function. The notification is performed using a new exception, the VMM
>>> Communication exception (#VC). The information is shared through the
>>> Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT instruction.
>>> The GHCB format and the protocol for using it is documented in "SEV-ES
>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>
>>> The main areas of the EDK2 code that are updated to support SEV-ES are
>>> around the exception handling support and the AP boot support.
>>>
>>> Exception support is required starting in Sec, continuing through Pei
>>> and into Dxe in order to handle #VC exceptions that are generated. Each
>>> AP requires it's own GHCB page as well as a page to hold values specific
>>> to that AP.
>>>
>>> AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
>>> is typically used to boot the APs. However, the hypervisor is not allowed
>>> to update the guest registers. The GHCB document [2] talks about how SMP
>>> booting under SEV-ES is performed.
>>>
>>> Since the GHCB page must be a shared (unencrypted) page, the processor
>>> must be running in long mode in order for the guest and hypervisor to
>>> communicate with each other. As a result, SEV-ES is only supported under
>>> the X64 architecture.
>>>
>>> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0
>>> [2] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>
>>> ---
>>>
>>> These patches are based on commit:
>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max failures")
>>>
>>> Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
>>>
>>> A version of the tree (with an extra patch to workaround Bugzilla 2340) can
>>> be found at:
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0
>>>
>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> Cc: Benjamin You <benjamin.you@intel.com>
>>> Cc: Dandan Bi <dandan.bi@intel.com>
>>> Cc: Eric Dong <eric.dong@intel.com>
>>> Cc: Guo Dong <guo.dong@intel.com>
>>> Cc: Hao A Wu <hao.a.wu@intel.com>
>>> Cc: Jian J Wang <jian.j.wang@intel.com>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Liming Gao <liming.gao@intel.com>
>>> Cc: Maurice Ma <maurice.ma@intel.com>
>>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>>> Cc: Ray Ni <ray.ni@intel.com>
>>>
>>> Changes since v6:
>>> - Add function comments to all functions, including local functions
>>> - Add function parameter direction to all functions (in/out)
>>> - Add support for MMIO MOVZX/MOVSX instructions
>>> - Ensure the per-CPU variable page remains encrypted
>>> - Coding-style fixes as identified by Ecc
>>>
>>> Changes since v5:
>>> - Remove extraneous VmgExitLib usage
>>> - Miscellaneous changes to address feedback (coding style, etc.)
>>>
>>> Changes since v4:
>>> - Move the SEV-ES protocol negotiation out of the SEC exception handler
>>> and into the SecMain.c file. As a result:
>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
>>> - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
>>> single AMDSevVcHandler.c
>>> - Consolidate VmgExitLib usage into common LibraryClasses sections
>>> - Add documentation comments to the VmgExitLib functions
>>>
>>> Changes since v3:
>>> - Remove the need for the MP library finalization routine. The AP
>>> jump table address will be held by the hypervisor rather than
>>> communicated via the GHCB MSR. This removes some fragility around
>>> the UEFI to OS transition.
>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
>>> communicate the SEV-ES status, so that SEC CPU exception handling is
>>> only established for an SEV-ES guest.
>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>> - Fix SMM build breakage by adding VC exception support the SMM CPU
>>> exception handling.
>>> - Add memory fencing around the invocation of AsmVmgExit().
>>> - Clarify comments around the SEV-ES AP reset RIP values and usage.
>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>
>>> Changes since v2:
>>> - Added a way to locate the SEV-ES fixed AP RIP address for starting
>>> AP's to avoid updating the actual flash image (build time location
>>> that is identified with a GUID value).
>>> - Create a VmgExit library to replace static inline functions.
>>> - Move some PCDs to the appropriate packages
>>> - Add support for writing to QEMU flash under SEV-ES
>>> - Add additional MMIO opcode support
>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>
>>> Changes since v1:
>>> - Patches reworked to be more specific to the component/area being updated
>>> and order of definition/usage
>>> - Created a library for VMGEXIT-related functions to replace use of inline
>>> functions
>>> - Allocation method for GDT changed from AllocatePool to AllocatePages
>>> - Early caching only enabled for SEV-ES guests
>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>
>>> Tom Lendacky (43):
>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>> MdePkg: Add the MSR definition for the GHCB register
>>> MdePkg: Add a structure definition for the GHCB
>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>> UefiCpuPkg: Implement library support for VMGEXIT
>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
>>> UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
>>> UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
>>> events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
>>> events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
>>> events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
>>> events
>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
>>> OvmfPkg: Add support to perform SEV-ES initialization
>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
>>> OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
>>> SEV-ES is enabled
>>> UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
>>> enabled
>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>
>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>> OvmfPkg/OvmfPkg.dec | 9 +
>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>> OvmfPkg/OvmfXen.dsc | 1 +
>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>> .../QemuFlash.h | 13 +
>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>> .../CpuExceptionCommon.h | 2 +
>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>> .../MemEncryptSevLibInternal.c | 75 +-
>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>> .../QemuFlash.c | 23 +-
>>> .../QemuFlashDxe.c | 22 +
>>> .../QemuFlashSmm.c | 16 +
>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>> .../CpuExceptionCommon.c | 2 +-
>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>> .../PeiDxeSmmCpuException.c | 16 +
>>> .../SecPeiCpuException.c | 16 +
>>> .../X64/ArchAMDSevVcHandler.c | 1699 +++++++++++++++++
>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>> create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-09 14:34 ` Lendacky, Thomas
@ 2020-05-09 19:09 ` Andrew Fish
2020-05-11 5:24 ` Ni, Ray
2020-05-12 16:49 ` Lendacky, Thomas
0 siblings, 2 replies; 81+ messages in thread
From: Andrew Fish @ 2020-05-09 19:09 UTC (permalink / raw)
To: devel, thomas.lendacky
Cc: Ni, Ray, Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Mike Kinney,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
[-- Attachment #1: Type: text/plain, Size: 22256 bytes --]
> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com> wrote:
>
> On 5/9/20 1:44 AM, Ni, Ray wrote:
>> Tom,
>
> Hi Ray,
>
>> I have a bit concern on your change that directly modifies CpuExceptionHandlerLib to handle
>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the exception context for
>> every exception. Any component which wants to do specific handling of certain exceptions
>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe driver:
>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG, DebugExceptionHandler);
>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, PageFaultExceptionHandler);
>> }
>> Is it possible for your feature to follow the same pattern?
>
> There are two problems:
>
> The first is that RegisterCpuInterruptHandler() is not implemented for both the SEC and PEI phases, so it is not currently possible to register a handler that early.
>
> The second is that I need to be able to propagate an exception request from the hypervisor. With the current implementation there doesn't appear to be an easy way to perform this propagation.
>
> If there's a way to accomplish both of the above I wouldn't be opposed to using RegisterCpuInterruptHandler() as long as there are no #VCs that can occur between initializing exception handling and and registering the #VC handler.
>
Thomas,
As you point out it is tricky dealing with XIP code. You can't have globals that you can write and generally you use a PEI service to look tings up, the most common thing being using a HOB. But SEC has no services and I'm not sure you really want to be calling into the PEI Core on a random exception.
Here are the best options that popped into my head after reading your email
1) IDT in RAM
If your code populates the IDT the IDTR gives you access to the address of the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for a cached copy of the PEI Services Table, but otther than that you are good to go. It should be possible to have a global so you can have the table required to implement RegisterCpuInterruptHandler(). There might be some usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data after the IDT would be a good option. In general if your code allocates the memory for the IDT then you can treat the IDT as part of your private context data structure and that gives you access
2) IDT in ROM.
For this it seems like you need a library to link in to the CpuExceptionHandlerLib that allows you to override the handler. If CpuInterruptHandlerOverride() returns NULL you do the current behavior if not NULL then you call the returned handler.
EFI_CPU_INTERRUPT_HANDLER
EFIAPI
OverrideCpuInterruptHandler (
IN EFI_EXCEPTION_TYPE InterruptType
);
Thanks,
Andrew Fish
PS Off topic, but it would also be useful to have a library that overrides the state dump display. For example using Xcode you can always display a stack frame from the exception handler.
> Thanks,
> Tom
>
>> Thanks,
>> Ray
>>> -----Original Message-----
>>> From: Tom Lendacky <thomas.lendacky@amd.com>
>>> Sent: Saturday, May 9, 2020 3:16 AM
>>> To: devel@edk2.groups.io
>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>>> Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin
>>> <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A
>>> <hao.a.wu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>
>>> I was able to use the pull request method that Laszlo documented and fixed
>>> up all of the issues identified by the VS compiler.
>>>
>>> An additional change I'm planning to make for the next version (v8) of the
>>> patches is to create a NULL library instance of the VmgExitLib that will
>>> also include the #VC handler function. This will reduce the amount of code
>>> associated with this feature for platforms that don't use/support SEV-ES.
>>>
>>> Laszlo, this will mean that I will introduce a version of the VmgExitLib
>>> under OvmfPkg that will provide the majority of the functionality that is
>>> present today in UefiCpuPkg. In essence, the functionality in v7 patches 8
>>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
>>> this is the better way to do this. Let me know if you have any concerns.
>>>
>>> Thanks,
>>> Tom
>>>
>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>> This patch series provides support for running EDK2/OVMF under SEV-ES.
>>>>
>>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
>>>> SEV support to protect the guest register state from the hypervisor. See
>>>> "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>
>>>> In order to allow a hypervisor to perform functions on behalf of a guest,
>>>> there is architectural support for notifying a guest's operating system
>>>> when certain types of VMEXITs are about to occur. This allows the guest to
>>>> selectively share information with the hypervisor to satisfy the requested
>>>> function. The notification is performed using a new exception, the VMM
>>>> Communication exception (#VC). The information is shared through the
>>>> Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT instruction.
>>>> The GHCB format and the protocol for using it is documented in "SEV-ES
>>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>>
>>>> The main areas of the EDK2 code that are updated to support SEV-ES are
>>>> around the exception handling support and the AP boot support.
>>>>
>>>> Exception support is required starting in Sec, continuing through Pei
>>>> and into Dxe in order to handle #VC exceptions that are generated. Each
>>>> AP requires it's own GHCB page as well as a page to hold values specific
>>>> to that AP.
>>>>
>>>> AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
>>>> is typically used to boot the APs. However, the hypervisor is not allowed
>>>> to update the guest registers. The GHCB document [2] talks about how SMP
>>>> booting under SEV-ES is performed.
>>>>
>>>> Since the GHCB page must be a shared (unencrypted) page, the processor
>>>> must be running in long mode in order for the guest and hypervisor to
>>>> communicate with each other. As a result, SEV-ES is only supported under
>>>> the X64 architecture.
>>>>
>>>> [1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0 <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0>
>>>> [2] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0 <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0>
>>>>
>>>> ---
>>>>
>>>> These patches are based on commit:
>>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max failures")
>>>>
>>>> Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
>>>>
>>>> A version of the tree (with an extra patch to workaround Bugzilla 2340) can
>>>> be found at:
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0 <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0>
>>>>
>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org <mailto:ard.biesheuvel@linaro.org>>
>>>> Cc: Benjamin You <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>
>>>> Cc: Dandan Bi <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>
>>>> Cc: Eric Dong <eric.dong@intel.com <mailto:eric.dong@intel.com>>
>>>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
>>>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
>>>> Cc: Jian J Wang <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>
>>>> Cc: Jordan Justen <jordan.l.justen@intel.com <mailto:jordan.l.justen@intel.com>>
>>>> Cc: Laszlo Ersek <lersek@redhat.com <mailto:lersek@redhat.com>>
>>>> Cc: Liming Gao <liming.gao@intel.com <mailto:liming.gao@intel.com>>
>>>> Cc: Maurice Ma <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>>
>>>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>>>>
>>>> Changes since v6:
>>>> - Add function comments to all functions, including local functions
>>>> - Add function parameter direction to all functions (in/out)
>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>> - Ensure the per-CPU variable page remains encrypted
>>>> - Coding-style fixes as identified by Ecc
>>>>
>>>> Changes since v5:
>>>> - Remove extraneous VmgExitLib usage
>>>> - Miscellaneous changes to address feedback (coding style, etc.)
>>>>
>>>> Changes since v4:
>>>> - Move the SEV-ES protocol negotiation out of the SEC exception handler
>>>> and into the SecMain.c file. As a result:
>>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
>>>> - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
>>>> single AMDSevVcHandler.c
>>>> - Consolidate VmgExitLib usage into common LibraryClasses sections
>>>> - Add documentation comments to the VmgExitLib functions
>>>>
>>>> Changes since v3:
>>>> - Remove the need for the MP library finalization routine. The AP
>>>> jump table address will be held by the hypervisor rather than
>>>> communicated via the GHCB MSR. This removes some fragility around
>>>> the UEFI to OS transition.
>>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
>>>> communicate the SEV-ES status, so that SEC CPU exception handling is
>>>> only established for an SEV-ES guest.
>>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>>> - Fix SMM build breakage by adding VC exception support the SMM CPU
>>>> exception handling.
>>>> - Add memory fencing around the invocation of AsmVmgExit().
>>>> - Clarify comments around the SEV-ES AP reset RIP values and usage.
>>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>>
>>>> Changes since v2:
>>>> - Added a way to locate the SEV-ES fixed AP RIP address for starting
>>>> AP's to avoid updating the actual flash image (build time location
>>>> that is identified with a GUID value).
>>>> - Create a VmgExit library to replace static inline functions.
>>>> - Move some PCDs to the appropriate packages
>>>> - Add support for writing to QEMU flash under SEV-ES
>>>> - Add additional MMIO opcode support
>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>
>>>> Changes since v1:
>>>> - Patches reworked to be more specific to the component/area being updated
>>>> and order of definition/usage
>>>> - Created a library for VMGEXIT-related functions to replace use of inline
>>>> functions
>>>> - Allocation method for GDT changed from AllocatePool to AllocatePages
>>>> - Early caching only enabled for SEV-ES guests
>>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>>
>>>> Tom Lendacky (43):
>>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>>> MdePkg: Add the MSR definition for the GHCB register
>>>> MdePkg: Add a structure definition for the GHCB
>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
>>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>>> UefiCpuPkg: Implement library support for VMGEXIT
>>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
>>>> UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
>>>> events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
>>>> events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
>>>> events
>>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
>>>> events
>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
>>>> OvmfPkg: Add support to perform SEV-ES initialization
>>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
>>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
>>>> OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
>>>> SEV-ES is enabled
>>>> UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
>>>> enabled
>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
>>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>>
>>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>>> OvmfPkg/OvmfPkg.dec | 9 +
>>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>>> OvmfPkg/OvmfXen.dsc | 1 +
>>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>>> .../QemuFlash.h | 13 +
>>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>>> .../CpuExceptionCommon.h | 2 +
>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>>> .../MemEncryptSevLibInternal.c | 75 +-
>>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>>> .../QemuFlash.c | 23 +-
>>>> .../QemuFlashDxe.c | 22 +
>>>> .../QemuFlashSmm.c | 16 +
>>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>>> .../CpuExceptionCommon.c | 2 +-
>>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>>> .../PeiDxeSmmCpuException.c | 16 +
>>>> .../SecPeiCpuException.c | 16 +
>>>> .../X64/ArchAMDSevVcHandler.c | 1699 +++++++++++++++++
>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>> create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>> create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>
>
>
[-- Attachment #2: Type: text/html, Size: 44158 bytes --]
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-09 19:09 ` [edk2-devel] " Andrew Fish
@ 2020-05-11 5:24 ` Ni, Ray
2020-05-12 14:59 ` Lendacky, Thomas
2020-05-12 16:49 ` Lendacky, Thomas
1 sibling, 1 reply; 81+ messages in thread
From: Ni, Ray @ 2020-05-11 5:24 UTC (permalink / raw)
To: devel@edk2.groups.io, afish@apple.com, thomas.lendacky@amd.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
[-- Attachment #1: Type: text/plain, Size: 21464 bytes --]
Tom,
I agree with the first issue. I am not quite clear on the second one.
SourceLevelDebugPkg provides source level debugging support early in SEC
through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
It hooks all Intel SDM defined exceptions. It hooks INT32 additionally to support breaking from HOST.
It doesn't use CpuExceptionLib because it hooks in very early SEC phase.
Can you use the same way?
Thanks,
Ray
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Andrew Fish via groups.io
Sent: Sunday, May 10, 2020 3:10 AM
To: devel@edk2.groups.io; thomas.lendacky@amd.com
Cc: Ni, Ray <ray.ni@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com<mailto:thomas.lendacky@amd.com>> wrote:
On 5/9/20 1:44 AM, Ni, Ray wrote:
Tom,
Hi Ray,
I have a bit concern on your change that directly modifies CpuExceptionHandlerLib to handle
exception #29. Today's CpuExceptionHandlerLib simplify dumps the exception context for
every exception. Any component which wants to do specific handling of certain exceptions
should call RegisterCpuInterruptHandler(). Such as code in CpuDxe driver:
if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG, DebugExceptionHandler);
RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT, PageFaultExceptionHandler);
}
Is it possible for your feature to follow the same pattern?
There are two problems:
The first is that RegisterCpuInterruptHandler() is not implemented for both the SEC and PEI phases, so it is not currently possible to register a handler that early.
The second is that I need to be able to propagate an exception request from the hypervisor. With the current implementation there doesn't appear to be an easy way to perform this propagation.
If there's a way to accomplish both of the above I wouldn't be opposed to using RegisterCpuInterruptHandler() as long as there are no #VCs that can occur between initializing exception handling and and registering the #VC handler.
Thomas,
As you point out it is tricky dealing with XIP code. You can't have globals that you can write and generally you use a PEI service to look tings up, the most common thing being using a HOB. But SEC has no services and I'm not sure you really want to be calling into the PEI Core on a random exception.
Here are the best options that popped into my head after reading your email
1) IDT in RAM
If your code populates the IDT the IDTR gives you access to the address of the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for a cached copy of the PEI Services Table, but otther than that you are good to go. It should be possible to have a global so you can have the table required to implement RegisterCpuInterruptHandler(). There might be some usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data after the IDT would be a good option. In general if your code allocates the memory for the IDT then you can treat the IDT as part of your private context data structure and that gives you access
2) IDT in ROM.
For this it seems like you need a library to link in to the CpuExceptionHandlerLib that allows you to override the handler. If CpuInterruptHandlerOverride() returns NULL you do the current behavior if not NULL then you call the returned handler.
EFI_CPU_INTERRUPT_HANDLER
EFIAPI
OverrideCpuInterruptHandler (
IN EFI_EXCEPTION_TYPE InterruptType
);
Thanks,
Andrew Fish
PS Off topic, but it would also be useful to have a library that overrides the state dump display. For example using Xcode you can always display a stack frame from the exception handler.
Thanks,
Tom
Thanks,
Ray
-----Original Message-----
From: Tom Lendacky <thomas.lendacky@amd.com<mailto:thomas.lendacky@amd.com>>
Sent: Saturday, May 9, 2020 3:16 AM
To: devel@edk2.groups.io<mailto:devel@edk2.groups.io>
Cc: Justen, Jordan L <jordan.l.justen@intel.com<mailto:jordan.l.justen@intel.com>>; Laszlo Ersek <lersek@redhat.com<mailto:lersek@redhat.com>>; Ard Biesheuvel
<ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D <michael.d.kinney@intel.com<mailto:michael.d.kinney@intel.com>>; Gao, Liming <liming.gao@intel.com<mailto:liming.gao@intel.com>>; Dong,
Eric <eric.dong@intel.com<mailto:eric.dong@intel.com>>; Ni, Ray <ray.ni@intel.com<mailto:ray.ni@intel.com>>; Brijesh Singh <brijesh.singh@amd.com<mailto:brijesh.singh@amd.com>>; You, Benjamin
<benjamin.you@intel.com<mailto:benjamin.you@intel.com>>; Bi, Dandan <dandan.bi@intel.com<mailto:dandan.bi@intel.com>>; Dong, Guo <guo.dong@intel.com<mailto:guo.dong@intel.com>>; Wu, Hao A
<hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>; Wang, Jian J <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>; Ma, Maurice <maurice.ma@intel.com<mailto:maurice.ma@intel.com>>
Subject: Re: [PATCH v7 00/43] SEV-ES guest support
I was able to use the pull request method that Laszlo documented and fixed
up all of the issues identified by the VS compiler.
An additional change I'm planning to make for the next version (v8) of the
patches is to create a NULL library instance of the VmgExitLib that will
also include the #VC handler function. This will reduce the amount of code
associated with this feature for platforms that don't use/support SEV-ES.
Laszlo, this will mean that I will introduce a version of the VmgExitLib
under OvmfPkg that will provide the majority of the functionality that is
present today in UefiCpuPkg. In essence, the functionality in v7 patches 8
and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
this is the better way to do this. Let me know if you have any concerns.
Thanks,
Tom
On 4/22/20 12:41 PM, Tom Lendacky wrote:
This patch series provides support for running EDK2/OVMF under SEV-ES.
Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
SEV support to protect the guest register state from the hypervisor. See
"AMD64 Architecture Programmer's Manual Volume 2: System Programming",
section "15.35 Encrypted State (SEV-ES)" [1].
In order to allow a hypervisor to perform functions on behalf of a guest,
there is architectural support for notifying a guest's operating system
when certain types of VMEXITs are about to occur. This allows the guest to
selectively share information with the hypervisor to satisfy the requested
function. The notification is performed using a new exception, the VMM
Communication exception (#VC). The information is shared through the
Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT instruction.
The GHCB format and the protocol for using it is documented in "SEV-ES
Guest-Hypervisor Communication Block Standardization" [2].
The main areas of the EDK2 code that are updated to support SEV-ES are
around the exception handling support and the AP boot support.
Exception support is required starting in Sec, continuing through Pei
and into Dxe in order to handle #VC exceptions that are generated. Each
AP requires it's own GHCB page as well as a page to hold values specific
to that AP.
AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
is typically used to boot the APs. However, the hypervisor is not allowed
to update the guest registers. The GHCB document [2] talks about how SMP
booting under SEV-ES is performed.
Since the GHCB page must be a shared (unencrypted) page, the processor
must be running in long mode in order for the guest and hypervisor to
communicate with each other. As a result, SEV-ES is only supported under
the X64 architecture.
[1] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0
[2] https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
---
These patches are based on commit:
be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max failures")
Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
A version of the tree (with an extra patch to workaround Bugzilla 2340) can
be found at:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org<mailto:ard.biesheuvel@linaro.org>>
Cc: Benjamin You <benjamin.you@intel.com<mailto:benjamin.you@intel.com>>
Cc: Dandan Bi <dandan.bi@intel.com<mailto:dandan.bi@intel.com>>
Cc: Eric Dong <eric.dong@intel.com<mailto:eric.dong@intel.com>>
Cc: Guo Dong <guo.dong@intel.com<mailto:guo.dong@intel.com>>
Cc: Hao A Wu <hao.a.wu@intel.com<mailto:hao.a.wu@intel.com>>
Cc: Jian J Wang <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
Cc: Jordan Justen <jordan.l.justen@intel.com<mailto:jordan.l.justen@intel.com>>
Cc: Laszlo Ersek <lersek@redhat.com<mailto:lersek@redhat.com>>
Cc: Liming Gao <liming.gao@intel.com<mailto:liming.gao@intel.com>>
Cc: Maurice Ma <maurice.ma@intel.com<mailto:maurice.ma@intel.com>>
Cc: Michael D Kinney <michael.d.kinney@intel.com<mailto:michael.d.kinney@intel.com>>
Cc: Ray Ni <ray.ni@intel.com<mailto:ray.ni@intel.com>>
Changes since v6:
- Add function comments to all functions, including local functions
- Add function parameter direction to all functions (in/out)
- Add support for MMIO MOVZX/MOVSX instructions
- Ensure the per-CPU variable page remains encrypted
- Coding-style fixes as identified by Ecc
Changes since v5:
- Remove extraneous VmgExitLib usage
- Miscellaneous changes to address feedback (coding style, etc.)
Changes since v4:
- Move the SEV-ES protocol negotiation out of the SEC exception handler
and into the SecMain.c file. As a result:
- Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
- Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
single AMDSevVcHandler.c
- Consolidate VmgExitLib usage into common LibraryClasses sections
- Add documentation comments to the VmgExitLib functions
Changes since v3:
- Remove the need for the MP library finalization routine. The AP
jump table address will be held by the hypervisor rather than
communicated via the GHCB MSR. This removes some fragility around
the UEFI to OS transition.
- Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
communicate the SEV-ES status, so that SEC CPU exception handling is
only established for an SEV-ES guest.
- Fix SMM build breakageAdd around QemuFlashPtrWrite().
- Fix SMM build breakage by adding VC exception support the SMM CPU
exception handling.
- Add memory fencing around the invocation of AsmVmgExit().
- Clarify comments around the SEV-ES AP reset RIP values and usage.
- Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
- Remove the 16-bit code selector definition from MdeModulePkg
Changes since v2:
- Added a way to locate the SEV-ES fixed AP RIP address for starting
AP's to avoid updating the actual flash image (build time location
that is identified with a GUID value).
- Create a VmgExit library to replace static inline functions.
- Move some PCDs to the appropriate packages
- Add support for writing to QEMU flash under SEV-ES
- Add additional MMIO opcode support
- Cleaned up the GHCB MSR CPUID protocol support
Changes since v1:
- Patches reworked to be more specific to the component/area being updated
and order of definition/usage
- Created a library for VMGEXIT-related functions to replace use of inline
functions
- Allocation method for GDT changed from AllocatePool to AllocatePages
- Early caching only enabled for SEV-ES guests
- Ensure AP loop mode set to halt loop mode for SEV-ES guests
- Reserved SEC GHCB-related memory areas when S3 is enabled
Tom Lendacky (43):
MdeModulePkg: Create PCDs to be used in support of SEV-ES
UefiCpuPkg: Create PCD to be used in support of SEV-ES
MdePkg: Add the MSR definition for the GHCB register
MdePkg: Add a structure definition for the GHCB
MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
MdePkg/BaseLib: Add support for the XGETBV instruction
MdePkg/BaseLib: Add support for the VMGEXIT instruction
UefiCpuPkg: Implement library support for VMGEXIT
OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
events
UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
events
UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
events
UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
events
OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
OvmfPkg: Add support to perform SEV-ES initialization
OvmfPkg: Create a GHCB page for use during Sec phase
OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
UefiCpuPkg: Create an SEV-ES workarea PCD
OvmfPkg: Reserve a page in memory for the SEV-ES usage
OvmfPkg/ResetVector: Add support for a 32-bit SEV check
OvmfPkg/Sec: Add #VC exception handling for Sec phase
OvmfPkg/Sec: Enable cache early to speed up booting
OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
SEV-ES is enabled
UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
enabled
UefiCpuPkg: Allow AP booting under SEV-ES
OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
OvmfPkg: Move the GHCB allocations into reserved memory
UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
MdeModulePkg/MdeModulePkg.dec | 9 +
OvmfPkg/OvmfPkg.dec | 9 +
UefiCpuPkg/UefiCpuPkg.dec | 17 +
OvmfPkg/OvmfPkgIa32.dsc | 6 +
OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
OvmfPkg/OvmfPkgX64.dsc | 6 +
OvmfPkg/OvmfXen.dsc | 1 +
UefiCpuPkg/UefiCpuPkg.dsc | 2 +
UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
OvmfPkg/OvmfPkgX64.fdf | 9 +
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
MdePkg/Library/BaseLib/BaseLib.inf | 4 +
OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
.../FvbServicesRuntimeDxe.inf | 2 +
OvmfPkg/ResetVector/ResetVector.inf | 8 +
OvmfPkg/Sec/SecMain.inf | 4 +
.../DxeCpuExceptionHandlerLib.inf | 5 +
.../PeiCpuExceptionHandlerLib.inf | 5 +
.../SecPeiCpuExceptionHandlerLib.inf | 5 +
.../SmmCpuExceptionHandlerLib.inf | 5 +
UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
.../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
MdePkg/Include/Library/BaseLib.h | 31 +
MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
.../QemuFlash.h | 13 +
UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
.../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
.../CpuExceptionCommon.h | 2 +
UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
.../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
.../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
.../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
.../MemEncryptSevLibInternal.c | 75 +-
OvmfPkg/PlatformPei/AmdSev.c | 89 +
OvmfPkg/PlatformPei/MemDetect.c | 23 +
.../QemuFlash.c | 23 +-
.../QemuFlashDxe.c | 22 +
.../QemuFlashSmm.c | 16 +
OvmfPkg/Sec/SecMain.c | 188 +-
UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
.../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
.../CpuExceptionCommon.c | 2 +-
.../Ia32/ArchAMDSevVcHandler.c | 38 +
.../PeiDxeSmmCpuException.c | 16 +
.../SecPeiCpuException.c | 16 +
.../X64/ArchAMDSevVcHandler.c | 1699 +++++++++++++++++
UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
MdeModulePkg/MdeModulePkg.uni | 8 +
MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
.../X64/ExceptionHandlerAsm.nasm | 17 +
UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
.../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
.../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
UefiCpuPkg/UefiCpuPkg.uni | 11 +
75 files changed, 4707 insertions(+), 102 deletions(-)
create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
[-- Attachment #2: Type: text/html, Size: 44668 bytes --]
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-11 5:24 ` Ni, Ray
@ 2020-05-12 14:59 ` Lendacky, Thomas
2020-05-14 13:10 ` Ni, Ray
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-12 14:59 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
On 5/11/20 12:24 AM, Ni, Ray wrote:
> Tom,
>
> I agree with the first issue. I am not quite clear on the second one.
In regards to the exception propagation, the hypervisor is allowed to
request an exception as part of the return information. For example, the
guest issues a RDMSR instruction for an invalid MSR. The hypervisor would
normally inject a #GP into the guest. With SEV-ES, the VC handler has to
do this. Hence the need to possibly propogate to other exception handlers
after handling the #VC.
>
> SourceLevelDebugPkg provides source level debugging support early in SEC
> through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
>
> It hooks all Intel SDM defined exceptions. It hooks INT32 additionally to
> support breaking from HOST.
>
> It doesn’t use CpuExceptionLib because it hooks in very early SEC phase.
>
> Can you use the same way?
I can look at trying to do something like this. I guess the source level
debug needs to be aware of all the exceptions, which is why it hooks all
them. The SEV-ES support is only concerned with the #VC exception. It just
seems like a lot of duplicated and extra code vs. checking for / handling
the #VC exception in the CpuExceptionHandler library.
My plan for v8 is/was to have a NULL VmgExitLib library, of which the #VC
handler would be part of the interface, with the CpuExceptionHandler
library invoking the #VC handler on #VC exception and having the OvmfPkg
provide a VmgExitLib library with all the functionality.
Thanks,
Tom
>
> Thanks,
> Ray
>
> *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of *Andrew
> Fish via groups.io
> *Sent:* Sunday, May 10, 2020 3:10 AM
> *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
> *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
> Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You,
> Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong,
> Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
> *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>
>
>
> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
> <mailto:thomas.lendacky@amd.com>> wrote:
>
> On 5/9/20 1:44 AM, Ni, Ray wrote:
>
> Tom,
>
>
> Hi Ray,
>
>
> I have a bit concern on your change that directly modifies
> CpuExceptionHandlerLib to handle
> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
> exception context for
> every exception. Any component which wants to do specific handling
> of certain exceptions
> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe
> driver:
> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
> DebugExceptionHandler);
> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
> PageFaultExceptionHandler);
> }
> Is it possible for your feature to follow the same pattern?
>
>
> There are two problems:
>
> The first is that RegisterCpuInterruptHandler() is not implemented for
> both the SEC and PEI phases, so it is not currently possible to
> register a handler that early.
>
> The second is that I need to be able to propagate an exception request
> from the hypervisor. With the current implementation there doesn't
> appear to be an easy way to perform this propagation.
>
> If there's a way to accomplish both of the above I wouldn't be opposed
> to using RegisterCpuInterruptHandler() as long as there are no #VCs
> that can occur between initializing exception handling and and
> registering the #VC handler.
>
> Thomas,
>
> As you point out it is tricky dealing with XIP code. You can't have
> globals that you can write and generally you use a PEI service to look
> tings up, the most common thing being using a HOB. But SEC has no services
> and I'm not sure you really want to be calling into the PEI Core on a
> random exception.
>
> Here are the best options that popped into my head after reading your email
>
> 1) IDT in RAM
>
> If your code populates the IDT the IDTR gives you access to the address of
> the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for
> a cached copy of the PEI Services Table, but otther than that you are good
> to go. It should be possible to have a global so you can have the table
> required to implement RegisterCpuInterruptHandler(). There might be some
> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data
> after the IDT would be a good option. In general if your code allocates
> the memory for the IDT then you can treat the IDT as part of your private
> context data structure and that gives you access
>
> 2) IDT in ROM.
>
> For this it seems like you need a library to link in to
> the CpuExceptionHandlerLib that allows you to override the handler. If
> CpuInterruptHandlerOverride() returns NULL you do the current behavior if
> not NULL then you call the returned handler.
>
> EFI_CPU_INTERRUPT_HANDLER
>
> EFIAPI
>
> OverrideCpuInterruptHandler (
>
> IN EFI_EXCEPTION_TYPE InterruptType
>
> );
>
> Thanks,
>
> Andrew Fish
>
> PS Off topic, but it would also be useful to have a library that overrides
> the state dump display. For example using Xcode you can always display a
> stack frame from the exception handler.
>
>
>
> Thanks,
> Tom
>
>
> Thanks,
> Ray
>
> -----Original Message-----
> From: Tom Lendacky <thomas.lendacky@amd.com
> <mailto:thomas.lendacky@amd.com>>
> Sent: Saturday, May 9, 2020 3:16 AM
> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
> Cc: Justen, Jordan L <jordan.l.justen@intel.com
> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
> <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org
> <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
> <michael.d.kinney@intel.com
> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni,
> Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh
> Singh <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>;
> You, Benjamin
> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi,
> Dandan <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>;
> Dong, Guo <guo.dong@intel.com <mailto:guo.dong@intel.com>>;
> Wu, Hao A
> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma,
> Maurice <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>
> I was able to use the pull request method that Laszlo
> documented and fixed
> up all of the issues identified by the VS compiler.
>
> An additional change I'm planning to make for the next version
> (v8) of the
> patches is to create a NULL library instance of the VmgExitLib
> that will
> also include the #VC handler function. This will reduce the
> amount of code
> associated with this feature for platforms that don't
> use/support SEV-ES.
>
> Laszlo, this will mean that I will introduce a version of the
> VmgExitLib
> under OvmfPkg that will provide the majority of the
> functionality that is
> present today in UefiCpuPkg. In essence, the functionality in
> v7 patches 8
> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg.
> I think
> this is the better way to do this. Let me know if you have any
> concerns.
>
> Thanks,
> Tom
>
> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>
> This patch series provides support for running EDK2/OVMF
> under SEV-ES.
>
> Secure Encrypted Virtualization - Encrypted State (SEV-ES)
> expands on the
> SEV support to protect the guest register state from the
> hypervisor. See
> "AMD64 Architecture Programmer's Manual Volume 2: System
> Programming",
> section "15.35 Encrypted State (SEV-ES)" [1].
>
> In order to allow a hypervisor to perform functions on
> behalf of a guest,
> there is architectural support for notifying a guest's
> operating system
> when certain types of VMEXITs are about to occur. This
> allows the guest to
> selectively share information with the hypervisor to
> satisfy the requested
> function. The notification is performed using a new
> exception, the VMM
> Communication exception (#VC). The information is shared
> through the
> Guest-Hypervisor Communication Block (GHCB) using the
> VMGEXIT instruction.
> The GHCB format and the protocol for using it is
> documented in "SEV-ES
> Guest-Hypervisor Communication Block Standardization" [2].
>
> The main areas of the EDK2 code that are updated to
> support SEV-ES are
> around the exception handling support and the AP boot support.
>
> Exception support is required starting in Sec, continuing
> through Pei
> and into Dxe in order to handle #VC exceptions that are
> generated. Each
> AP requires it's own GHCB page as well as a page to hold
> values specific
> to that AP.
>
> AP booting poses some interesting challenges. The
> INIT-SIPI-SIPI sequence
> is typically used to boot the APs. However, the hypervisor
> is not allowed
> to update the guest registers. The GHCB document [2] talks
> about how SMP
> booting under SEV-ES is performed.
>
> Since the GHCB page must be a shared (unencrypted) page,
> the processor
> must be running in long mode in order for the guest and
> hypervisor to
> communicate with each other. As a result, SEV-ES is only
> supported under
> the X64 architecture.
>
> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8lyZo0%3D&reserved=0>
> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4BNIeKe0Of4K5Kuix4%3D&reserved=0>
>
> ---
>
> These patches are based on commit:
> be7295b36405 (".python/SpellCheck: Increase SpellCheck
> plugin max failures")
>
> Proper execution of SEV-ES relies on Bugzilla 2340 being
> fixed.
>
> A version of the tree (with an extra patch to workaround
> Bugzilla 2340) can
> be found at:
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F6vqMg%3D&reserved=0>
>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
> <mailto:ard.biesheuvel@linaro.org>>
> Cc: Benjamin You <benjamin.you@intel.com
> <mailto:benjamin.you@intel.com>>
> Cc: Dandan Bi <dandan.bi@intel.com
> <mailto:dandan.bi@intel.com>>
> Cc: Eric Dong <eric.dong@intel.com
> <mailto:eric.dong@intel.com>>
> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
> Cc: Jian J Wang <jian.j.wang@intel.com
> <mailto:jian.j.wang@intel.com>>
> Cc: Jordan Justen <jordan.l.justen@intel.com
> <mailto:jordan.l.justen@intel.com>>
> Cc: Laszlo Ersek <lersek@redhat.com
> <mailto:lersek@redhat.com>>
> Cc: Liming Gao <liming.gao@intel.com
> <mailto:liming.gao@intel.com>>
> Cc: Maurice Ma <maurice.ma@intel.com
> <mailto:maurice.ma@intel.com>>
> Cc: Michael D Kinney <michael.d.kinney@intel.com
> <mailto:michael.d.kinney@intel.com>>
> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>
> Changes since v6:
> - Add function comments to all functions, including local
> functions
> - Add function parameter direction to all functions (in/out)
> - Add support for MMIO MOVZX/MOVSX instructions
> - Ensure the per-CPU variable page remains encrypted
> - Coding-style fixes as identified by Ecc
>
> Changes since v5:
> - Remove extraneous VmgExitLib usage
> - Miscellaneous changes to address feedback (coding style,
> etc.)
>
> Changes since v4:
> - Move the SEV-ES protocol negotiation out of the SEC
> exception handler
> and into the SecMain.c file. As a result:
> - Move the SecGhcb related PCDs out of UefiCpuPkg and
> into OvmfPkg
> - Combine SecAMDSevVcHandler.c and
> PeiDxeAMDSevVcHandler.c into a
> single AMDSevVcHandler.c
> - Consolidate VmgExitLib usage into common LibraryClasses
> sections
> - Add documentation comments to the VmgExitLib functions
>
> Changes since v3:
> - Remove the need for the MP library finalization routine.
> The AP
> jump table address will be held by the hypervisor
> rather than
> communicated via the GHCB MSR. This removes some
> fragility around
> the UEFI to OS transition.
> - Rename the SEV-ES RIP reset area to SEV-ES workarea and
> use it to
> communicate the SEV-ES status, so that SEC CPU
> exception handling is
> only established for an SEV-ES guest.
> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
> - Fix SMM build breakage by adding VC exception support
> the SMM CPU
> exception handling.
> - Add memory fencing around the invocation of AsmVmgExit().
> - Clarify comments around the SEV-ES AP reset RIP values
> and usage.
> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
> - Remove the 16-bit code selector definition from MdeModulePkg
>
> Changes since v2:
> - Added a way to locate the SEV-ES fixed AP RIP address
> for starting
> AP's to avoid updating the actual flash image (build
> time location
> that is identified with a GUID value).
> - Create a VmgExit library to replace static inline functions.
> - Move some PCDs to the appropriate packages
> - Add support for writing to QEMU flash under SEV-ES
> - Add additional MMIO opcode support
> - Cleaned up the GHCB MSR CPUID protocol support
>
> Changes since v1:
> - Patches reworked to be more specific to the
> component/area being updated
> and order of definition/usage
> - Created a library for VMGEXIT-related functions to
> replace use of inline
> functions
> - Allocation method for GDT changed from AllocatePool to
> AllocatePages
> - Early caching only enabled for SEV-ES guests
> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
> - Reserved SEC GHCB-related memory areas when S3 is enabled
>
> Tom Lendacky (43):
> MdeModulePkg: Create PCDs to be used in support of SEV-ES
> UefiCpuPkg: Create PCD to be used in support of SEV-ES
> MdePkg: Add the MSR definition for the GHCB register
> MdePkg: Add a structure definition for the GHCB
> MdeModulePkg/DxeIplPeim: Support GHCB pages when
> creating page tables
> MdePkg/BaseLib: Add support for the XGETBV instruction
> MdePkg/BaseLib: Add support for the VMGEXIT instruction
> UefiCpuPkg: Implement library support for VMGEXIT
> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
> UefiPayloadPkg: Prepare UefiPayloadPkg to use the
> VmgExitLib library
> UefiCpuPkg/CpuExceptionHandler: Add base support for
> the #VC exception
> UefiCpuPkg/CpuExceptionHandler: Add support for
> IOIO_PROT NAE events
> UefiCpuPkg/CpuExceptionHandler: Support string IO for
> IOIO_PROT NAE
> events
> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID
> NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for
> MSR_PROT NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for NPF
> NAE events (MMIO)
> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD
> NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC
> NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC
> NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for INVD
> NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for
> VMMCALL NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP
> NAE events
> UefiCpuPkg/CpuExceptionHandler: Add support for
> MONITOR/MONITORX NAE
> events
> UefiCpuPkg/CpuExceptionHandler: Add support for
> MWAIT/MWAITX NAE
> events
> UefiCpuPkg/CpuExceptionHandler: Add support for DR7
> Read/Write NAE
> events
> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
> indicator function
> OvmfPkg: Add support to perform SEV-ES initialization
> OvmfPkg: Create a GHCB page for use during Sec phase
> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3
> is supported
> OvmfPkg: Create GHCB pages for use during Pei and Dxe
> phase
> OvmfPkg/PlatformPei: Move early GDT into ram when
> SEV-ES is enabled
> UefiCpuPkg: Create an SEV-ES workarea PCD
> OvmfPkg: Reserve a page in memory for the SEV-ES usage
> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
> OvmfPkg/Sec: Add #VC exception handling for Sec phase
> OvmfPkg/Sec: Enable cache early to speed up booting
> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash
> detection with
> SEV-ES is enabled
> UefiCpuPkg: Add a 16-bit protected mode code segment
> descriptor
> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate
> if SEV-ES is
> enabled
> UefiCpuPkg: Allow AP booting under SEV-ES
> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP
> reset vector
> OvmfPkg: Move the GHCB allocations into reserved memory
> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>
> MdeModulePkg/MdeModulePkg.dec | 9 +
> OvmfPkg/OvmfPkg.dec | 9 +
> UefiCpuPkg/UefiCpuPkg.dec | 17 +
> OvmfPkg/OvmfPkgIa32.dsc | 6 +
> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
> OvmfPkg/OvmfPkgX64.dsc | 6 +
> OvmfPkg/OvmfXen.dsc | 1 +
> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
> OvmfPkg/OvmfPkgX64.fdf | 9 +
> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
> .../FvbServicesRuntimeDxe.inf | 2 +
> OvmfPkg/ResetVector/ResetVector.inf | 8 +
> OvmfPkg/Sec/SecMain.inf | 4 +
> .../DxeCpuExceptionHandlerLib.inf | 5 +
> .../PeiCpuExceptionHandlerLib.inf | 5 +
> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
> .../SmmCpuExceptionHandlerLib.inf | 5 +
> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
> MdePkg/Include/Library/BaseLib.h | 31 +
> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
> .../QemuFlash.h | 13 +
> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
> .../CpuExceptionCommon.h | 2 +
> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
> .../MemEncryptSevLibInternal.c | 75 +-
> OvmfPkg/PlatformPei/AmdSev.c | 89 +
> OvmfPkg/PlatformPei/MemDetect.c | 23 +
> .../QemuFlash.c | 23 +-
> .../QemuFlashDxe.c | 22 +
> .../QemuFlashSmm.c | 16 +
> OvmfPkg/Sec/SecMain.c | 188 +-
> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
> .../CpuExceptionCommon.c | 2 +-
> .../Ia32/ArchAMDSevVcHandler.c | 38 +
> .../PeiDxeSmmCpuException.c | 16 +
> .../SecPeiCpuException.c | 16 +
> .../X64/ArchAMDSevVcHandler.c | 1699
> +++++++++++++++++
> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
> MdeModulePkg/MdeModulePkg.uni | 8 +
> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
> .../X64/ExceptionHandlerAsm.nasm | 17 +
> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
> UefiCpuPkg/UefiCpuPkg.uni | 11 +
> 75 files changed, 4707 insertions(+), 102 deletions(-)
> create mode 100644
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
> create mode 100644
> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
> create mode 100644
> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
> create mode 100644
> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
> create mode 100644
> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
> create mode 100644
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
> create mode 100644
> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> create mode 100644
> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>
>
>
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-12 14:59 ` Lendacky, Thomas
@ 2020-05-14 13:10 ` Ni, Ray
2020-05-14 17:59 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Ni, Ray @ 2020-05-14 13:10 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice, Fan Jeff
Tom,
I just discussed with original CPU owner Jeff and went through how IDT is setup in the boot flow.
Here is what I think you can do to avoid modifying the CpuExceptionHandlerLib.
1. SecPlatformMain() modifies IDT[29] to point to your VC handler. This step helps to build the VC handler in whole 32bit mode SEC+PEI.
2. Create a new DXE driver with dependency set to TRUE and call RegisterCpuInteruptHandler(29, xx) in its entrypoint to register VC handler for whole 64bit mode DXE.
3. Platform FDF uses apriori file mechanism to make sure the driver created in step #2 is dispatched as the 1st driver in DXE phase. This step is optional if you accept there is some time that VC handler is not setup in early DXE phase.
4. In the new DXE driver, gets the EFI_VECTOR_HANDOFF_INFO (MdePkg\Include\Ppi\VectorHandoffInfo.h) from configuration table.
It reports failure if the vector_handoff table says DO_NOT_HOOK for #29.
It re-produces vector_handoff table with #29 set to DO_NOT_HOOK so that no one could use CpuArch protocol to override #29 handler.
In general, I want to use the API/capability provided by CpuExceptionHandlerLib instead of directly modifying it for handler registration.
Directly modifying it gives an improper code reference/example for future developers.
Thanks,
Ray
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
> Sent: Tuesday, May 12, 2020 11:00 PM
> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi,
> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>
> On 5/11/20 12:24 AM, Ni, Ray wrote:
> > Tom,
> >
> > I agree with the first issue. I am not quite clear on the second one.
>
> In regards to the exception propagation, the hypervisor is allowed to
> request an exception as part of the return information. For example, the
> guest issues a RDMSR instruction for an invalid MSR. The hypervisor would
> normally inject a #GP into the guest. With SEV-ES, the VC handler has to
> do this. Hence the need to possibly propogate to other exception handlers
> after handling the #VC.
>
> >
> > SourceLevelDebugPkg provides source level debugging support early in SEC
> > through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
> >
> > It hooks all Intel SDM defined exceptions. It hooks INT32 additionally to
> > support breaking from HOST.
> >
> > It doesn't use CpuExceptionLib because it hooks in very early SEC phase.
> >
> > Can you use the same way?
>
> I can look at trying to do something like this. I guess the source level
> debug needs to be aware of all the exceptions, which is why it hooks all
> them. The SEV-ES support is only concerned with the #VC exception. It just
> seems like a lot of duplicated and extra code vs. checking for / handling
> the #VC exception in the CpuExceptionHandler library.
>
> My plan for v8 is/was to have a NULL VmgExitLib library, of which the #VC
> handler would be part of the interface, with the CpuExceptionHandler
> library invoking the #VC handler on #VC exception and having the OvmfPkg
> provide a VmgExitLib library with all the functionality.
>
> Thanks,
> Tom
>
> >
> > Thanks,
> > Ray
> >
> > *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of *Andrew
> > Fish via groups.io
> > *Sent:* Sunday, May 10, 2020 3:10 AM
> > *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
> > *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
> > <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
> > Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> > Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You,
> > Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong,
> > Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
> > <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
> > *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
> >
> >
> >
> > On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
> > <mailto:thomas.lendacky@amd.com>> wrote:
> >
> > On 5/9/20 1:44 AM, Ni, Ray wrote:
> >
> > Tom,
> >
> >
> > Hi Ray,
> >
> >
> > I have a bit concern on your change that directly modifies
> > CpuExceptionHandlerLib to handle
> > exception #29. Today's CpuExceptionHandlerLib simplify dumps the
> > exception context for
> > every exception. Any component which wants to do specific handling
> > of certain exceptions
> > should call RegisterCpuInterruptHandler(). Such as code in CpuDxe
> > driver:
> > if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
> > RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
> > DebugExceptionHandler);
> > RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
> > PageFaultExceptionHandler);
> > }
> > Is it possible for your feature to follow the same pattern?
> >
> >
> > There are two problems:
> >
> > The first is that RegisterCpuInterruptHandler() is not implemented for
> > both the SEC and PEI phases, so it is not currently possible to
> > register a handler that early.
> >
> > The second is that I need to be able to propagate an exception request
> > from the hypervisor. With the current implementation there doesn't
> > appear to be an easy way to perform this propagation.
> >
> > If there's a way to accomplish both of the above I wouldn't be opposed
> > to using RegisterCpuInterruptHandler() as long as there are no #VCs
> > that can occur between initializing exception handling and and
> > registering the #VC handler.
> >
> > Thomas,
> >
> > As you point out it is tricky dealing with XIP code. You can't have
> > globals that you can write and generally you use a PEI service to look
> > tings up, the most common thing being using a HOB. But SEC has no services
> > and I'm not sure you really want to be calling into the PEI Core on a
> > random exception.
> >
> > Here are the best options that popped into my head after reading your email
> >
> > 1) IDT in RAM
> >
> > If your code populates the IDT the IDTR gives you access to the address of
> > the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for
> > a cached copy of the PEI Services Table, but otther than that you are good
> > to go. It should be possible to have a global so you can have the table
> > required to implement RegisterCpuInterruptHandler(). There might be some
> > usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data
> > after the IDT would be a good option. In general if your code allocates
> > the memory for the IDT then you can treat the IDT as part of your private
> > context data structure and that gives you access
> >
> > 2) IDT in ROM.
> >
> > For this it seems like you need a library to link in to
> > the CpuExceptionHandlerLib that allows you to override the handler. If
> > CpuInterruptHandlerOverride() returns NULL you do the current behavior if
> > not NULL then you call the returned handler.
> >
> > EFI_CPU_INTERRUPT_HANDLER
> >
> > EFIAPI
> >
> > OverrideCpuInterruptHandler (
> >
> > IN EFI_EXCEPTION_TYPE InterruptType
> >
> > );
> >
> > Thanks,
> >
> > Andrew Fish
> >
> > PS Off topic, but it would also be useful to have a library that overrides
> > the state dump display. For example using Xcode you can always display a
> > stack frame from the exception handler.
> >
> >
> >
> > Thanks,
> > Tom
> >
> >
> > Thanks,
> > Ray
> >
> > -----Original Message-----
> > From: Tom Lendacky <thomas.lendacky@amd.com
> > <mailto:thomas.lendacky@amd.com>>
> > Sent: Saturday, May 9, 2020 3:16 AM
> > To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
> > Cc: Justen, Jordan L <jordan.l.justen@intel.com
> > <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
> > <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard Biesheuvel
> > <ard.biesheuvel@linaro.org
> > <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
> > <michael.d.kinney@intel.com
> > <mailto:michael.d.kinney@intel.com>>; Gao, Liming
> > <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
> > Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni,
> > Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh
> > Singh <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>;
> > You, Benjamin
> > <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi,
> > Dandan <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>;
> > Dong, Guo <guo.dong@intel.com <mailto:guo.dong@intel.com>>;
> > Wu, Hao A
> > <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
> > <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma,
> > Maurice <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
> > Subject: Re: [PATCH v7 00/43] SEV-ES guest support
> >
> > I was able to use the pull request method that Laszlo
> > documented and fixed
> > up all of the issues identified by the VS compiler.
> >
> > An additional change I'm planning to make for the next version
> > (v8) of the
> > patches is to create a NULL library instance of the VmgExitLib
> > that will
> > also include the #VC handler function. This will reduce the
> > amount of code
> > associated with this feature for platforms that don't
> > use/support SEV-ES.
> >
> > Laszlo, this will mean that I will introduce a version of the
> > VmgExitLib
> > under OvmfPkg that will provide the majority of the
> > functionality that is
> > present today in UefiCpuPkg. In essence, the functionality in
> > v7 patches 8
> > and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg.
> > I think
> > this is the better way to do this. Let me know if you have any
> > concerns.
> >
> > Thanks,
> > Tom
> >
> > On 4/22/20 12:41 PM, Tom Lendacky wrote:
> >
> > This patch series provides support for running EDK2/OVMF
> > under SEV-ES.
> >
> > Secure Encrypted Virtualization - Encrypted State (SEV-ES)
> > expands on the
> > SEV support to protect the guest register state from the
> > hypervisor. See
> > "AMD64 Architecture Programmer's Manual Volume 2: System
> > Programming",
> > section "15.35 Encrypted State (SEV-ES)" [1].
> >
> > In order to allow a hypervisor to perform functions on
> > behalf of a guest,
> > there is architectural support for notifying a guest's
> > operating system
> > when certain types of VMEXITs are about to occur. This
> > allows the guest to
> > selectively share information with the hypervisor to
> > satisfy the requested
> > function. The notification is performed using a new
> > exception, the VMM
> > Communication exception (#VC). The information is shared
> > through the
> > Guest-Hypervisor Communication Block (GHCB) using the
> > VMGEXIT instruction.
> > The GHCB format and the protocol for using it is
> > documented in "SEV-ES
> > Guest-Hypervisor Communication Block Standardization" [2].
> >
> > The main areas of the EDK2 code that are updated to
> > support SEV-ES are
> > around the exception handling support and the AP boot support.
> >
> > Exception support is required starting in Sec, continuing
> > through Pei
> > and into Dxe in order to handle #VC exceptions that are
> > generated. Each
> > AP requires it's own GHCB page as well as a page to hold
> > values specific
> > to that AP.
> >
> > AP booting poses some interesting challenges. The
> > INIT-SIPI-SIPI sequence
> > is typically used to boot the APs. However, the hypervisor
> > is not allowed
> > to update the guest registers. The GHCB document [2] talks
> > about how SMP
> > booting under SEV-ES is performed.
> >
> > Since the GHCB page must be a shared (unencrypted) page,
> > the processor
> > must be running in long mode in order for the guest and
> > hypervisor to
> > communicate with each other. As a result, SEV-ES is only
> > supported under
> > the X64 architecture.
> >
> >
> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%
> 2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe
> 4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCid
> wLMl5c%3D&reserved=0
> >
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2
> F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884
> e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8
> lyZo0%3D&reserved=0>
> > [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f
> 3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2
> XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
> > <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56b
> a3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4B
> NIeKe0Of4K5Kuix4%3D&reserved=0>
> >
> > ---
> >
> > These patches are based on commit:
> > be7295b36405 (".python/SpellCheck: Increase SpellCheck
> > plugin max failures")
> >
> > Proper execution of SEV-ES relies on Bugzilla 2340 being
> > fixed.
> >
> > A version of the tree (with an extra patch to workaround
> > Bugzilla 2340) can
> > be found at:
> >
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-
> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e60
> 8e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedv
> E%3D&reserved=0
> >
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
> es-
> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e1
> 1a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F
> 6vqMg%3D&reserved=0>
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
> > <mailto:ard.biesheuvel@linaro.org>>
> > Cc: Benjamin You <benjamin.you@intel.com
> > <mailto:benjamin.you@intel.com>>
> > Cc: Dandan Bi <dandan.bi@intel.com
> > <mailto:dandan.bi@intel.com>>
> > Cc: Eric Dong <eric.dong@intel.com
> > <mailto:eric.dong@intel.com>>
> > Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
> > Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
> > Cc: Jian J Wang <jian.j.wang@intel.com
> > <mailto:jian.j.wang@intel.com>>
> > Cc: Jordan Justen <jordan.l.justen@intel.com
> > <mailto:jordan.l.justen@intel.com>>
> > Cc: Laszlo Ersek <lersek@redhat.com
> > <mailto:lersek@redhat.com>>
> > Cc: Liming Gao <liming.gao@intel.com
> > <mailto:liming.gao@intel.com>>
> > Cc: Maurice Ma <maurice.ma@intel.com
> > <mailto:maurice.ma@intel.com>>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com
> > <mailto:michael.d.kinney@intel.com>>
> > Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
> >
> > Changes since v6:
> > - Add function comments to all functions, including local
> > functions
> > - Add function parameter direction to all functions (in/out)
> > - Add support for MMIO MOVZX/MOVSX instructions
> > - Ensure the per-CPU variable page remains encrypted
> > - Coding-style fixes as identified by Ecc
> >
> > Changes since v5:
> > - Remove extraneous VmgExitLib usage
> > - Miscellaneous changes to address feedback (coding style,
> > etc.)
> >
> > Changes since v4:
> > - Move the SEV-ES protocol negotiation out of the SEC
> > exception handler
> > and into the SecMain.c file. As a result:
> > - Move the SecGhcb related PCDs out of UefiCpuPkg and
> > into OvmfPkg
> > - Combine SecAMDSevVcHandler.c and
> > PeiDxeAMDSevVcHandler.c into a
> > single AMDSevVcHandler.c
> > - Consolidate VmgExitLib usage into common LibraryClasses
> > sections
> > - Add documentation comments to the VmgExitLib functions
> >
> > Changes since v3:
> > - Remove the need for the MP library finalization routine.
> > The AP
> > jump table address will be held by the hypervisor
> > rather than
> > communicated via the GHCB MSR. This removes some
> > fragility around
> > the UEFI to OS transition.
> > - Rename the SEV-ES RIP reset area to SEV-ES workarea and
> > use it to
> > communicate the SEV-ES status, so that SEC CPU
> > exception handling is
> > only established for an SEV-ES guest.
> > - Fix SMM build breakageAdd around QemuFlashPtrWrite().
> > - Fix SMM build breakage by adding VC exception support
> > the SMM CPU
> > exception handling.
> > - Add memory fencing around the invocation of AsmVmgExit().
> > - Clarify comments around the SEV-ES AP reset RIP values
> > and usage.
> > - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
> > - Remove the 16-bit code selector definition from MdeModulePkg
> >
> > Changes since v2:
> > - Added a way to locate the SEV-ES fixed AP RIP address
> > for starting
> > AP's to avoid updating the actual flash image (build
> > time location
> > that is identified with a GUID value).
> > - Create a VmgExit library to replace static inline functions.
> > - Move some PCDs to the appropriate packages
> > - Add support for writing to QEMU flash under SEV-ES
> > - Add additional MMIO opcode support
> > - Cleaned up the GHCB MSR CPUID protocol support
> >
> > Changes since v1:
> > - Patches reworked to be more specific to the
> > component/area being updated
> > and order of definition/usage
> > - Created a library for VMGEXIT-related functions to
> > replace use of inline
> > functions
> > - Allocation method for GDT changed from AllocatePool to
> > AllocatePages
> > - Early caching only enabled for SEV-ES guests
> > - Ensure AP loop mode set to halt loop mode for SEV-ES guests
> > - Reserved SEC GHCB-related memory areas when S3 is enabled
> >
> > Tom Lendacky (43):
> > MdeModulePkg: Create PCDs to be used in support of SEV-ES
> > UefiCpuPkg: Create PCD to be used in support of SEV-ES
> > MdePkg: Add the MSR definition for the GHCB register
> > MdePkg: Add a structure definition for the GHCB
> > MdeModulePkg/DxeIplPeim: Support GHCB pages when
> > creating page tables
> > MdePkg/BaseLib: Add support for the XGETBV instruction
> > MdePkg/BaseLib: Add support for the VMGEXIT instruction
> > UefiCpuPkg: Implement library support for VMGEXIT
> > OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
> > UefiPayloadPkg: Prepare UefiPayloadPkg to use the
> > VmgExitLib library
> > UefiCpuPkg/CpuExceptionHandler: Add base support for
> > the #VC exception
> > UefiCpuPkg/CpuExceptionHandler: Add support for
> > IOIO_PROT NAE events
> > UefiCpuPkg/CpuExceptionHandler: Support string IO for
> > IOIO_PROT NAE
> > events
> > UefiCpuPkg/CpuExceptionHandler: Add support for CPUID
> > NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for
> > MSR_PROT NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for NPF
> > NAE events (MMIO)
> > UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD
> > NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC
> > NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC
> > NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for INVD
> > NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for
> > VMMCALL NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP
> > NAE events
> > UefiCpuPkg/CpuExceptionHandler: Add support for
> > MONITOR/MONITORX NAE
> > events
> > UefiCpuPkg/CpuExceptionHandler: Add support for
> > MWAIT/MWAITX NAE
> > events
> > UefiCpuPkg/CpuExceptionHandler: Add support for DR7
> > Read/Write NAE
> > events
> > OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
> > indicator function
> > OvmfPkg: Add support to perform SEV-ES initialization
> > OvmfPkg: Create a GHCB page for use during Sec phase
> > OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3
> > is supported
> > OvmfPkg: Create GHCB pages for use during Pei and Dxe
> > phase
> > OvmfPkg/PlatformPei: Move early GDT into ram when
> > SEV-ES is enabled
> > UefiCpuPkg: Create an SEV-ES workarea PCD
> > OvmfPkg: Reserve a page in memory for the SEV-ES usage
> > OvmfPkg/ResetVector: Add support for a 32-bit SEV check
> > OvmfPkg/Sec: Add #VC exception handling for Sec phase
> > OvmfPkg/Sec: Enable cache early to speed up booting
> > OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash
> > detection with
> > SEV-ES is enabled
> > UefiCpuPkg: Add a 16-bit protected mode code segment
> > descriptor
> > UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate
> > if SEV-ES is
> > enabled
> > UefiCpuPkg: Allow AP booting under SEV-ES
> > OvmfPkg: Use the SEV-ES work area for the SEV-ES AP
> > reset vector
> > OvmfPkg: Move the GHCB allocations into reserved memory
> > UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
> >
> > MdeModulePkg/MdeModulePkg.dec | 9 +
> > OvmfPkg/OvmfPkg.dec | 9 +
> > UefiCpuPkg/UefiCpuPkg.dec | 17 +
> > OvmfPkg/OvmfPkgIa32.dsc | 6 +
> > OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
> > OvmfPkg/OvmfPkgX64.dsc | 6 +
> > OvmfPkg/OvmfXen.dsc | 1 +
> > UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> > UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
> > UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
> > OvmfPkg/OvmfPkgX64.fdf | 9 +
> > MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
> > MdePkg/Library/BaseLib/BaseLib.inf | 4 +
> > OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
> > .../FvbServicesRuntimeDxe.inf | 2 +
> > OvmfPkg/ResetVector/ResetVector.inf | 8 +
> > OvmfPkg/Sec/SecMain.inf | 4 +
> > .../DxeCpuExceptionHandlerLib.inf | 5 +
> > .../PeiCpuExceptionHandlerLib.inf | 5 +
> > .../SecPeiCpuExceptionHandlerLib.inf | 5 +
> > .../SmmCpuExceptionHandlerLib.inf | 5 +
> > UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
> > UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
> > .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
> > MdePkg/Include/Library/BaseLib.h | 31 +
> > MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
> > MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
> > OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
> > .../QemuFlash.h | 13 +
> > UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
> > UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
> > .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
> > .../CpuExceptionCommon.h | 2 +
> > UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
> > .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
> > .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
> > .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
> > MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
> > MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
> > .../MemEncryptSevLibInternal.c | 75 +-
> > OvmfPkg/PlatformPei/AmdSev.c | 89 +
> > OvmfPkg/PlatformPei/MemDetect.c | 23 +
> > .../QemuFlash.c | 23 +-
> > .../QemuFlashDxe.c | 22 +
> > .../QemuFlashSmm.c | 16 +
> > OvmfPkg/Sec/SecMain.c | 188 +-
> > UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
> > .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
> > .../CpuExceptionCommon.c | 2 +-
> > .../Ia32/ArchAMDSevVcHandler.c | 38 +
> > .../PeiDxeSmmCpuException.c | 16 +
> > .../SecPeiCpuException.c | 16 +
> > .../X64/ArchAMDSevVcHandler.c | 1699
> > +++++++++++++++++
> > UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
> > UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
> > UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
> > UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
> > MdeModulePkg/MdeModulePkg.uni | 8 +
> > MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
> > MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
> > MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
> > MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
> > OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
> > OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
> > OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
> > .../X64/ExceptionHandlerAsm.nasm | 17 +
> > UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
> > .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
> > UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
> > UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
> > .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
> > UefiCpuPkg/UefiCpuPkg.uni | 11 +
> > 75 files changed, 4707 insertions(+), 102 deletions(-)
> > create mode 100644
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> > create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
> > create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
> > create mode 100644
> > UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
> > create mode 100644
> > UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
> > create mode 100644
> > UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
> > create mode 100644
> > UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
> > create mode 100644
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> > create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
> > create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> > create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
> > create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
> > create mode 100644
> > OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> > create mode 100644
> > UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
> >
> >
> >
> >
> >
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-14 13:10 ` Ni, Ray
@ 2020-05-14 17:59 ` Lendacky, Thomas
2020-05-15 5:47 ` Ni, Ray
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-14 17:59 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice, Fan Jeff
On 5/14/20 8:10 AM, Ni, Ray wrote:
> Tom,
Hi Ray,
> I just discussed with original CPU owner Jeff and went through how IDT is setup in the boot flow.
> Here is what I think you can do to avoid modifying the CpuExceptionHandlerLib.
> 1. SecPlatformMain() modifies IDT[29] to point to your VC handler. This step helps to build the VC handler in whole 32bit mode SEC+PEI.
That can probably be done, but duplicates a lot of code - all of the
exception entry assembler code.
Additionally, UefiCpuPkg/CpuMpPei/CpuMpPei.c will also invoke
InitializeCpuExceptionHandlers() registering a new IDT[29] entry.
> 2. Create a new DXE driver with dependency set to TRUE and call RegisterCpuInteruptHandler(29, xx) in its entrypoint to register VC handler for whole 64bit mode DXE.
> 3. Platform FDF uses apriori file mechanism to make sure the driver created in step #2 is dispatched as the 1st driver in DXE phase. This step is optional if you accept there is some time that VC handler is not setup in early DXE phase.
Tracing the execution of an apriori driver shows that this happens after
DXE has initialized its exception handler and #VCs occur before a handler
can be reigstered by the new driver, causing a failure.
> 4. In the new DXE driver, gets the EFI_VECTOR_HANDOFF_INFO (MdePkg\Include\Ppi\VectorHandoffInfo.h) from configuration table.
> It reports failure if the vector_handoff table says DO_NOT_HOOK for #29.
> It re-produces vector_handoff table with #29 set to DO_NOT_HOOK so that no one could use CpuArch protocol to override #29 handler.
>
>
> In general, I want to use the API/capability provided by CpuExceptionHandlerLib instead of directly modifying it for handler registration.
> Directly modifying it gives an improper code reference/example for future developers.
I also don't see how this method will allow me to easily propagate a new
exception value through the exception handling stack.
My current plan was to create a CpuExceptionOverrideLib library that is
invoked as part of exception handling. This allows immediate ability to
hook any exception without having to wait for an opportunity to register a
handler - which in the case of #VC, is too late. Future developers that
need immediate exception handling will be able to override the default
library without any modification to CpuExceptionHandlerLib.
The change would look something like this:
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index 20148db74cf8..7ac86f56d7d2 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/CpuExceptionOverrideLib.h>
#include "CpuExceptionCommon.h"
CONST UINTN mDoFarReturnFlag = 0;
@@ -24,6 +25,22 @@ CommonExceptionHandler (
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
+ EFI_STATUS Status;
+
+ //
+ // If the exception is overridden, exit early.
+ //
+ Status = OverrideCpuExceptionHandler (ExceptionType, SystemContext);
+ if (Status == EFI_SUCCESS) {
+ return;
+ }
+
+ //
+ // If the exception was not overridden, then the extract the exception value
+ // to continue with.
+ //
+ ExceptionType = OVERRIDE_EXCEPTION (Status);
+
(To request vector 0 (#DE), the return is encoded to be non-zero and the
exception value extracted)
The NULL implementation of the override library would just return the
current exception type so that exception processing continues as today.
This seems to be the best way to handle the #VC exception without hard
coding it into CpuExceptionHandlerLib and being able to catch a #VC as
soon as possible.
Thoughts?
Thanks,
Tom
>
> Thanks,
> Ray
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
>> Sent: Tuesday, May 12, 2020 11:00 PM
>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi,
>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>
>> On 5/11/20 12:24 AM, Ni, Ray wrote:
>>> Tom,
>>>
>>> I agree with the first issue. I am not quite clear on the second one.
>>
>> In regards to the exception propagation, the hypervisor is allowed to
>> request an exception as part of the return information. For example, the
>> guest issues a RDMSR instruction for an invalid MSR. The hypervisor would
>> normally inject a #GP into the guest. With SEV-ES, the VC handler has to
>> do this. Hence the need to possibly propogate to other exception handlers
>> after handling the #VC.
>>
>>>
>>> SourceLevelDebugPkg provides source level debugging support early in SEC
>>> through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
>>>
>>> It hooks all Intel SDM defined exceptions. It hooks INT32 additionally to
>>> support breaking from HOST.
>>>
>>> It doesn't use CpuExceptionLib because it hooks in very early SEC phase.
>>>
>>> Can you use the same way?
>>
>> I can look at trying to do something like this. I guess the source level
>> debug needs to be aware of all the exceptions, which is why it hooks all
>> them. The SEV-ES support is only concerned with the #VC exception. It just
>> seems like a lot of duplicated and extra code vs. checking for / handling
>> the #VC exception in the CpuExceptionHandler library.
>>
>> My plan for v8 is/was to have a NULL VmgExitLib library, of which the #VC
>> handler would be part of the interface, with the CpuExceptionHandler
>> library invoking the #VC handler on #VC exception and having the OvmfPkg
>> provide a VmgExitLib library with all the functionality.
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Ray
>>>
>>> *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of *Andrew
>>> Fish via groups.io
>>> *Sent:* Sunday, May 10, 2020 3:10 AM
>>> *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
>>> *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
>>> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
>>> Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You,
>>> Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong,
>>> Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>> *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>
>>>
>>>
>>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
>>> <mailto:thomas.lendacky@amd.com>> wrote:
>>>
>>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>>
>>> Tom,
>>>
>>>
>>> Hi Ray,
>>>
>>>
>>> I have a bit concern on your change that directly modifies
>>> CpuExceptionHandlerLib to handle
>>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
>>> exception context for
>>> every exception. Any component which wants to do specific handling
>>> of certain exceptions
>>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe
>>> driver:
>>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
>>> DebugExceptionHandler);
>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>> PageFaultExceptionHandler);
>>> }
>>> Is it possible for your feature to follow the same pattern?
>>>
>>>
>>> There are two problems:
>>>
>>> The first is that RegisterCpuInterruptHandler() is not implemented for
>>> both the SEC and PEI phases, so it is not currently possible to
>>> register a handler that early.
>>>
>>> The second is that I need to be able to propagate an exception request
>>> from the hypervisor. With the current implementation there doesn't
>>> appear to be an easy way to perform this propagation.
>>>
>>> If there's a way to accomplish both of the above I wouldn't be opposed
>>> to using RegisterCpuInterruptHandler() as long as there are no #VCs
>>> that can occur between initializing exception handling and and
>>> registering the #VC handler.
>>>
>>> Thomas,
>>>
>>> As you point out it is tricky dealing with XIP code. You can't have
>>> globals that you can write and generally you use a PEI service to look
>>> tings up, the most common thing being using a HOB. But SEC has no services
>>> and I'm not sure you really want to be calling into the PEI Core on a
>>> random exception.
>>>
>>> Here are the best options that popped into my head after reading your email
>>>
>>> 1) IDT in RAM
>>>
>>> If your code populates the IDT the IDTR gives you access to the address of
>>> the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for
>>> a cached copy of the PEI Services Table, but otther than that you are good
>>> to go. It should be possible to have a global so you can have the table
>>> required to implement RegisterCpuInterruptHandler(). There might be some
>>> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data
>>> after the IDT would be a good option. In general if your code allocates
>>> the memory for the IDT then you can treat the IDT as part of your private
>>> context data structure and that gives you access
>>>
>>> 2) IDT in ROM.
>>>
>>> For this it seems like you need a library to link in to
>>> the CpuExceptionHandlerLib that allows you to override the handler. If
>>> CpuInterruptHandlerOverride() returns NULL you do the current behavior if
>>> not NULL then you call the returned handler.
>>>
>>> EFI_CPU_INTERRUPT_HANDLER
>>>
>>> EFIAPI
>>>
>>> OverrideCpuInterruptHandler (
>>>
>>> IN EFI_EXCEPTION_TYPE InterruptType
>>>
>>> );
>>>
>>> Thanks,
>>>
>>> Andrew Fish
>>>
>>> PS Off topic, but it would also be useful to have a library that overrides
>>> the state dump display. For example using Xcode you can always display a
>>> stack frame from the exception handler.
>>>
>>>
>>>
>>> Thanks,
>>> Tom
>>>
>>>
>>> Thanks,
>>> Ray
>>>
>>> -----Original Message-----
>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>> <mailto:thomas.lendacky@amd.com>>
>>> Sent: Saturday, May 9, 2020 3:16 AM
>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
>>> <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard Biesheuvel
>>> <ard.biesheuvel@linaro.org
>>> <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
>>> <michael.d.kinney@intel.com
>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
>>> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni,
>>> Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh
>>> Singh <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>;
>>> You, Benjamin
>>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi,
>>> Dandan <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>;
>>> Dong, Guo <guo.dong@intel.com <mailto:guo.dong@intel.com>>;
>>> Wu, Hao A
>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
>>> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma,
>>> Maurice <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>
>>> I was able to use the pull request method that Laszlo
>>> documented and fixed
>>> up all of the issues identified by the VS compiler.
>>>
>>> An additional change I'm planning to make for the next version
>>> (v8) of the
>>> patches is to create a NULL library instance of the VmgExitLib
>>> that will
>>> also include the #VC handler function. This will reduce the
>>> amount of code
>>> associated with this feature for platforms that don't
>>> use/support SEV-ES.
>>>
>>> Laszlo, this will mean that I will introduce a version of the
>>> VmgExitLib
>>> under OvmfPkg that will provide the majority of the
>>> functionality that is
>>> present today in UefiCpuPkg. In essence, the functionality in
>>> v7 patches 8
>>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg.
>>> I think
>>> this is the better way to do this. Let me know if you have any
>>> concerns.
>>>
>>> Thanks,
>>> Tom
>>>
>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>
>>> This patch series provides support for running EDK2/OVMF
>>> under SEV-ES.
>>>
>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES)
>>> expands on the
>>> SEV support to protect the guest register state from the
>>> hypervisor. See
>>> "AMD64 Architecture Programmer's Manual Volume 2: System
>>> Programming",
>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>
>>> In order to allow a hypervisor to perform functions on
>>> behalf of a guest,
>>> there is architectural support for notifying a guest's
>>> operating system
>>> when certain types of VMEXITs are about to occur. This
>>> allows the guest to
>>> selectively share information with the hypervisor to
>>> satisfy the requested
>>> function. The notification is performed using a new
>>> exception, the VMM
>>> Communication exception (#VC). The information is shared
>>> through the
>>> Guest-Hypervisor Communication Block (GHCB) using the
>>> VMGEXIT instruction.
>>> The GHCB format and the protocol for using it is
>>> documented in "SEV-ES
>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>
>>> The main areas of the EDK2 code that are updated to
>>> support SEV-ES are
>>> around the exception handling support and the AP boot support.
>>>
>>> Exception support is required starting in Sec, continuing
>>> through Pei
>>> and into Dxe in order to handle #VC exceptions that are
>>> generated. Each
>>> AP requires it's own GHCB page as well as a page to hold
>>> values specific
>>> to that AP.
>>>
>>> AP booting poses some interesting challenges. The
>>> INIT-SIPI-SIPI sequence
>>> is typically used to boot the APs. However, the hypervisor
>>> is not allowed
>>> to update the guest registers. The GHCB document [2] talks
>>> about how SMP
>>> booting under SEV-ES is performed.
>>>
>>> Since the GHCB page must be a shared (unencrypted) page,
>>> the processor
>>> must be running in long mode in order for the guest and
>>> hypervisor to
>>> communicate with each other. As a result, SEV-ES is only
>>> supported under
>>> the X64 architecture.
>>>
>>>
>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%25
>> 2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe
>> 4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCid
>> wLMl5c%3D&reserved=0
>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%252
>> F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884
>> e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8
>> lyZo0%3D&reserved=0>
>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f
>> 3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2
>> XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56b
>> a3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4B
>> NIeKe0Of4K5Kuix4%3D&reserved=0>
>>>
>>> ---
>>>
>>> These patches are based on commit:
>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck
>>> plugin max failures")
>>>
>>> Proper execution of SEV-ES relies on Bugzilla 2340 being
>>> fixed.
>>>
>>> A version of the tree (with an extra patch to workaround
>>> Bugzilla 2340) can
>>> be found at:
>>>
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e60
>> 8e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedv
>> E%3D&reserved=0
>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>> es-
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e1
>> 1a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F
>> 6vqMg%3D&reserved=0>
>>>
>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>> <mailto:ard.biesheuvel@linaro.org>>
>>> Cc: Benjamin You <benjamin.you@intel.com
>>> <mailto:benjamin.you@intel.com>>
>>> Cc: Dandan Bi <dandan.bi@intel.com
>>> <mailto:dandan.bi@intel.com>>
>>> Cc: Eric Dong <eric.dong@intel.com
>>> <mailto:eric.dong@intel.com>>
>>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
>>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
>>> Cc: Jian J Wang <jian.j.wang@intel.com
>>> <mailto:jian.j.wang@intel.com>>
>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>> <mailto:jordan.l.justen@intel.com>>
>>> Cc: Laszlo Ersek <lersek@redhat.com
>>> <mailto:lersek@redhat.com>>
>>> Cc: Liming Gao <liming.gao@intel.com
>>> <mailto:liming.gao@intel.com>>
>>> Cc: Maurice Ma <maurice.ma@intel.com
>>> <mailto:maurice.ma@intel.com>>
>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>> <mailto:michael.d.kinney@intel.com>>
>>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>>>
>>> Changes since v6:
>>> - Add function comments to all functions, including local
>>> functions
>>> - Add function parameter direction to all functions (in/out)
>>> - Add support for MMIO MOVZX/MOVSX instructions
>>> - Ensure the per-CPU variable page remains encrypted
>>> - Coding-style fixes as identified by Ecc
>>>
>>> Changes since v5:
>>> - Remove extraneous VmgExitLib usage
>>> - Miscellaneous changes to address feedback (coding style,
>>> etc.)
>>>
>>> Changes since v4:
>>> - Move the SEV-ES protocol negotiation out of the SEC
>>> exception handler
>>> and into the SecMain.c file. As a result:
>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and
>>> into OvmfPkg
>>> - Combine SecAMDSevVcHandler.c and
>>> PeiDxeAMDSevVcHandler.c into a
>>> single AMDSevVcHandler.c
>>> - Consolidate VmgExitLib usage into common LibraryClasses
>>> sections
>>> - Add documentation comments to the VmgExitLib functions
>>>
>>> Changes since v3:
>>> - Remove the need for the MP library finalization routine.
>>> The AP
>>> jump table address will be held by the hypervisor
>>> rather than
>>> communicated via the GHCB MSR. This removes some
>>> fragility around
>>> the UEFI to OS transition.
>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and
>>> use it to
>>> communicate the SEV-ES status, so that SEC CPU
>>> exception handling is
>>> only established for an SEV-ES guest.
>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>> - Fix SMM build breakage by adding VC exception support
>>> the SMM CPU
>>> exception handling.
>>> - Add memory fencing around the invocation of AsmVmgExit().
>>> - Clarify comments around the SEV-ES AP reset RIP values
>>> and usage.
>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>
>>> Changes since v2:
>>> - Added a way to locate the SEV-ES fixed AP RIP address
>>> for starting
>>> AP's to avoid updating the actual flash image (build
>>> time location
>>> that is identified with a GUID value).
>>> - Create a VmgExit library to replace static inline functions.
>>> - Move some PCDs to the appropriate packages
>>> - Add support for writing to QEMU flash under SEV-ES
>>> - Add additional MMIO opcode support
>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>
>>> Changes since v1:
>>> - Patches reworked to be more specific to the
>>> component/area being updated
>>> and order of definition/usage
>>> - Created a library for VMGEXIT-related functions to
>>> replace use of inline
>>> functions
>>> - Allocation method for GDT changed from AllocatePool to
>>> AllocatePages
>>> - Early caching only enabled for SEV-ES guests
>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>
>>> Tom Lendacky (43):
>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>> MdePkg: Add the MSR definition for the GHCB register
>>> MdePkg: Add a structure definition for the GHCB
>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when
>>> creating page tables
>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>> UefiCpuPkg: Implement library support for VMGEXIT
>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the
>>> VmgExitLib library
>>> UefiCpuPkg/CpuExceptionHandler: Add base support for
>>> the #VC exception
>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>> IOIO_PROT NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for
>>> IOIO_PROT NAE
>>> events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID
>>> NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>> MSR_PROT NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF
>>> NAE events (MMIO)
>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD
>>> NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC
>>> NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC
>>> NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD
>>> NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>> VMMCALL NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP
>>> NAE events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>> MONITOR/MONITORX NAE
>>> events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>> MWAIT/MWAITX NAE
>>> events
>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7
>>> Read/Write NAE
>>> events
>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
>>> indicator function
>>> OvmfPkg: Add support to perform SEV-ES initialization
>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3
>>> is supported
>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe
>>> phase
>>> OvmfPkg/PlatformPei: Move early GDT into ram when
>>> SEV-ES is enabled
>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash
>>> detection with
>>> SEV-ES is enabled
>>> UefiCpuPkg: Add a 16-bit protected mode code segment
>>> descriptor
>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate
>>> if SEV-ES is
>>> enabled
>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP
>>> reset vector
>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>
>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>> OvmfPkg/OvmfPkg.dec | 9 +
>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>> OvmfPkg/OvmfXen.dsc | 1 +
>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>> .../QemuFlash.h | 13 +
>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>> .../CpuExceptionCommon.h | 2 +
>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>> .../MemEncryptSevLibInternal.c | 75 +-
>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>> .../QemuFlash.c | 23 +-
>>> .../QemuFlashDxe.c | 22 +
>>> .../QemuFlashSmm.c | 16 +
>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>> .../CpuExceptionCommon.c | 2 +-
>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>> .../PeiDxeSmmCpuException.c | 16 +
>>> .../SecPeiCpuException.c | 16 +
>>> .../X64/ArchAMDSevVcHandler.c | 1699
>>> +++++++++++++++++
>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>> create mode 100644
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>> create mode 100644
>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>> create mode 100644
>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>> create mode 100644
>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>> create mode 100644
>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>> create mode 100644
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>> create mode 100644
>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>> create mode 100644
>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>
>>>
>>>
>>>
>>>
>>
>>
>
^ permalink raw reply related [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-14 17:59 ` Lendacky, Thomas
@ 2020-05-15 5:47 ` Ni, Ray
2020-05-15 14:30 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Ni, Ray @ 2020-05-15 5:47 UTC (permalink / raw)
To: devel@edk2.groups.io, thomas.lendacky@amd.com, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice, Fan Jeff
I just realized my solution doesn't cover some scenarios:
1. SMM
2. S3 boot path
3. CapsuleX64
If we want to hook #29 in all scenarios, your way
directly modifying CpuExceptionHandlerLib is the
easiest way because RegisterInterruptHandler() is supported
only in DXE/SMM case.
There is no way to use RegisterXXX() API for #2 and #3 because
PEI instance doesn't support.
Do we need to hook in all scenarios? What instructions could
cause #29?
I don't see much difference between the new way
introducing OverrideCpuExceptionHandler () and directly modifying
the CpuExceptionHandlerLib. Both ways modifies the library.
Introducing OverrideCpuExceptionHandler() might be worse because
it creates an interface which encourages anyone to hook any exceptions.
Your current way only hooks #29.
Thanks,
Ray
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
> Sent: Friday, May 15, 2020 1:59 AM
> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi,
> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>; Fan Jeff <vanjeff_919@hotmail.com>
> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>
> On 5/14/20 8:10 AM, Ni, Ray wrote:
> > Tom,
>
> Hi Ray,
>
> > I just discussed with original CPU owner Jeff and went through how IDT is setup in the boot flow.
> > Here is what I think you can do to avoid modifying the CpuExceptionHandlerLib.
> > 1. SecPlatformMain() modifies IDT[29] to point to your VC handler. This step helps to build the VC handler in whole 32bit
> mode SEC+PEI.
>
> That can probably be done, but duplicates a lot of code - all of the
> exception entry assembler code.
>
> Additionally, UefiCpuPkg/CpuMpPei/CpuMpPei.c will also invoke
> InitializeCpuExceptionHandlers() registering a new IDT[29] entry.
>
> > 2. Create a new DXE driver with dependency set to TRUE and call RegisterCpuInteruptHandler(29, xx) in its entrypoint to
> register VC handler for whole 64bit mode DXE.
> > 3. Platform FDF uses apriori file mechanism to make sure the driver created in step #2 is dispatched as the 1st driver in
> DXE phase. This step is optional if you accept there is some time that VC handler is not setup in early DXE phase.
>
> Tracing the execution of an apriori driver shows that this happens after
> DXE has initialized its exception handler and #VCs occur before a handler
> can be reigstered by the new driver, causing a failure.
>
> > 4. In the new DXE driver, gets the EFI_VECTOR_HANDOFF_INFO (MdePkg\Include\Ppi\VectorHandoffInfo.h) from
> configuration table.
> > It reports failure if the vector_handoff table says DO_NOT_HOOK for #29.
> > It re-produces vector_handoff table with #29 set to DO_NOT_HOOK so that no one could use CpuArch protocol to
> override #29 handler.
> >
> >
> > In general, I want to use the API/capability provided by CpuExceptionHandlerLib instead of directly modifying it for
> handler registration.
> > Directly modifying it gives an improper code reference/example for future developers.
>
> I also don't see how this method will allow me to easily propagate a new
> exception value through the exception handling stack.
>
> My current plan was to create a CpuExceptionOverrideLib library that is
> invoked as part of exception handling. This allows immediate ability to
> hook any exception without having to wait for an opportunity to register a
> handler - which in the case of #VC, is too late. Future developers that
> need immediate exception handling will be able to override the default
> library without any modification to CpuExceptionHandlerLib.
>
>
> The change would look something like this:
>
> diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
> index 20148db74cf8..7ac86f56d7d2 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/CpuExceptionOverrideLib.h>
> #include "CpuExceptionCommon.h"
>
> CONST UINTN mDoFarReturnFlag = 0;
> @@ -24,6 +25,22 @@ CommonExceptionHandler (
> IN EFI_SYSTEM_CONTEXT SystemContext
> )
> {
> + EFI_STATUS Status;
> +
> + //
> + // If the exception is overridden, exit early.
> + //
> + Status = OverrideCpuExceptionHandler (ExceptionType, SystemContext);
> + if (Status == EFI_SUCCESS) {
> + return;
> + }
> +
> + //
> + // If the exception was not overridden, then the extract the exception value
> + // to continue with.
> + //
> + ExceptionType = OVERRIDE_EXCEPTION (Status);
> +
>
> (To request vector 0 (#DE), the return is encoded to be non-zero and the
> exception value extracted)
>
>
> The NULL implementation of the override library would just return the
> current exception type so that exception processing continues as today.
>
> This seems to be the best way to handle the #VC exception without hard
> coding it into CpuExceptionHandlerLib and being able to catch a #VC as
> soon as possible.
>
> Thoughts?
>
> Thanks,
> Tom
>
> >
> > Thanks,
> > Ray
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
> >> Sent: Tuesday, May 12, 2020 11:00 PM
> >> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
> >> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
> >> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Dong,
> >> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi,
> >> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
> >> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
> >> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
> >>
> >> On 5/11/20 12:24 AM, Ni, Ray wrote:
> >>> Tom,
> >>>
> >>> I agree with the first issue. I am not quite clear on the second one.
> >>
> >> In regards to the exception propagation, the hypervisor is allowed to
> >> request an exception as part of the return information. For example, the
> >> guest issues a RDMSR instruction for an invalid MSR. The hypervisor would
> >> normally inject a #GP into the guest. With SEV-ES, the VC handler has to
> >> do this. Hence the need to possibly propogate to other exception handlers
> >> after handling the #VC.
> >>
> >>>
> >>> SourceLevelDebugPkg provides source level debugging support early in SEC
> >>> through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
> >>>
> >>> It hooks all Intel SDM defined exceptions. It hooks INT32 additionally to
> >>> support breaking from HOST.
> >>>
> >>> It doesn't use CpuExceptionLib because it hooks in very early SEC phase.
> >>>
> >>> Can you use the same way?
> >>
> >> I can look at trying to do something like this. I guess the source level
> >> debug needs to be aware of all the exceptions, which is why it hooks all
> >> them. The SEV-ES support is only concerned with the #VC exception. It just
> >> seems like a lot of duplicated and extra code vs. checking for / handling
> >> the #VC exception in the CpuExceptionHandler library.
> >>
> >> My plan for v8 is/was to have a NULL VmgExitLib library, of which the #VC
> >> handler would be part of the interface, with the CpuExceptionHandler
> >> library invoking the #VC handler on #VC exception and having the OvmfPkg
> >> provide a VmgExitLib library with all the functionality.
> >>
> >> Thanks,
> >> Tom
> >>
> >>>
> >>> Thanks,
> >>> Ray
> >>>
> >>> *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of *Andrew
> >>> Fish via groups.io
> >>> *Sent:* Sunday, May 10, 2020 3:10 AM
> >>> *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
> >>> *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
> >>> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
> >>> Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
> >>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
> >>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You,
> >>> Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong,
> >>> Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
> >>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
> >>> *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
> >>>
> >>>
> >>>
> >>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
> >>> <mailto:thomas.lendacky@amd.com>> wrote:
> >>>
> >>> On 5/9/20 1:44 AM, Ni, Ray wrote:
> >>>
> >>> Tom,
> >>>
> >>>
> >>> Hi Ray,
> >>>
> >>>
> >>> I have a bit concern on your change that directly modifies
> >>> CpuExceptionHandlerLib to handle
> >>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
> >>> exception context for
> >>> every exception. Any component which wants to do specific handling
> >>> of certain exceptions
> >>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe
> >>> driver:
> >>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
> >>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
> >>> DebugExceptionHandler);
> >>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
> >>> PageFaultExceptionHandler);
> >>> }
> >>> Is it possible for your feature to follow the same pattern?
> >>>
> >>>
> >>> There are two problems:
> >>>
> >>> The first is that RegisterCpuInterruptHandler() is not implemented for
> >>> both the SEC and PEI phases, so it is not currently possible to
> >>> register a handler that early.
> >>>
> >>> The second is that I need to be able to propagate an exception request
> >>> from the hypervisor. With the current implementation there doesn't
> >>> appear to be an easy way to perform this propagation.
> >>>
> >>> If there's a way to accomplish both of the above I wouldn't be opposed
> >>> to using RegisterCpuInterruptHandler() as long as there are no #VCs
> >>> that can occur between initializing exception handling and and
> >>> registering the #VC handler.
> >>>
> >>> Thomas,
> >>>
> >>> As you point out it is tricky dealing with XIP code. You can't have
> >>> globals that you can write and generally you use a PEI service to look
> >>> tings up, the most common thing being using a HOB. But SEC has no services
> >>> and I'm not sure you really want to be calling into the PEI Core on a
> >>> random exception.
> >>>
> >>> Here are the best options that popped into my head after reading your email
> >>>
> >>> 1) IDT in RAM
> >>>
> >>> If your code populates the IDT the IDTR gives you access to the address of
> >>> the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for
> >>> a cached copy of the PEI Services Table, but otther than that you are good
> >>> to go. It should be possible to have a global so you can have the table
> >>> required to implement RegisterCpuInterruptHandler(). There might be some
> >>> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data
> >>> after the IDT would be a good option. In general if your code allocates
> >>> the memory for the IDT then you can treat the IDT as part of your private
> >>> context data structure and that gives you access
> >>>
> >>> 2) IDT in ROM.
> >>>
> >>> For this it seems like you need a library to link in to
> >>> the CpuExceptionHandlerLib that allows you to override the handler. If
> >>> CpuInterruptHandlerOverride() returns NULL you do the current behavior if
> >>> not NULL then you call the returned handler.
> >>>
> >>> EFI_CPU_INTERRUPT_HANDLER
> >>>
> >>> EFIAPI
> >>>
> >>> OverrideCpuInterruptHandler (
> >>>
> >>> IN EFI_EXCEPTION_TYPE InterruptType
> >>>
> >>> );
> >>>
> >>> Thanks,
> >>>
> >>> Andrew Fish
> >>>
> >>> PS Off topic, but it would also be useful to have a library that overrides
> >>> the state dump display. For example using Xcode you can always display a
> >>> stack frame from the exception handler.
> >>>
> >>>
> >>>
> >>> Thanks,
> >>> Tom
> >>>
> >>>
> >>> Thanks,
> >>> Ray
> >>>
> >>> -----Original Message-----
> >>> From: Tom Lendacky <thomas.lendacky@amd.com
> >>> <mailto:thomas.lendacky@amd.com>>
> >>> Sent: Saturday, May 9, 2020 3:16 AM
> >>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
> >>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
> >>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
> >>> <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard Biesheuvel
> >>> <ard.biesheuvel@linaro.org
> >>> <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
> >>> <michael.d.kinney@intel.com
> >>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
> >>> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
> >>> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni,
> >>> Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh
> >>> Singh <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>;
> >>> You, Benjamin
> >>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi,
> >>> Dandan <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>;
> >>> Dong, Guo <guo.dong@intel.com <mailto:guo.dong@intel.com>>;
> >>> Wu, Hao A
> >>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
> >>> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma,
> >>> Maurice <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
> >>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
> >>>
> >>> I was able to use the pull request method that Laszlo
> >>> documented and fixed
> >>> up all of the issues identified by the VS compiler.
> >>>
> >>> An additional change I'm planning to make for the next version
> >>> (v8) of the
> >>> patches is to create a NULL library instance of the VmgExitLib
> >>> that will
> >>> also include the #VC handler function. This will reduce the
> >>> amount of code
> >>> associated with this feature for platforms that don't
> >>> use/support SEV-ES.
> >>>
> >>> Laszlo, this will mean that I will introduce a version of the
> >>> VmgExitLib
> >>> under OvmfPkg that will provide the majority of the
> >>> functionality that is
> >>> present today in UefiCpuPkg. In essence, the functionality in
> >>> v7 patches 8
> >>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg.
> >>> I think
> >>> this is the better way to do this. Let me know if you have any
> >>> concerns.
> >>>
> >>> Thanks,
> >>> Tom
> >>>
> >>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
> >>>
> >>> This patch series provides support for running EDK2/OVMF
> >>> under SEV-ES.
> >>>
> >>> Secure Encrypted Virtualization - Encrypted State (SEV-ES)
> >>> expands on the
> >>> SEV support to protect the guest register state from the
> >>> hypervisor. See
> >>> "AMD64 Architecture Programmer's Manual Volume 2: System
> >>> Programming",
> >>> section "15.35 Encrypted State (SEV-ES)" [1].
> >>>
> >>> In order to allow a hypervisor to perform functions on
> >>> behalf of a guest,
> >>> there is architectural support for notifying a guest's
> >>> operating system
> >>> when certain types of VMEXITs are about to occur. This
> >>> allows the guest to
> >>> selectively share information with the hypervisor to
> >>> satisfy the requested
> >>> function. The notification is performed using a new
> >>> exception, the VMM
> >>> Communication exception (#VC). The information is shared
> >>> through the
> >>> Guest-Hypervisor Communication Block (GHCB) using the
> >>> VMGEXIT instruction.
> >>> The GHCB format and the protocol for using it is
> >>> documented in "SEV-ES
> >>> Guest-Hypervisor Communication Block Standardization" [2].
> >>>
> >>> The main areas of the EDK2 code that are updated to
> >>> support SEV-ES are
> >>> around the exception handling support and the AP boot support.
> >>>
> >>> Exception support is required starting in Sec, continuing
> >>> through Pei
> >>> and into Dxe in order to handle #VC exceptions that are
> >>> generated. Each
> >>> AP requires it's own GHCB page as well as a page to hold
> >>> values specific
> >>> to that AP.
> >>>
> >>> AP booting poses some interesting challenges. The
> >>> INIT-SIPI-SIPI sequence
> >>> is typically used to boot the APs. However, the hypervisor
> >>> is not allowed
> >>> to update the guest registers. The GHCB document [2] talks
> >>> about how SMP
> >>> booting under SEV-ES is performed.
> >>>
> >>> Since the GHCB page must be a shared (unencrypted) page,
> >>> the processor
> >>> must be running in long mode in order for the guest and
> >>> hypervisor to
> >>> communicate with each other. As a result, SEV-ES is only
> >>> supported under
> >>> the X64 architecture.
> >>>
> >>>
> >>
> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%
> 25
> >>
> 2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe
> >>
> 4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCid
> >> wLMl5c%3D&reserved=0
> >>>
> >>
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2
> 52
> >>
> F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884
> >>
> e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8
> >> lyZo0%3D&reserved=0>
> >>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
> >>
> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f
> >>
> 3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2
> >> XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
> >>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
> >>
> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56b
> >>
> a3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4B
> >> NIeKe0Of4K5Kuix4%3D&reserved=0>
> >>>
> >>> ---
> >>>
> >>> These patches are based on commit:
> >>> be7295b36405 (".python/SpellCheck: Increase SpellCheck
> >>> plugin max failures")
> >>>
> >>> Proper execution of SEV-ES relies on Bugzilla 2340 being
> >>> fixed.
> >>>
> >>> A version of the tree (with an extra patch to workaround
> >>> Bugzilla 2340) can
> >>> be found at:
> >>>
> >> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
> es-
> >>
> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e60
> >>
> 8e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedv
> >> E%3D&reserved=0
> >>>
> >>
> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
> >> es-
> >>
> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e1
> >>
> 1a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F
> >> 6vqMg%3D&reserved=0>
> >>>
> >>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
> >>> <mailto:ard.biesheuvel@linaro.org>>
> >>> Cc: Benjamin You <benjamin.you@intel.com
> >>> <mailto:benjamin.you@intel.com>>
> >>> Cc: Dandan Bi <dandan.bi@intel.com
> >>> <mailto:dandan.bi@intel.com>>
> >>> Cc: Eric Dong <eric.dong@intel.com
> >>> <mailto:eric.dong@intel.com>>
> >>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
> >>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
> >>> Cc: Jian J Wang <jian.j.wang@intel.com
> >>> <mailto:jian.j.wang@intel.com>>
> >>> Cc: Jordan Justen <jordan.l.justen@intel.com
> >>> <mailto:jordan.l.justen@intel.com>>
> >>> Cc: Laszlo Ersek <lersek@redhat.com
> >>> <mailto:lersek@redhat.com>>
> >>> Cc: Liming Gao <liming.gao@intel.com
> >>> <mailto:liming.gao@intel.com>>
> >>> Cc: Maurice Ma <maurice.ma@intel.com
> >>> <mailto:maurice.ma@intel.com>>
> >>> Cc: Michael D Kinney <michael.d.kinney@intel.com
> >>> <mailto:michael.d.kinney@intel.com>>
> >>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
> >>>
> >>> Changes since v6:
> >>> - Add function comments to all functions, including local
> >>> functions
> >>> - Add function parameter direction to all functions (in/out)
> >>> - Add support for MMIO MOVZX/MOVSX instructions
> >>> - Ensure the per-CPU variable page remains encrypted
> >>> - Coding-style fixes as identified by Ecc
> >>>
> >>> Changes since v5:
> >>> - Remove extraneous VmgExitLib usage
> >>> - Miscellaneous changes to address feedback (coding style,
> >>> etc.)
> >>>
> >>> Changes since v4:
> >>> - Move the SEV-ES protocol negotiation out of the SEC
> >>> exception handler
> >>> and into the SecMain.c file. As a result:
> >>> - Move the SecGhcb related PCDs out of UefiCpuPkg and
> >>> into OvmfPkg
> >>> - Combine SecAMDSevVcHandler.c and
> >>> PeiDxeAMDSevVcHandler.c into a
> >>> single AMDSevVcHandler.c
> >>> - Consolidate VmgExitLib usage into common LibraryClasses
> >>> sections
> >>> - Add documentation comments to the VmgExitLib functions
> >>>
> >>> Changes since v3:
> >>> - Remove the need for the MP library finalization routine.
> >>> The AP
> >>> jump table address will be held by the hypervisor
> >>> rather than
> >>> communicated via the GHCB MSR. This removes some
> >>> fragility around
> >>> the UEFI to OS transition.
> >>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and
> >>> use it to
> >>> communicate the SEV-ES status, so that SEC CPU
> >>> exception handling is
> >>> only established for an SEV-ES guest.
> >>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
> >>> - Fix SMM build breakage by adding VC exception support
> >>> the SMM CPU
> >>> exception handling.
> >>> - Add memory fencing around the invocation of AsmVmgExit().
> >>> - Clarify comments around the SEV-ES AP reset RIP values
> >>> and usage.
> >>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
> >>> - Remove the 16-bit code selector definition from MdeModulePkg
> >>>
> >>> Changes since v2:
> >>> - Added a way to locate the SEV-ES fixed AP RIP address
> >>> for starting
> >>> AP's to avoid updating the actual flash image (build
> >>> time location
> >>> that is identified with a GUID value).
> >>> - Create a VmgExit library to replace static inline functions.
> >>> - Move some PCDs to the appropriate packages
> >>> - Add support for writing to QEMU flash under SEV-ES
> >>> - Add additional MMIO opcode support
> >>> - Cleaned up the GHCB MSR CPUID protocol support
> >>>
> >>> Changes since v1:
> >>> - Patches reworked to be more specific to the
> >>> component/area being updated
> >>> and order of definition/usage
> >>> - Created a library for VMGEXIT-related functions to
> >>> replace use of inline
> >>> functions
> >>> - Allocation method for GDT changed from AllocatePool to
> >>> AllocatePages
> >>> - Early caching only enabled for SEV-ES guests
> >>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
> >>> - Reserved SEC GHCB-related memory areas when S3 is enabled
> >>>
> >>> Tom Lendacky (43):
> >>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
> >>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
> >>> MdePkg: Add the MSR definition for the GHCB register
> >>> MdePkg: Add a structure definition for the GHCB
> >>> MdeModulePkg/DxeIplPeim: Support GHCB pages when
> >>> creating page tables
> >>> MdePkg/BaseLib: Add support for the XGETBV instruction
> >>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
> >>> UefiCpuPkg: Implement library support for VMGEXIT
> >>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
> >>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the
> >>> VmgExitLib library
> >>> UefiCpuPkg/CpuExceptionHandler: Add base support for
> >>> the #VC exception
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for
> >>> IOIO_PROT NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Support string IO for
> >>> IOIO_PROT NAE
> >>> events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID
> >>> NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for
> >>> MSR_PROT NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF
> >>> NAE events (MMIO)
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD
> >>> NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC
> >>> NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC
> >>> NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD
> >>> NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for
> >>> VMMCALL NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP
> >>> NAE events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for
> >>> MONITOR/MONITORX NAE
> >>> events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for
> >>> MWAIT/MWAITX NAE
> >>> events
> >>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7
> >>> Read/Write NAE
> >>> events
> >>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
> >>> indicator function
> >>> OvmfPkg: Add support to perform SEV-ES initialization
> >>> OvmfPkg: Create a GHCB page for use during Sec phase
> >>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3
> >>> is supported
> >>> OvmfPkg: Create GHCB pages for use during Pei and Dxe
> >>> phase
> >>> OvmfPkg/PlatformPei: Move early GDT into ram when
> >>> SEV-ES is enabled
> >>> UefiCpuPkg: Create an SEV-ES workarea PCD
> >>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
> >>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
> >>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
> >>> OvmfPkg/Sec: Enable cache early to speed up booting
> >>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash
> >>> detection with
> >>> SEV-ES is enabled
> >>> UefiCpuPkg: Add a 16-bit protected mode code segment
> >>> descriptor
> >>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate
> >>> if SEV-ES is
> >>> enabled
> >>> UefiCpuPkg: Allow AP booting under SEV-ES
> >>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP
> >>> reset vector
> >>> OvmfPkg: Move the GHCB allocations into reserved memory
> >>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
> >>>
> >>> MdeModulePkg/MdeModulePkg.dec | 9 +
> >>> OvmfPkg/OvmfPkg.dec | 9 +
> >>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
> >>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
> >>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
> >>> OvmfPkg/OvmfPkgX64.dsc | 6 +
> >>> OvmfPkg/OvmfXen.dsc | 1 +
> >>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
> >>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
> >>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
> >>> OvmfPkg/OvmfPkgX64.fdf | 9 +
> >>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
> >>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
> >>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
> >>> .../FvbServicesRuntimeDxe.inf | 2 +
> >>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
> >>> OvmfPkg/Sec/SecMain.inf | 4 +
> >>> .../DxeCpuExceptionHandlerLib.inf | 5 +
> >>> .../PeiCpuExceptionHandlerLib.inf | 5 +
> >>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
> >>> .../SmmCpuExceptionHandlerLib.inf | 5 +
> >>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
> >>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
> >>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
> >>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
> >>> MdePkg/Include/Library/BaseLib.h | 31 +
> >>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
> >>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
> >>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
> >>> .../QemuFlash.h | 13 +
> >>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
> >>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
> >>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
> >>> .../CpuExceptionCommon.h | 2 +
> >>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
> >>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
> >>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
> >>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
> >>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
> >>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
> >>> .../MemEncryptSevLibInternal.c | 75 +-
> >>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
> >>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
> >>> .../QemuFlash.c | 23 +-
> >>> .../QemuFlashDxe.c | 22 +
> >>> .../QemuFlashSmm.c | 16 +
> >>> OvmfPkg/Sec/SecMain.c | 188 +-
> >>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
> >>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
> >>> .../CpuExceptionCommon.c | 2 +-
> >>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
> >>> .../PeiDxeSmmCpuException.c | 16 +
> >>> .../SecPeiCpuException.c | 16 +
> >>> .../X64/ArchAMDSevVcHandler.c | 1699
> >>> +++++++++++++++++
> >>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
> >>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
> >>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
> >>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
> >>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
> >>> MdeModulePkg/MdeModulePkg.uni | 8 +
> >>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
> >>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
> >>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
> >>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
> >>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
> >>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
> >>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
> >>> .../X64/ExceptionHandlerAsm.nasm | 17 +
> >>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
> >>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
> >>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
> >>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
> >>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
> >>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
> >>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
> >>> 75 files changed, 4707 insertions(+), 102 deletions(-)
> >>> create mode 100644
> >>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
> >>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
> >>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
> >>> create mode 100644
> >>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
> >>> create mode 100644
> >>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
> >>> create mode 100644
> >>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
> >>> create mode 100644
> >>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
> >>> create mode 100644
> >>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
> >>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
> >>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
> >>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
> >>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
> >>> create mode 100644
> >>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
> >>> create mode 100644
> >>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
> >>>
> >>>
> >>>
> >>>
> >>>
> >>
> >>
> >
>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-15 5:47 ` Ni, Ray
@ 2020-05-15 14:30 ` Lendacky, Thomas
2020-05-18 20:44 ` Brian J. Johnson
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-15 14:30 UTC (permalink / raw)
To: Ni, Ray, devel@edk2.groups.io, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice, Fan Jeff
On 5/15/20 12:47 AM, Ni, Ray wrote:
> I just realized my solution doesn't cover some scenarios:
> 1. SMM
> 2. S3 boot path
> 3. CapsuleX64
>
> If we want to hook #29 in all scenarios, your way
> directly modifying CpuExceptionHandlerLib is the
> easiest way because RegisterInterruptHandler() is supported
> only in DXE/SMM case.
> There is no way to use RegisterXXX() API for #2 and #3 because
> PEI instance doesn't support.
>
> Do we need to hook in all scenarios? What instructions could
> cause #29?
A #VC can only be genereted by an SEV-ES guest, so in the standard case
the hook will never be called. For an SEV-ES guest, a number of different
instructions can cause a #VC. These include IO instructions (such as used
to output debug message to the serial port), CPUID instructions, anything
performing MMIO, RDMSR/WRMSR instructions, etc. So we need to hook it in
all SEV-ES scenarios.
To eliminate all of the handler code in the standard case, I'm planning on
providing a NULL VmgExitLib library that has a (near) empty #VC handler so
that the full #VC handler code will only be in the Ovmf package.
>
>
> I don't see much difference between the new way
> introducing OverrideCpuExceptionHandler () and directly modifying
> the CpuExceptionHandlerLib. Both ways modifies the library.
> Introducing OverrideCpuExceptionHandler() might be worse because
> it creates an interface which encourages anyone to hook any exceptions.
>
> Your current way only hooks #29.
Ok, I can go back to the explicit check for exception #29.
I'll work to get these changes and changes from other feedback into the
next version and out for review early next week.
Thanks for taking the time to work through this with me!
Tom
>
> Thanks,
> Ray
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
>> Sent: Friday, May 15, 2020 1:59 AM
>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi,
>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>; Fan Jeff <vanjeff_919@hotmail.com>
>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>
>> On 5/14/20 8:10 AM, Ni, Ray wrote:
>>> Tom,
>>
>> Hi Ray,
>>
>>> I just discussed with original CPU owner Jeff and went through how IDT is setup in the boot flow.
>>> Here is what I think you can do to avoid modifying the CpuExceptionHandlerLib.
>>> 1. SecPlatformMain() modifies IDT[29] to point to your VC handler. This step helps to build the VC handler in whole 32bit
>> mode SEC+PEI.
>>
>> That can probably be done, but duplicates a lot of code - all of the
>> exception entry assembler code.
>>
>> Additionally, UefiCpuPkg/CpuMpPei/CpuMpPei.c will also invoke
>> InitializeCpuExceptionHandlers() registering a new IDT[29] entry.
>>
>>> 2. Create a new DXE driver with dependency set to TRUE and call RegisterCpuInteruptHandler(29, xx) in its entrypoint to
>> register VC handler for whole 64bit mode DXE.
>>> 3. Platform FDF uses apriori file mechanism to make sure the driver created in step #2 is dispatched as the 1st driver in
>> DXE phase. This step is optional if you accept there is some time that VC handler is not setup in early DXE phase.
>>
>> Tracing the execution of an apriori driver shows that this happens after
>> DXE has initialized its exception handler and #VCs occur before a handler
>> can be reigstered by the new driver, causing a failure.
>>
>>> 4. In the new DXE driver, gets the EFI_VECTOR_HANDOFF_INFO (MdePkg\Include\Ppi\VectorHandoffInfo.h) from
>> configuration table.
>>> It reports failure if the vector_handoff table says DO_NOT_HOOK for #29.
>>> It re-produces vector_handoff table with #29 set to DO_NOT_HOOK so that no one could use CpuArch protocol to
>> override #29 handler.
>>>
>>>
>>> In general, I want to use the API/capability provided by CpuExceptionHandlerLib instead of directly modifying it for
>> handler registration.
>>> Directly modifying it gives an improper code reference/example for future developers.
>>
>> I also don't see how this method will allow me to easily propagate a new
>> exception value through the exception handling stack.
>>
>> My current plan was to create a CpuExceptionOverrideLib library that is
>> invoked as part of exception handling. This allows immediate ability to
>> hook any exception without having to wait for an opportunity to register a
>> handler - which in the case of #VC, is too late. Future developers that
>> need immediate exception handling will be able to override the default
>> library without any modification to CpuExceptionHandlerLib.
>>
>>
>> The change would look something like this:
>>
>> diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
>> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
>> index 20148db74cf8..7ac86f56d7d2 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/CpuExceptionOverrideLib.h>
>> #include "CpuExceptionCommon.h"
>>
>> CONST UINTN mDoFarReturnFlag = 0;
>> @@ -24,6 +25,22 @@ CommonExceptionHandler (
>> IN EFI_SYSTEM_CONTEXT SystemContext
>> )
>> {
>> + EFI_STATUS Status;
>> +
>> + //
>> + // If the exception is overridden, exit early.
>> + //
>> + Status = OverrideCpuExceptionHandler (ExceptionType, SystemContext);
>> + if (Status == EFI_SUCCESS) {
>> + return;
>> + }
>> +
>> + //
>> + // If the exception was not overridden, then the extract the exception value
>> + // to continue with.
>> + //
>> + ExceptionType = OVERRIDE_EXCEPTION (Status);
>> +
>>
>> (To request vector 0 (#DE), the return is encoded to be non-zero and the
>> exception value extracted)
>>
>>
>> The NULL implementation of the override library would just return the
>> current exception type so that exception processing continues as today.
>>
>> This seems to be the best way to handle the #VC exception without hard
>> coding it into CpuExceptionHandlerLib and being able to catch a #VC as
>> soon as possible.
>>
>> Thoughts?
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Ray
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Lendacky, Thomas
>>>> Sent: Tuesday, May 12, 2020 11:00 PM
>>>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
>> Dong,
>>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi,
>>>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
>>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>>
>>>> On 5/11/20 12:24 AM, Ni, Ray wrote:
>>>>> Tom,
>>>>>
>>>>> I agree with the first issue. I am not quite clear on the second one.
>>>>
>>>> In regards to the exception propagation, the hypervisor is allowed to
>>>> request an exception as part of the return information. For example, the
>>>> guest issues a RDMSR instruction for an invalid MSR. The hypervisor would
>>>> normally inject a #GP into the guest. With SEV-ES, the VC handler has to
>>>> do this. Hence the need to possibly propogate to other exception handlers
>>>> after handling the #VC.
>>>>
>>>>>
>>>>> SourceLevelDebugPkg provides source level debugging support early in SEC
>>>>> through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
>>>>>
>>>>> It hooks all Intel SDM defined exceptions. It hooks INT32 additionally to
>>>>> support breaking from HOST.
>>>>>
>>>>> It doesn't use CpuExceptionLib because it hooks in very early SEC phase.
>>>>>
>>>>> Can you use the same way?
>>>>
>>>> I can look at trying to do something like this. I guess the source level
>>>> debug needs to be aware of all the exceptions, which is why it hooks all
>>>> them. The SEV-ES support is only concerned with the #VC exception. It just
>>>> seems like a lot of duplicated and extra code vs. checking for / handling
>>>> the #VC exception in the CpuExceptionHandler library.
>>>>
>>>> My plan for v8 is/was to have a NULL VmgExitLib library, of which the #VC
>>>> handler would be part of the interface, with the CpuExceptionHandler
>>>> library invoking the #VC handler on #VC exception and having the OvmfPkg
>>>> provide a VmgExitLib library with all the functionality.
>>>>
>>>> Thanks,
>>>> Tom
>>>>
>>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>
>>>>> *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of *Andrew
>>>>> Fish via groups.io
>>>>> *Sent:* Sunday, May 10, 2020 3:10 AM
>>>>> *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
>>>>> *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
>>>>> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
>>>>> Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>>>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You,
>>>>> Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong,
>>>>> Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J
>>>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>>>> *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>>
>>>>>
>>>>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>> wrote:
>>>>>
>>>>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>>>>
>>>>> Tom,
>>>>>
>>>>>
>>>>> Hi Ray,
>>>>>
>>>>>
>>>>> I have a bit concern on your change that directly modifies
>>>>> CpuExceptionHandlerLib to handle
>>>>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
>>>>> exception context for
>>>>> every exception. Any component which wants to do specific handling
>>>>> of certain exceptions
>>>>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe
>>>>> driver:
>>>>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
>>>>> DebugExceptionHandler);
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>>>> PageFaultExceptionHandler);
>>>>> }
>>>>> Is it possible for your feature to follow the same pattern?
>>>>>
>>>>>
>>>>> There are two problems:
>>>>>
>>>>> The first is that RegisterCpuInterruptHandler() is not implemented for
>>>>> both the SEC and PEI phases, so it is not currently possible to
>>>>> register a handler that early.
>>>>>
>>>>> The second is that I need to be able to propagate an exception request
>>>>> from the hypervisor. With the current implementation there doesn't
>>>>> appear to be an easy way to perform this propagation.
>>>>>
>>>>> If there's a way to accomplish both of the above I wouldn't be opposed
>>>>> to using RegisterCpuInterruptHandler() as long as there are no #VCs
>>>>> that can occur between initializing exception handling and and
>>>>> registering the #VC handler.
>>>>>
>>>>> Thomas,
>>>>>
>>>>> As you point out it is tricky dealing with XIP code. You can't have
>>>>> globals that you can write and generally you use a PEI service to look
>>>>> tings up, the most common thing being using a HOB. But SEC has no services
>>>>> and I'm not sure you really want to be calling into the PEI Core on a
>>>>> random exception.
>>>>>
>>>>> Here are the best options that popped into my head after reading your email
>>>>>
>>>>> 1) IDT in RAM
>>>>>
>>>>> If your code populates the IDT the IDTR gives you access to the address of
>>>>> the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for
>>>>> a cached copy of the PEI Services Table, but otther than that you are good
>>>>> to go. It should be possible to have a global so you can have the table
>>>>> required to implement RegisterCpuInterruptHandler(). There might be some
>>>>> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data
>>>>> after the IDT would be a good option. In general if your code allocates
>>>>> the memory for the IDT then you can treat the IDT as part of your private
>>>>> context data structure and that gives you access
>>>>>
>>>>> 2) IDT in ROM.
>>>>>
>>>>> For this it seems like you need a library to link in to
>>>>> the CpuExceptionHandlerLib that allows you to override the handler. If
>>>>> CpuInterruptHandlerOverride() returns NULL you do the current behavior if
>>>>> not NULL then you call the returned handler.
>>>>>
>>>>> EFI_CPU_INTERRUPT_HANDLER
>>>>>
>>>>> EFIAPI
>>>>>
>>>>> OverrideCpuInterruptHandler (
>>>>>
>>>>> IN EFI_EXCEPTION_TYPE InterruptType
>>>>>
>>>>> );
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Andrew Fish
>>>>>
>>>>> PS Off topic, but it would also be useful to have a library that overrides
>>>>> the state dump display. For example using Xcode you can always display a
>>>>> stack frame from the exception handler.
>>>>>
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>
>>>>> -----Original Message-----
>>>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>>
>>>>> Sent: Saturday, May 9, 2020 3:16 AM
>>>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
>>>>> <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard Biesheuvel
>>>>> <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
>>>>> <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>>>> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
>>>>> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni,
>>>>> Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh
>>>>> Singh <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>;
>>>>> You, Benjamin
>>>>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi,
>>>>> Dandan <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>;
>>>>> Dong, Guo <guo.dong@intel.com <mailto:guo.dong@intel.com>>;
>>>>> Wu, Hao A
>>>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
>>>>> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma,
>>>>> Maurice <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>> I was able to use the pull request method that Laszlo
>>>>> documented and fixed
>>>>> up all of the issues identified by the VS compiler.
>>>>>
>>>>> An additional change I'm planning to make for the next version
>>>>> (v8) of the
>>>>> patches is to create a NULL library instance of the VmgExitLib
>>>>> that will
>>>>> also include the #VC handler function. This will reduce the
>>>>> amount of code
>>>>> associated with this feature for platforms that don't
>>>>> use/support SEV-ES.
>>>>>
>>>>> Laszlo, this will mean that I will introduce a version of the
>>>>> VmgExitLib
>>>>> under OvmfPkg that will provide the majority of the
>>>>> functionality that is
>>>>> present today in UefiCpuPkg. In essence, the functionality in
>>>>> v7 patches 8
>>>>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg.
>>>>> I think
>>>>> this is the better way to do this. Let me know if you have any
>>>>> concerns.
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>>>
>>>>> This patch series provides support for running EDK2/OVMF
>>>>> under SEV-ES.
>>>>>
>>>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES)
>>>>> expands on the
>>>>> SEV support to protect the guest register state from the
>>>>> hypervisor. See
>>>>> "AMD64 Architecture Programmer's Manual Volume 2: System
>>>>> Programming",
>>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>>
>>>>> In order to allow a hypervisor to perform functions on
>>>>> behalf of a guest,
>>>>> there is architectural support for notifying a guest's
>>>>> operating system
>>>>> when certain types of VMEXITs are about to occur. This
>>>>> allows the guest to
>>>>> selectively share information with the hypervisor to
>>>>> satisfy the requested
>>>>> function. The notification is performed using a new
>>>>> exception, the VMM
>>>>> Communication exception (#VC). The information is shared
>>>>> through the
>>>>> Guest-Hypervisor Communication Block (GHCB) using the
>>>>> VMGEXIT instruction.
>>>>> The GHCB format and the protocol for using it is
>>>>> documented in "SEV-ES
>>>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>>>
>>>>> The main areas of the EDK2 code that are updated to
>>>>> support SEV-ES are
>>>>> around the exception handling support and the AP boot support.
>>>>>
>>>>> Exception support is required starting in Sec, continuing
>>>>> through Pei
>>>>> and into Dxe in order to handle #VC exceptions that are
>>>>> generated. Each
>>>>> AP requires it's own GHCB page as well as a page to hold
>>>>> values specific
>>>>> to that AP.
>>>>>
>>>>> AP booting poses some interesting challenges. The
>>>>> INIT-SIPI-SIPI sequence
>>>>> is typically used to boot the APs. However, the hypervisor
>>>>> is not allowed
>>>>> to update the guest registers. The GHCB document [2] talks
>>>>> about how SMP
>>>>> booting under SEV-ES is performed.
>>>>>
>>>>> Since the GHCB page must be a shared (unencrypted) page,
>>>>> the processor
>>>>> must be running in long mode in order for the guest and
>>>>> hypervisor to
>>>>> communicate with each other. As a result, SEV-ES is only
>>>>> supported under
>>>>> the X64 architecture.
>>>>>
>>>>>
>>>>
>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%25
>> 25
>>>>
>> 2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe
>>>>
>> 4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCid
>>>> wLMl5c%3D&reserved=0
>>>>>
>>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%252
>> 52
>>>>
>> F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884
>>>>
>> e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8
>>>> lyZo0%3D&reserved=0>
>>>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>>>>
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f
>>>>
>> 3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2
>>>> XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>>>>
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56b
>>>>
>> a3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4B
>>>> NIeKe0Of4K5Kuix4%3D&reserved=0>
>>>>>
>>>>> ---
>>>>>
>>>>> These patches are based on commit:
>>>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck
>>>>> plugin max failures")
>>>>>
>>>>> Proper execution of SEV-ES relies on Bugzilla 2340 being
>>>>> fixed.
>>>>>
>>>>> A version of the tree (with an extra patch to workaround
>>>>> Bugzilla 2340) can
>>>>> be found at:
>>>>>
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>> es-
>>>>
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e60
>>>>
>> 8e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedv
>>>> E%3D&reserved=0
>>>>>
>>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>>>> es-
>>>>
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e1
>>>>
>> 1a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F
>>>> 6vqMg%3D&reserved=0>
>>>>>
>>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>
>>>>> Cc: Benjamin You <benjamin.you@intel.com
>>>>> <mailto:benjamin.you@intel.com>>
>>>>> Cc: Dandan Bi <dandan.bi@intel.com
>>>>> <mailto:dandan.bi@intel.com>>
>>>>> Cc: Eric Dong <eric.dong@intel.com
>>>>> <mailto:eric.dong@intel.com>>
>>>>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
>>>>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
>>>>> Cc: Jian J Wang <jian.j.wang@intel.com
>>>>> <mailto:jian.j.wang@intel.com>>
>>>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>
>>>>> Cc: Laszlo Ersek <lersek@redhat.com
>>>>> <mailto:lersek@redhat.com>>
>>>>> Cc: Liming Gao <liming.gao@intel.com
>>>>> <mailto:liming.gao@intel.com>>
>>>>> Cc: Maurice Ma <maurice.ma@intel.com
>>>>> <mailto:maurice.ma@intel.com>>
>>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>
>>>>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>>>>>
>>>>> Changes since v6:
>>>>> - Add function comments to all functions, including local
>>>>> functions
>>>>> - Add function parameter direction to all functions (in/out)
>>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>>> - Ensure the per-CPU variable page remains encrypted
>>>>> - Coding-style fixes as identified by Ecc
>>>>>
>>>>> Changes since v5:
>>>>> - Remove extraneous VmgExitLib usage
>>>>> - Miscellaneous changes to address feedback (coding style,
>>>>> etc.)
>>>>>
>>>>> Changes since v4:
>>>>> - Move the SEV-ES protocol negotiation out of the SEC
>>>>> exception handler
>>>>> and into the SecMain.c file. As a result:
>>>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and
>>>>> into OvmfPkg
>>>>> - Combine SecAMDSevVcHandler.c and
>>>>> PeiDxeAMDSevVcHandler.c into a
>>>>> single AMDSevVcHandler.c
>>>>> - Consolidate VmgExitLib usage into common LibraryClasses
>>>>> sections
>>>>> - Add documentation comments to the VmgExitLib functions
>>>>>
>>>>> Changes since v3:
>>>>> - Remove the need for the MP library finalization routine.
>>>>> The AP
>>>>> jump table address will be held by the hypervisor
>>>>> rather than
>>>>> communicated via the GHCB MSR. This removes some
>>>>> fragility around
>>>>> the UEFI to OS transition.
>>>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and
>>>>> use it to
>>>>> communicate the SEV-ES status, so that SEC CPU
>>>>> exception handling is
>>>>> only established for an SEV-ES guest.
>>>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>>>> - Fix SMM build breakage by adding VC exception support
>>>>> the SMM CPU
>>>>> exception handling.
>>>>> - Add memory fencing around the invocation of AsmVmgExit().
>>>>> - Clarify comments around the SEV-ES AP reset RIP values
>>>>> and usage.
>>>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>>>
>>>>> Changes since v2:
>>>>> - Added a way to locate the SEV-ES fixed AP RIP address
>>>>> for starting
>>>>> AP's to avoid updating the actual flash image (build
>>>>> time location
>>>>> that is identified with a GUID value).
>>>>> - Create a VmgExit library to replace static inline functions.
>>>>> - Move some PCDs to the appropriate packages
>>>>> - Add support for writing to QEMU flash under SEV-ES
>>>>> - Add additional MMIO opcode support
>>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>>
>>>>> Changes since v1:
>>>>> - Patches reworked to be more specific to the
>>>>> component/area being updated
>>>>> and order of definition/usage
>>>>> - Created a library for VMGEXIT-related functions to
>>>>> replace use of inline
>>>>> functions
>>>>> - Allocation method for GDT changed from AllocatePool to
>>>>> AllocatePages
>>>>> - Early caching only enabled for SEV-ES guests
>>>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>>>
>>>>> Tom Lendacky (43):
>>>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>>>> MdePkg: Add the MSR definition for the GHCB register
>>>>> MdePkg: Add a structure definition for the GHCB
>>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when
>>>>> creating page tables
>>>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>>>> UefiCpuPkg: Implement library support for VMGEXIT
>>>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the
>>>>> VmgExitLib library
>>>>> UefiCpuPkg/CpuExceptionHandler: Add base support for
>>>>> the #VC exception
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> IOIO_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for
>>>>> IOIO_PROT NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MSR_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF
>>>>> NAE events (MMIO)
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> VMMCALL NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MONITOR/MONITORX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MWAIT/MWAITX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7
>>>>> Read/Write NAE
>>>>> events
>>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
>>>>> indicator function
>>>>> OvmfPkg: Add support to perform SEV-ES initialization
>>>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3
>>>>> is supported
>>>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe
>>>>> phase
>>>>> OvmfPkg/PlatformPei: Move early GDT into ram when
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash
>>>>> detection with
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Add a 16-bit protected mode code segment
>>>>> descriptor
>>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate
>>>>> if SEV-ES is
>>>>> enabled
>>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP
>>>>> reset vector
>>>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>>>
>>>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>>>> OvmfPkg/OvmfPkg.dec | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>>>> OvmfPkg/OvmfXen.dsc | 1 +
>>>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>>>> .../QemuFlash.h | 13 +
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>>>> .../CpuExceptionCommon.h | 2 +
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>>>> .../MemEncryptSevLibInternal.c | 75 +-
>>>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>>>> .../QemuFlash.c | 23 +-
>>>>> .../QemuFlashDxe.c | 22 +
>>>>> .../QemuFlashSmm.c | 16 +
>>>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>>>> .../CpuExceptionCommon.c | 2 +-
>>>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>>>> .../PeiDxeSmmCpuException.c | 16 +
>>>>> .../SecPeiCpuException.c | 16 +
>>>>> .../X64/ArchAMDSevVcHandler.c | 1699
>>>>> +++++++++++++++++
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>> create mode 100644
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-15 14:30 ` Lendacky, Thomas
@ 2020-05-18 20:44 ` Brian J. Johnson
2020-05-20 1:57 ` 回复: " Fan Jeff
0 siblings, 1 reply; 81+ messages in thread
From: Brian J. Johnson @ 2020-05-18 20:44 UTC (permalink / raw)
To: devel, thomas.lendacky, Ni, Ray, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice, Fan Jeff
FWIW, I kind of like the idea of having a way to provide an exception
handler in all situations via a library. We use a custom fatal
exception handler which prints extra debugging information. So
currently we have to modify CpuExceptionHandlerLib, or explicitly hook
every exception as early as we can. Neither is ideal: modifying the
library becomes a maintenance burden, and hooking the exceptions via
RegisterInterruptHandler() has limitations, as Ray pointed out.
I think that shows that we don't currently have a good way to write a
"system" exception handler to provide underlying support to the rest of
BIOS. CpuExceptionHandlerLib is large and complex, but monolithic.
I don't have a solution to propose, but maybe it will get someone
thinking....
--
Brian J. Johnson
Enterprise X86 Lab
Hewlett Packard Enterprise
brian.johnson@hpe.com
-------- Original Message --------
From: Lendacky, Thomas [mailto:thomas.lendacky@amd.com]
Sent: Friday, May 15, 2020, 9:30 AM
To: Ni, Ray <ray.ni@intel.com>, devel@edk2.groups.io
<devel@edk2.groups.io>, afish@apple.com <afish@apple.com>
Cc: Justen, Jordan L <jordan.l.justen@intel.com>, Laszlo Ersek
<lersek@redhat.com>, Ard Biesheuvel <ard.biesheuvel@linaro.org>, Kinney,
Michael D <michael.d.kinney@intel.com>, Gao, Liming
<liming.gao@intel.com>, Dong, Eric <eric.dong@intel.com>, Brijesh Singh
<brijesh.singh@amd.com>, You, Benjamin <benjamin.you@intel.com>, Bi,
Dandan <dandan.bi@intel.com>, Dong, Guo <guo.dong@intel.com>, Wu, Hao A
<hao.a.wu@intel.com>, Wang, Jian J <jian.j.wang@intel.com>, Ma, Maurice
<maurice.ma@intel.com>, Fan Jeff <vanjeff_919@hotmail.com>
Subject: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
On 5/15/20 12:47 AM, Ni, Ray wrote:
> I just realized my solution doesn't cover some scenarios:
> 1. SMM
> 2. S3 boot path
> 3. CapsuleX64
>
> If we want to hook #29 in all scenarios, your way
> directly modifying CpuExceptionHandlerLib is the
> easiest way because RegisterInterruptHandler() is supported
> only in DXE/SMM case.
> There is no way to use RegisterXXX() API for #2 and #3 because
> PEI instance doesn't support.
>
> Do we need to hook in all scenarios? What instructions could
> cause #29?
A #VC can only be genereted by an SEV-ES guest, so in the standard case
the hook will never be called. For an SEV-ES guest, a number of
different instructions can cause a #VC. These include IO instructions
(such as used to output debug message to the serial port), CPUID
instructions, anything performing MMIO, RDMSR/WRMSR instructions, etc.
So we need to hook it in all SEV-ES scenarios.
To eliminate all of the handler code in the standard case, I'm planning
on providing a NULL VmgExitLib library that has a (near) empty #VC
handler so that the full #VC handler code will only be in the Ovmf package.
>
>
> I don't see much difference between the new way
> introducing OverrideCpuExceptionHandler () and directly modifying
> the CpuExceptionHandlerLib. Both ways modifies the library.
> Introducing OverrideCpuExceptionHandler() might be worse because
> it creates an interface which encourages anyone to hook any exceptions.
>
> Your current way only hooks #29.
Ok, I can go back to the explicit check for exception #29.
I'll work to get these changes and changes from other feedback into the
next version and out for review early next week.
Thanks for taking the time to work through this with me!
Tom
>
> Thanks,
> Ray
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Friday, May 15, 2020 1:59 AM
>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>> <lersek@redhat.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>> You, Benjamin <benjamin.you@intel.com>; Bi,
>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao
>> A <hao.a.wu@intel.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>; Fan Jeff
>> <vanjeff_919@hotmail.com>
>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>
>> On 5/14/20 8:10 AM, Ni, Ray wrote:
>>> Tom,
>>
>> Hi Ray,
>>
>>> I just discussed with original CPU owner Jeff and went through how
>>> IDT is setup in the boot flow.
>>> Here is what I think you can do to avoid modifying the
>>> CpuExceptionHandlerLib.
>>> 1. SecPlatformMain() modifies IDT[29] to point to your VC handler.
>>> This step helps to build the VC handler in whole 32bit
>> mode SEC+PEI.
>>
>> That can probably be done, but duplicates a lot of code - all of the
>> exception entry assembler code.
>>
>> Additionally, UefiCpuPkg/CpuMpPei/CpuMpPei.c will also invoke
>> InitializeCpuExceptionHandlers() registering a new IDT[29] entry.
>>
>>> 2. Create a new DXE driver with dependency set to TRUE and call
>>> RegisterCpuInteruptHandler(29, xx) in its entrypoint to
>> register VC handler for whole 64bit mode DXE.
>>> 3. Platform FDF uses apriori file mechanism to make sure the driver
>>> created in step #2 is dispatched as the 1st driver in
>> DXE phase. This step is optional if you accept there is some time
>> that VC handler is not setup in early DXE phase.
>>
>> Tracing the execution of an apriori driver shows that this happens after
>> DXE has initialized its exception handler and #VCs occur before a
>> handler
>> can be reigstered by the new driver, causing a failure.
>>
>>> 4. In the new DXE driver, gets the EFI_VECTOR_HANDOFF_INFO
>>> (MdePkg\Include\Ppi\VectorHandoffInfo.h) from
>> configuration table.
>>> It reports failure if the vector_handoff table says
>>> DO_NOT_HOOK for #29.
>>> It re-produces vector_handoff table with #29 set to
>>> DO_NOT_HOOK so that no one could use CpuArch protocol to
>> override #29 handler.
>>>
>>>
>>> In general, I want to use the API/capability provided by
>>> CpuExceptionHandlerLib instead of directly modifying it for
>> handler registration.
>>> Directly modifying it gives an improper code reference/example for
>>> future developers.
>>
>> I also don't see how this method will allow me to easily propagate a new
>> exception value through the exception handling stack.
>>
>> My current plan was to create a CpuExceptionOverrideLib library that is
>> invoked as part of exception handling. This allows immediate ability to
>> hook any exception without having to wait for an opportunity to
>> register a
>> handler - which in the case of #VC, is too late. Future developers that
>> need immediate exception handling will be able to override the default
>> library without any modification to CpuExceptionHandlerLib.
>>
>>
>> The change would look something like this:
>>
>> diff --git
>> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
>> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
>> index 20148db74cf8..7ac86f56d7d2 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/CpuExceptionOverrideLib.h>
>> #include "CpuExceptionCommon.h"
>>
>> CONST UINTN mDoFarReturnFlag = 0;
>> @@ -24,6 +25,22 @@ CommonExceptionHandler (
>> IN EFI_SYSTEM_CONTEXT SystemContext
>> )
>> {
>> + EFI_STATUS Status;
>> +
>> + //
>> + // If the exception is overridden, exit early.
>> + //
>> + Status = OverrideCpuExceptionHandler (ExceptionType, SystemContext);
>> + if (Status == EFI_SUCCESS) {
>> + return;
>> + }
>> +
>> + //
>> + // If the exception was not overridden, then the extract the
>> exception value
>> + // to continue with.
>> + //
>> + ExceptionType = OVERRIDE_EXCEPTION (Status);
>> +
>>
>> (To request vector 0 (#DE), the return is encoded to be non-zero and the
>> exception value extracted)
>>
>>
>> The NULL implementation of the override library would just return the
>> current exception type so that exception processing continues as today.
>>
>> This seems to be the best way to handle the #VC exception without hard
>> coding it into CpuExceptionHandlerLib and being able to catch a #VC as
>> soon as possible.
>>
>> Thoughts?
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Ray
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>> Lendacky, Thomas
>>>> Sent: Tuesday, May 12, 2020 11:00 PM
>>>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>>>> <lersek@redhat.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
>> Dong,
>>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>>>> You, Benjamin <benjamin.you@intel.com>; Bi,
>>>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu,
>>>> Hao A <hao.a.wu@intel.com>; Wang, Jian J
>>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>>
>>>> On 5/11/20 12:24 AM, Ni, Ray wrote:
>>>>> Tom,
>>>>>
>>>>> I agree with the first issue. I am not quite clear on the second one.
>>>>
>>>> In regards to the exception propagation, the hypervisor is allowed to
>>>> request an exception as part of the return information. For
>>>> example, the
>>>> guest issues a RDMSR instruction for an invalid MSR. The hypervisor
>>>> would
>>>> normally inject a #GP into the guest. With SEV-ES, the VC handler
>>>> has to
>>>> do this. Hence the need to possibly propogate to other exception
>>>> handlers
>>>> after handling the #VC.
>>>>
>>>>>
>>>>> SourceLevelDebugPkg provides source level debugging support early
>>>>> in SEC
>>>>> through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
>>>>>
>>>>> It hooks all Intel SDM defined exceptions. It hooks INT32
>>>>> additionally to
>>>>> support breaking from HOST.
>>>>>
>>>>> It doesn't use CpuExceptionLib because it hooks in very early SEC
>>>>> phase.
>>>>>
>>>>> Can you use the same way?
>>>>
>>>> I can look at trying to do something like this. I guess the source
>>>> level
>>>> debug needs to be aware of all the exceptions, which is why it
>>>> hooks all
>>>> them. The SEV-ES support is only concerned with the #VC exception.
>>>> It just
>>>> seems like a lot of duplicated and extra code vs. checking for /
>>>> handling
>>>> the #VC exception in the CpuExceptionHandler library.
>>>>
>>>> My plan for v8 is/was to have a NULL VmgExitLib library, of which
>>>> the #VC
>>>> handler would be part of the interface, with the CpuExceptionHandler
>>>> library invoking the #VC handler on #VC exception and having the
>>>> OvmfPkg
>>>> provide a VmgExitLib library with all the functionality.
>>>>
>>>> Thanks,
>>>> Tom
>>>>
>>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>
>>>>> *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of
>>>>> *Andrew
>>>>> Fish via groups.io
>>>>> *Sent:* Sunday, May 10, 2020 3:10 AM
>>>>> *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
>>>>> *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
>>>>> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
>>>>> Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
>>>>> Dong,
>>>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>>>>> You,
>>>>> Benjamin <benjamin.you@intel.com>; Bi, Dandan
>>>>> <dandan.bi@intel.com>; Dong,
>>>>> Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang,
>>>>> Jian J
>>>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>>>> *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>>
>>>>>
>>>>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas
>>>>> <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>> wrote:
>>>>>
>>>>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>>>>
>>>>> Tom,
>>>>>
>>>>>
>>>>> Hi Ray,
>>>>>
>>>>>
>>>>> I have a bit concern on your change that directly modifies
>>>>> CpuExceptionHandlerLib to handle
>>>>> exception #29. Today's CpuExceptionHandlerLib simplify
>>>>> dumps the
>>>>> exception context for
>>>>> every exception. Any component which wants to do
>>>>> specific handling
>>>>> of certain exceptions
>>>>> should call RegisterCpuInterruptHandler(). Such as code
>>>>> in CpuDxe
>>>>> driver:
>>>>> if (HEAP_GUARD_NONSTOP_MODE ||
>>>>> NULL_DETECTION_NONSTOP_MODE) {
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
>>>>> DebugExceptionHandler);
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>>>> PageFaultExceptionHandler);
>>>>> }
>>>>> Is it possible for your feature to follow the same pattern?
>>>>>
>>>>>
>>>>> There are two problems:
>>>>>
>>>>> The first is that RegisterCpuInterruptHandler() is not
>>>>> implemented for
>>>>> both the SEC and PEI phases, so it is not currently possible to
>>>>> register a handler that early.
>>>>>
>>>>> The second is that I need to be able to propagate an
>>>>> exception request
>>>>> from the hypervisor. With the current implementation there
>>>>> doesn't
>>>>> appear to be an easy way to perform this propagation.
>>>>>
>>>>> If there's a way to accomplish both of the above I wouldn't
>>>>> be opposed
>>>>> to using RegisterCpuInterruptHandler() as long as there are
>>>>> no #VCs
>>>>> that can occur between initializing exception handling and and
>>>>> registering the #VC handler.
>>>>>
>>>>> Thomas,
>>>>>
>>>>> As you point out it is tricky dealing with XIP code. You can't have
>>>>> globals that you can write and generally you use a PEI service to
>>>>> look
>>>>> tings up, the most common thing being using a HOB. But SEC has no
>>>>> services
>>>>> and I'm not sure you really want to be calling into the PEI Core on a
>>>>> random exception.
>>>>>
>>>>> Here are the best options that popped into my head after reading
>>>>> your email
>>>>>
>>>>> 1) IDT in RAM
>>>>>
>>>>> If your code populates the IDT the IDTR gives you access to the
>>>>> address of
>>>>> the IDTR via an instruction. The PI Spec reserves IDT - sizeof
>>>>> (UNITN) for
>>>>> a cached copy of the PEI Services Table, but otther than that you
>>>>> are good
>>>>> to go. It should be possible to have a global so you can have the
>>>>> table
>>>>> required to implement RegisterCpuInterruptHandler(). There might
>>>>> be some
>>>>> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing
>>>>> data
>>>>> after the IDT would be a good option. In general if your code
>>>>> allocates
>>>>> the memory for the IDT then you can treat the IDT as part of your
>>>>> private
>>>>> context data structure and that gives you access
>>>>>
>>>>> 2) IDT in ROM.
>>>>>
>>>>> For this it seems like you need a library to link in to
>>>>> the CpuExceptionHandlerLib that allows you to override the
>>>>> handler. If
>>>>> CpuInterruptHandlerOverride() returns NULL you do the current
>>>>> behavior if
>>>>> not NULL then you call the returned handler.
>>>>>
>>>>> EFI_CPU_INTERRUPT_HANDLER
>>>>>
>>>>> EFIAPI
>>>>>
>>>>> OverrideCpuInterruptHandler (
>>>>>
>>>>> IN EFI_EXCEPTION_TYPE InterruptType
>>>>>
>>>>> );
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Andrew Fish
>>>>>
>>>>> PS Off topic, but it would also be useful to have a library that
>>>>> overrides
>>>>> the state dump display. For example using Xcode you can always
>>>>> display a
>>>>> stack frame from the exception handler.
>>>>>
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>
>>>>> -----Original Message-----
>>>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>>
>>>>> Sent: Saturday, May 9, 2020 3:16 AM
>>>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
>>>>> <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard
>>>>> Biesheuvel
>>>>> <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
>>>>> <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>>>> <liming.gao@intel.com
>>>>> <mailto:liming.gao@intel.com>>; Dong,
>>>>> Eric <eric.dong@intel.com
>>>>> <mailto:eric.dong@intel.com>>; Ni,
>>>>> Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>;
>>>>> Brijesh
>>>>> Singh <brijesh.singh@amd.com
>>>>> <mailto:brijesh.singh@amd.com>>;
>>>>> You, Benjamin
>>>>> <benjamin.you@intel.com
>>>>> <mailto:benjamin.you@intel.com>>; Bi,
>>>>> Dandan <dandan.bi@intel.com
>>>>> <mailto:dandan.bi@intel.com>>;
>>>>> Dong, Guo <guo.dong@intel.com
>>>>> <mailto:guo.dong@intel.com>>;
>>>>> Wu, Hao A
>>>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>;
>>>>> Wang, Jian J
>>>>> <jian.j.wang@intel.com
>>>>> <mailto:jian.j.wang@intel.com>>; Ma,
>>>>> Maurice <maurice.ma@intel.com
>>>>> <mailto:maurice.ma@intel.com>>
>>>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>> I was able to use the pull request method that Laszlo
>>>>> documented and fixed
>>>>> up all of the issues identified by the VS compiler.
>>>>>
>>>>> An additional change I'm planning to make for the
>>>>> next version
>>>>> (v8) of the
>>>>> patches is to create a NULL library instance of the
>>>>> VmgExitLib
>>>>> that will
>>>>> also include the #VC handler function. This will
>>>>> reduce the
>>>>> amount of code
>>>>> associated with this feature for platforms that don't
>>>>> use/support SEV-ES.
>>>>>
>>>>> Laszlo, this will mean that I will introduce a
>>>>> version of the
>>>>> VmgExitLib
>>>>> under OvmfPkg that will provide the majority of the
>>>>> functionality that is
>>>>> present today in UefiCpuPkg. In essence, the
>>>>> functionality in
>>>>> v7 patches 8
>>>>> and 11 - 25 will now live under OvmfPkg instead of
>>>>> UefiCpuPkg.
>>>>> I think
>>>>> this is the better way to do this. Let me know if
>>>>> you have any
>>>>> concerns.
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>>>
>>>>> This patch series provides support for running
>>>>> EDK2/OVMF
>>>>> under SEV-ES.
>>>>>
>>>>> Secure Encrypted Virtualization - Encrypted
>>>>> State (SEV-ES)
>>>>> expands on the
>>>>> SEV support to protect the guest register state
>>>>> from the
>>>>> hypervisor. See
>>>>> "AMD64 Architecture Programmer's Manual Volume
>>>>> 2: System
>>>>> Programming",
>>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>>
>>>>> In order to allow a hypervisor to perform
>>>>> functions on
>>>>> behalf of a guest,
>>>>> there is architectural support for notifying a
>>>>> guest's
>>>>> operating system
>>>>> when certain types of VMEXITs are about to
>>>>> occur. This
>>>>> allows the guest to
>>>>> selectively share information with the
>>>>> hypervisor to
>>>>> satisfy the requested
>>>>> function. The notification is performed using a new
>>>>> exception, the VMM
>>>>> Communication exception (#VC). The information
>>>>> is shared
>>>>> through the
>>>>> Guest-Hypervisor Communication Block (GHCB)
>>>>> using the
>>>>> VMGEXIT instruction.
>>>>> The GHCB format and the protocol for using it is
>>>>> documented in "SEV-ES
>>>>> Guest-Hypervisor Communication Block
>>>>> Standardization" [2].
>>>>>
>>>>> The main areas of the EDK2 code that are updated to
>>>>> support SEV-ES are
>>>>> around the exception handling support and the AP
>>>>> boot support.
>>>>>
>>>>> Exception support is required starting in Sec,
>>>>> continuing
>>>>> through Pei
>>>>> and into Dxe in order to handle #VC exceptions
>>>>> that are
>>>>> generated. Each
>>>>> AP requires it's own GHCB page as well as a page
>>>>> to hold
>>>>> values specific
>>>>> to that AP.
>>>>>
>>>>> AP booting poses some interesting challenges. The
>>>>> INIT-SIPI-SIPI sequence
>>>>> is typically used to boot the APs. However, the
>>>>> hypervisor
>>>>> is not allowed
>>>>> to update the guest registers. The GHCB document
>>>>> [2] talks
>>>>> about how SMP
>>>>> booting under SEV-ES is performed.
>>>>>
>>>>> Since the GHCB page must be a shared
>>>>> (unencrypted) page,
>>>>> the processor
>>>>> must be running in long mode in order for the
>>>>> guest and
>>>>> hypervisor to
>>>>> communicate with each other. As a result, SEV-ES
>>>>> is only
>>>>> supported under
>>>>> the X64 architecture.
>>>>>
>>>>>
>>>>
>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%25
>> 25
>>>>
>> 2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe
>>
>>>>
>> 4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCid
>>
>>>> wLMl5c%3D&reserved=0
>>>>>
>>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%252
>> 52
>>>>
>> F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884
>>
>>>>
>> e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8
>>
>>>> lyZo0%3D&reserved=0>
>>>>>
>>>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>>>>
>>>>
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f
>>
>>>>
>> 3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2
>>
>>>> XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>>>
>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>>>>
>>>>
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56b
>>
>>>>
>> a3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4B
>>
>>>> NIeKe0Of4K5Kuix4%3D&reserved=0>
>>>>>
>>>>> ---
>>>>>
>>>>> These patches are based on commit:
>>>>> be7295b36405 (".python/SpellCheck: Increase
>>>>> SpellCheck
>>>>> plugin max failures")
>>>>>
>>>>> Proper execution of SEV-ES relies on Bugzilla
>>>>> 2340 being
>>>>> fixed.
>>>>>
>>>>> A version of the tree (with an extra patch to
>>>>> workaround
>>>>> Bugzilla 2340) can
>>>>> be found at:
>>>>>
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>>
>> es-
>>>>
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e60
>>
>>>>
>> 8e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedv
>>
>>>> E%3D&reserved=0
>>>>>
>>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>>
>>>> es-
>>>>
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e1
>>
>>>>
>> 1a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F
>>
>>>> 6vqMg%3D&reserved=0>
>>>>>
>>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>
>>>>> Cc: Benjamin You <benjamin.you@intel.com
>>>>> <mailto:benjamin.you@intel.com>>
>>>>> Cc: Dandan Bi <dandan.bi@intel.com
>>>>> <mailto:dandan.bi@intel.com>>
>>>>> Cc: Eric Dong <eric.dong@intel.com
>>>>> <mailto:eric.dong@intel.com>>
>>>>> Cc: Guo Dong <guo.dong@intel.com
>>>>> <mailto:guo.dong@intel.com>>
>>>>> Cc: Hao A Wu <hao.a.wu@intel.com
>>>>> <mailto:hao.a.wu@intel.com>>
>>>>> Cc: Jian J Wang <jian.j.wang@intel.com
>>>>> <mailto:jian.j.wang@intel.com>>
>>>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>
>>>>> Cc: Laszlo Ersek <lersek@redhat.com
>>>>> <mailto:lersek@redhat.com>>
>>>>> Cc: Liming Gao <liming.gao@intel.com
>>>>> <mailto:liming.gao@intel.com>>
>>>>> Cc: Maurice Ma <maurice.ma@intel.com
>>>>> <mailto:maurice.ma@intel.com>>
>>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>
>>>>> Cc: Ray Ni <ray.ni@intel.com
>>>>> <mailto:ray.ni@intel.com>>
>>>>>
>>>>> Changes since v6:
>>>>> - Add function comments to all functions,
>>>>> including local
>>>>> functions
>>>>> - Add function parameter direction to all
>>>>> functions (in/out)
>>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>>> - Ensure the per-CPU variable page remains
>>>>> encrypted
>>>>> - Coding-style fixes as identified by Ecc
>>>>>
>>>>> Changes since v5:
>>>>> - Remove extraneous VmgExitLib usage
>>>>> - Miscellaneous changes to address feedback
>>>>> (coding style,
>>>>> etc.)
>>>>>
>>>>> Changes since v4:
>>>>> - Move the SEV-ES protocol negotiation out of
>>>>> the SEC
>>>>> exception handler
>>>>> and into the SecMain.c file. As a result:
>>>>> - Move the SecGhcb related PCDs out of
>>>>> UefiCpuPkg and
>>>>> into OvmfPkg
>>>>> - Combine SecAMDSevVcHandler.c and
>>>>> PeiDxeAMDSevVcHandler.c into a
>>>>> single AMDSevVcHandler.c
>>>>> - Consolidate VmgExitLib usage into common
>>>>> LibraryClasses
>>>>> sections
>>>>> - Add documentation comments to the VmgExitLib
>>>>> functions
>>>>>
>>>>> Changes since v3:
>>>>> - Remove the need for the MP library
>>>>> finalization routine.
>>>>> The AP
>>>>> jump table address will be held by the
>>>>> hypervisor
>>>>> rather than
>>>>> communicated via the GHCB MSR. This removes
>>>>> some
>>>>> fragility around
>>>>> the UEFI to OS transition.
>>>>> - Rename the SEV-ES RIP reset area to SEV-ES
>>>>> workarea and
>>>>> use it to
>>>>> communicate the SEV-ES status, so that SEC CPU
>>>>> exception handling is
>>>>> only established for an SEV-ES guest.
>>>>> - Fix SMM build breakageAdd around
>>>>> QemuFlashPtrWrite().
>>>>> - Fix SMM build breakage by adding VC exception
>>>>> support
>>>>> the SMM CPU
>>>>> exception handling.
>>>>> - Add memory fencing around the invocation of
>>>>> AsmVmgExit().
>>>>> - Clarify comments around the SEV-ES AP reset
>>>>> RIP values
>>>>> and usage.
>>>>> - Move some PCD definitions from MdeModulePkg to
>>>>> UefiCpuPkg.
>>>>> - Remove the 16-bit code selector definition
>>>>> from MdeModulePkg
>>>>>
>>>>> Changes since v2:
>>>>> - Added a way to locate the SEV-ES fixed AP RIP
>>>>> address
>>>>> for starting
>>>>> AP's to avoid updating the actual flash
>>>>> image (build
>>>>> time location
>>>>> that is identified with a GUID value).
>>>>> - Create a VmgExit library to replace static
>>>>> inline functions.
>>>>> - Move some PCDs to the appropriate packages
>>>>> - Add support for writing to QEMU flash under
>>>>> SEV-ES
>>>>> - Add additional MMIO opcode support
>>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>>
>>>>> Changes since v1:
>>>>> - Patches reworked to be more specific to the
>>>>> component/area being updated
>>>>> and order of definition/usage
>>>>> - Created a library for VMGEXIT-related
>>>>> functions to
>>>>> replace use of inline
>>>>> functions
>>>>> - Allocation method for GDT changed from
>>>>> AllocatePool to
>>>>> AllocatePages
>>>>> - Early caching only enabled for SEV-ES guests
>>>>> - Ensure AP loop mode set to halt loop mode for
>>>>> SEV-ES guests
>>>>> - Reserved SEC GHCB-related memory areas when S3
>>>>> is enabled
>>>>>
>>>>> Tom Lendacky (43):
>>>>> MdeModulePkg: Create PCDs to be used in
>>>>> support of SEV-ES
>>>>> UefiCpuPkg: Create PCD to be used in support
>>>>> of SEV-ES
>>>>> MdePkg: Add the MSR definition for the GHCB
>>>>> register
>>>>> MdePkg: Add a structure definition for the GHCB
>>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages
>>>>> when
>>>>> creating page tables
>>>>> MdePkg/BaseLib: Add support for the XGETBV
>>>>> instruction
>>>>> MdePkg/BaseLib: Add support for the VMGEXIT
>>>>> instruction
>>>>> UefiCpuPkg: Implement library support for
>>>>> VMGEXIT
>>>>> OvmfPkg: Prepare OvmfPkg to use the
>>>>> VmgExitLib library
>>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to
>>>>> use the
>>>>> VmgExitLib library
>>>>> UefiCpuPkg/CpuExceptionHandler: Add base
>>>>> support for
>>>>> the #VC exception
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> IOIO_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Support
>>>>> string IO for
>>>>> IOIO_PROT NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for CPUID
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MSR_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for NPF
>>>>> NAE events (MMIO)
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for WBINVD
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for RDTSC
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for RDPMC
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for INVD
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> VMMCALL NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for RDTSCP
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MONITOR/MONITORX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MWAIT/MWAITX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for DR7
>>>>> Read/Write NAE
>>>>> events
>>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
>>>>> indicator function
>>>>> OvmfPkg: Add support to perform SEV-ES
>>>>> initialization
>>>>> OvmfPkg: Create a GHCB page for use during
>>>>> Sec phase
>>>>> OvmfPkg/PlatformPei: Reserve GHCB-related
>>>>> areas if S3
>>>>> is supported
>>>>> OvmfPkg: Create GHCB pages for use during
>>>>> Pei and Dxe
>>>>> phase
>>>>> OvmfPkg/PlatformPei: Move early GDT into ram
>>>>> when
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>>> OvmfPkg: Reserve a page in memory for the
>>>>> SEV-ES usage
>>>>> OvmfPkg/ResetVector: Add support for a
>>>>> 32-bit SEV check
>>>>> OvmfPkg/Sec: Add #VC exception handling for
>>>>> Sec phase
>>>>> OvmfPkg/Sec: Enable cache early to speed up
>>>>> booting
>>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe:
>>>>> Bypass flash
>>>>> detection with
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Add a 16-bit protected mode code
>>>>> segment
>>>>> descriptor
>>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag
>>>>> to indicate
>>>>> if SEV-ES is
>>>>> enabled
>>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>>> OvmfPkg: Use the SEV-ES work area for the
>>>>> SEV-ES AP
>>>>> reset vector
>>>>> OvmfPkg: Move the GHCB allocations into
>>>>> reserved memory
>>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest
>>>>> APs for OS use
>>>>>
>>>>> MdeModulePkg/MdeModulePkg.dec
>>>>> | 9 +
>>>>> OvmfPkg/OvmfPkg.dec
>>>>> | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.dec
>>>>> | 17 +
>>>>> OvmfPkg/OvmfPkgIa32.dsc
>>>>> | 6 +
>>>>> OvmfPkg/OvmfPkgIa32X64.dsc
>>>>> | 6 +
>>>>> OvmfPkg/OvmfPkgX64.dsc
>>>>> | 6 +
>>>>> OvmfPkg/OvmfXen.dsc
>>>>> | 1 +
>>>>> UefiCpuPkg/UefiCpuPkg.dsc
>>>>> | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc
>>>>> | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
>>>>> | 2 +
>>>>> OvmfPkg/OvmfPkgX64.fdf
>>>>> | 9 +
>>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>>>>> | 2 +
>>>>> MdePkg/Library/BaseLib/BaseLib.inf
>>>>> | 4 +
>>>>> OvmfPkg/PlatformPei/PlatformPei.inf
>>>>> | 7 +
>>>>> .../FvbServicesRuntimeDxe.inf
>>>>> | 2 +
>>>>> OvmfPkg/ResetVector/ResetVector.inf
>>>>> | 8 +
>>>>> OvmfPkg/Sec/SecMain.inf
>>>>> | 4 +
>>>>> .../DxeCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> .../PeiCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> .../SecPeiCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> .../SmmCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
>>>>> | 4 +
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
>>>>> | 4 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>> | 33 +
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h
>>>>> | 12 +-
>>>>> MdePkg/Include/Library/BaseLib.h
>>>>> | 31 +
>>>>> MdePkg/Include/Register/Amd/Fam17Msr.h
>>>>> | 42 +
>>>>> MdePkg/Include/Register/Amd/Ghcb.h
>>>>> | 136 ++
>>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h
>>>>> | 12 +
>>>>> .../QemuFlash.h
>>>>> | 13 +
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.h
>>>>> | 4 +-
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>> | 117 ++
>>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>> | 49 +
>>>>> .../CpuExceptionCommon.h
>>>>> | 2 +
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h
>>>>> | 68 +-
>>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c
>>>>> | 4 +-
>>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c
>>>>> | 11 +-
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c
>>>>> | 57 +-
>>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c
>>>>> | 45 +
>>>>> MdePkg/Library/BaseLib/X64/GccInline.c
>>>>> | 47 +
>>>>> .../MemEncryptSevLibInternal.c
>>>>> | 75 +-
>>>>> OvmfPkg/PlatformPei/AmdSev.c
>>>>> | 89 +
>>>>> OvmfPkg/PlatformPei/MemDetect.c
>>>>> | 23 +
>>>>> .../QemuFlash.c
>>>>> | 23 +-
>>>>> .../QemuFlashDxe.c
>>>>> | 22 +
>>>>> .../QemuFlashSmm.c
>>>>> | 16 +
>>>>> OvmfPkg/Sec/SecMain.c
>>>>> | 188 +-
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.c
>>>>> | 8 +-
>>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>> | 40 +
>>>>> .../CpuExceptionCommon.c
>>>>> | 2 +-
>>>>> .../Ia32/ArchAMDSevVcHandler.c
>>>>> | 38 +
>>>>> .../PeiDxeSmmCpuException.c
>>>>> | 16 +
>>>>> .../SecPeiCpuException.c
>>>>> | 16 +
>>>>> .../X64/ArchAMDSevVcHandler.c
>>>>> | 1699
>>>>> +++++++++++++++++
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
>>>>> | 113 +-
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c
>>>>> | 265 ++-
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
>>>>> | 19 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>> | 293 +++
>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
>>>>> | 2 +-
>>>>> MdeModulePkg/MdeModulePkg.uni
>>>>> | 8 +
>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>> | 37 +
>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>> | 31 +
>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>> | 32 +
>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>> | 34 +
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>> | 100 +
>>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>>>> | 350 +++-
>>>>> OvmfPkg/ResetVector/ResetVector.nasmb
>>>>> | 20 +
>>>>> .../X64/ExceptionHandlerAsm.nasm
>>>>> | 17 +
>>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
>>>>> | 2 +-
>>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm
>>>>> | 15 +
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
>>>>> | 4 +-
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
>>>>> | 370 +++-
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>> | 15 +
>>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
>>>>> | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.uni
>>>>> | 11 +
>>>>> 75 files changed, 4707 insertions(+), 102
>>>>> deletions(-)
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>> create mode 100644
>>>>> MdePkg/Include/Register/Amd/Ghcb.h
>>>>> create mode 100644
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>> create mode 100644
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* 回复: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-18 20:44 ` Brian J. Johnson
@ 2020-05-20 1:57 ` Fan Jeff
0 siblings, 0 replies; 81+ messages in thread
From: Fan Jeff @ 2020-05-20 1:57 UTC (permalink / raw)
To: Brian J. Johnson, devel@edk2.groups.io, thomas.lendacky@amd.com,
Ni, Ray, afish@apple.com
Cc: Justen, Jordan L, Laszlo Ersek, Ard Biesheuvel, Kinney, Michael D,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
[-- Attachment #1: Type: text/plain, Size: 47616 bytes --]
hi,
Firstly, I'd like to give some background on CpuExceptionHandlerLib and ReservedVectorList.
For CpuExceptionHandlerLib:
1, CpuExceptionHandlerLib was introduced to dump CPU context from early SEC phase to the reset of BIOS(PEI, DXE, SMM).
It was intended to be linked by SecCore, Cpu PEI(CpuMpPei), DXE Core,CPU DXE(CpuDxe), CPU SMM(PiSmmCpuDxeSmm), and other modules that needs to switch mode(from protected mode to long, such as CapsuleX64 and BootScriptDxe)
2, RegisterCpuInterruptHandler() function was designed for CPU ARCH Protocol's Register Interrupt service and did not consider the usage on PEI.
3, For PEI phase, it was also required to work after memory was ready.
I agree with Brian's point "CpuExceptionHandlerLib is large and complex, but monolithic."
For ReservedVectorList:
1, It was designed for any module wants to provide its own IDT entry (ASM code).
2, It also defined the manner how to co-work with existing/following IDT entry.
I think ReservedVectorList is better to handle TOM's case. It could work from early SEC phase, we need to take care the mode switch cases. The shortcoming is that ASM codes need writting.
Best Regards,
Jeff
________________________________
发件人: Brian J. Johnson <brian.johnson@hpe.com>
发送时间: 2020年5月19日 4:44
收件人: devel@edk2.groups.io <devel@edk2.groups.io>; thomas.lendacky@amd.com <thomas.lendacky@amd.com>; Ni, Ray <ray.ni@intel.com>; afish@apple.com <afish@apple.com>
抄送: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong, Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>; You, Benjamin <benjamin.you@intel.com>; Bi, Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>; Fan Jeff <vanjeff_919@hotmail.com>
主题: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
FWIW, I kind of like the idea of having a way to provide an exception
handler in all situations via a library. We use a custom fatal
exception handler which prints extra debugging information. So
currently we have to modify CpuExceptionHandlerLib, or explicitly hook
every exception as early as we can. Neither is ideal: modifying the
library becomes a maintenance burden, and hooking the exceptions via
RegisterInterruptHandler() has limitations, as Ray pointed out.
I think that shows that we don't currently have a good way to write a
"system" exception handler to provide underlying support to the rest of
BIOS. CpuExceptionHandlerLib is large and complex, but monolithic.
I don't have a solution to propose, but maybe it will get someone
thinking....
--
Brian J. Johnson
Enterprise X86 Lab
Hewlett Packard Enterprise
brian.johnson@hpe.com
-------- Original Message --------
From: Lendacky, Thomas [mailto:thomas.lendacky@amd.com]
Sent: Friday, May 15, 2020, 9:30 AM
To: Ni, Ray <ray.ni@intel.com>, devel@edk2.groups.io
<devel@edk2.groups.io>, afish@apple.com <afish@apple.com>
Cc: Justen, Jordan L <jordan.l.justen@intel.com>, Laszlo Ersek
<lersek@redhat.com>, Ard Biesheuvel <ard.biesheuvel@linaro.org>, Kinney,
Michael D <michael.d.kinney@intel.com>, Gao, Liming
<liming.gao@intel.com>, Dong, Eric <eric.dong@intel.com>, Brijesh Singh
<brijesh.singh@amd.com>, You, Benjamin <benjamin.you@intel.com>, Bi,
Dandan <dandan.bi@intel.com>, Dong, Guo <guo.dong@intel.com>, Wu, Hao A
<hao.a.wu@intel.com>, Wang, Jian J <jian.j.wang@intel.com>, Ma, Maurice
<maurice.ma@intel.com>, Fan Jeff <vanjeff_919@hotmail.com>
Subject: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
On 5/15/20 12:47 AM, Ni, Ray wrote:
> I just realized my solution doesn't cover some scenarios:
> 1. SMM
> 2. S3 boot path
> 3. CapsuleX64
>
> If we want to hook #29 in all scenarios, your way
> directly modifying CpuExceptionHandlerLib is the
> easiest way because RegisterInterruptHandler() is supported
> only in DXE/SMM case.
> There is no way to use RegisterXXX() API for #2 and #3 because
> PEI instance doesn't support.
>
> Do we need to hook in all scenarios? What instructions could
> cause #29?
A #VC can only be genereted by an SEV-ES guest, so in the standard case
the hook will never be called. For an SEV-ES guest, a number of
different instructions can cause a #VC. These include IO instructions
(such as used to output debug message to the serial port), CPUID
instructions, anything performing MMIO, RDMSR/WRMSR instructions, etc.
So we need to hook it in all SEV-ES scenarios.
To eliminate all of the handler code in the standard case, I'm planning
on providing a NULL VmgExitLib library that has a (near) empty #VC
handler so that the full #VC handler code will only be in the Ovmf package.
>
>
> I don't see much difference between the new way
> introducing OverrideCpuExceptionHandler () and directly modifying
> the CpuExceptionHandlerLib. Both ways modifies the library.
> Introducing OverrideCpuExceptionHandler() might be worse because
> it creates an interface which encourages anyone to hook any exceptions.
>
> Your current way only hooks #29.
Ok, I can go back to the explicit check for exception #29.
I'll work to get these changes and changes from other feedback into the
next version and out for review early next week.
Thanks for taking the time to work through this with me!
Tom
>
> Thanks,
> Ray
>
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Lendacky, Thomas
>> Sent: Friday, May 15, 2020 1:59 AM
>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>> <lersek@redhat.com>; Ard Biesheuvel
>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Dong,
>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>> You, Benjamin <benjamin.you@intel.com>; Bi,
>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu, Hao
>> A <hao.a.wu@intel.com>; Wang, Jian J
>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>; Fan Jeff
>> <vanjeff_919@hotmail.com>
>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>
>> On 5/14/20 8:10 AM, Ni, Ray wrote:
>>> Tom,
>>
>> Hi Ray,
>>
>>> I just discussed with original CPU owner Jeff and went through how
>>> IDT is setup in the boot flow.
>>> Here is what I think you can do to avoid modifying the
>>> CpuExceptionHandlerLib.
>>> 1. SecPlatformMain() modifies IDT[29] to point to your VC handler.
>>> This step helps to build the VC handler in whole 32bit
>> mode SEC+PEI.
>>
>> That can probably be done, but duplicates a lot of code - all of the
>> exception entry assembler code.
>>
>> Additionally, UefiCpuPkg/CpuMpPei/CpuMpPei.c will also invoke
>> InitializeCpuExceptionHandlers() registering a new IDT[29] entry.
>>
>>> 2. Create a new DXE driver with dependency set to TRUE and call
>>> RegisterCpuInteruptHandler(29, xx) in its entrypoint to
>> register VC handler for whole 64bit mode DXE.
>>> 3. Platform FDF uses apriori file mechanism to make sure the driver
>>> created in step #2 is dispatched as the 1st driver in
>> DXE phase. This step is optional if you accept there is some time
>> that VC handler is not setup in early DXE phase.
>>
>> Tracing the execution of an apriori driver shows that this happens after
>> DXE has initialized its exception handler and #VCs occur before a
>> handler
>> can be reigstered by the new driver, causing a failure.
>>
>>> 4. In the new DXE driver, gets the EFI_VECTOR_HANDOFF_INFO
>>> (MdePkg\Include\Ppi\VectorHandoffInfo.h) from
>> configuration table.
>>> It reports failure if the vector_handoff table says
>>> DO_NOT_HOOK for #29.
>>> It re-produces vector_handoff table with #29 set to
>>> DO_NOT_HOOK so that no one could use CpuArch protocol to
>> override #29 handler.
>>>
>>>
>>> In general, I want to use the API/capability provided by
>>> CpuExceptionHandlerLib instead of directly modifying it for
>> handler registration.
>>> Directly modifying it gives an improper code reference/example for
>>> future developers.
>>
>> I also don't see how this method will allow me to easily propagate a new
>> exception value through the exception handling stack.
>>
>> My current plan was to create a CpuExceptionOverrideLib library that is
>> invoked as part of exception handling. This allows immediate ability to
>> hook any exception without having to wait for an opportunity to
>> register a
>> handler - which in the case of #VC, is too late. Future developers that
>> need immediate exception handling will be able to override the default
>> library without any modification to CpuExceptionHandlerLib.
>>
>>
>> The change would look something like this:
>>
>> diff --git
>> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
>> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
>> index 20148db74cf8..7ac86f56d7d2 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/CpuExceptionOverrideLib.h>
>> #include "CpuExceptionCommon.h"
>>
>> CONST UINTN mDoFarReturnFlag = 0;
>> @@ -24,6 +25,22 @@ CommonExceptionHandler (
>> IN EFI_SYSTEM_CONTEXT SystemContext
>> )
>> {
>> + EFI_STATUS Status;
>> +
>> + //
>> + // If the exception is overridden, exit early.
>> + //
>> + Status = OverrideCpuExceptionHandler (ExceptionType, SystemContext);
>> + if (Status == EFI_SUCCESS) {
>> + return;
>> + }
>> +
>> + //
>> + // If the exception was not overridden, then the extract the
>> exception value
>> + // to continue with.
>> + //
>> + ExceptionType = OVERRIDE_EXCEPTION (Status);
>> +
>>
>> (To request vector 0 (#DE), the return is encoded to be non-zero and the
>> exception value extracted)
>>
>>
>> The NULL implementation of the override library would just return the
>> current exception type so that exception processing continues as today.
>>
>> This seems to be the best way to handle the #VC exception without hard
>> coding it into CpuExceptionHandlerLib and being able to catch a #VC as
>> soon as possible.
>>
>> Thoughts?
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>> Ray
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>>>> Lendacky, Thomas
>>>> Sent: Tuesday, May 12, 2020 11:00 PM
>>>> To: Ni, Ray <ray.ni@intel.com>; devel@edk2.groups.io; afish@apple.com
>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek
>>>> <lersek@redhat.com>; Ard Biesheuvel
>>>> <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
>> Dong,
>>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>>>> You, Benjamin <benjamin.you@intel.com>; Bi,
>>>> Dandan <dandan.bi@intel.com>; Dong, Guo <guo.dong@intel.com>; Wu,
>>>> Hao A <hao.a.wu@intel.com>; Wang, Jian J
>>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>>> Subject: Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>>
>>>> On 5/11/20 12:24 AM, Ni, Ray wrote:
>>>>> Tom,
>>>>>
>>>>> I agree with the first issue. I am not quite clear on the second one.
>>>>
>>>> In regards to the exception propagation, the hypervisor is allowed to
>>>> request an exception as part of the return information. For
>>>> example, the
>>>> guest issues a RDMSR instruction for an invalid MSR. The hypervisor
>>>> would
>>>> normally inject a #GP into the guest. With SEV-ES, the VC handler
>>>> has to
>>>> do this. Hence the need to possibly propogate to other exception
>>>> handlers
>>>> after handling the #VC.
>>>>
>>>>>
>>>>> SourceLevelDebugPkg provides source level debugging support early
>>>>> in SEC
>>>>> through SourceLevelDebugPkg\Library\DebugAgent\SecPeiDebugAgent\.
>>>>>
>>>>> It hooks all Intel SDM defined exceptions. It hooks INT32
>>>>> additionally to
>>>>> support breaking from HOST.
>>>>>
>>>>> It doesn't use CpuExceptionLib because it hooks in very early SEC
>>>>> phase.
>>>>>
>>>>> Can you use the same way?
>>>>
>>>> I can look at trying to do something like this. I guess the source
>>>> level
>>>> debug needs to be aware of all the exceptions, which is why it
>>>> hooks all
>>>> them. The SEV-ES support is only concerned with the #VC exception.
>>>> It just
>>>> seems like a lot of duplicated and extra code vs. checking for /
>>>> handling
>>>> the #VC exception in the CpuExceptionHandler library.
>>>>
>>>> My plan for v8 is/was to have a NULL VmgExitLib library, of which
>>>> the #VC
>>>> handler would be part of the interface, with the CpuExceptionHandler
>>>> library invoking the #VC handler on #VC exception and having the
>>>> OvmfPkg
>>>> provide a VmgExitLib library with all the functionality.
>>>>
>>>> Thanks,
>>>> Tom
>>>>
>>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>
>>>>> *From:* devel@edk2.groups.io <devel@edk2.groups.io> *On Behalf Of
>>>>> *Andrew
>>>>> Fish via groups.io
>>>>> *Sent:* Sunday, May 10, 2020 3:10 AM
>>>>> *To:* devel@edk2.groups.io; thomas.lendacky@amd.com
>>>>> *Cc:* Ni, Ray <ray.ni@intel.com>; Justen, Jordan L
>>>>> <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard
>>>>> Biesheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D
>>>>> <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
>>>>> Dong,
>>>>> Eric <eric.dong@intel.com>; Brijesh Singh <brijesh.singh@amd.com>;
>>>>> You,
>>>>> Benjamin <benjamin.you@intel.com>; Bi, Dandan
>>>>> <dandan.bi@intel.com>; Dong,
>>>>> Guo <guo.dong@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Wang,
>>>>> Jian J
>>>>> <jian.j.wang@intel.com>; Ma, Maurice <maurice.ma@intel.com>
>>>>> *Subject:* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>>
>>>>>
>>>>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas
>>>>> <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>> wrote:
>>>>>
>>>>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>>>>
>>>>> Tom,
>>>>>
>>>>>
>>>>> Hi Ray,
>>>>>
>>>>>
>>>>> I have a bit concern on your change that directly modifies
>>>>> CpuExceptionHandlerLib to handle
>>>>> exception #29. Today's CpuExceptionHandlerLib simplify
>>>>> dumps the
>>>>> exception context for
>>>>> every exception. Any component which wants to do
>>>>> specific handling
>>>>> of certain exceptions
>>>>> should call RegisterCpuInterruptHandler(). Such as code
>>>>> in CpuDxe
>>>>> driver:
>>>>> if (HEAP_GUARD_NONSTOP_MODE ||
>>>>> NULL_DETECTION_NONSTOP_MODE) {
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
>>>>> DebugExceptionHandler);
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>>>> PageFaultExceptionHandler);
>>>>> }
>>>>> Is it possible for your feature to follow the same pattern?
>>>>>
>>>>>
>>>>> There are two problems:
>>>>>
>>>>> The first is that RegisterCpuInterruptHandler() is not
>>>>> implemented for
>>>>> both the SEC and PEI phases, so it is not currently possible to
>>>>> register a handler that early.
>>>>>
>>>>> The second is that I need to be able to propagate an
>>>>> exception request
>>>>> from the hypervisor. With the current implementation there
>>>>> doesn't
>>>>> appear to be an easy way to perform this propagation.
>>>>>
>>>>> If there's a way to accomplish both of the above I wouldn't
>>>>> be opposed
>>>>> to using RegisterCpuInterruptHandler() as long as there are
>>>>> no #VCs
>>>>> that can occur between initializing exception handling and and
>>>>> registering the #VC handler.
>>>>>
>>>>> Thomas,
>>>>>
>>>>> As you point out it is tricky dealing with XIP code. You can't have
>>>>> globals that you can write and generally you use a PEI service to
>>>>> look
>>>>> tings up, the most common thing being using a HOB. But SEC has no
>>>>> services
>>>>> and I'm not sure you really want to be calling into the PEI Core on a
>>>>> random exception.
>>>>>
>>>>> Here are the best options that popped into my head after reading
>>>>> your email
>>>>>
>>>>> 1) IDT in RAM
>>>>>
>>>>> If your code populates the IDT the IDTR gives you access to the
>>>>> address of
>>>>> the IDTR via an instruction. The PI Spec reserves IDT - sizeof
>>>>> (UNITN) for
>>>>> a cached copy of the PEI Services Table, but otther than that you
>>>>> are good
>>>>> to go. It should be possible to have a global so you can have the
>>>>> table
>>>>> required to implement RegisterCpuInterruptHandler(). There might
>>>>> be some
>>>>> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing
>>>>> data
>>>>> after the IDT would be a good option. In general if your code
>>>>> allocates
>>>>> the memory for the IDT then you can treat the IDT as part of your
>>>>> private
>>>>> context data structure and that gives you access
>>>>>
>>>>> 2) IDT in ROM.
>>>>>
>>>>> For this it seems like you need a library to link in to
>>>>> the CpuExceptionHandlerLib that allows you to override the
>>>>> handler. If
>>>>> CpuInterruptHandlerOverride() returns NULL you do the current
>>>>> behavior if
>>>>> not NULL then you call the returned handler.
>>>>>
>>>>> EFI_CPU_INTERRUPT_HANDLER
>>>>>
>>>>> EFIAPI
>>>>>
>>>>> OverrideCpuInterruptHandler (
>>>>>
>>>>> IN EFI_EXCEPTION_TYPE InterruptType
>>>>>
>>>>> );
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Andrew Fish
>>>>>
>>>>> PS Off topic, but it would also be useful to have a library that
>>>>> overrides
>>>>> the state dump display. For example using Xcode you can always
>>>>> display a
>>>>> stack frame from the exception handler.
>>>>>
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>
>>>>> -----Original Message-----
>>>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>>
>>>>> Sent: Saturday, May 9, 2020 3:16 AM
>>>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek
>>>>> <lersek@redhat.com <mailto:lersek@redhat.com>>; Ard
>>>>> Biesheuvel
>>>>> <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>; Kinney, Michael D
>>>>> <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>>>> <liming.gao@intel.com
>>>>> <mailto:liming.gao@intel.com>>; Dong,
>>>>> Eric <eric.dong@intel.com
>>>>> <mailto:eric.dong@intel.com>>; Ni,
>>>>> Ray <ray.ni@intel.com <mailto:ray.ni@intel.com>>;
>>>>> Brijesh
>>>>> Singh <brijesh.singh@amd.com
>>>>> <mailto:brijesh.singh@amd.com>>;
>>>>> You, Benjamin
>>>>> <benjamin.you@intel.com
>>>>> <mailto:benjamin.you@intel.com>>; Bi,
>>>>> Dandan <dandan.bi@intel.com
>>>>> <mailto:dandan.bi@intel.com>>;
>>>>> Dong, Guo <guo.dong@intel.com
>>>>> <mailto:guo.dong@intel.com>>;
>>>>> Wu, Hao A
>>>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>;
>>>>> Wang, Jian J
>>>>> <jian.j.wang@intel.com
>>>>> <mailto:jian.j.wang@intel.com>>; Ma,
>>>>> Maurice <maurice.ma@intel.com
>>>>> <mailto:maurice.ma@intel.com>>
>>>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>> I was able to use the pull request method that Laszlo
>>>>> documented and fixed
>>>>> up all of the issues identified by the VS compiler.
>>>>>
>>>>> An additional change I'm planning to make for the
>>>>> next version
>>>>> (v8) of the
>>>>> patches is to create a NULL library instance of the
>>>>> VmgExitLib
>>>>> that will
>>>>> also include the #VC handler function. This will
>>>>> reduce the
>>>>> amount of code
>>>>> associated with this feature for platforms that don't
>>>>> use/support SEV-ES.
>>>>>
>>>>> Laszlo, this will mean that I will introduce a
>>>>> version of the
>>>>> VmgExitLib
>>>>> under OvmfPkg that will provide the majority of the
>>>>> functionality that is
>>>>> present today in UefiCpuPkg. In essence, the
>>>>> functionality in
>>>>> v7 patches 8
>>>>> and 11 - 25 will now live under OvmfPkg instead of
>>>>> UefiCpuPkg.
>>>>> I think
>>>>> this is the better way to do this. Let me know if
>>>>> you have any
>>>>> concerns.
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>>>
>>>>> This patch series provides support for running
>>>>> EDK2/OVMF
>>>>> under SEV-ES.
>>>>>
>>>>> Secure Encrypted Virtualization - Encrypted
>>>>> State (SEV-ES)
>>>>> expands on the
>>>>> SEV support to protect the guest register state
>>>>> from the
>>>>> hypervisor. See
>>>>> "AMD64 Architecture Programmer's Manual Volume
>>>>> 2: System
>>>>> Programming",
>>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>>
>>>>> In order to allow a hypervisor to perform
>>>>> functions on
>>>>> behalf of a guest,
>>>>> there is architectural support for notifying a
>>>>> guest's
>>>>> operating system
>>>>> when certain types of VMEXITs are about to
>>>>> occur. This
>>>>> allows the guest to
>>>>> selectively share information with the
>>>>> hypervisor to
>>>>> satisfy the requested
>>>>> function. The notification is performed using a new
>>>>> exception, the VMM
>>>>> Communication exception (#VC). The information
>>>>> is shared
>>>>> through the
>>>>> Guest-Hypervisor Communication Block (GHCB)
>>>>> using the
>>>>> VMGEXIT instruction.
>>>>> The GHCB format and the protocol for using it is
>>>>> documented in "SEV-ES
>>>>> Guest-Hypervisor Communication Block
>>>>> Standardization" [2].
>>>>>
>>>>> The main areas of the EDK2 code that are updated to
>>>>> support SEV-ES are
>>>>> around the exception handling support and the AP
>>>>> boot support.
>>>>>
>>>>> Exception support is required starting in Sec,
>>>>> continuing
>>>>> through Pei
>>>>> and into Dxe in order to handle #VC exceptions
>>>>> that are
>>>>> generated. Each
>>>>> AP requires it's own GHCB page as well as a page
>>>>> to hold
>>>>> values specific
>>>>> to that AP.
>>>>>
>>>>> AP booting poses some interesting challenges. The
>>>>> INIT-SIPI-SIPI sequence
>>>>> is typically used to boot the APs. However, the
>>>>> hypervisor
>>>>> is not allowed
>>>>> to update the guest registers. The GHCB document
>>>>> [2] talks
>>>>> about how SMP
>>>>> booting under SEV-ES is performed.
>>>>>
>>>>> Since the GHCB page must be a shared
>>>>> (unencrypted) page,
>>>>> the processor
>>>>> must be running in long mode in order for the
>>>>> guest and
>>>>> hypervisor to
>>>>> communicate with each other. As a result, SEV-ES
>>>>> is only
>>>>> supported under
>>>>> the X64 architecture.
>>>>>
>>>>>
>>>>
>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%25
>> 25
>>>>
>> 2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe
>>
>>>>
>> 4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCid
>>
>>>> wLMl5c%3D&reserved=0
>>>>>
>>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%252
>> 52
>>>>
>> F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884
>>
>>>>
>> e608e11a82d994e183d%7C0%7C0%7C637247716490462692&sdata=i3CuKMgAY08Cl%2FZWool7SIc3DTf%2BVA9HE%2BwpC8
>>
>>>> lyZo0%3D&reserved=0>
>>>>>
>>>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>>>>
>>>>
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f
>>
>>>>
>> 3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2
>>
>>>> XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>>>
>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-
>>>>
>>>>
>> content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56b
>>
>>>>
>> a3c1%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637247716490472688&sdata=7GPXxfEPOzDIg8uFx2rx108eY4B
>>
>>>> NIeKe0Of4K5Kuix4%3D&reserved=0>
>>>>>
>>>>> ---
>>>>>
>>>>> These patches are based on commit:
>>>>> be7295b36405 (".python/SpellCheck: Increase
>>>>> SpellCheck
>>>>> plugin max failures")
>>>>>
>>>>> Proper execution of SEV-ES relies on Bugzilla
>>>>> 2340 being
>>>>> fixed.
>>>>>
>>>>> A version of the tree (with an extra patch to
>>>>> workaround
>>>>> Bugzilla 2340) can
>>>>> be found at:
>>>>>
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>>
>> es-
>>>>
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e60
>>
>>>>
>> 8e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedv
>>
>>>> E%3D&reserved=0
>>>>>
>>>>
>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-
>>
>>>> es-
>>>>
>> v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Ca6a68a0fea9147d39c2508d7f56ba3c1%7C3dd8961fe4884e608e1
>>
>>>>
>> 1a82d994e183d%7C0%7C0%7C637247716490482690&sdata=27Er3PcupFhMsb%2F%2F5%2B9we7gW9NaDcjbVRgNp%2F%2F
>>
>>>> 6vqMg%3D&reserved=0>
>>>>>
>>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>
>>>>> Cc: Benjamin You <benjamin.you@intel.com
>>>>> <mailto:benjamin.you@intel.com>>
>>>>> Cc: Dandan Bi <dandan.bi@intel.com
>>>>> <mailto:dandan.bi@intel.com>>
>>>>> Cc: Eric Dong <eric.dong@intel.com
>>>>> <mailto:eric.dong@intel.com>>
>>>>> Cc: Guo Dong <guo.dong@intel.com
>>>>> <mailto:guo.dong@intel.com>>
>>>>> Cc: Hao A Wu <hao.a.wu@intel.com
>>>>> <mailto:hao.a.wu@intel.com>>
>>>>> Cc: Jian J Wang <jian.j.wang@intel.com
>>>>> <mailto:jian.j.wang@intel.com>>
>>>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>
>>>>> Cc: Laszlo Ersek <lersek@redhat.com
>>>>> <mailto:lersek@redhat.com>>
>>>>> Cc: Liming Gao <liming.gao@intel.com
>>>>> <mailto:liming.gao@intel.com>>
>>>>> Cc: Maurice Ma <maurice.ma@intel.com
>>>>> <mailto:maurice.ma@intel.com>>
>>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>
>>>>> Cc: Ray Ni <ray.ni@intel.com
>>>>> <mailto:ray.ni@intel.com>>
>>>>>
>>>>> Changes since v6:
>>>>> - Add function comments to all functions,
>>>>> including local
>>>>> functions
>>>>> - Add function parameter direction to all
>>>>> functions (in/out)
>>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>>> - Ensure the per-CPU variable page remains
>>>>> encrypted
>>>>> - Coding-style fixes as identified by Ecc
>>>>>
>>>>> Changes since v5:
>>>>> - Remove extraneous VmgExitLib usage
>>>>> - Miscellaneous changes to address feedback
>>>>> (coding style,
>>>>> etc.)
>>>>>
>>>>> Changes since v4:
>>>>> - Move the SEV-ES protocol negotiation out of
>>>>> the SEC
>>>>> exception handler
>>>>> and into the SecMain.c file. As a result:
>>>>> - Move the SecGhcb related PCDs out of
>>>>> UefiCpuPkg and
>>>>> into OvmfPkg
>>>>> - Combine SecAMDSevVcHandler.c and
>>>>> PeiDxeAMDSevVcHandler.c into a
>>>>> single AMDSevVcHandler.c
>>>>> - Consolidate VmgExitLib usage into common
>>>>> LibraryClasses
>>>>> sections
>>>>> - Add documentation comments to the VmgExitLib
>>>>> functions
>>>>>
>>>>> Changes since v3:
>>>>> - Remove the need for the MP library
>>>>> finalization routine.
>>>>> The AP
>>>>> jump table address will be held by the
>>>>> hypervisor
>>>>> rather than
>>>>> communicated via the GHCB MSR. This removes
>>>>> some
>>>>> fragility around
>>>>> the UEFI to OS transition.
>>>>> - Rename the SEV-ES RIP reset area to SEV-ES
>>>>> workarea and
>>>>> use it to
>>>>> communicate the SEV-ES status, so that SEC CPU
>>>>> exception handling is
>>>>> only established for an SEV-ES guest.
>>>>> - Fix SMM build breakageAdd around
>>>>> QemuFlashPtrWrite().
>>>>> - Fix SMM build breakage by adding VC exception
>>>>> support
>>>>> the SMM CPU
>>>>> exception handling.
>>>>> - Add memory fencing around the invocation of
>>>>> AsmVmgExit().
>>>>> - Clarify comments around the SEV-ES AP reset
>>>>> RIP values
>>>>> and usage.
>>>>> - Move some PCD definitions from MdeModulePkg to
>>>>> UefiCpuPkg.
>>>>> - Remove the 16-bit code selector definition
>>>>> from MdeModulePkg
>>>>>
>>>>> Changes since v2:
>>>>> - Added a way to locate the SEV-ES fixed AP RIP
>>>>> address
>>>>> for starting
>>>>> AP's to avoid updating the actual flash
>>>>> image (build
>>>>> time location
>>>>> that is identified with a GUID value).
>>>>> - Create a VmgExit library to replace static
>>>>> inline functions.
>>>>> - Move some PCDs to the appropriate packages
>>>>> - Add support for writing to QEMU flash under
>>>>> SEV-ES
>>>>> - Add additional MMIO opcode support
>>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>>
>>>>> Changes since v1:
>>>>> - Patches reworked to be more specific to the
>>>>> component/area being updated
>>>>> and order of definition/usage
>>>>> - Created a library for VMGEXIT-related
>>>>> functions to
>>>>> replace use of inline
>>>>> functions
>>>>> - Allocation method for GDT changed from
>>>>> AllocatePool to
>>>>> AllocatePages
>>>>> - Early caching only enabled for SEV-ES guests
>>>>> - Ensure AP loop mode set to halt loop mode for
>>>>> SEV-ES guests
>>>>> - Reserved SEC GHCB-related memory areas when S3
>>>>> is enabled
>>>>>
>>>>> Tom Lendacky (43):
>>>>> MdeModulePkg: Create PCDs to be used in
>>>>> support of SEV-ES
>>>>> UefiCpuPkg: Create PCD to be used in support
>>>>> of SEV-ES
>>>>> MdePkg: Add the MSR definition for the GHCB
>>>>> register
>>>>> MdePkg: Add a structure definition for the GHCB
>>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages
>>>>> when
>>>>> creating page tables
>>>>> MdePkg/BaseLib: Add support for the XGETBV
>>>>> instruction
>>>>> MdePkg/BaseLib: Add support for the VMGEXIT
>>>>> instruction
>>>>> UefiCpuPkg: Implement library support for
>>>>> VMGEXIT
>>>>> OvmfPkg: Prepare OvmfPkg to use the
>>>>> VmgExitLib library
>>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to
>>>>> use the
>>>>> VmgExitLib library
>>>>> UefiCpuPkg/CpuExceptionHandler: Add base
>>>>> support for
>>>>> the #VC exception
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> IOIO_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Support
>>>>> string IO for
>>>>> IOIO_PROT NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for CPUID
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MSR_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for NPF
>>>>> NAE events (MMIO)
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for WBINVD
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for RDTSC
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for RDPMC
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for INVD
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> VMMCALL NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for RDTSCP
>>>>> NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MONITOR/MONITORX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for
>>>>> MWAIT/MWAITX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support
>>>>> for DR7
>>>>> Read/Write NAE
>>>>> events
>>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest
>>>>> indicator function
>>>>> OvmfPkg: Add support to perform SEV-ES
>>>>> initialization
>>>>> OvmfPkg: Create a GHCB page for use during
>>>>> Sec phase
>>>>> OvmfPkg/PlatformPei: Reserve GHCB-related
>>>>> areas if S3
>>>>> is supported
>>>>> OvmfPkg: Create GHCB pages for use during
>>>>> Pei and Dxe
>>>>> phase
>>>>> OvmfPkg/PlatformPei: Move early GDT into ram
>>>>> when
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>>> OvmfPkg: Reserve a page in memory for the
>>>>> SEV-ES usage
>>>>> OvmfPkg/ResetVector: Add support for a
>>>>> 32-bit SEV check
>>>>> OvmfPkg/Sec: Add #VC exception handling for
>>>>> Sec phase
>>>>> OvmfPkg/Sec: Enable cache early to speed up
>>>>> booting
>>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe:
>>>>> Bypass flash
>>>>> detection with
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Add a 16-bit protected mode code
>>>>> segment
>>>>> descriptor
>>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag
>>>>> to indicate
>>>>> if SEV-ES is
>>>>> enabled
>>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>>> OvmfPkg: Use the SEV-ES work area for the
>>>>> SEV-ES AP
>>>>> reset vector
>>>>> OvmfPkg: Move the GHCB allocations into
>>>>> reserved memory
>>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest
>>>>> APs for OS use
>>>>>
>>>>> MdeModulePkg/MdeModulePkg.dec
>>>>> | 9 +
>>>>> OvmfPkg/OvmfPkg.dec
>>>>> | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.dec
>>>>> | 17 +
>>>>> OvmfPkg/OvmfPkgIa32.dsc
>>>>> | 6 +
>>>>> OvmfPkg/OvmfPkgIa32X64.dsc
>>>>> | 6 +
>>>>> OvmfPkg/OvmfPkgX64.dsc
>>>>> | 6 +
>>>>> OvmfPkg/OvmfXen.dsc
>>>>> | 1 +
>>>>> UefiCpuPkg/UefiCpuPkg.dsc
>>>>> | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc
>>>>> | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
>>>>> | 2 +
>>>>> OvmfPkg/OvmfPkgX64.fdf
>>>>> | 9 +
>>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>>>>> | 2 +
>>>>> MdePkg/Library/BaseLib/BaseLib.inf
>>>>> | 4 +
>>>>> OvmfPkg/PlatformPei/PlatformPei.inf
>>>>> | 7 +
>>>>> .../FvbServicesRuntimeDxe.inf
>>>>> | 2 +
>>>>> OvmfPkg/ResetVector/ResetVector.inf
>>>>> | 8 +
>>>>> OvmfPkg/Sec/SecMain.inf
>>>>> | 4 +
>>>>> .../DxeCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> .../PeiCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> .../SecPeiCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> .../SmmCpuExceptionHandlerLib.inf
>>>>> | 5 +
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
>>>>> | 4 +
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
>>>>> | 4 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>> | 33 +
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h
>>>>> | 12 +-
>>>>> MdePkg/Include/Library/BaseLib.h
>>>>> | 31 +
>>>>> MdePkg/Include/Register/Amd/Fam17Msr.h
>>>>> | 42 +
>>>>> MdePkg/Include/Register/Amd/Ghcb.h
>>>>> | 136 ++
>>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h
>>>>> | 12 +
>>>>> .../QemuFlash.h
>>>>> | 13 +
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.h
>>>>> | 4 +-
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>> | 117 ++
>>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>> | 49 +
>>>>> .../CpuExceptionCommon.h
>>>>> | 2 +
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h
>>>>> | 68 +-
>>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c
>>>>> | 4 +-
>>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c
>>>>> | 11 +-
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c
>>>>> | 57 +-
>>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c
>>>>> | 45 +
>>>>> MdePkg/Library/BaseLib/X64/GccInline.c
>>>>> | 47 +
>>>>> .../MemEncryptSevLibInternal.c
>>>>> | 75 +-
>>>>> OvmfPkg/PlatformPei/AmdSev.c
>>>>> | 89 +
>>>>> OvmfPkg/PlatformPei/MemDetect.c
>>>>> | 23 +
>>>>> .../QemuFlash.c
>>>>> | 23 +-
>>>>> .../QemuFlashDxe.c
>>>>> | 22 +
>>>>> .../QemuFlashSmm.c
>>>>> | 16 +
>>>>> OvmfPkg/Sec/SecMain.c
>>>>> | 188 +-
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.c
>>>>> | 8 +-
>>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>> | 40 +
>>>>> .../CpuExceptionCommon.c
>>>>> | 2 +-
>>>>> .../Ia32/ArchAMDSevVcHandler.c
>>>>> | 38 +
>>>>> .../PeiDxeSmmCpuException.c
>>>>> | 16 +
>>>>> .../SecPeiCpuException.c
>>>>> | 16 +
>>>>> .../X64/ArchAMDSevVcHandler.c
>>>>> | 1699
>>>>> +++++++++++++++++
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
>>>>> | 113 +-
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c
>>>>> | 265 ++-
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
>>>>> | 19 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>> | 293 +++
>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
>>>>> | 2 +-
>>>>> MdeModulePkg/MdeModulePkg.uni
>>>>> | 8 +
>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>> | 37 +
>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>> | 31 +
>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>> | 32 +
>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>> | 34 +
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>> | 100 +
>>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm
>>>>> | 350 +++-
>>>>> OvmfPkg/ResetVector/ResetVector.nasmb
>>>>> | 20 +
>>>>> .../X64/ExceptionHandlerAsm.nasm
>>>>> | 17 +
>>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
>>>>> | 2 +-
>>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm
>>>>> | 15 +
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
>>>>> | 4 +-
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
>>>>> | 370 +++-
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>> | 15 +
>>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm
>>>>> | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.uni
>>>>> | 11 +
>>>>> 75 files changed, 4707 insertions(+), 102
>>>>> deletions(-)
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>> create mode 100644
>>>>> MdePkg/Include/Register/Amd/Ghcb.h
>>>>> create mode 100644
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>>
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>> create mode 100644
>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>> create mode 100644
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>
[-- Attachment #2: Type: text/html, Size: 110877 bytes --]
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-09 19:09 ` [edk2-devel] " Andrew Fish
2020-05-11 5:24 ` Ni, Ray
@ 2020-05-12 16:49 ` Lendacky, Thomas
2020-05-12 17:44 ` Lendacky, Thomas
1 sibling, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-12 16:49 UTC (permalink / raw)
To: Andrew Fish, devel
Cc: Ni, Ray, Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Mike Kinney,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
On 5/9/20 2:09 PM, Andrew Fish wrote:
>
>
>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
>> <mailto:thomas.lendacky@amd.com>> wrote:
>>
>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>> Tom,
>>
>> Hi Ray,
>>
>>> I have a bit concern on your change that directly modifies
>>> CpuExceptionHandlerLib to handle
>>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
>>> exception context for
>>> every exception. Any component which wants to do specific handling of
>>> certain exceptions
>>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe driver:
>>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG, DebugExceptionHandler);
>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>> PageFaultExceptionHandler);
>>> }
>>> Is it possible for your feature to follow the same pattern?
>>
>> There are two problems:
>>
>> The first is that RegisterCpuInterruptHandler() is not implemented for
>> both the SEC and PEI phases, so it is not currently possible to register
>> a handler that early.
>>
>> The second is that I need to be able to propagate an exception request
>> from the hypervisor. With the current implementation there doesn't
>> appear to be an easy way to perform this propagation.
>>
>> If there's a way to accomplish both of the above I wouldn't be opposed
>> to using RegisterCpuInterruptHandler() as long as there are no #VCs that
>> can occur between initializing exception handling and and registering
>> the #VC handler.
>>
>
> Thomas,
>
> As you point out it is tricky dealing with XIP code. You can't have
> globals that you can write and generally you use a PEI service to look
> tings up, the most common thing being using a HOB. But SEC has no services
> and I'm not sure you really want to be calling into the PEI Core on a
> random exception.
>
> Here are the best options that popped into my head after reading your email
> 1) IDT in RAM
> If your code populates the IDT the IDTR gives you access to the address of
> the IDTR via an instruction. The PI Spec reserves IDT - sizeof (UNITN) for
> a cached copy of the PEI Services Table, but otther than that you are good
> to go. It should be possible to have a global so you can have the table
> required to implement RegisterCpuInterruptHandler(). There might be some
> usage of IDT - ( 2* sizeof(UINTN)), I know I'm guilty, so storing data
> after the IDT would be a good option. In general if your code allocates
> the memory for the IDT then you can treat the IDT as part of your private
> context data structure and that gives you access
>
> 2) IDT in ROM.
> For this it seems like you need a library to link in to
> the CpuExceptionHandlerLib that allows you to override the handler. If
> CpuInterruptHandlerOverride() returns NULL you do the current behavior if
> not NULL then you call the returned handler.
>
> EFI_CPU_INTERRUPT_HANDLER
> EFIAPI
> OverrideCpuInterruptHandler (
> IN EFI_EXCEPTION_TYPE InterruptType
> );
I like the override idea in general, if that works for everyone. There
could be a NULL instance that never overrides the exception. Then it can
be implemented by those packages that need it. In this case a library can
be created in OvmfPkg that provides an override for #VC and the override
return code can determine if further processing is performed.
Thanks,
Tom
>
> Thanks,
>
> Andrew Fish
>
> PS Off topic, but it would also be useful to have a library that overrides
> the state dump display. For example using Xcode you can always display a
> stack frame from the exception handler.
>
>
>> Thanks,
>> Tom
>>
>>> Thanks,
>>> Ray
>>>> -----Original Message-----
>>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>>> <mailto:thomas.lendacky@amd.com>>
>>>> Sent: Saturday, May 9, 2020 3:16 AM
>>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek <lersek@redhat.com
>>>> <mailto:lersek@redhat.com>>; Ard Biesheuvel
>>>> <ard.biesheuvel@linaro.org <mailto:ard.biesheuvel@linaro.org>>;
>>>> Kinney, Michael D <michael.d.kinney@intel.com
>>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>>> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
>>>> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni, Ray
>>>> <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh Singh
>>>> <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>; You, Benjamin
>>>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi, Dandan
>>>> <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>; Dong, Guo
>>>> <guo.dong@intel.com <mailto:guo.dong@intel.com>>; Wu, Hao A
>>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
>>>> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma, Maurice
>>>> <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>>
>>>> I was able to use the pull request method that Laszlo documented and fixed
>>>> up all of the issues identified by the VS compiler.
>>>>
>>>> An additional change I'm planning to make for the next version (v8) of the
>>>> patches is to create a NULL library instance of the VmgExitLib that will
>>>> also include the #VC handler function. This will reduce the amount of code
>>>> associated with this feature for platforms that don't use/support SEV-ES.
>>>>
>>>> Laszlo, this will mean that I will introduce a version of the VmgExitLib
>>>> under OvmfPkg that will provide the majority of the functionality that is
>>>> present today in UefiCpuPkg. In essence, the functionality in v7 patches 8
>>>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
>>>> this is the better way to do this. Let me know if you have any concerns.
>>>>
>>>> Thanks,
>>>> Tom
>>>>
>>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>>> This patch series provides support for running EDK2/OVMF under SEV-ES.
>>>>>
>>>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
>>>>> SEV support to protect the guest register state from the hypervisor. See
>>>>> "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
>>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>>
>>>>> In order to allow a hypervisor to perform functions on behalf of a guest,
>>>>> there is architectural support for notifying a guest's operating system
>>>>> when certain types of VMEXITs are about to occur. This allows the
>>>>> guest to
>>>>> selectively share information with the hypervisor to satisfy the
>>>>> requested
>>>>> function. The notification is performed using a new exception, the VMM
>>>>> Communication exception (#VC). The information is shared through the
>>>>> Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT
>>>>> instruction.
>>>>> The GHCB format and the protocol for using it is documented in "SEV-ES
>>>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>>>
>>>>> The main areas of the EDK2 code that are updated to support SEV-ES are
>>>>> around the exception handling support and the AP boot support.
>>>>>
>>>>> Exception support is required starting in Sec, continuing through Pei
>>>>> and into Dxe in order to handle #VC exceptions that are generated. Each
>>>>> AP requires it's own GHCB page as well as a page to hold values specific
>>>>> to that AP.
>>>>>
>>>>> AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
>>>>> is typically used to boot the APs. However, the hypervisor is not allowed
>>>>> to update the guest registers. The GHCB document [2] talks about how SMP
>>>>> booting under SEV-ES is performed.
>>>>>
>>>>> Since the GHCB page must be a shared (unencrypted) page, the processor
>>>>> must be running in long mode in order for the guest and hypervisor to
>>>>> communicate with each other. As a result, SEV-ES is only supported under
>>>>> the X64 architecture.
>>>>>
>>>>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0
>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364539668&sdata=I5jER2hmPSQP7r1TLLZp1UwuMqFkPbg4Zq%2BiUQ%2BLviw%3D&reserved=0>
>>>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364549626&sdata=9UxP5Z73Vb7GVP9mIhl2L89FN3xJrTG1PYr1RQS4Iqg%3D&reserved=0>
>>>>>
>>>>> ---
>>>>>
>>>>> These patches are based on commit:
>>>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max
>>>>> failures")
>>>>>
>>>>> Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
>>>>>
>>>>> A version of the tree (with an extra patch to workaround Bugzilla
>>>>> 2340) can
>>>>> be found at:
>>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0
>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364549626&sdata=2TQjm7iBKcrdnV8Jq6amArZPUCzyn%2BpoxS8lHuXa1Tk%3D&reserved=0>
>>>>>
>>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>>>> <mailto:ard.biesheuvel@linaro.org>>
>>>>> Cc: Benjamin You <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>
>>>>> Cc: Dandan Bi <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>
>>>>> Cc: Eric Dong <eric.dong@intel.com <mailto:eric.dong@intel.com>>
>>>>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
>>>>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
>>>>> Cc: Jian J Wang <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>
>>>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>
>>>>> Cc: Laszlo Ersek <lersek@redhat.com <mailto:lersek@redhat.com>>
>>>>> Cc: Liming Gao <liming.gao@intel.com <mailto:liming.gao@intel.com>>
>>>>> Cc: Maurice Ma <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>
>>>>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>>>>>
>>>>> Changes since v6:
>>>>> - Add function comments to all functions, including local functions
>>>>> - Add function parameter direction to all functions (in/out)
>>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>>> - Ensure the per-CPU variable page remains encrypted
>>>>> - Coding-style fixes as identified by Ecc
>>>>>
>>>>> Changes since v5:
>>>>> - Remove extraneous VmgExitLib usage
>>>>> - Miscellaneous changes to address feedback (coding style, etc.)
>>>>>
>>>>> Changes since v4:
>>>>> - Move the SEV-ES protocol negotiation out of the SEC exception handler
>>>>> and into the SecMain.c file. As a result:
>>>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
>>>>> - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
>>>>> single AMDSevVcHandler.c
>>>>> - Consolidate VmgExitLib usage into common LibraryClasses sections
>>>>> - Add documentation comments to the VmgExitLib functions
>>>>>
>>>>> Changes since v3:
>>>>> - Remove the need for the MP library finalization routine. The AP
>>>>> jump table address will be held by the hypervisor rather than
>>>>> communicated via the GHCB MSR. This removes some fragility around
>>>>> the UEFI to OS transition.
>>>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
>>>>> communicate the SEV-ES status, so that SEC CPU exception handling is
>>>>> only established for an SEV-ES guest.
>>>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>>>> - Fix SMM build breakage by adding VC exception support the SMM CPU
>>>>> exception handling.
>>>>> - Add memory fencing around the invocation of AsmVmgExit().
>>>>> - Clarify comments around the SEV-ES AP reset RIP values and usage.
>>>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>>>
>>>>> Changes since v2:
>>>>> - Added a way to locate the SEV-ES fixed AP RIP address for starting
>>>>> AP's to avoid updating the actual flash image (build time location
>>>>> that is identified with a GUID value).
>>>>> - Create a VmgExit library to replace static inline functions.
>>>>> - Move some PCDs to the appropriate packages
>>>>> - Add support for writing to QEMU flash under SEV-ES
>>>>> - Add additional MMIO opcode support
>>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>>
>>>>> Changes since v1:
>>>>> - Patches reworked to be more specific to the component/area being
>>>>> updated
>>>>> and order of definition/usage
>>>>> - Created a library for VMGEXIT-related functions to replace use of
>>>>> inline
>>>>> functions
>>>>> - Allocation method for GDT changed from AllocatePool to AllocatePages
>>>>> - Early caching only enabled for SEV-ES guests
>>>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>>>
>>>>> Tom Lendacky (43):
>>>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>>>> MdePkg: Add the MSR definition for the GHCB register
>>>>> MdePkg: Add a structure definition for the GHCB
>>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables
>>>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>>>> UefiCpuPkg: Implement library support for VMGEXIT
>>>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
>>>>> UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO)
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
>>>>> events
>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
>>>>> events
>>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
>>>>> OvmfPkg: Add support to perform SEV-ES initialization
>>>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
>>>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
>>>>> OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
>>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
>>>>> SEV-ES is enabled
>>>>> UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
>>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
>>>>> enabled
>>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
>>>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>>>
>>>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>>>> OvmfPkg/OvmfPkg.dec | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>>>> OvmfPkg/OvmfXen.dsc | 1 +
>>>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>>>> .../QemuFlash.h | 13 +
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>>>> .../CpuExceptionCommon.h | 2 +
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>>>> .../MemEncryptSevLibInternal.c | 75 +-
>>>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>>>> .../QemuFlash.c | 23 +-
>>>>> .../QemuFlashDxe.c | 22 +
>>>>> .../QemuFlashSmm.c | 16 +
>>>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>>>> .../CpuExceptionCommon.c | 2 +-
>>>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>>>> .../PeiDxeSmmCpuException.c | 16 +
>>>>> .../SecPeiCpuException.c | 16 +
>>>>> .../X64/ArchAMDSevVcHandler.c | 1699 +++++++++++++++++
>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>>> create mode 100644
>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>> create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>>
>>
>>
>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-12 16:49 ` Lendacky, Thomas
@ 2020-05-12 17:44 ` Lendacky, Thomas
2020-05-12 20:10 ` Lendacky, Thomas
0 siblings, 1 reply; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-12 17:44 UTC (permalink / raw)
To: Andrew Fish, devel
Cc: Ni, Ray, Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Mike Kinney,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
On 5/12/20 11:49 AM, Tom Lendacky wrote:
> On 5/9/20 2:09 PM, Andrew Fish wrote:
>>
>>
>>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
>>> <mailto:thomas.lendacky@amd.com>> wrote:
>>>
>>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>>> Tom,
>>>
>>> Hi Ray,
>>>
>>>> I have a bit concern on your change that directly modifies
>>>> CpuExceptionHandlerLib to handle
>>>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
>>>> exception context for
>>>> every exception. Any component which wants to do specific handling of
>>>> certain exceptions
>>>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe driver:
>>>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
>>>> DebugExceptionHandler);
>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>>> PageFaultExceptionHandler);
>>>> }
>>>> Is it possible for your feature to follow the same pattern?
>>>
>>> There are two problems:
>>>
>>> The first is that RegisterCpuInterruptHandler() is not implemented for
>>> both the SEC and PEI phases, so it is not currently possible to
>>> register a handler that early.
>>>
>>> The second is that I need to be able to propagate an exception request
>>> from the hypervisor. With the current implementation there doesn't
>>> appear to be an easy way to perform this propagation.
>>>
>>> If there's a way to accomplish both of the above I wouldn't be opposed
>>> to using RegisterCpuInterruptHandler() as long as there are no #VCs
>>> that can occur between initializing exception handling and and
>>> registering the #VC handler.
>>>
>>
>> Thomas,
>>
>> As you point out it is tricky dealing with XIP code. You can't have
>> globals that you can write and generally you use a PEI service to look
>> tings up, the most common thing being using a HOB. But SEC has no
>> services and I'm not sure you really want to be calling into the PEI
>> Core on a random exception.
>>
>> Here are the best options that popped into my head after reading your email
>> 1) IDT in RAM
>> If your code populates the IDT the IDTR gives you access to the address
>> of the IDTR via an instruction. The PI Spec reserves IDT - sizeof
>> (UNITN) for a cached copy of the PEI Services Table, but otther than
>> that you are good to go. It should be possible to have a global so you
>> can have the table required to implement RegisterCpuInterruptHandler().
>> There might be some usage of IDT - ( 2* sizeof(UINTN)), I know I'm
>> guilty, so storing data after the IDT would be a good option. In general
>> if your code allocates the memory for the IDT then you can treat the IDT
>> as part of your private context data structure and that gives you access
>>
>> 2) IDT in ROM.
>> For this it seems like you need a library to link in to
>> the CpuExceptionHandlerLib that allows you to override the handler. If
>> CpuInterruptHandlerOverride() returns NULL you do the current behavior
>> if not NULL then you call the returned handler.
>>
>> EFI_CPU_INTERRUPT_HANDLER
>> EFIAPI
>> OverrideCpuInterruptHandler (
>> IN EFI_EXCEPTION_TYPE InterruptType
>> );
>
> I like the override idea in general, if that works for everyone. There
> could be a NULL instance that never overrides the exception. Then it can
> be implemented by those packages that need it. In this case a library can
> be created in OvmfPkg that provides an override for #VC and the override
> return code can determine if further processing is performed.
Hmm... so the problem is that EFI_CPU_INTERRUPT_HANDLER does not return a
value. So maybe just create an override type specific to the override
library? I don't think that would present any issues.
typedef
EFI_STATUS
(EFIAPI *CPU_INTERRUPT_OVERRRIDE) (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
);
CPU_INTERRUPT_OVERRIDE
EFIAPI
OverrideCpuInterruptHandler (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
);
Thanks,
Tom
>
> Thanks,
> Tom
>
>>
>> Thanks,
>>
>> Andrew Fish
>>
>> PS Off topic, but it would also be useful to have a library that
>> overrides the state dump display. For example using Xcode you can always
>> display a stack frame from the exception handler.
>>
>>
>>> Thanks,
>>> Tom
>>>
>>>> Thanks,
>>>> Ray
>>>>> -----Original Message-----
>>>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>>>> <mailto:thomas.lendacky@amd.com>>
>>>>> Sent: Saturday, May 9, 2020 3:16 AM
>>>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek <lersek@redhat.com
>>>>> <mailto:lersek@redhat.com>>; Ard Biesheuvel
>>>>> <ard.biesheuvel@linaro.org <mailto:ard.biesheuvel@linaro.org>>;
>>>>> Kinney, Michael D <michael.d.kinney@intel.com
>>>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>>>> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
>>>>> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni, Ray
>>>>> <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh Singh
>>>>> <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>; You, Benjamin
>>>>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi, Dandan
>>>>> <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>; Dong, Guo
>>>>> <guo.dong@intel.com <mailto:guo.dong@intel.com>>; Wu, Hao A
>>>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
>>>>> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma, Maurice
>>>>> <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>>>
>>>>> I was able to use the pull request method that Laszlo documented and
>>>>> fixed
>>>>> up all of the issues identified by the VS compiler.
>>>>>
>>>>> An additional change I'm planning to make for the next version (v8)
>>>>> of the
>>>>> patches is to create a NULL library instance of the VmgExitLib that will
>>>>> also include the #VC handler function. This will reduce the amount of
>>>>> code
>>>>> associated with this feature for platforms that don't use/support
>>>>> SEV-ES.
>>>>>
>>>>> Laszlo, this will mean that I will introduce a version of the VmgExitLib
>>>>> under OvmfPkg that will provide the majority of the functionality
>>>>> that is
>>>>> present today in UefiCpuPkg. In essence, the functionality in v7
>>>>> patches 8
>>>>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
>>>>> this is the better way to do this. Let me know if you have any concerns.
>>>>>
>>>>> Thanks,
>>>>> Tom
>>>>>
>>>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>>>> This patch series provides support for running EDK2/OVMF under SEV-ES.
>>>>>>
>>>>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands
>>>>>> on the
>>>>>> SEV support to protect the guest register state from the hypervisor.
>>>>>> See
>>>>>> "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
>>>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>>>
>>>>>> In order to allow a hypervisor to perform functions on behalf of a
>>>>>> guest,
>>>>>> there is architectural support for notifying a guest's operating system
>>>>>> when certain types of VMEXITs are about to occur. This allows the
>>>>>> guest to
>>>>>> selectively share information with the hypervisor to satisfy the
>>>>>> requested
>>>>>> function. The notification is performed using a new exception, the VMM
>>>>>> Communication exception (#VC). The information is shared through the
>>>>>> Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT
>>>>>> instruction.
>>>>>> The GHCB format and the protocol for using it is documented in "SEV-ES
>>>>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>>>>
>>>>>> The main areas of the EDK2 code that are updated to support SEV-ES are
>>>>>> around the exception handling support and the AP boot support.
>>>>>>
>>>>>> Exception support is required starting in Sec, continuing through Pei
>>>>>> and into Dxe in order to handle #VC exceptions that are generated.
>>>>>> Each
>>>>>> AP requires it's own GHCB page as well as a page to hold values
>>>>>> specific
>>>>>> to that AP.
>>>>>>
>>>>>> AP booting poses some interesting challenges. The INIT-SIPI-SIPI
>>>>>> sequence
>>>>>> is typically used to boot the APs. However, the hypervisor is not
>>>>>> allowed
>>>>>> to update the guest registers. The GHCB document [2] talks about how
>>>>>> SMP
>>>>>> booting under SEV-ES is performed.
>>>>>>
>>>>>> Since the GHCB page must be a shared (unencrypted) page, the processor
>>>>>> must be running in long mode in order for the guest and hypervisor to
>>>>>> communicate with each other. As a result, SEV-ES is only supported
>>>>>> under
>>>>>> the X64 architecture.
>>>>>>
>>>>>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0
>>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364539668&sdata=I5jER2hmPSQP7r1TLLZp1UwuMqFkPbg4Zq%2BiUQ%2BLviw%3D&reserved=0>
>>>>>>
>>>>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364549626&sdata=9UxP5Z73Vb7GVP9mIhl2L89FN3xJrTG1PYr1RQS4Iqg%3D&reserved=0>
>>>>>>
>>>>>>
>>>>>> ---
>>>>>>
>>>>>> These patches are based on commit:
>>>>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max
>>>>>> failures")
>>>>>>
>>>>>> Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
>>>>>>
>>>>>> A version of the tree (with an extra patch to workaround Bugzilla
>>>>>> 2340) can
>>>>>> be found at:
>>>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0
>>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364549626&sdata=2TQjm7iBKcrdnV8Jq6amArZPUCzyn%2BpoxS8lHuXa1Tk%3D&reserved=0>
>>>>>>
>>>>>>
>>>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>>>>> <mailto:ard.biesheuvel@linaro.org>>
>>>>>> Cc: Benjamin You <benjamin.you@intel.com
>>>>>> <mailto:benjamin.you@intel.com>>
>>>>>> Cc: Dandan Bi <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>
>>>>>> Cc: Eric Dong <eric.dong@intel.com <mailto:eric.dong@intel.com>>
>>>>>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
>>>>>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>
>>>>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>>>>> <mailto:jordan.l.justen@intel.com>>
>>>>>> Cc: Laszlo Ersek <lersek@redhat.com <mailto:lersek@redhat.com>>
>>>>>> Cc: Liming Gao <liming.gao@intel.com <mailto:liming.gao@intel.com>>
>>>>>> Cc: Maurice Ma <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>>>>> <mailto:michael.d.kinney@intel.com>>
>>>>>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>>>>>>
>>>>>> Changes since v6:
>>>>>> - Add function comments to all functions, including local functions
>>>>>> - Add function parameter direction to all functions (in/out)
>>>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>>>> - Ensure the per-CPU variable page remains encrypted
>>>>>> - Coding-style fixes as identified by Ecc
>>>>>>
>>>>>> Changes since v5:
>>>>>> - Remove extraneous VmgExitLib usage
>>>>>> - Miscellaneous changes to address feedback (coding style, etc.)
>>>>>>
>>>>>> Changes since v4:
>>>>>> - Move the SEV-ES protocol negotiation out of the SEC exception handler
>>>>>> and into the SecMain.c file. As a result:
>>>>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
>>>>>> - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
>>>>>> single AMDSevVcHandler.c
>>>>>> - Consolidate VmgExitLib usage into common LibraryClasses sections
>>>>>> - Add documentation comments to the VmgExitLib functions
>>>>>>
>>>>>> Changes since v3:
>>>>>> - Remove the need for the MP library finalization routine. The AP
>>>>>> jump table address will be held by the hypervisor rather than
>>>>>> communicated via the GHCB MSR. This removes some fragility around
>>>>>> the UEFI to OS transition.
>>>>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
>>>>>> communicate the SEV-ES status, so that SEC CPU exception handling is
>>>>>> only established for an SEV-ES guest.
>>>>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>>>>> - Fix SMM build breakage by adding VC exception support the SMM CPU
>>>>>> exception handling.
>>>>>> - Add memory fencing around the invocation of AsmVmgExit().
>>>>>> - Clarify comments around the SEV-ES AP reset RIP values and usage.
>>>>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>>>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>>>>
>>>>>> Changes since v2:
>>>>>> - Added a way to locate the SEV-ES fixed AP RIP address for starting
>>>>>> AP's to avoid updating the actual flash image (build time location
>>>>>> that is identified with a GUID value).
>>>>>> - Create a VmgExit library to replace static inline functions.
>>>>>> - Move some PCDs to the appropriate packages
>>>>>> - Add support for writing to QEMU flash under SEV-ES
>>>>>> - Add additional MMIO opcode support
>>>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>>>
>>>>>> Changes since v1:
>>>>>> - Patches reworked to be more specific to the component/area being
>>>>>> updated
>>>>>> and order of definition/usage
>>>>>> - Created a library for VMGEXIT-related functions to replace use of
>>>>>> inline
>>>>>> functions
>>>>>> - Allocation method for GDT changed from AllocatePool to AllocatePages
>>>>>> - Early caching only enabled for SEV-ES guests
>>>>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>>>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>>>>
>>>>>> Tom Lendacky (43):
>>>>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>>>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>>>>> MdePkg: Add the MSR definition for the GHCB register
>>>>>> MdePkg: Add a structure definition for the GHCB
>>>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page
>>>>>> tables
>>>>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>>>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>>>>> UefiCpuPkg: Implement library support for VMGEXIT
>>>>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib library
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC
>>>>>> exception
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
>>>>>> events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events
>>>>>> (MMIO)
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX NAE
>>>>>> events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
>>>>>> events
>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
>>>>>> events
>>>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
>>>>>> OvmfPkg: Add support to perform SEV-ES initialization
>>>>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>>>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
>>>>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
>>>>>> OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
>>>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>>>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>>>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>>>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
>>>>>> SEV-ES is enabled
>>>>>> UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
>>>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
>>>>>> enabled
>>>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
>>>>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>>>>
>>>>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>>>>> OvmfPkg/OvmfPkg.dec | 9 +
>>>>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>>>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>>>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>>>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>>>>> OvmfPkg/OvmfXen.dsc | 1 +
>>>>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>>>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>>>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>>>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>>>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>>>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>>>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>>>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>>>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>>>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>>>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>>>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>>>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>>>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>>>>> .../QemuFlash.h | 13 +
>>>>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>>>>> .../CpuExceptionCommon.h | 2 +
>>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>>>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>>>>> .../MemEncryptSevLibInternal.c | 75 +-
>>>>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>>>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>>>>> .../QemuFlash.c | 23 +-
>>>>>> .../QemuFlashDxe.c | 22 +
>>>>>> .../QemuFlashSmm.c | 16 +
>>>>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>>>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>>>>> .../CpuExceptionCommon.c | 2 +-
>>>>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>>>>> .../PeiDxeSmmCpuException.c | 16 +
>>>>>> .../SecPeiCpuException.c | 16 +
>>>>>> .../X64/ArchAMDSevVcHandler.c | 1699
>>>>>> +++++++++++++++++
>>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>>>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>>>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>>>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>>>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>>>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>>>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>>> create mode 100644
>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>>> create mode 100644
>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>>> create mode 100644
>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>>>> create mode 100644
>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>>> create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>>>
>>>
>>>
>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [edk2-devel] [PATCH v7 00/43] SEV-ES guest support
2020-05-12 17:44 ` Lendacky, Thomas
@ 2020-05-12 20:10 ` Lendacky, Thomas
0 siblings, 0 replies; 81+ messages in thread
From: Lendacky, Thomas @ 2020-05-12 20:10 UTC (permalink / raw)
To: Andrew Fish, devel
Cc: Ni, Ray, Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Mike Kinney,
Gao, Liming, Dong, Eric, Brijesh Singh, You, Benjamin, Bi, Dandan,
Dong, Guo, Wu, Hao A, Wang, Jian J, Ma, Maurice
On 5/12/20 12:44 PM, Tom Lendacky wrote:
> On 5/12/20 11:49 AM, Tom Lendacky wrote:
>> On 5/9/20 2:09 PM, Andrew Fish wrote:
>>>
>>>
>>>> On May 9, 2020, at 7:34 AM, Lendacky, Thomas <thomas.lendacky@amd.com
>>>> <mailto:thomas.lendacky@amd.com>> wrote:
>>>>
>>>> On 5/9/20 1:44 AM, Ni, Ray wrote:
>>>>> Tom,
>>>>
>>>> Hi Ray,
>>>>
>>>>> I have a bit concern on your change that directly modifies
>>>>> CpuExceptionHandlerLib to handle
>>>>> exception #29. Today's CpuExceptionHandlerLib simplify dumps the
>>>>> exception context for
>>>>> every exception. Any component which wants to do specific handling of
>>>>> certain exceptions
>>>>> should call RegisterCpuInterruptHandler(). Such as code in CpuDxe
>>>>> driver:
>>>>> if (HEAP_GUARD_NONSTOP_MODE || NULL_DETECTION_NONSTOP_MODE) {
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_DEBUG,
>>>>> DebugExceptionHandler);
>>>>> RegisterCpuInterruptHandler (EXCEPT_IA32_PAGE_FAULT,
>>>>> PageFaultExceptionHandler);
>>>>> }
>>>>> Is it possible for your feature to follow the same pattern?
>>>>
>>>> There are two problems:
>>>>
>>>> The first is that RegisterCpuInterruptHandler() is not implemented for
>>>> both the SEC and PEI phases, so it is not currently possible to
>>>> register a handler that early.
>>>>
>>>> The second is that I need to be able to propagate an exception request
>>>> from the hypervisor. With the current implementation there doesn't
>>>> appear to be an easy way to perform this propagation.
>>>>
>>>> If there's a way to accomplish both of the above I wouldn't be opposed
>>>> to using RegisterCpuInterruptHandler() as long as there are no #VCs
>>>> that can occur between initializing exception handling and and
>>>> registering the #VC handler.
>>>>
>>>
>>> Thomas,
>>>
>>> As you point out it is tricky dealing with XIP code. You can't have
>>> globals that you can write and generally you use a PEI service to look
>>> tings up, the most common thing being using a HOB. But SEC has no
>>> services and I'm not sure you really want to be calling into the PEI
>>> Core on a random exception.
>>>
>>> Here are the best options that popped into my head after reading your
>>> email
>>> 1) IDT in RAM
>>> If your code populates the IDT the IDTR gives you access to the address
>>> of the IDTR via an instruction. The PI Spec reserves IDT - sizeof
>>> (UNITN) for a cached copy of the PEI Services Table, but otther than
>>> that you are good to go. It should be possible to have a global so you
>>> can have the table required to implement RegisterCpuInterruptHandler().
>>> There might be some usage of IDT - ( 2* sizeof(UINTN)), I know I'm
>>> guilty, so storing data after the IDT would be a good option. In
>>> general if your code allocates the memory for the IDT then you can
>>> treat the IDT as part of your private context data structure and that
>>> gives you access
>>>
>>> 2) IDT in ROM.
>>> For this it seems like you need a library to link in to
>>> the CpuExceptionHandlerLib that allows you to override the handler. If
>>> CpuInterruptHandlerOverride() returns NULL you do the current behavior
>>> if not NULL then you call the returned handler.
>>>
>>> EFI_CPU_INTERRUPT_HANDLER
>>> EFIAPI
>>> OverrideCpuInterruptHandler (
>>> IN EFI_EXCEPTION_TYPE InterruptType
>>> );
>>
>> I like the override idea in general, if that works for everyone. There
>> could be a NULL instance that never overrides the exception. Then it can
>> be implemented by those packages that need it. In this case a library
>> can be created in OvmfPkg that provides an override for #VC and the
>> override return code can determine if further processing is performed.
>
> Hmm... so the problem is that EFI_CPU_INTERRUPT_HANDLER does not return a
> value. So maybe just create an override type specific to the override
> library? I don't think that would present any issues.
>
> typedef
> EFI_STATUS
> (EFIAPI *CPU_INTERRUPT_OVERRRIDE) (
> IN EFI_EXCEPTION_TYPE ExceptionType,
> IN EFI_SYSTEM_CONTEXT SystemContext
> );
>
> CPU_INTERRUPT_OVERRIDE
> EFIAPI
> OverrideCpuInterruptHandler (
> IN EFI_EXCEPTION_TYPE ExceptionType,
> IN EFI_SYSTEM_CONTEXT SystemContext
> );
Then again, you don't need two routines to do this. Just have the return
code from the OverrideCpuInterruptHandler() indicate whether it was
overridden or not.
Thanks,
Tom
>
> Thanks,
> Tom
>
>>
>> Thanks,
>> Tom
>>
>>>
>>> Thanks,
>>>
>>> Andrew Fish
>>>
>>> PS Off topic, but it would also be useful to have a library that
>>> overrides the state dump display. For example using Xcode you can
>>> always display a stack frame from the exception handler.
>>>
>>>
>>>> Thanks,
>>>> Tom
>>>>
>>>>> Thanks,
>>>>> Ray
>>>>>> -----Original Message-----
>>>>>> From: Tom Lendacky <thomas.lendacky@amd.com
>>>>>> <mailto:thomas.lendacky@amd.com>>
>>>>>> Sent: Saturday, May 9, 2020 3:16 AM
>>>>>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
>>>>>> Cc: Justen, Jordan L <jordan.l.justen@intel.com
>>>>>> <mailto:jordan.l.justen@intel.com>>; Laszlo Ersek <lersek@redhat.com
>>>>>> <mailto:lersek@redhat.com>>; Ard Biesheuvel
>>>>>> <ard.biesheuvel@linaro.org <mailto:ard.biesheuvel@linaro.org>>;
>>>>>> Kinney, Michael D <michael.d.kinney@intel.com
>>>>>> <mailto:michael.d.kinney@intel.com>>; Gao, Liming
>>>>>> <liming.gao@intel.com <mailto:liming.gao@intel.com>>; Dong,
>>>>>> Eric <eric.dong@intel.com <mailto:eric.dong@intel.com>>; Ni, Ray
>>>>>> <ray.ni@intel.com <mailto:ray.ni@intel.com>>; Brijesh Singh
>>>>>> <brijesh.singh@amd.com <mailto:brijesh.singh@amd.com>>; You, Benjamin
>>>>>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>>; Bi, Dandan
>>>>>> <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>; Dong, Guo
>>>>>> <guo.dong@intel.com <mailto:guo.dong@intel.com>>; Wu, Hao A
>>>>>> <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>; Wang, Jian J
>>>>>> <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>; Ma, Maurice
>>>>>> <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>>>> Subject: Re: [PATCH v7 00/43] SEV-ES guest support
>>>>>>
>>>>>> I was able to use the pull request method that Laszlo documented and
>>>>>> fixed
>>>>>> up all of the issues identified by the VS compiler.
>>>>>>
>>>>>> An additional change I'm planning to make for the next version (v8)
>>>>>> of the
>>>>>> patches is to create a NULL library instance of the VmgExitLib that
>>>>>> will
>>>>>> also include the #VC handler function. This will reduce the amount
>>>>>> of code
>>>>>> associated with this feature for platforms that don't use/support
>>>>>> SEV-ES.
>>>>>>
>>>>>> Laszlo, this will mean that I will introduce a version of the
>>>>>> VmgExitLib
>>>>>> under OvmfPkg that will provide the majority of the functionality
>>>>>> that is
>>>>>> present today in UefiCpuPkg. In essence, the functionality in v7
>>>>>> patches 8
>>>>>> and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg. I think
>>>>>> this is the better way to do this. Let me know if you have any
>>>>>> concerns.
>>>>>>
>>>>>> Thanks,
>>>>>> Tom
>>>>>>
>>>>>> On 4/22/20 12:41 PM, Tom Lendacky wrote:
>>>>>>> This patch series provides support for running EDK2/OVMF under SEV-ES.
>>>>>>>
>>>>>>> Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands
>>>>>>> on the
>>>>>>> SEV support to protect the guest register state from the
>>>>>>> hypervisor. See
>>>>>>> "AMD64 Architecture Programmer's Manual Volume 2: System Programming",
>>>>>>> section "15.35 Encrypted State (SEV-ES)" [1].
>>>>>>>
>>>>>>> In order to allow a hypervisor to perform functions on behalf of a
>>>>>>> guest,
>>>>>>> there is architectural support for notifying a guest's operating
>>>>>>> system
>>>>>>> when certain types of VMEXITs are about to occur. This allows the
>>>>>>> guest to
>>>>>>> selectively share information with the hypervisor to satisfy the
>>>>>>> requested
>>>>>>> function. The notification is performed using a new exception, the VMM
>>>>>>> Communication exception (#VC). The information is shared through the
>>>>>>> Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT
>>>>>>> instruction.
>>>>>>> The GHCB format and the protocol for using it is documented in "SEV-ES
>>>>>>> Guest-Hypervisor Communication Block Standardization" [2].
>>>>>>>
>>>>>>> The main areas of the EDK2 code that are updated to support SEV-ES are
>>>>>>> around the exception handling support and the AP boot support.
>>>>>>>
>>>>>>> Exception support is required starting in Sec, continuing through Pei
>>>>>>> and into Dxe in order to handle #VC exceptions that are generated.
>>>>>>> Each
>>>>>>> AP requires it's own GHCB page as well as a page to hold values
>>>>>>> specific
>>>>>>> to that AP.
>>>>>>>
>>>>>>> AP booting poses some interesting challenges. The INIT-SIPI-SIPI
>>>>>>> sequence
>>>>>>> is typically used to boot the APs. However, the hypervisor is not
>>>>>>> allowed
>>>>>>> to update the guest registers. The GHCB document [2] talks about
>>>>>>> how SMP
>>>>>>> booting under SEV-ES is performed.
>>>>>>>
>>>>>>> Since the GHCB page must be a shared (unencrypted) page, the processor
>>>>>>> must be running in long mode in order for the guest and hypervisor to
>>>>>>> communicate with each other. As a result, SEV-ES is only supported
>>>>>>> under
>>>>>>> the X64 architecture.
>>>>>>>
>>>>>>> [1]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=H74fQl1n2sXzCMSoGm1tGOKc5epMtVkGJFCidwLMl5c%3D&reserved=0
>>>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.amd.com%2Fsystem%2Ffiles%2FTechDocs%2F24593.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364539668&sdata=I5jER2hmPSQP7r1TLLZp1UwuMqFkPbg4Zq%2BiUQ%2BLviw%3D&reserved=0>
>>>>>>>
>>>>>>> [2]https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=EwW9575nJMaWxizo2XrLHjrbUMJIB0WFTDLjwy%2BM%2F4k%3D&reserved=0
>>>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdeveloper.amd.com%2Fwp-content%2Fresources%2F56421.pdf&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364549626&sdata=9UxP5Z73Vb7GVP9mIhl2L89FN3xJrTG1PYr1RQS4Iqg%3D&reserved=0>
>>>>>>>
>>>>>>>
>>>>>>> ---
>>>>>>>
>>>>>>> These patches are based on commit:
>>>>>>> be7295b36405 (".python/SpellCheck: Increase SpellCheck plugin max
>>>>>>> failures")
>>>>>>>
>>>>>>> Proper execution of SEV-ES relies on Bugzilla 2340 being fixed.
>>>>>>>
>>>>>>> A version of the tree (with an extra patch to workaround Bugzilla
>>>>>>> 2340) can
>>>>>>> be found at:
>>>>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7Cf5d7875dfcf54e45c42208d7f3e4676b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246036118033165&sdata=U8fIzb%2F4A8WBaiVbScxUuGDw22kyxxnRP5olSyTedvE%3D&reserved=0
>>>>>>> <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FAMDESE%2Fovmf%2Ftree%2Fsev-es-v14&data=02%7C01%7Cthomas.lendacky%40amd.com%7C7553e751dfac47f5de2808d7f44c92d2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637246483364549626&sdata=2TQjm7iBKcrdnV8Jq6amArZPUCzyn%2BpoxS8lHuXa1Tk%3D&reserved=0>
>>>>>>>
>>>>>>>
>>>>>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org
>>>>>>> <mailto:ard.biesheuvel@linaro.org>>
>>>>>>> Cc: Benjamin You <benjamin.you@intel.com
>>>>>>> <mailto:benjamin.you@intel.com>>
>>>>>>> Cc: Dandan Bi <dandan.bi@intel.com <mailto:dandan.bi@intel.com>>
>>>>>>> Cc: Eric Dong <eric.dong@intel.com <mailto:eric.dong@intel.com>>
>>>>>>> Cc: Guo Dong <guo.dong@intel.com <mailto:guo.dong@intel.com>>
>>>>>>> Cc: Hao A Wu <hao.a.wu@intel.com <mailto:hao.a.wu@intel.com>>
>>>>>>> Cc: Jian J Wang <jian.j.wang@intel.com <mailto:jian.j.wang@intel.com>>
>>>>>>> Cc: Jordan Justen <jordan.l.justen@intel.com
>>>>>>> <mailto:jordan.l.justen@intel.com>>
>>>>>>> Cc: Laszlo Ersek <lersek@redhat.com <mailto:lersek@redhat.com>>
>>>>>>> Cc: Liming Gao <liming.gao@intel.com <mailto:liming.gao@intel.com>>
>>>>>>> Cc: Maurice Ma <maurice.ma@intel.com <mailto:maurice.ma@intel.com>>
>>>>>>> Cc: Michael D Kinney <michael.d.kinney@intel.com
>>>>>>> <mailto:michael.d.kinney@intel.com>>
>>>>>>> Cc: Ray Ni <ray.ni@intel.com <mailto:ray.ni@intel.com>>
>>>>>>>
>>>>>>> Changes since v6:
>>>>>>> - Add function comments to all functions, including local functions
>>>>>>> - Add function parameter direction to all functions (in/out)
>>>>>>> - Add support for MMIO MOVZX/MOVSX instructions
>>>>>>> - Ensure the per-CPU variable page remains encrypted
>>>>>>> - Coding-style fixes as identified by Ecc
>>>>>>>
>>>>>>> Changes since v5:
>>>>>>> - Remove extraneous VmgExitLib usage
>>>>>>> - Miscellaneous changes to address feedback (coding style, etc.)
>>>>>>>
>>>>>>> Changes since v4:
>>>>>>> - Move the SEV-ES protocol negotiation out of the SEC exception
>>>>>>> handler
>>>>>>> and into the SecMain.c file. As a result:
>>>>>>> - Move the SecGhcb related PCDs out of UefiCpuPkg and into OvmfPkg
>>>>>>> - Combine SecAMDSevVcHandler.c and PeiDxeAMDSevVcHandler.c into a
>>>>>>> single AMDSevVcHandler.c
>>>>>>> - Consolidate VmgExitLib usage into common LibraryClasses sections
>>>>>>> - Add documentation comments to the VmgExitLib functions
>>>>>>>
>>>>>>> Changes since v3:
>>>>>>> - Remove the need for the MP library finalization routine. The AP
>>>>>>> jump table address will be held by the hypervisor rather than
>>>>>>> communicated via the GHCB MSR. This removes some fragility around
>>>>>>> the UEFI to OS transition.
>>>>>>> - Rename the SEV-ES RIP reset area to SEV-ES workarea and use it to
>>>>>>> communicate the SEV-ES status, so that SEC CPU exception
>>>>>>> handling is
>>>>>>> only established for an SEV-ES guest.
>>>>>>> - Fix SMM build breakageAdd around QemuFlashPtrWrite().
>>>>>>> - Fix SMM build breakage by adding VC exception support the SMM CPU
>>>>>>> exception handling.
>>>>>>> - Add memory fencing around the invocation of AsmVmgExit().
>>>>>>> - Clarify comments around the SEV-ES AP reset RIP values and usage.
>>>>>>> - Move some PCD definitions from MdeModulePkg to UefiCpuPkg.
>>>>>>> - Remove the 16-bit code selector definition from MdeModulePkg
>>>>>>>
>>>>>>> Changes since v2:
>>>>>>> - Added a way to locate the SEV-ES fixed AP RIP address for starting
>>>>>>> AP's to avoid updating the actual flash image (build time location
>>>>>>> that is identified with a GUID value).
>>>>>>> - Create a VmgExit library to replace static inline functions.
>>>>>>> - Move some PCDs to the appropriate packages
>>>>>>> - Add support for writing to QEMU flash under SEV-ES
>>>>>>> - Add additional MMIO opcode support
>>>>>>> - Cleaned up the GHCB MSR CPUID protocol support
>>>>>>>
>>>>>>> Changes since v1:
>>>>>>> - Patches reworked to be more specific to the component/area being
>>>>>>> updated
>>>>>>> and order of definition/usage
>>>>>>> - Created a library for VMGEXIT-related functions to replace use of
>>>>>>> inline
>>>>>>> functions
>>>>>>> - Allocation method for GDT changed from AllocatePool to AllocatePages
>>>>>>> - Early caching only enabled for SEV-ES guests
>>>>>>> - Ensure AP loop mode set to halt loop mode for SEV-ES guests
>>>>>>> - Reserved SEC GHCB-related memory areas when S3 is enabled
>>>>>>>
>>>>>>> Tom Lendacky (43):
>>>>>>> MdeModulePkg: Create PCDs to be used in support of SEV-ES
>>>>>>> UefiCpuPkg: Create PCD to be used in support of SEV-ES
>>>>>>> MdePkg: Add the MSR definition for the GHCB register
>>>>>>> MdePkg: Add a structure definition for the GHCB
>>>>>>> MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page
>>>>>>> tables
>>>>>>> MdePkg/BaseLib: Add support for the XGETBV instruction
>>>>>>> MdePkg/BaseLib: Add support for the VMGEXIT instruction
>>>>>>> UefiCpuPkg: Implement library support for VMGEXIT
>>>>>>> OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library
>>>>>>> UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmgExitLib
>>>>>>> library
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC
>>>>>>> exception
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE
>>>>>>> events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE
>>>>>>> events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for CPUID NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events
>>>>>>> (MMIO)
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for INVD NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP NAE events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX
>>>>>>> NAE
>>>>>>> events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX NAE
>>>>>>> events
>>>>>>> UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write NAE
>>>>>>> events
>>>>>>> OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function
>>>>>>> OvmfPkg: Add support to perform SEV-ES initialization
>>>>>>> OvmfPkg: Create a GHCB page for use during Sec phase
>>>>>>> OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported
>>>>>>> OvmfPkg: Create GHCB pages for use during Pei and Dxe phase
>>>>>>> OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled
>>>>>>> UefiCpuPkg: Create an SEV-ES workarea PCD
>>>>>>> OvmfPkg: Reserve a page in memory for the SEV-ES usage
>>>>>>> OvmfPkg/ResetVector: Add support for a 32-bit SEV check
>>>>>>> OvmfPkg/Sec: Add #VC exception handling for Sec phase
>>>>>>> OvmfPkg/Sec: Enable cache early to speed up booting
>>>>>>> OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with
>>>>>>> SEV-ES is enabled
>>>>>>> UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
>>>>>>> UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is
>>>>>>> enabled
>>>>>>> UefiCpuPkg: Allow AP booting under SEV-ES
>>>>>>> OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector
>>>>>>> OvmfPkg: Move the GHCB allocations into reserved memory
>>>>>>> UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use
>>>>>>>
>>>>>>> MdeModulePkg/MdeModulePkg.dec | 9 +
>>>>>>> OvmfPkg/OvmfPkg.dec | 9 +
>>>>>>> UefiCpuPkg/UefiCpuPkg.dec | 17 +
>>>>>>> OvmfPkg/OvmfPkgIa32.dsc | 6 +
>>>>>>> OvmfPkg/OvmfPkgIa32X64.dsc | 6 +
>>>>>>> OvmfPkg/OvmfPkgX64.dsc | 6 +
>>>>>>> OvmfPkg/OvmfXen.dsc | 1 +
>>>>>>> UefiCpuPkg/UefiCpuPkg.dsc | 2 +
>>>>>>> UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +
>>>>>>> UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +
>>>>>>> OvmfPkg/OvmfPkgX64.fdf | 9 +
>>>>>>> MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +
>>>>>>> MdePkg/Library/BaseLib/BaseLib.inf | 4 +
>>>>>>> OvmfPkg/PlatformPei/PlatformPei.inf | 7 +
>>>>>>> .../FvbServicesRuntimeDxe.inf | 2 +
>>>>>>> OvmfPkg/ResetVector/ResetVector.inf | 8 +
>>>>>>> OvmfPkg/Sec/SecMain.inf | 4 +
>>>>>>> .../DxeCpuExceptionHandlerLib.inf | 5 +
>>>>>>> .../PeiCpuExceptionHandlerLib.inf | 5 +
>>>>>>> .../SecPeiCpuExceptionHandlerLib.inf | 5 +
>>>>>>> .../SmmCpuExceptionHandlerLib.inf | 5 +
>>>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 4 +
>>>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 4 +
>>>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf | 33 +
>>>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.h | 12 +-
>>>>>>> MdePkg/Include/Library/BaseLib.h | 31 +
>>>>>>> MdePkg/Include/Register/Amd/Fam17Msr.h | 42 +
>>>>>>> MdePkg/Include/Register/Amd/Ghcb.h | 136 ++
>>>>>>> OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 +
>>>>>>> .../QemuFlash.h | 13 +
>>>>>>> UefiCpuPkg/CpuDxe/CpuGdt.h | 4 +-
>>>>>>> UefiCpuPkg/Include/Library/VmgExitLib.h | 117 ++
>>>>>>> .../CpuExceptionHandlerLib/AMDSevVcCommon.h | 49 +
>>>>>>> .../CpuExceptionCommon.h | 2 +
>>>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.h | 68 +-
>>>>>>> .../Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 4 +-
>>>>>>> .../Core/DxeIplPeim/X64/DxeLoadFunc.c | 11 +-
>>>>>>> .../Core/DxeIplPeim/X64/VirtualMemory.c | 57 +-
>>>>>>> MdePkg/Library/BaseLib/Ia32/GccInline.c | 45 +
>>>>>>> MdePkg/Library/BaseLib/X64/GccInline.c | 47 +
>>>>>>> .../MemEncryptSevLibInternal.c | 75 +-
>>>>>>> OvmfPkg/PlatformPei/AmdSev.c | 89 +
>>>>>>> OvmfPkg/PlatformPei/MemDetect.c | 23 +
>>>>>>> .../QemuFlash.c | 23 +-
>>>>>>> .../QemuFlashDxe.c | 22 +
>>>>>>> .../QemuFlashSmm.c | 16 +
>>>>>>> OvmfPkg/Sec/SecMain.c | 188 +-
>>>>>>> UefiCpuPkg/CpuDxe/CpuGdt.c | 8 +-
>>>>>>> .../CpuExceptionHandlerLib/AMDSevVcHandler.c | 40 +
>>>>>>> .../CpuExceptionCommon.c | 2 +-
>>>>>>> .../Ia32/ArchAMDSevVcHandler.c | 38 +
>>>>>>> .../PeiDxeSmmCpuException.c | 16 +
>>>>>>> .../SecPeiCpuException.c | 16 +
>>>>>>> .../X64/ArchAMDSevVcHandler.c | 1699
>>>>>>> +++++++++++++++++
>>>>>>> UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 113 +-
>>>>>>> UefiCpuPkg/Library/MpInitLib/MpLib.c | 265 ++-
>>>>>>> UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 19 +
>>>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c | 293 +++
>>>>>>> UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +-
>>>>>>> MdeModulePkg/MdeModulePkg.uni | 8 +
>>>>>>> MdePkg/Library/BaseLib/Ia32/VmgExit.nasm | 37 +
>>>>>>> MdePkg/Library/BaseLib/Ia32/XGetBv.nasm | 31 +
>>>>>>> MdePkg/Library/BaseLib/X64/VmgExit.nasm | 32 +
>>>>>>> MdePkg/Library/BaseLib/X64/XGetBv.nasm | 34 +
>>>>>>> OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 100 +
>>>>>>> OvmfPkg/ResetVector/Ia32/PageTables64.asm | 350 +++-
>>>>>>> OvmfPkg/ResetVector/ResetVector.nasmb | 20 +
>>>>>>> .../X64/ExceptionHandlerAsm.nasm | 17 +
>>>>>>> UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc | 2 +-
>>>>>>> .../Library/MpInitLib/Ia32/MpFuncs.nasm | 15 +
>>>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc | 4 +-
>>>>>>> UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 370 +++-
>>>>>>> UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni | 15 +
>>>>>>> .../ResetVector/Vtf0/Ia16/Real16ToFlat32.asm | 9 +
>>>>>>> UefiCpuPkg/UefiCpuPkg.uni | 11 +
>>>>>>> 75 files changed, 4707 insertions(+), 102 deletions(-)
>>>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.inf
>>>>>>> create mode 100644 MdePkg/Include/Register/Amd/Ghcb.h
>>>>>>> create mode 100644 UefiCpuPkg/Include/Library/VmgExitLib.h
>>>>>>> create mode 100644
>>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcCommon.h
>>>>>>> create mode 100644
>>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/AMDSevVcHandler.c
>>>>>>> create mode 100644
>>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchAMDSevVcHandler.c
>>>>>>> create mode 100644
>>>>>>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
>>>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.c
>>>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/VmgExit.nasm
>>>>>>> create mode 100644 MdePkg/Library/BaseLib/Ia32/XGetBv.nasm
>>>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/VmgExit.nasm
>>>>>>> create mode 100644 MdePkg/Library/BaseLib/X64/XGetBv.nasm
>>>>>>> create mode 100644 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
>>>>>>> create mode 100644 UefiCpuPkg/Library/VmgExitLib/VmgExitLib.uni
>>>>>>>
>>>>
>>>>
>>>
^ permalink raw reply [flat|nested] 81+ messages in thread
* Re: [PATCH v7 00/43] SEV-ES guest support
2020-05-08 19:16 ` [PATCH v7 00/43] SEV-ES guest support Lendacky, Thomas
2020-05-09 6:44 ` Ni, Ray
@ 2020-05-11 15:37 ` Laszlo Ersek
1 sibling, 0 replies; 81+ messages in thread
From: Laszlo Ersek @ 2020-05-11 15:37 UTC (permalink / raw)
To: Tom Lendacky, devel
Cc: Jordan Justen, Ard Biesheuvel, Michael D Kinney, Liming Gao,
Eric Dong, Ray Ni, Brijesh Singh, Benjamin You, Dandan Bi,
Guo Dong, Hao A Wu, Jian J Wang, Maurice Ma
On 05/08/20 21:16, Tom Lendacky wrote:
> I was able to use the pull request method that Laszlo documented and
> fixed up all of the issues identified by the VS compiler.
>
> An additional change I'm planning to make for the next version (v8) of
> the patches is to create a NULL library instance of the VmgExitLib that
> will also include the #VC handler function. This will reduce the amount
> of code associated with this feature for platforms that don't
> use/support SEV-ES.
>
> Laszlo, this will mean that I will introduce a version of the VmgExitLib
> under OvmfPkg that will provide the majority of the functionality that
> is present today in UefiCpuPkg. In essence, the functionality in v7
> patches 8 and 11 - 25 will now live under OvmfPkg instead of UefiCpuPkg.
> I think this is the better way to do this. Let me know if you have any
> concerns.
That's OK with me.
I'll have to spend more time to review those patches, of course. I think
I'll go for Acked-by tags only, as these modules should be well-contained.
In the next version, please consider introducing a new section to the
"Maintainers.txt" file, and listing yourself and Brijesh in "R" roles
for the (new) VmgExitLib and CpuExceptionHandlerLib instances under OvmfPkg.
Best would be to list all the new files and modules introcuced by this
patch set under OvmfPkg -- maybe Eric and Ray would prefer that for
UefiCpuPkg as well. That's their call; for OvmfPkg I'd like this
additional reviewership spelled out.
Recent examples:
- 335644f90f15 ("Maintainers.txt: Add Liran and Nikita as
OvmfPkg/PvScsiDxe reviewers", 2020-04-01)
- feec20b28dd0 ("OvmfPkg/MptScsiDxe: Create empty driver", 2020-05-05)
Thanks!
Laszlo
^ permalink raw reply [flat|nested] 81+ messages in thread