Example #1
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""

        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('ioports: Missing %s config setting' % field)

                return parse_ioport(val)
            except:
                raise VmError('ioports: Invalid config setting %s: %s' %
                              (field, val))
       
        io_from = get_param('from')
        io_to = get_param('to') 

        if io_to < io_from or io_to >= 65536:
            raise VmError('ioports: Invalid i/o range: %s - %s' %
                          (io_from, io_to))

        rc = xc.domain_ioport_permission(domid        = self.getDomid(),
                                         first_port   = io_from,
                                         nr_ports     = io_to - io_from + 1,
                                         allow_access = True)

        if rc < 0:
            #todo non-fatal
            raise VmError(
                'ioports: Failed to configure legacy i/o range: %s - %s' %
                (io_from, io_to))

        back = dict([(k, config[k]) for k in self.valid_cfg if k in config])
        return (self.allocateDeviceID(), back, {})
Example #2
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""
        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('ioports: Missing %s config setting' % field)

                return parse_ioport(val)
            except:
                raise VmError('ioports: Invalid config setting %s: %s' %
                              (field, val))

        io_from = get_param('from')
        io_to = get_param('to')

        if io_to < io_from or io_to >= 65536:
            raise VmError('ioports: Invalid i/o range: %s - %s' %
                          (io_from, io_to))

        rc = xc.domain_ioport_permission(domid=self.getDomid(),
                                         first_port=io_from,
                                         nr_ports=io_to - io_from + 1,
                                         allow_access=True)

        if rc < 0:
            #todo non-fatal
            raise VmError(
                'ioports: Failed to configure legacy i/o range: %s - %s' %
                (io_from, io_to))

        return (None, {}, {})
Example #3
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""

        def get_param(field):
            try:
                val = sxp.child_value(config, field)

                if not val:
                    raise VmError('ioports: Missing %s config setting' % field)

                return parse_ioport(val)
            except:
                raise VmError('ioports: Invalid config setting %s: %s' %
                              (field, val))
       
        io_from = get_param('from')
        io_to = get_param('to') 

        if io_to < io_from or io_to >= 65536:
            raise VmError('ioports: Invalid i/o range: %s - %s' %
                          (io_from, io_to))

        rc = xc.domain_ioport_permission(dom          = self.getDomid(),
                                         first_port   = io_from,
                                         nr_ports     = io_to - io_from + 1,
                                         allow_access = True)

        if rc < 0:
            #todo non-fatal
            raise VmError(
                'ioports: Failed to configure legacy i/o range: %s - %s' %
                (io_from, io_to))

        return (None, {}, {})
Example #4
0
    def domain_ioport_range_disable(self, domid, first, last):
        """Disable access to a range of IO ports for a domain

        @param first: first IO port
        @param last: last IO port
        @return: 0 on success, -1 on error
        """
        dominfo = self.domain_lookup_by_name_or_id_nr(domid)
        if not dominfo:
            raise XendInvalidDomain(str(domid))
        nr_ports = last - first + 1
        try:
            return xc.domain_ioport_permission(dominfo.getDomid(),
                                               first_port = first,
                                               nr_ports = nr_ports,
                                               allow_access = 0)
        except Exception, ex:
            raise XendError(str(ex))
Example #5
0
        self.CheckSiblingDevices(fe_domid, dev)

        if dev.driver == 'pciback':
            PCIQuirk(dev)

        if not self.vm.info.is_hvm() and not self.vm.info.is_stubdom() :
            # Setup IOMMU device assignment
            bdf = xc.assign_device(fe_domid, pci_dict_to_xc_str(pci_dev))
            pci_str = pci_dict_to_bdf_str(pci_dev)
            if bdf > 0:
                raise VmError("Failed to assign device to IOMMU (%s)" % pci_str)
            log.debug("pci: assign device %s" % pci_str)

        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,
