Skip to contentSkip to conversation

xen: add Intel IGD passthrough support

PATCH Superseded Tiejun Chen 12 participants 75 messages May 16, 2014 – Jun 30, 2014

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover xen: add Intel IGD passthrough support

v2:

* rebase on current qemu tree.
* retrieve VGA bios from sysfs properly.
* redefine some function name.
* introduce bitmap to manage registe/runregister pci dev, and provide a common way to reserve some specific devfn.
* introduce is_igd_passthrough() to make sure we touch physical host bridge only in IGD case.
* We should return zero as an invalid address value while calling igd_read_opregion().

Additionally, now its also not necessary to recompile seabios with some extra steps like v1.

The following patches are ported partially from Xen Qemu-traditional branch which are adding Intel IGD passthrough supporting to Qemu upstream.

To pass through IGD to guest, user need to add following lines in Xen config file:
gfx_passthru=1
pci=['00:02.0 <at> 2']

Now successfully boot Ubuntu 14.04 guests with IGD assigned in Haswell desktop with Latest Xen + Qemu upstream.

----------------------------------------------------------------
Tiejun Chen (5):
pci: use bitmap to manage registe/runregister pci device
pci: provide a way to reserve some specific devfn xen, gfx passthrough: reserve 00:02.0 for INTEL IGD xen, gfx passthrough: create intel isa bridge xen, gfx passthrough: create host bridge to passthrough

Yang Zhang (3):
xen, gfx passthrough: basic graphics passthrough support xen, gfx passthrough: support Intel IGD passthrough with VT-D xen, gfx passthrough: add opregion mapping

 hw/pci-host/piix.c           |  64 ++++++++++++++++++++-
 hw/pci/pci.c                 |  23 +++++++-
 hw/xen/Makefile.objs         |   2 +-
 hw/xen/xen-host-pci-device.c |   5 ++
 hw/xen/xen-host-pci-device.h |   1 +
 hw/xen/xen_pt.c              |  10 ++++
 hw/xen/xen_pt.h              |  12 +++-
 hw/xen/xen_pt_config_init.c  |  45 ++++++++++++++-
 hw/xen/xen_pt_graphics.c     | 435 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/pci/pci.h         |   1 +
 include/hw/pci/pci_bus.h     |   1 +
 qemu-options.hx              |   9 +++
 vl.c                         |  11 +++-
 13 files changed, 612 insertions(+), 7 deletions(-)
 create mode 100644 hw/xen/xen_pt_graphics.c

Thanks
Tiejun

#1 lore raw

PATCH v2 1/8 pci: use bitmap to manage registe/runregister pci device

It would be convenient to manage devfn directly in some cases.

---
v2:

* New patch

 hw/pci/pci.c             | 12 +++++++++++-
 include/hw/pci/pci_bus.h |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)
hw/pci/pci.c +11 -1
index 22fe5ee..ef944cf 100644
@@ -36,6 +36,7 @@
 #include "hw/pci/msix.h"
 #include "exec/address-spaces.h"
 #include "hw/hotplug.h"
+#include "qemu/bitmap.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -316,6 +317,12 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
     QLIST_INIT(&bus->child);
 
     pci_host_bus_register(bus, parent);
+
+    if (bus->pci_bdf_bitmap) {
+        g_free(bus->pci_bdf_bitmap);
+    }
+    bus->pci_bdf_bitmap = bitmap_new(PCI_SLOT_MAX * PCI_FUNC_MAX);
+    bitmap_clear(bus->pci_bdf_bitmap, 0, PCI_SLOT_MAX * PCI_FUNC_MAX);
 }
 
 bool pci_bus_is_express(PCIBus *bus)
@@ -798,6 +805,7 @@ static void pci_config_free(PCIDevice *pci_dev)
 
 static void do_pci_unregister_device(PCIDevice *pci_dev)
 {
+    clear_bit(pci_dev->devfn, pci_dev->bus->pci_bdf_bitmap);
     pci_dev->bus->devices[pci_dev->devfn] = NULL;
     pci_config_free(pci_dev);
 
@@ -817,8 +825,9 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
             devfn += PCI_FUNC_MAX) {
-            if (!bus->devices[devfn])
+            if (!test_bit(devfn, bus->pci_bdf_bitmap)) {
                 goto found;
+            }
         }
         error_report("PCI: no slot/function available for %s, all in use", name);
         return NULL;
@@ -840,6 +849,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                        name);
 
     pci_dev->devfn = devfn;
+    set_bit(pci_dev->devfn, pci_dev->bus->pci_bdf_bitmap);
     pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
     pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);
include/hw/pci/pci_bus.h +1 -0
index fabaeee..f2d8d53 100644
@@ -19,6 +19,7 @@ struct PCIBus {
     void *irq_opaque;
     PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
     PCIDevice *parent_dev;
+    unsigned long *pci_bdf_bitmap;
     MemoryRegion *address_space_mem;
     MemoryRegion *address_space_io;
 
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 2/8 pci: provide a way to reserve some specific devfn

In reply to Tiejun Chen

Sometime we may need to reserve some specific devfn since some vgabios or drivers have to work well with a fixed bdf.

---
v2:

* New patch

 hw/pci/pci.c         | 11 +++++++++++
 include/hw/pci/pci.h |  1 +
 2 files changed, 12 insertions(+)
hw/pci/pci.c +11 -0
index ef944cf..06b0c92 100644
@@ -813,6 +813,17 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
     memory_region_destroy(&pci_dev->bus_master_enable_region);
 }
 
+
+void pci_reserve_pci_devfn(PCIBus *bus, uint8_t devfn)
+{
+    int ret = test_and_set_bit(devfn, bus->pci_bdf_bitmap);
+    if (ret) {
+        error_report("PCI: %02x:%02x:%02x is not available to reserve.",
+                    pci_bus_num(bus), PCI_SLOT(devfn), PCI_FUNC(devfn));
+        return;
+    }
+}
+
 /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                          const char *name, int devfn)
include/hw/pci/pci.h +1 -0
index 8c25ae5..cbb174e 100644
@@ -342,6 +342,7 @@ void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          MemoryRegion *address_space_mem,
                          MemoryRegion *address_space_io,
                          uint8_t devfn_min, const char *typename);
+void pci_reserve_pci_devfn(PCIBus *bus, uint8_t devfn);
 PCIBus *pci_bus_new(DeviceState *parent, const char *name,
                     MemoryRegion *address_space_mem,
                     MemoryRegion *address_space_io,
Signature · 1 line
1.9.1
#3 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 2/8] pci: provide a way to reserve some specific devfn

Quoted 18 lines · Tiejun Chen

Sometime we may need to reserve some specific devfn since some vgabios or drivers have to work well with a fixed bdf.

---
v2:

* New patch

 hw/pci/pci.c         | 11 +++++++++++
 include/hw/pci/pci.h |  1 +
 2 files changed, 12 insertions(+)
hw/pci/pci.c +0 -0
index ef944cf..06b0c92 100644

hw/pci/pci.c static void do_pci_unregister_device(PCIDevice *pci_dev) · line 819

Quoted 7 lines
hw/pci/pci.c +4 -0
@@ -813,6 +813,17 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
     memory_region_destroy(&pci_dev->bus_master_enable_region);
 }
 
+
+void pci_reserve_pci_devfn(PCIBus *bus, uint8_t devfn)
+{
+    int ret = test_and_set_bit(devfn, bus->pci_bdf_bitmap);

unsigned int please.

hw/pci/pci.c static void do_pci_unregister_device(PCIDevice *pci_dev) · line 825

Quoted 6 lines
hw/pci/pci.c +6 -0
+    if (ret) {
+        error_report("PCI: %02x:%02x:%02x is not available to reserve.",
+                    pci_bus_num(bus), PCI_SLOT(devfn), PCI_FUNC(devfn));
+        return;
+    }
+}

Don't we want to return whether we are failed or not?

Quoted 24 lines
hw/pci/pci.c +1 -0
+
 /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                          const char *name, int devfn)
include/hw/pci/pci.h +1 -0
index 8c25ae5..cbb174e 100644
@@ -342,6 +342,7 @@ void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          MemoryRegion *address_space_mem,
                          MemoryRegion *address_space_io,
                          uint8_t devfn_min, const char *typename);
+void pci_reserve_pci_devfn(PCIBus *bus, uint8_t devfn);
 PCIBus *pci_bus_new(DeviceState *parent, const char *name,
                     MemoryRegion *address_space_mem,
                     MemoryRegion *address_space_io,
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#4 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 2/8] pci: provide a way to reserve some specific devfn

Quoted 31 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:07 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 2/8] pci: provide a way to reserve some specific devfn

hw/pci/pci.c static void do_pci_unregister_device(PCIDevice

Quoted 17 lines · Tiejun Chen

Sometime we may need to reserve some specific devfn since some vgabios or drivers have to work well with a fixed bdf.

---
v2:

* New patch

 hw/pci/pci.c         | 11 +++++++++++
 include/hw/pci/pci.h |  1 +
 2 files changed, 12 insertions(+)
hw/pci/pci.c +0 -0
@@ -813,6 +813,17 @@ static void do_pci_unregister_device(PCIDevice

*pci_dev)

Quoted 8 lines

hw/pci/pci.c static void do_pci_unregister_device(PCIDevice *pci_dev) · line 819

Quoted 6 lines
hw/pci/pci.c +3 -0
     memory_region_destroy(&pci_dev->bus_master_enable_region);
 }
 
+
+void pci_reserve_pci_devfn(PCIBus *bus, uint8_t devfn) {
+    int ret = test_and_set_bit(devfn, bus->pci_bdf_bitmap);

unsigned int please.

Fixed.

Quoted 9 lines

hw/pci/pci.c static void do_pci_unregister_device(PCIDevice *pci_dev)

Quoted 3 lines
hw/pci/pci.c +3 -0
+    if (ret) {
+        error_report("PCI: %02x:%02x:%02x is not available to reserve.",
+                    pci_bus_num(bus), PCI_SLOT(devfn),

PCI_FUNC(devfn));

hw/pci/pci.c static void do_pci_unregister_device(PCIDevice *pci_dev) · line 825

Quoted 3 lines
hw/pci/pci.c +3 -0
+        return;
+    }
+}

Don't we want to return whether we are failed or not?

Its my typo so I will remove that "return" simply.

Thanks
Tiejun

#5 lore raw

PATCH v2 3/8 xen, gfx passthrough: basic graphics passthrough support

In reply to Tiejun Chen

basic gfx passthrough support:
- add a vga type for gfx passthrough
- retrieve VGA bios from sysfs, then load it to guest 0xC0000
- register/unregister legacy VGA I/O ports and MMIOs for passthroughed gfx

The original patch is from Weidong Han <[email protected]>

---
v2:

* retrieve VGA bios from sysfs properly.
* redefine some function name.

 hw/xen/Makefile.objs         |   2 +-
 hw/xen/xen-host-pci-device.c |   5 ++
 hw/xen/xen-host-pci-device.h |   1 +
 hw/xen/xen_pt.c              |  10 +++
 hw/xen/xen_pt.h              |   4 +
 hw/xen/xen_pt_graphics.c     | 177 +++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx              |   9 +++
 vl.c                         |  11 ++-
 8 files changed, 217 insertions(+), 2 deletions(-)
 create mode 100644 hw/xen/xen_pt_graphics.c
hw/xen/Makefile.objs +1 -1
index a0ca0aa..77b7dae 100644
@@ -2,4 +2,4 @@
 common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
-obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
+obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o xen_pt_graphics.o
hw/xen/xen-host-pci-device.c +5 -0
index 743b37b..a54b7de 100644
@@ -376,6 +376,11 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
         goto error;
     }
     d->irq = v;
+    rc = xen_host_pci_get_hex_value(d, "class", &v);
+    if (rc) {
+        goto error;
+    }
+    d->class_code = v;
     d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
 
     return 0;
hw/xen/xen-host-pci-device.h +1 -0
index c2486f0..f1e1c30 100644
@@ -25,6 +25,7 @@ typedef struct XenHostPCIDevice {
 
     uint16_t vendor_id;
     uint16_t device_id;
+    uint32_t class_code;
     int irq;
 
     XenHostPCIIORegion io_regions[PCI_NUM_REGIONS - 1];
hw/xen/xen_pt.c +10 -0
index be4220b..a0113ea 100644
@@ -450,6 +450,7 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s)
                    d->rom.size, d->rom.base_addr);
     }
 
+    xen_pt_register_vga_regions(d);
     return 0;
 }
 
@@ -470,6 +471,8 @@ static void xen_pt_unregister_regions(XenPCIPassthroughState *s)
     if (d->rom.base_addr && d->rom.size) {
         memory_region_destroy(&s->rom);
     }
+
+    xen_pt_unregister_vga_regions(d);
 }
 
 /* region mapping */
@@ -693,6 +696,13 @@ static int xen_pt_initfn(PCIDevice *d)
     /* Handle real device's MMIO/PIO BARs */
     xen_pt_register_regions(s);
 
+    /* Setup VGA bios for passthroughed gfx */
+    if (xen_pt_setup_vga(&s->real_device) < 0) {
+        XEN_PT_ERR(d, "Setup VGA BIOS of passthroughed gfx failed!\n");
+        xen_host_pci_device_put(&s->real_device);
+        return -1;
+    }
+
     /* reinitialize each config register to be emulated */
     if (xen_pt_config_init(s)) {
         XEN_PT_ERR(d, "PCI Config space initialisation failed.\n");
hw/xen/xen_pt.h +4 -0
index 942dc60..4d3a18d 100644
@@ -298,5 +298,9 @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
     return s->msix && s->msix->bar_index == bar;
 }
 
+extern int xen_has_gfx_passthru;
+int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
+int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
+int xen_pt_setup_vga(XenHostPCIDevice *dev);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c new file +177 -0

177 lines not on this page · raw message

qemu-options.hx +9 -0
index 781af14..cece134 100644
@@ -1047,6 +1047,15 @@ STEXI
 Rotate graphical output some deg left (only PXA LCD).
 ETEXI
 
+DEF("gfx_passthru", 0, QEMU_OPTION_gfx_passthru,
+    "-gfx_passthru   enable Intel IGD passthrough by XEN\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -gfx_passthru
+@findex -gfx_passthru
+Enable Intel IGD passthrough by XEN
+ETEXI
+
 DEF("vga", HAS_ARG, QEMU_OPTION_vga,
     "-vga [std|cirrus|vmware|qxl|xenfb|tcx|cg3|none]\n"
     "                select video card type\n", QEMU_ARCH_ALL)
vl.c +10 -1
index 73e0661..c86e95f 100644
@@ -1436,6 +1436,13 @@ static void smp_parse(QemuOpts *opts)
 
 }
 
+/* We still need this for compatibility with XEN. */
+int xen_has_gfx_passthru;
+static void xen_gfx_passthru(const char *optarg)
+{
+    xen_has_gfx_passthru = 1;
+}
+
 static void configure_realtime(QemuOpts *opts)
 {
     bool enable_mlock;
@@ -2988,7 +2995,6 @@ int main(int argc, char **argv, char **envp)
     const char *trace_file = NULL;
     const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
                                         1024 * 1024;
-
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
     qemu_init_exec_dir(argv[0]);
@@ -3956,6 +3962,9 @@ int main(int argc, char **argv, char **envp)
                 }
                 configure_msg(opts);
                 break;
+            case QEMU_OPTION_gfx_passthru:
+                xen_gfx_passthru(optarg);
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
Signature · 1 line
1.9.1
#6 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Quoted 148 lines · Tiejun Chen

basic gfx passthrough support:
- add a vga type for gfx passthrough
- retrieve VGA bios from sysfs, then load it to guest 0xC0000
- register/unregister legacy VGA I/O ports and MMIOs for passthroughed gfx

The original patch is from Weidong Han <[email protected]>

---
v2:

* retrieve VGA bios from sysfs properly.
* redefine some function name.

 hw/xen/Makefile.objs         |   2 +-
 hw/xen/xen-host-pci-device.c |   5 ++
 hw/xen/xen-host-pci-device.h |   1 +
 hw/xen/xen_pt.c              |  10 +++
 hw/xen/xen_pt.h              |   4 +
 hw/xen/xen_pt_graphics.c     | 177 +++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx              |   9 +++
 vl.c                         |  11 ++-
 8 files changed, 217 insertions(+), 2 deletions(-)
 create mode 100644 hw/xen/xen_pt_graphics.c
hw/xen/Makefile.objs +1 -1
index a0ca0aa..77b7dae 100644
@@ -2,4 +2,4 @@
 common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
-obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
+obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o xen_pt_graphics.o
hw/xen/xen-host-pci-device.c +5 -0
index 743b37b..a54b7de 100644
@@ -376,6 +376,11 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
         goto error;
     }
     d->irq = v;
+    rc = xen_host_pci_get_hex_value(d, "class", &v);
+    if (rc) {
+        goto error;
+    }
+    d->class_code = v;
     d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
 
     return 0;
hw/xen/xen-host-pci-device.h +1 -0
index c2486f0..f1e1c30 100644
@@ -25,6 +25,7 @@ typedef struct XenHostPCIDevice {
 
     uint16_t vendor_id;
     uint16_t device_id;
+    uint32_t class_code;
     int irq;
 
     XenHostPCIIORegion io_regions[PCI_NUM_REGIONS - 1];
hw/xen/xen_pt.c +10 -0
index be4220b..a0113ea 100644
@@ -450,6 +450,7 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s)
                    d->rom.size, d->rom.base_addr);
     }
 
+    xen_pt_register_vga_regions(d);
     return 0;
 }
 
@@ -470,6 +471,8 @@ static void xen_pt_unregister_regions(XenPCIPassthroughState *s)
     if (d->rom.base_addr && d->rom.size) {
         memory_region_destroy(&s->rom);
     }
+
+    xen_pt_unregister_vga_regions(d);
 }
 
 /* region mapping */
@@ -693,6 +696,13 @@ static int xen_pt_initfn(PCIDevice *d)
     /* Handle real device's MMIO/PIO BARs */
     xen_pt_register_regions(s);
 
+    /* Setup VGA bios for passthroughed gfx */
+    if (xen_pt_setup_vga(&s->real_device) < 0) {
+        XEN_PT_ERR(d, "Setup VGA BIOS of passthroughed gfx failed!\n");
+        xen_host_pci_device_put(&s->real_device);
+        return -1;
+    }
+
     /* reinitialize each config register to be emulated */
     if (xen_pt_config_init(s)) {
         XEN_PT_ERR(d, "PCI Config space initialisation failed.\n");
hw/xen/xen_pt.h +4 -0
index 942dc60..4d3a18d 100644
@@ -298,5 +298,9 @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
     return s->msix && s->msix->bar_index == bar;
 }
 
+extern int xen_has_gfx_passthru;
+int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
+int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
+int xen_pt_setup_vga(XenHostPCIDevice *dev);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c new file +28 -0
new file mode 100644
index 0000000..e1f0724
@@ -0,0 +1,177 @@
+/*
+ * graphics passthrough
+ */
+#include "xen_pt.h"
+#include "xen-host-pci-device.h"
+#include "hw/xen/xen_backend.h"
+
+static int is_vga_passthrough(XenHostPCIDevice *dev)
+{
+    return (xen_has_gfx_passthru
+            && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
+}
+
+/*
+ * register VGA resources for the domain with assigned gfx
+ */
+int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
+{
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xA, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,

hw/xen/xen_pt_graphics.c line 38

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+            0x3C0, 0x20, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0x20,
+            DPCI_ADD_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region mapping failed\n");

It would be actually useful to know _which_ of them failed. Perhaps you could structure this a bit differently and do:

struct _args {
        uint32_t gport;
        uint32_t mport;
        uint32_t nport;
};
        struct _args args[3] = {{ 0x3B0, 0x3B0, 0xA }, {...}};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(args); i++) {
		ret = xc_domain_ioport_mapping(xen_xc, xen_domid, args[i].gport, args[i]..)
		if (ret) {
			XEN_PT_ERR_(NULL, "VGA region mapping of 0x%lx for 0x%x pages failed with rc:%d\n",
					... fill in the values)
			return ret;
	}	
Quoted 22 lines
hw/xen/xen_pt_graphics.c new file +22 -0
+    }
+
+    return ret;
+}
+
+/*
+ * unregister VGA resources for the domain with assigned gfx
+ */
+int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
+{
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xC, DPCI_REMOVE_MAPPING);
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
+            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
+

hw/xen/xen_pt_graphics.c line 70

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            20,
+            DPCI_REMOVE_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+    }
+

The same pattern as above.

hw/xen/xen_pt_graphics.c line 83

