debuggers.hg
changeset 18085:39c2cab9e765
xm: vt-d: Add a command "xm pci-list-assignable-devices" to list all
the assignable devices.
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
the assignable devices.
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Jul 14 10:12:07 2008 +0100 (2008-07-14) |
parents | e61978c24d84 |
children | 79517ed2a108 |
files | tools/python/xen/util/pci.py tools/python/xen/xm/main.py |
line diff
1.1 --- a/tools/python/xen/util/pci.py Mon Jul 14 10:11:39 2008 +0100 1.2 +++ b/tools/python/xen/util/pci.py Mon Jul 14 10:12:07 2008 +0100 1.3 @@ -27,6 +27,7 @@ SYSFS_PCI_DEV_DEVICE_PATH = '/device' 1.4 SYSFS_PCI_DEV_SUBVENDOR_PATH = '/subsystem_vendor' 1.5 SYSFS_PCI_DEV_SUBDEVICE_PATH = '/subsystem_device' 1.6 SYSFS_PCI_DEV_CLASS_PATH = '/class' 1.7 +SYSFS_PCIBACK_PATH = '/bus/pci/drivers/pciback/' 1.8 1.9 LSPCI_CMD = 'lspci' 1.10 1.11 @@ -210,6 +211,109 @@ def restore_pci_conf_space(pci_cfg_list) 1.12 os.write(fd, dw) 1.13 os.close(fd) 1.14 1.15 +def find_all_devices_owned_by_pciback(): 1.16 + sysfs_mnt = find_sysfs_mnt() 1.17 + pciback_path = sysfs_mnt + SYSFS_PCIBACK_PATH 1.18 + pci_names = os.popen('ls ' + pciback_path).read() 1.19 + pci_list = re.findall(PCI_DEV_REG_EXPRESS_STR, pci_names) 1.20 + dev_list = [] 1.21 + for pci in pci_list: 1.22 + (dom, b, d, f) = parse_pci_name(pci) 1.23 + dev = PciDevice(dom, b, d, f) 1.24 + dev_list = dev_list + [dev] 1.25 + return dev_list 1.26 + 1.27 +def transform_list(target, src): 1.28 + ''' src: its element is pci string (Format: xxxx:xx:xx:x). 1.29 + target: its element is pci string, or a list of pci string. 1.30 + 1.31 + If all the elements in src are in target, we remove them from target 1.32 + and add src into target; otherwise, we remove from target all the 1.33 + elements that also appear in src. 1.34 + ''' 1.35 + result = [] 1.36 + target_contains_src = True 1.37 + for e in src: 1.38 + if not e in target: 1.39 + target_contains_src = False 1.40 + break 1.41 + 1.42 + if target_contains_src: 1.43 + result = result + [src] 1.44 + for e in target: 1.45 + if not e in src: 1.46 + result = result + [e] 1.47 + return result 1.48 + 1.49 +def check_FLR_capability(dev_list): 1.50 + i = len(dev_list) 1.51 + if i == 0: 1.52 + return [] 1.53 + i = i - 1; 1.54 + while i >= 0: 1.55 + dev = dev_list[i] 1.56 + if dev.bus == 0: 1.57 + if dev.dev_type == DEV_TYPE_PCIe_ENDPOINT and not dev.pcie_flr: 1.58 + del dev_list[i] 1.59 + elif dev.dev_type == DEV_TYPE_PCI and not dev.pci_af_flr: 1.60 + del dev_list[i] 1.61 + i = i - 1 1.62 + 1.63 + pci_list = [] 1.64 + pci_dev_dict = {} 1.65 + for dev in dev_list: 1.66 + pci_list = pci_list + [dev.name] 1.67 + pci_dev_dict[dev.name] = dev 1.68 + 1.69 + while True: 1.70 + need_transform = False 1.71 + for pci in pci_list: 1.72 + if isinstance(pci, types.StringTypes): 1.73 + dev = pci_dev_dict[pci] 1.74 + if dev.dev_type == DEV_TYPE_PCIe_ENDPOINT and not dev.pcie_flr: 1.75 + coassigned_pci_list = dev.find_all_the_multi_functions() 1.76 + need_transform = True 1.77 + elif dev.dev_type == DEV_TYPE_PCI and not dev.pci_af_flr: 1.78 + coassigned_pci_list = dev.find_coassigned_devices(True) 1.79 + del coassigned_pci_list[0] 1.80 + need_transform = True 1.81 + 1.82 + if need_transform: 1.83 + pci_list = transform_list(pci_list, coassigned_pci_list) 1.84 + if not need_transform: 1.85 + break 1.86 + 1.87 + if len(pci_list) == 0: 1.88 + return [] 1.89 + 1.90 + for i in range(0, len(pci_list)): 1.91 + if isinstance(pci_list[i], types.StringTypes): 1.92 + pci_list[i] = [pci_list[i]] 1.93 + 1.94 + # Now every element in pci_list is a list of pci string. 1.95 + 1.96 + result = [] 1.97 + for pci_names in pci_list: 1.98 + devs = [] 1.99 + for pci in pci_names: 1.100 + devs = devs + [pci_dev_dict[pci]] 1.101 + result = result + [devs] 1.102 + return result 1.103 + 1.104 +def check_mmio_bar(devs_list): 1.105 + result = [] 1.106 + 1.107 + for dev_list in devs_list: 1.108 + non_aligned_bar_found = False 1.109 + for dev in dev_list: 1.110 + if dev.has_non_page_aligned_bar: 1.111 + non_aligned_bar_found = True 1.112 + break 1.113 + if not non_aligned_bar_found: 1.114 + result = result + [dev_list] 1.115 + 1.116 + return result 1.117 + 1.118 class PciDeviceNotFoundError(Exception): 1.119 def __init__(self,domain,bus,slot,func): 1.120 self.domain = domain
2.1 --- a/tools/python/xen/xm/main.py Mon Jul 14 10:11:39 2008 +0100 2.2 +++ b/tools/python/xen/xm/main.py Mon Jul 14 10:12:07 2008 +0100 2.3 @@ -38,6 +38,7 @@ from select import select 2.4 import xml.dom.minidom 2.5 from xen.util.blkif import blkdev_name_to_number 2.6 from xen.util import vscsi_util 2.7 +from xen.util.pci import * 2.8 2.9 import warnings 2.10 warnings.filterwarnings('ignore', category=FutureWarning) 2.11 @@ -56,6 +57,9 @@ from xen.util.acmpolicy import ACM_LABEL 2.12 2.13 import XenAPI 2.14 2.15 +import xen.lowlevel.xc 2.16 +xc = xen.lowlevel.xc.xc() 2.17 + 2.18 import inspect 2.19 from xen.xend import XendOptions 2.20 xoptions = XendOptions.instance() 2.21 @@ -183,6 +187,7 @@ SUBCOMMAND_HELP = { 2.22 'Remove a domain\'s pass-through pci device.'), 2.23 'pci-list' : ('<Domain>', 2.24 'List pass-through pci devices for a domain.'), 2.25 + 'pci-list-assignable-devices' : ('', 'List all the assignable pci devices'), 2.26 'scsi-attach' : ('<Domain> <PhysDevice> <VirtDevice> [BackDomain]', 2.27 'Attach a new SCSI device.'), 2.28 'scsi-detach' : ('<Domain> <VirtDevice>', 2.29 @@ -355,6 +360,7 @@ device_commands = [ 2.30 "pci-attach", 2.31 "pci-detach", 2.32 "pci-list", 2.33 + "pci-list-assignable-devices", 2.34 "scsi-attach", 2.35 "scsi-detach", 2.36 "scsi-list", 2.37 @@ -2116,6 +2122,35 @@ def xm_pci_list(args): 2.38 hdr = 1 2.39 print ( fmt_str % x ) 2.40 2.41 +def xm_pci_list_assignable_devices(args): 2.42 + # Each element of dev_list is a PciDevice 2.43 + dev_list = find_all_devices_owned_by_pciback() 2.44 + 2.45 + # Each element of devs_list is a list of PciDevice 2.46 + devs_list = check_FLR_capability(dev_list) 2.47 + 2.48 + devs_list = check_mmio_bar(devs_list) 2.49 + 2.50 + # Check if the devices have been assigned to guests. 2.51 + final_devs_list = [] 2.52 + for dev_list in devs_list: 2.53 + available = True 2.54 + for d in dev_list: 2.55 + pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func) 2.56 + # Xen doesn't care what the domid is, so we pass 0 here... 2.57 + domid = 0 2.58 + bdf = xc.test_assign_device(domid, pci_str) 2.59 + if bdf != 0: 2.60 + available = False 2.61 + break 2.62 + if available: 2.63 + final_devs_list = final_devs_list + [dev_list] 2.64 + 2.65 + for dev_list in final_devs_list: 2.66 + for d in dev_list: 2.67 + print d.name, 2.68 + print 2.69 + 2.70 def vscsi_convert_sxp_to_dict(dev_sxp): 2.71 dev_dict = {} 2.72 for opt_val in dev_sxp[1:]: 2.73 @@ -2645,6 +2680,7 @@ commands = { 2.74 "pci-attach": xm_pci_attach, 2.75 "pci-detach": xm_pci_detach, 2.76 "pci-list": xm_pci_list, 2.77 + "pci-list-assignable-devices": xm_pci_list_assignable_devices, 2.78 # vscsi 2.79 "scsi-attach": xm_scsi_attach, 2.80 "scsi-detach": xm_scsi_detach,