Example #6
0
class PciController(DevController):
    def __init__(self, vm):
        DevController.__init__(self, vm)

    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""

        #log.debug('pci config='+sxp.to_string(config))

        def get_param(config, field, default=None):
            try:
                val = sxp.child_value(config, field)

                if not val:
                    if default == None:
                        raise VmError('pci: Missing %s config setting' % field)
                    else:
                        return default

                if isinstance(val, types.StringType):
                    return int(val, 16)
                else:
                    return val
            except:
                if default == None:
                    raise VmError('pci: Invalid config setting %s: %s' %
                                  (field, val))
                else:
                    return default

        back = {}

        val = sxp.child_value(config, 'dev')
        if isinstance(val, list):
            pcidevid = 0
            for dev_config in sxp.children(config, 'dev'):
                domain = get_param(dev_config, 'domain', 0)
                bus = get_param(dev_config, 'bus')
                slot = get_param(dev_config, 'slot')
                func = get_param(dev_config, 'func')

                self.setupDevice(domain, bus, slot, func)

                back['dev-%i'%(pcidevid)]="%04x:%02x:%02x.%02x"% \
                        (domain, bus, slot, func)
                pcidevid += 1

            back['num_devs'] = str(pcidevid)

        else:
            # Xen 2.0 configuration compatibility
            domain = get_param(dev_config, 'domain', 0)
            bus = get_param(config, 'bus')
            slot = get_param(config, 'dev')
            func = get_param(config, 'func')

            self.setupDevice(domain, bus, slot, func)

            back['dev-0'] = "%04x:%02x:%02x.%02x" % (domain, bus, slot, func)
            back['num_devs'] = str(1)

        return (0, back, {})

    def setupDevice(self, domain, bus, slot, func):
        """ Attach I/O resources for device to 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 - %s" + 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))

        for (start, size) in dev.ioports:
            log.debug('pci: enabling ioport 0x%x/0x%x' % (start, size))
            rc = xc.domain_ioport_permission(dom=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(dom=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))

        if dev.irq > 0:
            log.debug('pci: enabling irq %d' % dev.irq)
            rc = xc.domain_irq_permission(dom=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))
Example #7
0
        if dev.driver == 'pciback':
            PCIQuirk(dev)

        if not self.vm.info.is_hvm() and not self.vm.info.is_stubdom():
            # Setup IOMMU device assignment
            bdf = xc.assign_device(fe_domid, pci_dict_to_xc_str(pci_dev))
            pci_str = pci_dict_to_bdf_str(pci_dev)
            if bdf > 0:
                raise VmError("Failed to assign device to IOMMU (%s)" %
                              pci_str)
            log.debug("pci: assign device %s" % pci_str)

        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,
Example #8
0
class PciController(DevController):
    def __init__(self, vm):
        DevController.__init__(self, vm)

    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""
        def parse_hex(val):
            try:
                if isinstance(val, types.StringTypes):
                    return int(val, 16)
                else:
                    return val
            except ValueError:
                return None

        back = {}
        pcidevid = 0
        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))
            self.setupDevice(domain, bus, slot, func)
            back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
                                        (domain, bus, slot, func)
            pcidevid += 1

        back['num_devs'] = str(pcidevid)
        back['uuid'] = config.get('uuid', '')
        return (0, back, {})

    def getDeviceConfiguration(self, devid, transaction=None):
        result = DevController.getDeviceConfiguration(self, devid, transaction)
        num_devs = self.readBackend(devid, 'num_devs')
        pci_devs = []

        for i in range(int(num_devs)):
            dev_config = self.readBackend(devid, 'dev-%d' % i)

            pci_match = re.match(
                r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" +
                r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" +
                r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" +
                r"(?P<func>[0-9a-fA-F]{1,2})", dev_config)

            if pci_match != None:
                pci_dev_info = pci_match.groupdict()
                pci_devs.append({
                    'domain': '0x%(domain)s' % pci_dev_info,
                    'bus': '0x%(bus)s' % pci_dev_info,
                    'slot': '0x%(slot)s' % pci_dev_info,
                    'func': '0x%(func)s' % pci_dev_info
                })

        result['devs'] = pci_devs
        result['uuid'] = self.readBackend(devid, 'uuid')
        return result

    def configuration(self, devid, transaction=None):
        """Returns SXPR for devices on domain.

        @note: we treat this dict especially to convert to
        SXP because it is not a straight dict of strings."""

        configDict = self.getDeviceConfiguration(devid, transaction)
        sxpr = [self.deviceClass]

        # remove devs
        devs = configDict.pop('devs', [])

        for dev in devs:
            dev_sxpr = ['dev']
            for dev_item in dev.items():
                dev_sxpr.append(list(dev_item))
            sxpr.append(dev_sxpr)

        for key, val in configDict.items():
            if type(val) == type(list()):
                for v in val:
                    sxpr.append([key, v])
            else:
                sxpr.append([key, val])

        return sxpr

    def setupDevice(self, domain, bus, slot, func):
        """ Attach I/O resources for device to 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))

        PCIQuirk(dev.vendor, dev.device, dev.subvendor, dev.subdevice, domain,
                 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))

        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))