Quoted 13 lines
hw/xen/xen_pt_graphics.c new file +13 -0
+    return ret;
+}
+
+static int get_vgabios(unsigned char *buf, XenHostPCIDevice *dev)
+{
+    char rom_file[64];
+    FILE *fp;
+    uint8_t val;
+    struct stat st;
+    uint16_t magic = 0;
+
+    snprintf(rom_file, sizeof(rom_file),
+             "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom",

I think the format changed to be: /%04x:%02x:%02x.%d in Linux (see pci_setup_device in drivers/pci/probe.c) - not that it makes that much difference as the function is only up to 7.

hw/xen/xen_pt_graphics.c line 88

Quoted 5 lines
hw/xen/xen_pt_graphics.c new file +5 -0
+             dev->domain, dev->bus, dev->dev,
+             dev->func);
+
+    if (stat(rom_file, &st)) {
+        return -1;

ENODEV?

hw/xen/xen_pt_graphics.c line 94

Quoted 6 lines
hw/xen/xen_pt_graphics.c new file +6 -0
+    }
+
+    if (access(rom_file, F_OK)) {
+        XEN_PT_ERR(NULL, "pci-assign: Insufficient privileges for %s",
+                    rom_file);
+        return -1;

EPERM?

hw/xen/xen_pt_graphics.c line 99

Quoted 5 lines
hw/xen/xen_pt_graphics.c new file +5 -0
+    }
+
+    /* Write "1" to the ROM file to enable it */
+    fp = fopen(rom_file, "r+");
+    if (fp == NULL) {

EACCESS ?

Quoted 5 lines
hw/xen/xen_pt_graphics.c new file +5 -0
+        return -1;
+    }
+    val = 1;
+    if (fwrite(&val, 1, 1, fp) != 1) {
+        goto close_rom;

hw/xen/xen_pt_graphics.c line 114

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    /*
+     * Check if it a real bios extension.
+     * The magic number is 0xAA55.
+     */
+    if (fread(&magic, sizeof(magic), 1, fp)) {
+        goto close_rom;
+    }

Don't you want to do that before you write '1' in it?

Quoted 9 lines
hw/xen/xen_pt_graphics.c new file +9 -0
+
+    if (magic != 0xAA55) {
+        goto close_rom;
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    if (!fread(buf, 1, st.st_size, fp)) {
+        XEN_PT_ERR(NULL, "pci-assign: Cannot read from host %s", rom_file);
+        XEN_PT_LOG(NULL, "Device option ROM contents are probably invalid "

hw/xen/xen_pt_graphics.c line 133

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+                     "(check dmesg).\nSkip option ROM probe with rombar=0, "
+                     "or load from file with romfile=\n");
+    }
+
+close_rom:
+    /* Write "0" to disable ROM */
+    fseek(fp, 0, SEEK_SET);
+    val = 0;
+    if (!fwrite(&val, 1, 1, fp)) {
+        XEN_PT_LOG("%s\n", "Failed to disable pci-sysfs rom file");

Should we return -1? (after closing the file of course)

hw/xen/xen_pt_graphics.c line 136

Quoted 3 lines
hw/xen/xen_pt_graphics.c new file +3 -0
+    }
+    fclose(fp);
+    return st.st_size;

Ah, that is why your return -1! In that case I presume the caller of this function will check the 'errno' to find the underlaying issue

Quoted 12 lines
hw/xen/xen_pt_graphics.c new file +12 -0
+}
+
+/* Allocated 128K for the vga bios */
+#define VGA_BIOS_DEFAULT_SIZE (0x20000)
+
+int xen_pt_setup_vga(XenHostPCIDevice *dev)
+{
+    unsigned char *bios = NULL;
+    int bios_size = 0;
+    char *c = NULL;
+    char checksum = 0;
+    int rc = 0;

hw/xen/xen_pt_graphics.c line 158

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+
+    if (!is_vga_passthrough(dev)) {
+        return rc;
+    }
+
+    bios = g_malloc0(VGA_BIOS_DEFAULT_SIZE);
+
+    bios_size = get_vgabios(bios, dev);
+    if (bios_size == 0 || bios_size > VGA_BIOS_DEFAULT_SIZE) {
+        XEN_PT_ERR(NULL, "vga bios size (0x%x) is invalid!\n", bios_size);

Um, with an error code, the 'bios size (0xfffffffff)' is going to show up. Why don't you an extra code to check for this , like:

	if (bios_size < 0)
		XEN_PT_ERR(NULL,"Error %d (%s) getting BIOS!\n", errno, strerror(errno));
	else
		.. the other error.
Quoted 84 lines
hw/xen/xen_pt_graphics.c new file +19 -0
+        rc = -1;
 
+        goto out;
+    }
+
+    /* Adjust the bios checksum */
+    for (c = (char *)bios; c < ((char *)bios + bios_size); c++) {
+        checksum += *c;
+    }
+    if (checksum) {
+        bios[bios_size - 1] -= checksum;
+        XEN_PT_LOG(NULL, "vga bios checksum is adjusted!\n");
+    }
+
+    /* Currently we fixed this address as a primary. */
+    cpu_physical_memory_rw(0xc0000, bios, bios_size, 1);
+out:
+    g_free(bios);
+    return rc;
+}
qemu-options.hx +9 -0
index 781af14..cece134 100644
@@ -1047,6 +1047,15 @@ STEXI
 Rotate graphical output some deg left (only PXA LCD).
 ETEXI
 
+DEF("gfx_passthru", 0, QEMU_OPTION_gfx_passthru,
+    "-gfx_passthru   enable Intel IGD passthrough by XEN\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -gfx_passthru
+@findex -gfx_passthru
+Enable Intel IGD passthrough by XEN
+ETEXI
+
 DEF("vga", HAS_ARG, QEMU_OPTION_vga,
     "-vga [std|cirrus|vmware|qxl|xenfb|tcx|cg3|none]\n"
     "                select video card type\n", QEMU_ARCH_ALL)
vl.c +10 -1
index 73e0661..c86e95f 100644
@@ -1436,6 +1436,13 @@ static void smp_parse(QemuOpts *opts)
 
 }
 
+/* We still need this for compatibility with XEN. */
+int xen_has_gfx_passthru;
+static void xen_gfx_passthru(const char *optarg)
+{
+    xen_has_gfx_passthru = 1;
+}
+
 static void configure_realtime(QemuOpts *opts)
 {
     bool enable_mlock;
@@ -2988,7 +2995,6 @@ int main(int argc, char **argv, char **envp)
     const char *trace_file = NULL;
     const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
                                         1024 * 1024;
-
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
     qemu_init_exec_dir(argv[0]);
@@ -3956,6 +3962,9 @@ int main(int argc, char **argv, char **envp)
                 }
                 configure_msg(opts);
                 break;
+            case QEMU_OPTION_gfx_passthru:
+                xen_gfx_passthru(optarg);
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#7 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Quoted 12 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:06 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

[snip]

Quoted 34 lines
Quoted 13 lines
(quoted diff) +13 -0
+/*
+ * register VGA resources for the domain with assigned gfx  */ int
+xen_pt_register_vga_regions(XenHostPCIDevice *dev) {
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xA, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,

Review

Quoted 10 lines
(quoted diff) +10 -0
+            0x3C0, 0x20, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0x20,
+            DPCI_ADD_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region mapping failed\n");

It would be actually useful to know _which_ of them failed. Perhaps you could structure this a bit differently and do:

struct _args {
        uint32_t gport;
        uint32_t mport;
        uint32_t nport;
};
Quoted 13 lines
        struct _args args[3] = {{ 0x3B0, 0x3B0, 0xA }, {...}};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(args); i++) {
		ret = xc_domain_ioport_mapping(xen_xc, xen_domid, args[i].gport,
args[i]..)
		if (ret) {
			XEN_PT_ERR_(NULL, "VGA region mapping of 0x%lx for 0x%x
pages failed with rc:%d\n",
					... fill in the values)
			return ret;
	}

Looks good so what about this based on the original,

hw/xen/xen_pt_graphics.c +75 -32
@@ -14,34 +14,73 @@ static int is_vga_passthrough(XenHostPCIDevice *dev)
             && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
 }
 
+typedef struct VGARegion {
+    int type;           /* Memory or port I/O */
+    uint64_t guest_base_addr;
+    uint64_t machine_base_addr;
+    uint64_t size;    /* size of the region */
+    int rc;
+} VGARegion;
+
+#define IORESOURCE_IO           0x00000100
+#define IORESOURCE_MEM          0x00000200
+
+static struct VGARegion vga_args[] = {
+    {
+        .type = IORESOURCE_IO,
+        .guest_base_addr = 0x3B0,
+        .machine_base_addr = 0x3B0,
+        .size = 0xC,
+        .rc = -1,
+    },
+    {
+        .type = IORESOURCE_IO,
+        .guest_base_addr = 0x3C0,
+        .machine_base_addr = 0x3C0,
+        .size = 0x20,
+        .rc = -1,
+    },
+    {
+        .type = IORESOURCE_MEM,
+        .guest_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
+        .machine_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
+        .size = 0x20,
+        .rc = -1,
+    },
+};
+
 /*
  * register VGA resources for the domain with assigned gfx
  */
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
 {
-    int ret = 0;
+    int i = 0;
 
     if (!is_vga_passthrough(dev)) {
-        return ret;
+        return -1;
     }
 
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
-            0x3B0, 0xA, DPCI_ADD_MAPPING);
-
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
-            0x3C0, 0x20, DPCI_ADD_MAPPING);
-
-    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0x20,
-            DPCI_ADD_MAPPING);
+    for(i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
+        if (vga_args[i].type == IORESOURCE_IO) {
+            vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_ADD_MAPPING);
+        } else {
+            vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_ADD_MAPPING);
+        }
 
-    if (ret) {
-        XEN_PT_ERR(NULL, "VGA region mapping failed\n");
+        if (vga_args[i].rc) {
+            XEN_PT_ERR(NULL, "VGA %s mapping failed! (rc: %i)\n",
+                    vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory",
+                    vga_args[i].rc);
+        }
     }
 
-    return ret;
+    return 0;
 }
 
 /*
@@ -49,29 +88,33 @@ int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
  */
 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
 {
-    int ret = 0;
+    int i = 0;
 
     if (!is_vga_passthrough(dev)) {
-        return ret;
+        return -1;
     }
 
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
-            0x3B0, 0xC, DPCI_REMOVE_MAPPING);
-
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
-            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
-
-    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0xa0000 >> XC_PAGE_SHIFT,
-            20,
-            DPCI_REMOVE_MAPPING);
+    for(i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
+        if (vga_args[i].type == IORESOURCE_IO) {
+            vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_REMOVE_MAPPING);
+        } else {
+            vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_REMOVE_MAPPING);
+        }
 
-    if (ret) {
-        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+        if (vga_args[i].rc) {
+            XEN_PT_ERR(NULL, "VGA %s unmapping failed! (rc: %i)\n",
+                    vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory",
+                    vga_args[i].rc);
+        }
     }
 
-    return ret;
+    return 0;
 }
 
 static int get_vgabios(unsigned char *buf, XenHostPCIDevice *dev)
Quoted 25 lines
Quoted 25 lines
(quoted diff) +24 -0
+    }
+
+    return ret;
+}
+
+/*
+ * unregister VGA resources for the domain with assigned gfx  */ int
+xen_pt_unregister_vga_regions(XenHostPCIDevice *dev) {
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xC, DPCI_REMOVE_MAPPING);
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
+            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            20,
Quoted 9 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+            DPCI_REMOVE_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+    }
+

The same pattern as above.

See the above.

Quoted 8 lines
Quoted 8 lines
(quoted diff) +8 -0
+    return ret;
+}
+
+static int get_vgabios(unsigned char *buf, XenHostPCIDevice *dev) {
+    char rom_file[64];
+    FILE *fp;
+    uint8_t val;
+    struct stat st;
Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+    uint16_t magic = 0;
+
+    snprintf(rom_file, sizeof(rom_file),
+             "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom",

I think the format changed to be: /%04x:%02x:%02x.%d in Linux (see pci_setup_device in drivers/pci/probe.c) - not that it makes that much difference as the function is only up to 7.

Will improved this as you pointed.

Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +5 -0
+             dev->domain, dev->bus, dev->dev,
+             dev->func);
+
+    if (stat(rom_file, &st)) {
+        return -1;

ENODEV?

Fixed.

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +6 -0
+    }
+
+    if (access(rom_file, F_OK)) {
+        XEN_PT_ERR(NULL, "pci-assign: Insufficient privileges for %s",
+                    rom_file);
+        return -1;

EPERM?

Fixed.

Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+    }
+
+    /* Write "1" to the ROM file to enable it */
+    fp = fopen(rom_file, "r+");
+    if (fp == NULL) {

EACCESS ?

Fixed.

Quoted 16 lines
Quoted 5 lines
(quoted diff) +5 -0
+        return -1;
+    }
+    val = 1;
+    if (fwrite(&val, 1, 1, fp) != 1) {
+        goto close_rom;

Review

Quoted 10 lines
(quoted diff) +10 -0
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    /*
+     * Check if it a real bios extension.
+     * The magic number is 0xAA55.
+     */
+    if (fread(&magic, sizeof(magic), 1, fp)) {
+        goto close_rom;
+    }
Quoted 2 lines

Don't you want to do that before you write '1' in it?

Definitely, but I really did this above this line :)

Quoted 13 lines

Review

Quoted 8 lines
(quoted diff) +8 -0
+
+    if (magic != 0xAA55) {
+        goto close_rom;
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    if (!fread(buf, 1, st.st_size, fp)) {
+        XEN_PT_ERR(NULL, "pci-assign: Cannot read from host %s",

rom_file);

Quoted 1 line

+ XEN_PT_LOG(NULL, "Device option ROM contents are probably

invalid "

Quoted 1 line

+ "(check dmesg).\nSkip option ROM probe with

rombar=0, "

Quoted 12 lines

Review

Quoted 9 lines
(quoted diff) +9 -0
+                     "or load from file with romfile=\n");
+    }
+
+close_rom:
+    /* Write "0" to disable ROM */
+    fseek(fp, 0, SEEK_SET);
+    val = 0;
+    if (!fwrite(&val, 1, 1, fp)) {
+        XEN_PT_LOG("%s\n", "Failed to disable pci-sysfs rom file");

Should we return -1? (after closing the file of course)

Fixed.

Quoted 6 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+    }
+    fclose(fp);
+    return st.st_size;

Ah, that is why your return -1! In that case I presume the caller of this function will check the 'errno' to find the underlaying issue

I will modify something here and xen_pt_setup_vga(). Please see next version.

Thanks
Tiejun

#8 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Quoted 194 lines · Tiejun
Quoted 12 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:06 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

[snip]

Quoted 34 lines
Quoted 13 lines
(quoted diff) +13 -0
+/*
+ * register VGA resources for the domain with assigned gfx  */ int
+xen_pt_register_vga_regions(XenHostPCIDevice *dev) {
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xA, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,

Review

Quoted 10 lines
(quoted diff) +10 -0
+            0x3C0, 0x20, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0x20,
+            DPCI_ADD_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region mapping failed\n");

It would be actually useful to know _which_ of them failed. Perhaps you could structure this a bit differently and do:

struct _args {
        uint32_t gport;
        uint32_t mport;
        uint32_t nport;
};
Quoted 13 lines
        struct _args args[3] = {{ 0x3B0, 0x3B0, 0xA }, {...}};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(args); i++) {
		ret = xc_domain_ioport_mapping(xen_xc, xen_domid, args[i].gport,
args[i]..)
		if (ret) {
			XEN_PT_ERR_(NULL, "VGA region mapping of 0x%lx for 0x%x
pages failed with rc:%d\n",
					... fill in the values)
			return ret;
	}

Looks good so what about this based on the original,

hw/xen/xen_pt_graphics.c +69 -30
@@ -14,34 +14,73 @@ static int is_vga_passthrough(XenHostPCIDevice *dev)
             && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
 }
 
+typedef struct VGARegion {
+    int type;           /* Memory or port I/O */
+    uint64_t guest_base_addr;
+    uint64_t machine_base_addr;
+    uint64_t size;    /* size of the region */
+    int rc;
+} VGARegion;
+
+#define IORESOURCE_IO           0x00000100
+#define IORESOURCE_MEM          0x00000200
+
+static struct VGARegion vga_args[] = {
+    {
+        .type = IORESOURCE_IO,
+        .guest_base_addr = 0x3B0,
+        .machine_base_addr = 0x3B0,
+        .size = 0xC,
+        .rc = -1,
+    },
+    {
+        .type = IORESOURCE_IO,
+        .guest_base_addr = 0x3C0,
+        .machine_base_addr = 0x3C0,
+        .size = 0x20,
+        .rc = -1,
+    },
+    {
+        .type = IORESOURCE_MEM,
+        .guest_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
+        .machine_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
+        .size = 0x20,
+        .rc = -1,
+    },
+};
+
 /*
  * register VGA resources for the domain with assigned gfx
  */
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
 {
-    int ret = 0;
+    int i = 0;
 
     if (!is_vga_passthrough(dev)) {
-        return ret;
+        return -1;
     }
 
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
-            0x3B0, 0xA, DPCI_ADD_MAPPING);
-
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
-            0x3C0, 0x20, DPCI_ADD_MAPPING);
-
-    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0x20,
-            DPCI_ADD_MAPPING);
+    for(i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
+        if (vga_args[i].type == IORESOURCE_IO) {
+            vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_ADD_MAPPING);
+        } else {
+            vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_ADD_MAPPING);
+        }
 
-    if (ret) {
-        XEN_PT_ERR(NULL, "VGA region mapping failed\n");
+        if (vga_args[i].rc) {
+            XEN_PT_ERR(NULL, "VGA %s mapping failed! (rc: %i)\n",
+                    vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory",
+                    vga_args[i].rc);
+        }
     }
 
-    return ret;
+    return 0;
 }
 
 /*
@@ -49,29 +88,33 @@ int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
  */
 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
 {
-    int ret = 0;
+    int i = 0;
 
     if (!is_vga_passthrough(dev)) {
-        return ret;
+        return -1;
     }
 
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
-            0x3B0, 0xC, DPCI_REMOVE_MAPPING);
-
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
-            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
-
-    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0xa0000 >> XC_PAGE_SHIFT,
-            20,
-            DPCI_REMOVE_MAPPING);
+    for(i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
+        if (vga_args[i].type == IORESOURCE_IO) {
+            vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_REMOVE_MAPPING);
+        } else {
+            vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid,
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size, DPCI_REMOVE_MAPPING);
+        }
 
-    if (ret) {

hw/xen/xen_pt_graphics.c int xen_pt_register_vga_regions(XenHostPCIDevice *dev) · line 117

Quoted 10 lines
hw/xen/xen_pt_graphics.c +6 -2
-        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+        if (vga_args[i].rc) {
+            XEN_PT_ERR(NULL, "VGA %s unmapping failed! (rc: %i)\n",
+                    vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory",
+                    vga_args[i].rc);
+        }
     }
 
-    return ret;
+    return 0;

I think you still need to return a non-zero value in case of failure.

Quoted 40 lines
hw/xen/xen_pt_graphics.c +0 -0
 }
 
 static int get_vgabios(unsigned char *buf, XenHostPCIDevice *dev)
Quoted 27 lines
Quoted 27 lines
(quoted diff) +24 -0
+    }
+
+    return ret;
+}
+
+/*
+ * unregister VGA resources for the domain with assigned gfx  */ int
+xen_pt_unregister_vga_regions(XenHostPCIDevice *dev) {
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xC, DPCI_REMOVE_MAPPING);
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
+            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            20,
Quoted 9 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+            DPCI_REMOVE_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+    }
+

The same pattern as above.

Quoted 3 lines

See the above.

Quoted 1 line
Quoted 1 line

+ return ret;

I think you still need to return a non-zero value in case of failure.

Quoted 113 lines
Quoted 7 lines
Quoted 7 lines
(quoted diff) +7 -0
+}
+
+static int get_vgabios(unsigned char *buf, XenHostPCIDevice *dev) {
+    char rom_file[64];
+    FILE *fp;
+    uint8_t val;
+    struct stat st;
Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+    uint16_t magic = 0;
+
+    snprintf(rom_file, sizeof(rom_file),
+             "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom",

I think the format changed to be: /%04x:%02x:%02x.%d in Linux (see pci_setup_device in drivers/pci/probe.c) - not that it makes that much difference as the function is only up to 7.

Will improved this as you pointed.

Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +5 -0
+             dev->domain, dev->bus, dev->dev,
+             dev->func);
+
+    if (stat(rom_file, &st)) {
+        return -1;

ENODEV?

Fixed.

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +6 -0
+    }
+
+    if (access(rom_file, F_OK)) {
+        XEN_PT_ERR(NULL, "pci-assign: Insufficient privileges for %s",
+                    rom_file);
+        return -1;

EPERM?

Fixed.

Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+    }
+
+    /* Write "1" to the ROM file to enable it */
+    fp = fopen(rom_file, "r+");
+    if (fp == NULL) {

EACCESS ?

Fixed.

Quoted 16 lines
Quoted 5 lines
(quoted diff) +5 -0
+        return -1;
+    }
+    val = 1;
+    if (fwrite(&val, 1, 1, fp) != 1) {
+        goto close_rom;

Review

Quoted 10 lines
(quoted diff) +10 -0
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    /*
+     * Check if it a real bios extension.
+     * The magic number is 0xAA55.
+     */
+    if (fread(&magic, sizeof(magic), 1, fp)) {
+        goto close_rom;
+    }
Quoted 2 lines

Don't you want to do that before you write '1' in it?

Definitely, but I really did this above this line :)

Quoted 13 lines

Review

Quoted 8 lines
(quoted diff) +8 -0
+
+    if (magic != 0xAA55) {
+        goto close_rom;
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    if (!fread(buf, 1, st.st_size, fp)) {
+        XEN_PT_ERR(NULL, "pci-assign: Cannot read from host %s",

rom_file);

Quoted 1 line

+ XEN_PT_LOG(NULL, "Device option ROM contents are probably

invalid "

Quoted 1 line

+ "(check dmesg).\nSkip option ROM probe with

rombar=0, "

Quoted 12 lines

Review

Quoted 9 lines
(quoted diff) +9 -0
+                     "or load from file with romfile=\n");
+    }
+
+close_rom:
+    /* Write "0" to disable ROM */
+    fseek(fp, 0, SEEK_SET);
+    val = 0;
+    if (!fwrite(&val, 1, 1, fp)) {
+        XEN_PT_LOG("%s\n", "Failed to disable pci-sysfs rom file");

Should we return -1? (after closing the file of course)

Fixed.

Quoted 6 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+    }
+    fclose(fp);
+    return st.st_size;

Ah, that is why your return -1! In that case I presume the caller of this function will check the 'errno' to find the underlaying issue

I will modify something here and xen_pt_setup_vga(). Please see next version.

Thanks
Tiejun

#9 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Just resend since looks this delivery is delayed to these recipients or groups.

Sorry for any inconveniences.

Thanks
Tiejun

Quoted 210 lines

-----Original Message-----
From: Chen, Tiejun
Sent: Tuesday, May 20, 2014 9:30 AM
To: 'Konrad Rzeszutek Wilk'
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z
Subject: RE: [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Quoted 11 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Monday, May 19, 2014 9:36 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

[snip]

Quoted 57 lines

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice

Quoted 5 lines

Looks good so what about this based on the original,

hw/xen/xen_pt_graphics.c +0 -0
@@ -14,34 +14,73 @@ static int is_vga_passthrough(XenHostPCIDevice

*dev)

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice · line 14

Quoted 1 line
hw/xen/xen_pt_graphics.c +0 -0
             && ((dev->class_code >> 0x8) ==

PCI_CLASS_DISPLAY_VGA));

Quoted 49 lines
hw/xen/xen_pt_graphics.c +37 -2
 }
 
+typedef struct VGARegion {
+    int type;           /* Memory or port I/O */
+    uint64_t guest_base_addr;
+    uint64_t machine_base_addr;
+    uint64_t size;    /* size of the region */
+    int rc;
+} VGARegion;
+
+#define IORESOURCE_IO           0x00000100
+#define IORESOURCE_MEM          0x00000200
+
+static struct VGARegion vga_args[] = {
+    {
+        .type = IORESOURCE_IO,
+        .guest_base_addr = 0x3B0,
+        .machine_base_addr = 0x3B0,
+        .size = 0xC,
+        .rc = -1,
+    },
+    {
+        .type = IORESOURCE_IO,
+        .guest_base_addr = 0x3C0,
+        .machine_base_addr = 0x3C0,
+        .size = 0x20,
+        .rc = -1,
+    },
+    {
+        .type = IORESOURCE_MEM,
+        .guest_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
+        .machine_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
+        .size = 0x20,
+        .rc = -1,
+    },
+};
+
 /*
  * register VGA resources for the domain with assigned gfx
  */
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev)  {
-    int ret = 0;
+    int i = 0;
 
     if (!is_vga_passthrough(dev)) {
-        return ret;
+        return -1;
     }
 
Quoted 18 lines
Quoted 4 lines
hw/xen/xen_pt_graphics.c +0 -4
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
-            0x3B0, 0xA, DPCI_ADD_MAPPING);
-
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice *dev)

Quoted 10 lines
hw/xen/xen_pt_graphics.c +3 -7
-            0x3C0, 0x20, DPCI_ADD_MAPPING);
-
-    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0x20,
-            DPCI_ADD_MAPPING);
+    for(i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
+        if (vga_args[i].type == IORESOURCE_IO) {
+            vga_args[i].rc = xc_domain_ioport_mapping(xen_xc,

xen_domid,

Quoted 3 lines
hw/xen/xen_pt_graphics.c +3 -0
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size,

DPCI_ADD_MAPPING);

Quoted 6 lines

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice · line 69

Quoted 2 lines
hw/xen/xen_pt_graphics.c +2 -0
+        } else {
+            vga_args[i].rc = xc_domain_memory_mapping(xen_xc,

xen_domid,

Quoted 3 lines
hw/xen/xen_pt_graphics.c +3 -0
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size,

DPCI_ADD_MAPPING);

Quoted 12 lines

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice *dev)

Quoted 7 lines
hw/xen/xen_pt_graphics.c +4 -2
+        }
 
-    if (ret) {
-        XEN_PT_ERR(NULL, "VGA region mapping failed\n");
+        if (vga_args[i].rc) {
+            XEN_PT_ERR(NULL, "VGA %s mapping failed! (rc: %i)\n",
+                    vga_args[i].type == IORESOURCE_IO ? "ioport" :

"memory",

Quoted 4 lines
hw/xen/xen_pt_graphics.c +2 -0
+                    vga_args[i].rc);
+        }
     }
 
Quoted 6 lines

hw/xen/xen_pt_graphics.c int

Quoted 6 lines
hw/xen/xen_pt_graphics.c +1 -1
-    return ret;
+    return 0;
 }
 
 /*
@@ -49,29 +88,33 @@ int

xen_pt_register_vga_regions(XenHostPCIDevice

Quoted 45 lines

*dev)

Quoted 14 lines
hw/xen/xen_pt_graphics.c +2 -6
  */
 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)  {
-    int ret = 0;
+    int i = 0;
 
     if (!is_vga_passthrough(dev)) {
-        return ret;
+        return -1;
     }
 
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
-            0x3B0, 0xC, DPCI_REMOVE_MAPPING);
-
-    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,

hw/xen/xen_pt_graphics.c int xen_pt_register_vga_regions(XenHostPCIDevice *dev)

Quoted 10 lines
hw/xen/xen_pt_graphics.c +3 -7
-            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
-
-    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
-            0xa0000 >> XC_PAGE_SHIFT,
-            0xa0000 >> XC_PAGE_SHIFT,
-            20,
-            DPCI_REMOVE_MAPPING);
+    for(i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
+        if (vga_args[i].type == IORESOURCE_IO) {
+            vga_args[i].rc = xc_domain_ioport_mapping(xen_xc,

xen_domid,

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice *dev)

Quoted 3 lines
hw/xen/xen_pt_graphics.c +3 -0
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size,

DPCI_REMOVE_MAPPING);

hw/xen/xen_pt_graphics.c int · line 103

Quoted 2 lines
hw/xen/xen_pt_graphics.c +2 -0
+        } else {
+            vga_args[i].rc = xc_domain_memory_mapping(xen_xc,

xen_domid,

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice *dev)

Quoted 3 lines
hw/xen/xen_pt_graphics.c +3 -0
+                            vga_args[i].guest_base_addr,
+                            vga_args[i].machine_base_addr,
+                            vga_args[i].size,

DPCI_REMOVE_MAPPING);

hw/xen/xen_pt_graphics.c int xen_pt_register_vga_regions(XenHostPCIDevice *dev)

Quoted 7 lines
hw/xen/xen_pt_graphics.c +4 -2
+        }
 
-    if (ret) {
-        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+        if (vga_args[i].rc) {
+            XEN_PT_ERR(NULL, "VGA %s unmapping failed! (rc: %i)\n",
+                    vga_args[i].type == IORESOURCE_IO ? "ioport" :

"memory",

Quoted 9 lines

hw/xen/xen_pt_graphics.c static int is_vga_passthrough(XenHostPCIDevice *dev) · line 83

Quoted 6 lines
hw/xen/xen_pt_graphics.c +3 -1
+                    vga_args[i].rc);
+        }
     }
 
-    return ret;
+    return 0;

I think you still need to return a non-zero value in case of failure.

Okay I will do this like,

hw/xen/xen_pt_graphics.c index renamed from hw/xen/xen_pt_graphics.c +0 -0

5603a8e..1342f4f 100644

