From 603ad2d6ae7c0b46815123a59a2b8c8169711c0e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 1 Mar 2024 11:23:58 +0100 Subject: OvmfPkg/PlatformInitLib: add support for GuestPhysBits Add support for GuestPhysBits (cpuid 0x80000008, eax, bits 23:16). GuestPhysBits is a field which can be set by the hypervisor to inform the guest about the /usable/ physical address space bits. This can be smaller than the PhysBits of the CPU, for example because of nested paging limitations. OVMF will read GuestPhysBits, log the value, in case it is set use it as upper limit. Signed-off-by: Gerd Hoffmann --- OvmfPkg/Library/PlatformInitLib/MemDetect.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'OvmfPkg') diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c index e64c0ee..f531b98 100644 --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c @@ -633,6 +633,7 @@ PlatformAddressWidthFromCpuid ( { UINT32 RegEax, RegEbx, RegEcx, RegEdx, Max; UINT8 PhysBits; + UINT8 GuestPhysBits; CHAR8 Signature[13]; IA32_CR4 Cr4; BOOLEAN Valid = FALSE; @@ -655,13 +656,17 @@ PlatformAddressWidthFromCpuid ( if (Max >= 0x80000008) { AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); - PhysBits = (UINT8)RegEax; + PhysBits = (UINT8)RegEax; + GuestPhysBits = (UINT8)(RegEax >> 16); } else { - PhysBits = 36; + PhysBits = 36; + GuestPhysBits = 0; } if (!QemuQuirk) { Valid = TRUE; + } else if (GuestPhysBits) { + Valid = TRUE; } else if (PhysBits >= 41) { Valid = TRUE; } else if (AsciiStrCmp (Signature, "GenuineIntel") == 0) { @@ -678,15 +683,21 @@ PlatformAddressWidthFromCpuid ( DEBUG (( DEBUG_INFO, - "%a: Signature: '%a', PhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n", + "%a: Signature: '%a', PhysBits: %d, GuestPhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n", __func__, Signature, PhysBits, + GuestPhysBits, QemuQuirk ? "On" : "Off", Cr4.Bits.LA57 ? "On" : "Off", Valid ? "Yes" : "No" )); + if (GuestPhysBits && (PhysBits > GuestPhysBits)) { + DEBUG ((DEBUG_INFO, "%a: limit PhysBits to %d (GuestPhysBits)\n", __func__, GuestPhysBits)); + PhysBits = GuestPhysBits; + } + if (Valid) { /* * Due to the sign extension we can use only the lower half of the -- cgit v1.1