mirror of https://github.com/acidanthera/audk.git
OvmfPkg/PlatformInitLib: add 5-level paging support
Adjust physical address space logic for la57 mode (5-level paging). With a larger logical address space we can identity-map a larger physical address space. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Acked-by: Ard Biesheuvel <ardb@kernel.org> Message-Id: <20240222105407.75735-4-kraxel@redhat.com> Cc: Michael Roth <michael.roth@amd.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Oliver Steffen <osteffen@redhat.com> Cc: Ard Biesheuvel <ardb@kernel.org> [lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list posting into "Cc:" tags in the commit message, in order to pacify "PatchCheck.py"]
This commit is contained in:
parent
13fbc16556
commit
adebfe121c
|
@ -628,11 +628,12 @@ PlatformAddressWidthFromCpuid (
|
|||
IN BOOLEAN QemuQuirk
|
||||
)
|
||||
{
|
||||
UINT32 RegEax, RegEbx, RegEcx, RegEdx, Max;
|
||||
UINT8 PhysBits;
|
||||
CHAR8 Signature[13];
|
||||
BOOLEAN Valid = FALSE;
|
||||
BOOLEAN Page1GSupport = FALSE;
|
||||
UINT32 RegEax, RegEbx, RegEcx, RegEdx, Max;
|
||||
UINT8 PhysBits;
|
||||
CHAR8 Signature[13];
|
||||
IA32_CR4 Cr4;
|
||||
BOOLEAN Valid = FALSE;
|
||||
BOOLEAN Page1GSupport = FALSE;
|
||||
|
||||
ZeroMem (Signature, sizeof (Signature));
|
||||
|
||||
|
@ -670,30 +671,54 @@ PlatformAddressWidthFromCpuid (
|
|||
}
|
||||
}
|
||||
|
||||
Cr4.UintN = AsmReadCr4 ();
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: Signature: '%a', PhysBits: %d, QemuQuirk: %a, Valid: %a\n",
|
||||
"%a: Signature: '%a', PhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n",
|
||||
__func__,
|
||||
Signature,
|
||||
PhysBits,
|
||||
QemuQuirk ? "On" : "Off",
|
||||
Cr4.Bits.LA57 ? "On" : "Off",
|
||||
Valid ? "Yes" : "No"
|
||||
));
|
||||
|
||||
if (Valid) {
|
||||
if (PhysBits > 46) {
|
||||
/*
|
||||
* Avoid 5-level paging altogether for now, which limits
|
||||
* PhysBits to 48. Also avoid using address bit 48, due to sign
|
||||
* extension we can't identity-map these addresses (and lots of
|
||||
* places in edk2 assume we have everything identity-mapped).
|
||||
* So the actual limit is 47.
|
||||
*
|
||||
* Also some older linux kernels apparently have problems handling
|
||||
* phys-bits > 46 correctly, so use that as limit.
|
||||
*/
|
||||
DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 46 (avoid 5-level paging)\n", __func__));
|
||||
PhysBits = 46;
|
||||
/*
|
||||
* Due to the sign extension we can use only the lower half of the
|
||||
* virtual address space to identity-map physical address space,
|
||||
* which gives us a 47 bit wide address space with 4 paging levels
|
||||
* and a 56 bit wide address space with 5 paging levels.
|
||||
*/
|
||||
if (Cr4.Bits.LA57) {
|
||||
if (PhysBits > 48) {
|
||||
/*
|
||||
* Some Intel CPUs support 5-level paging, have more than 48
|
||||
* phys-bits but support only 4-level EPT, which effectively
|
||||
* limits guest phys-bits to 48.
|
||||
*
|
||||
* AMD Processors have a different but somewhat related
|
||||
* problem: They can handle guest phys-bits larger than 48
|
||||
* only in case the host runs in 5-level paging mode.
|
||||
*
|
||||
* Until we have some way to communicate that kind of
|
||||
* limitations from hypervisor to guest, limit phys-bits
|
||||
* to 48 unconditionally.
|
||||
*/
|
||||
DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 48 (5-level paging)\n", __func__));
|
||||
PhysBits = 48;
|
||||
}
|
||||
} else {
|
||||
if (PhysBits > 46) {
|
||||
/*
|
||||
* Some older linux kernels apparently have problems handling
|
||||
* phys-bits > 46 correctly, so use that instead of 47 as
|
||||
* limit.
|
||||
*/
|
||||
DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 46 (4-level paging)\n", __func__));
|
||||
PhysBits = 46;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Page1GSupport && (PhysBits > 40)) {
|
||||
|
|
Loading…
Reference in New Issue