hw/xen/xen_pt_graphics.c +1 -0
@@ -77,6 +77,7 @@ int xen_pt_register_vga_regions(XenHostPCIDevice
 *dev)
             XEN_PT_ERR(NULL, "VGA %s mapping failed! (rc: %i)\n",
                     vga_args[i].type == IORESOURCE_IO ? "ioport" :
 "memory",
                     vga_args[i].rc);
+            return vga_args[i].rc;
         }
     }
hw/xen/xen_pt_graphics.c +1 -0
@@ -111,6 +112,7 @@ int xen_pt_unregister_vga_regions(XenHostPCIDevice
 *dev)
             XEN_PT_ERR(NULL, "VGA %s unmapping failed! (rc: %i)\n",
                     vga_args[i].type == IORESOURCE_IO ? "ioport" :
 "memory",
                     vga_args[i].rc);
+            return vga_args[i].rc;
         }
     }

Thanks
Tiejun

#10 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

In reply to Konrad Rzeszutek Wilk
Quoted 139 lines · Konrad Rzeszutek Wilk
Quoted 138 lines · Tiejun Chen

basic gfx passthrough support:
- add a vga type for gfx passthrough
- retrieve VGA bios from sysfs, then load it to guest 0xC0000
- register/unregister legacy VGA I/O ports and MMIOs for passthroughed gfx

The original patch is from Weidong Han <[email protected]>

---
v2:

* retrieve VGA bios from sysfs properly.
* redefine some function name.

 hw/xen/Makefile.objs         |   2 +-
 hw/xen/xen-host-pci-device.c |   5 ++
 hw/xen/xen-host-pci-device.h |   1 +
 hw/xen/xen_pt.c              |  10 +++
 hw/xen/xen_pt.h              |   4 +
 hw/xen/xen_pt_graphics.c     | 177 +++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx              |   9 +++
 vl.c                         |  11 ++-
 8 files changed, 217 insertions(+), 2 deletions(-)
 create mode 100644 hw/xen/xen_pt_graphics.c
hw/xen/Makefile.objs +1 -1
index a0ca0aa..77b7dae 100644
@@ -2,4 +2,4 @@
 common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
-obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
+obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o xen_pt_graphics.o
hw/xen/xen-host-pci-device.c +5 -0
index 743b37b..a54b7de 100644
@@ -376,6 +376,11 @@ int xen_host_pci_device_get(XenHostPCIDevice *d, uint16_t domain,
         goto error;
     }
     d->irq = v;
+    rc = xen_host_pci_get_hex_value(d, "class", &v);
+    if (rc) {
+        goto error;
+    }
+    d->class_code = v;
     d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
 
     return 0;
hw/xen/xen-host-pci-device.h +1 -0
index c2486f0..f1e1c30 100644
@@ -25,6 +25,7 @@ typedef struct XenHostPCIDevice {
 
     uint16_t vendor_id;
     uint16_t device_id;
+    uint32_t class_code;
     int irq;
 
     XenHostPCIIORegion io_regions[PCI_NUM_REGIONS - 1];
hw/xen/xen_pt.c +10 -0
index be4220b..a0113ea 100644
@@ -450,6 +450,7 @@ static int xen_pt_register_regions(XenPCIPassthroughState *s)
                    d->rom.size, d->rom.base_addr);
     }
 
+    xen_pt_register_vga_regions(d);
     return 0;
 }
 
@@ -470,6 +471,8 @@ static void xen_pt_unregister_regions(XenPCIPassthroughState *s)
     if (d->rom.base_addr && d->rom.size) {
         memory_region_destroy(&s->rom);
     }
+
+    xen_pt_unregister_vga_regions(d);
 }
 
 /* region mapping */
@@ -693,6 +696,13 @@ static int xen_pt_initfn(PCIDevice *d)
     /* Handle real device's MMIO/PIO BARs */
     xen_pt_register_regions(s);
 
+    /* Setup VGA bios for passthroughed gfx */
+    if (xen_pt_setup_vga(&s->real_device) < 0) {
+        XEN_PT_ERR(d, "Setup VGA BIOS of passthroughed gfx failed!\n");
+        xen_host_pci_device_put(&s->real_device);
+        return -1;
+    }
+
     /* reinitialize each config register to be emulated */
     if (xen_pt_config_init(s)) {
         XEN_PT_ERR(d, "PCI Config space initialisation failed.\n");
hw/xen/xen_pt.h +4 -0
index 942dc60..4d3a18d 100644
@@ -298,5 +298,9 @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
     return s->msix && s->msix->bar_index == bar;
 }
 
+extern int xen_has_gfx_passthru;
+int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
+int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
+int xen_pt_setup_vga(XenHostPCIDevice *dev);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c new file +18 -0
new file mode 100644
index 0000000..e1f0724
@@ -0,0 +1,177 @@
+/*
+ * graphics passthrough
+ */
+#include "xen_pt.h"
+#include "xen-host-pci-device.h"
+#include "hw/xen/xen_backend.h"
+
+static int is_vga_passthrough(XenHostPCIDevice *dev)
+{
+    return (xen_has_gfx_passthru
+            && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
+}
+
+/*
+ * register VGA resources for the domain with assigned gfx
+ */
+int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
+{
Quoted 8 lines

hw/xen/xen_pt_graphics.c line 26

Quoted 8 lines
hw/xen/xen_pt_graphics.c new file +8 -0
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xA, DPCI_ADD_MAPPING);

The original code does:

    ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0,
                        0x3B0, 0xC, DPCI_ADD_MAPPING);

why are we remapping fewer ports now?

Quoted 44 lines

hw/xen/xen_pt_graphics.c line 38

Quoted 11 lines
hw/xen/xen_pt_graphics.c new file +11 -0
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
+            0x3C0, 0x20, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0x20,
+            DPCI_ADD_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region mapping failed\n");

It would be actually useful to know _which_ of them failed. Perhaps you could structure this a bit differently and do:

struct _args {
        uint32_t gport;
        uint32_t mport;
        uint32_t nport;
};
        struct _args args[3] = {{ 0x3B0, 0x3B0, 0xA }, {...}};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(args); i++) {
		ret = xc_domain_ioport_mapping(xen_xc, xen_domid, args[i].gport, args[i]..)
		if (ret) {
			XEN_PT_ERR_(NULL, "VGA region mapping of 0x%lx for 0x%x pages failed with rc:%d\n",
					... fill in the values)
			return ret;
	}	
Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+    }
+
+    return ret;
+}
+
+/*
+ * unregister VGA resources for the domain with assigned gfx
+ */
+int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
+{
Quoted 8 lines

hw/xen/xen_pt_graphics.c line 56

Quoted 8 lines
hw/xen/xen_pt_graphics.c new file +8 -0
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xC, DPCI_REMOVE_MAPPING);

But here we are unmapping 0xC ioports....

Quoted 102 lines

hw/xen/xen_pt_graphics.c line 70

Quoted 13 lines
hw/xen/xen_pt_graphics.c new file +13 -0
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
+            0x3C0, 0x20, DPCI_REMOVE_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            20,
+            DPCI_REMOVE_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region unmapping failed\n");
+    }
+

The same pattern as above.

hw/xen/xen_pt_graphics.c line 83

Quoted 13 lines
hw/xen/xen_pt_graphics.c new file +13 -0
+    return ret;
+}
+
+static int get_vgabios(unsigned char *buf, XenHostPCIDevice *dev)
+{
+    char rom_file[64];
+    FILE *fp;
+    uint8_t val;
+    struct stat st;
+    uint16_t magic = 0;
+
+    snprintf(rom_file, sizeof(rom_file),
+             "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom",

I think the format changed to be: /%04x:%02x:%02x.%d in Linux (see pci_setup_device in drivers/pci/probe.c) - not that it makes that much difference as the function is only up to 7.

hw/xen/xen_pt_graphics.c line 88

Quoted 5 lines
hw/xen/xen_pt_graphics.c new file +5 -0
+             dev->domain, dev->bus, dev->dev,
+             dev->func);
+
+    if (stat(rom_file, &st)) {
+        return -1;

ENODEV?

hw/xen/xen_pt_graphics.c line 94

Quoted 6 lines
hw/xen/xen_pt_graphics.c new file +6 -0
+    }
+
+    if (access(rom_file, F_OK)) {
+        XEN_PT_ERR(NULL, "pci-assign: Insufficient privileges for %s",
+                    rom_file);
+        return -1;

EPERM?

hw/xen/xen_pt_graphics.c line 99

Quoted 5 lines
hw/xen/xen_pt_graphics.c new file +5 -0
+    }
+
+    /* Write "1" to the ROM file to enable it */
+    fp = fopen(rom_file, "r+");
+    if (fp == NULL) {

EACCESS ?

Quoted 5 lines
hw/xen/xen_pt_graphics.c new file +5 -0
+        return -1;
+    }
+    val = 1;
+    if (fwrite(&val, 1, 1, fp) != 1) {
+        goto close_rom;

hw/xen/xen_pt_graphics.c line 114

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    /*
+     * Check if it a real bios extension.
+     * The magic number is 0xAA55.
+     */
+    if (fread(&magic, sizeof(magic), 1, fp)) {
+        goto close_rom;
+    }

Don't you want to do that before you write '1' in it?

Quoted 9 lines
hw/xen/xen_pt_graphics.c new file +9 -0
+
+    if (magic != 0xAA55) {
+        goto close_rom;
+    }
+    fseek(fp, 0, SEEK_SET);
+
+    if (!fread(buf, 1, st.st_size, fp)) {
+        XEN_PT_ERR(NULL, "pci-assign: Cannot read from host %s", rom_file);
+        XEN_PT_LOG(NULL, "Device option ROM contents are probably invalid "

hw/xen/xen_pt_graphics.c line 133

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+                     "(check dmesg).\nSkip option ROM probe with rombar=0, "
+                     "or load from file with romfile=\n");
+    }
+
+close_rom:
+    /* Write "0" to disable ROM */
+    fseek(fp, 0, SEEK_SET);
+    val = 0;
+    if (!fwrite(&val, 1, 1, fp)) {
+        XEN_PT_LOG("%s\n", "Failed to disable pci-sysfs rom file");

Should we return -1? (after closing the file of course)

hw/xen/xen_pt_graphics.c line 136

Quoted 3 lines
hw/xen/xen_pt_graphics.c new file +3 -0
+    }
+    fclose(fp);
+    return st.st_size;
Quoted 6 lines

Ah, that is why your return -1! In that case I presume the caller of this function will check the 'errno' to find the underlaying issue

hw/xen/xen_pt_graphics.c line 140

Quoted 4 lines
hw/xen/xen_pt_graphics.c new file +4 -0
+}
+
+/* Allocated 128K for the vga bios */
+#define VGA_BIOS_DEFAULT_SIZE (0x20000)

The old default was 0x10000, why are we changing it?

Quoted 111 lines
Quoted 7 lines
hw/xen/xen_pt_graphics.c new file +7 -0
+int xen_pt_setup_vga(XenHostPCIDevice *dev)
+{
+    unsigned char *bios = NULL;
+    int bios_size = 0;
+    char *c = NULL;
+    char checksum = 0;
+    int rc = 0;

hw/xen/xen_pt_graphics.c line 158

Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+
+    if (!is_vga_passthrough(dev)) {
+        return rc;
+    }
+
+    bios = g_malloc0(VGA_BIOS_DEFAULT_SIZE);
+
+    bios_size = get_vgabios(bios, dev);
+    if (bios_size == 0 || bios_size > VGA_BIOS_DEFAULT_SIZE) {
+        XEN_PT_ERR(NULL, "vga bios size (0x%x) is invalid!\n", bios_size);

Um, with an error code, the 'bios size (0xfffffffff)' is going to show up. Why don't you an extra code to check for this , like:

	if (bios_size < 0)
		XEN_PT_ERR(NULL,"Error %d (%s) getting BIOS!\n", errno, strerror(errno));
	else
		.. the other error.
Quoted 84 lines
hw/xen/xen_pt_graphics.c new file +19 -0
+        rc = -1;
 
+        goto out;
+    }
+
+    /* Adjust the bios checksum */
+    for (c = (char *)bios; c < ((char *)bios + bios_size); c++) {
+        checksum += *c;
+    }
+    if (checksum) {
+        bios[bios_size - 1] -= checksum;
+        XEN_PT_LOG(NULL, "vga bios checksum is adjusted!\n");
+    }
+
+    /* Currently we fixed this address as a primary. */
+    cpu_physical_memory_rw(0xc0000, bios, bios_size, 1);
+out:
+    g_free(bios);
+    return rc;
+}
qemu-options.hx +9 -0
index 781af14..cece134 100644
@@ -1047,6 +1047,15 @@ STEXI
 Rotate graphical output some deg left (only PXA LCD).
 ETEXI
 
+DEF("gfx_passthru", 0, QEMU_OPTION_gfx_passthru,
+    "-gfx_passthru   enable Intel IGD passthrough by XEN\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -gfx_passthru
+@findex -gfx_passthru
+Enable Intel IGD passthrough by XEN
+ETEXI
+
 DEF("vga", HAS_ARG, QEMU_OPTION_vga,
     "-vga [std|cirrus|vmware|qxl|xenfb|tcx|cg3|none]\n"
     "                select video card type\n", QEMU_ARCH_ALL)
vl.c +10 -1
index 73e0661..c86e95f 100644
@@ -1436,6 +1436,13 @@ static void smp_parse(QemuOpts *opts)
 
 }
 
+/* We still need this for compatibility with XEN. */
+int xen_has_gfx_passthru;
+static void xen_gfx_passthru(const char *optarg)
+{
+    xen_has_gfx_passthru = 1;
+}
+
 static void configure_realtime(QemuOpts *opts)
 {
     bool enable_mlock;
@@ -2988,7 +2995,6 @@ int main(int argc, char **argv, char **envp)
     const char *trace_file = NULL;
     const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
                                         1024 * 1024;
-
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
     qemu_init_exec_dir(argv[0]);
@@ -3956,6 +3962,9 @@ int main(int argc, char **argv, char **envp)
                 }
                 configure_msg(opts);
                 break;
+            case QEMU_OPTION_gfx_passthru:
+                xen_gfx_passthru(optarg);
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#11 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Quoted 219 lines

-----Original Message-----
From: Stefano Stabellini [mailto:[email protected]]
Sent: Monday, May 19, 2014 8:10 PM
To: Konrad Rzeszutek Wilk
Cc: Chen, Tiejun; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 3/8] xen, gfx passthrough: basic graphics passthrough support

Quoted 18 lines · Konrad Rzeszutek Wilk
Quoted 17 lines · Tiejun Chen

basic gfx passthrough support:
- add a vga type for gfx passthrough
- retrieve VGA bios from sysfs, then load it to guest 0xC0000
- register/unregister legacy VGA I/O ports and MMIOs for passthroughed gfx

The original patch is from Weidong Han <[email protected]>

---
v2:

* retrieve VGA bios from sysfs properly.
* redefine some function name.

Quoted 6 lines
Quoted 6 lines
 hw/xen/Makefile.objs         |   2 +-
 hw/xen/xen-host-pci-device.c |   5 ++
 hw/xen/xen-host-pci-device.h |   1 +
 hw/xen/xen_pt.c              |  10 +++
 hw/xen/xen_pt.h              |   4 +
 hw/xen/xen_pt_graphics.c     | 177

+++++++++++++++++++++++++++++++++++++++++++

Quoted 11 lines

hw/xen/Makefile.objs line 2

Quoted 11 lines
 qemu-options.hx              |   9 +++
 vl.c                         |  11 ++-
 8 files changed, 217 insertions(+), 2 deletions(-)  create mode

100644 hw/xen/xen_pt_graphics.c

hw/xen/Makefile.objs index renamed from hw/xen/Makefile.objs +0 -0

a0ca0aa..77b7dae 100644

hw/xen/Makefile.objs +0 -0
@@ -2,4 +2,4 @@
 common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o

xen_devconfig.o

Quoted 11 lines

hw/xen/xen-host-pci-device.c int xen_host_pci_device_get(XenHostPCIDevice

Quoted 11 lines
hw/xen/Makefile.objs +0 -1
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
-obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o

xen_pt_msi.o

hw/xen/Makefile.objs +2 -0
+obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o
+xen_pt_msi.o xen_pt_graphics.o
(quoted diff) +0 -0

b/hw/xen/xen-host-pci-device.c index 743b37b..a54b7de 100644

hw/xen/xen-host-pci-device.c +0 -0
@@ -376,6 +376,11 @@ int xen_host_pci_device_get(XenHostPCIDevice

*d, uint16_t domain,

Quoted 22 lines
Quoted 22 lines
hw/xen/xen-host-pci-device.c +5 -0
         goto error;
     }
     d->irq = v;
+    rc = xen_host_pci_get_hex_value(d, "class", &v);
+    if (rc) {
+        goto error;
+    }
+    d->class_code = v;
     d->is_virtfn = xen_host_pci_dev_is_virtfn(d);
 
     return 0;
(quoted diff) +0 -0

b/hw/xen/xen-host-pci-device.h index c2486f0..f1e1c30 100644

hw/xen/xen-host-pci-device.h +1 -0
@@ -25,6 +25,7 @@ typedef struct XenHostPCIDevice {
 
     uint16_t vendor_id;
     uint16_t device_id;
+    uint32_t class_code;
     int irq;
 
Quoted 5 lines

hw/xen/xen_pt.c static int

Quoted 5 lines
hw/xen/xen-host-pci-device.h +0 -0
     XenHostPCIIORegion io_regions[PCI_NUM_REGIONS - 1]; diff --git

a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index be4220b..a0113ea 100644

hw/xen/xen_pt.c +0 -0
@@ -450,6 +450,7 @@ static int

xen_pt_register_regions(XenPCIPassthroughState *s)

Quoted 8 lines

hw/xen/xen_pt.c static void

Quoted 8 lines
hw/xen/xen_pt.c +1 -0
                    d->rom.size, d->rom.base_addr);
     }
 
+    xen_pt_register_vga_regions(d);
     return 0;
 }
 
@@ -470,6 +471,8 @@ static void

xen_pt_unregister_regions(XenPCIPassthroughState *s)

Quoted 7 lines
Quoted 7 lines
hw/xen/xen_pt.c +2 -0
     if (d->rom.base_addr && d->rom.size) {
         memory_region_destroy(&s->rom);
     }
+
+    xen_pt_unregister_vga_regions(d);
 }
 
Quoted 8 lines

hw/xen/xen_pt.c static int xen_pt_initfn(PCIDevice *d) · line 701

Quoted 8 lines
hw/xen/xen_pt.c +3 -0
 /* region mapping */
@@ -693,6 +696,13 @@ static int xen_pt_initfn(PCIDevice *d)
     /* Handle real device's MMIO/PIO BARs */
     xen_pt_register_regions(s);
 
+    /* Setup VGA bios for passthroughed gfx */
+    if (xen_pt_setup_vga(&s->real_device) < 0) {
+        XEN_PT_ERR(d, "Setup VGA BIOS of passthroughed gfx

failed!\n");

Quoted 4 lines
Quoted 4 lines
hw/xen/xen_pt.c +4 -0
+        xen_host_pci_device_put(&s->real_device);
+        return -1;
+    }
+
Quoted 8 lines

hw/xen/xen_pt.h static inline bool

Quoted 8 lines
hw/xen/xen_pt.c +0 -0
     /* reinitialize each config register to be emulated */
     if (xen_pt_config_init(s)) {
         XEN_PT_ERR(d, "PCI Config space initialisation failed.\n");
hw/xen/xen_pt.h index renamed from hw/xen/xen_pt.h +0 -0

942dc60..4d3a18d 100644

hw/xen/xen_pt.h +0 -0
@@ -298,5 +298,9 @@ static inline bool

xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)

Quoted 28 lines
Quoted 28 lines
hw/xen/xen_pt.h +4 -0
     return s->msix && s->msix->bar_index == bar;  }
 
+extern int xen_has_gfx_passthru;
+int xen_pt_register_vga_regions(XenHostPCIDevice *dev); int
+xen_pt_unregister_vga_regions(XenHostPCIDevice *dev); int
+xen_pt_setup_vga(XenHostPCIDevice *dev);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c new renamed from hw/xen/xen_pt_graphics.c +0 -0

file mode 100644 index 0000000..e1f0724

hw/xen/xen_pt_graphics.c new file +15 -0
@@ -0,0 +1,177 @@
+/*
+ * graphics passthrough
+ */
+#include "xen_pt.h"
+#include "xen-host-pci-device.h"
+#include "hw/xen/xen_backend.h"
+
+static int is_vga_passthrough(XenHostPCIDevice *dev) {
+    return (xen_has_gfx_passthru
+            && ((dev->class_code >> 0x8) ==
+PCI_CLASS_DISPLAY_VGA)); }
+
+/*
+ * register VGA resources for the domain with assigned gfx  */ int
+xen_pt_register_vga_regions(XenHostPCIDevice *dev) {
Quoted 8 lines

hw/xen/xen_pt_graphics.c line 26

Quoted 8 lines
hw/xen/xen_pt_graphics.c new file +8 -0
+    int ret = 0;
+
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xA, DPCI_ADD_MAPPING);

The original code does:

    ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0,
                        0x3B0, 0xC, DPCI_ADD_MAPPING);

why are we remapping fewer ports now?

Quoted 22 lines

hw/xen/xen_pt_graphics.c line 38

Quoted 11 lines
hw/xen/xen_pt_graphics.c new file +11 -0
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3C0,
+            0x3C0, 0x20, DPCI_ADD_MAPPING);
+
+    ret |= xc_domain_memory_mapping(xen_xc, xen_domid,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0xa0000 >> XC_PAGE_SHIFT,
+            0x20,
+            DPCI_ADD_MAPPING);
+
+    if (ret) {
+        XEN_PT_ERR(NULL, "VGA region mapping failed\n");

It would be actually useful to know _which_ of them failed. Perhaps you could structure this a bit differently and do:

struct _args {
        uint32_t gport;
        uint32_t mport;
        uint32_t nport;
};
Quoted 5 lines
        struct _args args[3] = {{ 0x3B0, 0x3B0, 0xA }, {...}};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(args); i++) {
		ret = xc_domain_ioport_mapping(xen_xc, xen_domid, args[i].gport,

args[i]..)

Quoted 2 lines
		if (ret) {
			XEN_PT_ERR_(NULL, "VGA region mapping of 0x%lx for 0x%x

pages failed with rc:%d\n",

Quoted 15 lines
					... fill in the values)
			return ret;
	}
Quoted 10 lines
hw/xen/xen_pt_graphics.c new file +10 -0
+    }
+
+    return ret;
+}
+
+/*
+ * unregister VGA resources for the domain with assigned gfx  */
+int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev) {
+    int ret = 0;
+
Quoted 9 lines
Quoted 6 lines

hw/xen/xen_pt_graphics.c line 56

Quoted 6 lines
hw/xen/xen_pt_graphics.c new file +6 -0
+    if (!is_vga_passthrough(dev)) {
+        return ret;
+    }
+
+    ret |= xc_domain_ioport_mapping(xen_xc, xen_domid, 0x3B0,
+            0x3B0, 0xC, DPCI_REMOVE_MAPPING);

But here we are unmapping 0xC ioports....

They're typos and they should be introduced by the original v1.

Actually I also notice this yesterday when I try to improve this part with your comments, you can see I already unify these places when I reply to you online.

Thanks
Tiejun

#12 lore raw

PATCH v2 4/8 xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Tiejun Chen

Some VBIOSs and drivers assume the IGD BDF (bus:device:function) is always 00:02.0, so we need to reserves 00:02.0 for assigned IGD in guest.

---
v2:

* Use a common way patch #2 introduce to reserve PCI devfn.

 hw/pci-host/piix.c | 8 ++++++++
 1 file changed, 8 insertions(+)
hw/pci-host/piix.c +8 -0
index ffdc853..b6f49bd 100644
@@ -329,6 +329,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     s = PCI_HOST_BRIDGE(dev);
     b = pci_bus_new(dev, NULL, pci_address_space,
                     address_space_io, 0, TYPE_PCI_BUS);
+
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is 00:02.0.
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));
+
     s->bus = b;
     object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
Signature · 1 line
1.9.1
#13 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 2 lines · Tiejun Chen

Some VBIOSs and drivers assume the IGD BDF (bus:device:function) is always 00:02.0, so we need to reserves 00:02.0 for assigned IGD in

reserve

Quoted 18 lines

guest.

---
v2:

* Use a common way patch #2 introduce to reserve PCI devfn.

 hw/pci-host/piix.c | 8 ++++++++
 1 file changed, 8 insertions(+)
hw/pci-host/piix.c +0 -0
index ffdc853..b6f49bd 100644
@@ -329,6 +329,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     s = PCI_HOST_BRIDGE(dev);

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 339

Quoted 10 lines
hw/pci-host/piix.c +8 -0
     b = pci_bus_new(dev, NULL, pci_address_space,
                     address_space_io, 0, TYPE_PCI_BUS);
+
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is 00:02.0.
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));
+

And we do this without checking whether PCI passthrough is done. Should it be gated on that? Or is the reason you do it unconditionally because you want to be able to hot-plug an GFX in?

