xen: add Intel IGD passthrough support
v3 cover xen: add Intel IGD passthrough support
v3:
* In this case, as we discussed we will give priority to devices to reserve a specific devfn by passing "device_model_args_hvm = ['-device', 'xen-platform,addr=0x3']" and "vga=none", so withdraw patch #1, #2 and #4.
* Fix some typos.
* Add more comments to make that readable.
* To unmap igd_opregion when call xen_pt_unregister_vga_regions().
* Improve some return paths.
* Force to convert igd_guest/host_opoegion as an unsigned long type while calling xc_domain_memory_mapping().
* We need to map 3 pages for opregion as hvmloader set.
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 (2):
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 | 56 +++++++++++++- 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 | 50 ++++++++++++- hw/xen/xen_pt_graphics.c | 518 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 9 +++ vl.c | 11 ++- 10 files changed, 668 insertions(+), 6 deletions(-) create mode 100644 hw/xen/xen_pt_graphics.c
Thanks
Tiejun
PATCH v3 1/5 xen, gfx passthrough: basic graphics passthrough support
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]>
---
v3:
* Fix some typos.
* Add more comments to make that readable.
* Improve some return paths.
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 | 232 +++++++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 9 ++ vl.c | 11 +- 8 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 hw/xen/xen_pt_graphics.c
hw/xen/Makefile.objs +1 -1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 +232 -0
232 lines not on this page · raw message
qemu-options.hx +9 -0
@@ -1053,6 +1053,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
@@ -1438,6 +1438,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;
@@ -2990,7 +2997,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 ]);
@@ -3957,6 +3963,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
PATCH v3 2/5 xen, gfx passthrough: create intel isa bridge
In reply to Tiejun ChenISA 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]]
---
v3:
* Fix some typos.
* Improve some return paths.
v2:
* Nothing is changed.
hw/xen/xen_pt_graphics.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
hw/xen/xen_pt_graphics.c +63 -0
@@ -230,3 +230,66 @@ out:g_free (bios);return rc; } + +static uint32_t isa_bridge_read_config (PCIDevice *d,uint32_t addr,int len) +{ +return pci_default_read_config (d, addr, len); +} + +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 ="intel-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 ),"intel-pch-isa-bridge" ); + +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 created.\n" ); +return 0 ; +}
Signature · 1 line
1.9.1
PATCH v3 3/5 xen, gfx passthrough: support Intel IGD passthrough with VT-D
In reply to Tiejun ChenSome 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 >
---
v3:
* Improve comments to make that readable.
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 | 159 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+)
hw/xen/xen_pt.h +4 -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); +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 +159 -0
168 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v3 4/5 xen, gfx passthrough: create host bridge to passthrough
In reply to Tiejun ChenImplement that pci host bridge to specific to passthrough. Actually thsi just inherit the standard one.
---
v3:
* Just fix this patch head description typo.
v2:
* New patch.
hw/pci-host/piix.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-)
hw/pci-host/piix.c +54 -2
@@ -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,
@@ -333,8 +348,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;
@@ -705,6 +727,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) {
@@ -746,6 +797,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
PATCH v3 5/5 xen, gfx passthrough: add opregion mapping
In reply to Tiejun ChenThe 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]>
---
v3:
* Fix some typos.
* Add more comments to make that readable.
* To unmap igd_opregion when call xen_pt_unregister_vga_regions().
* Improve some return paths.
* We need to map 3 pages for opregion as hvmloader set.
* Force to convert igd_guest/host_opoegion as an unsigned long type while calling xc_domain_memory_mapping().
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 | 50 ++++++++++++++++++++++++++++++++++- hw/xen/xen_pt_graphics.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-)
hw/xen/xen_pt.h +3 -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 */
@@ -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 +49 -1
80 lines not on this page · raw message
hw/xen/xen_pt_graphics.c +64 -0
85 lines not on this page · raw message
Signature · 1 line
1.9.1
Please ignore this series since I have some typos to some email address :(
Sorry for any inconveniences.
Thanks
Tiejun
Quoted 80 lines
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Tiejun Chen
Sent: Monday, May 26, 2014 5:37 PM
To: [email protected]; [email protected]; [email protected]; [email protected]
Cc: [email protected]; [email protected]; Kay, Allen M; [email protected]; [email protected]; Zhang, Yang Z
Subject: [Qemu-devel] [v3][PATCH 0/8] xen: add Intel IGD passthrough supportv3:
* In this case, as we discussed we will give priority to devices to reserve a specific devfn by passing "
device_model_args_hvm= ['-device', 'xen-platform,addr=0x3']" and "vga=none", so withdraw patch #1, #2 and #4.
* Fix some typos.
* Add more comments to make that readable.
* To unmapigd_opregionwhen callxen_pt_unregister_vga_regions().
* Improve some return paths.
* Force to convert igd_guest/host_opoegion as an unsigned long type while callingxc_domain_memory_mapping().
* We need to map 3 pages for opregion as hvmloader set.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.
* introduceis_igd_passthrough()to make sure we touch physical host bridge only in IGD case.
* We should return zero as an invalid address value while callingigd_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 (2):
xen, gfx passthrough: create intel isa bridge xen, gfx passthrough: create host bridge to passthroughYang Zhang (3):
xen, gfx passthrough: basic graphics passthrough support xen, gfx passthrough: support Intel IGD passthrough with VT-D xen, gfx passthrough: add opregion mappinghw/pci-host/piix.c | 56 +++++++++++++- 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 | 50 ++++++++++++- hw/xen/xen_pt_graphics.c | 518 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ qemu-options.hx | 9 +++ vl.c | 11 ++- 10 files changed, 668 insertions(+), 6 deletions(-) create mode 100644
hw/xen/xen_pt_graphics.cThanks
Tiejun