From: "Laszlo Ersek" <lersek@redhat.com>
To: devel@edk2.groups.io, thomas.lendacky@amd.com
Cc: Jordan Justen <jordan.l.justen@intel.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
Michael D Kinney <michael.d.kinney@intel.com>,
Liming Gao <liming.gao@intel.com>,
Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
Brijesh Singh <brijesh.singh@amd.com>
Subject: Re: [edk2-devel] [PATCH v5 34/42] OvmfPkg/Sec: Add #VC exception handling for Sec phase
Date: Tue, 3 Mar 2020 14:29:18 +0100 [thread overview]
Message-ID: <cd226d5c-d35c-02a1-bbe9-6a819c210f62@redhat.com> (raw)
In-Reply-To: <555d15ee95133cce0617edbd5500c05785847a4c.1583190432.git.thomas.lendacky@amd.com>
Hi Tom,
On 03/03/20 00:07, Lendacky, Thomas wrote:
> 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.
>
> 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>
this patch has changed significantly since the last version (v4); I
think my R-b given for v4 should not have been picked up in v5.
AFAICS the new stuff is SevEsProtocolFailure() and SevEsProtocolCheck(),
which -- per v5 blurb -- have moved from UefiCpuPkg to OvmfPkg:
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
> OvmfPkg/Sec/SecMain.inf | 4 ++
> OvmfPkg/Sec/SecMain.c | 151 ++++++++++++++++++++++++++++++++++++----
> 2 files changed, 142 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..577596a949f9 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,90 @@ FindAndReportEntryPoints (
> return;
> }
>
> +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 (0);
(1) The argument should be FALSE, not 0.
> + CpuDeadLoop ();
> +}
> +
> +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 */
(2) The comment style is not consistent with the rest.
With the style warts (1) and (2) fixed:
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Thanks
Laszlo
> + Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);
> + Ghcb->GhcbUsage = GHCB_STANDARD_USAGE;
> +}
> +
> +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 +828,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 +889,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
>
next prev parent reply other threads:[~2020-03-03 13:29 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-02 23:06 [PATCH v5 00/42] SEV-ES guest support Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 01/42] MdePkg: Create PCDs to be used in support of SEV-ES Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 02/42] MdePkg: Add the MSR definition for the GHCB register Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 03/42] MdePkg: Add a structure definition for the GHCB Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 04/42] MdeModulePkg/DxeIplPeim: Support GHCB pages when creating page tables Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 05/42] MdePkg/BaseLib: Add support for the XGETBV instruction Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 06/42] MdePkg/BaseLib: Add support for the VMGEXIT instruction Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 07/42] UefiCpuPkg: Implement library support for VMGEXIT Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 08/42] OvmfPkg: Prepare OvmfPkg to use the VmgExitLib library Lendacky, Thomas
2020-03-03 12:10 ` [edk2-devel] " Laszlo Ersek
2020-03-02 23:06 ` [PATCH v5 09/42] UefiPayloadPkg: Prepare UefiPayloadPkg " Lendacky, Thomas
2020-03-03 23:52 ` [edk2-devel] " Guo Dong
2020-03-02 23:06 ` [PATCH v5 10/42] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VC exception Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 11/42] UefiCpuPkg/CpuExceptionHandler: Add support for IOIO_PROT NAE events Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 12/42] UefiCpuPkg/CpuExceptionHandler: Support string IO " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 13/42] UefiCpuPkg/CpuExceptionHandler: Add support for CPUID " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 14/42] UefiCpuPkg/CpuExceptionHandler: Add support for MSR_PROT " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 15/42] UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO) Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 16/42] UefiCpuPkg/CpuExceptionHandler: Add support for WBINVD NAE events Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 17/42] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSC " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 18/42] UefiCpuPkg/CpuExceptionHandler: Add support for RDPMC " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 19/42] UefiCpuPkg/CpuExceptionHandler: Add support for INVD " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 20/42] UefiCpuPkg/CpuExceptionHandler: Add support for VMMCALL " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 21/42] UefiCpuPkg/CpuExceptionHandler: Add support for RDTSCP " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 22/42] UefiCpuPkg/CpuExceptionHandler: Add support for MONITOR/MONITORX " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 23/42] UefiCpuPkg/CpuExceptionHandler: Add support for MWAIT/MWAITX " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 24/42] UefiCpuPkg/CpuExceptionHandler: Add support for DR7 Read/Write " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 25/42] OvmfPkg/MemEncryptSevLib: Add an SEV-ES guest indicator function Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 26/42] OvmfPkg: Add support to perform SEV-ES initialization Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 27/42] OvmfPkg: Create a GHCB page for use during Sec phase Lendacky, Thomas
2020-03-03 5:29 ` Lendacky, Thomas
2020-03-03 5:36 ` [PATCH v5.1 27/43] " Lendacky, Thomas
2020-03-02 23:06 ` [PATCH v5 28/42] OvmfPkg/PlatformPei: Reserve GHCB-related areas if S3 is supported Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 29/42] OvmfPkg: Create GHCB pages for use during Pei and Dxe phase Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 30/42] OvmfPkg/PlatformPei: Move early GDT into ram when SEV-ES is enabled Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 31/42] UefiCpuPkg: Create an SEV-ES workarea PCD Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 32/42] OvmfPkg: Reserve a page in memory for the SEV-ES usage Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 33/42] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 34/42] OvmfPkg/Sec: Add #VC exception handling for Sec phase Lendacky, Thomas
2020-03-03 13:29 ` Laszlo Ersek [this message]
2020-03-03 14:20 ` [edk2-devel] " Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 35/42] OvmfPkg/Sec: Enable cache early to speed up booting Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 36/42] OvmfPkg/QemuFlashFvbServicesRuntimeDxe: Bypass flash detection with SEV-ES is enabled Lendacky, Thomas
2020-03-03 12:33 ` [edk2-devel] " Laszlo Ersek
2020-03-03 14:26 ` Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 37/42] UefiCpuPkg: Add a 16-bit protected mode code segment descriptor Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 38/42] UefiCpuPkg/MpInitLib: Add CPU MP data flag to indicate if SEV-ES is enabled Lendacky, Thomas
2020-03-02 23:07 ` [PATCH v5 39/42] UefiCpuPkg: Allow AP booting under SEV-ES Lendacky, Thomas
2020-03-03 5:43 ` [PATCH v5 40/42] OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset vector Lendacky, Thomas
2020-03-03 5:43 ` [PATCH v5 41/42] OvmfPkg: Move the GHCB allocations into reserved memory Lendacky, Thomas
2020-03-03 5:43 ` [PATCH v5 42/42] UefiCpuPkg/MpInitLib: Prepare SEV-ES guest APs for OS use Lendacky, Thomas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cd226d5c-d35c-02a1-bbe9-6a819c210f62@redhat.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox