/* * 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; }