Red Hat Bugzilla – Bug 1514105
backport edk2 commit 6e3287442774 so that PciBusDxe not over-claim resources
Last modified: 2018-04-10 12:31:21 EDT
*** Description of problem: (This issue was found as part of <https://bugzilla.redhat.com/show_bug.cgi?id=1437113#c13>.) The PciBusDxe driver in OVMF currently aligns the length of the total resource demand a given resource type) of a bridge to the max BAR alignment required by any device behind the bridge. This is incorrect -- while BARs behind the bridge are sorted in decreasing size & alignment order, so that all their base addresses are correctly aligned, their accumulated size need not and should not be aligned (rounded up) at all. Consider an example where device #1 needs an MMIO BAR of 16MB size, and device #2 needs an MMIO BAR of 8MB size. This means device #1's BAR will come first (at an address aligned at 16MB, and ending at a similarly aligned address), and device #2's BAR will come second (at the previous end-address, aligned at 16MB, which satisfies the 8MB alignment requirement; and ending at an address aligned at 8MB). From the base of device #1's BAR, the bridge's own base alignment will be 16MB. However, the size of the bridge's resource demand should be 16MB + 8MB = 24MB, not 32MB (i.e., 24MB rounded up to a multiple of 16MB). *** Version-Release number of selected component (if applicable): OVMF-20171011-1.git92d07e48907f.el7.noarch (For the reproducer below, you also need a qemu-kvm-rhev package that fixes bug 1437113.) *** How reproducible: 100% *** Steps to Reproduce: (Instead of multiple devices behind a bridge, this reproducer uses multiple paddings (resource reservations) for a single PCI Express root port. The symptoms are exhibited the same way.) CODE=/usr/share/OVMF/OVMF_CODE.secboot.verbose.fd TMPL=/usr/share/OVMF/OVMF_VARS.fd UEFI_SHELL=/usr/share/OVMF/UefiShell.verbose.iso QEMU=/usr/libexec/qemu-kvm cp $TMPL vars.overclaim.fd $QEMU \ -nodefconfig \ -nodefaults \ \ -m 1024 \ \ -machine q35,smm=on,accel=kvm \ -global driver=cfi.pflash01,property=secure,value=on \ \ -drive if=pflash,readonly,format=raw,file=$CODE \ -drive if=pflash,format=raw,file=vars.overclaim.fd \ \ -chardev file,id=debugfile,path=debug.overclaim.log \ -device isa-debugcon,iobase=0x402,chardev=debugfile \ \ -chardev stdio,signal=off,mux=on,id=char0 \ -mon chardev=char0,mode=readline \ -serial chardev:char0 \ \ -device pcie-root-port,id=rp1,bus=pcie.0,multifunction=on,addr=1.0,chassis=1 \ -device pcie-root-port,id=rp2,bus=pcie.0,multifunction=on,addr=1.1,chassis=2 \ -device pcie-root-port,id=rp3,bus=pcie.0,multifunction=on,addr=1.2,chassis=3,io-reserve=4K,mem-reserve=8M,pref32-reserve=16M \ \ -device virtio-gpu-pci,bus=rp1 \ \ -device qemu-xhci,id=xhci,bus=rp2 \ -device usb-tablet,bus=xhci.0 \ \ -device virtio-rng-pci,bus=rp3,disable-legacy=on,disable-modern=off \ \ -device virtio-scsi-pci,id=scsi0,bus=pcie.0,addr=2.0 \ -device scsi-cd,bus=scsi0.0,drive=uefi-shell,bootindex=0 \ -drive if=none,format=raw,file=$UEFI_SHELL,id=uefi-shell,readonly *** Actual results: The "debug.overclaim.log" file will contain: > PciBus: Resource Map for Bridge [00|01|02] > Type = Io16; Base = 0x6000; Length = 0x1000; Alignment = 0xFFF > Base = Padding; Length = 0x1000; Alignment = 0xFFF > Type = Mem32; Base = 0x90000000; Length = 0x2000000; Alignment = 0xFFFFFF ^^^^^^^^^^^^^^^^^^ > Base = Padding; Length = 0x1000000; Alignment = 0xFFFFFF > Base = Padding; Length = 0x800000; Alignment = 0x7FFFFF > Type = Mem32; Base = 0x92402000; Length = 0x1000; Alignment = 0xFFF > Type = PMem64; Base = 0x800100000; Length = 0x100000; Alignment = 0xFFFFF > Base = 0x800100000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [03|00|00:20] *** Expected results: The "debug.overclaim.log" file should contain: > PciBus: Resource Map for Bridge [00|01|02] > Type = Io16; Base = 0x6000; Length = 0x1000; Alignment = 0xFFF > Base = Padding; Length = 0x1000; Alignment = 0xFFF > Type = Mem32; Base = 0x90000000; Length = 0x1800000; Alignment = 0xFFFFFF ^^^^^^^^^^^^^^^^^^ > Base = Padding; Length = 0x1000000; Alignment = 0xFFFFFF > Base = Padding; Length = 0x800000; Alignment = 0x7FFFFF > Type = Mem32; Base = 0x91C02000; Length = 0x1000; Alignment = 0xFFF > Type = PMem64; Base = 0x800100000; Length = 0x100000; Alignment = 0xFFFFF > Base = 0x800100000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [03|00|00:20] *** Additional information: This was fixed in upstream commit 6e3287442774 ("MdeModulePkg/PciBus: Fix bug that PCI BUS claims too much resource", 2017-10-20).
Fix included in ovmf-20171011-2.git92d07e48907f.el7
Verified the bug with OVMF-20171011-4.git92d07e48907f.el7.noarch & qemu-kvm-rhev-2.10.0-11.el7.x86_64. Base on qemu command in comment0. QE got this result as below. As it is the same with expected results. So, set this bug as verified. .......... PciBus: Resource Map for Bridge [00|01|02] Type = Io16; Base = 0x6000; Length = 0x1000; Alignment = 0xFFF Base = Padding; Length = 0x1000; Alignment = 0xFFF Type = Mem32; Base = 0x90000000; Length = 0x1800000; Alignment = 0xFFFFFF Base = Padding; Length = 0x1000000; Alignment = 0xFFFFFF Base = Padding; Length = 0x800000; Alignment = 0x7FFFFF Type = Mem32; Base = 0x91C02000; Length = 0x1000; Alignment = 0xFFF Type = PMem64; Base = 0x800100000; Length = 0x100000; Alignment = 0xFFFFF Base = 0x800100000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [03|00|00:20] ......
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2018:0902