OvmfPkg/igvm: add igvm memory map support.

In case a IGVM memory map is present in the parameter area use that
when detecting guest memory.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2025-08-08 14:23:34 +02:00 committed by mergify[bot]
parent 313004a57f
commit 5e8db785e4
5 changed files with 137 additions and 5 deletions

View file

@ -10,6 +10,7 @@
#define PLATFORM_INIT_LIB_H_
#include <PiPei.h>
#include <IndustryStandard/E820.h>
#pragma pack(1)
@ -290,4 +291,22 @@ PlatformInitEmuVariableNvStore (
IN VOID *EmuVariableNvStore
);
typedef VOID (*E820_SCAN_CALLBACK) (
EFI_E820_ENTRY64 *E820Entry,
EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
BOOLEAN
EFIAPI
PlatformIgvmMemoryMapCheck (
VOID
);
EFI_STATUS
EFIAPI
PlatformIgvmScanE820 (
IN E820_SCAN_CALLBACK Callback,
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
#endif // PLATFORM_INIT_LIB_H_

View file

@ -0,0 +1,110 @@
/** @file
IGVM Parameter parsing
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/PlatformInitLib.h>
#include <Library/DebugLib.h>
/* keep in sync with OvmfPkg/ResetVector/X64/IgvmMetadata.asm */
#define MEMORY_MAP_OFFSET 0
#define MEMORY_MAP_ENTRIES 8
#define MEMORY_MAP_SIZE (MEMORY_MAP_ENTRIES * sizeof(IGVM_MEMORY_MAP_ENTRY))
#define IGVM_MM_ENTRY_TYPE_MEMORY 0x00
#define IGVM_MM_ENTRY_TYPE_RESERVED 0x01
#define IGVM_MM_ENTRY_TYPE_PERSISTENT 0x02
typedef struct IGVM_MEMORY_MAP_ENTRY {
UINT64 PageStart;
UINT64 PageCount;
UINT16 EntryType;
UINT16 EntryFlags;
UINT32 Reserved;
} IGVM_MEMORY_MAP_ENTRY;
STATIC
IGVM_MEMORY_MAP_ENTRY *
EFIAPI
PlatformIgvmMemoryMapFind (
VOID
)
{
UINT64 Address;
IGVM_MEMORY_MAP_ENTRY *Map;
Address = FixedPcdGet64 (PcdOvmfIgvmParamBase);
if (Address == 0) {
// no parameter area
return NULL;
}
Map = (VOID *)(UINTN)(Address + MEMORY_MAP_OFFSET);
if (Map[0].PageCount == 0) {
// no memory map entries
return NULL;
}
return Map;
}
BOOLEAN
EFIAPI
PlatformIgvmMemoryMapCheck (
VOID
)
{
return PlatformIgvmMemoryMapFind () != NULL;
}
EFI_STATUS
EFIAPI
PlatformIgvmScanE820 (
IN E820_SCAN_CALLBACK Callback,
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
STATIC BOOLEAN First = TRUE;
IGVM_MEMORY_MAP_ENTRY *Map;
EFI_E820_ENTRY64 Entry;
UINT32 Index;
Map = PlatformIgvmMemoryMapFind ();
if (Map == NULL) {
return EFI_NOT_FOUND;
}
for (Index = 0; Map[Index].PageCount > 0; Index++) {
if (First) {
DEBUG ((
DEBUG_INFO,
"%a: IgvmMemoryMap[%d]: PageStart %lx, PageCount %lx, EntryType %d\n",
__func__,
Index,
Map[Index].PageStart,
Map[Index].PageCount,
Map[Index].EntryType
));
}
Entry.BaseAddr = LShiftU64 (Map[Index].PageStart, EFI_PAGE_SHIFT);
Entry.Length = LShiftU64 (Map[Index].PageCount, EFI_PAGE_SHIFT);
switch (Map[Index].EntryType) {
case IGVM_MM_ENTRY_TYPE_MEMORY:
Entry.Type = EfiAcpiAddressRangeMemory;
Callback (&Entry, PlatformInfoHob);
break;
case IGVM_MM_ENTRY_TYPE_RESERVED:
Entry.Type = EfiAcpiAddressRangeReserved;
Callback (&Entry, PlatformInfoHob);
break;
}
}
First = FALSE;
return EFI_SUCCESS;
}

View file

@ -102,11 +102,6 @@ PlatformQemuUc32BaseInitialization (
}
}
typedef VOID (*E820_SCAN_CALLBACK) (
EFI_E820_ENTRY64 *E820Entry,
EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
STATIC
EFI_STATUS
PlatformScanE820Tdx (
@ -373,6 +368,10 @@ PlatformScanE820 (
EFI_E820_ENTRY64 E820Entry;
UINTN Processed;
if (PlatformIgvmMemoryMapCheck ()) {
return PlatformIgvmScanE820 (Callback, PlatformInfoHob);
}
if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
return PlatformScanE820Pvh (Callback, PlatformInfoHob);
}

View file

@ -24,6 +24,7 @@
[Sources]
Cmos.c
Igvm.c
MemDetect.c
Platform.c
@ -110,5 +111,7 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfEarlyMemDebugLogSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfIgvmParamBase
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode

View file

@ -15,6 +15,7 @@ ALIGN 16
%define IGVM_ID_HOB_AREA 0x200
; keep in sync with OvmfPkg/Library/PlatformInitLib/Igvm.c
%define MEMORY_MAP_OFFSET 0
%define MEMORY_MAP_ENTRIES 8
%define MEMORY_MAP_SIZE (MEMORY_MAP_ENTRIES * 24)