From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.44290.1635772975415423575 for ; Mon, 01 Nov 2021 06:22:59 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: min.m.xu@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10154"; a="254617551" X-IronPort-AV: E=Sophos;i="5.87,199,1631602800"; d="scan'208";a="254617551" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Nov 2021 06:17:04 -0700 X-IronPort-AV: E=Sophos;i="5.87,199,1631602800"; d="scan'208";a="500035515" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.255.29.216]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Nov 2021 06:17:01 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Michael D Kinney , Liming Gao , Zhiguang Liu , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [PATCH V3 09/29] MdePkg: Support IoRead/IoWrite for Tdx guest in BaseIoLibIntrinsic Date: Mon, 1 Nov 2021 21:15:58 +0800 Message-Id: <0e3ed03d7185dd535a1b7a4e2aec6298eb11aa34.1635769996.git.min.m.xu@intel.com> X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 This commit supports IoRead/IoWrite for SEV/TDX/Legacy guest in one binary. It checks the guest type in runtime and then call corresponding functions. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Signed-off-by: Min Xu --- MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c | 49 +++++++++++-- MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c | 73 +++++++++++++++----- 2 files changed, 98 insertions(+), 24 deletions(-) diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c index ecf9ed61911f..42b5d5743a4f 100644 --- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c @@ -17,6 +17,7 @@ #include "BaseIoLibIntrinsicInternal.h" +#include "IoLibTdx.h" /** Reads an 8-bit I/O port. @@ -25,7 +26,9 @@ This function must guarantee that all I/O read and write operations are serialized. - If 8-bit I/O port operations are not supported, then ASSERT(). + If 8-bit I/O port operations are not supported, then ASSERT() + + For Td guest TDVMCALL_IO is invoked to read I/O port. @param Port The I/O port to read. @@ -43,7 +46,11 @@ IoRead8 ( Flag = FilterBeforeIoRead (FilterWidth8, Port, &Data); if (Flag) { - __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port)); + if (IsTdxGuest ()) { + Data = TdIoRead8 (Port); + } else { + __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port)); + } } FilterAfterIoRead (FilterWidth8, Port, &Data); @@ -59,6 +66,8 @@ IoRead8 ( If 8-bit I/O port operations are not supported, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to write I/O port. + @param Port The I/O port to write. @param Value The value to write to the I/O port. @@ -76,7 +85,11 @@ IoWrite8 ( Flag = FilterBeforeIoWrite (FilterWidth8, Port, &Value); if (Flag) { - __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + if (IsTdxGuest ()) { + TdIoWrite8 (Port, Value); + } else { + __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + } } FilterAfterIoWrite (FilterWidth8, Port, &Value); @@ -93,6 +106,8 @@ IoWrite8 ( If 16-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 16-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. @return The value read. @@ -111,7 +126,11 @@ IoRead16 ( Flag = FilterBeforeIoRead (FilterWidth16, Port, &Data); if (Flag) { + if (IsTdxGuest ()) { + Data = TdIoRead16 (Port); + } else { __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port)); + } } FilterAfterIoRead (FilterWidth16, Port, &Data); @@ -128,6 +147,8 @@ IoRead16 ( If 16-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 16-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to write I/O port. + @param Port The I/O port to write. @param Value The value to write to the I/O port. @@ -148,7 +169,11 @@ IoWrite16 ( Flag = FilterBeforeIoWrite (FilterWidth16, Port, &Value); if (Flag) { - __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + if (IsTdxGuest ()) { + TdIoWrite16 (Port, Value); + } else { + __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + } } FilterAfterIoWrite (FilterWidth16, Port, &Value); @@ -165,6 +190,8 @@ IoWrite16 ( If 32-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 32-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. @return The value read. @@ -183,7 +210,11 @@ IoRead32 ( Flag = FilterBeforeIoRead (FilterWidth32, Port, &Data); if (Flag) { - __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port)); + if (IsTdxGuest ()) { + Data = TdIoRead32 (Port); + } else { + __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port)); + } } FilterAfterIoRead (FilterWidth32, Port, &Data); @@ -200,6 +231,8 @@ IoRead32 ( If 32-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 32-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to write I/O port. + @param Port The I/O port to write. @param Value The value to write to the I/O port. @@ -219,7 +252,11 @@ IoWrite32 ( Flag = FilterBeforeIoWrite (FilterWidth32, Port, &Value); if (Flag) { - __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + if (IsTdxGuest ()) { + TdIoWrite32 (Port, Value); + } else { + __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port)); + } } FilterAfterIoWrite (FilterWidth32, Port, &Value); diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c index d2bc5f527cf6..4d7945ae496f 100644 --- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c @@ -16,6 +16,7 @@ #include "BaseIoLibIntrinsicInternal.h" +#include "IoLibTdx.h" // // Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. @@ -54,6 +55,8 @@ void _ReadWriteBarrier (void); If 8-bit I/O port operations are not supported, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. @return The value read. @@ -70,9 +73,13 @@ IoRead8 ( Flag = FilterBeforeIoRead (FilterWidth8, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - Value = (UINT8)_inp ((UINT16)Port); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + Value = TdIoRead8 (Port); + } else { + _ReadWriteBarrier (); + Value = (UINT8)_inp ((UINT16)Port); + _ReadWriteBarrier (); + } } FilterAfterIoRead (FilterWidth8, Port, &Value); @@ -88,6 +95,8 @@ IoRead8 ( If 8-bit I/O port operations are not supported, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to write I/O port. + @param Port The I/O port to write. @param Value The value to write to the I/O port. @@ -105,9 +114,13 @@ IoWrite8 ( Flag = FilterBeforeIoWrite(FilterWidth8, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - (UINT8)_outp ((UINT16)Port, Value); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + TdIoWrite8 (Port, Value); + } else { + _ReadWriteBarrier (); + (UINT8)_outp ((UINT16)Port, Value); + _ReadWriteBarrier (); + } } FilterAfterIoWrite (FilterWidth8, Port, &Value); @@ -124,6 +137,8 @@ IoWrite8 ( If 16-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 16-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. @return The value read. @@ -142,9 +157,13 @@ IoRead16 ( Flag = FilterBeforeIoRead (FilterWidth16, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - Value = _inpw ((UINT16)Port); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + Value = TdIoRead16 (Port); + } else { + _ReadWriteBarrier (); + Value = _inpw ((UINT16)Port); + _ReadWriteBarrier (); + } } FilterBeforeIoRead (FilterWidth16, Port, &Value); @@ -161,6 +180,8 @@ IoRead16 ( If 16-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 16-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to write I/O port. + @param Port The I/O port to write. @param Value The value to write to the I/O port. @@ -180,9 +201,13 @@ IoWrite16 ( Flag = FilterBeforeIoWrite(FilterWidth16, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - _outpw ((UINT16)Port, Value); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + TdIoWrite16 (Port, Value); + } else { + _ReadWriteBarrier (); + _outpw ((UINT16)Port, Value); + _ReadWriteBarrier (); + } } FilterAfterIoWrite (FilterWidth16, Port, &Value); @@ -199,6 +224,8 @@ IoWrite16 ( If 32-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 32-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. @return The value read. @@ -217,9 +244,13 @@ IoRead32 ( Flag = FilterBeforeIoRead(FilterWidth32, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - Value = _inpd ((UINT16)Port); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + Value = TdIoRead32 (Port); + } else { + _ReadWriteBarrier (); + Value = _inpd ((UINT16)Port); + _ReadWriteBarrier (); + } } FilterAfterIoRead (FilterWidth32, Port, &Value); @@ -236,6 +267,8 @@ IoRead32 ( If 32-bit I/O port operations are not supported, then ASSERT(). If Port is not aligned on a 32-bit boundary, then ASSERT(). + For Td guest TDVMCALL_IO is invoked to write I/O port. + @param Port The I/O port to write. @param Value The value to write to the I/O port. @@ -255,9 +288,13 @@ IoWrite32 ( Flag = FilterBeforeIoWrite(FilterWidth32, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - _outpd ((UINT16)Port, Value); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + TdIoWrite32 (Port, Value); + } else { + _ReadWriteBarrier (); + _outpd ((UINT16)Port, Value); + _ReadWriteBarrier (); + } } FilterAfterIoWrite (FilterWidth32, Port, &Value); -- 2.29.2.windows.2