All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/10] igd passthrough chipset tweaks
@ 2015-12-14 11:39 ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

  Hi,

We have some code in our tree to support pci passthrough of intel
graphics devices (igd) on xen, which requires some chipset tweaks
for (a) the host bridge and (b) the lpc/isa-bridge to meat the
expectations of the guest driver.

For kvm we need pretty much the same, also the requirements for vgpu
(xengt/kvmgt) are very simliar.  This patch wires up the existing
support for kvm.  It also brings a bunch of bugfixes and cleanups.

Unfortunaly the oldish laptop I had planned to use for testing turned
out to have no working iommu support for igd, so this patch series
still has seen very light testing only.  Any testing feedback is very
welcome.

Testing with kvm/i440fx:
  Add '-M pc,igd-passthru=on -device igd-passthrough-isa-bridge,addr=1f'
  to turn on the chipset tweaks.  Passthrough the igd using vfio.

Testing with kvm/q35:
  Add '-M q35,igd-passthru=on' to turn on the the chipset tweaks.  Pick
  up the linux kernel patch referenced in patch #10, build a custom
  kernel with it.  Passthrough the igd using vfio.

Testing with xen:
  Existing setups should continue working ;)

Changes in v2:
  * Added igd-passthrough-isa-bridge support form kvm.
  * Added patch to drop has_igd_gfx_passthru.

TODO:
  * Possibly handle igd-passthrough-isa-bridge automatically (see patch 10).
  * Figure a way to handle the opregion, probably via vfio extension.
    Beyond the scope of this patch series, but probably needed to make
    laptop panels work correctly.

Gerd Hoffmann (10):
  pc: wire up TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE for !xen
  pc: remove has_igd_gfx_passthru global
  pc: move igd support code to igd.c
  igd: switch TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE to realize
  igd: TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE: call parent realize
  igd: use defines for standard pci config space offsets
  igd: revamp host config read
  igd: add q35 support
  igd: move igd-passthrough-isa-bridge to igd.c too
  igd: handle igd-passthrough-isa-bridge setup in realize()

 hw/i386/pc_piix.c         | 124 ++-----------------------------
 hw/pci-host/Makefile.objs |   3 +
 hw/pci-host/igd.c         | 181 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci-host/piix.c        |  88 ----------------------
 hw/pci-host/q35.c         |   6 +-
 hw/xen/xen_pt.h           |   3 +-
 vl.c                      |  10 ---
 7 files changed, 195 insertions(+), 220 deletions(-)
 create mode 100644 hw/pci-host/igd.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 00/10] igd passthrough chipset tweaks
@ 2015-12-14 11:39 ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

  Hi,

We have some code in our tree to support pci passthrough of intel
graphics devices (igd) on xen, which requires some chipset tweaks
for (a) the host bridge and (b) the lpc/isa-bridge to meat the
expectations of the guest driver.

For kvm we need pretty much the same, also the requirements for vgpu
(xengt/kvmgt) are very simliar.  This patch wires up the existing
support for kvm.  It also brings a bunch of bugfixes and cleanups.

Unfortunaly the oldish laptop I had planned to use for testing turned
out to have no working iommu support for igd, so this patch series
still has seen very light testing only.  Any testing feedback is very
welcome.

Testing with kvm/i440fx:
  Add '-M pc,igd-passthru=on -device igd-passthrough-isa-bridge,addr=1f'
  to turn on the chipset tweaks.  Passthrough the igd using vfio.

Testing with kvm/q35:
  Add '-M q35,igd-passthru=on' to turn on the the chipset tweaks.  Pick
  up the linux kernel patch referenced in patch #10, build a custom
  kernel with it.  Passthrough the igd using vfio.

Testing with xen:
  Existing setups should continue working ;)

Changes in v2:
  * Added igd-passthrough-isa-bridge support form kvm.
  * Added patch to drop has_igd_gfx_passthru.

TODO:
  * Possibly handle igd-passthrough-isa-bridge automatically (see patch 10).
  * Figure a way to handle the opregion, probably via vfio extension.
    Beyond the scope of this patch series, but probably needed to make
    laptop panels work correctly.

Gerd Hoffmann (10):
  pc: wire up TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE for !xen
  pc: remove has_igd_gfx_passthru global
  pc: move igd support code to igd.c
  igd: switch TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE to realize
  igd: TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE: call parent realize
  igd: use defines for standard pci config space offsets
  igd: revamp host config read
  igd: add q35 support
  igd: move igd-passthrough-isa-bridge to igd.c too
  igd: handle igd-passthrough-isa-bridge setup in realize()

 hw/i386/pc_piix.c         | 124 ++-----------------------------
 hw/pci-host/Makefile.objs |   3 +
 hw/pci-host/igd.c         | 181 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci-host/piix.c        |  88 ----------------------
 hw/pci-host/q35.c         |   6 +-
 hw/xen/xen_pt.h           |   3 +-
 vl.c                      |  10 ---
 7 files changed, 195 insertions(+), 220 deletions(-)
 create mode 100644 hw/pci-host/igd.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH] ehci: make idt processing more robust
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

Make ehci_process_itd return an error in case we didn't do any actual
iso transfer because we've found no active transaction.  That'll avoid
ehci happily run in circles forever if the guest builds a loop out of
idts.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-ehci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 4e2161b..d07f228 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1389,7 +1389,7 @@ static int ehci_process_itd(EHCIState *ehci,
 {
     USBDevice *dev;
     USBEndpoint *ep;
-    uint32_t i, len, pid, dir, devaddr, endp;
+    uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
     uint32_t pg, off, ptr1, ptr2, max, mult;
 
     ehci->periodic_sched_active = PERIODIC_ACTIVE;
@@ -1479,9 +1479,10 @@ static int ehci_process_itd(EHCIState *ehci,
                 ehci_raise_irq(ehci, USBSTS_INT);
             }
             itd->transact[i] &= ~ITD_XACT_ACTIVE;
+            xfers++;
         }
     }
-    return 0;
+    return xfers ? 0 : -1;
 }
 
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH] ehci: make idt processing more robust
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Make ehci_process_itd return an error in case we didn't do any actual
iso transfer because we've found no active transaction.  That'll avoid
ehci happily run in circles forever if the guest builds a loop out of
idts.

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/usb/hcd-ehci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 4e2161b..d07f228 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1389,7 +1389,7 @@ static int ehci_process_itd(EHCIState *ehci,
 {
     USBDevice *dev;
     USBEndpoint *ep;
-    uint32_t i, len, pid, dir, devaddr, endp;
+    uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
     uint32_t pg, off, ptr1, ptr2, max, mult;
 
     ehci->periodic_sched_active = PERIODIC_ACTIVE;
@@ -1479,9 +1479,10 @@ static int ehci_process_itd(EHCIState *ehci,
                 ehci_raise_irq(ehci, USBSTS_INT);
             }
             itd->transact[i] &= ~ITD_XACT_ACTIVE;
+            xfers++;
         }
     }
-    return 0;
+    return xfers ? 0 : -1;
 }
 
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 01/10] pc: wire up TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE for !xen
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Michael S. Tsirkin, Gerd Hoffmann, Paolo Bonzini,
	Richard Henderson, vfio-users

rename pc_xen_hvm_init_pci to pc_i440fx_init_pci,
use it for both xen and non-xen init.

That changes behavior of all pc-i440fx-$version machine types where
specifying -machine igd-passthru=on used to have no effect and now it
has.  It is unlikely to cause any trouble though as there used to be
no reason to add that option to kvm guests in the first place.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/i386/pc_piix.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 2e41efe..ce6c3c5 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -419,10 +419,9 @@ static void pc_init_isa(MachineState *machine)
     pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
 }
 
-#ifdef CONFIG_XEN
-static void pc_xen_hvm_init_pci(MachineState *machine)
+static void pc_i440fx_init_pci(MachineState *machine)
 {
-    const char *pci_type = has_igd_gfx_passthru ?
+    const char *pci_type = machine->igd_gfx_passthru ?
                 TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
 
     pc_init1(machine,
@@ -430,6 +429,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
              pci_type);
 }
 
+#ifdef CONFIG_XEN
 static void pc_xen_hvm_init(MachineState *machine)
 {
     PCIBus *bus;
@@ -439,7 +439,7 @@ static void pc_xen_hvm_init(MachineState *machine)
         exit(1);
     }
 
-    pc_xen_hvm_init_pci(machine);
+    pc_i440fx_init_pci(machine);
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
@@ -455,8 +455,7 @@ static void pc_xen_hvm_init(MachineState *machine)
         if (compat) { \
             compat(machine); \
         } \
-        pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
-                 TYPE_I440FX_PCI_DEVICE); \
+        pc_i440fx_init_pci(machine); \
     } \
     DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 01/10] pc: wire up TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE for !xen
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, Michael S. Tsirkin, Paolo Bonzini,
	Richard Henderson, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

rename pc_xen_hvm_init_pci to pc_i440fx_init_pci,
use it for both xen and non-xen init.

That changes behavior of all pc-i440fx-$version machine types where
specifying -machine igd-passthru=on used to have no effect and now it
has.  It is unlikely to cause any trouble though as there used to be
no reason to add that option to kvm guests in the first place.

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Eduardo Habkost <ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ@public.gmane.org>
---
 hw/i386/pc_piix.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 2e41efe..ce6c3c5 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -419,10 +419,9 @@ static void pc_init_isa(MachineState *machine)
     pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
 }
 
-#ifdef CONFIG_XEN
-static void pc_xen_hvm_init_pci(MachineState *machine)
+static void pc_i440fx_init_pci(MachineState *machine)
 {
-    const char *pci_type = has_igd_gfx_passthru ?
+    const char *pci_type = machine->igd_gfx_passthru ?
                 TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : TYPE_I440FX_PCI_DEVICE;
 
     pc_init1(machine,
@@ -430,6 +429,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
              pci_type);
 }
 
+#ifdef CONFIG_XEN
 static void pc_xen_hvm_init(MachineState *machine)
 {
     PCIBus *bus;
@@ -439,7 +439,7 @@ static void pc_xen_hvm_init(MachineState *machine)
         exit(1);
     }
 
-    pc_xen_hvm_init_pci(machine);
+    pc_i440fx_init_pci(machine);
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
@@ -455,8 +455,7 @@ static void pc_xen_hvm_init(MachineState *machine)
         if (compat) { \
             compat(machine); \
         } \
