From: Grzegorz Uriasz <gorbak25@gmail.com>
To: qemu-devel@nongnu.org
Cc: artur@puzio.waw.pl, Stefano Stabellini <sstabellini@kernel.org>,
Paul Durrant <paul@xen.org>,
jakub@bartmin.ski, marmarek@invisiblethingslab.com,
Grzegorz Uriasz <gorbak25@gmail.com>,
Anthony Perard <anthony.perard@citrix.com>,
j.nowak26@student.uw.edu.pl, xen-devel@lists.xenproject.org
Subject: [PATCH 2/2] Improve legacy vbios handling
Date: Tue, 28 Apr 2020 06:28:47 +0000 [thread overview]
Message-ID: <20200428062847.7764-3-gorbak25@gmail.com> (raw)
In-Reply-To: <20200428062847.7764-1-gorbak25@gmail.com>
Signed-off-by: Grzegorz Uriasz <gorbak25@gmail.com>
---
hw/xen/xen_pt.c | 8 +++++--
hw/xen/xen_pt_graphics.c | 48 +++++++++++++++++++++++++++++++++++++---
hw/xen/xen_pt_load_rom.c | 2 +-
3 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index b91082cb8b..ffc3559dd4 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -483,8 +483,12 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd)
i, r->size, r->base_addr, type);
}
- /* Register expansion ROM address */
- if (d->rom.base_addr && d->rom.size) {
+ /*
+ * Register expansion ROM address. If we are dealing with a ROM
+ * shadow copy for legacy vga devices then don't bother to map it
+ * as previous code creates a proper shadow copy
+ */
+ if (d->rom.base_addr && d->rom.size && !(is_igd_vga_passthrough(d))) {
uint32_t bar_data = 0;
/* Re-set BAR reported by OS, otherwise ROM can't be read. */
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index a3bc7e3921..fe0ef2685c 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -129,7 +129,7 @@ int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
return 0;
}
-static void *get_vgabios(XenPCIPassthroughState *s, int *size,
+static void *get_sysfs_vgabios(XenPCIPassthroughState *s, int *size,
XenHostPCIDevice *dev)
{
return pci_assign_dev_load_option_rom(&s->dev, size,
@@ -137,6 +137,45 @@ static void *get_vgabios(XenPCIPassthroughState *s, int *size,
dev->dev, dev->func);
}
+static void xen_pt_direct_vbios_copy(XenPCIPassthroughState *s, Error **errp)
+{
+ int fd = -1;
+ void *guest_bios = NULL;
+ void *host_vbios = NULL;
+ /* This is always 32 pages in the real mode reserved region */
+ int bios_size = 32 << XC_PAGE_SHIFT;
+ int vbios_addr = 0xc0000;
+
+ fd = open("/dev/mem", O_RDONLY);
+ if (fd == -1) {
+ error_setg(errp, "Can't open /dev/mem: %s", strerror(errno));
+ return;
+ }
+ host_vbios = mmap(NULL, bios_size,
+ PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, fd, vbios_addr);
+ close(fd);
+
+ if (host_vbios == MAP_FAILED) {
+ error_setg(errp, "Failed to mmap host vbios: %s", strerror(errno));
+ return;
+ }
+
+ memory_region_init_ram(&s->dev.rom, OBJECT(&s->dev),
+ "legacy_vbios.rom", bios_size, &error_abort);
+ guest_bios = memory_region_get_ram_ptr(&s->dev.rom);
+ memcpy(guest_bios, host_vbios, bios_size);
+
+ if (munmap(host_vbios, bios_size) == -1) {
+ XEN_PT_LOG(&s->dev, "Failed to unmap host vbios: %s\n", strerror(errno));
+ }
+
+ cpu_physical_memory_write(vbios_addr, guest_bios, bios_size);
+ memory_region_set_address(&s->dev.rom, vbios_addr);
+ pci_register_bar(&s->dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->dev.rom);
+ s->dev.has_rom = true;
+ XEN_PT_LOG(&s->dev, "Legacy VBIOS registered\n");
+}
+
/* Refer to Seabios. */
struct rom_header {
uint16_t signature;
@@ -179,9 +218,11 @@ void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
return;
}
- bios = get_vgabios(s, &bios_size, dev);
+ bios = get_sysfs_vgabios(s, &bios_size, dev);
if (!bios) {
- error_setg(errp, "VGA: Can't get VBIOS");
+ XEN_PT_LOG(&s->dev, "Unable to get host VBIOS from sysfs - "
+ "falling back to a direct copy of memory ranges\n");
+ xen_pt_direct_vbios_copy(s, errp);
return;
}
@@ -223,6 +264,7 @@ void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev,
/* Currently we fixed this address as a primary for legacy BIOS. */
cpu_physical_memory_write(0xc0000, bios, bios_size);
+ XEN_PT_LOG(&s->dev, "Legacy VBIOS registered\n");
}
uint32_t igd_read_opregion(XenPCIPassthroughState *s)
diff --git a/hw/xen/xen_pt_load_rom.c b/hw/xen/xen_pt_load_rom.c
index 9f100dc159..8cd9aa84dc 100644
--- a/hw/xen/xen_pt_load_rom.c
+++ b/hw/xen/xen_pt_load_rom.c
@@ -65,7 +65,7 @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev,
goto close_rom;
}
- pci_register_bar(dev, PCI_ROM_SLOT, 0, &dev->rom);
+ pci_register_bar(dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_SPACE_MEMORY, &dev->rom);
dev->has_rom = true;
*size = st.st_size;
close_rom:
--
2.26.1
prev parent reply other threads:[~2020-04-28 6:30 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-28 6:28 [PATCH 0/2] Fix QEMU crashes when passing IGD to a guest VM under XEN Grzegorz Uriasz
2020-04-28 6:28 ` [PATCH 1/2] Fix undefined behaviour Grzegorz Uriasz
2020-04-28 8:10 ` Paul Durrant
2020-04-28 9:40 ` Artur Puzio
2020-04-28 12:32 ` Paul Durrant
2020-04-28 12:33 ` Paul Durrant
2020-04-28 8:58 ` Peter Maydell
2020-04-28 6:28 ` Grzegorz Uriasz [this message]
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=20200428062847.7764-3-gorbak25@gmail.com \
--to=gorbak25@gmail.com \
--cc=anthony.perard@citrix.com \
--cc=artur@puzio.waw.pl \
--cc=j.nowak26@student.uw.edu.pl \
--cc=jakub@bartmin.ski \
--cc=marmarek@invisiblethingslab.com \
--cc=paul@xen.org \
--cc=qemu-devel@nongnu.org \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.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).