pciif.py

来自「xen虚拟机源代码安装包」· Python 代码 · 共 567 行 · 第 1/2 页

PY
567
字号
                    "bind your slot/device to the PCI backend using sysfs" \                    )%(dev.name))        if dev.has_non_page_aligned_bar and arch.type != "ia64":            raise VmError("pci: %: non-page-aligned MMIO BAR found." % dev.name)        self.CheckSiblingDevices(fe_domid, dev)        # We don't do FLR when we create domain and hotplug device into guest,        # namely, we only do FLR when we destroy domain or hotplug device from        # guest. This is mainly to work around the race condition in hotplug code        # paths. See the changeset's description for details.        # if arch.type != "ia64":        #    dev.do_FLR()        PCIQuirk(dev.vendor, dev.device, dev.subvendor, dev.subdevice, domain,                 bus, slot, func)        if not self.vm.info.is_hvm():            # Setup IOMMU device assignment            pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func)            bdf = xc.assign_device(fe_domid, pci_str)            if bdf > 0:                raise VmError("Failed to assign device to IOMMU (%x:%x.%x)"                              % (bus, slot, func))            log.debug("pci: assign device %x:%x.%x" % (bus, slot, func))        for (start, size) in dev.ioports:            log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))            rc = xc.domain_ioport_permission(domid = fe_domid, first_port = start,                    nr_ports = size, allow_access = True)            if rc<0:                raise VmError(('pci: failed to configure I/O ports on device '+                            '%s - errno=%d')%(dev.name,rc))                    for (start, size) in dev.iomem:            # Convert start/size from bytes to page frame sizes            start_pfn = start>>PAGE_SHIFT            # Round number of pages up to nearest page boundary (if not on one)            nr_pfns = (size+(PAGE_SIZE-1))>>PAGE_SHIFT            log.debug('pci: enabling iomem 0x%x/0x%x pfn 0x%x/0x%x'% \                    (start,size,start_pfn,nr_pfns))            rc = xc.domain_iomem_permission(domid =  fe_domid,                    first_pfn = start_pfn,                    nr_pfns = nr_pfns,                    allow_access = True)            if rc<0:                raise VmError(('pci: failed to configure I/O memory on device '+                            '%s - errno=%d')%(dev.name,rc))            rc = xc.physdev_map_pirq(domid = fe_domid,                                   index = dev.irq,                                   pirq  = dev.irq)            if rc < 0:                raise VmError(('pci: failed to map irq on device '+                            '%s - errno=%d')%(dev.name,rc))        if dev.msix:            for (start, size) in dev.msix_iomem:                start_pfn = start>>PAGE_SHIFT                nr_pfns = (size+(PAGE_SIZE-1))>>PAGE_SHIFT                log.debug('pci-msix: remove permission for 0x%x/0x%x 0x%x/0x%x' % \                         (start,size, start_pfn, nr_pfns))                rc = xc.domain_iomem_permission(domid = fe_domid,                                                first_pfn = start_pfn,                                                nr_pfns = nr_pfns,                                                allow_access = False)                if rc<0:                    raise VmError(('pci: failed to remove msi-x iomem'))        if dev.irq>0:            log.debug('pci: enabling irq %d'%dev.irq)            rc = xc.domain_irq_permission(domid =  fe_domid, pirq = dev.irq,                    allow_access = True)            if rc<0:                raise VmError(('pci: failed to configure irq on device '+                            '%s - errno=%d')%(dev.name,rc))    def setupDevice(self, config):        """Setup devices from config        """        pci_str_list = []        pci_dev_list = []        for pci_config in config.get('devs', []):            domain = parse_hex(pci_config.get('domain', 0))            bus = parse_hex(pci_config.get('bus', 0))            slot = parse_hex(pci_config.get('slot', 0))            func = parse_hex(pci_config.get('func', 0))                        pci_str = '%04x:%02x:%02x.%01x' % (domain, bus, slot, func)            pci_str_list = pci_str_list + [pci_str]            pci_dev_list = pci_dev_list + [(domain, bus, slot, func)]        for (domain, bus, slot, func) in pci_dev_list:            try:                dev = PciDevice(domain, bus, slot, func)            except Exception, e:                raise VmError("pci: failed to locate device and "+                        "parse it's resources - "+str(e))            if (dev.dev_type == DEV_TYPE_PCIe_ENDPOINT) and not dev.pcie_flr:                if dev.bus == 0:                    # We cope with this case by using the Dstate transition                    # method for now.                    err_msg = 'pci: %s: it is on bus 0, but has no PCIe' +\                        ' FLR Capability. Will try the Dstate transition'+\                        ' method if available.'                    log.warn(err_msg % dev.name)                else:                    funcs = dev.find_all_the_multi_functions()                    for f in funcs:                        if not f in pci_str_list:                            (f_dom, f_bus, f_slot, f_func) = parse_pci_name(f)                            f_pci_str = '0x%x,0x%x,0x%x,0x%x' % \                                (f_dom, f_bus, f_slot, f_func)                            # f has been assigned to other guest?                            if xc.test_assign_device(0, f_pci_str) != 0:                                err_msg = 'pci: %s must be co-assigned to' + \                                    ' the same guest with %s'                                raise VmError(err_msg % (f, dev.name))            elif dev.dev_type == DEV_TYPE_PCI:                if dev.bus == 0 or arch.type == "ia64":                    if not dev.pci_af_flr:                        # We cope with this case by using the Dstate transition                        # method for now.                        err_msg = 'pci: %s: it is on bus 0, but has no PCI' +\                            ' Advanced Capabilities for FLR. Will try the'+\                            ' Dstate transition method if available.'                        log.warn(err_msg % dev.name)                else:                    # All devices behind the uppermost PCI/PCI-X bridge must be\                    # co-assigned to the same guest.                    devs_str = dev.find_coassigned_devices(True)                    # Remove the element 0 which is a bridge                    del devs_str[0]                    for s in devs_str:                        if not s in pci_str_list:                            (s_dom, s_bus, s_slot, s_func) = parse_pci_name(s)                            s_pci_str = '0x%x,0x%x,0x%x,0x%x' % \                                (s_dom, s_bus, s_slot, s_func)                            # s has been assigned to other guest?                            if xc.test_assign_device(0, s_pci_str) != 0:                                err_msg = 'pci: %s must be co-assigned to the'+\                                    ' same guest with %s'                                raise VmError(err_msg % (s, dev.name))        for (domain, bus, slot, func) in pci_dev_list:            self.setupOneDevice(domain, bus, slot, func)        return    def cleanupOneDevice(self, domain, bus, slot, func):        """ Detach I/O resources for device from frontend domain        """        fe_domid = self.getDomid()        try:            dev = PciDevice(domain, bus, slot, func)        except Exception, e:            raise VmError("pci: failed to locate device and "+                    "parse it's resources - "+str(e))        if dev.driver!='pciback':            raise VmError(("pci: PCI Backend does not own device "+ \                    "%s\n"+ \                    "See the pciback.hide kernel "+ \                    "command-line parameter or\n"+ \                    "bind your slot/device to the PCI backend using sysfs" \                    )%(dev.name))        if not self.vm.info.is_hvm():            pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func)            bdf = xc.deassign_device(fe_domid, pci_str)            if bdf > 0:                raise VmError("Failed to deassign device from IOMMU (%x:%x.%x)"                              % (bus, slot, func))            log.debug("pci: deassign device %x:%x.%x" % (bus, slot, func))        for (start, size) in dev.ioports:            log.debug('pci: disabling ioport 0x%x/0x%x'%(start,size))            rc = xc.domain_ioport_permission(domid = fe_domid, first_port = start,                    nr_ports = size, allow_access = False)            if rc<0:                raise VmError(('pci: failed to configure I/O ports on device '+                            '%s - errno=%d')%(dev.name,rc))        for (start, size) in dev.iomem:            # Convert start/size from bytes to page frame sizes            start_pfn = start>>PAGE_SHIFT            # Round number of pages up to nearest page boundary (if not on one)            nr_pfns = (size+(PAGE_SIZE-1))>>PAGE_SHIFT            log.debug('pci: disabling iomem 0x%x/0x%x pfn 0x%x/0x%x'% \                    (start,size,start_pfn,nr_pfns))            rc = xc.domain_iomem_permission(domid =  fe_domid,                    first_pfn = start_pfn,                    nr_pfns = nr_pfns,                    allow_access = False)            if rc<0:                raise VmError(('pci: failed to configure I/O memory on device '+                            '%s - errno=%d')%(dev.name,rc))        if dev.irq>0:            log.debug('pci: disabling irq %d'%dev.irq)            rc = xc.domain_irq_permission(domid =  fe_domid, pirq = dev.irq,                    allow_access = False)            if rc<0:                raise VmError(('pci: failed to configure irq on device '+                            '%s - errno=%d')%(dev.name,rc))        dev.do_FLR()    def cleanupDevice(self, devid):        """ Detach I/O resources for device and cleanup xenstore nodes        after reconfigure.        @param devid: The device ID        @type devid:  int        @return:      Return the number of devices connected        @rtype:       int        """        num_devs = int(self.readBackend(devid, 'num_devs'))        new_num_devs = 0        for i in range(num_devs):            state = int(self.readBackend(devid, 'state-%i' % i))            if state == xenbusState['Closing']:                # Detach I/O resources.                dev = self.readBackend(devid, 'dev-%i' % i)                (domain, bus, slotfunc) = dev.split(':')                (slot, func) = slotfunc.split('.')                domain = parse_hex(domain)                bus = parse_hex(bus)                slot = parse_hex(slot)                func = parse_hex(func)                            # In HVM case, I/O resources are disabled in ioemu.                self.cleanupOneDevice(domain, bus, slot, func)                # Remove xenstore nodes.                self.removeBackend(devid, 'dev-%i' % i)                self.removeBackend(devid, 'vdev-%i' % i)                self.removeBackend(devid, 'state-%i' % i)                self.removeBackend(devid, 'uuid-%i' % i)            else:                if new_num_devs != i:                    tmpdev = self.readBackend(devid, 'dev-%i' % i)                    self.writeBackend(devid, 'dev-%i' % new_num_devs, tmpdev)                    self.removeBackend(devid, 'dev-%i' % i)                    tmpvdev = self.readBackend(devid, 'vdev-%i' % i)                    if tmpvdev is not None:                        self.writeBackend(devid, 'vdev-%i' % new_num_devs,                                          tmpvdev)                    self.removeBackend(devid, 'vdev-%i' % i)                    tmpstate = self.readBackend(devid, 'state-%i' % i)                    self.writeBackend(devid, 'state-%i' % new_num_devs, tmpstate)                    self.removeBackend(devid, 'state-%i' % i)                    tmpuuid = self.readBackend(devid, 'uuid-%i' % i)                    self.writeBackend(devid, 'uuid-%i' % new_num_devs, tmpuuid)                    self.removeBackend(devid, 'uuid-%i' % i)                new_num_devs = new_num_devs + 1        self.writeBackend(devid, 'num_devs', str(new_num_devs))        return new_num_devs    def cleanupDeviceOnDomainDestroy(self, devid):        num_devs = int(self.readBackend(devid, 'num_devs'))        dev_str_list = []        for i in range(num_devs):            dev_str = self.readBackend(devid, 'dev-%i' % i)            dev_str_list = dev_str_list + [dev_str]        for dev_str in dev_str_list:            (dom, b, d, f) = parse_pci_name(dev_str)            try:                dev = PciDevice(dom, b, d, f)            except Exception, e:                raise VmError("pci: failed to locate device and "+                        "parse it's resources - "+str(e))            dev.do_FLR()    def waitForBackend(self,devid):        return (0, "ok - no hotplug")    def migrate(self, config, network, dst, step, domName):        raise XendError('Migration not permitted with assigned PCI device.')

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?