[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [v8][RESEND][PATCH 05/10] xen, gfx passthrough: basic g
From: |
Stefano Stabellini |
Subject: |
Re: [Qemu-devel] [v8][RESEND][PATCH 05/10] xen, gfx passthrough: basic graphics passthrough support |
Date: |
Wed, 1 Jul 2015 16:45:37 +0100 |
User-agent: |
Alpine 2.02 (DEB 1266 2009-07-14) |
On Fri, 5 Jun 2015, Tiejun Chen wrote:
> basic gfx passthrough support:
> - add a vga type for gfx passthrough
> - register/unregister legacy VGA I/O ports and MMIOs for passthrough GFX
>
> Signed-off-by: Tiejun Chen <address@hidden>
> Signed-off-by: Yang Zhang <address@hidden>
Acked-by: Stefano Stabellini <address@hidden>
> hw/core/machine.c | 20 ++++++++
> hw/xen/Makefile.objs | 1 +
> hw/xen/xen-host-pci-device.c | 5 ++
> hw/xen/xen-host-pci-device.h | 1 +
> hw/xen/xen_pt.c | 4 ++
> hw/xen/xen_pt.h | 10 +++-
> hw/xen/xen_pt_graphics.c | 111
> +++++++++++++++++++++++++++++++++++++++++++
> include/hw/boards.h | 1 +
> qemu-options.hx | 3 ++
> vl.c | 10 ++++
> 10 files changed, 165 insertions(+), 1 deletion(-)
> create mode 100644 hw/xen/xen_pt_graphics.c
>
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 25c45e6..0655665 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -226,6 +226,20 @@ static void machine_set_usb(Object *obj, bool value,
> Error **errp)
> ms->usb_disabled = !value;
> }
>
> +static bool machine_get_igd_gfx_passthru(Object *obj, Error **errp)
> +{
> + MachineState *ms = MACHINE(obj);
> +
> + return ms->igd_gfx_passthru;
> +}
> +
> +static void machine_set_igd_gfx_passthru(Object *obj, bool value, Error
> **errp)
> +{
> + MachineState *ms = MACHINE(obj);
> +
> + ms->igd_gfx_passthru = value;
> +}
> +
> static char *machine_get_firmware(Object *obj, Error **errp)
> {
> MachineState *ms = MACHINE(obj);
> @@ -380,6 +394,12 @@ static void machine_initfn(Object *obj)
> object_property_set_description(obj, "usb",
> "Set on/off to enable/disable usb",
> NULL);
> + object_property_add_bool(obj, "igd-passthru",
> + machine_get_igd_gfx_passthru,
> + machine_set_igd_gfx_passthru, NULL);
> + object_property_set_description(obj, "igd-passthru",
> + "Set on/off to enable/disable igd
> passthrou",
> + NULL);
> object_property_add_str(obj, "firmware",
> machine_get_firmware,
> machine_set_firmware, NULL);
> diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
> index a0ca0aa..a9ad7e7 100644
> --- a/hw/xen/Makefile.objs
> +++ b/hw/xen/Makefile.objs
> @@ -3,3 +3,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
> diff --git a/hw/xen/xen-host-pci-device.c b/hw/xen/xen-host-pci-device.c
> index 743b37b..a54b7de 100644
> --- a/hw/xen/xen-host-pci-device.c
> +++ b/hw/xen/xen-host-pci-device.c
> @@ -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;
> diff --git a/hw/xen/xen-host-pci-device.h b/hw/xen/xen-host-pci-device.h
> index c2486f0..f1e1c30 100644
> --- a/hw/xen/xen-host-pci-device.h
> +++ b/hw/xen/xen-host-pci-device.h
> @@ -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];
> diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
> index 9afcda8..50bdf6f 100644
> --- a/hw/xen/xen_pt.c
> +++ b/hw/xen/xen_pt.c
> @@ -494,6 +494,7 @@ static int xen_pt_register_regions(XenPCIPassthroughState
> *s, uint16_t *cmd)
> d->rom.size, d->rom.base_addr);
> }
>
> + xen_pt_register_vga_regions(d);
> return 0;
> }
>
> @@ -798,6 +799,7 @@ out:
> static void xen_pt_unregister_device(PCIDevice *d)
> {
> XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
> + XenHostPCIDevice *host_dev = &s->real_device;
> uint8_t machine_irq = s->machine_irq;
> uint8_t intx = xen_pt_pci_intx(s);
> int rc;
> @@ -841,6 +843,8 @@ static void xen_pt_unregister_device(PCIDevice *d)
> /* delete all emulated config registers */
> xen_pt_config_delete(s);
>
> + xen_pt_unregister_vga_regions(host_dev);
> +
> memory_listener_unregister(&s->memory_listener);
> memory_listener_unregister(&s->io_listener);
>
> diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
> index 4bba559..dfa6171 100644
> --- a/hw/xen/xen_pt.h
> +++ b/hw/xen/xen_pt.h
> @@ -301,5 +301,13 @@ static inline bool
> xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
> return s->msix && s->msix->bar_index == bar;
> }
>
> -
> +extern bool has_igd_gfx_passthru;
> +static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
> +{
> + return (has_igd_gfx_passthru
> + && ((dev->class_code >> 0x8) == PCI_CLASS_DISPLAY_VGA));
> +}
> +int xen_pt_register_vga_regions(XenHostPCIDevice *dev);
> +int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev);
> +int xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev);
> #endif /* !XEN_PT_H */
> diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
> new file mode 100644
> index 0000000..9b3df81
> --- /dev/null
> +++ b/hw/xen/xen_pt_graphics.c
> @@ -0,0 +1,111 @@
> +/*
> + * graphics passthrough
> + */
> +#include "xen_pt.h"
> +#include "xen-host-pci-device.h"
> +#include "hw/xen/xen_backend.h"
> +
> +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 i = 0;
> +
> + if (!is_igd_vga_passthrough(dev)) {
> + return 0;
> + }
> +
> + 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 (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 vga_args[i].rc;
> + }
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * unregister VGA resources for the domain with assigned gfx
> + */
> +int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
> +{
> + int i = 0;
> +
> + if (!is_igd_vga_passthrough(dev)) {
> + return 0;
> + }
> +
> + 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 (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 vga_args[i].rc;
> + }
> + }
> +
> + return 0;
> +}
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index ff79797..a7b75ac 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -134,6 +134,7 @@ struct MachineState {
> bool mem_merge;
> bool usb;
> bool usb_disabled;
> + bool igd_gfx_passthru;
> char *firmware;
> bool iommu;
> bool suppress_vmdesc;
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 7edd1f1..964ba0d 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -38,6 +38,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
> " dump-guest-core=on|off include guest memory in a core
> dump (default=on)\n"
> " mem-merge=on|off controls memory merge support
> (default: on)\n"
> " iommu=on|off controls emulated Intel IOMMU (VT-d)
> support (default=off)\n"
> + " igd-passthru=on|off controls IGD GFX passthrough
> support (default=off)\n"
> " aes-key-wrap=on|off controls support for AES key
> wrapping (default=on)\n"
> " dea-key-wrap=on|off controls support for DEA key
> wrapping (default=on)\n"
> " suppress-vmdesc=on|off disables self-describing
> migration (default=off)\n",
> @@ -55,6 +56,8 @@ than one accelerator specified, the next one is used if the
> previous one fails
> to initialize.
> @item kernel_irqchip=on|off
> Enables in-kernel irqchip support for the chosen accelerator when available.
> address@hidden gfx_passthru=on|off
> +Enables IGD GFX passthrough support for the chosen machine when available.
> @item vmport=on|off|auto
> Enables emulation of VMWare IO port, for vmmouse etc. auto says to select the
> value based on accel. For accel=xen the default is off otherwise the default
> diff --git a/vl.c b/vl.c
> index 1d4c089..34c1d55 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1224,6 +1224,13 @@ static void configure_msg(QemuOpts *opts)
> enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true);
> }
>
> +/* Now we still need this for compatibility with XEN. */
> +bool has_igd_gfx_passthru;
> +static void igd_gfx_passthru(void)
> +{
> + has_igd_gfx_passthru = current_machine->igd_gfx_passthru;
> +}
> +
> /***********************************************************/
> /* USB devices */
>
> @@ -4256,6 +4263,9 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
>
> + /* Check if IGD GFX passthrough. */
> + igd_gfx_passthru();
> +
> /* init generic devices */
> if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL,
> 1) != 0)
> exit(1);
> --
> 1.9.1
>
>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [v8][RESEND][PATCH 05/10] xen, gfx passthrough: basic graphics passthrough support,
Stefano Stabellini <=