Quoted 11 lines
hw/pci-host/piix.c +0 -0
     s->bus = b;
     object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#14 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 12 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:09 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 5 lines
Quoted 2 lines · Tiejun Chen

Some VBIOSs and drivers assume the IGD BDF (bus:device:function) is always 00:02.0, so we need to reserves 00:02.0 for assigned IGD in

reserve

Fixed.

Quoted 32 lines

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState

Quoted 18 lines

guest.

---
v2:

* Use a common way patch #2 introduce to reserve PCI devfn.

 hw/pci-host/piix.c | 8 ++++++++
 1 file changed, 8 insertions(+)
hw/pci-host/piix.c index renamed from hw/pci-host/piix.c +0 -0

ffdc853..b6f49bd 100644

hw/pci-host/piix.c +0 -0
@@ -329,6 +329,14 @@ PCIBus *i440fx_init(PCII440FXState

**pi440fx_state,

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state,

Quoted 6 lines
hw/pci-host/piix.c +3 -0
     s = PCI_HOST_BRIDGE(dev);
     b = pci_bus_new(dev, NULL, pci_address_space,
                     address_space_io, 0, TYPE_PCI_BUS);
+
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is

00:02.0.

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 339

Quoted 5 lines
hw/pci-host/piix.c +5 -0
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));
+
Quoted 4 lines

And we do this without checking whether PCI passthrough is done. Should it be gated on that? Or is the reason you do it unconditionally because you want to be able to hot-plug an GFX in?

To be honest currently we can't support hot-plug an GFX :( But I believe this would come soon. And additionally, as you know XEN and KVM have different way to implement pci-passthrough, so looks its not easy to distinguish these scenarios here. And I think now it may be acceptable just to reserve one specific devfn, right? Or could you have a good way, I can try to improve this point.

Thanks
Tiejun

#15 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Tiejun Chen

Hi,

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 6 lines
hw/pci-host/piix.c +6 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is 00:02.0.
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot 2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr= property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command line.

cheers,
Gerd

#16 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Il 19/05/2014 08:44, Gerd Hoffmann ha scritto:

Quoted 22 lines
   Hi,

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 6 lines
hw/pci-host/piix.c +6 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is 00:02.0.
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot 2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr= property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command line.

Quoted 2 lines

cheers,
Gerd

I already added vga none support on libxl, useful also for this cases:
http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=2e5738ff47b9d2e1948024100f87b1a25fcf004a

This patch is already tested and working, for now I not tested and I can't test with intel gpu passthrough, someone can test it with intel gpu passthrough?

Thanks for any reply and sorry for my bad english.

Quoted 7 lines

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#17 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Fabio Fantoni wrote on 2014-05-19:

Quoted 20 lines

Il 19/05/2014 08:44, Gerd Hoffmann ha scritto:

Quoted 19 lines
   Hi,
Quoted 4 lines

+ /* + * Some video bioses and gfx drivers will assume the bdf
of IGD is 00:02.0. + * So user need to set it to 00:02.0 in Xen
configure file explicitly, + * otherwise IGD will fail to work. +
*/ + pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot 2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr= property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command line.

Quoted 6 lines
Quoted 2 lines

cheers,
Gerd

I already added vga none support on libxl, useful also for this cases:
http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=2e5738ff47b9d2e19480
24100f87b1a25fcf004a

Thanks for provide such useful information to us. I will try to see whether it can meet our demand.

Quoted 14 lines

This patch is already tested and working, for now I not tested and I can't test with intel gpu passthrough, someone can test it with intel gpu passthrough?

Thanks for any reply and sorry for my bad english.

Quoted 7 lines

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

Best regards,
Yang

#18 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Fabio Fantoni
Quoted 41 lines

-----Original Message-----
From: Fabio Fantoni [mailto:[email protected]]
Sent: Monday, May 19, 2014 3:48 PM
To: Gerd Hoffmann; Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Zhang, Yang Z; [email protected]; [email protected]
Subject: Re: [Xen-devel] [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve 00:02.0 for INTEL IGD

Il 19/05/2014 08:44, Gerd Hoffmann ha scritto:

Quoted 4 lines
   Hi,
Quoted 2 lines
(quoted diff) +2 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is

00:02.0.

Quoted 20 lines

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 4 lines
hw/pci-host/piix.c +4 -0
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot
2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr=
property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command line.

Quoted 2 lines

cheers,
Gerd

Quoted 8 lines

I already added vga none support on libxl, useful also for this cases:
http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=2e5738ff47b9d2e19480
24100f87b1a25fcf004a

This patch is already tested and working, for now I not tested and I can't test with intel gpu passthrough, someone can test it with intel gpu passthrough?

Thanks for any reply and sorry for my bad english.

But I think what we intend is to reserve a specific slot to work vga passthrough on IGD.

Thanks
Tiejun

#19 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Gerd Hoffmann
Quoted 28 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 2:45 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Review

Quoted 2 lines
(quoted diff) +2 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is

00:02.0.

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 4 lines
hw/pci-host/piix.c +4 -0
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot
2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Quoted 4 lines

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr=

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Quoted 2 lines

property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command line.

So in my test scenario, we can see this information:

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Thanks
Tiejun

#20 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 28 lines · Tiejun
Quoted 28 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 2:45 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Review

Quoted 2 lines
(quoted diff) +2 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of IGD is

00:02.0.

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 4 lines
hw/pci-host/piix.c +4 -0
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot
2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Quoted 6 lines
Quoted 4 lines

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr=

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

So stop doing this.
Address -1 is a short-cut intended for humans.
In particular we have no way to guarantee that migration works unless you specify addresses explicitly.

Quoted 8 lines
Quoted 2 lines

property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command line.

So in my test scenario, we can see this information:

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform Thanks
Tiejun

I think the best fix is to give priority to devices that supply a specific slot.

I'll look into this.

Signature · 1 line
MST
#21 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 53 lines

-----Original Message-----
From: Michael S. Tsirkin [mailto:[email protected]]
Sent: Monday, May 19, 2014 6:13 PM
To: Chen, Tiejun
Cc: Gerd Hoffmann; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Quoted 31 lines · Tiejun
Quoted 31 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 2:45 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Hi,

Review

Quoted 3 lines
(quoted diff) +3 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of 
+ IGD is

00:02.0.

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 4 lines
hw/pci-host/piix.c +4 -0
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot
2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Quoted 8 lines
Quoted 5 lines

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr=

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0,

Quoted 7 lines

but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

So stop doing this.
Address -1 is a short-cut intended for humans.

Are you saying we need remove all auto assigned places like this,

piix.c: i440fx_init()

    if (xen_enabled()) {
        piix3 = DO_UPCAST(PIIX3State, dev,
                pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
                piix3, XEN_PIIX_NUM_PIRQS);
    } else {
        piix3 = DO_UPCAST(PIIX3State, dev,
                pci_create_simple_multifunction(b, -1, true, "PIIX3"));
Quoted 6 lines

In particular we have no way to guarantee that migration works unless you specify addresses explicitly.

Quoted 3 lines
Quoted 3 lines

property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command

Quoted 9 lines

line.

Quoted 5 lines

So in my test scenario, we can see this information:

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform Thanks Tiejun

I think the best fix is to give priority to devices that supply a specific slot.

Maybe I can extend that bitmap I implemented in patch #1 to do this.

But anyway you also need to concern if this is compatible with libxl in xen case.

Thanks
Tiejun

#22 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 65 lines · Tiejun
Quoted 53 lines

-----Original Message-----
From: Michael S. Tsirkin [mailto:[email protected]]
Sent: Monday, May 19, 2014 6:13 PM
To: Chen, Tiejun
Cc: Gerd Hoffmann; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Quoted 31 lines · Tiejun
Quoted 31 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 2:45 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Hi,

Review

Quoted 3 lines
(quoted diff) +3 -0
+    /*
+     * Some video bioses and gfx drivers will assume the bdf of 
+ IGD is

00:02.0.

hw/pci-host/piix.c PCIBus *i440fx_init(PCII440FXState **pi440fx_state, · line 338

Quoted 4 lines
hw/pci-host/piix.c +4 -0
+     * So user need to set it to 00:02.0 in Xen configure file explicitly,
+     * otherwise IGD will fail to work.
+     */
+    pci_reserve_pci_devfn(b, PCI_DEVFN(2, 0));

That is asking for trouble. Slot 2 is used by the qemu vga cards by default, and for quite a while (before memory api was merged) it even was impossible to change it. libvirt still places the vga card at slot
2 for that reason -> boom. I wouldn't be surprised if you find that assumption in other management libs / apps too.

Quoted 8 lines
Quoted 5 lines

Why do you need that patch in the first place? It should be possible to configure qemu to not occupy slot 2 if you need it that way. Just pass '-vga none' to qemu. Which you probably want anyway if you pass-through a vga to the guest. And explicitly configure a slot (via addr=

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0,

Quoted 7 lines

but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

So stop doing this.
Address -1 is a short-cut intended for humans.

Are you saying we need remove all auto assigned places like this,

piix.c: i440fx_init()

Quoted 8 lines
    if (xen_enabled()) {
        piix3 = DO_UPCAST(PIIX3State, dev,
                pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
                piix3, XEN_PIIX_NUM_PIRQS);
    } else {
        piix3 = DO_UPCAST(PIIX3State, dev,
                pci_create_simple_multifunction(b, -1, true, "PIIX3"));

Preferably, these should supply the address explicitly.

Quoted 16 lines
Quoted 6 lines

In particular we have no way to guarantee that migration works unless you specify addresses explicitly.

Quoted 3 lines
Quoted 3 lines

property) for all your pci devices. Doing it only for the IGD works too if you list the device before any other pci device on the qemu command

Quoted 9 lines

line.

Quoted 5 lines

So in my test scenario, we can see this information:

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform Thanks Tiejun

I think the best fix is to give priority to devices that supply a specific slot.

Quoted 6 lines

Maybe I can extend that bitmap I implemented in patch #1 to do this.

But anyway you also need to concern if this is compatible with libxl in xen case.

Thanks
Tiejun

libxl should stop using uto-assignment too.

Signature · 1 line
MST
#23 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Chen, Tiejun

Hi,

Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed. Use -device instead to create the devices.

Quoted 1 line

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

cheers,
Gerd

#24 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 19 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 7:23 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Quoted 4 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed.
Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

Quoted 11 lines
Quoted 2 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Quoted 5 lines

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

Looks you recommend we should change current xen platform design, I'm not sure if something in libxl also need to be modified. Especially, this may not be compatible with those old xen version. And especially, how to guarantee no one occupy 00:02.0 in the future with auto assign?

Thanks
Tiejun

#25 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 8 lines
Quoted 4 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed.
Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

libvirt does this unconditionally, because it is a good idea anyway for a number of reasons. Example: create a machine with three pci devices, hot-unplug the second, then live-migrate to another machine. The only way to create the correct config on the target machine is to explicitly assign slots, otherwise the third pci device ends up in the wrong slot.

Don't know how the libxl (and xl tool) work. Maybe it does the same anyway. Maybe it can handle the address assignment transparently for the user.

Quoted 8 lines
Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Quoted 8 lines
Quoted 4 lines

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

Looks you recommend we should change current xen platform design, I'm not sure if something in libxl also need to be modified. Especially, this may not be compatible with those old xen version.

Going for (1) certainly is easier as (2) indeed will need changes in the libxl, and might be tricky to get work with both old+new versions.

Quoted 2 lines

And especially, how to guarantee no one occupy 00:02.0 in the future with auto assign?

Creating devices automatically turned out to have a number of problems. So it is very unlikely we'll ever do this again.

cheers,
Gerd

#26 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 17 lines · Gerd Hoffmann

Hi,

Quoted 8 lines
Quoted 4 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed.
Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

libvirt does this unconditionally, because it is a good idea anyway for a number of reasons. Example: create a machine with three pci devices, hot-unplug the second, then live-migrate to another machine. The only way to create the correct config on the target machine is to explicitly assign slots, otherwise the third pci device ends up in the wrong slot.

Quoted 3 lines

Don't know how the libxl (and xl tool) work. Maybe it does the same anyway. Maybe it can handle the address assignment transparently for the user.

I'm not sure if libxl itself takes care of this under the hood, but the libvirt libxl driver at least does not deal with persistent PCI address allocation currently.

We're pulling the QEMU driver PCI address allocation code out into a shared module, for reuse by libvirt's BHyve driver for BSD, which will make it easy for the libvirt libxl driver to also use it if required too.

Regards,
Daniel

Signature · 4 lines
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
#27 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Gerd Hoffmann
Quoted 49 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 9:51 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 2 lines
Quoted 2 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2

indeed.

Quoted 6 lines
Quoted 2 lines

Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

libvirt does this unconditionally, because it is a good idea anyway for a number of reasons. Example: create a machine with three pci devices, hot-unplug the second, then live-migrate to another machine. The only way to create the correct config on the target machine is to explicitly assign slots, otherwise the third pci device ends up in the wrong slot.

Don't know how the libxl (and xl tool) work. Maybe it does the same anyway. Maybe it can handle the address assignment transparently for the user.

Quoted 8 lines
Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Quoted 8 lines
Quoted 4 lines

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

Looks you recommend we should change current xen platform design, I'm not sure if something in libxl also need to be modified. Especially, this may not be compatible with those old xen version.

Quoted 9 lines

Going for (1) certainly is easier as (2) indeed will need changes in the libxl, and might be tricky to get work with both old+new versions.

Quoted 2 lines

And especially, how to guarantee no one occupy 00:02.0 in the future with auto assign?

Creating devices automatically turned out to have a number of problems. So it is very unlikely we'll ever do this again.

According to our discussions, I realize we may have some plans or policies dedicated to how to assign devfn, but to support GFX passthrough for XEN, I think currently it may be a better solution to adopt #1 simply like this:

hw/i386/pc_piix.c +1 -1
index eaf3e61..500b3c2 100644
@@ -386,7 +386,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
-        pci_create_simple(bus, -1, "xen-platform");
+        pci_create_simple(bus, PCI_DEVFN(3,0), "xen-platform");
     }
 }
 #endif

Then we can go out to plan how to assign devfn in common, is this fine?

Thanks
Tiejun

#28 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Just ping, any concern about this?

Thanks
Tiejun

Quoted 99 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Chen, Tiejun
Sent: Wednesday, May 21, 2014 3:08 PM
To: Gerd Hoffmann; Anthony PERARD; Daniel P. Berrange
Cc: [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 25 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 9:51 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Hi,

Quoted 3 lines
Quoted 3 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2

indeed.

Quoted 6 lines
Quoted 2 lines

Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

Quoted 5 lines

libvirt does this unconditionally, because it is a good idea anyway for a number of reasons. Example: create a machine with three pci devices, hot-unplug the second, then live-migrate to another machine. The only way to create the correct config on the target machine is to explicitly assign slots, otherwise the third pci device ends up in the wrong

slot.

Quoted 2 lines

Don't know how the libxl (and xl tool) work. Maybe it does the same

anyway.

Quoted 19 lines

Maybe it can handle the address assignment transparently for the user.

Quoted 8 lines
Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Quoted 8 lines
Quoted 4 lines

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

Looks you recommend we should change current xen platform design, I'm not sure if something in libxl also need to be modified. Especially, this may not be compatible with those old xen version.

Quoted 9 lines

Going for (1) certainly is easier as (2) indeed will need changes in the libxl, and might be tricky to get work with both old+new versions.

Quoted 2 lines

And especially, how to guarantee no one occupy 00:02.0 in the future with auto assign?

Creating devices automatically turned out to have a number of problems. So it is very unlikely we'll ever do this again.

According to our discussions, I realize we may have some plans or policies dedicated to how to assign devfn, but to support GFX passthrough for XEN, I think currently it may be a better solution to adopt #1 simply like this:

hw/i386/pc_piix.c index eaf3e61..500b3c2 renamed from hw/i386/pc_piix.c +0 -0

100644

hw/i386/pc_piix.c +1 -1
@@ -386,7 +386,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs
 *args)
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
-        pci_create_simple(bus, -1, "xen-platform");
+        pci_create_simple(bus, PCI_DEVFN(3,0), "xen-platform");
     }
 }

#endif

Then we can go out to plan how to assign devfn in common, is this fine?

Thanks
Tiejun

#29 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 19 lines
Quoted 19 lines

According to our discussions, I realize we may have some plans or policies dedicated to how to assign devfn, but to support GFX passthrough for XEN, I think currently it may be a better solution to adopt #1 simply like this:

hw/i386/pc_piix.c index eaf3e61..500b3c2 renamed from hw/i386/pc_piix.c +0 -0

100644

hw/i386/pc_piix.c +1 -1
@@ -386,7 +386,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs
 *args)
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
-        pci_create_simple(bus, -1, "xen-platform");
+        pci_create_simple(bus, PCI_DEVFN(3,0), "xen-platform");
     }
 }

#endif

Quoted 1 line
Quoted 1 line

Then we can go out to plan how to assign devfn in common, is this fine?

Somewhere else in the thread someone listed a libxl config file snippet which is supposed to disable the xen platform device. Which doesn't work with upstream qemu for some reason.

Searching ... ah, here:
http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03996.html

So, how about making "xen_platform_pci=0" working correctly ?

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

cheers,
Gerd

#30 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 37 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 1:40 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 3 lines
Quoted 3 lines

According to our discussions, I realize we may have some plans or policies dedicated to how to assign devfn, but to support GFX passthrough for XEN, I think currently it may be a better solution to adopt

#1 simply like this:

Quoted 7 lines

hw/i386/pc_piix.c static void

Quoted 7 lines
hw/i386/pc_piix.c index renamed from hw/i386/pc_piix.c +0 -0

eaf3e61..500b3c2
100644

hw/i386/pc_piix.c +0 -0
@@ -386,7 +386,7 @@ static void

pc_xen_hvm_init(QEMUMachineInitArgs

Quoted 11 lines
Quoted 11 lines
hw/i386/pc_piix.c +1 -1
 *args)
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
-        pci_create_simple(bus, -1, "xen-platform");
+        pci_create_simple(bus, PCI_DEVFN(3,0), "xen-platform");
     }
 }

#endif

Then we can go out to plan how to assign devfn in common, is this fine?

Quoted 8 lines

Somewhere else in the thread someone listed a libxl config file snippet which is supposed to disable the xen platform device. Which doesn't work with upstream qemu for some reason.

Searching ... ah, here:
http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03996.html

So, how about making "xen_platform_pci=0" working correctly ?

Yes, this is exactly what I did as Anthony told me to add these two lines:

Quoted 2 lines

xen_platform_pci=0
device_model_args_hvm = [ '-device', 'xen-platform,addr=0x3' ]

But also as I already reply to Anthony yesterday, this doesn't work

http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg04101.html

I think this only work with some legacy xen/qemu which don't introduce to support ACPI pcihp.

Quoted 5 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices existed on that.

Thanks
Tiejun

#31 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

cheers,
Gerd

Quoted 1 line

From 405349bf38fc05653bfb8c971c61796e981eee98 Mon Sep 17 00:00:00 2001

From: Gerd Hoffmann <[email protected]>
Date: Thu, 22 May 2014 08:34:28 +0200
Subject: [PATCH] xen: make xen-platform a default device

---
 hw/i386/pc_piix.c    | 2 +-
 include/hw/xen/xen.h | 1 +
 vl.c                 | 3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)
hw/i386/pc_piix.c +1 -1
index eaf3e61..f987d03 100644
@@ -385,7 +385,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
     pc_init_pci(args);
 
     bus = pci_find_primary_bus();
-    if (bus != NULL) {
+    if (bus != NULL && default_xenplatform) {
         pci_create_simple(bus, -1, "xen-platform");
     }
 }
