]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Sec/SecMain.c
OvmfPkg/Sec: fix stack switch
[mirror_edk2.git] / OvmfPkg / Sec / SecMain.c
index 6d81d5b629880051ca66b119434914ad07eeeb8a..3ca0dcdfd3ddd513f85566be0692fea2aa5825b3 100644 (file)
@@ -17,6 +17,7 @@
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/PeiServicesLib.h>\r
 #include <Library/PcdLib.h>\r
+#include <Library/CpuLib.h>\r
 #include <Library/UefiCpuLib.h>\r
 #include <Library/DebugAgentLib.h>\r
 #include <Library/IoLib.h>\r
 #include <Library/ExtractGuidedSectionLib.h>\r
 #include <Library/LocalApicLib.h>\r
 #include <Library/CpuExceptionHandlerLib.h>\r
-#include <Library/MemEncryptSevLib.h>\r
-#include <Register/Amd/Ghcb.h>\r
-#include <Register/Amd/Msr.h>\r
-\r
 #include <Ppi/TemporaryRamSupport.h>\r
+#include <Ppi/MpInitLibDep.h>\r
+#include <Library/PlatformInitLib.h>\r
+#include <Library/CcProbeLib.h>\r
+#include "AmdSev.h"\r
 \r
 #define SEC_IDT_ENTRY_COUNT  34\r
 \r
@@ -61,12 +62,30 @@ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI  mTemporaryRamSupportPpi = {
   TemporaryRamMigration\r
 };\r
 \r
-EFI_PEI_PPI_DESCRIPTOR  mPrivateDispatchTable[] = {\r
+EFI_PEI_PPI_DESCRIPTOR  mPrivateDispatchTableMp[] = {\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI),\r
+    &gEfiTemporaryRamSupportPpiGuid,\r
+    &mTemporaryRamSupportPpi\r
+  },\r
   {\r
     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiMpInitLibMpDepPpiGuid,\r
+    NULL\r
+  },\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mPrivateDispatchTableUp[] = {\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI),\r
     &gEfiTemporaryRamSupportPpiGuid,\r
     &mTemporaryRamSupportPpi\r
   },\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiMpInitLibUpDepPpiGuid,\r
+    NULL\r
+  },\r
 };\r
 \r
 //\r
@@ -726,157 +745,6 @@ FindAndReportEntryPoints (
   return;\r
 }\r
 \r
