Skip to content

Commit

Permalink
MdePkg: Support mmio for Tdx guest in BaseIoLibIntrinsic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mxu9 authored and mergify[bot] committed Apr 2, 2022
1 parent ab9d790 commit b6b2de8
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 8 deletions.
2 changes: 2 additions & 0 deletions MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
IoLibMmioBuffer.c
BaseIoLibIntrinsicInternal.h
IoHighLevel.c
IoLibInternalTdxNull.c
IoLibTdx.h

[Sources.IA32]
IoLibGcc.c | GCC
Expand Down
3 changes: 3 additions & 0 deletions MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
81 changes: 73 additions & 8 deletions MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
**/

#include "BaseIoLibIntrinsicInternal.h"
#include "IoLibTdx.h"

/**
Reads a 64-bit I/O port.
Expand Down Expand Up @@ -69,6 +70,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.
Expand All @@ -86,7 +89,13 @@ MmioRead8 (
Flag = FilterBeforeMmIoRead (FilterWidth8, Address, &Value);
if (Flag) {
MemoryFence ();
Value = *(volatile UINT8 *)Address;

if (IsTdxGuest ()) {
Value = TdMmioRead8 (Address);
} else {
Value = *(volatile UINT8 *)Address;
}

MemoryFence ();
}

Expand All @@ -104,6 +113,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.
Expand All @@ -122,7 +133,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 ();
}

Expand All @@ -141,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.
Expand All @@ -159,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 ();
}

Expand All @@ -178,6 +203,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.
Expand All @@ -198,7 +225,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 ();
}

Expand All @@ -217,6 +250,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.
Expand All @@ -236,7 +271,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 ();
}

Expand All @@ -255,6 +296,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.
Expand All @@ -275,7 +318,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 ();
}

Expand All @@ -294,6 +343,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.
Expand All @@ -313,7 +364,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 ();
}

Expand All @@ -332,6 +389,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.
Expand All @@ -350,7 +409,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 ();
}

Expand Down

0 comments on commit b6b2de8

Please sign in to comment.