]> xenbits.xen.org Git - xenclient/xen-pq.git/commitdiff
Add patch to filter Intel graphics writes to GTT via I/O
authorThomas Horsten <thomas.horsten@citrix.com>
Tue, 13 Oct 2009 15:53:40 +0000 (16:53 +0100)
committerThomas Horsten <thomas.horsten@citrix.com>
Tue, 13 Oct 2009 15:54:45 +0000 (16:54 +0100)
NOT ADDED TO SERIES - add to activate...

master/filter-igfx-io [new file with mode: 0644]

diff --git a/master/filter-igfx-io b/master/filter-igfx-io
new file mode 100644 (file)
index 0000000..6e9d482
--- /dev/null
@@ -0,0 +1,83 @@
+diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
+index 0d7f5ff..8be35e5 100644
+--- a/xen/arch/x86/hvm/io.c
++++ b/xen/arch/x86/hvm/io.c
+@@ -278,6 +278,7 @@ void dpci_ioport_write(uint32_t mport, ioreq_t *p)
+ {
+     int i, sign = p->df ? -1 : 1;
+     uint32_t data;
++    struct domain *d = current->domain;
+     for ( i = 0; i < p->count; i++ )
+     {
+@@ -286,6 +287,19 @@ void dpci_ioport_write(uint32_t mport, ioreq_t *p)
+             (void)hvm_copy_from_guest_phys(
+                 &data, p->data + (sign * i * p->size), p->size);
++        if (d->igfx_ioport)
++        {
++            if (mport == d->igfx_ioport) {
++                d->igfx_index = data;
++            } else if (mport == (d->igfx_ioport+4)) {
++                if ((d->igfx_index & 1) && (d->igfx_index < 0x10000)) {
++                    //gdprintk(XENLOG_DEBUG, "iGFXIo: Skip outl(0x%04x,0x%08x) idx=0x%08x\n",
++                    //         (u16)(mport), data, d->igfx_index);
++                    continue;
++                }
++            }
++        }
++
+         switch ( p->size )
+         {
+         case 1:
+diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
+index ff56a19..2e8efff 100644
+--- a/xen/drivers/passthrough/vtd/iommu.c
++++ b/xen/drivers/passthrough/vtd/iommu.c
+@@ -1395,6 +1395,24 @@ static int domain_context_unmap(struct domain *domain, u8 bus, u8 devfn)
+     return ret;
+ }
++static void pci_check_intel_gfx(struct domain *domain, u8 bus, u8 devfn)
++{
++    u16 vendorid, deviceid;
++    u8 d = PCI_SLOT(devfn), f = PCI_FUNC(devfn);
++
++    vendorid = pci_conf_read16(bus, d, f, PCI_VENDOR_ID);
++    deviceid = pci_conf_read16(bus, d, f, PCI_DEVICE_ID);
++    if ((vendorid == 0x8086) && (deviceid == 0x2a42)) {
++        u32 iobase = pci_conf_read32(bus, d, f, PCI_BASE_ADDRESS_0 + 4*4) & PCI_BASE_ADDRESS_IO_MASK;
++        printk(XENLOG_DEBUG "Found Intel 8086:2a42 gfx with I/O at 0x%04x\n", iobase);
++        if (iobase > 0xffff) {
++            printk(XENLOG_ERR "Intel 8086:2a42 gfx has invalid I/O base 0x%08x\n", iobase);
++        } else {
++            domain->igfx_ioport = (iobase & 0xffff);
++        }
++    }
++}
++
+ static int reassign_device_ownership(
+     struct domain *source,
+     struct domain *target,
+@@ -1423,6 +1441,8 @@ static int reassign_device_ownership(
+     list_move(&pdev->domain_list, &target->arch.pdev_list);
+     pdev->domain = target;
++    pci_check_intel_gfx(target, bus, devfn);
++
+     for_each_pdev ( source, pdev )
+     {
+         drhd = acpi_find_matched_drhd_unit(pdev);
+diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
+index 46731a5..06a9016 100644
+--- a/xen/include/xen/sched.h
++++ b/xen/include/xen/sched.h
+@@ -206,6 +206,8 @@ struct domain
+     /* I/O capabilities (access to IRQs and memory-mapped I/O). */
+     struct rangeset *iomem_caps;
+     struct rangeset *irq_caps;
++    u16 igfx_ioport;
++    u32 igfx_index;
+     /* Is this an HVM guest? */
+     bool_t           is_hvm;