-/**\r
-  Handle an SEV-ES/GHCB protocol check failure.\r
-\r
-  Notify the hypervisor using the VMGEXIT instruction that the SEV-ES guest\r
-  wishes to be terminated.\r
-\r
-  @param[in] ReasonCode  Reason code to provide to the hypervisor for the\r
-                         termination request.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-SevEsProtocolFailure (\r
-  IN UINT8  ReasonCode\r
-  )\r
-{\r
-  MSR_SEV_ES_GHCB_REGISTER  Msr;\r
-\r
-  //\r
-  // Use the GHCB MSR Protocol to request termination by the hypervisor\r
-  //\r
-  Msr.GhcbPhysicalAddress         = 0;\r
-  Msr.GhcbTerminate.Function      = GHCB_INFO_TERMINATE_REQUEST;\r
-  Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;\r
-  Msr.GhcbTerminate.ReasonCode    = ReasonCode;\r
-  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
-\r
-  AsmVmgExit ();\r
-\r
-  ASSERT (FALSE);\r
-  CpuDeadLoop ();\r
-}\r
-\r
-/**\r
-  Validate the SEV-ES/GHCB protocol level.\r
-\r
-  Verify that the level of SEV-ES/GHCB protocol supported by the hypervisor\r
-  and the guest intersect. If they don't intersect, request termination.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-SevEsProtocolCheck (\r
-  VOID\r
-  )\r
-{\r
-  MSR_SEV_ES_GHCB_REGISTER  Msr;\r
-  GHCB                      *Ghcb;\r
-\r
-  //\r
-  // Use the GHCB MSR Protocol to obtain the GHCB SEV-ES Information for\r
-  // protocol checking\r
-  //\r
-  Msr.GhcbPhysicalAddress = 0;\r
-  Msr.GhcbInfo.Function   = GHCB_INFO_SEV_INFO_GET;\r
-  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
-\r
-  AsmVmgExit ();\r
-\r
-  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
-\r
-  if (Msr.GhcbInfo.Function != GHCB_INFO_SEV_INFO) {\r
-    SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);\r
-  }\r
-\r
-  if (Msr.GhcbProtocol.SevEsProtocolMin > Msr.GhcbProtocol.SevEsProtocolMax) {\r
-    SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);\r
-  }\r
-\r
-  if ((Msr.GhcbProtocol.SevEsProtocolMin > GHCB_VERSION_MAX) ||\r
-      (Msr.GhcbProtocol.SevEsProtocolMax < GHCB_VERSION_MIN))\r
-  {\r
-    SevEsProtocolFailure (GHCB_TERMINATE_GHCB_PROTOCOL);\r
-  }\r
-\r
-  //\r
-  // SEV-ES protocol checking succeeded, set the initial GHCB address\r
-  //\r
-  Msr.GhcbPhysicalAddress = FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
-  AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
-\r
-  Ghcb = Msr.Ghcb;\r
-  SetMem (Ghcb, sizeof (*Ghcb), 0);\r
-\r
-  //\r
-  // Set the version to the maximum that can be supported\r
-  //\r
-  Ghcb->ProtocolVersion = MIN (Msr.GhcbProtocol.SevEsProtocolMax, GHCB_VERSION_MAX);\r
-  Ghcb->GhcbUsage       = GHCB_STANDARD_USAGE;\r
-}\r
-\r
-/**\r
- Determine if the SEV is active.\r
-\r
- During the early booting, GuestType is set in the work area. Verify that it\r
- is an SEV guest.\r
-\r
- @retval TRUE   SEV is enabled\r
- @retval FALSE  SEV is not enabled\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-IsSevGuest (\r
-  VOID\r
-  )\r
-{\r
-  OVMF_WORK_AREA  *WorkArea;\r
-\r
-  //\r
-  // Ensure that the size of the Confidential Computing work area header\r
-  // is same as what is provided through a fixed PCD.\r
-  //\r
-  ASSERT (\r
-    (UINTN)FixedPcdGet32 (PcdOvmfConfidentialComputingWorkAreaHeader) ==\r
-    sizeof (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER)\r
-    );\r
-\r
-  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);\r
-\r
-  return ((WorkArea != NULL) && (WorkArea->Header.GuestType == GUEST_TYPE_AMD_SEV));\r
-}\r
-\r
-/**\r
-  Determine if SEV-ES is active.\r
-\r
-  During early booting, SEV-ES support code will set a flag to indicate that\r
-  SEV-ES is enabled. Return the value of this flag as an indicator that SEV-ES\r
-  is enabled.\r
-\r
-  @retval TRUE   SEV-ES is enabled\r
-  @retval FALSE  SEV-ES is not enabled\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-SevEsIsEnabled (\r
-  VOID\r
-  )\r
-{\r
-  SEC_SEV_ES_WORK_AREA  *SevEsWorkArea;\r
-\r
-  if (!IsSevGuest ()) {\r
-    return FALSE;\r
-  }\r
-\r
-  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
-\r
-  return (SevEsWorkArea->SevEsEnabled != 0);\r
-}\r
-\r
 VOID\r
 EFIAPI\r
 SecCoreStartupWithStack (\r
@@ -890,6 +758,20 @@ SecCoreStartupWithStack (
   UINT32                Index;\r
   volatile UINT8        *Table;\r
 \r
+ #if defined (TDX_GUEST_SUPPORTED)\r
+  if (CcProbe () == CcGuestTypeIntelTdx) {\r
+    //\r
+    // For Td guests, the memory map info is in TdHobLib. It should be processed\r
+    // first so that the memory is accepted. Otherwise access to the unaccepted\r
+    // memory will trigger tripple fault.\r
+    //\r
+    if (ProcessTdxHobList () != EFI_SUCCESS) {\r
+      CpuDeadLoop ();\r
+    }\r
+  }\r
+\r
+ #endif\r
+\r
   //\r
   // To ensure SMM can't be compromised on S3 resume, we must force re-init of\r
   // the BaseExtractGuidedSectionLib. Since this is before library contructors\r
@@ -908,13 +790,19 @@ SecCoreStartupWithStack (
   // we use a loop rather than CopyMem.\r
   //\r
   IdtTableInStack.PeiService = NULL;\r
+\r
   for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
-    UINT8  *Src;\r
-    UINT8  *Dst;\r
-    UINTN  Byte;\r
+    //\r
+    // Declare the local variables that actually move the data elements as\r
+    // volatile to prevent the optimizer from replacing this function with\r
+    // the intrinsic memcpy()\r
+    //\r
+    CONST UINT8     *Src;\r
+    volatile UINT8  *Dst;\r
+    UINTN           Byte;\r
 \r
-    Src = (UINT8 *)&mIdtEntryTemplate;\r
-    Dst = (UINT8 *)&IdtTableInStack.IdtTable[Index];\r
+    Src = (CONST UINT8 *)&mIdtEntryTemplate;\r
+    Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];\r
     for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {\r
       Dst[Byte] = Src[Byte];\r
     }\r
@@ -960,6 +848,17 @@ SecCoreStartupWithStack (
     AsmEnableCache ();\r
   }\r
 \r
+ #if defined (TDX_GUEST_SUPPORTED)\r
+  if (CcProbe () == CcGuestTypeIntelTdx) {\r
+    //\r
+    // InitializeCpuExceptionHandlers () should be called in Td guests so that\r
+    // #VE exceptions can be handled correctly.\r
+    //\r
+    InitializeCpuExceptionHandlers (NULL);\r
+  }\r
+\r
+ #endif\r
+\r
   DEBUG ((\r
     DEBUG_INFO,\r
     "SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
@@ -1012,6 +911,11 @@ SecCoreStartupWithStack (
   SecCoreData.BootFirmwareVolumeBase = BootFv;\r
   SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
 \r
+  //\r
+  // Validate the System RAM used in the SEC Phase\r
+  //\r
+  SecValidateSystemRam ();\r
+\r
   //\r
   // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled\r
   //\r
@@ -1051,6 +955,7 @@ SecStartupPhase2 (
   EFI_SEC_PEI_HAND_OFF        *SecCoreData;\r
   EFI_FIRMWARE_VOLUME_HEADER  *BootFv;\r
   EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;\r
+  EFI_PEI_PPI_DESCRIPTOR      *EfiPeiPpiDescriptor;\r
 \r
   SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;\r
 \r
@@ -1063,10 +968,20 @@ SecStartupPhase2 (
   SecCoreData->BootFirmwareVolumeBase = BootFv;\r
   SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
 \r
+  //\r
+  // Td guest is required to use the MpInitLibUp (unique-processor version).\r
+  // Other guests use the MpInitLib (multi-processor version).\r
+  //\r
+  if (CcProbe () == CcGuestTypeIntelTdx) {\r
+    EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableUp;\r
+  } else {\r
+    EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableMp;\r
+  }\r
+\r
   //\r
   // Transfer the control to the PEI core\r
   //\r
-  (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);\r
+  (*PeiCoreEntryPoint)(SecCoreData, EfiPeiPpiDescriptor);\r
 \r
   //\r
   // If we get here then the PEI Core returned, which is not recoverable.\r
@@ -1137,11 +1052,15 @@ TemporaryRamMigration (
   if (SetJump (&JumpBuffer) == 0) {\r
  #if defined (MDE_CPU_IA32)\r
     JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;\r
+ #ifndef OMIT_FRAME_POINTER\r
     JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;\r
  #endif\r
+ #endif\r
  #if defined (MDE_CPU_X64)\r
     JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;\r
+ #ifndef OMIT_FRAME_POINTER\r
     JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;\r
+ #endif\r
  #endif\r
     LongJump (&JumpBuffer, (UINTN)-1);\r
   }\r