]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Update PlatformInitLib for Tdx guest
authorMin Xu <min.m.xu@intel.com>
Wed, 16 Feb 2022 05:42:55 +0000 (13:42 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 2 Apr 2022 08:15:12 +0000 (08:15 +0000)
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

There are below changes in PlatformInitLib for Tdx guest:

1. Publish ram regions
In Tdx guest, the system memory is passed in TdHob by host VMM. So
the major task of PlatformTdxPublishRamRegions is to walk thru the
TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob
to the hobs in DXE phase.

2. Build MemoryAllocationHob for Tdx Mailbox and Ovmf work area.

3. Update of PlatformAddressWidthInitialization. The physical
address width that Tdx guest supports is either 48 or 52.

4. Update of PlatformMemMapInitialization.
0xA0000 - 0xFFFFF is VGA bios region.  Platform initialization marks the
region as MMIO region. Dxe code maps MMIO region as IO region.
As TDX guest, MMIO region is maps as shared.  However VGA BIOS doesn't need
to be shared.  Guest TDX Linux maps VGA BIOS as private and accesses for
BIOS and stuck on repeating EPT violation.  VGA BIOS (more generally ROM
region) should be private.  Skip marking VGA BIOA region [0xa000, 0xfffff]
as MMIO in HOB.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
OvmfPkg/Include/Library/PlatformInitLib.h
OvmfPkg/Library/PlatformInitLib/IntelTdx.c
OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
OvmfPkg/Library/PlatformInitLib/MemDetect.c
OvmfPkg/Library/PlatformInitLib/Platform.c

index 6152a43d0da7cc44c89775d24c09ae9eb843bcca..2987a367cc9c8fa06bac931f0633911e644a474d 100644 (file)
@@ -220,4 +220,18 @@ ProcessTdxHobList (
   VOID\r
   );\r
 \r
+/**\r
+  In Tdx guest, the system memory is passed in TdHob by host VMM. So\r
+  the major task of PlatformTdxPublishRamRegions is to walk thru the\r
+  TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob\r
+  to the hobs in DXE phase.\r
+\r
+  MemoryAllocationHob should also be created for Mailbox and Ovmf work area.\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformTdxPublishRamRegions (\r
+  VOID\r
+  );\r
+\r
 #endif // PLATFORM_INIT_LIB_H_\r
index e9196b7ffaa703a5a4864655734821ff80919ad1..c6d7c8bb6e0e73a4d97910ecd487259558acbf19 100644 (file)
@@ -512,3 +512,52 @@ TransferTdxHobList (
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
 }\r
+\r
+/**\r
+  In Tdx guest, the system memory is passed in TdHob by host VMM. So\r
+  the major task of PlatformTdxPublishRamRegions is to walk thru the\r
+  TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob\r
+  to the hobs in DXE phase.\r
+\r
+  MemoryAllocationHob should also be created for Mailbox and Ovmf work area.\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformTdxPublishRamRegions (\r
+  VOID\r
+  )\r
+{\r
+  if (!TdIsEnabled ()) {\r
+    return;\r
+  }\r
+\r
+  TransferTdxHobList ();\r
+\r
+  //\r
+  // The memory region defined by PcdOvmfSecGhcbBackupBase is pre-allocated by\r
+  // host VMM and used as the td mailbox at the beginning of system boot.\r
+  //\r
+  BuildMemoryAllocationHob (\r
+    FixedPcdGet32 (PcdOvmfSecGhcbBackupBase),\r
+    FixedPcdGet32 (PcdOvmfSecGhcbBackupSize),\r
+    EfiACPIMemoryNVS\r
+    );\r
+\r
+  if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) {\r
+    //\r
+    // Reserve the work area.\r
+    //\r
+    // Since this memory range will be used by the Reset Vector on S3\r
+    // resume, it must be reserved as ACPI NVS.\r
+    //\r
+    // If S3 is unsupported, then various drivers might still write to the\r
+    // work area. We ought to prevent DXE from serving allocation requests\r
+    // such that they would overlap the work area.\r
+    //\r
+    BuildMemoryAllocationHob (\r
+      (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase),\r
+      (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize),\r
+      EfiBootServicesData\r
+      );\r
+  }\r
+}\r
index af90e0866e89f94789e46c442797cc57470e70e9..3ebe582af8de448f8dcf93e533c00f46900b057f 100644 (file)
@@ -28,3 +28,19 @@ ProcessTdxHobList (
 {\r
   return EFI_UNSUPPORTED;\r
 }\r
+\r
+/**\r
+  In Tdx guest, the system memory is passed in TdHob by host VMM. So\r
+  the major task of PlatformTdxPublishRamRegions is to walk thru the\r
+  TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob\r
+  to the hobs in DXE phase.\r
+\r
+  MemoryAllocationHob should also be created for Mailbox and Ovmf work area.\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformTdxPublishRamRegions (\r
+  VOID\r
+  )\r
+{\r
+}\r
index 911c0906cb3d0635c0a03fdd08f2d486e9e2e3f2..4c1dedf863c38c97fbefc0644bfdea0686e001ec 100644 (file)
@@ -37,6 +37,8 @@ Module Name:
 #include <Library/MtrrLib.h>\r
 #include <Library/QemuFwCfgLib.h>\r
 #include <Library/QemuFwCfgSimpleParserLib.h>\r
+#include <Library/TdxLib.h>\r
+\r
 #include <Library/PlatformInitLib.h>\r
 \r
 VOID\r
@@ -528,7 +530,19 @@ PlatformAddressWidthInitialization (
     PhysMemAddressWidth = 36;\r
   }\r
 \r
+ #if defined (MDE_CPU_X64)\r
+  if (TdIsEnabled ()) {\r
+    if (TdSharedPageMask () == (1ULL << 47)) {\r
+      PhysMemAddressWidth = 48;\r
+    } else {\r
+      PhysMemAddressWidth = 52;\r
+    }\r
+  }\r
+\r
+  ASSERT (PhysMemAddressWidth <= 52);\r
+ #else\r
   ASSERT (PhysMemAddressWidth <= 48);\r
+ #endif\r
 \r
   PlatformInfoHob->FirstNonAddress     = FirstNonAddress;\r
   PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;\r
index c4fa7d4453941b73bc7af4e87322abadd72616b7..101074f6100d34e08077549d1da09f0bec7d41b4 100644 (file)
@@ -136,7 +136,9 @@ PlatformMemMapInitialization (
   //\r
   // Video memory + Legacy BIOS region\r
   //\r
-  PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB);\r
+  if (!TdIsEnabled ()) {\r
+    PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB);\r
+  }\r
 \r
   if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {\r
     PlatformAddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB);\r