[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH][VTD] enable integrated graphics passthrough for Calpella and Sandybridge
On Fri, 4 Jun 2010, Kay, Allen M wrote: > > Added Calpella and Sandybridge integrated graphics pass-through support, > consolidated graphics pass-through code into > pt-graphics.c. > > Signed-off-by: Allen Kay <allen.m.kay@xxxxxxxxx> > some comments follow > diff --git a/hw/pass-through.c b/hw/pass-through.c > index 5a76e8d..971c7f1 100644 > --- a/hw/pass-through.c > +++ b/hw/pass-through.c > @@ -1865,50 +1865,6 @@ static int pt_dev_is_virtfn(struct pci_dev *dev) > return rc; > } > > -/* > - * register VGA resources for the domain with assigned gfx > - */ > -static int register_vga_regions(struct pt_dev *real_device) > -{ > - int ret = 0; > - > - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, > - 0x3B0, 0xC, DPCI_ADD_MAPPING); > - > - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, > - 0x3C0, 0x20, DPCI_ADD_MAPPING); > - > - ret |= xc_domain_memory_mapping(xc_handle, domid, > - 0xa0000 >> XC_PAGE_SHIFT, > - 0xa0000 >> XC_PAGE_SHIFT, > - 0x20, > - DPCI_ADD_MAPPING); > - > - return ret; > -} > - > -/* > - * unregister VGA resources for the domain with assigned gfx > - */ > -static int unregister_vga_regions(struct pt_dev *real_device) > -{ > - int ret = 0; > - > - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, > - 0x3B0, 0xC, DPCI_REMOVE_MAPPING); > - > - ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, > - 0x3C0, 0x20, DPCI_REMOVE_MAPPING); > - > - ret |= xc_domain_memory_mapping(xc_handle, domid, > - 0xa0000 >> XC_PAGE_SHIFT, > - 0xa0000 >> XC_PAGE_SHIFT, > - 0x20, > - DPCI_REMOVE_MAPPING); > - > - return ret; > -} > - > static int pt_register_regions(struct pt_dev *assigned_device) > { > int i = 0; > @@ -1970,17 +1926,7 @@ static int pt_register_regions(struct pt_dev > *assigned_device) > PT_LOG("Expansion ROM registered (size=0x%08x base_addr=0x%08x)\n", > (uint32_t)(pci_dev->rom_size), > (uint32_t)(pci_dev->rom_base_addr)); > } > - > - if ( gfx_passthru && (pci_dev->device_class == 0x0300) ) > - { > - ret = register_vga_regions(assigned_device); > - if ( ret != 0 ) > - { > - PT_LOG("VGA region mapping failed\n"); > - return ret; > - } > - } > - > + register_vga_regions(assigned_device); > return 0; > } > > @@ -2029,13 +1975,7 @@ static void pt_unregister_regions(struct pt_dev > *assigned_device) > } > > } > - > - if ( gfx_passthru && (assigned_device->pci_dev->device_class == 0x0300) ) > - { > - ret = unregister_vga_regions(assigned_device); > - if ( ret != 0 ) > - PT_LOG("VGA region unmapping failed\n"); > - } > + unregister_vga_regions(assigned_device); > } > > static uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap) > @@ -2097,46 +2037,66 @@ static uint32_t find_ext_cap_offset(struct pci_dev > *pci_dev, uint32_t cap) > return 0; > } > > -u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr) > +static void pci_access_init(void) > { > - struct pci_dev *pci_dev; > - u8 val; > + struct pci_access *pci_access; > > - pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn); > - if ( !pci_dev ) > - return 0; > + if (dpci_infos.pci_access) > + return; > > - val = pci_read_byte(pci_dev, addr); > - pci_free_dev(pci_dev); > - return val; > + /* Initialize libpci */ > + pci_access = pci_alloc(); > + if ( pci_access == NULL ) { > + PT_LOG("Error: pci_access is NULL\n"); > + return -1; > + } > + pci_init(pci_access); > + pci_scan_bus(pci_access); > + dpci_infos.pci_access = pci_access; > } > > -u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr) > +u32 pt_pci_host_read(int bus, int dev, int fn, u32 addr, int len) > { > + > struct pci_dev *pci_dev; > - u16 val; > + u32 val = -1; > > + pci_access_init(); > pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn); > if ( !pci_dev ) > return 0; > > - val = pci_read_word(pci_dev, addr); > - pci_free_dev(pci_dev); > + switch (len) > + { > + case 1: val = pci_read_byte(pci_dev, addr); break; > + case 2: val = pci_read_word(pci_dev, addr); break; > + case 4: val = pci_read_long(pci_dev, addr); break; > + default: > + fprintf(stderr, "error: pt_pci_host_read: invalid len = %d\n", > len); > + } > return val; > } > > -u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr) > +int pt_pci_host_write(int bus, int dev, int fn, u32 addr, u32 val, int len) > { > struct pci_dev *pci_dev; > - u32 val; > + int ret = 0; > > + pci_access_init(); > pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn); > if ( !pci_dev ) > return 0; > > - val = pci_read_long(pci_dev, addr); > + switch (len) > + { > + case 1: ret = pci_write_byte(pci_dev, addr, val); break; > + case 2: ret = pci_write_word(pci_dev, addr, val); break; > + case 4: ret = pci_write_long(pci_dev, addr, val); break; > + default: > + fprintf(stderr, "error: pt_pci_host_write: invalid len = %d\n", > len); > + } > pci_free_dev(pci_dev); > - return val; > + return ret; > } > > /* parse BAR */ > @@ -4200,92 +4160,6 @@ static int pt_pmcsr_reg_restore(struct pt_dev *ptdev, > return 0; > } > > -static int get_vgabios(unsigned char *buf) > -{ > - int fd; > - uint32_t bios_size = 0; > - uint32_t start = 0xC0000; > - uint16_t magic = 0; > - > - if ( (fd = open("/dev/mem", O_RDONLY)) < 0 ) > - { > - PT_LOG("Error: Can't open /dev/mem: %s\n", strerror(errno)); > - return 0; > - } > - > - /* > - * Check if it a real bios extension. > - * The magic number is 0xAA55. > - */ > - if ( start != lseek(fd, start, SEEK_SET) ) > - goto out; > - if ( read(fd, &magic, 2) != 2 ) > - goto out; > - if ( magic != 0xAA55 ) > - goto out; > - > - /* Find the size of the rom extension */ > - if ( start != lseek(fd, start, SEEK_SET) ) > - goto out; > - if ( lseek(fd, 2, SEEK_CUR) != (start + 2) ) > - goto out; > - if ( read(fd, &bios_size, 1) != 1 ) > - goto out; > - > - /* This size is in 512 bytes */ > - bios_size *= 512; > - > - /* > - * Set the file to the begining of the rombios, > - * to start the copy. > - */ > - if ( start != lseek(fd, start, SEEK_SET) ) > - goto out; > - > - if ( bios_size != read(fd, buf, bios_size)) > - bios_size = 0; > - > -out: > - close(fd); > - return bios_size; > -} > - > -static int setup_vga_pt(void) > -{ > - unsigned char *bios = NULL; > - int bios_size = 0; > - char *c = NULL; > - char checksum = 0; > - int rc = 0; > - > - /* Allocated 64K for the vga bios */ > - if ( !(bios = malloc(64 * 1024)) ) > - return -1; > - > - bios_size = get_vgabios(bios); > - if ( bios_size == 0 || bios_size > 64 * 1024) > - { > - PT_LOG("vga bios size (0x%x) is invalid!\n", bios_size); > - 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; > - PT_LOG("vga bios checksum is adjusted!\n"); > - } > - > - cpu_physical_memory_rw(0xc0000, bios, bios_size, 1); > - > -out: > - free(bios); > - return rc; > -} > - > static struct pt_dev * register_real_device(PCIBus *e_bus, > const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev, > uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access, > @@ -4387,16 +4261,13 @@ static struct pt_dev * register_real_device(PCIBus > *e_bus, > pt_register_regions(assigned_device); > > /* Setup VGA bios for passthroughed gfx */ > - if ( gfx_passthru && (assigned_device->pci_dev->device_class == 0x0300) ) > + if ( setup_vga_pt(assigned_device) < 0 ) > { > - rc = setup_vga_pt(); > - if ( rc < 0 ) > - { > - PT_LOG("Setup VGA BIOS of passthroughed gfx failed!\n"); > - return NULL; > - } > + PT_LOG("Setup VGA BIOS of passthroughed gfx failed!\n"); > + return NULL; > } > > + > /* reinitialize each config register to be emulated */ > rc = pt_config_init(assigned_device); > if ( rc < 0 ) { > @@ -4548,19 +4419,8 @@ int power_on_php_devfn(int devfn) > { > struct php_dev *php_dev = &dpci_infos.php_devs[devfn]; > struct pt_dev *pt_dev; > - struct pci_access *pci_access; > > - if (!dpci_infos.pci_access) { > - /* Initialize libpci */ > - pci_access = pci_alloc(); > - if ( pci_access == NULL ) { > - PT_LOG("Error: pci_access is NULL\n"); > - return -1; > - } > - pci_init(pci_access); > - pci_scan_bus(pci_access); > - dpci_infos.pci_access = pci_access; > - } > + pci_access_init(); > > pt_dev = > register_real_device(dpci_infos.e_bus, > diff --git a/hw/pass-through.h b/hw/pass-through.h > index f8a0c73..6c5e8ca 100644 > --- a/hw/pass-through.h > +++ b/hw/pass-through.h > @@ -406,10 +406,16 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base) > } > > uint8_t pci_intx(struct pt_dev *ptdev); > - > -u8 pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr); > -u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr); > -u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr); > +u32 pt_pci_host_read(int bus, int dev, int fn, u32 addr, int len); > +int pt_pci_host_write(int bus, int dev, int fn, u32 addr, u32 val, int len); > +PCIBus *intel_pch_init(PCIBus *bus); > +int igd_pci_write(PCIDevice *pci_dev, int config_addr, uint32_t val, int > len); > +int igd_pci_read(PCIDevice *pci_dev, int config_addr, uint32_t *val, int > len); > +int register_vga_regions(struct pt_dev *real_device); > +int unregister_vga_regions(struct pt_dev *real_device); > +int setup_vga_pt(struct pt_dev *real_device); > +PCIBus *intel_pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, > + uint16_t did, const char *name, uint16_t revision); > > #endif /* __PASSTHROUGH_H__ */ > > diff --git a/hw/pc.c b/hw/pc.c > index 9375951..7364cb8 100644 > --- a/hw/pc.c > +++ b/hw/pc.c > @@ -42,6 +42,10 @@ > #include "virtio-console.h" > #include "hpet_emul.h" > > +#ifdef CONFIG_PASSTHROUGH > +#include "pass-through.h" > +#endif > + > /* output Bochs bios info messages */ > //#define DEBUG_BIOS > > @@ -978,6 +982,8 @@ vga_bios_error: > pci_bus = NULL; > } > > + intel_pch_init(pci_bus); > + > /* init basic PC hardware */ > register_ioport_write(0x80, 1, 1, ioport80_write, NULL); > You are missing a ifdef CONFIG_PASSTHROUGH here > diff --git a/hw/pci.c b/hw/pci.c > index b07e5ea..fa32ed9 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -39,24 +39,6 @@ extern int igd_passthru; > > //#define DEBUG_PCI > > -struct PCIBus { > - int bus_num; > - int devfn_min; > - pci_set_irq_fn set_irq; > - pci_map_irq_fn map_irq; > - uint32_t config_reg; /* XXX: suppress */ > - /* low level pic */ > - SetIRQFunc *low_set_irq; > - qemu_irq *irq_opaque; > - PCIDevice *devices[256]; > - PCIDevice *parent_dev; > - PCIBus *next; > - /* The bus IRQ state is the logical OR of the connected devices. > - Keep a count of the number of devices with raised IRQs. */ > - int nirq; > - int irq_count[]; > -}; > - > static void pci_update_mappings(PCIDevice *d); > static void pci_set_irq(void *opaque, int irq_num, int level); > > @@ -96,7 +78,7 @@ PCIBus *pci_register_bus(pci_set_irq_fn set_irq, > pci_map_irq_fn map_irq, > return bus; > } > > -static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn > map_irq) > +PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq) > { > PCIBus *bus; > bus = qemu_mallocz(sizeof(PCIBus)); > @@ -590,6 +572,10 @@ void pci_data_write(void *opaque, uint32_t addr, > uint32_t val, int len) > printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n", > pci_dev->name, config_addr, val, len); > #endif > + > +#ifdef CONFIG_PASSTHROUGH > + if (igd_pci_write(pci_dev, config_addr, val, len) == 0) > +#endif > pci_dev->config_write(pci_dev, config_addr, val, len); > } > > @@ -598,7 +584,7 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int > len) > PCIBus *s = opaque; > PCIDevice *pci_dev; > int config_addr, bus_num; > - uint32_t val; > + uint32_t val = 0; > > bus_num = (addr >> 16) & 0xff; > while (s && s->bus_num != bus_num) > @@ -625,26 +611,8 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int > len) > config_addr = addr & 0xff; > > #ifdef CONFIG_PASSTHROUGH > - /* host bridge reads for IGD passthrough */ > - if ( igd_passthru && pci_dev->devfn == 0x00 ) { > - val = pci_dev->config_read(pci_dev, config_addr, len); > - > - if ( config_addr == 0x00 && len == 4 ) > - val = pt_pci_host_read_long(0, 0, 0, 0x00); > - else if ( config_addr == 0x02 ) // Device ID > - val = pt_pci_host_read_word(0, 0, 0, 0x02); > - else if ( config_addr == 0x52 ) // GMCH Graphics Control Register > - val = pt_pci_host_read_word(0, 0, 0, 0x52); > - else if ( config_addr == 0xa0 ) // GMCH Top of Memory Register > - val = pt_pci_host_read_word(0, 0, 0, 0xa0); > - goto done_config_read; > - } else if ( igd_passthru && pci_dev->devfn == 0x10 && > - config_addr == 0xfc ) { // read on IGD device > - val = 0; // use SMI to communicate with the system BIOS > - goto done_config_read; > - } > + if ( igd_pci_read(pci_dev, config_addr, &val, len) == 0) > #endif > - > val = pci_dev->config_read(pci_dev, config_addr, len); > > done_config_read: > @@ -892,12 +860,7 @@ void pci_unplug_netifs(void) > } > } > > -typedef struct { > - PCIDevice dev; > - PCIBus *bus; > -} PCIBridge; > - > -static void pci_bridge_write_config(PCIDevice *d, > +void pci_bridge_write_config(PCIDevice *d, > uint32_t address, uint32_t val, int len) > { > PCIBridge *s = (PCIBridge *)d; > diff --git a/hw/pci.h b/hw/pci.h > index de5a4e1..18e7b6f 100644 > --- a/hw/pci.h > +++ b/hw/pci.h > @@ -207,6 +207,32 @@ struct PCIDevice { > int irq_state[4]; > }; > > +typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level); > +typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); > + > +struct PCIBus { > + int bus_num; > + int devfn_min; > + pci_set_irq_fn set_irq; > + pci_map_irq_fn map_irq; > + uint32_t config_reg; /* XXX: suppress */ > + /* low level pic */ > + SetIRQFunc *low_set_irq; > + qemu_irq *irq_opaque; > + PCIDevice *devices[256]; > + PCIDevice *parent_dev; > + PCIBus *next; > + /* The bus IRQ state is the logical OR of the connected devices. > + Keep a count of the number of devices with raised IRQs. */ > + int nirq; > + int irq_count[]; > +}; > + > +typedef struct { > + PCIDevice dev; > + PCIBus *bus; > +} PCIBridge; > + > extern char direct_pci_str[]; > extern int direct_pci_msitranslate; > extern int direct_pci_power_mgmt; > @@ -235,8 +261,6 @@ void pci_default_write_config(PCIDevice *d, > void pci_device_save(PCIDevice *s, QEMUFile *f); > int pci_device_load(PCIDevice *s, QEMUFile *f); > > -typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level); > -typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); > PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, > qemu_irq *pic, int devfn_min, int nirq); > > @@ -341,5 +365,9 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, > pci_map_irq_fn map_irq, > > /* pass-through.c */ > int pt_init(PCIBus *e_bus); > +void pci_bridge_write_config(PCIDevice *d, > + uint32_t address, uint32_t val, int len); > +PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq); > + > > #endif > diff --git a/hw/pt-graphics.c b/hw/pt-graphics.c > new file mode 100644 > index 0000000..3b9ce95 > --- /dev/null > +++ b/hw/pt-graphics.c > @@ -0,0 +1,266 @@ > +/* > + * graphics passthrough > + */ > + > +#include "pass-through.h" > +#include "pci/header.h" > +#include "pci/pci.h" > +#include "pt-msi.h" > +#include "qemu-xen.h" > +#include "iomulti.h" > + > +#include <unistd.h> > +#include <sys/ioctl.h> > + > +extern int gfx_passthru; > +extern int igd_passthru; > + > +static int pch_irq_function(PCIDevice *pci_dev, int irq_num) > +{ > + PT_LOG("pch_irq_function called\n"); > + return irq_num; > +} > + > +PCIBus *intel_pch_init(PCIBus *bus) > +{ > + PCIBridge *pch; > + u16 vendor_id, device_id; > + u8 rev_id; > + > + if ( !gfx_passthru ) > + return NULL; > + > + vendor_id = pt_pci_host_read(0, 0x1f, 0, 0, 2); > + device_id = pt_pci_host_read(0, 0x1f, 0, 2, 2); > + rev_id = pt_pci_host_read(0, 0x1f, 0, 8, 1); > + > + pch = (PCIBridge *) > + pci_register_device(bus, "intel_bridge_1f", sizeof(PCIBridge), > + PCI_DEVFN(0x1f, 0), NULL, pci_bridge_write_config); > + > + pci_config_set_vendor_id(pch->dev.config, vendor_id); > + pci_config_set_device_id(pch->dev.config, device_id); > + > + pch->dev.config[0x04] = 0x06; // command = bus master, pci mem > + pch->dev.config[0x05] = 0x00; > + pch->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no > error > + pch->dev.config[0x07] = 0x00; // status = fast devsel > + pch->dev.config[0x08] = rev_id; > + pch->dev.config[0x09] = 0x00; // programming i/f > + pci_config_set_class(pch->dev.config, PCI_CLASS_BRIDGE_ISA); > + pch->dev.config[0x0D] = 0x10; // latency_timer > + pch->dev.config[0x0E] = 0x81; // header_type > + pch->dev.config[0x1E] = 0xa0; // secondary status > + > + pch->bus = pci_register_secondary_bus(&pch->dev, pch_irq_function); > + return pch->bus; > +} > + What happens if the hardware is a pre-Calpella Intel graphic card? Is it still going to work? > +int igd_pci_write(PCIDevice *pci_dev, int config_addr, uint32_t val, int len) > +{ > + if ( !igd_passthru || (pci_dev->devfn != 0x00 ) ) > + return 0; > + > + switch (config_addr) > + { > + case 0x58: // PAVPC Offset > + pt_pci_host_write(0, 0, 0, config_addr, val, len); > + PT_LOG("pci_config_write: %x:%x.%x: addr=%x len=%x val=%x\n", > + pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), > + PCI_FUNC(pci_dev->devfn), config_addr, len, val); > + break; > + default: > + pci_dev->config_write(pci_dev, config_addr, val, len); > + } > + return 1; > +} > + > +int igd_pci_read(PCIDevice *pci_dev, int config_addr, uint32_t *val, int len) > +{ > + if ( !igd_passthru || (pci_dev->devfn != 0) ) > + return 0; > + > + switch (config_addr) > + { > + case 0x00: /* vendor id */ > + case 0x02: /* device id */ > + 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 */ > + *val = pt_pci_host_read(0, PCI_SLOT(pci_dev->devfn), > + 0, config_addr, len); > + PT_LOG("pci_config_read: %x:%x.%x: addr=%x len=%x val=%x\n", > + pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), > + PCI_FUNC(pci_dev->devfn), config_addr, len, *val); > + > + break; > + default: > + *val = pci_dev->config_read(pci_dev, config_addr, len); > + } > + return 1; > +} > + > +/* > + * register VGA resources for the domain with assigned gfx > + */ > +int register_vga_regions(struct pt_dev *real_device) > +{ > + u32 igd_opregion, igd_bsm; > + int ret = 0; > + > + if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 ) > + return ret; > + > + ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0, > + 0x3B0, 0xC, DPCI_ADD_MAPPING); > + > + ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, > + 0x3C0, 0x20, DPCI_ADD_MAPPING); > + > + ret |= xc_domain_memory_mapping(xc_handle, domid, > + 0xa0000 >> XC_PAGE_SHIFT, > + 0xa0000 >> XC_PAGE_SHIFT, > + 0x20, > + DPCI_ADD_MAPPING); > + > + /* 1:1 map ASL Storage register value */ > + igd_opregion = pt_pci_host_read(0, 2, 0, 0xfc, 4); > + PT_LOG("register_vga: igd_opregion = %x\n", igd_opregion); > + ret |= xc_domain_memory_mapping(xc_handle, domid, > + igd_opregion >> XC_PAGE_SHIFT, > + igd_opregion >> XC_PAGE_SHIFT, > + 2, > + DPCI_ADD_MAPPING); Again, what happens if the hardware is older? Do all Intel graphic cards have an opregion? > + igd_opregion = pt_pci_host_read(0, 2, 0, 0xfc, 4); > + ret |= xc_domain_memory_mapping(xc_handle, domid, > + igd_opregion >> XC_PAGE_SHIFT, > + igd_opregion >> XC_PAGE_SHIFT, > + 2, > + DPCI_REMOVE_MAPPING); > + ditto _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |