OvmfPkg/IntelTdx: Add memory debug logging support for TDX guests

OVMF already supports MemDebugLogLib for capturing firmware debug
output in a runtime memory buffer. Align the TDX peiless boot path
with OVMF by integrating the same library, so that TDX guests can
use memory-based debug logging.

In PeilessStartupLib, allocate a runtime buffer for the debug log
during PeilessStartup() and copy any early SEC-phase logs from
the pre-allocated FDF region into it.

Register the early debug log memory region in the TDX metadata as
TEMP_MEM so the TDX module accepts it during guest initialization.

Move PlatformDxe/Platform.inf from NCCFV to DXEFV because it
exposes the memory debug log HOB to the guest.

Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
This commit is contained in:
Luigi Leonardi 2026-06-22 10:04:34 +02:00 committed by mergify[bot]
parent e59458b658
commit 35345c76a9
7 changed files with 124 additions and 1 deletions

View file

@ -30,6 +30,7 @@
# -D FLAG=VALUE
#
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE DEBUG_TO_MEM = FALSE
#
# Shell can be useful for debugging but should not be enabled for production
@ -218,11 +219,18 @@
TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf
PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
!if $(DEBUG_TO_MEM)
MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogDxeLib.inf
!else
MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
!endif
[LibraryClasses.common.SEC]
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
!if $(DEBUG_TO_MEM)
MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogSecLib.inf
!endif
!ifdef $(DEBUG_ON_SERIAL_PORT)
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
!else
@ -271,6 +279,9 @@
DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
!endif
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
!if $(DEBUG_TO_MEM)
MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogRtLib.inf
!endif
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
@ -565,6 +576,7 @@
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
<LibraryClasses>
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
}
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
@ -654,6 +666,9 @@
<LibraryClasses>
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
!if $(DEBUG_TO_MEM)
MemDebugLogLib|OvmfPkg/Library/MemDebugLogLib/MemDebugLogLibNull.inf
!endif
}
MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf

View file

@ -94,6 +94,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase|gUefiOvmfPkgTokenSpaceGuid.PcdO
0x00E000|0x001000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
!if $(DEBUG_TO_MEM)
0x00F000|0x001000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogSize
!endif
0x010000|0x010000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
@ -263,6 +268,8 @@ INF MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf
INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
INF OvmfPkg/PlatformDxe/Platform.inf
################################################################################
[FV.NCCFV]
@ -321,7 +328,6 @@ INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
INF OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
INF OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
INF OvmfPkg/PlatformDxe/Platform.inf
!include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc
!include OvmfPkg/Include/Fdf/OvmfRngDxe.fdf.inc

View file

@ -21,8 +21,10 @@
#include <Library/PeilessStartupLib.h>
#include <Library/PlatformInitLib.h>
#include <Library/TdxHelperLib.h>
#include <Library/QemuFwCfgSimpleParserLib.h>
#include <ConfidentialComputingGuestAttr.h>
#include <Guid/MemoryTypeInformation.h>
#include <Library/MemDebugLogLib.h>
#include <OvmfPlatforms.h>
#include "PeilessStartupInternal.h"
@ -123,6 +125,79 @@ InitializePlatform (
return EFI_SUCCESS;
}
STATIC
VOID
MemDebugLogSetup (
VOID
)
{
UINT32 MemDebugLogBufPages;
VOID *Buffer;
MEM_DEBUG_LOG_HOB_DATA HobData;
EFI_STATUS Status;
Status = QemuFwCfgParseUint32 ("opt/ovmf/MemDebugLogPages", TRUE, &MemDebugLogBufPages);
if (EFI_ERROR (Status)) {
MemDebugLogBufPages = FixedPcdGet32 (PcdMemDebugLogPages);
}
if (MemDebugLogBufPages == 0) {
HobData.MemDebugLogBufAddr = 0;
BuildGuidDataHob (&gMemDebugLogHobGuid, &HobData, sizeof (HobData));
return;
}
if (MemDebugLogBufPages > MAX_MEM_DEBUG_LOG_PAGES) {
MemDebugLogBufPages = MAX_MEM_DEBUG_LOG_PAGES;
}
Buffer = AllocateRuntimePages (MemDebugLogBufPages);
if (Buffer == NULL) {
DEBUG ((DEBUG_ERROR, "%a: Failed to allocate Memory Debug Log buffer. Logging disabled\n", __func__));
HobData.MemDebugLogBufAddr = 0;
BuildGuidDataHob (&gMemDebugLogHobGuid, &HobData, sizeof (HobData));
return;
}
Status = MemDebugLogInit (
(EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
(UINT32)EFI_PAGES_TO_SIZE (MemDebugLogBufPages)
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: MemDebugLogInit failed: %r\n", __func__, Status));
FreePages (Buffer, MemDebugLogBufPages);
HobData.MemDebugLogBufAddr = 0;
BuildGuidDataHob (&gMemDebugLogHobGuid, &HobData, sizeof (HobData));
return;
}
if (FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase) != 0) {
Status = MemDebugLogCopy (
(EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
(EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase)
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "%a: MemDebugLogCopy failed: %r\n", __func__, Status));
}
ZeroMem (
(VOID *)(UINTN)FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase),
FixedPcdGet32 (PcdOvmfEarlyMemDebugLogSize)
);
}
HobData.MemDebugLogBufAddr = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
BuildGuidDataHob (&gMemDebugLogHobGuid, &HobData, sizeof (HobData));
DEBUG ((
DEBUG_INFO,
"%a: MemDebugLog buffer at 0x%lx, %d pages\n",
__func__,
(UINT64)(UINTN)Buffer,
MemDebugLogBufPages
));
}
STATIC
EFI_HOB_PLATFORM_INFO *
BuildPlatformInfoHob (
@ -215,6 +290,10 @@ PeilessStartup (
CpuDeadLoop ();
}
if (MemDebugLogEnabled ()) {
MemDebugLogSetup ();
}
//
// SecFV
//

View file

@ -55,7 +55,9 @@
MemoryAllocationLib
PrePiLib
QemuFwCfgLib
QemuFwCfgSimpleParserLib
PlatformInitLib
MemDebugLogLib
[Guids]
gEfiHobMemoryAllocModuleGuid
@ -65,6 +67,7 @@
gPcdDataBaseHobGuid
gCcEventEntryHobGuid
gEfiNonCcFvGuid
gMemDebugLogHobGuid
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase
@ -84,3 +87,8 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootSupported
[FixedPcd]
gUefiOvmfPkgTokenSpaceGuid.PcdMemDebugLogPages
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogSize

View file

@ -70,4 +70,6 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfIgvmParamSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfIgvmHobBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfIgvmHobSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogSize
gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable

View file

@ -138,6 +138,9 @@
%define OVMF_PAGE_TABLE_BASE FixedPcdGet32 (PcdOvmfSecPageTablesBase)
%define OVMF_PAGE_TABLE_SIZE FixedPcdGet32 (PcdOvmfSecPageTablesSize)
%define TDX_EARLY_DEBUG_LOG_BASE FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase)
%define TDX_EARLY_DEBUG_LOG_SIZE FixedPcdGet32 (PcdOvmfEarlyMemDebugLogSize)
%define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4)
%define TDX_WORK_AREA_GPAW (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 8)

View file

@ -111,5 +111,15 @@ _OvmfPageTable:
DD TDX_METADATA_SECTION_TYPE_TEMP_MEM
DD 0
%if TDX_EARLY_DEBUG_LOG_SIZE != 0
_EarlyDebugLog:
DD 0
DD 0
DQ TDX_EARLY_DEBUG_LOG_BASE
DQ TDX_EARLY_DEBUG_LOG_SIZE
DD TDX_METADATA_SECTION_TYPE_TEMP_MEM
DD 0
%endif
TdxGuidedStructureEnd:
ALIGN 16