MdePkg: Support mmio for Tdx guest in BaseIoLibIntrinsic

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@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@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: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
Min Xu
2021-10-22 13:48:28 +08:00
committed by mergify[bot]
parent ab9d790901
commit b6b2de8848
3 changed files with 78 additions and 8 deletions

View File

@ -34,6 +34,8 @@
IoLibMmioBuffer.c IoLibMmioBuffer.c
BaseIoLibIntrinsicInternal.h BaseIoLibIntrinsicInternal.h
IoHighLevel.c IoHighLevel.c
IoLibInternalTdxNull.c
IoLibTdx.h
[Sources.IA32] [Sources.IA32]
IoLibGcc.c | GCC IoLibGcc.c | GCC

View File

@ -30,17 +30,20 @@
IoLibMmioBuffer.c IoLibMmioBuffer.c
BaseIoLibIntrinsicInternal.h BaseIoLibIntrinsicInternal.h
IoHighLevel.c IoHighLevel.c
IoLibTdx.h
[Sources.IA32] [Sources.IA32]
IoLibGcc.c | GCC IoLibGcc.c | GCC
IoLibMsc.c | MSFT IoLibMsc.c | MSFT
IoLib.c IoLib.c
IoLibInternalTdxNull.c
Ia32/IoFifoSev.nasm Ia32/IoFifoSev.nasm
[Sources.X64] [Sources.X64]
IoLibGcc.c | GCC IoLibGcc.c | GCC
IoLibMsc.c | MSFT IoLibMsc.c | MSFT
IoLib.c IoLib.c
IoLibInternalTdx.c
X64/IoFifoSev.nasm X64/IoFifoSev.nasm
[Packages] [Packages]

View File

@ -7,6 +7,7 @@
**/ **/
#include "BaseIoLibIntrinsicInternal.h" #include "BaseIoLibIntrinsicInternal.h"
#include "IoLibTdx.h"
/** /**
Reads a 64-bit I/O port. Reads a 64-bit I/O port.
@ -69,6 +70,8 @@ IoWrite64 (
If 8-bit MMIO register operations are not supported, then ASSERT(). 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. @param Address The MMIO register to read.
@return The value read. @return The value read.
@ -86,7 +89,13 @@ MmioRead8 (
Flag = FilterBeforeMmIoRead (FilterWidth8, Address, &Value); Flag = FilterBeforeMmIoRead (FilterWidth8, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
Value = *(volatile UINT8 *)Address;
if (IsTdxGuest ()) {
Value = TdMmioRead8 (Address);
} else {
Value = *(volatile UINT8 *)Address;
}
MemoryFence (); MemoryFence ();
} }
@ -104,6 +113,8 @@ MmioRead8 (
If 8-bit MMIO register operations are not supported, then ASSERT(). 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 Address The MMIO register to write.
@param Value The value to write to the MMIO register. @param Value The value to write to the MMIO register.
@ -122,7 +133,13 @@ MmioWrite8 (
Flag = FilterBeforeMmIoWrite (FilterWidth8, Address, &Value); Flag = FilterBeforeMmIoWrite (FilterWidth8, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
*(volatile UINT8 *)Address = Value;
if (IsTdxGuest ()) {
TdMmioWrite8 (Address, Value);
} else {
*(volatile UINT8 *)Address = Value;
}
MemoryFence (); MemoryFence ();
} }
@ -141,6 +158,8 @@ MmioWrite8 (
If 16-bit MMIO register operations are not supported, then ASSERT(). If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, 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. @param Address The MMIO register to read.
@return The value read. @return The value read.
@ -159,7 +178,13 @@ MmioRead16 (
Flag = FilterBeforeMmIoRead (FilterWidth16, Address, &Value); Flag = FilterBeforeMmIoRead (FilterWidth16, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
Value = *(volatile UINT16 *)Address;
if (IsTdxGuest ()) {
Value = TdMmioRead16 (Address);
} else {
Value = *(volatile UINT16 *)Address;
}
MemoryFence (); MemoryFence ();
} }
@ -178,6 +203,8 @@ MmioRead16 (
If 16-bit MMIO register operations are not supported, then ASSERT(). If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, 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 Address The MMIO register to write.
@param Value The value to write to the MMIO register. @param Value The value to write to the MMIO register.
@ -198,7 +225,13 @@ MmioWrite16 (
Flag = FilterBeforeMmIoWrite (FilterWidth16, Address, &Value); Flag = FilterBeforeMmIoWrite (FilterWidth16, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
*(volatile UINT16 *)Address = Value;
if (IsTdxGuest ()) {
TdMmioWrite16 (Address, Value);
} else {
*(volatile UINT16 *)Address = Value;
}
MemoryFence (); MemoryFence ();
} }
@ -217,6 +250,8 @@ MmioWrite16 (
If 32-bit MMIO register operations are not supported, then ASSERT(). If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, 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. @param Address The MMIO register to read.
@return The value read. @return The value read.
@ -236,7 +271,13 @@ MmioRead32 (
Flag = FilterBeforeMmIoRead (FilterWidth32, Address, &Value); Flag = FilterBeforeMmIoRead (FilterWidth32, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
Value = *(volatile UINT32 *)Address;
if (IsTdxGuest ()) {
Value = TdMmioRead32 (Address);
} else {
Value = *(volatile UINT32 *)Address;
}
MemoryFence (); MemoryFence ();
} }
@ -255,6 +296,8 @@ MmioRead32 (
If 32-bit MMIO register operations are not supported, then ASSERT(). If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, 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 Address The MMIO register to write.
@param Value The value to write to the MMIO register. @param Value The value to write to the MMIO register.
@ -275,7 +318,13 @@ MmioWrite32 (
Flag = FilterBeforeMmIoWrite (FilterWidth32, Address, &Value); Flag = FilterBeforeMmIoWrite (FilterWidth32, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
*(volatile UINT32 *)Address = Value;
if (IsTdxGuest ()) {
TdMmioWrite32 (Address, Value);
} else {
*(volatile UINT32 *)Address = Value;
}
MemoryFence (); MemoryFence ();
} }
@ -294,6 +343,8 @@ MmioWrite32 (
If 64-bit MMIO register operations are not supported, then ASSERT(). If 64-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 64-bit boundary, 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. @param Address The MMIO register to read.
@return The value read. @return The value read.
@ -313,7 +364,13 @@ MmioRead64 (
Flag = FilterBeforeMmIoRead (FilterWidth64, Address, &Value); Flag = FilterBeforeMmIoRead (FilterWidth64, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
Value = *(volatile UINT64 *)Address;
if (IsTdxGuest ()) {
Value = TdMmioRead64 (Address);
} else {
Value = *(volatile UINT64 *)Address;
}
MemoryFence (); MemoryFence ();
} }
@ -332,6 +389,8 @@ MmioRead64 (
If 64-bit MMIO register operations are not supported, then ASSERT(). If 64-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 64-bit boundary, 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 Address The MMIO register to write.
@param Value The value to write to the MMIO register. @param Value The value to write to the MMIO register.
@ -350,7 +409,13 @@ MmioWrite64 (
Flag = FilterBeforeMmIoWrite (FilterWidth64, Address, &Value); Flag = FilterBeforeMmIoWrite (FilterWidth64, Address, &Value);
if (Flag) { if (Flag) {
MemoryFence (); MemoryFence ();
*(volatile UINT64 *)Address = Value;
if (IsTdxGuest ()) {
TdMmioWrite64 (Address, Value);
} else {
*(volatile UINT64 *)Address = Value;
}
MemoryFence (); MemoryFence ();
} }