[Pkg-xen-devel] Bug#988333: Bug#988333: Bug#988333: libxenmisc4.16: libxl fails to grant necessary I/O memory access for gfx_passthru of Intel IGD
Chuck Zmudzinski
brchuckz at netscape.net
Fri Mar 11 05:19:58 GMT 2022
On 3/8/2022 6:00 AM, Hans van Kranenburg wrote:
>> On 3/7/22 18:30, Chuck Zmudzinski wrote:
>>> [...]
>>
>> Thanks for adding all the info and researching this, Chuck!
>>
>> Hans
>
> Thanks for the encouragement. Now I am working on two things:
>
> 1. I want to understand the problem better so I can Improve the patch.
> The patch I proposed for this bug currently adds two pages to the
> permitted I/O addresses for the domain starting at 0xcc490, but I
> don't know the best way to determine that memory address. Probably a
> hard-coded constant address is not good enough to handle all possible
> hardware affected by this bug. It might be different for different
> Intel revisions of the Intel IGD, and it probably can be read from
> somewhere, but where? Also, what is that memory for? I would like to
> understand that before finalizing what the patch should be. I am
> researching these things, and then I will have a better version of the
> patch to propose for Xen upstream. I have found places where Qemu/vfio
> deals with what they call Intel IGD quirks, and that information can
> shed light on how to solve this bug in Xen. Hopefully upstream will
> accept a patch when we have a patch to propose to them. I am fairly
> sure there really is a bug that should be patched upstream to improve
> support for the Intel IGD passthrough feature on Xen.
I discovered that address 0xcc490 is for the Intel IGD Opregion, an area
of memory that Xen's hvmloader and Qemu both know about. So I was able
to propose this patch to the xen-devel mailing list.
Regards,
Chuck
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -24,6 +24,7 @@
#define PCI_OPTIONS "msitranslate=%d,power_mgmt=%d"
#define PCI_BDF_XSPATH "%04x-%02x-%02x-%01x"
#define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x"
+#define PCI_INTEL_OPREGION 0xfc /* value defined in
tools/firmware/hvmloader/pci_regs.h */
static unsigned int pci_encode_bdf(libxl_device_pci *pci)
{
@@ -640,6 +641,45 @@
}
/*
+ * This function assumes prior verification
+ * that pci is an Intel IGD device.
+ */
+static uint32_t sysfs_dev_get_igd_opregion(libxl__gc *gc,
libxl_device_pci *pci)
+{
+ char *pci_device_vendor_path =
+ GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/config",
+ pci->domain, pci->bus, pci->dev, pci->func);
+ size_t read_item;
+ uint32_t igd_opregion;
+
+ FILE *f = fopen(pci_device_vendor_path, "r");
+ if (!f) {
+ LOGE(ERROR,
+ "pci device "PCI_BDF" does not have config attribute",
+ pci->domain, pci->bus, pci->dev, pci->func);
+ return 0xffffffff;
+ }
+ if (fseek(f, PCI_INTEL_OPREGION, SEEK_SET)) {
+ LOGE(ERROR,
+ "pci device "PCI_BDF": cannot find igd-opregion address",
+ pci->domain, pci->bus, pci->dev, pci->func);
+ fclose(f);
+ return 0xffffffff;
+ }
+ read_item = fread(&igd_opregion, 4, 1, f);
+ fclose(f);
+
+ if (read_item != 1) {
+ LOGE(ERROR,
+ "cannot read igd-opresgion address of pci device "PCI_BDF,
+ pci->domain, pci->bus, pci->dev, pci->func);
+ return 0xffffffff;
+ }
+
+ return igd_opregion;
+}
+
+/*
* A brief comment about slots. I don't know what slots are for; however,
* I have by experimentation determined:
* - Before a device can be bound to pciback, its BDF must first be listed
@@ -2531,6 +2571,34 @@
domid, vga_iomem_start, (vga_iomem_start + 0x20 - 1));
return ret;
}
+
+ /* Allow access to Intel igd-opregion */
+ if (sysfs_dev_get_vendor(gc, pci) == 0x8086)
+ {
+ uint32_t igd_opregion = sysfs_dev_get_igd_opregion(gc, pci);
+ if (igd_opregion == 0xffffffff)
+ break;
+ vga_iomem_start = ((uint64_t)igd_opregion) >> XC_PAGE_SHIFT;
+ ret = xc_domain_iomem_permission(CTX->xch, stubdom_domid,
+ vga_iomem_start, 0x2, 1);
+ if (ret < 0) {
+ LOGED(ERROR, domid,
+ "failed to give stubdom%d access to iomem range "
+ "%"PRIx64"-%"PRIx64" for IGD passthru",
+ stubdom_domid,
+ vga_iomem_start, (vga_iomem_start + 0x2 - 1));
+ return ret;
+ }
+ ret = xc_domain_iomem_permission(CTX->xch, domid,
+ vga_iomem_start, 0x2, 1);
+ if (ret < 0) {
+ LOGED(ERROR, domid,
+ "failed to give dom%d access to iomem range "
+ "%"PRIx64"-%"PRIx64" for IGD passthru",
+ domid, vga_iomem_start, (vga_iomem_start + 0x2 - 1));
+ return ret;
+ }
+ }
break;
}
snip ---------------------------------------------------- snip
More information about the Pkg-xen-devel
mailing list