[edk2-devel] [PATCH V7 34/37] OvmfPkg: Update IoMmuDxe to support TDX

Min Xu min.m.xu at intel.com
Mon Feb 28 07:21:06 UTC 2022


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 at kernel.org>
Cc: Jordan Justen <jordan.l.justen at intel.com>
Cc: Brijesh Singh <brijesh.singh at amd.com>
Cc: Erdem Aktas <erdemaktas at google.com>
Cc: James Bottomley <jejb at linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Gerd Hoffmann <kraxel at redhat.com>
Acked-by: Gerd Hoffmann <kraxel at redhat.com>
Signed-off-by: Min Xu <min.m.xu at intel.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc   |   1 +
 OvmfPkg/Bhyve/BhyveX64.dsc     |   1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc |   1 +
 OvmfPkg/IoMmuDxe/AmdSevIoMmu.c | 103 +++++++++++++++++++++------------
 OvmfPkg/IoMmuDxe/AmdSevIoMmu.h |   6 +-
 OvmfPkg/IoMmuDxe/IoMmuDxe.c    |   6 +-
 OvmfPkg/IoMmuDxe/IoMmuDxe.inf  |   5 ++
 OvmfPkg/Microvm/MicrovmX64.dsc |   1 +
 OvmfPkg/OvmfPkgX64.dsc         |   2 +
 OvmfPkg/OvmfXen.dsc            |   1 +
 10 files changed, 85 insertions(+), 42 deletions(-)

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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#87081): https://edk2.groups.io/g/devel/message/87081
Mute This Topic: https://groups.io/mt/89446186/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list