-        pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
-                 TYPE_I440FX_PCI_DEVICE); \
+        pc_i440fx_init_pci(machine); \
     } \
     DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, Paolo Bonzini, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/xen/xen_pt.h |  3 +--
 vl.c            | 10 ----------
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index c545280..6d8702b 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -320,10 +320,9 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
                                             unsigned int domain,
                                             unsigned int bus, unsigned int slot,
                                             unsigned int function);
-extern bool has_igd_gfx_passthru;
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
-    return (has_igd_gfx_passthru
+    return (qdev_get_machine->igd_gfx_passthru
             && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
 }
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
diff --git a/vl.c b/vl.c
index 4211ff1..e45a1da 100644
--- a/vl.c
+++ b/vl.c
@@ -1365,13 +1365,6 @@ static inline void semihosting_arg_fallback(const char *file, const char *cmd)
     }
 }
 
-/* Now we still need this for compatibility with XEN. */
-bool has_igd_gfx_passthru;
-static void igd_gfx_passthru(void)
-{
-    has_igd_gfx_passthru = current_machine->igd_gfx_passthru;
-}
-
 /***********************************************************/
 /* USB devices */
 
@@ -4550,9 +4543,6 @@ int main(int argc, char **argv, char **envp)
             exit(1);
     }
 
-    /* Check if IGD GFX passthrough. */
-    igd_gfx_passthru();
-
     /* init generic devices */
     if (qemu_opts_foreach(qemu_find_opts("device"),
                           device_init_func, NULL, NULL)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, Paolo Bonzini,
	vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/xen/xen_pt.h |  3 +--
 vl.c            | 10 ----------
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index c545280..6d8702b 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -320,10 +320,9 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
                                             unsigned int domain,
                                             unsigned int bus, unsigned int slot,
                                             unsigned int function);
-extern bool has_igd_gfx_passthru;
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
-    return (has_igd_gfx_passthru
+    return (qdev_get_machine->igd_gfx_passthru
             && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
 }
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
diff --git a/vl.c b/vl.c
index 4211ff1..e45a1da 100644
--- a/vl.c
+++ b/vl.c
@@ -1365,13 +1365,6 @@ static inline void semihosting_arg_fallback(const char *file, const char *cmd)
     }
 }
 
-/* Now we still need this for compatibility with XEN. */
-bool has_igd_gfx_passthru;
-static void igd_gfx_passthru(void)
-{
-    has_igd_gfx_passthru = current_machine->igd_gfx_passthru;
-}
-
 /***********************************************************/
 /* USB devices */
 
@@ -4550,9 +4543,6 @@ int main(int argc, char **argv, char **envp)
             exit(1);
     }
 
-    /* Check if IGD GFX passthrough. */
-    igd_gfx_passthru();
-
     /* init generic devices */
     if (qemu_opts_foreach(qemu_find_opts("device"),
                           device_init_func, NULL, NULL)) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 03/10] pc: move igd support code to igd.c
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Michael S. Tsirkin, Gerd Hoffmann, vfio-users

Pure code motion, except for dropping instance_size for
TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE (no need to set,
we can inherit it from TYPE_I440FX_PCI_DEVICE).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/pci-host/Makefile.objs |  3 ++
 hw/pci-host/igd.c         | 96 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci-host/piix.c        | 88 -------------------------------------------
 3 files changed, 99 insertions(+), 88 deletions(-)
 create mode 100644 hw/pci-host/igd.c

diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 45f1f0e..e341a49 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -11,6 +11,9 @@ common-obj-$(CONFIG_PPCE500_PCI) += ppce500.o
 # ARM devices
 common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o
 
+# igd passthrough support
+common-obj-$(CONFIG_LINUX) += igd.o
+
 common-obj-$(CONFIG_PCI_APB) += apb.o
 common-obj-$(CONFIG_FULONG) += bonito.o
 common-obj-$(CONFIG_PCI_PIIX) += piix.o
diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
new file mode 100644
index 0000000..ef0273b
--- /dev/null
+++ b/hw/pci-host/igd.c
@@ -0,0 +1,96 @@
+#include "qemu-common.h"
+#include "hw/pci/pci.h"
+#include "hw/i386/pc.h"
+
+/* IGD Passthrough Host Bridge. */
+typedef struct {
+    uint8_t offset;
+    uint8_t len;
+} IGDHostInfo;
+
+/* Here we just expose minimal host bridge offset subset. */
+static const IGDHostInfo igd_host_bridge_infos[] = {
+    {0x08, 2},  /* revision id */
+    {0x2c, 2},  /* sybsystem vendor id */
+    {0x2e, 2},  /* sybsystem id */
+    {0x50, 2},  /* SNB: processor graphics control register */
+    {0x52, 2},  /* processor graphics control register */
+    {0xa4, 4},  /* SNB: graphics base of stolen memory */
+    {0xa8, 4},  /* SNB: base of GTT stolen memory */
+};
+
+static int host_pci_config_read(int pos, int len, uint32_t val)
+{
+    char path[PATH_MAX];
+    int config_fd;
+    ssize_t size = sizeof(path);
+    /* Access real host bridge. */
+    int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
+                      0, 0, 0, 0, "config");
+    int ret = 0;
+
+    if (rc >= size || rc < 0) {
+        return -ENODEV;
+    }
+
+    config_fd = open(path, O_RDWR);
+    if (config_fd < 0) {
+        return -ENODEV;
+    }
+
+    if (lseek(config_fd, pos, SEEK_SET) != pos) {
+        ret = -errno;
+        goto out;
+    }
+    do {
+        rc = read(config_fd, (uint8_t *)&val, len);
+    } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
+    if (rc != len) {
+        ret = -errno;
+    }
+out:
+    close(config_fd);
+    return ret;
+}
+
+static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
+{
+    uint32_t val = 0;
+    int rc, i, num;
+    int pos, len;
+
+    num = ARRAY_SIZE(igd_host_bridge_infos);
+    for (i = 0; i < num; i++) {
+        pos = igd_host_bridge_infos[i].offset;
+        len = igd_host_bridge_infos[i].len;
+        rc = host_pci_config_read(pos, len, val);
+        if (rc) {
+            return -ENODEV;
+        }
+        pci_default_write_config(pci_dev, pos, val, len);
+    }
+
+    return 0;
+}
+
+static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = igd_pt_i440fx_initfn;
+    dc->desc = "IGD Passthrough Host bridge";
+}
+
+static const TypeInfo igd_passthrough_i440fx_info = {
+    .name          = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
+    .parent        = TYPE_I440FX_PCI_DEVICE,
+    .class_init    = igd_passthrough_i440fx_class_init,
+};
+
+static void igd_register_types(void)
+{
+    type_register_static(&igd_passthrough_i440fx_info);
+}
+
+type_init(igd_register_types)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 715208b..ccacb57 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -744,93 +744,6 @@ static const TypeInfo i440fx_info = {
     .class_init    = i440fx_class_init,
 };
 