include/hw/xen/xen.h +1 -0
index 85fda3d..b350413 100644
@@ -20,6 +20,7 @@ enum xen_mode {
 
 extern uint32_t xen_domid;
 extern enum xen_mode xen_mode;
+extern int default_xenplatform;
 
 extern bool xen_allowed;
 
vl.c +3 -0
index 709d8cd..673148e 100644
@@ -226,6 +226,7 @@ static int default_floppy = 1;
 static int default_cdrom = 1;
 static int default_sdcard = 1;
 static int default_vga = 1;
+int default_xenplatform = 1;
 
 static struct {
     const char *driver;
@@ -247,6 +248,7 @@ static struct {
     { .driver = "isa-cirrus-vga",       .flag = &default_vga       },
     { .driver = "vmware-svga",          .flag = &default_vga       },
     { .driver = "qxl-vga",              .flag = &default_vga       },
+    { .driver = "xen-platform",         .flag = &default_xenplatform },
 };
 
 static QemuOptsList qemu_rtc_opts = {
@@ -4101,6 +4103,7 @@ int main(int argc, char **argv, char **envp)
         default_monitor = 0;
         default_net = 0;
         default_vga = 0;
+        default_xenplatform = 0;
     }
 
     if (is_daemonized()) {
Signature · 1 line
1.8.3.1
#32 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 27 lines · Gerd Hoffmann

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

cheers,
Gerd

Quoted 6 lines
Quoted 1 line

From 405349bf38fc05653bfb8c971c61796e981eee98 Mon Sep 17 00:00:00 2001

From: Gerd Hoffmann <[email protected]>
Date: Thu, 22 May 2014 08:34:28 +0200
Subject: [PATCH] xen: make xen-platform a default device

---

Looks good to me, though Sob is missing.
Can some Xen folks pls ack this one? I'll queue it up then.

Quoted 61 lines
 hw/i386/pc_piix.c    | 2 +-
 include/hw/xen/xen.h | 1 +
 vl.c                 | 3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)
hw/i386/pc_piix.c +1 -1
index eaf3e61..f987d03 100644
@@ -385,7 +385,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
     pc_init_pci(args);
 
     bus = pci_find_primary_bus();
-    if (bus != NULL) {
+    if (bus != NULL && default_xenplatform) {
         pci_create_simple(bus, -1, "xen-platform");
     }
 }
include/hw/xen/xen.h +1 -0
index 85fda3d..b350413 100644
@@ -20,6 +20,7 @@ enum xen_mode {
 
 extern uint32_t xen_domid;
 extern enum xen_mode xen_mode;
+extern int default_xenplatform;
 
 extern bool xen_allowed;
 
vl.c +3 -0
index 709d8cd..673148e 100644
@@ -226,6 +226,7 @@ static int default_floppy = 1;
 static int default_cdrom = 1;
 static int default_sdcard = 1;
 static int default_vga = 1;
+int default_xenplatform = 1;
 
 static struct {
     const char *driver;
@@ -247,6 +248,7 @@ static struct {
     { .driver = "isa-cirrus-vga",       .flag = &default_vga       },
     { .driver = "vmware-svga",          .flag = &default_vga       },
     { .driver = "qxl-vga",              .flag = &default_vga       },
+    { .driver = "xen-platform",         .flag = &default_xenplatform },
 };
 
 static QemuOptsList qemu_rtc_opts = {
@@ -4101,6 +4103,7 @@ int main(int argc, char **argv, char **envp)
         default_monitor = 0;
         default_net = 0;
         default_vga = 0;
+        default_xenplatform = 0;
     }
 
     if (is_daemonized()) {
Signature · 1 line
1.8.3.1
#33 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Gerd Hoffmann
Quoted 20 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

Quoted 8 lines

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.

I think this is unnecessary to add this option to support GFX passthrough.

Quoted 6 lines

(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

Yes, this patch works now. So I assume this would be merged into ML soon.

Thanks for your great help, Gerd!

Tiejun

#34 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Gerd Hoffmann
Quoted 26 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

Quoted 8 lines

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

Gerd,

Sorry, I may misunderstand what you mean previously then have a wrong test.

So this still doesn't work actually.

After applied your patch, 'xen-platform' is always disabled by default, right? So 00:02.0 is left naturally to be assigned to IGD as we expect like this,

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller (rev 04)

Then this is fine but if you intend to add a 'qemu -device xen-platform,addr=$slot', this doesn't work well. In my case,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3

Thanks
Tiejun

#35 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 78 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Chen, Tiejun
Sent: Thursday, May 22, 2014 6:50 PM
To: Gerd Hoffmann
Cc: [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]; Anthony PERARD
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 26 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

Quoted 8 lines

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

Gerd,

Sorry, I may misunderstand what you mean previously then have a wrong test.

So this still doesn't work actually.

After applied your patch, 'xen-platform' is always disabled by default, right? So 00:02.0 is left naturally to be assigned to IGD as we expect like this,

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM
Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen
Core Processor Integrated Graphics Controller (rev 06)
00:03.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family
USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller (rev 04)

Then this is fine but if you intend to add a 'qemu -device xen-platform,addr=$slot', this doesn't work well. In my case,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Quoted 8 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error
message from QMP server: Unsupported bus. Bus doesn't have property
'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add
failed: -3

Maybe you can assign explicitly the bus name, such as:
device_model_args_hvm = ['-device', 'xen-platform,bus=pci.0,addr=0x3']

Best regards,
-Gonglei

#36 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Chen, Tiejun

Hi,

Quoted 1 line

After applied your patch, 'xen-platform' is always disabled by default, right?

Only in case -nodefaults is passed on the qemu command line (don't know whenever libxl does that).

Quoted 3 lines

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0

^^^^^^^^^^^^^^^^^^
That line isn't needed ...

Quoted 1 line

device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

That alone should be enough to move away the platform device.

cheers,
Gerd

#37 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 15 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 7:22 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 1 line

After applied your patch, 'xen-platform' is always disabled by default, right?

Quoted 8 lines

Only in case -nodefaults is passed on the qemu command line (don't know whenever libxl does that).

Quoted 3 lines

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0

^^^^^^^^^^^^^^^^^^
That line isn't needed ...

Yes, this can work after remove this line:

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
#xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then domU has xen-platform again:

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 Unassigned class [ff80]: XenSource, Inc. Xen Platform Device (rev 01)
00:04.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller (rev 04)
Quoted 5 lines
Quoted 2 lines

device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

That alone should be enough to move away the platform device.

Sure.

Thanks
Tiejun

#38 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Chen, Tiejun
Quoted 59 lines · Tiejun
Quoted 26 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

Quoted 8 lines

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

Gerd,

Sorry, I may misunderstand what you mean previously then have a wrong test.

So this still doesn't work actually.

After applied your patch, 'xen-platform' is always disabled by default, right? So 00:02.0 is left naturally to be assigned to IGD as we expect like this,

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller (rev 04)

Then this is fine but if you intend to add a 'qemu -device xen-platform,addr=$slot', this doesn't work well. In my case,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Quoted 7 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3

Thanks
Tiejun

Weird: this implies use_acpi_pci_hotplug got set somehow.

Signature · 1 line
MST
#39 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 65 lines · On Thu, 22 May 2014 14:25:32 +0300 "Michael S. Tsirkin" <[email protected]> wrote:
Quoted 64 lines · Tiejun
Quoted 26 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

Quoted 8 lines

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device xen-platform,addr=$slot'.

Gerd,

Sorry, I may misunderstand what you mean previously then have a wrong test.

So this still doesn't work actually.

After applied your patch, 'xen-platform' is always disabled by default, right? So 00:02.0 is left naturally to be assigned to IGD as we expect like this,

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller (rev 04)

Then this is fine but if you intend to add a 'qemu -device xen-platform,addr=$slot', this doesn't work well. In my case,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
Quoted 4 lines
Quoted 2 lines

Thanks
Tiejun

Weird: this implies use_acpi_pci_hotplug got set somehow.

even if it's not set, and xenfv compat prop says it isn't, root PCI bus should have property present.

Tiejun,
What is output of the following debug patch:

---

hw/acpi/pcihp.c +2 -0
index 3b143b3..6f8e26d 100644
@@ -305,6 +305,7 @@ void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
     s->root= root_bus;
     s->legacy_piix = !bridges_enabled;
 
+    fprintf(stderr, "acpi_pcihp_init\n");
     if (s->legacy_piix) {
         unsigned *bus_bsel = g_malloc(sizeof *bus_bsel);
 
@@ -313,6 +314,7 @@ void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
         *bus_bsel = ACPI_PCIHP_BSEL_DEFAULT;
         object_property_add_uint32_ptr(OBJECT(root_bus), ACPI_PCIHP_PROP_BSEL,
                                        bus_bsel, NULL);
+	fprintf(stderr, "Legacy PCI hotplug\n");
     }
 
     memory_region_init_io(&s->io, NULL, &acpi_pcihp_io_ops, s,
hw/i386/acpi-build.c +1 -0
index 9fac589..a1211dd 100644
@@ -736,6 +736,7 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
     unsigned *bsel_alloc = opaque;
     unsigned *bus_bsel;
 
+    fprintf(stderr, "acpi_set_bsel bus: %s, hotpluggable: %d\n", bus->qbus.name, bus->qbus.allow_hotplug);
     if (bus->qbus.allow_hotplug) {
         bus_bsel = g_malloc(sizeof *bus_bsel);
#40 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 100 lines

-----Original Message-----
From: Igor Mammedov [mailto:[email protected]]
Sent: Thursday, May 22, 2014 10:20 PM
To: Michael S. Tsirkin
Cc: Chen, Tiejun; [email protected]; [email protected]; Daniel P. Berrange; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; Gerd Hoffmann; [email protected]; Anthony PERARD
Subject: Re: [Xen-devel] [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve 00:02.0 for INTEL IGD

Quoted 14 lines · On Thu, 22 May 2014 14:25:32 +0300 "Michael S. Tsirkin" <[email protected]> wrote:
Quoted 13 lines · Tiejun
Quoted 13 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

Hi,

Quoted 3 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga,

nic, cdrom, ...).

Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 3 lines

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device

xen-platform,addr=$slot'.

Quoted 5 lines
Quoted 5 lines
Quoted 1 line

Gerd,

Sorry, I may misunderstand what you mean previously then have a wrong

test.

Quoted 41 lines
Quoted 40 lines

So this still doesn't work actually.

After applied your patch, 'xen-platform' is always disabled by default, right? So 00:02.0 is left naturally to be assigned to IGD as we expect like this,

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM
Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA
[Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE
[Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200
v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 USB controller: Intel Corporation 8 Series/C220 Series
Chipset Family USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller
(rev 04)

Then this is fine but if you intend to add a 'qemu -device xen-platform,addr=$slot', this doesn't work well. In my case,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg Parsing config
from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an
error message from QMP server: Unsupported bus. Bus doesn't have
property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci:
libxl_device_pci_add failed: -3

Thanks
Tiejun

Quoted 6 lines
Quoted 1 line

Weird: this implies use_acpi_pci_hotplug got set somehow.

even if it's not set, and xenfv compat prop says it isn't, root PCI bus should have property present.

Tiejun,
What is output of the following debug patch:

With your patch and the following configurations,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then,

tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                                   
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/40 (label serial0)
acpi_pcihp_init
qemu: terminating on signal 1 from pid 24621
tchen0@tchen0-linux:~/workspace$

Thanks
Tiejun

Quoted 36 lines

---

hw/acpi/pcihp.c +2 -0
@@ -305,6 +305,7 @@ void acpi_pcihp_init(AcpiPciHpState *s, PCIBus
 *root_bus,
     s->root= root_bus;
     s->legacy_piix = !bridges_enabled;
 
+    fprintf(stderr, "acpi_pcihp_init\n");
     if (s->legacy_piix) {
         unsigned *bus_bsel = g_malloc(sizeof *bus_bsel);
@@ -313,6 +314,7 @@ void acpi_pcihp_init(AcpiPciHpState *s, PCIBus
 *root_bus,
         *bus_bsel = ACPI_PCIHP_BSEL_DEFAULT;
         object_property_add_uint32_ptr(OBJECT(root_bus),
 ACPI_PCIHP_PROP_BSEL,
                                        bus_bsel, NULL);
+	fprintf(stderr, "Legacy PCI hotplug\n");
     }
     memory_region_init_io(&s->io, NULL, &acpi_pcihp_io_ops, s, diff --git

a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 9fac589..a1211dd 100644

hw/i386/acpi-build.c +2 -0
@@ -736,6 +736,7 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
     unsigned *bsel_alloc = opaque;
     unsigned *bus_bsel;
 
+    fprintf(stderr, "acpi_set_bsel bus: %s, hotpluggable: %d\n",
+ bus->qbus.name, bus->qbus.allow_hotplug);
     if (bus->qbus.allow_hotplug) {
         bus_bsel = g_malloc(sizeof *bus_bsel);
#41 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 116 lines · Tiejun
Quoted 100 lines

-----Original Message-----
From: Igor Mammedov [mailto:[email protected]]
Sent: Thursday, May 22, 2014 10:20 PM
To: Michael S. Tsirkin
Cc: Chen, Tiejun; [email protected]; [email protected]; Daniel P. Berrange; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; Gerd Hoffmann; [email protected]; Anthony PERARD
Subject: Re: [Xen-devel] [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve 00:02.0 for INTEL IGD

Quoted 14 lines · On Thu, 22 May 2014 14:25:32 +0300 "Michael S. Tsirkin" <[email protected]> wrote:
Quoted 13 lines · Tiejun
Quoted 13 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Thursday, May 22, 2014 2:45 PM
To: Chen, Tiejun
Cc: Anthony PERARD; Daniel P. Berrange; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z; [email protected]
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

Hi,

Quoted 3 lines
Quoted 3 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga,

nic, cdrom, ...).

Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 3 lines

Currently looks 'xen-platform' itself can't be created, not those devices

existed on that.

The error message looks more like libxl tries to hot-unplug the xen platform device.

Attached patch (untested!) hooks up the xen platform device to the default device code we have in qemu. Two effects:

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

(1) As mentioned above the device will not be created in case -nodefaults is specified on the command line.
(2) Autocreating the device is also turned off in case xen-platform is added manually via -device.

With the patch applied you should be able to move the xen-platform device to some other place with a simple 'qemu -device

xen-platform,addr=$slot'.

Quoted 5 lines
Quoted 5 lines
Quoted 1 line

Gerd,

Sorry, I may misunderstand what you mean previously then have a wrong

test.

Quoted 41 lines
Quoted 40 lines

So this still doesn't work actually.

After applied your patch, 'xen-platform' is always disabled by default, right? So 00:02.0 is left naturally to be assigned to IGD as we expect like this,

tchen0@tchen0-HVM-domU:~$ lspci
00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM
Controller (rev 06)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA
[Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE
[Natoma/Triton II]
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200
v3/4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 USB controller: Intel Corporation 8 Series/C220 Series
Chipset Family USB EHCI #2 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Q87 Express LPC Controller
(rev 04)

Then this is fine but if you intend to add a 'qemu -device xen-platform,addr=$slot', this doesn't work well. In my case,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg Parsing config
from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an
error message from QMP server: Unsupported bus. Bus doesn't have
property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci:
libxl_device_pci_add failed: -3

Thanks
Tiejun

Quoted 6 lines
Quoted 1 line

Weird: this implies use_acpi_pci_hotplug got set somehow.

even if it's not set, and xenfv compat prop says it isn't, root PCI bus should have property present.

Tiejun,
What is output of the following debug patch:

With your patch and the following configurations,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then,

Quoted 8 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                                   
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/40 (label serial0)
acpi_pcihp_init
qemu: terminating on signal 1 from pid 24621

it looks like compat property "acpi-pci-hotplug-with-bridge-support" which is defined as 'off' for 'xenfv' machine is not applied for some reason.

I'd suggest to investigate a reason why compat properties don't work for xenfv machine.

Quoted 3 lines

Thanks
Tiejun

Signature · 2 lines
Regards,
  Igor
#42 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 20 lines · Igor Mammedov
Quoted 9 lines · Tiejun

With your patch and the following configurations,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then,

Quoted 8 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                                   
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/40 (label serial0)
acpi_pcihp_init
qemu: terminating on signal 1 from pid 24621
Quoted 6 lines

it looks like compat property "acpi-pci-hotplug-with-bridge-support" which is defined as 'off' for 'xenfv' machine is not applied for some reason.

I'd suggest to investigate a reason why compat properties don't work for xenfv machine.

This is because, to be able to remove the xen-platform device, we switch the -machine from xenfv to pc,accel=xen. So in that case ,the compat property is not applied...

Signature · 1 line
Anthony PERARD
#43 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 25 lines · Anthony PERARD
Quoted 24 lines · Igor Mammedov
Quoted 9 lines · Tiejun

With your patch and the following configurations,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then,

Quoted 8 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                                   
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/40 (label serial0)
acpi_pcihp_init
qemu: terminating on signal 1 from pid 24621

it looks like compat property "acpi-pci-hotplug-with-bridge-support" which is defined as 'off' for 'xenfv' machine is not applied for some reason.

Quoted 6 lines
Quoted 2 lines

I'd suggest to investigate a reason why compat properties don't work for xenfv machine.

This is because, to be able to remove the xen-platform device, we switch the -machine from xenfv to pc,accel=xen. So in that case ,the compat property is not applied...

Is there a way to specify acpi-pci-hotplug-with-bridge-support=off via QMP or command line?

#44 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 2 lines

Is there a way to specify acpi-pci-hotplug-with-bridge-support=off via QMP or command line?

-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off

cheers,
Gerd

#45 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Anthony PERARD
Quoted 25 lines · On Fri, 23 May 2014 11:52:19 +0100 Anthony PERARD <[email protected]>…
Quoted 24 lines · Igor Mammedov
Quoted 9 lines · Tiejun

With your patch and the following configurations,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then,

Quoted 8 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                                   
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/40 (label serial0)
acpi_pcihp_init
qemu: terminating on signal 1 from pid 24621

it looks like compat property "acpi-pci-hotplug-with-bridge-support" which is defined as 'off' for 'xenfv' machine is not applied for some reason.

Quoted 6 lines
Quoted 2 lines

I'd suggest to investigate a reason why compat properties don't work for xenfv machine.

This is because, to be able to remove the xen-platform device, we switch the -machine from xenfv to pc,accel=xen. So in that case ,the compat property is not applied...

I've just posted a patch that should fix "pc,accel=xen" case, please review.

Quoted 7 lines
Signature · 6 lines
Anthony PERARD

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Signature · 2 lines
Regards,
  Igor
#46 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Anthony PERARD
Quoted 25 lines · On Fri, 23 May 2014 11:52:19 +0100 Anthony PERARD <[email protected]>…
Quoted 24 lines · Igor Mammedov
Quoted 9 lines · Tiejun

With your patch and the following configurations,

gfx_passthru=1
pci=["00:02.0@2", "00:1a.0"]
xen_platform_pci=0
device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']

Then,

Quoted 8 lines
tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                                   
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/40 (label serial0)
acpi_pcihp_init
qemu: terminating on signal 1 from pid 24621

it looks like compat property "acpi-pci-hotplug-with-bridge-support" which is defined as 'off' for 'xenfv' machine is not applied for some reason.

Quoted 6 lines
Quoted 2 lines

I'd suggest to investigate a reason why compat properties don't work for xenfv machine.

This is because, to be able to remove the xen-platform device, we switch the -machine from xenfv to pc,accel=xen. So in that case ,the compat property is not applied...

I've just posted a patch that should fix "pc,accel=xen" case, please review.

Quoted 7 lines
Signature · 6 lines
Anthony PERARD

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Signature · 2 lines
Regards,
  Igor
#47 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Gerd Hoffmann
Quoted 27 lines · Gerd Hoffmann

Hi,

Quoted 19 lines
Quoted 19 lines

According to our discussions, I realize we may have some plans or policies dedicated to how to assign devfn, but to support GFX passthrough for XEN, I think currently it may be a better solution to adopt #1 simply like this:

hw/i386/pc_piix.c index eaf3e61..500b3c2 renamed from hw/i386/pc_piix.c +0 -0

100644

hw/i386/pc_piix.c +1 -1
@@ -386,7 +386,7 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs
 *args)
 
     bus = pci_find_primary_bus();
     if (bus != NULL) {
-        pci_create_simple(bus, -1, "xen-platform");
+        pci_create_simple(bus, PCI_DEVFN(3,0), "xen-platform");
     }
 }

#endif

Quoted 1 line
Quoted 1 line

Then we can go out to plan how to assign devfn in common, is this fine?

Somewhere else in the thread someone listed a libxl config file snippet which is supposed to disable the xen platform device. Which doesn't work with upstream qemu for some reason.

Quoted 5 lines

Searching ... ah, here:
http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03996.html

So, how about making "xen_platform_pci=0" working correctly ?

You don't want that enabled by default.
Otherwise the Linux (and Windows) drivers won't enable the PV functionality and we are using the emulated drivers (slow).

Quoted 13 lines

Another useful thing would be to not create the xen platform device in case "-nodefaults" was specified on the command line (that switch turns off a bunch of other devices present by default: vga, nic, cdrom, ...).

cheers,
Gerd

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#48 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Chen, Tiejun
Quoted 37 lines · Tiejun
Quoted 19 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 7:23 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Quoted 4 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed.
Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

Quoted 11 lines
Quoted 2 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Quoted 7 lines
Quoted 5 lines

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

Looks you recommend we should change current xen platform design, I'm not sure if something in libxl also need to be modified. Especially, this may not be compatible with those old xen version. And especially, how to guarantee no one occupy 00:02.0 in the future with auto assign?

Hi,

Libxl knows how to create a guest without xen-platform, but I think this can work only from QEMU 1.6 (which Xen 4.4 use).

So, using the options below with libxl would put the xen-platform device away from the 00:02 slot.
xen_platform_pci=0
device_model_args_hvm = [ '-device', 'xen-platform,addr=0x3' ]

Signature · 1 line
Anthony PERARD
#49 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 67 lines

-----Original Message-----
From: Anthony PERARD [mailto:[email protected]]
Sent: Tuesday, May 20, 2014 10:45 PM
To: Chen, Tiejun
Cc: Gerd Hoffmann; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 12 lines · Tiejun
Quoted 12 lines

-----Original Message-----
From: Gerd Hoffmann [mailto:[email protected]]
Sent: Monday, May 19, 2014 7:23 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough:
reserve
00:02.0 for INTEL IGD

Quoted 7 lines
Quoted 7 lines

Hi,

Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before

we need this.

Quoted 3 lines
Quoted 3 lines

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2

indeed.

Quoted 4 lines
Quoted 2 lines

Use -device instead to create the devices.

Are you saying we have to create the devices explicitly when we want to work

IGD vga with passthrough? But how to make sure all user know this workable way? Maybe you suggest we should document somewhere.

Quoted 12 lines
Quoted 12 lines
Quoted 3 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Quoted 7 lines
Quoted 5 lines

I personally would suggest to go for #2. As far I know the platform device is only needed if you want attach xenbus devices to the guest (correct?), so creating virtual machines without the xen platform device is a valid use case and you should allow it.

Looks you recommend we should change current xen platform design, I'm not

sure if something in libxl also need to be modified. Especially, this may not be compatible with those old xen version. And especially, how to guarantee no one occupy 00:02.0 in the future with auto assign?

Hi,

Quoted 8 lines

Libxl knows how to create a guest without xen-platform, but I think this can work only from QEMU 1.6 (which Xen 4.4 use).

So, using the options below with libxl would put the xen-platform device away from the 00:02 slot.
xen_platform_pci=0
device_model_args_hvm = [ '-device', 'xen-platform,addr=0x3' ]

I added these two lines in domU's configuration file, but failed:

tchen0@tchen0-linux:~/workspace$ sudo xl cr domu-cfg                                                                                                       
Parsing config from domu-cfg
libxl: error: libxl_qmp.c:287:qmp_handle_error_response: received an error message from QMP server: Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set
libxl: error: libxl_create.c:1277:domcreate_attach_pci: libxl_device_pci_add failed: -3
tchen0@tchen0-linux:~/workspace$ cat /var/log/xen/qemu-dm-HVM.log                                                                                                      
char device redirected to /dev/pts/49 (label serial0)
qemu: terminating on signal 1 from pid 3117

Anything else I'm still missing? Or this mean this way can't work based on the latest qemu/xen?

Thanks
Tiejun

#50 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

In reply to Gerd Hoffmann
Quoted 15 lines · Gerd Hoffmann

Hi,

Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed. Use -device instead to create the devices.

Quoted 2 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Gerd,

Sorry I return this discussion again.

As we discussed here, we should never use -vga xxx to avoid occupying slot 2. Instead, we will just use -device to create that emulated vga device as you said like this:

-device VGA,vgamem_mb=8,addr=0x4

But looks this may issue another problem. That is we can't see anything until the vga driver is initialized. I means if we pass `-device VGA,vgamem_mb=8,addr=0x4', qemu doesn't expose any vga interface to BIOS. Right? Or I'm still missing something.

Thanks
Tiejun

#51 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 33 lines · Tiejun
Quoted 15 lines · Gerd Hoffmann

Hi,

Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed. Use -device instead to create the devices.

Quoted 2 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Gerd,

Sorry I return this discussion again.

As we discussed here, we should never use -vga xxx to avoid occupying slot 2. Instead, we will just use -device to create that emulated vga device as you said like this:

Quoted 7 lines

-device VGA,vgamem_mb=8,addr=0x4

But looks this may issue another problem. That is we can't see anything until the vga driver is initialized. I means if we pass `-device VGA,vgamem_mb=8,addr=0x4', qemu doesn't expose any vga interface to BIOS. Right? Or I'm still missing something.

I know for Xen that

tools/firmware/hvmloader/acpi/dsdt.asl

also needs to change:

             /* Make cirrues VGA S3 suspend/resume work in Windows 
XP/2003 */
             Device (VGA)
             {
-               Name (_ADR, 0x00020000)
+               // Address of the VGA (device F function 0)
+               Name (_ADR, 0x000F0000)

is what I have for:

-device VGA,vgamem_mb=8,addr=0xF.0x0

I am not sure, but think that QEMU without Xen does this acpi adjustment at run time.

I also change seabios's config to include more VGA support but not sure it is needed.

-Don Slutz

Quoted 3 lines

Thanks
Tiejun

#52 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 58 lines · Donald Christopher
Quoted 33 lines · Tiejun
Quoted 15 lines · Gerd Hoffmann
   Hi,
Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed. Use -device instead to create the devices.

Quoted 2 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Gerd,

Sorry I return this discussion again.

As we discussed here, we should never use -vga xxx to avoid occupying slot 2. Instead, we will just use -device to create that emulated vga device as you said like this:

Quoted 7 lines

-device VGA,vgamem_mb=8,addr=0x4

But looks this may issue another problem. That is we can't see anything until the vga driver is initialized. I means if we pass `-device VGA,vgamem_mb=8,addr=0x4', qemu doesn't expose any vga interface to BIOS. Right? Or I'm still missing something.

I know for Xen that

tools/firmware/hvmloader/acpi/dsdt.asl

also needs to change:

              /* Make cirrues VGA S3 suspend/resume work in Windows
XP/2003 */
              Device (VGA)
              {
(quoted diff) +2 -1
-               Name (_ADR, 0x00020000)
+               // Address of the VGA (device F function 0)
+               Name (_ADR, 0x000F0000)
Quoted 4 lines

is what I have for:

-device VGA,vgamem_mb=8,addr=0xF.0x0

Do you mean we need to sync devfn with the passed address to work the emulated VGA before the real graphic device driver is called?

Thanks
Tiejun

Quoted 12 lines

I am not sure, but think that QEMU without Xen does this acpi adjustment at run time.

I also change seabios's config to include more VGA support but not sure it is needed.

-Don Slutz

Quoted 3 lines

Thanks
Tiejun

#53 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 50 lines · Tiejun
Quoted 49 lines · Donald Christopher
Quoted 33 lines · Tiejun
Quoted 15 lines · Gerd Hoffmann
   Hi,
Quoted 5 lines

I think '-vga none' just guarantees the qemu vga cards doesn't occupy 00:02.0, but this doesn't mean others use this specific slot since in qemu internal, we always pass -1 to assign a slot automatically to register a PCI device. So in some cases, we can't get this slot as we expect since that is already assigned previously before we need this.

Yes, -vga, -net nic, -drive if=scsi (maybe more) can internally create pci devices with auto slot assignment, which will occupy slot 2 indeed. Use -device instead to create the devices.

Quoted 2 lines

PCI: slot 2 function 0 not available for xen-pci-passthrough, in use by xen-platform

Quoted 8 lines

Ah, the xen platform device. /me looks. Ah, pc_xen_hvm_init creates this automatically. Two options here IMHO:

(1) Just move it somewhere else explicitly. For example slot 3, or make it a southbridge function (say 00:01.7).
(2) Don't create it automatically, instead expect management add it if needed, using -device xen-plaform,addr=...

Gerd,

Sorry I return this discussion again.

As we discussed here, we should never use -vga xxx to avoid occupying slot 2. Instead, we will just use -device to create that emulated vga device as you said like this:

Quoted 7 lines

-device VGA,vgamem_mb=8,addr=0x4

But looks this may issue another problem. That is we can't see anything until the vga driver is initialized. I means if we pass `-device VGA,vgamem_mb=8,addr=0x4', qemu doesn't expose any vga interface to BIOS. Right? Or I'm still missing something.

I know for Xen that

tools/firmware/hvmloader/acpi/dsdt.asl

also needs to change:

Quoted 8 lines

Review

Quoted 8 lines
              /* Make cirrues VGA S3 suspend/resume work in Windows
XP/2003 */
              Device (VGA)
              {
(quoted diff) +2 -1
-               Name (_ADR, 0x00020000)
+               // Address of the VGA (device F function 0)
+               Name (_ADR, 0x000F0000)

With this change I still didn't see anything.

Thanks
Tiejun

Quoted 27 lines
Quoted 5 lines

is what I have for:

-device VGA,vgamem_mb=8,addr=0xF.0x0

Do you mean we need to sync devfn with the passed address to work the emulated VGA before the real graphic device driver is called?

Thanks
Tiejun

Quoted 12 lines

I am not sure, but think that QEMU without Xen does this acpi adjustment at run time.

I also change seabios's config to include more VGA support but not sure it is needed.

-Don Slutz

Quoted 3 lines

Thanks
Tiejun

#54 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 16 lines · Tiejun
Quoted 15 lines · Tiejun
Quoted 14 lines · Donald Christopher
Quoted 13 lines · Tiejun
Quoted 3 lines · Gerd Hoffmann
   Hi,

Gerd,

Sorry I return this discussion again.

As we discussed here, we should never use -vga xxx to avoid occupying slot 2. Instead, we will just use -device to create that emulated vga device as you said like this:

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

-device VGA,vgamem_mb=8,addr=0x4

But looks this may issue another problem. That is we can't see anything until the vga driver is initialized. I means if we pass `-device VGA,vgamem_mb=8,addr=0x4', qemu doesn't expose any vga interface to BIOS. Right? Or I'm still missing something.

QEMU does not directly expose any vga interface to BIOS (SeaBIOS in my case).

However SeaBIOS searches for a vga device on the PCI Host bridge. And my testing is showing that it finds it.

(d12) Scan for VGA option rom
(d12) Running option rom at c000:0003
(XEN) stdvga.c:147:d12v0 entering stdvga and caching modes

Quoted 16 lines
Quoted 7 lines
Quoted 7 lines

I know for Xen that

tools/firmware/hvmloader/acpi/dsdt.asl

also needs to change:

Quoted 8 lines

Review

Quoted 8 lines
              /* Make cirrues VGA S3 suspend/resume work in Windows
XP/2003 */
              Device (VGA)
              {
(quoted diff) +2 -1
-               Name (_ADR, 0x00020000)
+               // Address of the VGA (device F function 0)
+               Name (_ADR, 0x000F0000)
Quoted 2 lines

With this change I still didn't see anything.

This does not match with what I see.

Looks like linux does not care about the acpi data. Using

xen: ddb4aa5, qemu: 8589744, and seabios: e51488c

and

GRUB_CMDLINE_XEN="dom0_mem=2G loglvl=all guest_loglvl=all console_timestamps=1 com1=9600,8n1 console=com1 apic_verbosity=verbose crashkernel=256M@256M no-cpuidle"

Config file (/home/don/P-1-5.list0.xfg):

dcs-xen-54:~>cat P-1-5.list0.xfg
builder = "hvm"
cpu_weight = 128
cpus = [
5,
]
vga = "none"
videoram = 8
device_model_args_hvm = [
"-monitor",
"pty",
"-boot",
"menu=on",
"-device",
"VGA,vgamem_mb=8,addr=0x4",
"-device", "e1000,id=nic0,netdev=net0,mac=00:0c:29:a0:a9:2c,addr=0x5.0x0", "-netdev", "type=tap,id=net0,ifname=vif9.0-emu,script=/etc/qemu-ifup,downscript=no", "-device",
"xen-platform,addr=0x6.0x0",
]
disk = [
"/home/don/qemu-img/P-1-5-disk.raw,,hda",
]
device_model_version = "qemu-xen"
maxmem = 3072
maxvcpus = 1
memory = 3072
name = "P-1-5"
serial = "pty"
tsc_mode = "native_paravirt"
uuid = "18cf5fd0-e564-49c4-b63f-e6c3c23b1294"
vcpus = 1
viridian = 0
xen_platform_pci = 0

[root@dcs-xen-54 ~]# xl cre -p -V /home/don/P-1-5.list0.xfg

Gives me a vncviewer screen that says:

Guest has not initialized the display (yet).

[root@dcs-xen-54 ~]# xl unpause 12

Adds the following ([root@dcs-xen-54 ~]# xl dmesg):

(d12) HVM Loader
(d12) Detected Xen v4.5-unstable
(d12) Xenbus rings @0xfeffc000, event channel 1
(d12) System requested SeaBIOS
(d12) CPU speed is 2400 MHz
(d12) Relocating guest memory for lowmem MMIO space disabled (XEN) irq.c:270: Dom12 PCI link 0 changed 0 -> 5
(d12) PCI-ISA link 0 routed to IRQ5
(XEN) irq.c:270: Dom12 PCI link 1 changed 0 -> 10
(d12) PCI-ISA link 1 routed to IRQ10
(XEN) irq.c:270: Dom12 PCI link 2 changed 0 -> 11
(d12) PCI-ISA link 2 routed to IRQ11
(XEN) irq.c:270: Dom12 PCI link 3 changed 0 -> 5
(d12) PCI-ISA link 3 routed to IRQ5
(d12) pci dev 01:3 INTA->IRQ10
(d12) pci dev 05:0 INTA->IRQ10
(d12) pci dev 06:0 INTA->IRQ11
(d12) No RAM in high memory; setting high_mem resource base to 100000000 (d12) pci dev 06:0 bar 14 size 001000000: 0f0000008
(d12) pci dev 04:0 bar 10 size 000800000: 0f1000008
(d12) pci dev 05:0 bar 30 size 000040000: 0f1800000
(d12) pci dev 05:0 bar 10 size 000020000: 0f1840000
(d12) pci dev 04:0 bar 30 size 000010000: 0f1860000
(d12) pci dev 04:0 bar 18 size 000001000: 0f1870000
(d12) pci dev 06:0 bar 10 size 000000100: 00000c001
(d12) pci dev 05:0 bar 14 size 000000040: 00000c101
(d12) pci dev 01:1 bar 20 size 000000010: 00000c141
(d12) Multiprocessor initialisation:
(d12) - CPU0 ... 36-bit phys ... fixed MTRRs ... var MTRRs [1/8] ... done. (d12) Testing HVM environment:
(d12) - REP INSB across page boundaries ... passed
(d12) - GS base MSRs and SWAPGS ... passed
(d12) Passed 2 of 2 tests
(d12) Writing SMBIOS tables ...
(d12) Loading SeaBIOS ...
(d12) Creating MP tables ...
(d12) Loading ACPI ...
(d12) vm86 TSS at fc00a180
(d12) BIOS map:
(d12) 10000-100d3: Scratch space
(d12) c0000-fffff: Main BIOS
(d12) E820 table:

(d12)  [00]: 00000000:00000000 - 00000000:000a0000: RAM
(d12)  HOLE: 00000000:000a0000 - 00000000:000c0000
(d12)  [01]: 00000000:000c0000 - 00000000:00100000: RESERVED
(d12)  [02]: 00000000:00100000 - 00000000:bf800000: RAM
(d12)  HOLE: 00000000:bf800000 - 00000000:fc000000
(d12)  [03]: 00000000:fc000000 - 00000001:00000000: RESERVED

(d12) Invoking SeaBIOS ...
(d12) SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54) (d12)
(d12) Found Xen hypervisor signature at 40000000
(d12) Running on QEMU (i440fx)
(d12) xen: copy e820...
(d12) Relocating init from 0x000df629 to 0xbf7ae600 (size 71995) (d12) CPU Mhz=2400
(d12) Found 7 PCI devices (max PCI bus is 00)
(d12) Allocated Xen hypercall page at bf7ff000
(d12) Detected Xen v4.5-unstable
(d12) xen: copy BIOS tables...
(d12) Copying SMBIOS entry point from 0x00010010 to 0x000f0f50 (d12) Copying MPTABLE from 0xfc001140/fc001150 to 0x000f0e70 (d12) Copying PIR from 0x00010030 to 0x000f0df0
(d12) Copying ACPI RSDP from 0x000100b0 to 0x000f0dc0
(d12) Using pmtimer, ioport 0xb008
(d12) Scan for VGA option rom
(d12) Running option rom at c000:0003
(XEN) stdvga.c:147:d12v0 entering stdvga and caching modes (d12) pmm call arg1=0
(d12) Turning on vga text mode console
(d12) SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54) (d12) Machine UUID 18cf5fd0-e564-49c4-b63f-e6c3c23b1294 (d12) All threads complete.
(d12) Found 0 lpt ports
(d12) Found 1 serial ports
(d12) ATA controller 1 at 1f0/3f4/0 (irq 14 dev 9)
(d12) ATA controller 2 at 170/374/0 (irq 15 dev 9)
(d12) ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 MiBytes) (d12) Searching bootorder for: /pci@i0cf8/*@1,1/drive@0/disk@0 (d12) PS2 keyboard initialized
(d12) All threads complete.
(d12) Scan for option roms
(d12) Running option rom at c980:0003
(d12) pmm call arg1=1
(d12) pmm call arg1=0
(d12) pmm call arg1=1
(d12) pmm call arg1=0
(d12) Searching bootorder for: /pci@i0cf8/*@5
(d12)
(d12) Press F12 for boot menu.
(d12)
(d12) Select boot device:
(d12)
(d12) 1. ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 MiBytes) (d12) 2. iPXE (PCI 00:05.0)

And the VGA screen has the SeaBIOS messages:

SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54) Machine UUID 18cf5fd0-e564-49c4-b63f-e6c3c23b1294

iPXE (http://ipxe.org) 00:05.0 C980 PCI2.10 PnP PMM+BF79C090+BF6FC090 C980

Press F12 for boot menu.

Select boot device:

1. ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 MiBytes)
2. iPXE (PCI 00:05.0)

The line (from above):
(d12) Turning on vga text mode console

allows me to use f12 in seabios which is why the guest is stopped waiting for a boot device selection.

In the guest (after boot):

[root@P-1-5 ~]# lspci
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:04.0 VGA compatible controller: Technical Corp. Unknown device 1111 00:05.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03) 00:06.0 Class ff80: XenSource, Inc. Xen Platform Device (rev 01)

Hope all this helps.

-Don Slutz

Quoted 30 lines

Thanks
Tiejun

Quoted 27 lines
Quoted 5 lines

is what I have for:

-device VGA,vgamem_mb=8,addr=0xF.0x0

Do you mean we need to sync devfn with the passed address to work the emulated VGA before the real graphic device driver is called?

Thanks
Tiejun

Quoted 12 lines

I am not sure, but think that QEMU without Xen does this acpi adjustment at run time.

I also change seabios's config to include more VGA support but not sure it is needed.

-Don Slutz

Quoted 3 lines

Thanks
Tiejun

#55 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Hi,

Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
              /* Make cirrues VGA S3 suspend/resume work in Windows
XP/2003 */
              Device (VGA)
              {
(quoted diff) +2 -1
-               Name (_ADR, 0x00020000)
+               // Address of the VGA (device F function 0)
+               Name (_ADR, 0x000F0000)
Quoted 6 lines
Quoted 2 lines

With this change I still didn't see anything.

This does not match with what I see.

Looks like linux does not care about the acpi data. Using

The acpi data doesn't matter at all for the boot screen, the vgabios doesn't look at it.

Quoted 2 lines

(d12) Scan for VGA option rom (d12) Running option rom at c000:0003

seabios loaded+initialized the vgabios (from the pci rom bar of the vga device). Which slot the vga is installed at should not matter at all. seabios scans the pci bus and should find the vga with no problems no matter where it is.

Quoted 1 line

(XEN) stdvga.c:147:d12v0 entering stdvga and caching modes

Seems to have worked fine ;)

Quoted 3 lines

(d12) pmm call arg1=0
(d12) Turning on vga text mode console
(d12) SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54)

At this point you should see the seabios banner at the vga screen.

Quoted 4 lines

And the VGA screen has the SeaBIOS messages:

SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54) Machine UUID 18cf5fd0-e564-49c4-b63f-e6c3c23b1294

As it should be.

Now the questions is why it doesn't work for Tiejun ... Anything in the logs?

cheers,
Gerd

#56 lore raw

Re: [Qemu-devel] [v2][PATCH 4/8] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD

Quoted 39 lines · Gerd Hoffmann
   Hi,
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
               /* Make cirrues VGA S3 suspend/resume work in Windows
XP/2003 */
               Device (VGA)
               {
(quoted diff) +2 -1
-               Name (_ADR, 0x00020000)
+               // Address of the VGA (device F function 0)
+               Name (_ADR, 0x000F0000)
Quoted 6 lines
Quoted 2 lines

With this change I still didn't see anything.

This does not match with what I see.

Looks like linux does not care about the acpi data. Using

The acpi data doesn't matter at all for the boot screen, the vgabios doesn't look at it.

Quoted 2 lines

(d12) Scan for VGA option rom (d12) Running option rom at c000:0003

seabios loaded+initialized the vgabios (from the pci rom bar of the vga device). Which slot the vga is installed at should not matter at all. seabios scans the pci bus and should find the vga with no problems no matter where it is.

Quoted 1 line

(XEN) stdvga.c:147:d12v0 entering stdvga and caching modes

Seems to have worked fine ;)

Quoted 3 lines

(d12) pmm call arg1=0
(d12) Turning on vga text mode console
(d12) SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54)

At this point you should see the seabios banner at the vga screen.

Quoted 8 lines
Quoted 4 lines

And the VGA screen has the SeaBIOS messages:

SeaBIOS (version rel-1.7.5-0-ge51488c-20140626_113926-dcs-xen-54) Machine UUID 18cf5fd0-e564-49c4-b63f-e6c3c23b1294

As it should be.

Now the questions is why it doesn't work for Tiejun ...

Gerd and Don,

Thanks for your information.

But I have no time to validate this configuration now, I will update this as soon as I try Don's config file.

Thanks again.

Tiejun

Quoted 8 lines

Anything in the logs?

cheers,
Gerd

#57 lore raw

PATCH v2 5/8 xen, gfx passthrough: create intel isa bridge

In reply to Tiejun Chen

ISA bridge is needed since Intel gfx drive will probe it instead of Dev31:Fun0 to make graphics device passthrough work easy for VMM, that only need to expose ISA bridge to let driver know the real hardware underneath.

The original patch is from Allen Kay [[email protected]]

---
v2:

* Nothing is changed.

 hw/xen/xen_pt_graphics.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
hw/xen/xen_pt_graphics.c +71 -0
index e1f0724..6b86293 100644
@@ -175,3 +175,74 @@ out:
     g_free(bios);
     return rc;
 }
+
+static uint32_t isa_bridge_read_config(PCIDevice *d, uint32_t addr, int len)
+{
+    uint32_t v;
+
+    v = pci_default_read_config(d, addr, len);
+
+    return v;
+}
+
+static void isa_bridge_write_config(PCIDevice *d, uint32_t addr, uint32_t v,
+                                    int len)
+{
+    pci_default_write_config(d, addr, v, len);
+
+    return;
+}
+
+static void isa_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->config_read = isa_bridge_read_config;
+    k->config_write = isa_bridge_write_config;
+
+    return;
+};
+
+typedef struct {
+    PCIDevice dev;
+} ISABridgeState;
+
+static TypeInfo isa_bridge_info = {
+    .name          = "inte-pch-isa-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(ISABridgeState),
+    .class_init = isa_bridge_class_init,
+};
+
+static void xen_pt_graphics_register_types(void)
+{
+    type_register_static(&isa_bridge_info);
+}
+
+type_init(xen_pt_graphics_register_types)
+
+static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev)
+{
+    struct PCIDevice *dev;
+
+    char rid;
+
+    dev = pci_create(bus, PCI_DEVFN(0x1f, 0), "inte-pch-isa-bridge");
+    if (!dev) {
+        XEN_PT_LOG(dev, "fail to create PCH ISA bridge.\n");
+        return -1;
+    }
+
+    qdev_init_nofail(&dev->qdev);
+
+    pci_config_set_vendor_id(dev->config, hdev->vendor_id);
+    pci_config_set_device_id(dev->config, hdev->device_id);
+
+    xen_host_pci_get_block(hdev, PCI_REVISION_ID, (uint8_t *)&rid, 1);
+
+    pci_config_set_revision(dev->config, rid);
+    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_ISA);
+
+    XEN_PT_LOG(dev, "Intel PCH ISA bridge is created.\n");
+    return 0;
+}
Signature · 1 line
1.9.1
#58 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 5/8] xen, gfx passthrough: create intel isa bridge

Quoted 23 lines · Tiejun Chen

ISA bridge is needed since Intel gfx drive will probe it instead of Dev31:Fun0 to make graphics device passthrough work easy for VMM, that only need to expose ISA bridge to let driver know the real hardware underneath.

The original patch is from Allen Kay [[email protected]]

---
v2:

* Nothing is changed.

 hw/xen/xen_pt_graphics.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
hw/xen/xen_pt_graphics.c +0 -0
index e1f0724..6b86293 100644
@@ -175,3 +175,74 @@ out:
     g_free(bios);

hw/xen/xen_pt_graphics.c out: · line 185

Quoted 10 lines
hw/xen/xen_pt_graphics.c +8 -0
     return rc;
 }
+
+static uint32_t isa_bridge_read_config(PCIDevice *d, uint32_t addr, int len)
+{
+    uint32_t v;
+
+    v = pci_default_read_config(d, addr, len);
+
+    return v;

return pci_default_read_config...

Quoted 16 lines
hw/xen/xen_pt_graphics.c +16 -0
+}
+
+static void isa_bridge_write_config(PCIDevice *d, uint32_t addr, uint32_t v,
+                                    int len)
+{
+    pci_default_write_config(d, addr, v, len);
+
+    return;
+}
+
+static void isa_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->config_read = isa_bridge_read_config;
+    k->config_write = isa_bridge_write_config;

hw/xen/xen_pt_graphics.c out: · line 211

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+
+    return;
+};
+
+typedef struct {
+    PCIDevice dev;
+} ISABridgeState;
+
+static TypeInfo isa_bridge_info = {
+    .name          = "inte-pch-isa-bridge",

s/inte/intel/

Quoted 9 lines
hw/xen/xen_pt_graphics.c +9 -0
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(ISABridgeState),
+    .class_init = isa_bridge_class_init,
+};
+
+static void xen_pt_graphics_register_types(void)
+{
+    type_register_static(&isa_bridge_info);
+}

hw/xen/xen_pt_graphics.c out: · line 230

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+
+type_init(xen_pt_graphics_register_types)
+
+static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev)
+{
+    struct PCIDevice *dev;
+
+    char rid;
+
+    dev = pci_create(bus, PCI_DEVFN(0x1f, 0), "inte-pch-isa-bridge");

s/inte/intel/?

hw/xen/xen_pt_graphics.c out: · line 232

Quoted 2 lines
hw/xen/xen_pt_graphics.c +2 -0
+    if (!dev) {
+        XEN_PT_LOG(dev, "fail to create PCH ISA bridge.\n");

failed

hw/xen/xen_pt_graphics.c out: · line 233

Quoted 1 line
hw/xen/xen_pt_graphics.c +1 -0
+        return -1;

Could we return a better error code to help troubleshoot why we failed?

hw/xen/xen_pt_graphics.c out: · line 246

Quoted 13 lines
hw/xen/xen_pt_graphics.c +13 -0
+    }
+
+    qdev_init_nofail(&dev->qdev);
+
+    pci_config_set_vendor_id(dev->config, hdev->vendor_id);
+    pci_config_set_device_id(dev->config, hdev->device_id);
+
+    xen_host_pci_get_block(hdev, PCI_REVISION_ID, (uint8_t *)&rid, 1);
+
+    pci_config_set_revision(dev->config, rid);
+    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_ISA);
+
+    XEN_PT_LOG(dev, "Intel PCH ISA bridge is created.\n");

s/is//

Quoted 10 lines
hw/xen/xen_pt_graphics.c +2 -0
+    return 0;
+}
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#59 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 5/8] xen, gfx passthrough: create intel isa bridge

Quoted 42 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:12 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 5/8] xen, gfx passthrough: create intel isa bridge

Quoted 3 lines · Tiejun Chen

ISA bridge is needed since Intel gfx drive will probe it instead of Dev31:Fun0 to make graphics device passthrough work easy for VMM, that only need to expose ISA bridge to let driver know the real hardware

underneath.

Quoted 25 lines

The original patch is from Allen Kay [[email protected]]

---
v2:

* Nothing is changed.

 hw/xen/xen_pt_graphics.c | 71
++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
hw/xen/xen_pt_graphics.c index renamed from hw/xen/xen_pt_graphics.c +0 -0

e1f0724..6b86293 100644

hw/xen/xen_pt_graphics.c +2 -0
@@ -175,3 +175,74 @@ out:
     g_free(bios);
     return rc;
 }
+
+static uint32_t isa_bridge_read_config(PCIDevice *d, uint32_t addr,
Quoted 8 lines

hw/xen/xen_pt_graphics.c out: · line 185

Quoted 6 lines
hw/xen/xen_pt_graphics.c +6 -0
+int len) {
+    uint32_t v;
+
+    v = pci_default_read_config(d, addr, len);
+
+    return v;

return pci_default_read_config...

Fixed.

Quoted 19 lines
Quoted 19 lines
hw/xen/xen_pt_graphics.c +18 -0
+}
+
+static void isa_bridge_write_config(PCIDevice *d, uint32_t addr, uint32_t v,
+                                    int len) {
+    pci_default_write_config(d, addr, v, len);
+
+    return;
+}
+
+static void isa_bridge_class_init(ObjectClass *klass, void *data) {
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->config_read = isa_bridge_read_config;
+    k->config_write = isa_bridge_write_config;
+
+    return;
+};
+
Quoted 8 lines

hw/xen/xen_pt_graphics.c out: · line 211

Quoted 6 lines
hw/xen/xen_pt_graphics.c +6 -0
+typedef struct {
+    PCIDevice dev;
+} ISABridgeState;
+
+static TypeInfo isa_bridge_info = {
+    .name          = "inte-pch-isa-bridge",

s/inte/intel/

Fixed.

Quoted 13 lines
Quoted 13 lines
hw/xen/xen_pt_graphics.c +12 -0
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(ISABridgeState),
+    .class_init = isa_bridge_class_init, };
+
+static void xen_pt_graphics_register_types(void)
+{
+    type_register_static(&isa_bridge_info);
+}
+
+type_init(xen_pt_graphics_register_types)
+
+static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev)
Quoted 8 lines

hw/xen/xen_pt_graphics.c out: · line 230

Quoted 6 lines
hw/xen/xen_pt_graphics.c +6 -0
+{
+    struct PCIDevice *dev;
+
+    char rid;
+
+    dev = pci_create(bus, PCI_DEVFN(0x1f, 0), "inte-pch-isa-bridge");

s/inte/intel/?

Fixed.

Quoted 5 lines

hw/xen/xen_pt_graphics.c out: · line 232

Quoted 3 lines
hw/xen/xen_pt_graphics.c +2 -0
+    if (!dev) {
+        XEN_PT_LOG(dev, "fail to create PCH ISA bridge.\n");

failed

Fixed.

Quoted 4 lines

hw/xen/xen_pt_graphics.c out: · line 233

Quoted 2 lines
hw/xen/xen_pt_graphics.c +1 -0
+        return -1;

Could we return a better error code to help troubleshoot why we failed?

I take a look at this then I think we can remove these lines,

pci_create()

	|
	+ qdev_create()

And

DeviceState *qdev_create(BusState *bus, const char *name)

{
    DeviceState *dev; 
 
    dev = qdev_try_create(bus, name); 
    if (!dev) {
        if (bus) {
            error_report("Unknown device '%s' for bus '%s'", name, 
                         object_get_typename(OBJECT(bus)));
        } else { 
            error_report("Unknown device '%s' for default sysbus", name);
        }
        abort(); 
    }
Quoted 17 lines
Quoted 5 lines
hw/xen/xen_pt_graphics.c +4 -0
+    }
+
+    qdev_init_nofail(&dev->qdev);
+

hw/xen/xen_pt_graphics.c out: · line 246

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+    pci_config_set_vendor_id(dev->config, hdev->vendor_id);
+    pci_config_set_device_id(dev->config, hdev->device_id);
+
+    xen_host_pci_get_block(hdev, PCI_REVISION_ID, (uint8_t *)&rid,
+ 1);
+
+    pci_config_set_revision(dev->config, rid);
+    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_ISA);
+
+    XEN_PT_LOG(dev, "Intel PCH ISA bridge is created.\n");

s/is//

Fixed.

Thanks
Tiejun

#60 lore raw

PATCH v2 6/8 xen, gfx passthrough: support Intel IGD passthrough with VT-D

In reply to Tiejun Chen

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

The original patch is from Weidong Han < weidong.han @ intel.com >

---
v2:

* To introduce is_igd_passthrough() to make sure we touch physical host bridge only in IGD case.

 hw/xen/xen_pt.h          |   4 ++
 hw/xen/xen_pt_graphics.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
hw/xen/xen_pt.h +4 -0
index 4d3a18d..507165c 100644
@@ -302,5 +302,9 @@ extern int xen_has_gfx_passthru;
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
 int xen_pt_setup_vga(XenHostPCIDevice *dev);
+int pci_create_pch(PCIBus *bus);
+void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
+                   uint32_t val, int len);
+uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c +140 -0

149 lines not on this page · raw message

Signature · 1 line
1.9.1
#61 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 3 lines · Tiejun Chen

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

When you say mapped - you mean they are aliased - so if I change the value in the IGD they will change in the host bridge as well, right?

Quoted 49 lines

The original patch is from Weidong Han < weidong.han @ intel.com >

---
v2:

* To introduce is_igd_passthrough() to make sure we touch physical host bridge only in IGD case.

 hw/xen/xen_pt.h          |   4 ++
 hw/xen/xen_pt_graphics.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
hw/xen/xen_pt.h +4 -0
index 4d3a18d..507165c 100644
@@ -302,5 +302,9 @@ extern int xen_has_gfx_passthru;
 int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
 int xen_pt_setup_vga(XenHostPCIDevice *dev);
+int pci_create_pch(PCIBus *bus);
+void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
+                   uint32_t val, int len);
+uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c +4 -0
index 6b86293..066bc4d 100644
@@ -4,6 +4,7 @@
 #include "xen_pt.h"
 #include "xen-host-pci-device.h"
 #include "hw/xen/xen_backend.h"
+#include "hw/pci/pci_bus.h"
 
 static int is_vga_passthrough(XenHostPCIDevice *dev)
 {
@@ -246,3 +247,142 @@ static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev)
     XEN_PT_LOG(dev, "Intel PCH ISA bridge is created.\n");
     return 0;
 }
+
+int pci_create_pch(PCIBus *bus)
+{

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 262

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+    XenHostPCIDevice hdev;
+    int r = 0;
+
+    if (!xen_has_gfx_passthru) {
+        return -1;
+    }
+
+    r = xen_host_pci_device_get(&hdev, 0, 0, 0x1f, 0);
+    if (r) {
+        XEN_PT_ERR(NULL, "Fail to find intel PCH in host\n");

Failed to find Intel PCH on host!

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 269

Quoted 7 lines
hw/xen/xen_pt_graphics.c +7 -0
+        goto err;
+    }
+
+    if (hdev.vendor_id == PCI_VENDOR_ID_INTEL) {
+        r = create_pch_isa_bridge(bus, &hdev);
+        if (r) {
+            XEN_PT_ERR(NULL, "Fail to create PCH ISA bridge.\n");

Failed

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 276

Quoted 7 lines
hw/xen/xen_pt_graphics.c +7 -0
+            goto err;
+        }
+    }
+
+    xen_host_pci_device_put(&hdev);
+
+    return  r;

Remove this return and let it go through.

Quoted 17 lines
hw/xen/xen_pt_graphics.c +17 -0
+
+err:
+    return r;
+}
+
+/*
+ * Currently we just pass this physical host bridge for IGD, 00:02.0.
+ */
+static int is_igd_passthrough(PCIDevice *pci_dev)
+{
+    PCIDevice *f = pci_dev->bus->devices[PCI_DEVFN(2, 0)];
+    if (pci_dev->bus->devices[PCI_DEVFN(2, 0)]) {
+        XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, f);
+        return (is_vga_passthrough(&s->real_device)
+                    && (s->real_device.vendor_id == PCI_VENDOR_ID_INTEL));
+    } else {
+        return 0;

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 303

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+    }
+}
+
+void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
+                   uint32_t val, int len)
+{
+    XenHostPCIDevice dev;
+    int r;
+
+    assert(pci_dev->devfn == 0x00);

Now I am confused. That would mean the host bridge, while earlier (pci_create_pch) you were using the ISA bridge.

Could you add a comment please?

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 313

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+
+    if (!is_igd_passthrough(pci_dev)) {
+        goto write_default;
+    }
+
+    switch (config_addr) {
+    case 0x58:      /* PAVPC Offset */
+        break;
+    default:
+        goto write_default;

As I understand this function will be called when the guest tries to touch the configuration of the VGA and write in the configuration entries.

Quoted 12 lines
hw/xen/xen_pt_graphics.c +11 -0
+    }
+
+    /* Host write */
+    r = xen_host_pci_device_get(&dev, 0, 0, 0, 0);
 
+    if (r) {
+        XEN_PT_ERR(pci_dev, "Can't get pci_dev_host_bridge\n");
+        abort();
+    }
+
+    r = xen_host_pci_set_block(&dev, config_addr, (uint8_t *)&val, len);
+    if (r) {

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 334

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+        XEN_PT_ERR(pci_dev, "Can't get pci_dev_host_bridge\n");
+        abort();
+    }
+
+    xen_host_pci_device_put(&dev);
+
+    return;
+
+write_default:
+    pci_default_write_config(pci_dev, config_addr, val, len);

and we just allow it through. But what happens if the guest decides to change the BAR sizes? Or fiddle with the GTT?

Ouch. That really looks dangerous - or maybe I am too paranoid?

Quoted 62 lines
hw/xen/xen_pt_graphics.c +54 -0
+}
+
+uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len)
+{
+    XenHostPCIDevice dev;
+    uint32_t val;
+    int r;
+
+    assert(pci_dev->devfn == 0x00);
+
+    if (!is_igd_passthrough(pci_dev)) {
+        goto read_default;
+    }
+
+    switch (config_addr) {
+    case 0x00:        /* vendor id */
+    case 0x02:        /* device id */
+    case 0x08:        /* revision id */
+    case 0x2c:        /* sybsystem vendor id */
+    case 0x2e:        /* sybsystem id */
+    case 0x50:        /* SNB: processor graphics control register */
+    case 0x52:        /* processor graphics control register */
+    case 0xa0:        /* top of memory */
+    case 0xb0:        /* ILK: BSM: should read from dev 2 offset 0x5c */
+    case 0x58:        /* SNB: PAVPC Offset */
+    case 0xa4:        /* SNB: graphics base of stolen memory */
+    case 0xa8:        /* SNB: base of GTT stolen memory */
+        break;
+    default:
+        goto read_default;
+    }
+
+    /* Host read */
+    r = xen_host_pci_device_get(&dev, 0, 0, 0, 0);
+    if (r) {
+        goto err_out;
+    }
+
+    r = xen_host_pci_get_block(&dev, config_addr, (uint8_t *)&val, len);
+    if (r) {
+        goto err_out;
+    }
+
+    xen_host_pci_device_put(&dev);
+
+    return val;
+
+read_default:
+    return pci_default_read_config(pci_dev, config_addr, len);
+
+err_out:
+    XEN_PT_ERR(pci_dev, "Can't get pci_dev_host_bridge\n");
+    return -1;
+}
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#62 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Konrad Rzeszutek Wilk wrote on 2014-05-16:

