[edk2-devel] [PATCH V3 07/29] MdePkg: Support mmio for Tdx guest in BaseIoLibIntrinsic

Min Xu min.m.xu at intel.com
Mon Nov 1 13:15:56 UTC 2021


RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

TDVF access MMIO with TDG.VP.VMCALL to invoke VMM provided emulation
functions. If the access to MMIO fails, it fall backs to the direct
access.

BaseIoLibIntrinsic.inf is the IoLib used by other packages. It will
not support I/O in Td guest. But some files are shared between
BaseIoLibIntrinsic and BaseIoLibIntrinsicSev (IoLib.c is the example). So
IoLibInternalTdxNull.c (which holds the null stub of the Td I/O routines)
is included in BaseIoLibIntrinsic.inf. BaseIoLibIntrinsic.inf doesn't
import TdxLib so that the Pkgs which include BaseIoLibIntrinsic.inf
need not include TdxLib.

Cc: Michael D Kinney <michael.d.kinney at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu 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>
Signed-off-by: Min Xu <min.m.xu at intel.com>
---
 .../BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf |  2 +
 .../BaseIoLibIntrinsicSev.inf                 |  5 +-
 MdePkg/Library/BaseIoLibIntrinsic/IoLib.c     | 82 +++++++++++++++++--
 3 files changed, 80 insertions(+), 9 deletions(-)

diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
index 97eeada0656e..27b15d9ae256 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
@@ -34,6 +34,8 @@
   IoLibMmioBuffer.c
   BaseIoLibIntrinsicInternal.h
   IoHighLevel.c
+  IoLibInternalTdxNull.c
+  IoLibTdx.h
 
 [Sources.IA32]
   IoLibGcc.c    | GCC
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
index 34f9d1d1062f..525aefb0d822 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
+++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
@@ -30,17 +30,20 @@
   IoLibMmioBuffer.c
   BaseIoLibIntrinsicInternal.h
   IoHighLevel.c
+  IoLibTdx.h
 
 [Sources.IA32]
   IoLibGcc.c    | GCC
   IoLibMsc.c    | MSFT
   IoLib.c
+  IoLibInternalTdxNull.c
   Ia32/IoFifoSev.nasm
 
 [Sources.X64]
   IoLibGcc.c    | GCC
   IoLibMsc.c    | MSFT
   IoLib.c
+  IoLibInternalTdx.c
   X64/IoFifoSev.nasm
 
 [Packages]
@@ -50,4 +53,4 @@
   DebugLib
   BaseLib
   RegisterFilterLib
-
+  TdxLib
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
index d0d7044f0901..62381647fd1d 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
@@ -7,6 +7,7 @@
 **/
 
 #include "BaseIoLibIntrinsicInternal.h"