-/* IGD Passthrough Host Bridge. */
-typedef struct {
-    uint8_t offset;
-    uint8_t len;
-} IGDHostInfo;
-
-/* Here we just expose minimal host bridge offset subset. */
-static const IGDHostInfo igd_host_bridge_infos[] = {
-    {0x08, 2},  /* revision id */
-    {0x2c, 2},  /* sybsystem vendor id */
-    {0x2e, 2},  /* sybsystem id */
-    {0x50, 2},  /* SNB: processor graphics control register */
-    {0x52, 2},  /* processor graphics control register */
-    {0xa4, 4},  /* SNB: graphics base of stolen memory */
-    {0xa8, 4},  /* SNB: base of GTT stolen memory */
-};
-
-static int host_pci_config_read(int pos, int len, uint32_t val)
-{
-    char path[PATH_MAX];
-    int config_fd;
-    ssize_t size = sizeof(path);
-    /* Access real host bridge. */
-    int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
-                      0, 0, 0, 0, "config");
-    int ret = 0;
-
-    if (rc >= size || rc < 0) {
-        return -ENODEV;
-    }
-
-    config_fd = open(path, O_RDWR);
-    if (config_fd < 0) {
-        return -ENODEV;
-    }
-
-    if (lseek(config_fd, pos, SEEK_SET) != pos) {
-        ret = -errno;
-        goto out;
-    }
-    do {
-        rc = read(config_fd, (uint8_t *)&val, len);
-    } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
-    if (rc != len) {
-        ret = -errno;
-    }
-out:
-    close(config_fd);
-    return ret;
-}
-
-static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
-{
-    uint32_t val = 0;
-    int rc, i, num;
-    int pos, len;
-
-    num = ARRAY_SIZE(igd_host_bridge_infos);
-    for (i = 0; i < num; i++) {
-        pos = igd_host_bridge_infos[i].offset;
-        len = igd_host_bridge_infos[i].len;
-        rc = host_pci_config_read(pos, len, val);
-        if (rc) {
-            return -ENODEV;
-        }
-        pci_default_write_config(pci_dev, pos, val, len);
-    }
-
-    return 0;
-}
-
-static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = igd_pt_i440fx_initfn;
-    dc->desc = "IGD Passthrough Host bridge";
-}
-
-static const TypeInfo igd_passthrough_i440fx_info = {
-    .name          = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
-    .parent        = TYPE_I440FX_PCI_DEVICE,
-    .instance_size = sizeof(PCII440FXState),
-    .class_init    = igd_passthrough_i440fx_class_init,
-};
-
 static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
                                                 PCIBus *rootbus)
 {
@@ -872,7 +785,6 @@ static const TypeInfo i440fx_pcihost_info = {
 static void i440fx_register_types(void)
 {
     type_register_static(&i440fx_info);
-    type_register_static(&igd_passthrough_i440fx_info);
     type_register_static(&piix3_pci_type_info);
     type_register_static(&piix3_info);
     type_register_static(&piix3_xen_info);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 03/10] pc: move igd support code to igd.c
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, Michael S. Tsirkin,
	vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Pure code motion, except for dropping instance_size for
TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE (no need to set,
we can inherit it from TYPE_I440FX_PCI_DEVICE).

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Stefano Stabellini <stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ@public.gmane.org>
---
 hw/pci-host/Makefile.objs |  3 ++
 hw/pci-host/igd.c         | 96 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/pci-host/piix.c        | 88 -------------------------------------------
 3 files changed, 99 insertions(+), 88 deletions(-)
 create mode 100644 hw/pci-host/igd.c

diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 45f1f0e..e341a49 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -11,6 +11,9 @@ common-obj-$(CONFIG_PPCE500_PCI) += ppce500.o
 # ARM devices
 common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o
 
+# igd passthrough support
+common-obj-$(CONFIG_LINUX) += igd.o
+
 common-obj-$(CONFIG_PCI_APB) += apb.o
 common-obj-$(CONFIG_FULONG) += bonito.o
 common-obj-$(CONFIG_PCI_PIIX) += piix.o
diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
new file mode 100644
index 0000000..ef0273b
--- /dev/null
+++ b/hw/pci-host/igd.c
@@ -0,0 +1,96 @@
+#include "qemu-common.h"
+#include "hw/pci/pci.h"
+#include "hw/i386/pc.h"
+
+/* IGD Passthrough Host Bridge. */
+typedef struct {
+    uint8_t offset;
+    uint8_t len;
+} IGDHostInfo;
+
+/* Here we just expose minimal host bridge offset subset. */
+static const IGDHostInfo igd_host_bridge_infos[] = {
+    {0x08, 2},  /* revision id */
+    {0x2c, 2},  /* sybsystem vendor id */
+    {0x2e, 2},  /* sybsystem id */
+    {0x50, 2},  /* SNB: processor graphics control register */
+    {0x52, 2},  /* processor graphics control register */
+    {0xa4, 4},  /* SNB: graphics base of stolen memory */
+    {0xa8, 4},  /* SNB: base of GTT stolen memory */
+};
+
+static int host_pci_config_read(int pos, int len, uint32_t val)
+{
+    char path[PATH_MAX];
+    int config_fd;
+    ssize_t size = sizeof(path);
+    /* Access real host bridge. */
+    int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
+                      0, 0, 0, 0, "config");
+    int ret = 0;
+
+    if (rc >= size || rc < 0) {
+        return -ENODEV;
+    }
+
+    config_fd = open(path, O_RDWR);
+    if (config_fd < 0) {
+        return -ENODEV;
+    }
+
+    if (lseek(config_fd, pos, SEEK_SET) != pos) {
+        ret = -errno;
+        goto out;
+    }
+    do {
+        rc = read(config_fd, (uint8_t *)&val, len);
+    } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
+    if (rc != len) {
+        ret = -errno;
+    }
+out:
+    close(config_fd);
+    return ret;
+}
+
+static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
+{
+    uint32_t val = 0;
+    int rc, i, num;
+    int pos, len;
+
+    num = ARRAY_SIZE(igd_host_bridge_infos);
+    for (i = 0; i < num; i++) {
+        pos = igd_host_bridge_infos[i].offset;
+        len = igd_host_bridge_infos[i].len;
+        rc = host_pci_config_read(pos, len, val);
+        if (rc) {
+            return -ENODEV;
+        }
+        pci_default_write_config(pci_dev, pos, val, len);
+    }
+
+    return 0;
+}
+
+static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = igd_pt_i440fx_initfn;
+    dc->desc = "IGD Passthrough Host bridge";
+}
+
+static const TypeInfo igd_passthrough_i440fx_info = {
+    .name          = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
+    .parent        = TYPE_I440FX_PCI_DEVICE,
+    .class_init    = igd_passthrough_i440fx_class_init,
+};
+
+static void igd_register_types(void)
+{
+    type_register_static(&igd_passthrough_i440fx_info);
+}
+
+type_init(igd_register_types)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 715208b..ccacb57 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -744,93 +744,6 @@ static const TypeInfo i440fx_info = {
     .class_init    = i440fx_class_init,
 };
 
-/* IGD Passthrough Host Bridge. */
-typedef struct {
-    uint8_t offset;
-    uint8_t len;
-} IGDHostInfo;
-
-/* Here we just expose minimal host bridge offset subset. */
-static const IGDHostInfo igd_host_bridge_infos[] = {
-    {0x08, 2},  /* revision id */
-    {0x2c, 2},  /* sybsystem vendor id */
-    {0x2e, 2},  /* sybsystem id */
-    {0x50, 2},  /* SNB: processor graphics control register */
-    {0x52, 2},  /* processor graphics control register */
-    {0xa4, 4},  /* SNB: graphics base of stolen memory */
-    {0xa8, 4},  /* SNB: base of GTT stolen memory */
-};
-
-static int host_pci_config_read(int pos, int len, uint32_t val)
-{
-    char path[PATH_MAX];
-    int config_fd;
-    ssize_t size = sizeof(path);
-    /* Access real host bridge. */
-    int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
-                      0, 0, 0, 0, "config");
-    int ret = 0;
-
-    if (rc >= size || rc < 0) {
-        return -ENODEV;
-    }
-
-    config_fd = open(path, O_RDWR);
-    if (config_fd < 0) {
-        return -ENODEV;
-    }
-
-    if (lseek(config_fd, pos, SEEK_SET) != pos) {
-        ret = -errno;
-        goto out;
-    }
-    do {
-        rc = read(config_fd, (uint8_t *)&val, len);
-    } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
-    if (rc != len) {
-        ret = -errno;
-    }
-out:
-    close(config_fd);
-    return ret;
-}
-
-static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
-{
-    uint32_t val = 0;
-    int rc, i, num;
-    int pos, len;
-
-    num = ARRAY_SIZE(igd_host_bridge_infos);
-    for (i = 0; i < num; i++) {
-        pos = igd_host_bridge_infos[i].offset;
-        len = igd_host_bridge_infos[i].len;
-        rc = host_pci_config_read(pos, len, val);
-        if (rc) {
-            return -ENODEV;
-        }
-        pci_default_write_config(pci_dev, pos, val, len);
-    }
-
-    return 0;
-}
-
-static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = igd_pt_i440fx_initfn;
-    dc->desc = "IGD Passthrough Host bridge";
-}
-
-static const TypeInfo igd_passthrough_i440fx_info = {
-    .name          = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
-    .parent        = TYPE_I440FX_PCI_DEVICE,
-    .instance_size = sizeof(PCII440FXState),
-    .class_init    = igd_passthrough_i440fx_class_init,
-};
-
 static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
                                                 PCIBus *rootbus)
 {
@@ -872,7 +785,6 @@ static const TypeInfo i440fx_pcihost_info = {
 static void i440fx_register_types(void)
 {
     type_register_static(&i440fx_info);
-    type_register_static(&igd_passthrough_i440fx_info);
     type_register_static(&piix3_pci_type_info);
     type_register_static(&piix3_info);
     type_register_static(&piix3_xen_info);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 04/10] igd: switch TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE to realize
  2015-12-14 11:39 ` Gerd Hoffmann
@ 2015-12-14 11:39   ` Gerd Hoffmann
  -1 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index ef0273b..d1eeafb 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -53,7 +53,7 @@ out:
     return ret;
 }
 
-static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
+static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
 {
     uint32_t val = 0;
     int rc, i, num;
@@ -65,12 +65,11 @@ static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
         len = igd_host_bridge_infos[i].len;
         rc = host_pci_config_read(pos, len, val);
         if (rc) {
-            return -ENODEV;
+            error_setg(errp, "failed to read host config");
+            return;
         }
         pci_default_write_config(pci_dev, pos, val, len);
     }
-
-    return 0;
 }
 
 static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
@@ -78,7 +77,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->init = igd_pt_i440fx_initfn;
+    k->realize = igd_pt_i440fx_realize;
     dc->desc = "IGD Passthrough Host bridge";
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 04/10] igd: switch TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE to realize
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index ef0273b..d1eeafb 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -53,7 +53,7 @@ out:
     return ret;
 }
 
-static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
+static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
 {
     uint32_t val = 0;
     int rc, i, num;
@@ -65,12 +65,11 @@ static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
         len = igd_host_bridge_infos[i].len;
         rc = host_pci_config_read(pos, len, val);
         if (rc) {
-            return -ENODEV;
+            error_setg(errp, "failed to read host config");
+            return;
         }
         pci_default_write_config(pci_dev, pos, val, len);
     }
-
-    return 0;
 }
 
 static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
@@ -78,7 +77,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->init = igd_pt_i440fx_initfn;
+    k->realize = igd_pt_i440fx_realize;
     dc->desc = "IGD Passthrough Host bridge";
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 05/10] igd: TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE: call parent realize
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index d1eeafb..6f52ab1 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -53,12 +53,20 @@ out:
     return ret;
 }
 
