From: Laszlo Ersek <lersek@redhat.com>
To: qemu-devel@nongnu.org, lersek@redhat.com
Cc: Marcel Apfelbaum <marcel@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>
Subject: [Qemu-devel] [PATCH 4/4] i386/acpi-build: build_crs(): fetch BAR from PCI config space directly
Date: Sat, 6 Jun 2015 01:46:29 +0200 [thread overview]
Message-ID: <1433547989-7238-5-git-send-email-lersek@redhat.com> (raw)
In-Reply-To: <1433547989-7238-1-git-send-email-lersek@redhat.com>
OVMF downloads the ACPI linker/loader script from QEMU when the edk2 PCI
Bus driver globally signals the firmware that PCI enumeration and resource
allocation have completed. At this point QEMU regenerates the ACPI payload
in an fw_cfg read callback, and this is when the PXB's _CRS gets
populated.
Unfortunately, when this happens, the PCI_COMMAND_MEMORY bit is clear in
the root bus's command register, *unlike* under SeaBIOS. The consequences
unfold as follows:
- When build_crs() fetches dev->io_regions[i].addr, it is all-bits-one,
because pci_update_mappings() --> pci_bar_address() calculated it as
PCI_BAR_UNMAPPED, due to the PCI_COMMAND_MEMORY bit being clear.
- Consequently, the SHPC MMIO BAR (bar 0) of the bridge is not added to
the _CRS, *despite* having been programmed in PCI config space.
- Similarly, the SHPC MMIO BAR of the PXB is not removed from the main
root bus's DWordMemory descriptor.
- Guest OSes (Linux and Windows alike) notice the pre-programmed SHPC BAR
within the PXB's config space, and notice that it conflicts with the
main root bus's memory resource descriptors. Linux reports
pci 0000:04:00.0: BAR 0: can't assign mem (size 0x100)
pci 0000:04:00.0: BAR 0: trying firmware assignment [mem
0x88200000-0x882000ff 64bit]
pci 0000:04:00.0: BAR 0: [mem 0x88200000-0x882000ff 64bit] conflicts
with PCI Bus 0000:00 [mem
0x88200000-0xfebfffff]
While Windows Server 2012 R2 reports
https://technet.microsoft.com/en-us/library/cc732199%28v=ws.10%29.aspx
This device cannot find enough free resources that it can use. If you
want to use this device, you will need to disable one of the other
devices on this system. (Code 12)
(This issue was apparently encountered earlier, see:
https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg02983.html
and the current hole-punching logic in build_crs() and build_ssdt() is
probably supposed to remedy exactly that problem -- however, for OVMF they
don't work, because at the end of the PCI enumeration and resource
allocation, which cues the ACPI linker/loader client, the command register
is clear.)
The solution is to fetch the BAR addresses from PCI config space directly,
for the purposes of build_crs(), regardless of the PCI command register
and any MemoryRegion state.
Example MMIO maps for a 2GB guest:
SeaBIOS:
main: 0x80000000..0xFC000000 / 0x7C000000
pxb: 0xFC000000..0xFC200000 / 0x00200000
main: 0xFC200000..0xFC213000 / 0x00013000
pxb: 0xFC213000..0xFC213100 / 0x00000100 <- SHPC BAR
main: 0xFC213100..0xFEA00000 / 0x027ECF00
pxb: 0xFEA00000..0xFEC00000 / 0x00200000
OVMF, without the fix:
main: 0x80000000..0x88100000 / 0x08100000
pxb: 0x88100000..0x88200000 / 0x00100000
main: 0x88200000..0xFEC00000 / 0x76A00000
OVMF, with the fix:
main: 0x80000000..0x88100000 / 0x08100000
pxb: 0x88100000..0x88200000 / 0x00100000
pxb: 0x88200000..0x88200100 / 0x00000100 <- SHPC BAR
main: 0x88200100..0xFEC00000 / 0x769FFF00
(Note that under OVMF the PCI enumerator includes requests for
prefetchable memory in the nonprefetchable memory pool -- separate windows
for nonprefetchable and prefetchable memory are not supported (yet) --
that's why there's one fewer pxb range in the corrected OVMF case than in
the SeaBIOS case.)
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
hw/i386/acpi-build.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b71e942..60d4f75 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -784,8 +784,8 @@ static Aml *build_crs(PCIHostState *host,
for (i = 0; i < PCI_NUM_REGIONS; i++) {
PCIIORegion *r = &dev->io_regions[i];
- range_base = r->addr;
- range_limit = r->addr + r->size - 1;
+ range_base = pci_bar_address(dev, i, r->type, r->size, false);
+ range_limit = range_base + r->size - 1;
/*
* Work-around for old bioses
--
1.8.3.1
next prev parent reply other threads:[~2015-06-05 23:46 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-05 23:45 [Qemu-devel] PXB fixes for QEMU, and extra root buses for OVMF Laszlo Ersek
2015-06-05 23:46 ` [Qemu-devel] [PATCH 0/4] PXB tweaks and fixes Laszlo Ersek
2015-06-05 23:46 ` [Qemu-devel] [PATCH 1/4] i386/acpi-build: more traditional _UID and _HID for PXB root buses Laszlo Ersek
2015-06-10 9:16 ` Marcel Apfelbaum
2015-06-05 23:46 ` [Qemu-devel] [PATCH 2/4] i386/acpi-build: fix PXB workarounds for unsupported BIOSes Laszlo Ersek
2015-06-10 9:17 ` Marcel Apfelbaum
2015-06-05 23:46 ` [Qemu-devel] [PATCH 3/4] hw/pci: allow the caller of pci_bar_address() to ignore command register Laszlo Ersek
2015-06-05 23:46 ` Laszlo Ersek [this message]
2015-06-07 9:23 ` [Qemu-devel] [PATCH 4/4] i386/acpi-build: build_crs(): fetch BAR from PCI config space directly Michael S. Tsirkin
2015-06-08 7:56 ` Laszlo Ersek
2015-06-08 9:40 ` Michael S. Tsirkin
2015-06-09 20:34 ` Laszlo Ersek
2015-06-10 10:06 ` Marcel Apfelbaum
2015-06-10 11:07 ` Laszlo Ersek
2015-06-10 16:21 ` Michael S. Tsirkin
2015-06-10 16:19 ` Michael S. Tsirkin
2015-06-10 9:09 ` [Qemu-devel] PXB fixes for QEMU, and extra root buses for OVMF Marcel Apfelbaum
2015-06-10 11:04 ` Laszlo Ersek
2015-06-10 11:55 ` Marcel Apfelbaum
2015-06-10 12:05 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1433547989-7238-5-git-send-email-lersek@redhat.com \
--to=lersek@redhat.com \
--cc=marcel@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).