Quoted 4 lines · Tiejun Chen
Quoted 3 lines

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

Thanks for your review for the whole series patch.

Quoted 3 lines

When you say mapped - you mean they are aliased - so if I change the value in the IGD they will change in the host bridge as well, right?

I guess you mean the physical host bridge. For it, only PAVPC will write to physical host bridge directly, see:

+ switch (config_addr) {
+ case 0x58: /* PAVPC Offset */
+ break;
+ default:
+ goto write_default;
+ }

Quoted 99 lines
Quoted 11 lines

The original patch is from Weidong Han < weidong.han @ intel.com >

<[email protected]>
---
v2:

* To introduce is_igd_passthrough() to make sure we touch physical host

bridge

Quoted 26 lines

only in IGD case.

 hw/xen/xen_pt.h          |   4 ++
 hw/xen/xen_pt_graphics.c | 140
+++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
hw/xen/xen_pt.h index 4d3a18d..507165c renamed from hw/xen/xen_pt.h +0 -0

100644

hw/xen/xen_pt.h +0 -0
@@ -302,5 +302,9 @@ extern int xen_has_gfx_passthru;  int

xen_pt_register_vga_regions(XenHostPCIDevice *dev); int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev); int xen_pt_setup_vga(XenHostPCIDevice *dev);

