From: Thomas Horsten Date: Tue, 13 Oct 2009 15:53:40 +0000 (+0100) Subject: Add patch to filter Intel graphics writes to GTT via I/O X-Git-Url: http://xenbits.xen.org/gitweb?a=commitdiff_plain;h=83cd9f0be5e83529186866c8c98381516e20e26d;p=xenclient%2Fxen-pq.git Add patch to filter Intel graphics writes to GTT via I/O NOT ADDED TO SERIES - add to activate... --- diff --git a/master/filter-igfx-io b/master/filter-igfx-io new file mode 100644 index 0000000..6e9d482 --- /dev/null +++ b/master/filter-igfx-io @@ -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;