Add PlatformReservationConflictCB() callback function for use with
PlatformScanE820(). It checks whenever the 64bit PCI MMIO window
overlaps with a reservation from qemu. If so move down the MMIO window
to resolve the conflict.
Write any actions done (moving mmio window) to the firmware log with
INFO loglevel.
This happens on (virtual) AMD machines with 1TB address space,
because the AMD IOMMU uses an address window just below 1TB.
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4251
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
OvmfPkg/Library/PlatformInitLib/MemDetect.c | 45 +++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
index c626fc49cf6c..1ce692e77ecb 100644
--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c
+++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
@@ -213,6 +213,50 @@ PlatformAddHobCB (
}
}
+/**
+ Check whenever the 64bit PCI MMIO window overlaps with a reservation
+ from qemu. If so move down the MMIO window to resolve the conflict.
+
+ This happens on (virtual) AMD machines with 1TB address space,
+ because the AMD IOMMU uses an address window just below 1TB.
+**/
+STATIC VOID
+PlatformReservationConflictCB (
+ IN EFI_E820_ENTRY64 *E820Entry,
+ IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
+ )
+{
+ UINT64 IntersectionBase;
+ UINT64 IntersectionEnd;
+ UINT64 NewBase;
+
+ IntersectionBase = MAX (
+ E820Entry->BaseAddr,
+ PlatformInfoHob->PcdPciMmio64Base
+ );
+ IntersectionEnd = MIN (
+ E820Entry->BaseAddr + E820Entry->Length,
+ PlatformInfoHob->PcdPciMmio64Base +
+ PlatformInfoHob->PcdPciMmio64Size
+ );
+
+ if (IntersectionBase >= IntersectionEnd) {
+ return; // no overlap
+ }
+
+ NewBase = E820Entry->BaseAddr - PlatformInfoHob->PcdPciMmio64Size;
+ NewBase = NewBase & ~(PlatformInfoHob->PcdPciMmio64Size - 1);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: move mmio: 0x%Lx => %Lx\n",
+ __FUNCTION__,
+ PlatformInfoHob->PcdPciMmio64Base,
+ NewBase
+ ));
+ PlatformInfoHob->PcdPciMmio64Base = NewBase;
+}
+
/**
Iterate over the entries in QEMU's fw_cfg E820 RAM map, call the
passed callback for each entry.
@@ -650,6 +694,7 @@ PlatformDynamicMmioWindow (
DEBUG ((DEBUG_INFO, "%a: MMIO Space 0x%Lx (%Ld GB)\n", __func__, MmioSpace, RShiftU64 (MmioSpace, 30)));
PlatformInfoHob->PcdPciMmio64Size = MmioSpace;
PlatformInfoHob->PcdPciMmio64Base = AddrSpace - MmioSpace;
+ PlatformScanE820 (PlatformReservationConflictCB, PlatformInfoHob);
} else {
DEBUG ((DEBUG_INFO, "%a: using classic mmio window\n", __func__));
}
--
2.39.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#98678): https://edk2.groups.io/g/devel/message/98678
Mute This Topic: https://groups.io/mt/96328407/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On 1/17/23 13:16, Gerd Hoffmann wrote:
> Add PlatformReservationConflictCB() callback function for use with
> PlatformScanE820(). It checks whenever the 64bit PCI MMIO window
> overlaps with a reservation from qemu. If so move down the MMIO window
> to resolve the conflict.
>
> Write any actions done (moving mmio window) to the firmware log with
> INFO loglevel.
>
> This happens on (virtual) AMD machines with 1TB address space,
> because the AMD IOMMU uses an address window just below 1TB.
>
> Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4251
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> OvmfPkg/Library/PlatformInitLib/MemDetect.c | 45 +++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
> index c626fc49cf6c..1ce692e77ecb 100644
> --- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c
> +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
> @@ -213,6 +213,50 @@ PlatformAddHobCB (
> }
> }
>
> +/**
> + Check whenever the 64bit PCI MMIO window overlaps with a reservation
> + from qemu. If so move down the MMIO window to resolve the conflict.
> +
> + This happens on (virtual) AMD machines with 1TB address space,
> + because the AMD IOMMU uses an address window just below 1TB.
> +**/
> +STATIC VOID
> +PlatformReservationConflictCB (
> + IN EFI_E820_ENTRY64 *E820Entry,
> + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + UINT64 IntersectionBase;
> + UINT64 IntersectionEnd;
> + UINT64 NewBase;
> +
> + IntersectionBase = MAX (
> + E820Entry->BaseAddr,
> + PlatformInfoHob->PcdPciMmio64Base
> + );
> + IntersectionEnd = MIN (
> + E820Entry->BaseAddr + E820Entry->Length,
> + PlatformInfoHob->PcdPciMmio64Base +
> + PlatformInfoHob->PcdPciMmio64Size
> + );
> +
> + if (IntersectionBase >= IntersectionEnd) {
> + return; // no overlap
> + }
> +
> + NewBase = E820Entry->BaseAddr - PlatformInfoHob->PcdPciMmio64Size;
> + NewBase = NewBase & ~(PlatformInfoHob->PcdPciMmio64Size - 1);
> +
> + DEBUG ((
> + DEBUG_INFO,
> + "%a: move mmio: 0x%Lx => %Lx\n",
> + __FUNCTION__,
> + PlatformInfoHob->PcdPciMmio64Base,
> + NewBase
> + ));
> + PlatformInfoHob->PcdPciMmio64Base = NewBase;
> +}
> +
> /**
> Iterate over the entries in QEMU's fw_cfg E820 RAM map, call the
> passed callback for each entry.
> @@ -650,6 +694,7 @@ PlatformDynamicMmioWindow (
> DEBUG ((DEBUG_INFO, "%a: MMIO Space 0x%Lx (%Ld GB)\n", __func__, MmioSpace, RShiftU64 (MmioSpace, 30)));
> PlatformInfoHob->PcdPciMmio64Size = MmioSpace;
> PlatformInfoHob->PcdPciMmio64Base = AddrSpace - MmioSpace;
> + PlatformScanE820 (PlatformReservationConflictCB, PlatformInfoHob);
> } else {
> DEBUG ((DEBUG_INFO, "%a: using classic mmio window\n", __func__));
> }
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#98708): https://edk2.groups.io/g/devel/message/98708
Mute This Topic: https://groups.io/mt/96328407/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.