hw/xen/xen_pt.h +4 -0
+int pci_create_pch(PCIBus *bus);
+void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
+                   uint32_t val, int len); uint32_t
+igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_graphics.c index renamed from hw/xen/xen_pt_graphics.c +0 -0

6b86293..066bc4d 100644

hw/xen/xen_pt_graphics.c line 10

Quoted 7 lines
hw/xen/xen_pt_graphics.c +2 -0
@@ -4,6 +4,7 @@
 #include "xen_pt.h"
 #include "xen-host-pci-device.h"
 #include "hw/xen/xen_backend.h"
+#include "hw/pci/pci_bus.h"
 
 static int is_vga_passthrough(XenHostPCIDevice *dev)  { @@ -246,3
+247,142 @@ static int create_pch_isa_bridge(PCIBus *bus,

XenHostPCIDevice *hdev)

Quoted 6 lines
hw/xen/xen_pt_graphics.c +3 -0
     XEN_PT_LOG(dev, "Intel PCH ISA bridge is created.\n");
     return 0;
 }
+
+int pci_create_pch(PCIBus *bus)
+{

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 262

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+    XenHostPCIDevice hdev;
+    int r = 0;
+
+    if (!xen_has_gfx_passthru) {
+        return -1;
+    }
+
+    r = xen_host_pci_device_get(&hdev, 0, 0, 0x1f, 0);
+    if (r) {
+        XEN_PT_ERR(NULL, "Fail to find intel PCH in host\n");

Failed to find Intel PCH on host!

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 269

Quoted 7 lines
hw/xen/xen_pt_graphics.c +7 -0
+        goto err;
+    }
+
+    if (hdev.vendor_id == PCI_VENDOR_ID_INTEL) {
+        r = create_pch_isa_bridge(bus, &hdev);
+        if (r) {
+            XEN_PT_ERR(NULL, "Fail to create PCH ISA bridge.\n");

Failed

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 276

Quoted 7 lines
hw/xen/xen_pt_graphics.c +7 -0
+            goto err;
+        }
+    }
+
+    xen_host_pci_device_put(&hdev);
+
+    return  r;

Remove this return and let it go through.

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev)

Quoted 12 lines
hw/xen/xen_pt_graphics.c +12 -0
+
+err:
+    return r;
+}
+
+/*
+ * Currently we just pass this physical host bridge for IGD, 00:02.0.
+ */
+static int is_igd_passthrough(PCIDevice *pci_dev) {
+    PCIDevice *f = pci_dev->bus->devices[PCI_DEVFN(2, 0)];
+    if (pci_dev->bus->devices[PCI_DEVFN(2, 0)]) {
+        XenPCIPassthroughState *s =

DO_UPCAST(XenPCIPassthroughState, dev, f);

hw/xen/xen_pt_graphics.c

Quoted 2 lines
hw/xen/xen_pt_graphics.c +2 -0
+        return (is_vga_passthrough(&s->real_device)
+                    && (s->real_device.vendor_id ==

PCI_VENDOR_ID_INTEL));

Quoted 14 lines

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 303

Quoted 11 lines
hw/xen/xen_pt_graphics.c +11 -0
+    } else {
+        return 0;
+    }
+}
+
+void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
+                   uint32_t val, int len) {
+    XenHostPCIDevice dev;
+    int r;
+
+    assert(pci_dev->devfn == 0x00);

Now I am confused. That would mean the host bridge, while earlier (pci_create_pch) you were using the ISA bridge.

IGD read/write is through the host bridge.
ISA bridge is only for detect purpose. In i915 driver it will probe ISA bridge to discover the IGD, see comment in i915_drv.c:
intel_detect_pch():
* The reason to probe ISA bridge instead of Dev31:Fun0 is to
* make graphics device passthrough work easy for VMM, that only
* need to expose ISA bridge to let driver know the real hardware
* underneath. This is a requirement from virtualization team.

Quoted 2 lines

Could you add a comment please?

Sure.

Quoted 41 lines

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 313

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+
+    if (!is_igd_passthrough(pci_dev)) {
+        goto write_default;
+    }
+
+    switch (config_addr) {
+    case 0x58:      /* PAVPC Offset */
+        break;
+    default:
+        goto write_default;

As I understand this function will be called when the guest tries to touch the configuration of the VGA and write in the configuration entries.

Quoted 12 lines
hw/xen/xen_pt_graphics.c +11 -0
+    }
+
+    /* Host write */
+    r = xen_host_pci_device_get(&dev, 0, 0, 0, 0);
 
+    if (r) {
+        XEN_PT_ERR(pci_dev, "Can't get pci_dev_host_bridge\n");
+        abort();
+    }
+
+    r = xen_host_pci_set_block(&dev, config_addr, (uint8_t *)&val, len);
+    if (r) {

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 334

Quoted 10 lines
hw/xen/xen_pt_graphics.c +10 -0
+        XEN_PT_ERR(pci_dev, "Can't get pci_dev_host_bridge\n");
+        abort();
+    }
+
+    xen_host_pci_device_put(&dev);
+
+    return;
+
+write_default:
+    pci_default_write_config(pci_dev, config_addr, val, len);

and we just allow it through. But what happens if the guest decides to change the BAR sizes? Or fiddle with the GTT?

Quoted 2 lines

Ouch. That really looks dangerous - or maybe I am too paranoid?

I do not quite understand your concern. We only pass through PAVPC to physical host bridge. The others are handled by current logic. We don't change any of it. So what problem will be exposed by this patch?

Best regards,
Yang

#63 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 7 lines · Yang Z

Konrad Rzeszutek Wilk wrote on 2014-05-16:

Quoted 4 lines · Tiejun Chen
Quoted 3 lines

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

Thanks for your review for the whole series patch.

Sure thing!

.. snip..

Quoted 11 lines
Quoted 9 lines

hw/xen/xen_pt_graphics.c static int create_pch_isa_bridge(PCIBus *bus, XenHostPCIDevice *hdev) · line 334

Quoted 2 lines
hw/xen/xen_pt_graphics.c +2 -0
+write_default:
+    pci_default_write_config(pci_dev, config_addr, val, len);

and we just allow it through. But what happens if the guest decides to change the BAR sizes? Or fiddle with the GTT?

Ouch. That really looks dangerous - or maybe I am too paranoid?

I do not quite understand your concern. We only pass through PAVPC to physical host bridge. The others are handled by current logic. We don't change any of it. So what problem will be exposed by this patch?

Ah, I assumed that pci_default_write_config would be writting everything without any checks. But it looks to be doing the right thing and just sets the emulated values.

Could we just add comment saying that it writes to the emulated values? That way it won't trip folks.

Quoted 5 lines

Best regards,
Yang

#64 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 38 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Monday, May 19, 2014 9:34 PM
To: Zhang, Yang Z
Cc: Chen, Tiejun; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]
Subject: Re: [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 7 lines · Yang Z

Konrad Rzeszutek Wilk wrote on 2014-05-16:

Quoted 4 lines · Tiejun Chen
Quoted 3 lines

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

Thanks for your review for the whole series patch.

Sure thing!

.. snip..

Quoted 11 lines
Quoted 9 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+write_default:
+    pci_default_write_config(pci_dev, config_addr, val, len);

and we just allow it through. But what happens if the guest decides to change the BAR sizes? Or fiddle with the GTT?

Ouch. That really looks dangerous - or maybe I am too paranoid?

I do not quite understand your concern. We only pass through PAVPC to

physical host bridge. The others are handled by current logic. We don't change any of it. So what problem will be exposed by this patch?

Quoted 6 lines

Ah, I assumed that pci_default_write_config would be writting everything without any checks. But it looks to be doing the right thing and just sets the emulated values.

Could we just add comment saying that it writes to the emulated values? That way it won't trip folks.

hw/xen/xen_pt_graphics.c +2 -0
index 1342f4f..5e5e3d5 100644
@@ -367,6 +367,7 @@ void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
     case 0x58:      /* PAVPC Offset */
         break;
     default:
+        /* Just sets the emulated values. */
         goto write_default;
     }
 
@@ -427,6 +428,7 @@ uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len)
     case 0xa8:        /* SNB: base of GTT stolen memory */
         break;
     default:
+        /* Just gets the emulated values. */
         goto read_default;
     }
 

Thanks
Tiejun

#65 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 58 lines · Tiejun
Quoted 44 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Monday, May 19, 2014 9:34 PM
To: Zhang, Yang Z
Cc: Chen, Tiejun; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]
Subject: Re: [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 7 lines · Yang Z

Konrad Rzeszutek Wilk wrote on 2014-05-16:

Quoted 4 lines · Tiejun Chen
Quoted 3 lines

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

Thanks for your review for the whole series patch.

Sure thing!

.. snip..

Quoted 11 lines
Quoted 9 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+write_default:
+    pci_default_write_config(pci_dev, config_addr, val, len);

and we just allow it through. But what happens if the guest decides to change the BAR sizes? Or fiddle with the GTT?

Ouch. That really looks dangerous - or maybe I am too paranoid?

I do not quite understand your concern. We only pass through PAVPC to

physical host bridge. The others are handled by current logic. We don't change any of it. So what problem will be exposed by this patch?

Ah, I assumed that pci_default_write_config would be writting everything without any checks. But it looks to be doing the right thing and just sets the emulated values.

Could we just add comment saying that it writes to the emulated values? That way it won't trip folks.

hw/xen/xen_pt_graphics.c +1 -0
index 1342f4f..5e5e3d5 100644
@@ -367,6 +367,7 @@ void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
     case 0x58:      /* PAVPC Offset */
         break;
     default:
+        /* Just sets the emulated values. */
         goto write_default;
     }
 

hw/xen/xen_pt_graphics.c uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len) · line 432

Quoted 5 lines
hw/xen/xen_pt_graphics.c +1 -0
@@ -427,6 +428,7 @@ uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len)
     case 0xa8:        /* SNB: base of GTT stolen memory */
         break;
     default:
+        /* Just gets the emulated values. */
         goto read_default;

Thanks!

Quoted 4 lines
hw/xen/xen_pt_graphics.c +0 -0
     }
 

Thanks
Tiejun

#66 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

In reply to Konrad Rzeszutek Wilk
Quoted 14 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:35 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 6/8] xen, gfx passthrough: support Intel IGD passthrough with VT-D

Quoted 8 lines
Quoted 3 lines · Tiejun Chen

Some registers of Intel IGD are mapped in host bridge, so it needs to passthrough these registers of physical host bridge to guest because emulated host bridge in guest doesn't have these mappings.

When you say mapped - you mean they are aliased - so if I change the value in the IGD they will change in the host bridge as well, right?

Loos Yang already address some most points, so I just correct others based on your comments.

Thanks
Tiejun

#67 lore raw

PATCH v2 7/8 xen, gfx passthrough: create host bridge to passthrough

In reply to Tiejun Chen

Implement that pci host bridge to specific to passthrough. Actually thsi just inherit the standard one.

---
v2:

* New patch.

 hw/pci-host/piix.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)
hw/pci-host/piix.c +54 -2
index b6f49bd..f79b582 100644
@@ -34,6 +34,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/i386/ioapic.h"
 #include "qapi/visitor.h"
+#include "hw/xen/xen_pt.h"
 
 /*
  * I440FX chipset data sheet.
@@ -95,6 +96,10 @@ typedef struct PIIX3State {
 #define I440FX_PCI_DEVICE(obj) \
     OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
 
+#define TYPE_I440FX_XEN_PCI_DEVICE "i440FX-xen"
+#define I440FX_XEN_PCI_DEVICE(obj) \
+    OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_XEN_PCI_DEVICE)
+
 struct PCII440FXState {
     /*< private >*/
     PCIDevice parent_obj;
@@ -305,6 +310,16 @@ static int i440fx_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int i440fx_xen_initfn(PCIDevice *dev)
+{
+    PCII440FXState *d = I440FX_XEN_PCI_DEVICE(dev);
+
+    dev->config[I440FX_SMRAM] = 0x02;
+
+    cpu_smm_register(&i440fx_set_smm, d);
+    return 0;
+}
+
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
                     int *piix3_devfn,
                     ISABus **isa_bus, qemu_irq *pic,
@@ -341,8 +356,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
 
-    d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);
-    *pi440fx_state = I440FX_PCI_DEVICE(d);
+    if (xen_enabled()) {
+        d = pci_create_simple(b, 0, TYPE_I440FX_XEN_PCI_DEVICE);
+        *pi440fx_state = I440FX_XEN_PCI_DEVICE(d);
+        pci_create_pch(b);
+    } else {
+        d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);
+        *pi440fx_state = I440FX_PCI_DEVICE(d);
+    }
+
     f = *pi440fx_state;
     f->system_memory = address_space_mem;
     f->pci_address_space = pci_address_space;
@@ -713,6 +735,35 @@ static const TypeInfo i440fx_info = {
     .class_init    = i440fx_class_init,
 };
 
+static void i440fx_xen_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = i440fx_xen_initfn;
+    k->config_write = igd_pci_write;
+    k->config_read = igd_pci_read;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82441;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+    dc->desc = "XEN Host bridge";
+    dc->vmsd = &vmstate_i440fx;
+    /*
+     * PCI-facing part of the host bridge, not usable without the
+     * host-facing part, which can't be device_add'ed, yet.
+     */
+    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->hotpluggable   = false;
+}
+
+static const TypeInfo i440fx_xen_info = {
+    .name          = TYPE_I440FX_XEN_PCI_DEVICE,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCII440FXState),
+    .class_init    = i440fx_xen_class_init,
+};
+
 static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
                                                 PCIBus *rootbus)
 {
@@ -754,6 +805,7 @@ static const TypeInfo i440fx_pcihost_info = {
 static void i440fx_register_types(void)
 {
     type_register_static(&i440fx_info);
+    type_register_static(&i440fx_xen_info);
     type_register_static(&piix3_info);
     type_register_static(&piix3_xen_info);
     type_register_static(&i440fx_pcihost_info);
Signature · 1 line
1.9.1
#68 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 7/8] xen, gfx passthrough: create host bridge to passthrough

Quoted 2 lines · Tiejun Chen

Implement that pci host bridge to specific to passthrough. Actually thsi just inherit the standard one.

this just inherits

Quoted 120 lines

---
v2:

* New patch.

 hw/pci-host/piix.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)
hw/pci-host/piix.c +54 -2
index b6f49bd..f79b582 100644
@@ -34,6 +34,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/i386/ioapic.h"
 #include "qapi/visitor.h"
+#include "hw/xen/xen_pt.h"
 
 /*
  * I440FX chipset data sheet.
@@ -95,6 +96,10 @@ typedef struct PIIX3State {
 #define I440FX_PCI_DEVICE(obj) \
     OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
 
+#define TYPE_I440FX_XEN_PCI_DEVICE "i440FX-xen"
+#define I440FX_XEN_PCI_DEVICE(obj) \
+    OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_XEN_PCI_DEVICE)
+
 struct PCII440FXState {
     /*< private >*/
     PCIDevice parent_obj;
@@ -305,6 +310,16 @@ static int i440fx_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int i440fx_xen_initfn(PCIDevice *dev)
+{
+    PCII440FXState *d = I440FX_XEN_PCI_DEVICE(dev);
+
+    dev->config[I440FX_SMRAM] = 0x02;
+
+    cpu_smm_register(&i440fx_set_smm, d);
+    return 0;
+}
+
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
                     int *piix3_devfn,
                     ISABus **isa_bus, qemu_irq *pic,
@@ -341,8 +356,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
 
-    d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);
-    *pi440fx_state = I440FX_PCI_DEVICE(d);
+    if (xen_enabled()) {
+        d = pci_create_simple(b, 0, TYPE_I440FX_XEN_PCI_DEVICE);
+        *pi440fx_state = I440FX_XEN_PCI_DEVICE(d);
+        pci_create_pch(b);
+    } else {
+        d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);
+        *pi440fx_state = I440FX_PCI_DEVICE(d);
+    }
+
     f = *pi440fx_state;
     f->system_memory = address_space_mem;
     f->pci_address_space = pci_address_space;
@@ -713,6 +735,35 @@ static const TypeInfo i440fx_info = {
     .class_init    = i440fx_class_init,
 };
 