+static void (*i440fx_realize)(PCIDevice *pci_dev, Error **errp);
 static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
 {
+    Error *err = NULL;
     uint32_t val = 0;
     int rc, i, num;
     int pos, len;
 
+    i440fx_realize(pci_dev, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+
     num = ARRAY_SIZE(igd_host_bridge_infos);
     for (i = 0; i < num; i++) {
         pos = igd_host_bridge_infos[i].offset;
@@ -77,6 +85,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
+    i440fx_realize = k->realize;
     k->realize = igd_pt_i440fx_realize;
     dc->desc = "IGD Passthrough Host bridge";
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 05/10] igd: TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE: call parent realize
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/pci-host/igd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index d1eeafb..6f52ab1 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -53,12 +53,20 @@ out:
     return ret;
 }
 
+static void (*i440fx_realize)(PCIDevice *pci_dev, Error **errp);
 static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
 {
+    Error *err = NULL;
     uint32_t val = 0;
     int rc, i, num;
     int pos, len;
 
+    i440fx_realize(pci_dev, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+
     num = ARRAY_SIZE(igd_host_bridge_infos);
     for (i = 0; i < num; i++) {
         pos = igd_host_bridge_infos[i].offset;
@@ -77,6 +85,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
+    i440fx_realize = k->realize;
     k->realize = igd_pt_i440fx_realize;
     dc->desc = "IGD Passthrough Host bridge";
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 06/10] igd: use defines for standard pci config space offsets
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index 6f52ab1..0784128 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -10,9 +10,9 @@ typedef struct {
 
 /* Here we just expose minimal host bridge offset subset. */
 static const IGDHostInfo igd_host_bridge_infos[] = {
-    {0x08, 2},  /* revision id */
-    {0x2c, 2},  /* sybsystem vendor id */
-    {0x2e, 2},  /* sybsystem id */
+    {PCI_REVISION_ID,         2},
+    {PCI_SUBSYSTEM_VENDOR_ID, 2},
+    {PCI_SUBSYSTEM_ID,        2},
     {0x50, 2},  /* SNB: processor graphics control register */
     {0x52, 2},  /* processor graphics control register */
     {0xa4, 4},  /* SNB: graphics base of stolen memory */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 06/10] igd: use defines for standard pci config space offsets
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/pci-host/igd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index 6f52ab1..0784128 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -10,9 +10,9 @@ typedef struct {
 
 /* Here we just expose minimal host bridge offset subset. */
 static const IGDHostInfo igd_host_bridge_infos[] = {
-    {0x08, 2},  /* revision id */
-    {0x2c, 2},  /* sybsystem vendor id */
-    {0x2e, 2},  /* sybsystem id */
+    {PCI_REVISION_ID,         2},
+    {PCI_SUBSYSTEM_VENDOR_ID, 2},
+    {PCI_SUBSYSTEM_ID,        2},
     {0x50, 2},  /* SNB: processor graphics control register */
     {0x52, 2},  /* processor graphics control register */
     {0xa4, 4},  /* SNB: graphics base of stolen memory */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 07/10] igd: revamp host config read
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

Move all work to the host_pci_config_copy helper function,
which we can easily reuse when adding q35 support.
Open sysfs file only once for all values.  Use pread.
Proper error handling.  Fix bugs:

 * Don't throw away results (like old host_pci_config_read
   did because val was passed by value not reference).
 * Update config space directly (writing via
   pci_default_write_config only works for registers
   whitelisted in wmask).

Hmm, this code can hardly ever worked before,
/me wonders what test coverage it had.

With this patch in place igd-passthru=on actually
works, although it still requires root priviledges
because linux refuses to allow non-root users access
pci config space above offset 0x50.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 65 +++++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 38 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index 0784128..ec48875 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -19,47 +19,39 @@ static const IGDHostInfo igd_host_bridge_infos[] = {
     {0xa8, 4},  /* SNB: base of GTT stolen memory */
 };
 
-static int host_pci_config_read(int pos, int len, uint32_t val)
+static void host_pci_config_copy(PCIDevice *guest, const char *host,
+                                 const IGDHostInfo *list, int len, Error **errp)
 {
-    char path[PATH_MAX];
-    int config_fd;
-    ssize_t size = sizeof(path);
-    /* Access real host bridge. */
-    int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
-                      0, 0, 0, 0, "config");
-    int ret = 0;
+    char *path;
+    int config_fd, rc, i;
 
-    if (rc >= size || rc < 0) {
-        return -ENODEV;
-    }
-
-    config_fd = open(path, O_RDWR);
+    path = g_strdup_printf("/sys/bus/pci/devices/%s/config", host);
+    config_fd = open(path, O_RDONLY);
     if (config_fd < 0) {
-        return -ENODEV;
+        error_setg_file_open(errp, errno, path);
+        goto out_free;
     }
 
-    if (lseek(config_fd, pos, SEEK_SET) != pos) {
-        ret = -errno;
-        goto out;
+    for (i = 0; i < len; i++) {
+        rc = pread(config_fd, guest->config + list[i].offset,
+                   list[i].len, list[i].offset);
+        if (rc != list[i].len) {
+            error_setg_errno(errp, errno, "read %s, offset 0x%x",
+                             path, list[i].offset);
+            goto out_close;
+        }
     }
-    do {
-        rc = read(config_fd, (uint8_t *)&val, len);
-    } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
-    if (rc != len) {
-        ret = -errno;
-    }
-out:
+
+out_close:
     close(config_fd);
-    return ret;
+out_free:
+    g_free(path);
 }
 
 static void (*i440fx_realize)(PCIDevice *pci_dev, Error **errp);
 static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
 {
     Error *err = NULL;
-    uint32_t val = 0;
-    int rc, i, num;
-    int pos, len;
 
     i440fx_realize(pci_dev, &err);
     if (err != NULL) {
@@ -67,16 +59,13 @@ static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
         return;
     }
 
-    num = ARRAY_SIZE(igd_host_bridge_infos);
-    for (i = 0; i < num; i++) {
-        pos = igd_host_bridge_infos[i].offset;
-        len = igd_host_bridge_infos[i].len;
-        rc = host_pci_config_read(pos, len, val);
-        if (rc) {
-            error_setg(errp, "failed to read host config");
-            return;
-        }
-        pci_default_write_config(pci_dev, pos, val, len);
+    host_pci_config_copy(pci_dev, "0000:00:00.0",
+                         igd_host_bridge_infos,
+                         ARRAY_SIZE(igd_host_bridge_infos),
+                         &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
     }
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 07/10] igd: revamp host config read
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Move all work to the host_pci_config_copy helper function,
which we can easily reuse when adding q35 support.
Open sysfs file only once for all values.  Use pread.
Proper error handling.  Fix bugs:

 * Don't throw away results (like old host_pci_config_read
   did because val was passed by value not reference).
 * Update config space directly (writing via
   pci_default_write_config only works for registers
   whitelisted in wmask).

Hmm, this code can hardly ever worked before,
/me wonders what test coverage it had.

With this patch in place igd-passthru=on actually
works, although it still requires root priviledges
because linux refuses to allow non-root users access
pci config space above offset 0x50.

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/pci-host/igd.c | 65 +++++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 38 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index 0784128..ec48875 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -19,47 +19,39 @@ static const IGDHostInfo igd_host_bridge_infos[] = {
     {0xa8, 4},  /* SNB: base of GTT stolen memory */
 };
 
-static int host_pci_config_read(int pos, int len, uint32_t val)
+static void host_pci_config_copy(PCIDevice *guest, const char *host,
+                                 const IGDHostInfo *list, int len, Error **errp)
 {
-    char path[PATH_MAX];
-    int config_fd;
-    ssize_t size = sizeof(path);
-    /* Access real host bridge. */
-    int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
-                      0, 0, 0, 0, "config");
-    int ret = 0;
+    char *path;
+    int config_fd, rc, i;
 
-    if (rc >= size || rc < 0) {
-        return -ENODEV;
-    }
-
-    config_fd = open(path, O_RDWR);
+    path = g_strdup_printf("/sys/bus/pci/devices/%s/config", host);
+    config_fd = open(path, O_RDONLY);
     if (config_fd < 0) {
-        return -ENODEV;
+        error_setg_file_open(errp, errno, path);
+        goto out_free;
     }
 
-    if (lseek(config_fd, pos, SEEK_SET) != pos) {
-        ret = -errno;
-        goto out;
+    for (i = 0; i < len; i++) {
+        rc = pread(config_fd, guest->config + list[i].offset,
+                   list[i].len, list[i].offset);
+        if (rc != list[i].len) {
+            error_setg_errno(errp, errno, "read %s, offset 0x%x",
+                             path, list[i].offset);
+            goto out_close;
+        }
     }
-    do {
-        rc = read(config_fd, (uint8_t *)&val, len);
-    } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
-    if (rc != len) {
-        ret = -errno;
-    }
-out:
+
+out_close:
     close(config_fd);
-    return ret;
+out_free:
+    g_free(path);
 }
 
 static void (*i440fx_realize)(PCIDevice *pci_dev, Error **errp);
 static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
 {
     Error *err = NULL;
-    uint32_t val = 0;
-    int rc, i, num;
-    int pos, len;
 
     i440fx_realize(pci_dev, &err);
     if (err != NULL) {
@@ -67,16 +59,13 @@ static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
         return;
     }
 
-    num = ARRAY_SIZE(igd_host_bridge_infos);
-    for (i = 0; i < num; i++) {
-        pos = igd_host_bridge_infos[i].offset;
-        len = igd_host_bridge_infos[i].len;
-        rc = host_pci_config_read(pos, len, val);
-        if (rc) {
-            error_setg(errp, "failed to read host config");
-            return;
-        }
-        pci_default_write_config(pci_dev, pos, val, len);
+    host_pci_config_copy(pci_dev, "0000:00:00.0",
+                         igd_host_bridge_infos,
+                         ARRAY_SIZE(igd_host_bridge_infos),
+                         &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
     }
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 08/10] igd: add q35 support
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Michael S. Tsirkin, Gerd Hoffmann, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 hw/pci-host/q35.c |  6 +++++-
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index ec48875..f6e3f7a 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -1,5 +1,6 @@
 #include "qemu-common.h"
 #include "hw/pci/pci.h"
+#include "hw/pci-host/q35.h"
 #include "hw/i386/pc.h"
 
 /* IGD Passthrough Host Bridge. */
@@ -76,7 +77,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
 
     i440fx_realize = k->realize;
     k->realize = igd_pt_i440fx_realize;
-    dc->desc = "IGD Passthrough Host bridge";
+    dc->desc = "IGD Passthrough Host bridge (i440fx)";
 }
 
 static const TypeInfo igd_passthrough_i440fx_info = {
@@ -85,9 +86,47 @@ static const TypeInfo igd_passthrough_i440fx_info = {
     .class_init    = igd_passthrough_i440fx_class_init,
 };
 
+static void (*q35_realize)(PCIDevice *pci_dev, Error **errp);
+static void igd_pt_q35_realize(PCIDevice *pci_dev, Error **errp)
+{
+    Error *err = NULL;
+
+    q35_realize(pci_dev, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    host_pci_config_copy(pci_dev, "0000:00:00.0",
+                         igd_host_bridge_infos,
+                         ARRAY_SIZE(igd_host_bridge_infos),
+                         &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+}
+
+static void igd_passthrough_q35_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    q35_realize = k->realize;
+    k->realize = igd_pt_q35_realize;
+    dc->desc = "IGD Passthrough Host bridge (q35)";
+}
+
+static const TypeInfo igd_passthrough_q35_info = {
+    .name          = "igd-passthrough-q35-mch",
+    .parent        = TYPE_MCH_PCI_DEVICE,
+    .class_init    = igd_passthrough_q35_class_init,
+};
+
 static void igd_register_types(void)
 {
     type_register_static(&igd_passthrough_i440fx_info);
+    type_register_static(&igd_passthrough_q35_info);
 }
 
 type_init(igd_register_types)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 1fb4707..07dc595 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -151,7 +151,11 @@ static void q35_host_initfn(Object *obj)
     memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
                           "pci-conf-data", 4);
 
-    object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
+    if (object_property_get_bool(qdev_get_machine(), "igd-passthru", NULL)) {
+        object_initialize(&s->mch, sizeof(s->mch), "igd-passthrough-q35-mch");
+    } else {
+        object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
+    }
     object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
     qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 08/10] igd: add q35 support
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, Michael S. Tsirkin,
	vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/pci-host/igd.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 hw/pci-host/q35.c |  6 +++++-
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index ec48875..f6e3f7a 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -1,5 +1,6 @@
 #include "qemu-common.h"
 #include "hw/pci/pci.h"
+#include "hw/pci-host/q35.h"
 #include "hw/i386/pc.h"
 
 /* IGD Passthrough Host Bridge. */
@@ -76,7 +77,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
 
     i440fx_realize = k->realize;
     k->realize = igd_pt_i440fx_realize;
-    dc->desc = "IGD Passthrough Host bridge";
+    dc->desc = "IGD Passthrough Host bridge (i440fx)";
 }
 
 static const TypeInfo igd_passthrough_i440fx_info = {
@@ -85,9 +86,47 @@ static const TypeInfo igd_passthrough_i440fx_info = {
     .class_init    = igd_passthrough_i440fx_class_init,
 };
 
+static void (*q35_realize)(PCIDevice *pci_dev, Error **errp);
+static void igd_pt_q35_realize(PCIDevice *pci_dev, Error **errp)
+{
+    Error *err = NULL;
+
+    q35_realize(pci_dev, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    host_pci_config_copy(pci_dev, "0000:00:00.0",
+                         igd_host_bridge_infos,
+                         ARRAY_SIZE(igd_host_bridge_infos),
+                         &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+}
+
+static void igd_passthrough_q35_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    q35_realize = k->realize;
+    k->realize = igd_pt_q35_realize;
+    dc->desc = "IGD Passthrough Host bridge (q35)";
+}
+
+static const TypeInfo igd_passthrough_q35_info = {
+    .name          = "igd-passthrough-q35-mch",
+    .parent        = TYPE_MCH_PCI_DEVICE,
+    .class_init    = igd_passthrough_q35_class_init,
+};
+
 static void igd_register_types(void)
 {
     type_register_static(&igd_passthrough_i440fx_info);
+    type_register_static(&igd_passthrough_q35_info);
 }
 
 type_init(igd_register_types)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 1fb4707..07dc595 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -151,7 +151,11 @@ static void q35_host_initfn(Object *obj)
     memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
                           "pci-conf-data", 4);
 
-    object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
+    if (object_property_get_bool(qdev_get_machine(), "igd-passthru", NULL)) {
+        object_initialize(&s->mch, sizeof(s->mch), "igd-passthrough-q35-mch");
+    } else {
+        object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
+    }
     object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
     qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 09/10] igd: move igd-passthrough-isa-bridge to igd.c too
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Michael S. Tsirkin, Gerd Hoffmann, Paolo Bonzini,
	Richard Henderson, vfio-users

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/i386/pc_piix.c | 113 ------------------------------------------------------
 hw/pci-host/igd.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 113 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ce6c3c5..656bc39 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -921,119 +921,6 @@ static void pc_i440fx_0_10_machine_options(MachineClass *m)
 DEFINE_I440FX_MACHINE(v0_10, "pc-0.10", pc_compat_0_13,
                       pc_i440fx_0_10_machine_options);
 
-typedef struct {
-    uint16_t gpu_device_id;
-    uint16_t pch_device_id;
-    uint8_t pch_revision_id;
-} IGDDeviceIDInfo;
-
-/* In real world different GPU should have different PCH. But actually
- * the different PCH DIDs likely map to different PCH SKUs. We do the
- * same thing for the GPU. For PCH, the different SKUs are going to be
- * all the same silicon design and implementation, just different
- * features turn on and off with fuses. The SW interfaces should be
- * consistent across all SKUs in a given family (eg LPT). But just same
- * features may not be supported.
- *
- * Most of these different PCH features probably don't matter to the
- * Gfx driver, but obviously any difference in display port connections
- * will so it should be fine with any PCH in case of passthrough.
- *
- * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
- * scenarios, 0x9cc3 for BDW(Broadwell).
- */
-static const IGDDeviceIDInfo igd_combo_id_infos[] = {
-    /* HSW Classic */
-    {0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */
-    {0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */
-    {0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */
-    {0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */
-    {0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */
-    /* HSW ULT */
-    {0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */
-    {0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */
-    {0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */
-    {0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */
-    {0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */
-    {0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */
-    /* HSW CRW */
-    {0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */
-    {0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */
-    /* HSW Server */
-    {0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */
-    /* HSW SRVR */
-    {0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */
-    /* BSW */
-    {0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */
-    {0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */
-    {0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */
-    {0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */
-    {0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */
-    {0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */
-    {0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */
-    {0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */
-    {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */
-    {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */
-    {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */
-};
-
-static void isa_bridge_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    dc->desc        = "ISA bridge faked to support IGD PT";
-    k->vendor_id    = PCI_VENDOR_ID_INTEL;
-    k->class_id     = PCI_CLASS_BRIDGE_ISA;
-};
-
-static TypeInfo isa_bridge_info = {
-    .name          = "igd-passthrough-isa-bridge",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIDevice),
-    .class_init = isa_bridge_class_init,
-};
-
-static void pt_graphics_register_types(void)
-{
-    type_register_static(&isa_bridge_info);
-}
-type_init(pt_graphics_register_types)
-
-void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
-{
-    struct PCIDevice *bridge_dev;
-    int i, num;
-    uint16_t pch_dev_id = 0xffff;
-    uint8_t pch_rev_id;
-
-    num = ARRAY_SIZE(igd_combo_id_infos);
-    for (i = 0; i < num; i++) {
-        if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
-            pch_dev_id = igd_combo_id_infos[i].pch_device_id;
-            pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
-        }
-    }
-
-    if (pch_dev_id == 0xffff) {
-        return;
-    }
-
-    /* Currently IGD drivers always need to access PCH by 1f.0. */
-    bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
-                                   "igd-passthrough-isa-bridge");
-
-    /*
-     * Note that vendor id is always PCI_VENDOR_ID_INTEL.
-     */
-    if (!bridge_dev) {
-        fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
-        return;
-    }
-    pci_config_set_device_id(bridge_dev->config, pch_dev_id);
-    pci_config_set_revision(bridge_dev->config, pch_rev_id);
-}
-
 static void isapc_machine_options(MachineClass *m)
 {
     m->desc = "ISA-only PC";
diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index f6e3f7a..96b679d 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -123,10 +123,118 @@ static const TypeInfo igd_passthrough_q35_info = {
     .class_init    = igd_passthrough_q35_class_init,
 };
 
+typedef struct {
+    uint16_t gpu_device_id;
+    uint16_t pch_device_id;
+    uint8_t pch_revision_id;
+} IGDDeviceIDInfo;
+
+/* In real world different GPU should have different PCH. But actually
+ * the different PCH DIDs likely map to different PCH SKUs. We do the
+ * same thing for the GPU. For PCH, the different SKUs are going to be
+ * all the same silicon design and implementation, just different
+ * features turn on and off with fuses. The SW interfaces should be
+ * consistent across all SKUs in a given family (eg LPT). But just same
+ * features may not be supported.
+ *
+ * Most of these different PCH features probably don't matter to the
+ * Gfx driver, but obviously any difference in display port connections
+ * will so it should be fine with any PCH in case of passthrough.
+ *
+ * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
+ * scenarios, 0x9cc3 for BDW(Broadwell).
+ */
+static const IGDDeviceIDInfo igd_combo_id_infos[] = {
+    /* HSW Classic */
+    {0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */
+    {0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */
+    {0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */
+    {0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */
+    {0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */
+    /* HSW ULT */
+    {0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */
+    {0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */
+    {0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */
+    {0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */
+    {0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */
+    {0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */
+    /* HSW CRW */
+    {0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */
+    {0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */
+    /* HSW Server */
+    {0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */
+    /* HSW SRVR */
+    {0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */
+    /* BSW */
+    {0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */
+    {0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */
+    {0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */
+    {0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */
+    {0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */
+    {0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */
+    {0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */
+    {0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */
+    {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */
+    {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */
+    {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */
+};
+
+static void isa_bridge_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    dc->desc        = "ISA bridge faked to support IGD PT";
+    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->class_id     = PCI_CLASS_BRIDGE_ISA;
+};
+
+static TypeInfo igd_passthrough_isa_bridge_info = {
+    .name          = "igd-passthrough-isa-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init = isa_bridge_class_init,
+};
+
+void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
+{
+    struct PCIDevice *bridge_dev;
+    int i, num;
+    uint16_t pch_dev_id = 0xffff;
+    uint8_t pch_rev_id;
+
+    num = ARRAY_SIZE(igd_combo_id_infos);
+    for (i = 0; i < num; i++) {
+        if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
+            pch_dev_id = igd_combo_id_infos[i].pch_device_id;
+            pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
+        }
+    }
+
+    if (pch_dev_id == 0xffff) {
+        return;
+    }
+
+    /* Currently IGD drivers always need to access PCH by 1f.0. */
+    bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
+                                   "igd-passthrough-isa-bridge");
+
+    /*
+     * Note that vendor id is always PCI_VENDOR_ID_INTEL.
+     */
+    if (!bridge_dev) {
+        fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
+        return;
+    }
+    pci_config_set_device_id(bridge_dev->config, pch_dev_id);
+    pci_config_set_revision(bridge_dev->config, pch_rev_id);
+}
+
 static void igd_register_types(void)
 {
     type_register_static(&igd_passthrough_i440fx_info);
     type_register_static(&igd_passthrough_q35_info);
+    type_register_static(&igd_passthrough_isa_bridge_info);
 }
 
 type_init(igd_register_types)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 09/10] igd: move igd-passthrough-isa-bridge to igd.c too
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, Michael S. Tsirkin, Paolo Bonzini,
	Richard Henderson, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/i386/pc_piix.c | 113 ------------------------------------------------------
 hw/pci-host/igd.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 113 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ce6c3c5..656bc39 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -921,119 +921,6 @@ static void pc_i440fx_0_10_machine_options(MachineClass *m)
 DEFINE_I440FX_MACHINE(v0_10, "pc-0.10", pc_compat_0_13,
                       pc_i440fx_0_10_machine_options);
 
-typedef struct {
-    uint16_t gpu_device_id;
-    uint16_t pch_device_id;
-    uint8_t pch_revision_id;
-} IGDDeviceIDInfo;
-
-/* In real world different GPU should have different PCH. But actually
- * the different PCH DIDs likely map to different PCH SKUs. We do the
- * same thing for the GPU. For PCH, the different SKUs are going to be
- * all the same silicon design and implementation, just different
- * features turn on and off with fuses. The SW interfaces should be
- * consistent across all SKUs in a given family (eg LPT). But just same
- * features may not be supported.
- *
- * Most of these different PCH features probably don't matter to the
- * Gfx driver, but obviously any difference in display port connections
- * will so it should be fine with any PCH in case of passthrough.
- *
- * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
- * scenarios, 0x9cc3 for BDW(Broadwell).
- */
-static const IGDDeviceIDInfo igd_combo_id_infos[] = {
-    /* HSW Classic */
-    {0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */
-    {0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */
-    {0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */
-    {0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */
-    {0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */
-    /* HSW ULT */
-    {0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */
-    {0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */
-    {0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */
-    {0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */
-    {0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */
-    {0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */
-    /* HSW CRW */
-    {0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */
-    {0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */
-    /* HSW Server */
-    {0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */
-    /* HSW SRVR */
-    {0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */
-    /* BSW */
-    {0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */
-    {0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */
-    {0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */
-    {0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */
-    {0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */
-    {0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */
-    {0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */
-    {0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */
-    {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */
-    {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */
-    {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */
-};
-
-static void isa_bridge_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    dc->desc        = "ISA bridge faked to support IGD PT";
-    k->vendor_id    = PCI_VENDOR_ID_INTEL;
-    k->class_id     = PCI_CLASS_BRIDGE_ISA;
-};
-
-static TypeInfo isa_bridge_info = {
-    .name          = "igd-passthrough-isa-bridge",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIDevice),
-    .class_init = isa_bridge_class_init,
-};
-
-static void pt_graphics_register_types(void)
-{
-    type_register_static(&isa_bridge_info);
-}
-type_init(pt_graphics_register_types)
-
-void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
-{
-    struct PCIDevice *bridge_dev;
-    int i, num;
-    uint16_t pch_dev_id = 0xffff;
-    uint8_t pch_rev_id;
-
-    num = ARRAY_SIZE(igd_combo_id_infos);
-    for (i = 0; i < num; i++) {
-        if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
-            pch_dev_id = igd_combo_id_infos[i].pch_device_id;
-            pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
-        }
-    }
-
-    if (pch_dev_id == 0xffff) {
-        return;
-    }
-
-    /* Currently IGD drivers always need to access PCH by 1f.0. */
-    bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
-                                   "igd-passthrough-isa-bridge");
-
-    /*
-     * Note that vendor id is always PCI_VENDOR_ID_INTEL.
-     */
-    if (!bridge_dev) {
-        fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
-        return;
-    }
-    pci_config_set_device_id(bridge_dev->config, pch_dev_id);
-    pci_config_set_revision(bridge_dev->config, pch_rev_id);
-}
-
 static void isapc_machine_options(MachineClass *m)
 {
     m->desc = "ISA-only PC";
diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index f6e3f7a..96b679d 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -123,10 +123,118 @@ static const TypeInfo igd_passthrough_q35_info = {
     .class_init    = igd_passthrough_q35_class_init,
 };
 
+typedef struct {
+    uint16_t gpu_device_id;
+    uint16_t pch_device_id;
+    uint8_t pch_revision_id;
+} IGDDeviceIDInfo;
+
+/* In real world different GPU should have different PCH. But actually
+ * the different PCH DIDs likely map to different PCH SKUs. We do the
+ * same thing for the GPU. For PCH, the different SKUs are going to be
+ * all the same silicon design and implementation, just different
+ * features turn on and off with fuses. The SW interfaces should be
+ * consistent across all SKUs in a given family (eg LPT). But just same
+ * features may not be supported.
+ *
+ * Most of these different PCH features probably don't matter to the
+ * Gfx driver, but obviously any difference in display port connections
+ * will so it should be fine with any PCH in case of passthrough.
+ *
+ * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
+ * scenarios, 0x9cc3 for BDW(Broadwell).
+ */
+static const IGDDeviceIDInfo igd_combo_id_infos[] = {
+    /* HSW Classic */
+    {0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */
+    {0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */
+    {0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */
+    {0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */
+    {0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */
+    /* HSW ULT */
+    {0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */
+    {0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */
+    {0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */
+    {0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */
+    {0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */
+    {0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */
+    /* HSW CRW */
+    {0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */
+    {0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */
+    /* HSW Server */
+    {0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */
+    /* HSW SRVR */
+    {0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */
+    /* BSW */
+    {0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */
+    {0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */
+    {0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */
+    {0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */
+    {0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */
+    {0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */
+    {0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */
+    {0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */
+    {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */
+    {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */
+    {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */
+};
+
+static void isa_bridge_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    dc->desc        = "ISA bridge faked to support IGD PT";
+    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->class_id     = PCI_CLASS_BRIDGE_ISA;
+};
+
+static TypeInfo igd_passthrough_isa_bridge_info = {
+    .name          = "igd-passthrough-isa-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init = isa_bridge_class_init,
+};
+
+void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
+{
+    struct PCIDevice *bridge_dev;
+    int i, num;
+    uint16_t pch_dev_id = 0xffff;
+    uint8_t pch_rev_id;
+
+    num = ARRAY_SIZE(igd_combo_id_infos);
+    for (i = 0; i < num; i++) {
+        if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
+            pch_dev_id = igd_combo_id_infos[i].pch_device_id;
+            pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
+        }
+    }
+
+    if (pch_dev_id == 0xffff) {
+        return;
+    }
+
+    /* Currently IGD drivers always need to access PCH by 1f.0. */
+    bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
+                                   "igd-passthrough-isa-bridge");
+
+    /*
+     * Note that vendor id is always PCI_VENDOR_ID_INTEL.
+     */
+    if (!bridge_dev) {
+        fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
+        return;
+    }
+    pci_config_set_device_id(bridge_dev->config, pch_dev_id);
+    pci_config_set_revision(bridge_dev->config, pch_rev_id);
+}
+
 static void igd_register_types(void)
 {
     type_register_static(&igd_passthrough_i440fx_info);
     type_register_static(&igd_passthrough_q35_info);
+    type_register_static(&igd_passthrough_isa_bridge_info);
 }
 
 type_init(igd_register_types)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v2 10/10] igd: handle igd-passthrough-isa-bridge setup in realize()
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel
  Cc: igvt-g, xen-devel, Eduardo Habkost, Stefano Stabellini,
	Gerd Hoffmann, vfio-users

That way a simple '-device igd-passthrough-isa-bridge,addr=1f' will
do the setup.

Also instead of looking up reasonable PCI IDs based on the graphic
device id simply copy over the ids from the host, thereby reusing the
infrastructure we have in place for the igd host bridges.  Less code,
and should be more robust as we don't have to maintain the id table
to keep things going.

Note that igd-passthrough-isa-bridge will be needed for '-machine pc'
only.  For q35 the plan is https://lkml.org/lkml/2015/11/26/183 (should
land in the next merge window, i.e. linux 4.5).

TODO: Figure if and how we are going to add this to the virtual machine
automatically.  The options I see are:

  (1) Nothing automatic, users must add the device manually.  This is
      what you get with this patch, except when running on xen.
  (2) Do it the xen way, let the pci pass-thru code add it when it
      finds a igd device (i.e. vfio-pci for kvm).  It's a bit ugly
      though, and it also has the problem that pc and q35 machine
      types have different needs here.
  (3) Let machine init do it in case igd-passthru=on is set.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pci-host/igd.c | 115 +++++++++++++-----------------------------------------
 1 file changed, 28 insertions(+), 87 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index 96b679d..2887b31 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -123,111 +123,52 @@ static const TypeInfo igd_passthrough_q35_info = {
     .class_init    = igd_passthrough_q35_class_init,
 };
 
-typedef struct {
-    uint16_t gpu_device_id;
-    uint16_t pch_device_id;
-    uint8_t pch_revision_id;
-} IGDDeviceIDInfo;
-
-/* In real world different GPU should have different PCH. But actually
- * the different PCH DIDs likely map to different PCH SKUs. We do the
- * same thing for the GPU. For PCH, the different SKUs are going to be
- * all the same silicon design and implementation, just different
- * features turn on and off with fuses. The SW interfaces should be
- * consistent across all SKUs in a given family (eg LPT). But just same
- * features may not be supported.
- *
- * Most of these different PCH features probably don't matter to the
- * Gfx driver, but obviously any difference in display port connections
- * will so it should be fine with any PCH in case of passthrough.
- *
- * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
- * scenarios, 0x9cc3 for BDW(Broadwell).
- */
-static const IGDDeviceIDInfo igd_combo_id_infos[] = {
-    /* HSW Classic */
-    {0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */
-    {0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */
-    {0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */
-    {0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */
-    {0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */
-    /* HSW ULT */
-    {0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */
-    {0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */
-    {0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */
-    {0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */
-    {0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */
-    {0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */
-    /* HSW CRW */
-    {0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */
-    {0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */
-    /* HSW Server */
-    {0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */
-    /* HSW SRVR */
-    {0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */
-    /* BSW */
-    {0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */
-    {0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */
-    {0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */
-    {0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */
-    {0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */
-    {0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */
-    {0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */
-    {0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */
-    {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */
-    {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */
-    {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */
+static const IGDHostInfo igd_isa_bridge_infos[] = {
+    {PCI_VENDOR_ID,           2},
+    {PCI_DEVICE_ID,           2},
+    {PCI_REVISION_ID,         2},
+    {PCI_SUBSYSTEM_VENDOR_ID, 2},
+    {PCI_SUBSYSTEM_ID,        2},
 };
 
+static void igd_pt_isa_bridge_realize(PCIDevice *pci_dev, Error **errp)
+{
+    Error *err = NULL;
+
+    if (pci_dev->devfn != PCI_DEVFN(0x1f, 0)) {
+        error_setg(errp, "igd isa bridge must have address 1f.0");
+        return;
+    }
+
+    host_pci_config_copy(pci_dev, "0000:00:1f.0",
+                         igd_isa_bridge_infos,
+                         ARRAY_SIZE(igd_isa_bridge_infos),
+                         &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+}
+
 static void isa_bridge_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    dc->desc        = "ISA bridge faked to support IGD PT";
-    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->realize      = igd_pt_isa_bridge_realize;
     k->class_id     = PCI_CLASS_BRIDGE_ISA;
+    dc->desc        = "ISA bridge faked to support IGD PT";
 };
 
 static TypeInfo igd_passthrough_isa_bridge_info = {
     .name          = "igd-passthrough-isa-bridge",
     .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIDevice),
     .class_init = isa_bridge_class_init,
 };
 
 void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
 {
-    struct PCIDevice *bridge_dev;
-    int i, num;
-    uint16_t pch_dev_id = 0xffff;
-    uint8_t pch_rev_id;
-
-    num = ARRAY_SIZE(igd_combo_id_infos);
-    for (i = 0; i < num; i++) {
-        if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
-            pch_dev_id = igd_combo_id_infos[i].pch_device_id;
-            pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
-        }
-    }
-
-    if (pch_dev_id == 0xffff) {
-        return;
-    }
-
-    /* Currently IGD drivers always need to access PCH by 1f.0. */
-    bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
-                                   "igd-passthrough-isa-bridge");
-
-    /*
-     * Note that vendor id is always PCI_VENDOR_ID_INTEL.
-     */
-    if (!bridge_dev) {
-        fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
-        return;
-    }
-    pci_config_set_device_id(bridge_dev->config, pch_dev_id);
-    pci_config_set_revision(bridge_dev->config, pch_rev_id);
+    pci_create_simple(bus, PCI_DEVFN(0x1f, 0), "igd-passthrough-isa-bridge");
 }
 
 static void igd_register_types(void)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 10/10] igd: handle igd-passthrough-isa-bridge setup in realize()
@ 2015-12-14 11:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 11:39 UTC (permalink / raw)
  To: qemu-devel-qX2TKyscuCcdnm+yROfE0A
  Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR, Eduardo Habkost,
	Stefano Stabellini, vfio-users-H+wXaHxf7aLQT0dZR+AlfA

That way a simple '-device igd-passthrough-isa-bridge,addr=1f' will
do the setup.

Also instead of looking up reasonable PCI IDs based on the graphic
device id simply copy over the ids from the host, thereby reusing the
infrastructure we have in place for the igd host bridges.  Less code,
and should be more robust as we don't have to maintain the id table
to keep things going.

Note that igd-passthrough-isa-bridge will be needed for '-machine pc'
only.  For q35 the plan is https://lkml.org/lkml/2015/11/26/183 (should
land in the next merge window, i.e. linux 4.5).

TODO: Figure if and how we are going to add this to the virtual machine
automatically.  The options I see are:

  (1) Nothing automatic, users must add the device manually.  This is
      what you get with this patch, except when running on xen.
  (2) Do it the xen way, let the pci pass-thru code add it when it
      finds a igd device (i.e. vfio-pci for kvm).  It's a bit ugly
      though, and it also has the problem that pc and q35 machine
      types have different needs here.
  (3) Let machine init do it in case igd-passthru=on is set.

Signed-off-by: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 hw/pci-host/igd.c | 115 +++++++++++++-----------------------------------------
 1 file changed, 28 insertions(+), 87 deletions(-)

diff --git a/hw/pci-host/igd.c b/hw/pci-host/igd.c
index 96b679d..2887b31 100644
--- a/hw/pci-host/igd.c
+++ b/hw/pci-host/igd.c
@@ -123,111 +123,52 @@ static const TypeInfo igd_passthrough_q35_info = {
     .class_init    = igd_passthrough_q35_class_init,
 };
 
-typedef struct {
-    uint16_t gpu_device_id;
-    uint16_t pch_device_id;
-    uint8_t pch_revision_id;
-} IGDDeviceIDInfo;
-
-/* In real world different GPU should have different PCH. But actually
- * the different PCH DIDs likely map to different PCH SKUs. We do the
- * same thing for the GPU. For PCH, the different SKUs are going to be
- * all the same silicon design and implementation, just different
- * features turn on and off with fuses. The SW interfaces should be
- * consistent across all SKUs in a given family (eg LPT). But just same
- * features may not be supported.
- *
- * Most of these different PCH features probably don't matter to the
- * Gfx driver, but obviously any difference in display port connections
- * will so it should be fine with any PCH in case of passthrough.
- *
- * So currently use one PCH version, 0x8c4e, to cover all HSW(Haswell)
- * scenarios, 0x9cc3 for BDW(Broadwell).
- */
-static const IGDDeviceIDInfo igd_combo_id_infos[] = {
-    /* HSW Classic */
-    {0x0402, 0x8c4e, 0x04}, /* HSWGT1D, HSWD_w7 */
-    {0x0406, 0x8c4e, 0x04}, /* HSWGT1M, HSWM_w7 */
-    {0x0412, 0x8c4e, 0x04}, /* HSWGT2D, HSWD_w7 */
-    {0x0416, 0x8c4e, 0x04}, /* HSWGT2M, HSWM_w7 */
-    {0x041E, 0x8c4e, 0x04}, /* HSWGT15D, HSWD_w7 */
-    /* HSW ULT */
-    {0x0A06, 0x8c4e, 0x04}, /* HSWGT1UT, HSWM_w7 */
-    {0x0A16, 0x8c4e, 0x04}, /* HSWGT2UT, HSWM_w7 */
-    {0x0A26, 0x8c4e, 0x06}, /* HSWGT3UT, HSWM_w7 */
-    {0x0A2E, 0x8c4e, 0x04}, /* HSWGT3UT28W, HSWM_w7 */
-    {0x0A1E, 0x8c4e, 0x04}, /* HSWGT2UX, HSWM_w7 */
-    {0x0A0E, 0x8c4e, 0x04}, /* HSWGT1ULX, HSWM_w7 */
-    /* HSW CRW */
-    {0x0D26, 0x8c4e, 0x04}, /* HSWGT3CW, HSWM_w7 */
-    {0x0D22, 0x8c4e, 0x04}, /* HSWGT3CWDT, HSWD_w7 */
-    /* HSW Server */
-    {0x041A, 0x8c4e, 0x04}, /* HSWSVGT2, HSWD_w7 */
-    /* HSW SRVR */
-    {0x040A, 0x8c4e, 0x04}, /* HSWSVGT1, HSWD_w7 */
-    /* BSW */
-    {0x1606, 0x9cc3, 0x03}, /* BDWULTGT1, BDWM_w7 */
-    {0x1616, 0x9cc3, 0x03}, /* BDWULTGT2, BDWM_w7 */
-    {0x1626, 0x9cc3, 0x03}, /* BDWULTGT3, BDWM_w7 */
-    {0x160E, 0x9cc3, 0x03}, /* BDWULXGT1, BDWM_w7 */
-    {0x161E, 0x9cc3, 0x03}, /* BDWULXGT2, BDWM_w7 */
-    {0x1602, 0x9cc3, 0x03}, /* BDWHALOGT1, BDWM_w7 */
-    {0x1612, 0x9cc3, 0x03}, /* BDWHALOGT2, BDWM_w7 */
-    {0x1622, 0x9cc3, 0x03}, /* BDWHALOGT3, BDWM_w7 */
-    {0x162B, 0x9cc3, 0x03}, /* BDWHALO28W, BDWM_w7 */
-    {0x162A, 0x9cc3, 0x03}, /* BDWGT3WRKS, BDWM_w7 */
-    {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */
+static const IGDHostInfo igd_isa_bridge_infos[] = {
+    {PCI_VENDOR_ID,           2},
+    {PCI_DEVICE_ID,           2},
+    {PCI_REVISION_ID,         2},
+    {PCI_SUBSYSTEM_VENDOR_ID, 2},
+    {PCI_SUBSYSTEM_ID,        2},
 };
 
+static void igd_pt_isa_bridge_realize(PCIDevice *pci_dev, Error **errp)
+{
+    Error *err = NULL;
+
+    if (pci_dev->devfn != PCI_DEVFN(0x1f, 0)) {
+        error_setg(errp, "igd isa bridge must have address 1f.0");
+        return;
+    }
+
+    host_pci_config_copy(pci_dev, "0000:00:1f.0",
+                         igd_isa_bridge_infos,
+                         ARRAY_SIZE(igd_isa_bridge_infos),
+                         &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+}
+
 static void isa_bridge_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    dc->desc        = "ISA bridge faked to support IGD PT";
-    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->realize      = igd_pt_isa_bridge_realize;
     k->class_id     = PCI_CLASS_BRIDGE_ISA;
+    dc->desc        = "ISA bridge faked to support IGD PT";
 };
 
 static TypeInfo igd_passthrough_isa_bridge_info = {
     .name          = "igd-passthrough-isa-bridge",
     .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIDevice),
     .class_init = isa_bridge_class_init,
 };
 
 void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
 {
-    struct PCIDevice *bridge_dev;
-    int i, num;
-    uint16_t pch_dev_id = 0xffff;
-    uint8_t pch_rev_id;
-
-    num = ARRAY_SIZE(igd_combo_id_infos);
-    for (i = 0; i < num; i++) {
-        if (gpu_dev_id == igd_combo_id_infos[i].gpu_device_id) {
-            pch_dev_id = igd_combo_id_infos[i].pch_device_id;
-            pch_rev_id = igd_combo_id_infos[i].pch_revision_id;
-        }
-    }
-
-    if (pch_dev_id == 0xffff) {
-        return;
-    }
-
-    /* Currently IGD drivers always need to access PCH by 1f.0. */
-    bridge_dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
-                                   "igd-passthrough-isa-bridge");
-
-    /*
-     * Note that vendor id is always PCI_VENDOR_ID_INTEL.
-     */
-    if (!bridge_dev) {
-        fprintf(stderr, "set igd-passthrough-isa-bridge failed!\n");
-        return;
-    }
-    pci_config_set_device_id(bridge_dev->config, pch_dev_id);
-    pci_config_set_revision(bridge_dev->config, pch_rev_id);
+    pci_create_simple(bus, PCI_DEVFN(0x1f, 0), "igd-passthrough-isa-bridge");
 }
 
 static void igd_register_types(void)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global
  2015-12-14 11:39   ` Gerd Hoffmann
@ 2015-12-17 17:45     ` Eduardo Habkost
  -1 siblings, 0 replies; 30+ messages in thread
From: Eduardo Habkost @ 2015-12-17 17:45 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: igvt-g, xen-devel, Stefano Stabellini, qemu-devel, vfio-users,
	Paolo Bonzini

On Mon, Dec 14, 2015 at 12:39:34PM +0100, Gerd Hoffmann wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/xen/xen_pt.h |  3 +--
>  vl.c            | 10 ----------
>  2 files changed, 1 insertion(+), 12 deletions(-)
> 
> diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
> index c545280..6d8702b 100644
> --- a/hw/xen/xen_pt.h
> +++ b/hw/xen/xen_pt.h
> @@ -320,10 +320,9 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
>                                              unsigned int domain,
>                                              unsigned int bus, unsigned int slot,
>                                              unsigned int function);
> -extern bool has_igd_gfx_passthru;
>  static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
>  {
> -    return (has_igd_gfx_passthru
> +    return (qdev_get_machine->igd_gfx_passthru
>              && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
>  }

Doesn't compile:

qemu/hw/xen/xen_pt.h: In function ‘is_igd_vga_passthrough’:
qemu/hw/xen/xen_pt.h:325:29: error: request for member ‘igd_gfx_passthru’ in something not a structure or union
     return (qdev_get_machine->igd_gfx_passthru
                             ^

-- 
Eduardo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global
@ 2015-12-17 17:45     ` Eduardo Habkost
  0 siblings, 0 replies; 30+ messages in thread
From: Eduardo Habkost @ 2015-12-17 17:45 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: igvt-g, xen-devel, Stefano Stabellini, qemu-devel, vfio-users,
	Paolo Bonzini

On Mon, Dec 14, 2015 at 12:39:34PM +0100, Gerd Hoffmann wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/xen/xen_pt.h |  3 +--
>  vl.c            | 10 ----------
>  2 files changed, 1 insertion(+), 12 deletions(-)
> 
> diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
> index c545280..6d8702b 100644
> --- a/hw/xen/xen_pt.h
> +++ b/hw/xen/xen_pt.h
> @@ -320,10 +320,9 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
>                                              unsigned int domain,
>                                              unsigned int bus, unsigned int slot,
>                                              unsigned int function);
> -extern bool has_igd_gfx_passthru;
>  static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
>  {
> -    return (has_igd_gfx_passthru
> +    return (qdev_get_machine->igd_gfx_passthru
>              && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
>  }

Doesn't compile:

qemu/hw/xen/xen_pt.h: In function ‘is_igd_vga_passthrough’:
qemu/hw/xen/xen_pt.h:325:29: error: request for member ‘igd_gfx_passthru’ in something not a structure or union
     return (qdev_get_machine->igd_gfx_passthru
                             ^

-- 
Eduardo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global
  2015-12-17 17:45     ` Eduardo Habkost
@ 2015-12-18  7:46       ` Gerd Hoffmann
  -1 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-18  7:46 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: igvt-g, xen-devel, Stefano Stabellini, qemu-devel, vfio-users,
	Paolo Bonzini

[-- Attachment #1: Type: text/plain, Size: 473 bytes --]

> > +    return (qdev_get_machine->igd_gfx_passthru
> >              && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
> >  }
> 
> Doesn't compile:
> 
> qemu/hw/xen/xen_pt.h: In function ‘is_igd_vga_passthrough’:
> qemu/hw/xen/xen_pt.h:325:29: error: request for member ‘igd_gfx_passthru’ in something not a structure or union
>      return (qdev_get_machine->igd_gfx_passthru

Incremental fix attached (will squash into v2).

cheers,
  Gerd


[-- Attachment #2: 0001-fixup-build-on-xen.patch --]
[-- Type: text/x-patch, Size: 1130 bytes --]

From b30226140f80202c4d2dda23acae9533aba6136b Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 18 Dec 2015 08:44:48 +0100
Subject: [PATCH] [fixup] build on xen

---
 hw/xen/xen_pt.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 6d8702b..680fe6e 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -4,6 +4,7 @@
 #include "qemu-common.h"
 #include "hw/xen/xen_common.h"
 #include "hw/pci/pci.h"
+#include "hw/boards.h"
 #include "xen-host-pci-device.h"
 
 void xen_pt_log(const PCIDevice *d, const char *f, ...) GCC_FMT_ATTR(2, 3);
@@ -322,7 +323,8 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
                                             unsigned int function);
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
-    return (qdev_get_machine->igd_gfx_passthru
+    MachineState *machine = MACHINE(qdev_get_machine());
+    return (machine->igd_gfx_passthru
             && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
 }
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global
@ 2015-12-18  7:46       ` Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-18  7:46 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: igvt-g, xen-devel, Stefano Stabellini, qemu-devel, vfio-users,
	Paolo Bonzini

[-- Attachment #1: Type: text/plain, Size: 473 bytes --]

> > +    return (qdev_get_machine->igd_gfx_passthru
> >              && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
> >  }
> 
> Doesn't compile:
> 
> qemu/hw/xen/xen_pt.h: In function ‘is_igd_vga_passthrough’:
> qemu/hw/xen/xen_pt.h:325:29: error: request for member ‘igd_gfx_passthru’ in something not a structure or union
>      return (qdev_get_machine->igd_gfx_passthru

Incremental fix attached (will squash into v2).

cheers,
  Gerd


[-- Attachment #2: 0001-fixup-build-on-xen.patch --]
[-- Type: text/x-patch, Size: 1130 bytes --]

From b30226140f80202c4d2dda23acae9533aba6136b Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 18 Dec 2015 08:44:48 +0100
Subject: [PATCH] [fixup] build on xen

---
 hw/xen/xen_pt.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 6d8702b..680fe6e 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -4,6 +4,7 @@
 #include "qemu-common.h"
 #include "hw/xen/xen_common.h"
 #include "hw/pci/pci.h"
+#include "hw/boards.h"
 #include "xen-host-pci-device.h"
 
 void xen_pt_log(const PCIDevice *d, const char *f, ...) GCC_FMT_ATTR(2, 3);
@@ -322,7 +323,8 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
                                             unsigned int function);
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
-    return (qdev_get_machine->igd_gfx_passthru
+    MachineState *machine = MACHINE(qdev_get_machine());
+    return (machine->igd_gfx_passthru
             && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
 }
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel]  [PATCH] ehci: make idt processing more robust
@ 2016-04-17 15:58 Jon Doe
  0 siblings, 0 replies; 30+ messages in thread
From: Jon Doe @ 2016-04-17 15:58 UTC (permalink / raw)
  To: kraxel, qemu-devel

This patch causes a regression in FreeBSD guests. Kernel dmesg reports:

usbus3: Run timeout
ehci0: USB init failed err=18

and USB 2.0 passthrough does not work. USB 1.0 still works though.

On a (possibly) related note, choosing any machine type above
pc-i440fx-2.0 causes 100% CPU in host.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH] ehci: make idt processing more robust
@ 2015-12-14 10:56 Gerd Hoffmann
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd Hoffmann @ 2015-12-14 10:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: luodalongde, Gerd Hoffmann, ppandit

Make ehci_process_itd return an error in case we didn't do any actual
iso transfer because we've found no active transaction.  That'll avoid
ehci happily run in circles forever if the guest builds a loop out of
idts.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Tested-by: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-ehci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 4e2161b..d07f228 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1389,7 +1389,7 @@ static int ehci_process_itd(EHCIState *ehci,
 {
     USBDevice *dev;
     USBEndpoint *ep;
-    uint32_t i, len, pid, dir, devaddr, endp;
+    uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
     uint32_t pg, off, ptr1, ptr2, max, mult;
 
     ehci->periodic_sched_active = PERIODIC_ACTIVE;
@@ -1479,9 +1479,10 @@ static int ehci_process_itd(EHCIState *ehci,
                 ehci_raise_irq(ehci, USBSTS_INT);
             }
             itd->transact[i] &= ~ITD_XACT_ACTIVE;
+            xfers++;
         }
     }
-    return 0;
+    return xfers ? 0 : -1;
 }
 
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2016-04-17 15:58 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-14 11:39 [Qemu-devel] [PATCH v2 00/10] igd passthrough chipset tweaks Gerd Hoffmann
2015-12-14 11:39 ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH] ehci: make idt processing more robust Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 01/10] pc: wire up TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE for !xen Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 02/10] pc: remove has_igd_gfx_passthru global Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-17 17:45   ` [Qemu-devel] " Eduardo Habkost
2015-12-17 17:45     ` Eduardo Habkost
2015-12-18  7:46     ` [Qemu-devel] " Gerd Hoffmann
2015-12-18  7:46       ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 03/10] pc: move igd support code to igd.c Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 04/10] igd: switch TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE to realize Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 05/10] igd: TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE: call parent realize Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 06/10] igd: use defines for standard pci config space offsets Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 07/10] igd: revamp host config read Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 08/10] igd: add q35 support Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 09/10] igd: move igd-passthrough-isa-bridge to igd.c too Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
2015-12-14 11:39 ` [Qemu-devel] [PATCH v2 10/10] igd: handle igd-passthrough-isa-bridge setup in realize() Gerd Hoffmann
2015-12-14 11:39   ` Gerd Hoffmann
  -- strict thread matches above, loose matches on Subject: below --
2016-04-17 15:58 [Qemu-devel] [PATCH] ehci: make idt processing more robust Jon Doe
2015-12-14 10:56 Gerd Hoffmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.