]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Update IoMmuDxe to support TDX
authorMin Xu <min.m.xu@intel.com>
Wed, 22 Sep 2021 12:49:05 +0000 (20:49 +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

The IOMMU protocol driver provides capabilities to set a DMA access
attribute and methods to allocate, free, map and unmap the DMA memory
for the PCI Bus devices.

The current IoMmuDxe driver supports DMA operations inside SEV guest.
To support DMA operation in TDX guest,
CC_GUEST_IS_XXX (PcdConfidentialComputingGuestAttr) is used to determine
if it is SEV guest or TDX guest.

Due to security reasons all DMA operations inside the SEV/TDX guest must
be performed on shared pages. The IOMMU protocol driver for the SEV/TDX
guest uses a bounce buffer to map guest DMA buffer to shared pages in
order to provide the support for DMA operations inside SEV/TDX guest.

The call of SEV or TDX specific function to set/clear EncMask/SharedBit
is determined by CC_GUEST_IS_XXX (PcdConfidentialComputingGuestAttr).

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/AmdSev/AmdSevX64.dsc
OvmfPkg/Bhyve/BhyveX64.dsc
OvmfPkg/CloudHv/CloudHvX64.dsc
OvmfPkg/IoMmuDxe/AmdSevIoMmu.c
OvmfPkg/IoMmuDxe/AmdSevIoMmu.h
OvmfPkg/IoMmuDxe/IoMmuDxe.c
OvmfPkg/IoMmuDxe/IoMmuDxe.inf
OvmfPkg/Microvm/MicrovmX64.dsc
OvmfPkg/OvmfPkgX64.dsc
OvmfPkg/OvmfXen.dsc

index dda98aa43bdb033cf2056667ac812a4e44a27dcf..5e096e15dc406cf6511a86ca072fe5d47ceca4c6 100644 (file)
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
   BlobVerifierLib|OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierLibSevHashes.inf\r
+  MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf\r
 \r
 !if $(SOURCE_DEBUG_ENABLE) == TRUE\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
index 0daae82d6705e2ce1f1d21238a582332cd1b5f0b..e1b6b8e15f3678ff28fa1906c506b583d1d7cc1f 100644 (file)
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf\r
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf\r
+  MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf\r
 \r
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
index 1732f281b4355c67537ea05dd247473e9c4a0636..ee340cc654bffdbc605ad1b12e772c72a9bf4d9b 100644 (file)
 !endif\r
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
+  MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf\r
 \r
 !if $(SOURCE_DEBUG_ENABLE) == TRUE\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
index 16b5b4eac8bc30b1a687b1c1ac00b5c9a42ddabe..6b65897f032aefcdcb538c27131828d800624abb 100644 (file)
@@ -1,9 +1,9 @@
 /** @file\r
 \r
   The protocol provides support to allocate, free, map and umap a DMA buffer\r
-  for bus master (e.g PciHostBridge). When SEV is enabled, the DMA operations\r
-  must be performed on unencrypted buffer hence we use a bounce buffer to map\r
-  the guest buffer into an unencrypted DMA buffer.\r
+  for bus master (e.g PciHostBridge). When SEV or TDX is enabled, the DMA\r
+  operations must be performed on unencrypted buffer hence we use a bounce\r
+  buffer to map the guest buffer into an unencrypted DMA buffer.\r
 \r
   Copyright (c) 2017, AMD Inc. All rights reserved.<BR>\r
   Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
@@ -12,6 +12,8 @@
 \r
 **/\r
 \r
+#include <Library/PcdLib.h>\r
+#include <ConfidentialComputingGuestAttr.h>\r
 #include "AmdSevIoMmu.h"\r
 \r
 #define MAP_INFO_SIG  SIGNATURE_64 ('M', 'A', 'P', '_', 'I', 'N', 'F', 'O')\r
@@ -74,7 +76,7 @@ typedef struct {
 \r
 /**\r
   Provides the controller-specific addresses required to access system memory\r
-  from a DMA bus master. On SEV guest, the DMA operations must be performed on\r
+  from a DMA bus master. On SEV/TDX guest, the DMA operations must be performed on\r
   shared buffer hence we allocate a bounce buffer to map the HostAddress to a\r
   DeviceAddress. The Encryption attribute is removed from the DeviceAddress\r
   buffer.\r
@@ -250,14 +252,28 @@ IoMmuMap (
       goto FreeMapInfo;\r
   }\r
 \r
-  //\r
-  // Clear the memory encryption mask on the plaintext buffer.\r
-  //\r
-  Status = MemEncryptSevClearPageEncMask (\r
-             0,\r
-             MapInfo->PlainTextAddress,\r
-             MapInfo->NumberOfPages\r
-             );\r
+  if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r
+    //\r
+    // Clear the memory encryption mask on the plaintext buffer.\r
+    //\r
+    Status = MemEncryptSevClearPageEncMask (\r
+               0,\r
+               MapInfo->PlainTextAddress,\r
+               MapInfo->NumberOfPages\r
+               );\r
+  } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r
+    //\r
+    // Set the memory shared bit.\r
+    //\r
+    Status = MemEncryptTdxSetPageSharedBit (\r
+               0,\r
+               MapInfo->PlainTextAddress,\r
+               MapInfo->NumberOfPages\r
+               );\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
   ASSERT_EFI_ERROR (Status);\r
   if (EFI_ERROR (Status)) {\r
     CpuDeadLoop ();\r
@@ -358,7 +374,7 @@ IoMmuUnmapWorker (
   }\r
 \r
   MapInfo = (MAP_INFO *)Mapping;\r
-\r
+  Status  = EFI_SUCCESS;\r
   //\r
   // set CommonBufferHeader to suppress incorrect compiler/analyzer warnings\r
   //\r
@@ -404,15 +420,30 @@ IoMmuUnmapWorker (
       break;\r
   }\r
 \r
-  //\r
-  // Restore the memory encryption mask on the area we used to hold the\r
-  // plaintext.\r
-  //\r
-  Status = MemEncryptSevSetPageEncMask (\r
-             0,\r
-             MapInfo->PlainTextAddress,\r
-             MapInfo->NumberOfPages\r
-             );\r
+  if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r
+    //\r
+    // Restore the memory encryption mask on the area we used to hold the\r
+    // plaintext.\r
+    //\r
+    Status = MemEncryptSevSetPageEncMask (\r
+               0,\r
+               MapInfo->PlainTextAddress,\r
+               MapInfo->NumberOfPages\r
+               );\r
+  } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r
+    //\r
+    // Restore the memory shared bit mask on the area we used to hold the\r
+    // plaintext.\r
+    //\r
+    Status = MemEncryptTdxClearPageSharedBit (\r
+               0,\r
+               MapInfo->PlainTextAddress,\r
+               MapInfo->NumberOfPages\r
+               );\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
   ASSERT_EFI_ERROR (Status);\r
   if (EFI_ERROR (Status)) {\r
     CpuDeadLoop ();\r
@@ -739,7 +770,7 @@ IoMmuSetAttribute (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-EDKII_IOMMU_PROTOCOL  mAmdSev = {\r
+EDKII_IOMMU_PROTOCOL  mIoMmu = {\r
   EDKII_IOMMU_PROTOCOL_REVISION,\r
   IoMmuSetAttribute,\r
   IoMmuMap,\r
@@ -771,7 +802,7 @@ EDKII_IOMMU_PROTOCOL  mAmdSev = {
 STATIC\r
 VOID\r
 EFIAPI\r
-AmdSevExitBoot (\r
+IoMmuExitBoot (\r
   IN EFI_EVENT  Event,\r
   IN VOID       *EventToSignal\r
   )\r
@@ -779,11 +810,11 @@ AmdSevExitBoot (
   //\r
   // (1) The NotifyFunctions of all the events in\r
   //     EFI_EVENT_GROUP_EXIT_BOOT_SERVICES will have been queued before\r
-  //     AmdSevExitBoot() is entered.\r
+  //     IoMmuExitBoot() is entered.\r
   //\r
-  // (2) AmdSevExitBoot() is executing minimally at TPL_CALLBACK.\r
+  // (2) IoMmuExitBoot() is executing minimally at TPL_CALLBACK.\r
   //\r
-  // (3) AmdSevExitBoot() has been queued in unspecified order relative to the\r
+  // (3) IoMmuExitBoot() has been queued in unspecified order relative to the\r
   //     NotifyFunctions of all the other events in\r
   //     EFI_EVENT_GROUP_EXIT_BOOT_SERVICES whose NotifyTpl is the same as\r
   //     Event's.\r
@@ -791,13 +822,13 @@ AmdSevExitBoot (
   // Consequences:\r
   //\r
   // - If Event's NotifyTpl is TPL_CALLBACK, then some other NotifyFunctions\r
-  //   queued at TPL_CALLBACK may be invoked after AmdSevExitBoot() returns.\r
+  //   queued at TPL_CALLBACK may be invoked after IoMmuExitBoot() returns.\r
   //\r
   // - If Event's NotifyTpl is TPL_NOTIFY, then some other NotifyFunctions\r
-  //   queued at TPL_NOTIFY may be invoked after AmdSevExitBoot() returns; plus\r
+  //   queued at TPL_NOTIFY may be invoked after IoMmuExitBoot() returns; plus\r
   //   *all* NotifyFunctions queued at TPL_CALLBACK will be invoked strictly\r
   //   after all NotifyFunctions queued at TPL_NOTIFY, including\r
-  //   AmdSevExitBoot(), have been invoked.\r
+  //   IoMmuExitBoot(), have been invoked.\r
   //\r
   // - By signaling EventToSignal here, whose NotifyTpl is TPL_CALLBACK, we\r
   //   queue EventToSignal's NotifyFunction after the NotifyFunctions of *all*\r
@@ -823,7 +854,7 @@ AmdSevExitBoot (
 STATIC\r
 VOID\r
 EFIAPI\r
-AmdSevUnmapAllMappings (\r
+IoMmuUnmapAllMappings (\r
   IN EFI_EVENT  Event,\r
   IN VOID       *Context\r
   )\r
@@ -842,7 +873,7 @@ AmdSevUnmapAllMappings (
     NextNode = GetNextNode (&mMapInfos, Node);\r
     MapInfo  = CR (Node, MAP_INFO, Link, MAP_INFO_SIG);\r
     IoMmuUnmapWorker (\r
-      &mAmdSev, // This\r
+      &mIoMmu,  // This\r
       MapInfo,  // Mapping\r
       TRUE      // MemoryMapLocked\r
       );\r
@@ -855,7 +886,7 @@ AmdSevUnmapAllMappings (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-AmdSevInstallIoMmuProtocol (\r
+InstallIoMmuProtocol (\r
   VOID\r
   )\r
 {\r
@@ -871,7 +902,7 @@ AmdSevInstallIoMmuProtocol (
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,      // Type\r
                   TPL_CALLBACK,           // NotifyTpl\r
-                  AmdSevUnmapAllMappings, // NotifyFunction\r
+                  IoMmuUnmapAllMappings,  // NotifyFunction\r
                   NULL,                   // NotifyContext\r
                   &UnmapAllMappingsEvent  // Event\r
                   );\r
@@ -886,7 +917,7 @@ AmdSevInstallIoMmuProtocol (
   Status = gBS->CreateEvent (\r
                   EVT_SIGNAL_EXIT_BOOT_SERVICES, // Type\r
                   TPL_CALLBACK,                  // NotifyTpl\r
-                  AmdSevExitBoot,                // NotifyFunction\r
+                  IoMmuExitBoot,                 // NotifyFunction\r
                   UnmapAllMappingsEvent,         // NotifyContext\r
                   &ExitBootEvent                 // Event\r
                   );\r
@@ -898,7 +929,7 @@ AmdSevInstallIoMmuProtocol (
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Handle,\r
                   &gEdkiiIoMmuProtocolGuid,\r
-                  &mAmdSev,\r
+                  &mIoMmu,\r
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
index 8244f28b57fd99fd54bf1280a5aaa1a402a5f397..8fdfa9968593e66b0ed5a4d4eee88545f724f954 100644 (file)
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemEncryptSevLib.h>\r
+#include <Library/MemEncryptTdxLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 \r
 /**\r
-  Install IOMMU protocol to provide the DMA support for PciHostBridge and\r
-  MemEncryptSevLib.\r
+  Install IOMMU protocol to provide the DMA support for PciHostBridge.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-AmdSevInstallIoMmuProtocol (\r
+InstallIoMmuProtocol (\r
   VOID\r
   );\r
 \r
index bca8c14c4076a527d9ca06f59ed27e8e490af4f4..86777dd05c2655cdff6412125b1d6a590dce1f68 100644 (file)
@@ -22,11 +22,11 @@ IoMmuDxeEntryPoint (
   EFI_HANDLE  Handle;\r
 \r
   //\r
-  // When SEV is enabled, install IoMmu protocol otherwise install the\r
+  // When SEV or TDX is enabled, install IoMmu protocol otherwise install the\r
   // placeholder protocol so that other dependent module can run.\r
   //\r
-  if (MemEncryptSevIsEnabled ()) {\r
-    Status = AmdSevInstallIoMmuProtocol ();\r
+  if (MemEncryptSevIsEnabled () || MemEncryptTdxIsEnabled ()) {\r
+    Status = InstallIoMmuProtocol ();\r
   } else {\r
     Handle = NULL;\r
 \r
index 2ebd74e5558c34a30b7b38fb9b3d468f52fafbfa..e10be1dcff490d645003b5bf7db4d40bbdcc9092 100644 (file)
   MdePkg/MdePkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
   OvmfPkg/OvmfPkg.dec\r
+#  UefiCpuPkg/UefiCpuPkg.dec\r
 \r
 [LibraryClasses]\r
   BaseLib\r
   BaseMemoryLib\r
   DebugLib\r
   MemEncryptSevLib\r
+  MemEncryptTdxLib\r
   MemoryAllocationLib\r
   UefiBootServicesTableLib\r
   UefiDriverEntryPoint\r
 \r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr\r
+\r
 [Protocols]\r
   gEdkiiIoMmuProtocolGuid                     ## SOMETIME_PRODUCES\r
   gIoMmuAbsentProtocolGuid                    ## SOMETIME_PRODUCES\r
index cde90f5235204f66192112e3f40b8e778709dc62..9fc0ff2750b1e866aac6399ebc1e801e680c1714 100644 (file)
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf\r
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
+  MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf\r
 \r
 !if $(SOURCE_DEBUG_ENABLE) == TRUE\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
index 21542479091588597763d6f7bbb310b0b0c93f2b..2647034d08a562f178f67d76ba2954fd298764cd 100644 (file)
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf\r
+  MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf\r
+\r
 !if $(SMM_REQUIRE) == FALSE\r
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf\r
 !endif\r
index 470c8cfe4d239406887d614d0ea163d89256a689..78d1509f75bd4ee19b4f3cad9f3b45c0ddd391c6 100644 (file)
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf\r
   CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
+  MemEncryptTdxLib|OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLib.inf\r
 \r
 !if $(SOURCE_DEBUG_ENABLE) == TRUE\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r