WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [qemu-xen-unstable] passthrough: support Intel IGD passt

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [qemu-xen-unstable] passthrough: support Intel IGD passthrough with VT-D
From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Date: Thu, 4 Feb 2010 09:35:03 -0800
Delivery-date: Thu, 04 Feb 2010 09:35:01 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
commit d463cfee458bacfe1ee3cb9c3b4ce46a6be06edf
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date:   Thu Feb 4 17:04:48 2010 +0000

    passthrough: support Intel IGD passthrough with VT-D
    
    Some registers of Intel IGD are mapped in host bridge, so it needs to
    passthrough these registers of physical host bridge to guest because
    emulated host bridge in guest doesn't have these mappings.
    
    Some VBIOSs and drivers ssume the IGD BDF (bus:device:function) is
    always 00:02.0, so this patch reserves 00:02.0 for assigned IGD in
    guest.
    
    (Patch modified slightly by Ian Jackson.)
    
    Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
    Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 hw/pass-through.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/pass-through.h |    4 +++
 hw/pci.c          |   32 ++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 1 deletions(-)

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 9371a39..ecb3d6f 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -94,6 +94,7 @@
 #include <sys/ioctl.h>
 
 extern int gfx_passthru;
+int igd_passthru = 0;
 
 struct php_dev {
     struct pt_dev *pt_dev;
@@ -915,6 +916,8 @@ static int find_free_vslot(void)
 
     for ( slot = 0; slot < NR_PCI_DEV; slot++ )
     {
+        if ( gfx_passthru && slot == 0x2 )
+            continue;
         for ( func = 0; func < NR_PCI_FUNC; func++ )
         {
             devfn = PCI_DEVFN(slot, func);
@@ -944,7 +947,16 @@ static int __insert_to_pci_devfn(int bus, int dev, int 
func, int devfn,
     PCIBus *e_bus = dpci_infos.e_bus;
     int vslot;
 
-    if ( devfn & AUTO_PHP_SLOT )
+    if ( gfx_passthru && bus == 0x0 && dev == 0x2 )
+    {
+        igd_passthru = 1;
+
+        /* make virtual BDF of Intel IGD in guest is same with host */
+        devfn = PCI_DEVFN(dev, func);
+        if ( test_pci_devfn(devfn) || pci_devfn_in_use(e_bus, devfn) )
+            return -2;
+    }
+    else if ( devfn & AUTO_PHP_SLOT )
     {
         vslot = find_free_vslot();
         if (vslot < 0)
@@ -2073,6 +2085,48 @@ static uint32_t find_ext_cap_offset(struct pci_dev 
*pci_dev, uint32_t cap)
     return 0;
 }
 
+u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr)
+{
+    struct pci_dev *pci_dev;
+    u8 val;
+
+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
+    if ( !pci_dev )
+        return 0;
+
+    val = pci_read_byte(pci_dev, addr);
+    pci_free_dev(pci_dev);
+    return val;
+}
+
+u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr)
+{
+    struct pci_dev *pci_dev;
+    u16 val;
+
+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
+    if ( !pci_dev )
+        return 0;
+
+    val = pci_read_word(pci_dev, addr);
+    pci_free_dev(pci_dev);
+    return val;
+}
+
+u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr)
+{
+    struct pci_dev *pci_dev;
+    u32 val;
+
+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
+    if ( !pci_dev )
+        return 0;
+
+    val = pci_read_long(pci_dev, addr);
+    pci_free_dev(pci_dev);
+    return val;
+}
+
 /* parse BAR */
 static int pt_bar_reg_parse(
         struct pt_dev *ptdev, struct pt_reg_info_tbl *reg)
diff --git a/hw/pass-through.h b/hw/pass-through.h
index 3156897..f8a0c73 100644
--- a/hw/pass-through.h
+++ b/hw/pass-through.h
@@ -407,5 +407,9 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base)
 
 uint8_t pci_intx(struct pt_dev *ptdev);
 
+u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr);
+u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr);
+u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr);
+
 #endif /* __PASSTHROUGH_H__ */
 
diff --git a/hw/pci.c b/hw/pci.c
index d7c516e..af70b11 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -31,6 +31,8 @@
 #include "exec-all.h"
 #include "qemu-xen.h"
 
+extern int igd_passthru;
+
 //#define DEBUG_PCI
 
 struct PCIBus {
@@ -230,6 +232,12 @@ PCIDevice *pci_register_device(PCIBus *bus, const char 
*name,
 
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
+#ifdef CONFIG_PASSTHROUGH
+            /* reserve 00:02.0, because some BIOSs and drivers assume
+             * 00:02.0 for Intel IGD */
+            if ( gfx_passthru && devfn == 0x10 )
+                continue;
+#endif
             if ( !pci_devfn_in_use(bus, devfn) )
                 goto found;
         }
@@ -611,7 +619,31 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int 
len)
         goto the_end;
     }
     config_addr = addr & 0xff;
+
+#ifdef CONFIG_PASSTHROUGH
+    /* host bridge reads for IGD passthrough */
+    if ( igd_passthru && pci_dev->devfn == 0x00 ) {
+        val = pci_dev->config_read(pci_dev, config_addr, len);
+
+        if ( config_addr == 0x00 && len == 4 )
+            val = pt_pci_host_read_long(0, 0, 0, 0x00);
+        else if ( config_addr == 0x02 ) // Device ID
+            val = pt_pci_host_read_word(0, 0, 0, 0x02);
+        else if ( config_addr == 0x52 ) // GMCH Graphics Control Register
+            val = pt_pci_host_read_word(0, 0, 0, 0x52);
+        else if ( config_addr == 0xa0 ) // GMCH Top of Memory Register
+            val = pt_pci_host_read_word(0, 0, 0, 0xa0);
+        goto done_config_read;
+    } else if ( igd_passthru && pci_dev->devfn == 0x10 &&
+              config_addr == 0xfc ) { // read on IGD device
+        val = 0;  // use SMI to communicate with the system BIOS
+        goto done_config_read;
+    }
+#endif
+
     val = pci_dev->config_read(pci_dev, config_addr, len);
+
+ done_config_read:
 #if defined(DEBUG_PCI)
     printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
            pci_dev->name, config_addr, val, len);
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [qemu-xen-unstable] passthrough: support Intel IGD passthrough with VT-D, Ian Jackson <=