From 64d555122ee65151008255a30173a3608006ae25 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 2 Dec 2022 14:10:08 +0100 Subject: [PATCH 30/32] OvmfPkg/QemuFwCfgLib: rewrite fw_cfg probe Move the code to a new QemuFwCfgProbe() function. Use direct Io*() calls instead of indirect QemuFwCfg*() calls to make sure we don't get recursive calls. Also simplify CC guest detection. Signed-off-by: Gerd Hoffmann Tested-by: Tom Lendacky Acked-by: Ard Biesheuvel (cherry picked from commit 81bbc1452c972218f071cd4a8f5899df974b1dae) --- .../Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf | 1 - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c | 101 +++++++----------- 2 files changed, 41 insertions(+), 61 deletions(-) diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf index 3910511880c9..1d7543a7d40f 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf @@ -41,7 +41,6 @@ [LibraryClasses] DebugLib IoLib MemoryAllocationLib - MemEncryptSevLib [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c index 7ab7027af168..a936fd103955 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "QemuFwCfgLibInternal.h" @@ -27,15 +26,16 @@ STATIC BOOLEAN mQemuFwCfgDmaSupported; @retval TRUE It is Tdx guest @retval FALSE It is not Tdx guest **/ +STATIC BOOLEAN -QemuFwCfgIsTdxGuest ( +QemuFwCfgIsCcGuest ( VOID ) { CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *CcWorkAreaHeader; CcWorkAreaHeader = (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *)FixedPcdGet32 (PcdOvmfWorkAreaBase); - return (CcWorkAreaHeader != NULL && CcWorkAreaHeader->GuestType == CcGuestTypeIntelTdx); + return (CcWorkAreaHeader != NULL && CcWorkAreaHeader->GuestType != CcGuestTypeNonEncrypted); } /** @@ -57,62 +57,49 @@ QemuFwCfgIsAvailable ( return InternalQemuFwCfgIsAvailable (); } +STATIC +VOID +QemuFwCfgProbe ( + BOOLEAN *Supported, + BOOLEAN *DmaSupported + ) +{ + UINT32 Signature; + UINT32 Revision; + BOOLEAN CcGuest; + + // Use direct Io* calls for probing to avoid recursion. + IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)QemuFwCfgItemSignature); + IoReadFifo8 (FW_CFG_IO_DATA, sizeof Signature, &Signature); + IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)QemuFwCfgItemInterfaceVersion); + IoReadFifo8 (FW_CFG_IO_DATA, sizeof Revision, &Revision); + CcGuest = QemuFwCfgIsCcGuest (); + + *Supported = FALSE; + *DmaSupported = FALSE; + if ((Signature == SIGNATURE_32 ('Q', 'E', 'M', 'U')) && (Revision >= 1)) { + *Supported = TRUE; + if ((Revision & FW_CFG_F_DMA) && !CcGuest) { + *DmaSupported = TRUE; + } + } + + DEBUG (( + DEBUG_INFO, + "%a: Supported %d, DMA %d\n", + __func__, + *Supported, + *DmaSupported + )); +} + RETURN_STATUS EFIAPI QemuFwCfgInitialize ( VOID ) { - UINT32 Signature; - UINT32 Revision; - - // - // Enable the access routines while probing to see if it is supported. - // For probing we always use the IO Port (IoReadFifo8()) access method. - // - mQemuFwCfgSupported = TRUE; - mQemuFwCfgDmaSupported = FALSE; - - QemuFwCfgSelectItem (QemuFwCfgItemSignature); - Signature = QemuFwCfgRead32 (); - DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature)); - QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); - Revision = QemuFwCfgRead32 (); - DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision)); - if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) || - (Revision < 1) - ) - { - DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n")); - mQemuFwCfgSupported = FALSE; - return RETURN_SUCCESS; - } - - if ((Revision & FW_CFG_F_DMA) == 0) { - DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n")); - } else { - // - // If SEV is enabled then we do not support DMA operations in PEI phase. - // This is mainly because DMA in SEV guest requires using bounce buffer - // (which need to allocate dynamic memory and allocating a PAGE size'd - // buffer can be challenge in PEI phase) - // - if (MemEncryptSevIsEnabled ()) { - DEBUG ((DEBUG_INFO, "SEV: QemuFwCfg fallback to IO Port interface.\n")); - } else if (QemuFwCfgIsTdxGuest ()) { - // - // If TDX is enabled then we do not support DMA operations in PEI phase. - // This is mainly because DMA in TDX guest requires using bounce buffer - // (which need to allocate dynamic memory and allocating a PAGE size'd - // buffer can be challenge in PEI phase) - // - DEBUG ((DEBUG_INFO, "TDX: QemuFwCfg fallback to IO Port interface.\n")); - } else { - mQemuFwCfgDmaSupported = TRUE; - DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n")); - } - } - + QemuFwCfgProbe (&mQemuFwCfgSupported, &mQemuFwCfgDmaSupported); return RETURN_SUCCESS; } @@ -183,17 +170,11 @@ InternalQemuFwCfgDmaBytes ( return; } - // - // SEV does not support DMA operations in PEI stage, we should - // not have reached here. - // - ASSERT (!MemEncryptSevIsEnabled ()); - // // TDX does not support DMA operations in PEI stage, we should // not have reached here. // - ASSERT (!QemuFwCfgIsTdxGuest ()); + ASSERT (!QemuFwCfgIsCcGuest ()); Access.Control = SwapBytes32 (Control); Access.Length = SwapBytes32 (Size); -- 2.38.1