[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xend: pass-through: fix "xm pci-list-assignable-devices' for pv_guest
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1248795732 -3600 # Node ID 7faf35a248c0cffa133347bae01a22e92345fd28 # Parent 5bb626155123eab4dbe81f15a3b6e4746da63982 xend: pass-through: fix "xm pci-list-assignable-devices' for pv_guest xc.test_assign_device(dev) can only tell us if dev is assigned to hvm guest; if a device is assigned to pv guest, xc.test_assign_device() still tells us the device is not assigned yet, as a result, the device still appears in the output of "xm pci-list-assignable-devices", and xend would not prevent us from assigning the device to a new pv or hvm guest. To judge if a device has been assigned to guest, we have to scan xenstore. Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx> --- tools/python/xen/xend/XendConfig.py | 3 - tools/python/xen/xend/XendDomainInfo.py | 52 +++++++++++++++----------------- tools/python/xen/xend/XendNode.py | 9 ++--- tools/python/xen/xend/server/pciif.py | 27 ++++++++++++---- 4 files changed, 50 insertions(+), 41 deletions(-) diff -r 5bb626155123 -r 7faf35a248c0 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Tue Jul 28 16:41:13 2009 +0100 +++ b/tools/python/xen/xend/XendConfig.py Tue Jul 28 16:42:12 2009 +0100 @@ -2059,9 +2059,6 @@ class XendConfig(dict): return self['platform'].get('hap', 0) def update_platform_pci(self): - if not self.is_hvm(): - return - pci = [] for dev_type, dev_info in self.all_devices_sxpr(): if dev_type != 'pci': diff -r 5bb626155123 -r 7faf35a248c0 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Tue Jul 28 16:41:13 2009 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Jul 28 16:42:12 2009 +0100 @@ -42,7 +42,7 @@ from xen.util.pci import serialise_pci_o from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \ pci_dict_to_bdf_str, pci_dict_to_xc_str, \ pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \ - pci_dict_cmp, PCI_DEVFN, PCI_SLOT, PCI_FUNC + pci_dict_cmp, PCI_DEVFN, PCI_SLOT, PCI_FUNC, parse_hex from xen.xend import balloon, sxp, uuid, image, arch from xen.xend import XendOptions, XendNode, XendConfig @@ -296,20 +296,11 @@ def dom_get(dom): log.trace("domain_getinfo(%d) failed, ignoring: %s", dom, str(err)) return None -def get_assigned_pci_devices(domid): - dev_str_list = [] - path = '/local/domain/0/backend/pci/%u/0/' % domid - num_devs = xstransact.Read(path + 'num_devs'); - if num_devs is None or num_devs == "": - return dev_str_list - num_devs = int(num_devs); - for i in range(num_devs): - dev_str = xstransact.Read(path + 'dev-%i' % i) - dev_str_list = dev_str_list + [dev_str] - return dev_str_list +from xen.xend.server.pciif import parse_pci_name, PciDevice,\ + get_assigned_pci_devices, get_all_assigned_pci_devices + def do_FLR(domid): - from xen.xend.server.pciif import parse_pci_name, PciDevice dev_str_list = get_assigned_pci_devices(domid) for dev_str in dev_str_list: @@ -686,15 +677,14 @@ class XendDomainInfo: raise VmError("device is already inserted") # Test whether the devices can be assigned with VT-d - bdf = xc.test_assign_device(0, pci_dict_to_xc_str(new_dev)) - if bdf != 0: - if bdf == -1: - raise VmError("failed to assign device: maybe the platform" - " doesn't support VT-d, or VT-d isn't enabled" - " properly?") - raise VmError("fail to assign device(%s): maybe it has" - " already been assigned to other domain, or maybe" - " it doesn't exist." % pci_dict_to_bdf_str(new_dev)) + pci_name = '%04x:%02x:%02x.%x' % \ + (parse_hex(new_dev['domain']),\ + parse_hex(new_dev['bus']),\ + parse_hex(new_dev['slot']),\ + parse_hex(new_dev['func'])) + if pci_name in get_all_assigned_pci_devices(): + raise VmError("failed to assign device %s that has" + " already been assigned to other domain." % pci_str) # Here, we duplicate some checkings (in some cases, we mustn't allow # a device to be hot-plugged into an HVM guest) that are also done in @@ -732,8 +722,7 @@ class XendDomainInfo: pci_device.devs_check_driver(coassignment_list) assigned_pci_device_str_list = self._get_assigned_pci_devices() for pci_str in coassignment_list: - pci_dev = parse_pci_name(pci_str) - if xc.test_assign_device(0, pci_dict_to_xc_str(pci_dev)) == 0: + if not (pci_str in get_all_assigned_pci_devices()): continue if not pci_str in assigned_pci_device_str_list: raise VmError(("pci: failed to pci-attach %s to domain %s" + \ @@ -859,7 +848,7 @@ class XendDomainInfo: pci_dev = sxp.children(dev_sxp, 'dev')[0] dev_config = pci_convert_sxp_to_dict(dev_sxp) dev = dev_config['devs'][0] - + # Do HVM specific processing if self.info.is_hvm(): if pci_state == 'Initialising': @@ -2454,7 +2443,8 @@ class XendDomainInfo: if pci and len(pci) > 0: pci = map(lambda x: x[0:4], pci) # strip options pci_str = str(pci) - if hvm and pci_str: + + if hvm and pci_str != '': bdf = xc.test_assign_device(0, pci_str) if bdf != 0: if bdf == -1: @@ -2465,9 +2455,17 @@ class XendDomainInfo: devfn = (bdf >> 8) & 0xff dev = (devfn >> 3) & 0x1f func = devfn & 0x7 - raise VmError("fail to assign device(%x:%x.%x): maybe it has" + raise VmError("failed to assign device(%x:%x.%x): maybe it has" " already been assigned to other domain, or maybe" " it doesn't exist." % (bus, dev, func)) + + # This test is done for both pv and hvm guest. + for p in pci: + pci_name = '%04x:%02x:%02x.%x' % \ + (parse_hex(p[0]), parse_hex(p[1]), parse_hex(p[2]), parse_hex(p[3])) + if pci_name in get_all_assigned_pci_devices(): + raise VmError("failed to assign device %s that has" + " already been assigned to other domain." % pci_name) # register the domain in the list from xen.xend import XendDomain diff -r 5bb626155123 -r 7faf35a248c0 tools/python/xen/xend/XendNode.py --- a/tools/python/xen/xend/XendNode.py Tue Jul 28 16:41:13 2009 +0100 +++ b/tools/python/xen/xend/XendNode.py Tue Jul 28 16:42:12 2009 +0100 @@ -834,6 +834,9 @@ class XendNode: def pciinfo(self): + from xen.xend.server.pciif import get_all_assigned_pci_devices + assigned_devs = get_all_assigned_pci_devices() + # Each element of dev_list is a PciDevice dev_list = PciUtil.find_all_assignable_devices() @@ -847,11 +850,7 @@ class XendNode: for dev_list in devs_list: available = True for d in dev_list: - pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func) - # Xen doesn't care what the domid is, so we pass 0 here... - domid = 0 - bdf = self.xc.test_assign_device(domid, pci_str) - if bdf != 0: + if d.name in assigned_devs: available = False break if available: diff -r 5bb626155123 -r 7faf35a248c0 tools/python/xen/xend/server/pciif.py --- a/tools/python/xen/xend/server/pciif.py Tue Jul 28 16:41:13 2009 +0100 +++ b/tools/python/xen/xend/server/pciif.py Tue Jul 28 16:42:12 2009 +0100 @@ -57,6 +57,25 @@ def parse_hex(val): return val except ValueError: return None + +def get_assigned_pci_devices(domid): + dev_str_list = [] + path = '/local/domain/0/backend/pci/%u/0/' % domid + num_devs = xstransact.Read(path + 'num_devs'); + if num_devs is None or num_devs == "": + return dev_str_list + num_devs = int(num_devs) + for i in range(num_devs): + dev_str = xstransact.Read(path + 'dev-%i' % i) + dev_str_list = dev_str_list + [dev_str] + return dev_str_list + +def get_all_assigned_pci_devices(): + dom_list = xstransact.List('/local/domain') + pci_str_list = [] + for d in dom_list: + pci_str_list = pci_str_list + get_assigned_pci_devices(int(d)) + return pci_str_list class PciController(DevController): @@ -368,11 +387,8 @@ class PciController(DevController): dev.devs_check_driver(funcs) 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: + if f in get_all_assigned_pci_devices(): err_msg = 'pci: %s must be co-assigned to' + \ ' the same guest with %s' raise VmError(err_msg % (f, dev.name)) @@ -396,9 +412,8 @@ class PciController(DevController): dev.devs_check_driver(devs_str) for s in devs_str: if not s in pci_str_list: - s_pci_str = pci_dict_to_bdf_str(parse_pci_name(s)) # s has been assigned to other guest? - if xc.test_assign_device(0, s_pci_str) != 0: + if s in get_all_assigned_pci_devices(): err_msg = 'pci: %s must be co-assigned to the'+\ ' same guest with %s' raise VmError(err_msg % (s, dev.name)) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |