From nobody Mon Feb 9 08:59:46 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+84717+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84717+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1639400280; cv=none; d=zohomail.com; s=zohoarc; b=SSl2Wg+69XYGr1Sb9Woz/S9RukWVNQMuzqgwrXa20ol4ywiCi70PBVJ9a2Y9DEOd/Kf8RCCTR9PgapwCEAA+9qjUM6UnQjZQS0uz9Ms7mzdT+YhL6aFGHMB2iyk55MVT85OBU168hmNMuNZYyXg6wsM8w7E4xXYVcBLalF7sXgk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639400280; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=FuONVuIY8SG04kt8xCuvtuSNq3Fomf5XSVx6UGDejLY=; b=PhFbP4lRMwajLu6eh+6WCKG0vALabzTnUWG6tRFHzLQfPtJJhWkDtDFZ3fMmLsJzf0pNzSmkFxa9K8eBMGHA84j8yepPtxwl8FzE5ktO/lpFSRIpcg67L2O9ZMcdKRPBDsmMwtJoBYGRsct9x0fNjqLRuo3JL1DLPoqOTtRDEdk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84717+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 16394002805841016.9763246153748; Mon, 13 Dec 2021 04:58:00 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8V1IYY1788612xvpT3S6sxY7; Mon, 13 Dec 2021 04:58:00 -0800 X-Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web10.10693.1639400242692099801 for ; Mon, 13 Dec 2021 04:57:59 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10196"; a="238669380" X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="238669380" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2021 04:57:59 -0800 X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="517738417" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.173.142]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2021 04:57:55 -0800 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: [edk2-devel] [PATCH V4 10/31] MdePkg: Support IoRead/IoWrite for Tdx guest in BaseIoLibIntrinsic Date: Mon, 13 Dec 2021 20:56:41 +0800 Message-Id: <1022a090a46291dec842c9035b42317ab9c0d147.1639399598.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: HrnJP0IP59mkUJKGAwXXQsjrx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1639400280; bh=//zHyLz4TLnR+yU9PRoxKy1qKtlb+0V3dKtTqD024ZY=; h=Cc:Date:From:Reply-To:Subject:To; b=kVwPkOhTi9XvnoWF4NP+tUWGMUlQQVqkx4pJrX9i+EOnlwQI9DBhRXobOvlHNB5kFFt 2xrXESIX8SfAgHesGFiG8QOtTR8hMSQlzElNYZkpViHzn1PyFiZBBdNg+eUSgB0ZKPB+h 1Pja9HQ1/nrMHtsTS7gaInRHq0MMDtcHeUE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1639400281831100001 Content-Type: text/plain; charset="utf-8" RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3429 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 Acked-by: Gerd Hoffmann --- MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c | 51 ++++++++++++-- MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c | 73 +++++++++++++++----- 2 files changed, 99 insertions(+), 25 deletions(-) diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c b/MdePkg/Library/= BaseIoLibIntrinsic/IoLibGcc.c index 5c791289c469..05a739085967 100644 --- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c @@ -16,6 +16,7 @@ **/ =20 #include "BaseIoLibIntrinsicInternal.h" +#include "IoLibTdx.h" =20 /** Reads an 8-bit I/O port. @@ -24,7 +25,9 @@ This function must guarantee that all I/O read and write operations are serialized. =20 - 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. =20 @param Port The I/O port to read. =20 @@ -42,7 +45,11 @@ IoRead8 ( =20 Flag =3D FilterBeforeIoRead (FilterWidth8, Port, &Data); if (Flag) { - __asm__ __volatile__ ("inb %w1,%b0" : "=3Da" (Data) : "d" ((UINT16)Por= t)); + if (IsTdxGuest ()) { + Data =3D TdIoRead8 (Port); + } else { + __asm__ __volatile__ ("inb %w1,%b0" : "=3Da" (Data) : "d" ((UINT16)P= ort)); + } } =20 FilterAfterIoRead (FilterWidth8, Port, &Data); @@ -59,6 +66,8 @@ IoRead8 ( =20 If 8-bit I/O port operations are not supported, then ASSERT(). =20 + 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. =20 @@ -76,7 +85,11 @@ IoWrite8 ( =20 Flag =3D FilterBeforeIoWrite (FilterWidth8, Port, &Value); if (Flag) { - __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Por= t)); + if (IsTdxGuest ()) { + TdIoWrite8 (Port, Value); + } else { + __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)P= ort)); + } } =20 FilterAfterIoWrite (FilterWidth8, Port, &Value); @@ -94,6 +107,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(). =20 + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. =20 @return The value read. @@ -112,7 +127,11 @@ IoRead16 ( =20 Flag =3D FilterBeforeIoRead (FilterWidth16, Port, &Data); if (Flag) { - __asm__ __volatile__ ("inw %w1,%w0" : "=3Da" (Data) : "d" ((UINT16)Por= t)); + if (IsTdxGuest ()) { + Data =3D TdIoRead16 (Port); + } else { + __asm__ __volatile__ ("inw %w1,%w0" : "=3Da" (Data) : "d" ((UINT16)P= ort)); + } } =20 FilterAfterIoRead (FilterWidth16, Port, &Data); @@ -130,6 +149,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(). =20 + 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. =20 @@ -149,7 +170,11 @@ IoWrite16 ( =20 Flag =3D FilterBeforeIoWrite (FilterWidth16, Port, &Value); if (Flag) { - __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Por= t)); + if (IsTdxGuest ()) { + TdIoWrite16 (Port, Value); + } else { + __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)P= ort)); + } } =20 FilterAfterIoWrite (FilterWidth16, Port, &Value); @@ -167,6 +192,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(). =20 + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. =20 @return The value read. @@ -185,7 +212,11 @@ IoRead32 ( =20 Flag =3D FilterBeforeIoRead (FilterWidth32, Port, &Data); if (Flag) { - __asm__ __volatile__ ("inl %w1,%0" : "=3Da" (Data) : "d" ((UINT16)Port= )); + if (IsTdxGuest ()) { + Data =3D TdIoRead32 (Port); + } else { + __asm__ __volatile__ ("inl %w1,%0" : "=3Da" (Data) : "d" ((UINT16)Po= rt)); + } } =20 FilterAfterIoRead (FilterWidth32, Port, &Data); @@ -203,6 +234,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(). =20 + 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. =20 @@ -222,7 +255,11 @@ IoWrite32 ( =20 Flag =3D 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)Po= rt)); + } } =20 FilterAfterIoWrite (FilterWidth32, Port, &Value); diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c b/MdePkg/Library/= BaseIoLibIntrinsic/IoLibMsc.c index 9f225a6b5d39..f1b7d51a7245 100644 --- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c @@ -14,6 +14,7 @@ **/ =20 #include "BaseIoLibIntrinsicInternal.h" +#include "IoLibTdx.h" =20 // // Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. @@ -82,6 +83,8 @@ _ReadWriteBarrier ( =20 If 8-bit I/O port operations are not supported, then ASSERT(). =20 + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. =20 @return The value read. @@ -98,9 +101,13 @@ IoRead8 ( =20 Flag =3D FilterBeforeIoRead (FilterWidth8, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - Value =3D (UINT8)_inp ((UINT16)Port); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + Value =3D TdIoRead8 (Port); + } else { + _ReadWriteBarrier (); + Value =3D (UINT8)_inp ((UINT16)Port); + _ReadWriteBarrier (); + } } =20 FilterAfterIoRead (FilterWidth8, Port, &Value); @@ -117,6 +124,8 @@ IoRead8 ( =20 If 8-bit I/O port operations are not supported, then ASSERT(). =20 + 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. =20 @@ -134,9 +143,13 @@ IoWrite8 ( =20 Flag =3D 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 (); + } } =20 FilterAfterIoWrite (FilterWidth8, Port, &Value); @@ -154,6 +167,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(). =20 + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. =20 @return The value read. @@ -172,9 +187,13 @@ IoRead16 ( =20 Flag =3D FilterBeforeIoRead (FilterWidth16, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - Value =3D _inpw ((UINT16)Port); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + Value =3D TdIoRead16 (Port); + } else { + _ReadWriteBarrier (); + Value =3D _inpw ((UINT16)Port); + _ReadWriteBarrier (); + } } =20 FilterBeforeIoRead (FilterWidth16, Port, &Value); @@ -192,6 +211,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(). =20 + 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. =20 @@ -211,9 +232,13 @@ IoWrite16 ( =20 Flag =3D FilterBeforeIoWrite (FilterWidth16, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - _outpw ((UINT16)Port, Value); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + TdIoWrite16 (Port, Value); + } else { + _ReadWriteBarrier (); + _outpw ((UINT16)Port, Value); + _ReadWriteBarrier (); + } } =20 FilterAfterIoWrite (FilterWidth16, Port, &Value); @@ -231,6 +256,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(). =20 + For Td guest TDVMCALL_IO is invoked to read I/O port. + @param Port The I/O port to read. =20 @return The value read. @@ -249,9 +276,13 @@ IoRead32 ( =20 Flag =3D FilterBeforeIoRead (FilterWidth32, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - Value =3D _inpd ((UINT16)Port); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + Value =3D TdIoRead32 (Port); + } else { + _ReadWriteBarrier (); + Value =3D _inpd ((UINT16)Port); + _ReadWriteBarrier (); + } } =20 FilterAfterIoRead (FilterWidth32, Port, &Value); @@ -269,6 +300,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(). =20 + 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. =20 @@ -288,9 +321,13 @@ IoWrite32 ( =20 Flag =3D FilterBeforeIoWrite (FilterWidth32, Port, &Value); if (Flag) { - _ReadWriteBarrier (); - _outpd ((UINT16)Port, Value); - _ReadWriteBarrier (); + if (IsTdxGuest ()) { + TdIoWrite32 (Port, Value); + } else { + _ReadWriteBarrier (); + _outpd ((UINT16)Port, Value); + _ReadWriteBarrier (); + } } =20 FilterAfterIoWrite (FilterWidth32, Port, &Value); --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84717): https://edk2.groups.io/g/devel/message/84717 Mute This Topic: https://groups.io/mt/87696567/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-