+#include "IoLibTdx.h"
 
 /**
   Reads a 64-bit I/O port.
@@ -70,6 +71,8 @@ IoWrite64 (
 
   If 8-bit MMIO register operations are not supported, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
   @param  Address The MMIO register to read.
 
   @return The value read.
@@ -87,8 +90,15 @@ MmioRead8 (
   Flag = FilterBeforeMmIoRead (FilterWidth8, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    Value = *(volatile UINT8*)Address;
+
+    if (IsTdxGuest ()) {
+      Value = TdMmioRead8 (Address);
+    } else {
+      Value = *(volatile UINT8*)Address;
+    }
+
     MemoryFence ();
+
   }
   FilterAfterMmIoRead (FilterWidth8, Address, &Value);
 
@@ -104,6 +114,8 @@ MmioRead8 (
 
   If 8-bit MMIO register operations are not supported, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to write MMIO registers.
+
   @param  Address The MMIO register to write.
   @param  Value   The value to write to the MMIO register.
 
@@ -122,7 +134,13 @@ MmioWrite8 (
   Flag = FilterBeforeMmIoWrite (FilterWidth8, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    *(volatile UINT8*)Address = Value;
+
+    if (IsTdxGuest ()) {
+      TdMmioWrite8 (Address, Value);
+    } else {
+      *(volatile UINT8*)Address = Value;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoWrite (FilterWidth8, Address, &Value);
@@ -140,6 +158,8 @@ MmioWrite8 (
   If 16-bit MMIO register operations are not supported, then ASSERT().
   If Address is not aligned on a 16-bit boundary, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
   @param  Address The MMIO register to read.
 
   @return The value read.
@@ -158,7 +178,13 @@ MmioRead16 (
   Flag = FilterBeforeMmIoRead (FilterWidth16, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    Value = *(volatile UINT16*)Address;
+
+    if (IsTdxGuest ()) {
+      Value = TdMmioRead16 (Address);
+    } else {
+      Value = *(volatile UINT16*)Address;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoRead (FilterWidth16, Address, &Value);
@@ -176,6 +202,8 @@ MmioRead16 (
   If 16-bit MMIO register operations are not supported, then ASSERT().
   If Address is not aligned on a 16-bit boundary, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to write MMIO registers.
+
   @param  Address The MMIO register to write.
   @param  Value   The value to write to the MMIO register.
 
@@ -196,7 +224,13 @@ MmioWrite16 (
   Flag = FilterBeforeMmIoWrite (FilterWidth16, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    *(volatile UINT16*)Address = Value;
+
+    if (IsTdxGuest ()) {
+      TdMmioWrite16 (Address, Value);
+    } else {
+      *(volatile UINT16*)Address = Value;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoWrite (FilterWidth16, Address, &Value);
@@ -214,6 +248,8 @@ MmioWrite16 (
   If 32-bit MMIO register operations are not supported, then ASSERT().
   If Address is not aligned on a 32-bit boundary, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
   @param  Address The MMIO register to read.
 
   @return The value read.
@@ -233,7 +269,13 @@ MmioRead32 (
   Flag = FilterBeforeMmIoRead (FilterWidth32, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    Value = *(volatile UINT32*)Address;
+
+    if (IsTdxGuest ()) {
+      Value = TdMmioRead32 (Address);
+    } else {
+      Value = *(volatile UINT32*)Address;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoRead (FilterWidth32, Address, &Value);
@@ -251,6 +293,8 @@ MmioRead32 (
   If 32-bit MMIO register operations are not supported, then ASSERT().
   If Address is not aligned on a 32-bit boundary, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to write MMIO registers.
+
   @param  Address The MMIO register to write.
   @param  Value   The value to write to the MMIO register.
 
@@ -271,7 +315,13 @@ MmioWrite32 (
   Flag = FilterBeforeMmIoWrite (FilterWidth32, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    *(volatile UINT32*)Address = Value;
+
+    if (IsTdxGuest ()) {
+      TdMmioWrite32 (Address, Value);
+    } else {
+      *(volatile UINT32*)Address = Value;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoWrite (FilterWidth32, Address, &Value);
@@ -289,6 +339,8 @@ MmioWrite32 (
   If 64-bit MMIO register operations are not supported, then ASSERT().
   If Address is not aligned on a 64-bit boundary, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to read MMIO registers.
+
   @param  Address The MMIO register to read.
 
   @return The value read.
@@ -308,7 +360,13 @@ MmioRead64 (
   Flag = FilterBeforeMmIoRead (FilterWidth64, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    Value = *(volatile UINT64*)Address;
+
+    if (IsTdxGuest ()) {
+      Value = TdMmioRead64 (Address);
+    } else {
+      Value = *(volatile UINT64*)Address;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoRead (FilterWidth64, Address, &Value);
@@ -326,6 +384,8 @@ MmioRead64 (
   If 64-bit MMIO register operations are not supported, then ASSERT().
   If Address is not aligned on a 64-bit boundary, then ASSERT().
 
+  For Td guest TDVMCALL_MMIO is invoked to write MMIO registers.
+
   @param  Address The MMIO register to write.
   @param  Value   The value to write to the MMIO register.
 
@@ -344,7 +404,13 @@ MmioWrite64 (
   Flag = FilterBeforeMmIoWrite (FilterWidth64, Address, &Value);
   if (Flag) {
     MemoryFence ();
-    *(volatile UINT64*)Address = Value;
+
+    if (IsTdxGuest ()) {
+      TdMmioWrite64 (Address, Value);
+    } else {
+      *(volatile UINT64*)Address = Value;
+    }
+
     MemoryFence ();
   }
   FilterAfterMmIoWrite (FilterWidth64, Address, &Value);
-- 
2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#82989): https://edk2.groups.io/g/devel/message/82989
Mute This Topic: https://groups.io/mt/86739962/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