+static void i440fx_xen_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = i440fx_xen_initfn;
+    k->config_write = igd_pci_write;
+    k->config_read = igd_pci_read;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82441;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+    dc->desc = "XEN Host bridge";
+    dc->vmsd = &vmstate_i440fx;
+    /*
+     * PCI-facing part of the host bridge, not usable without the
+     * host-facing part, which can't be device_add'ed, yet.
+     */
+    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->hotpluggable   = false;
+}
+
+static const TypeInfo i440fx_xen_info = {
+    .name          = TYPE_I440FX_XEN_PCI_DEVICE,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCII440FXState),
+    .class_init    = i440fx_xen_class_init,
+};
+
 static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
                                                 PCIBus *rootbus)
 {
@@ -754,6 +805,7 @@ static const TypeInfo i440fx_pcihost_info = {
 static void i440fx_register_types(void)
 {
     type_register_static(&i440fx_info);
+    type_register_static(&i440fx_xen_info);
     type_register_static(&piix3_info);
     type_register_static(&piix3_xen_info);
     type_register_static(&i440fx_pcihost_info);
Signature · 7 lines
1.9.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#69 lore raw

Re: [Qemu-devel] [Xen-devel] [v2][PATCH 7/8] xen, gfx passthrough: create host bridge to passthrough

Quoted 12 lines

-----Original Message-----
From: Konrad Rzeszutek Wilk [mailto:[email protected]]
Sent: Friday, May 16, 2014 10:37 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; [email protected]; Zhang, Yang Z
Subject: Re: [Xen-devel] [v2][PATCH 7/8] xen, gfx passthrough: create host bridge to passthrough

Quoted 6 lines
Quoted 2 lines · Tiejun Chen

Implement that pci host bridge to specific to passthrough. Actually thsi just inherit the standard one.

this just inherits

Fixed.

Thanks
Tiejun

#70 lore raw

PATCH v2 8/8 xen, gfx passthrough: add opregion mapping

In reply to Tiejun Chen

The OpRegion shouldn't be mapped 1:1 because the address in the host can't be used in the guest directly.

This patch traps read and write access to the opregion of the Intel GPU config space (offset 0xfc).

The original patch is from Jean Guyader <[email protected]>

---
v2:

* We should return zero as an invalid address value while calling igd_read_opregion().

 hw/xen/xen_pt.h             |  4 +++-
 hw/xen/xen_pt_config_init.c | 45 ++++++++++++++++++++++++++++++++++++++++++-
 hw/xen/xen_pt_graphics.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 2 deletions(-)
hw/xen/xen_pt.h +3 -1
index 507165c..25147cf 100644
@@ -63,7 +63,7 @@ typedef int (*xen_pt_conf_byte_read)
 #define XEN_PT_BAR_UNMAPPED (-1)
 
 #define PCI_CAP_MAX 48
-
+#define PCI_INTEL_OPREGION 0xfc
 
 typedef enum {
     XEN_PT_GRP_TYPE_HARDWIRED = 0,  /* 0 Hardwired reg group */
@@ -306,5 +306,7 @@ int pci_create_pch(PCIBus *bus);
 void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
                    uint32_t val, int len);
 uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);
+uint32_t igd_read_opregion(XenPCIPassthroughState *s);
+void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_config_init.c +44 -1

75 lines not on this page · raw message

hw/xen/xen_pt_graphics.c +47 -0

56 lines not on this page · raw message

Signature · 1 line
1.9.1
#71 lore raw

Re: [Qemu-devel] [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

Quoted 96 lines · Tiejun Chen

The OpRegion shouldn't be mapped 1:1 because the address in the host can't be used in the guest directly.

This patch traps read and write access to the opregion of the Intel GPU config space (offset 0xfc).

The original patch is from Jean Guyader <[email protected]>

---
v2:

* We should return zero as an invalid address value while calling igd_read_opregion().

 hw/xen/xen_pt.h             |  4 +++-
 hw/xen/xen_pt_config_init.c | 45 ++++++++++++++++++++++++++++++++++++++++++-
 hw/xen/xen_pt_graphics.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 2 deletions(-)
hw/xen/xen_pt.h +3 -1
index 507165c..25147cf 100644
@@ -63,7 +63,7 @@ typedef int (*xen_pt_conf_byte_read)
 #define XEN_PT_BAR_UNMAPPED (-1)
 
 #define PCI_CAP_MAX 48
-
+#define PCI_INTEL_OPREGION 0xfc
 
 typedef enum {
     XEN_PT_GRP_TYPE_HARDWIRED = 0,  /* 0 Hardwired reg group */
@@ -306,5 +306,7 @@ int pci_create_pch(PCIBus *bus);
 void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
                    uint32_t val, int len);
 uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);
+uint32_t igd_read_opregion(XenPCIPassthroughState *s);
+void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_config_init.c +31 -0
index de9a20f..cf36a40 100644
@@ -575,6 +575,22 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
     return 0;
 }
 
+static int xen_pt_intel_opregion_read(XenPCIPassthroughState *s,
+                                      XenPTReg *cfg_entry,
+                                      uint32_t *value, uint32_t valid_mask)
+{
+    *value = igd_read_opregion(s);
+    return 0;
+}
+
+static int xen_pt_intel_opregion_write(XenPCIPassthroughState *s,
+                                       XenPTReg *cfg_entry, uint32_t *value,
+                                       uint32_t dev_value, uint32_t valid_mask)
+{
+    igd_write_opregion(s, *value);
+    return 0;
+}
+
 /* Header Type0 reg static information table */
 static XenPTRegInfo xen_pt_emu_reg_header0[] = {
     /* Vendor ID reg */
@@ -1440,6 +1456,20 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
     },
 };
 
+static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
+    /* Intel IGFX OpRegion reg */
+    {
+        .offset     = 0x0,
+        .size       = 4,
+        .init_val   = 0,
+        .no_wb      = 1,
+        .u.dw.read   = xen_pt_intel_opregion_read,
+        .u.dw.write  = xen_pt_intel_opregion_write,
+    },
+    {
+        .size = 0,
+    },
+};
 
 /****************************
  * Capabilities
@@ -1677,6 +1707,14 @@ static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = {
         .size_init   = xen_pt_msix_size_init,
         .emu_regs = xen_pt_emu_reg_msix,
     },
+    /* Intel IGD Opregion group */

hw/xen/xen_pt_config_init.c static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = { · line 1720

Quoted 10 lines
hw/xen/xen_pt_config_init.c +7 -0
+    {
+        .grp_id      = PCI_INTEL_OPREGION,
+        .grp_type    = XEN_PT_GRP_TYPE_EMU,
+        .grp_size    = 0x4,
+        .size_init   = xen_pt_reg_grp_size_init,
+        .emu_regs    = xen_pt_emu_reg_igd_opregion,
+    },
     {
         .grp_size = 0,
     },

If I am not mistaken, in the original patch to qemu-xen-traditional, we were not adding an Intel IGD Opregion group. Instead we were changing the size of the header Type0 reg group:

+static uint8_t pt_reg_grp_header0_size_init(struct pt_dev *ptdev,
+ struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
+{

+    /*
+    ** By default we will trap up to 0x40 in the cfg space.
+    ** If an intel device is pass through we need to trap 0xfc,
+    ** therefore the size should be 0xff.
+    */
+    if (igd_passthru)

+ return 0xFF;
+ return grp_reg->grp_size;
+}

Here instead we are adding the new group and forcing the offset to be PCI_INTEL_OPREGION, below. It looks functionally equivalent, but nicer.

But wouldn't it be even better to have find_cap_offset return the right offset for Intel IGD Opregion group? Why do we need to manually set reg_grp_offset to PCI_INTEL_OPREGION?

Quoted 86 lines
hw/xen/xen_pt_config_init.c +6 -1
@@ -1806,7 +1844,8 @@ int xen_pt_config_init(XenPCIPassthroughState *s)
         uint32_t reg_grp_offset = 0;
         XenPTRegGroup *reg_grp_entry = NULL;
 
-        if (xen_pt_emu_reg_grps[i].grp_id != 0xFF) {
+        if (xen_pt_emu_reg_grps[i].grp_id != 0xFF
+            && xen_pt_emu_reg_grps[i].grp_id != PCI_INTEL_OPREGION) {
             if (xen_pt_hide_dev_cap(&s->real_device,
                                     xen_pt_emu_reg_grps[i].grp_id)) {
                 continue;
@@ -1819,6 +1858,10 @@ int xen_pt_config_init(XenPCIPassthroughState *s)
             }
         }
 
+        if (xen_pt_emu_reg_grps[i].grp_id == PCI_INTEL_OPREGION) {
+            reg_grp_offset = PCI_INTEL_OPREGION;
+        }
+
         reg_grp_entry = g_new0(XenPTRegGroup, 1);
         QLIST_INIT(&reg_grp_entry->reg_tbl_list);
         QLIST_INSERT_HEAD(&s->reg_grps, reg_grp_entry, entries);
hw/xen/xen_pt_graphics.c +47 -0
index 066bc4d..b25ecae 100644
@@ -6,6 +6,8 @@
 #include "hw/xen/xen_backend.h"
 #include "hw/pci/pci_bus.h"
 
+static int igd_guest_opregion;
+
 static int is_vga_passthrough(XenHostPCIDevice *dev)
 {
     return (xen_has_gfx_passthru
@@ -386,3 +388,48 @@ err_out:
     XEN_PT_ERR(pci_dev, "Can't get pci_dev_host_bridge\n");
     return -1;
 }
+
+uint32_t igd_read_opregion(XenPCIPassthroughState *s)
+{
+    uint32_t val = 0;
+
+    if (igd_guest_opregion == 0) {
+        return val;
+    }
+
+    val = igd_guest_opregion;
+
+    XEN_PT_LOG(&s->dev, "Read opregion val=%x\n", val);
+    return val;
+}
+
+void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val)
+{
+    uint32_t host_opregion = 0;
+    int ret;
+
+    if (igd_guest_opregion) {
+        XEN_PT_LOG(&s->dev, "opregion register already been set, ignoring %x\n",
+                   val);
+        return;
+    }
+
+    xen_host_pci_get_block(&s->real_device, PCI_INTEL_OPREGION,
+            (uint8_t *)&host_opregion, 4);
+    igd_guest_opregion = (val & ~0xfff) | (host_opregion & 0xfff);
+
+    ret = xc_domain_memory_mapping(xen_xc, xen_domid,
+            igd_guest_opregion >> XC_PAGE_SHIFT,
+            host_opregion >> XC_PAGE_SHIFT,
+            2,
+            DPCI_ADD_MAPPING);
+
+    if (ret != 0) {
+        XEN_PT_ERR(&s->dev, "Error: Can't map opregion\n");
+        igd_guest_opregion = 0;
+        return;
+    }
+
+    XEN_PT_LOG(&s->dev, "Map OpRegion: %x -> %x\n", host_opregion,
+            igd_guest_opregion);
+}
Signature · 1 line
1.9.1
#72 lore raw

Re: [Qemu-devel] [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

Quoted 153 lines

-----Original Message-----
From: Stefano Stabellini [mailto:[email protected]]
Sent: Monday, May 19, 2014 7:54 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; Zhang, Yang Z
Subject: Re: [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

Quoted 11 lines · Tiejun Chen

The OpRegion shouldn't be mapped 1:1 because the address in the host can't be used in the guest directly.

This patch traps read and write access to the opregion of the Intel GPU config space (offset 0xfc).

The original patch is from Jean Guyader <[email protected]>

Quoted 8 lines

---
v2:

* We should return zero as an invalid address value while calling igd_read_opregion().

 hw/xen/xen_pt.h             |  4 +++-
 hw/xen/xen_pt_config_init.c | 45

++++++++++++++++++++++++++++++++++++++++++-

Quoted 1 line
 hw/xen/xen_pt_graphics.c    | 47

+++++++++++++++++++++++++++++++++++++++++++++

Quoted 7 lines
 3 files changed, 94 insertions(+), 2 deletions(-)
hw/xen/xen_pt.h index 507165c..25147cf renamed from hw/xen/xen_pt.h +0 -0

100644

hw/xen/xen_pt.h typedef int (*xen_pt_conf_byte_read) #define · line 69

Quoted 8 lines
hw/xen/xen_pt.h +1 -1
@@ -63,7 +63,7 @@ typedef int (*xen_pt_conf_byte_read)  #define
 XEN_PT_BAR_UNMAPPED (-1)
 
 #define PCI_CAP_MAX 48
-
+#define PCI_INTEL_OPREGION 0xfc
 
 typedef enum {
     XEN_PT_GRP_TYPE_HARDWIRED = 0,  /* 0 Hardwired reg group */

@@

hw/xen/xen_pt_config_init.c static int

Quoted 13 lines

-306,5 +306,7 @@ int pci_create_pch(PCIBus *bus); void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,

                    uint32_t val, int len);  uint32_t

igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);

hw/xen/xen_pt.h +2 -0
+uint32_t igd_read_opregion(XenPCIPassthroughState *s); void
+igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_config_init.c +0 -0
index de9a20f..cf36a40 100644
@@ -575,6 +575,22 @@ static int

xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,

hw/xen/xen_pt_config_init.c static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,

Quoted 13 lines
hw/xen/xen_pt_config_init.c +10 -0
     return 0;
 }
 
+static int xen_pt_intel_opregion_read(XenPCIPassthroughState *s,
+                                      XenPTReg *cfg_entry,
+                                      uint32_t *value, uint32_t
+valid_mask) {
+    *value = igd_read_opregion(s);
+    return 0;
+}
+
+static int xen_pt_intel_opregion_write(XenPCIPassthroughState *s,
+                                       XenPTReg *cfg_entry,

uint32_t *value,

hw/xen/xen_pt_config_init.c static int · line 588

Quoted 1 line
hw/xen/xen_pt_config_init.c +1 -0
+                                       uint32_t dev_value,

uint32_t

hw/xen/xen_pt_config_init.c static const XenPTRegGroupInfo

Quoted 30 lines
hw/xen/xen_pt_config_init.c +19 -0
+valid_mask) {
+    igd_write_opregion(s, *value);
+    return 0;
+}
+
 /* Header Type0 reg static information table */  static XenPTRegInfo
 xen_pt_emu_reg_header0[] = {
     /* Vendor ID reg */
@@ -1440,6 +1456,20 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
     },
 };
 
+static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
+    /* Intel IGFX OpRegion reg */
+    {
+        .offset     = 0x0,
+        .size       = 4,
+        .init_val   = 0,
+        .no_wb      = 1,
+        .u.dw.read   = xen_pt_intel_opregion_read,
+        .u.dw.write  = xen_pt_intel_opregion_write,
+    },
+    {
+        .size = 0,
+    },
+};
 
 /****************************
  * Capabilities
@@ -1677,6 +1707,14 @@ static const XenPTRegGroupInfo

xen_pt_emu_reg_grps[] = {

Quoted 4 lines
hw/xen/xen_pt_config_init.c +1 -0
         .size_init   = xen_pt_msix_size_init,
         .emu_regs = xen_pt_emu_reg_msix,
     },
+    /* Intel IGD Opregion group */

hw/xen/xen_pt_config_init.c static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = { · line 1720

Quoted 10 lines
hw/xen/xen_pt_config_init.c +7 -0
+    {
+        .grp_id      = PCI_INTEL_OPREGION,
+        .grp_type    = XEN_PT_GRP_TYPE_EMU,
+        .grp_size    = 0x4,
+        .size_init   = xen_pt_reg_grp_size_init,
+        .emu_regs    = xen_pt_emu_reg_igd_opregion,
+    },
     {
         .grp_size = 0,
     },

If I am not mistaken, in the original patch to qemu-xen-traditional, we were not adding an Intel IGD Opregion group. Instead we were changing the size of the header Type0 reg group:

(quoted diff) +11 -0
+static uint8_t pt_reg_grp_header0_size_init(struct pt_dev *ptdev,
+        struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset) {
+    /*
+    ** By default we will trap up to 0x40 in the cfg space.
+    ** If an intel device is pass through we need to trap 0xfc,
+    ** therefore the size should be 0xff.
+    */
+    if (igd_passthru)
+        return 0xFF;
+    return grp_reg->grp_size;
+}

Here instead we are adding the new group and forcing the offset to be PCI_INTEL_OPREGION, below. It looks functionally equivalent, but nicer.

But wouldn't it be even better to have find_cap_offset return the right offset for Intel IGD Opregion group? Why do we need to manually set reg_grp_offset to PCI_INTEL_OPREGION?

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState

Quoted 1 line
hw/xen/xen_pt_config_init.c +0 -0
@@ -1806,7 +1844,8 @@ int xen_pt_config_init(XenPCIPassthroughState

*s)

Quoted 7 lines

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState *s)

Quoted 6 lines
hw/xen/xen_pt_config_init.c +2 -1
         uint32_t reg_grp_offset = 0;
         XenPTRegGroup *reg_grp_entry = NULL;
 
-        if (xen_pt_emu_reg_grps[i].grp_id != 0xFF) {
+        if (xen_pt_emu_reg_grps[i].grp_id != 0xFF
+            && xen_pt_emu_reg_grps[i].grp_id !=

PCI_INTEL_OPREGION) {

Actually in this emulated case we still call find_cap_offset() to get reg_grp_offset.

Quoted 13 lines

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState · line 1850

Quoted 2 lines
hw/xen/xen_pt_config_init.c +0 -0
             if (xen_pt_hide_dev_cap(&s->real_device,
 

xen_pt_emu_reg_grps[i].grp_id)) {

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState

Quoted 2 lines
hw/xen/xen_pt_config_init.c +0 -0
                 continue;
@@ -1819,6 +1858,10 @@ int xen_pt_config_init(XenPCIPassthroughState

*s)

Quoted 7 lines
hw/xen/xen_pt_config_init.c +4 -0
             }
         }
 
+        if (xen_pt_emu_reg_grps[i].grp_id == PCI_INTEL_OPREGION) {
+            reg_grp_offset = PCI_INTEL_OPREGION;
+        }
+

But for this pass through scenario, we have to set 0xfc manually since we need to trap 0xfc completely in that comment:

+    /*
+    ** By default we will trap up to 0x40 in the cfg space.
+    ** If an intel device is pass through we need to trap 0xfc,
+    ** therefore the size should be 0xff.
+    */

Thanks
Tiejun

#73 lore raw

Re: [Qemu-devel] [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

Quoted 179 lines · Tiejun
Quoted 153 lines

-----Original Message-----
From: Stefano Stabellini [mailto:[email protected]]
Sent: Monday, May 19, 2014 7:54 PM
To: Chen, Tiejun
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; [email protected]; Zhang, Yang Z
Subject: Re: [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

Quoted 11 lines · Tiejun Chen

The OpRegion shouldn't be mapped 1:1 because the address in the host can't be used in the guest directly.

This patch traps read and write access to the opregion of the Intel GPU config space (offset 0xfc).

The original patch is from Jean Guyader <[email protected]>

Quoted 8 lines

---
v2:

* We should return zero as an invalid address value while calling igd_read_opregion().

 hw/xen/xen_pt.h             |  4 +++-
 hw/xen/xen_pt_config_init.c | 45

++++++++++++++++++++++++++++++++++++++++++-

Quoted 1 line
 hw/xen/xen_pt_graphics.c    | 47

+++++++++++++++++++++++++++++++++++++++++++++

Quoted 7 lines
 3 files changed, 94 insertions(+), 2 deletions(-)
hw/xen/xen_pt.h index 507165c..25147cf renamed from hw/xen/xen_pt.h +0 -0

100644

hw/xen/xen_pt.h typedef int (*xen_pt_conf_byte_read) #define · line 69

Quoted 8 lines
hw/xen/xen_pt.h +1 -1
@@ -63,7 +63,7 @@ typedef int (*xen_pt_conf_byte_read)  #define
 XEN_PT_BAR_UNMAPPED (-1)
 
 #define PCI_CAP_MAX 48
-
+#define PCI_INTEL_OPREGION 0xfc
 
 typedef enum {
     XEN_PT_GRP_TYPE_HARDWIRED = 0,  /* 0 Hardwired reg group */

@@

hw/xen/xen_pt_config_init.c static int

Quoted 13 lines

-306,5 +306,7 @@ int pci_create_pch(PCIBus *bus); void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,

                    uint32_t val, int len);  uint32_t

igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);

hw/xen/xen_pt.h +2 -0
+uint32_t igd_read_opregion(XenPCIPassthroughState *s); void
+igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
 
 #endif /* !XEN_PT_H */
hw/xen/xen_pt_config_init.c +0 -0
index de9a20f..cf36a40 100644
@@ -575,6 +575,22 @@ static int

xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,

hw/xen/xen_pt_config_init.c static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,

Quoted 13 lines
hw/xen/xen_pt_config_init.c +10 -0
     return 0;
 }
 
+static int xen_pt_intel_opregion_read(XenPCIPassthroughState *s,
+                                      XenPTReg *cfg_entry,
+                                      uint32_t *value, uint32_t
+valid_mask) {
+    *value = igd_read_opregion(s);
+    return 0;
+}
+
+static int xen_pt_intel_opregion_write(XenPCIPassthroughState *s,
+                                       XenPTReg *cfg_entry,

uint32_t *value,

hw/xen/xen_pt_config_init.c static int · line 588

Quoted 1 line
hw/xen/xen_pt_config_init.c +1 -0
+                                       uint32_t dev_value,

uint32_t

hw/xen/xen_pt_config_init.c static const XenPTRegGroupInfo

Quoted 30 lines
hw/xen/xen_pt_config_init.c +19 -0
+valid_mask) {
+    igd_write_opregion(s, *value);
+    return 0;
+}
+
 /* Header Type0 reg static information table */  static XenPTRegInfo
 xen_pt_emu_reg_header0[] = {
     /* Vendor ID reg */
@@ -1440,6 +1456,20 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
     },
 };
 
+static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
+    /* Intel IGFX OpRegion reg */
+    {
+        .offset     = 0x0,
+        .size       = 4,
+        .init_val   = 0,
+        .no_wb      = 1,
+        .u.dw.read   = xen_pt_intel_opregion_read,
+        .u.dw.write  = xen_pt_intel_opregion_write,
+    },
+    {
+        .size = 0,
+    },
+};
 
 /****************************
  * Capabilities
@@ -1677,6 +1707,14 @@ static const XenPTRegGroupInfo

xen_pt_emu_reg_grps[] = {

Quoted 4 lines
hw/xen/xen_pt_config_init.c +1 -0
         .size_init   = xen_pt_msix_size_init,
         .emu_regs = xen_pt_emu_reg_msix,
     },
+    /* Intel IGD Opregion group */

hw/xen/xen_pt_config_init.c static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = { · line 1720

Quoted 10 lines
hw/xen/xen_pt_config_init.c +7 -0
+    {
+        .grp_id      = PCI_INTEL_OPREGION,
+        .grp_type    = XEN_PT_GRP_TYPE_EMU,
+        .grp_size    = 0x4,
+        .size_init   = xen_pt_reg_grp_size_init,
+        .emu_regs    = xen_pt_emu_reg_igd_opregion,
+    },
     {
         .grp_size = 0,
     },

If I am not mistaken, in the original patch to qemu-xen-traditional, we were not adding an Intel IGD Opregion group. Instead we were changing the size of the header Type0 reg group:

(quoted diff) +11 -0
+static uint8_t pt_reg_grp_header0_size_init(struct pt_dev *ptdev,
+        struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset) {
+    /*
+    ** By default we will trap up to 0x40 in the cfg space.
+    ** If an intel device is pass through we need to trap 0xfc,
+    ** therefore the size should be 0xff.
+    */
+    if (igd_passthru)
+        return 0xFF;
+    return grp_reg->grp_size;
+}

Here instead we are adding the new group and forcing the offset to be PCI_INTEL_OPREGION, below. It looks functionally equivalent, but nicer.

But wouldn't it be even better to have find_cap_offset return the right offset for Intel IGD Opregion group? Why do we need to manually set reg_grp_offset to PCI_INTEL_OPREGION?

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState

Quoted 1 line
hw/xen/xen_pt_config_init.c +0 -0
@@ -1806,7 +1844,8 @@ int xen_pt_config_init(XenPCIPassthroughState

*s)

Quoted 7 lines

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState *s)

Quoted 6 lines
hw/xen/xen_pt_config_init.c +2 -1
         uint32_t reg_grp_offset = 0;
         XenPTRegGroup *reg_grp_entry = NULL;
 
-        if (xen_pt_emu_reg_grps[i].grp_id != 0xFF) {
+        if (xen_pt_emu_reg_grps[i].grp_id != 0xFF
+            && xen_pt_emu_reg_grps[i].grp_id !=

PCI_INTEL_OPREGION) {

Actually in this emulated case we still call find_cap_offset() to get reg_grp_offset.

Quoted 13 lines

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState · line 1850

Quoted 2 lines
hw/xen/xen_pt_config_init.c +0 -0
             if (xen_pt_hide_dev_cap(&s->real_device,
 

xen_pt_emu_reg_grps[i].grp_id)) {

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState

Quoted 2 lines
hw/xen/xen_pt_config_init.c +0 -0
                 continue;
@@ -1819,6 +1858,10 @@ int xen_pt_config_init(XenPCIPassthroughState

*s)

Quoted 7 lines
hw/xen/xen_pt_config_init.c +4 -0
             }
         }
 
+        if (xen_pt_emu_reg_grps[i].grp_id == PCI_INTEL_OPREGION) {
+            reg_grp_offset = PCI_INTEL_OPREGION;
+        }
+

But for this pass through scenario, we have to set 0xfc manually since we need to trap 0xfc completely in that comment:

Review

Quoted 5 lines
(quoted diff) +5 -0
+    /*
+    ** By default we will trap up to 0x40 in the cfg space.
+    ** If an intel device is pass through we need to trap 0xfc,
+    ** therefore the size should be 0xff.
+    */

OK. Can you please keep this comment in your patch? Thanks!

#74 lore raw

Re: [Qemu-devel] [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

Quoted 10 lines

-----Original Message-----
From: Stefano Stabellini [mailto:[email protected]]
Sent: Tuesday, May 20, 2014 6:51 PM
To: Chen, Tiejun
Cc: Stefano Stabellini; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Kay, Allen M; Zhang, Yang Z
Subject: RE: [v2][PATCH 8/8] xen, gfx passthrough: add opregion mapping

[snip]

Quoted 9 lines
Quoted 7 lines
Quoted 5 lines

hw/xen/xen_pt_config_init.c int xen_pt_config_init(XenPCIPassthroughState *s) · line 1864

Quoted 5 lines
hw/xen/xen_pt_config_init.c +4 -0
+        if (xen_pt_emu_reg_grps[i].grp_id == PCI_INTEL_OPREGION) {
+            reg_grp_offset = PCI_INTEL_OPREGION;
+        }
+

But for this pass through scenario, we have to set 0xfc manually since we

need to trap 0xfc completely in that comment:

Quoted 1 line
Quoted 7 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+    /*
+    ** By default we will trap up to 0x40 in the cfg space.
+    ** If an intel device is pass through we need to trap 0xfc,
+    ** therefore the size should be 0xff.
+    */

OK. Can you please keep this comment in your patch? Thanks!

Sure.

Thanks
Tiejun