on 2014/06/09 23:14, Sheldon wrote:
On 06/09/2014 05:28 PM, Zhou Zheng Sheng wrote:
> +def _is_pci_qualified(pci_dev):
> + # PCI class such as bridge and storage controller are not
> suitable to
> + # passthrough to VM, so we make a whitelist and only passthrough PCI
> + # class in the list.
> +
> + whitelist_pci_classes = {
> + # Refer to Linux Kernel code include/linux/pci_ids.h
> + 0x000000: { # Old PCI devices
> + 0x000100: None}, # Old VGA devices
looks strange?
So the problem you think here is?
> + 0x020000: None, # Network controller
> + 0x030000: None, # Display controller
> + 0x040000: None, # Multimedia device
> + 0x090000: None, # Inupt device
> + 0x0d0000: None, # Wireless controller
> + 0x0f0000: None, # Satellite communication controller
> + 0x100000: None, # Cryption controller
> + 0x110000: None, # Signal Processing controller
> + }
> +
> + with open(os.path.join(pci_dev['path'], 'class')) as f:
> + pci_class = int(f.read(), 16)
> +
> + try:
> + subclass = whitelist_pci_classes[pci_class & 0xff0000]
> + except KeyError:
> + return False
> +
> + if subclass is None:
> + return True
> +
> + if pci_class & 0xffff00 in subclass:
> + return True
> +
> + return False
> +
> +
> +def get_passthrough_dev_infos():
> + ''' Get devices eligible to be passed through to VM.
'''
> +
> + dev_infos = _get_all_host_dev_infos()
> + devs = dict([(dev_info['name'], dev_info) for dev_info in
> dev_infos])
> +
> + for dev in dev_infos:
> + if dev['device_type'] in ('pci', 'usb_device',
'scsi'):
> + _strip_parents(devs, dev)
> +
> + def is_eligible(dev):
> + if dev['device_type'] not in ('pci', 'usb_device',
'scsi'):
> + return False
> + if dev['device_type'] == 'pci':
> + return _is_pci_qualified(dev)
> + return True
> +
> + return [dev for dev in devs.itervalues() if is_eligible(dev)]
> +
> +
> +def get_affected_passthrough_devices(passthrough_dev):
> + devs = dict([(dev['name'], dev) for dev in
> _get_all_host_dev_infos()])
> +
> + def get_iommu_group(dev_info):
> + try:
> + return int(dev_info['iommuGroup'])
> + except KeyError:
> + pass
> +
> + parent = dev_info['parent']
> + while parent is not None:
> + try:
> + iommuGroup = int(devs[parent]['iommuGroup'])
> + except KeyError:
> + pass
> + else:
> + return iommuGroup
> + parent = devs[parent]['parent']
> +
> + return -1
> +
> + iommu_group = get_iommu_group(passthrough_dev)
> +
> + return [dev for dev in get_passthrough_dev_infos()
> + if dev['name'] != passthrough_dev['name'] and
> + get_iommu_group(dev) == iommu_group]
does this means dev['name'] and passthrough_dev['name'] in same IOMMU
group ?
Yes.