mirror of https://github.com/acidanthera/audk.git
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 <kraxel@redhat.com> Tested-by: Tom Lendacky <thomas.lendacky@amd.com> Acked-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
e59747bd82
commit
81bbc1452c
|
@ -13,7 +13,6 @@
|
||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/QemuFwCfgLib.h>
|
#include <Library/QemuFwCfgLib.h>
|
||||||
#include <Library/MemEncryptSevLib.h>
|
|
||||||
#include <WorkArea.h>
|
#include <WorkArea.h>
|
||||||
|
|
||||||
#include "QemuFwCfgLibInternal.h"
|
#include "QemuFwCfgLibInternal.h"
|
||||||
|
@ -27,15 +26,16 @@ STATIC BOOLEAN mQemuFwCfgDmaSupported;
|
||||||
@retval TRUE It is Tdx guest
|
@retval TRUE It is Tdx guest
|
||||||
@retval FALSE It is not Tdx guest
|
@retval FALSE It is not Tdx guest
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
QemuFwCfgIsTdxGuest (
|
QemuFwCfgIsCcGuest (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *CcWorkAreaHeader;
|
CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *CcWorkAreaHeader;
|
||||||
|
|
||||||
CcWorkAreaHeader = (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
|
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 ();
|
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
|
RETURN_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
QemuFwCfgInitialize (
|
QemuFwCfgInitialize (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 Signature;
|
QemuFwCfgProbe (&mQemuFwCfgSupported, &mQemuFwCfgDmaSupported);
|
||||||
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"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,17 +170,11 @@ InternalQemuFwCfgDmaBytes (
|
||||||
return;
|
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
|
// TDX does not support DMA operations in PEI stage, we should
|
||||||
// not have reached here.
|
// not have reached here.
|
||||||
//
|
//
|
||||||
ASSERT (!QemuFwCfgIsTdxGuest ());
|
ASSERT (!QemuFwCfgIsCcGuest ());
|
||||||
|
|
||||||
Access.Control = SwapBytes32 (Control);
|
Access.Control = SwapBytes32 (Control);
|
||||||
Access.Length = SwapBytes32 (Size);
|
Access.Length = SwapBytes32 (Size);
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
DebugLib
|
DebugLib
|
||||||
IoLib
|
IoLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
MemEncryptSevLib
|
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
|
||||||
|
|
Loading…
Reference in New Issue