Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 00/16] xend: pass-through: various clean-ups and infrastructure
This series of patches cleans up various aspects of the PCI pass-through code. This is working towards multi-function pass-through devices in guests. But most of these changes are useful in their own right, so I am posting this batch without the rest of the multi-function changes. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 01/16] xend: pass-through: Only call setupOneDevice() once per device
As observed by Dexuan Cui, when PCI devices are passed through at
domain-creation-time setupOneDevice() will be called twice.
Once via setupDevice() and once via econfigureDevice() which
is called in pci_device_configure().
This patch removes the first of these.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-15
11:24:00.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-15
11:24:02.000000000 +1000
@@ -436,8 +436,6 @@ class PciController(DevController):
'' 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)
wPath = ''/local/domain/0/backend/pci/%u/0/aerState'' %
(self.getDomid())
self.aerStateWatch = xswatch(wPath, self._handleAerStateWatch)
log.debug(''pci: register aer watch %s'', wPath)
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 02/16] xend: pass-through: fix typo: spx -> sxp
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-11 19:05:28.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-11 19:05:40.000000000
+1000
@@ -124,7 +124,7 @@ def serialise_pci_opts(opts):
def split_pci_opts(opts):
return map(lambda x: x.split(''=''),
opts.split('',''))
-def pci_opts_list_to_spx(list):
+def pci_opts_list_to_sxp(list):
[''dev''] + map(lambda x: [''opts'', x],
list)
def parse_hex(val):
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-11
19:05:28.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-11
19:05:54.000000000 +1000
@@ -39,7 +39,7 @@ from xen.util import asserts, auxbin
from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
import xen.util.xsm.xsm as security
from xen.util import xsconstants
-from xen.util.pci import serialise_pci_opts, pci_opts_list_to_spx
+from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendOptions, XendNode, XendConfig
@@ -3771,7 +3771,7 @@ class XendDomainInfo:
opts_dict = xenapi_pci.get(''options'')
for k in opts_dict.keys():
dpci_opts.append([k, opts_dict[k]])
- opts_sxp = pci_opts_list_to_spx(dpci_opts)
+ opts_sxp = pci_opts_list_to_sxp(dpci_opts)
# Convert xenapi to sxp
ppci = XendAPIStore.get(xenapi_pci.get(''PPCI''),
''PPCI'')
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 03/16] xend: pass-through: tidy up PciController()
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-15
11:24:02.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-15
11:24:12.000000000 +1000
@@ -540,33 +540,24 @@ class PciController(DevController):
# 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)
- tmpopts = self.readBackend(devid, ''opts-%i'' %
i)
- if tmpopts is not None:
- self.removeBackend(devid, ''opts-%i'' % i)
+ list = [''dev'', ''vdev'',
''state'', ''uuid'']
+ if self.readBackend(devid, ''opts-%i'' % i) is
not None:
+ list.append(''opts'')
+ for key in list:
+ self.removeBackend(devid, ''%s-%i'' % (key,
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)
- tmpopts = self.readBackend(devid,
''opts-%i'' % i)
- if tmpopts is not None:
- self.removeBackend(devid, ''opts-%i'' %
i)
new_num_devs = new_num_devs + 1
+ if new_num_devs == i + 1:
+ continue
+
+ list = [''dev'', ''vdev'',
''state'', ''uuid'', ''opts'']
+ for key in list:
+ tmp = self.readBackend(devid, ''%s-%i'' %
(key, i))
+ if tmp is None:
+ continue
+ self.removeBackend(devid, ''%s-%i'' % (key,
i))
+ self.writeBackend(devid,
+ ''%s-%i'' % (key,
new_num_devs - 1), tmp)
self.writeBackend(devid, ''num_devs'',
str(new_num_devs))
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 04/16] xend: pass-through: cleanupDevice: move and remove recently added vslot entry
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-15
11:24:17.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-15
11:24:20.000000000 +1000
@@ -540,7 +540,7 @@ class PciController(DevController):
# In HVM case, I/O resources are disabled in ioemu.
self.cleanupOneDevice(domain, bus, slot, func)
# Remove xenstore nodes.
- list = [''dev'', ''vdev'',
''state'', ''uuid'']
+ list = [''dev'', ''vdev'',
''state'', ''uuid'', ''vslot'']
if self.readBackend(devid, ''opts-%i'' % i) is
not None:
list.append(''opts'')
for key in list:
@@ -550,7 +550,7 @@ class PciController(DevController):
if new_num_devs == i + 1:
continue
- list = [''dev'', ''vdev'',
''state'', ''uuid'', ''opts'']
+ list = [''dev'', ''vdev'',
''state'', ''uuid'', ''opts'',
''vslot'']
for key in list:
tmp = self.readBackend(devid, ''%s-%i'' %
(key, i))
if tmp is None:
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 05/16] xend: pass-through: sxp.merge() cant deal with values being a list
sxp.merge() can''t deal with values being a list so instead
of storing pci options as:
[ ''opts'', [ ''key1''
''value1''], [ ''key2'',
''value2''], ...]
store them as:
[ ''opts'', [ ''key1''
''value1''], [''opts'', [
''key2'', ''value2'']], ...
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
tools/python/xen/util/pci.py | 18 +++++++++++++--
tools/python/xen/xend/XendConfig.py | 38 +++++++++++++++------------------
tools/python/xen/xend/server/pciif.py | 3 +-
tools/python/xen/xm/create.py | 23 ++++++++-----------
tools/python/xen/xm/main.py | 11 ++++++---
tools/python/xen/xm/xenapi_create.py | 12 +++++-----
6 files changed, 58 insertions(+), 47 deletions(-)
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-13 10:32:59.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-13 10:33:14.000000000
+1000
@@ -118,14 +118,26 @@ def PCI_BDF(domain, bus, slot, func):
return (((domain & 0xffff) << 16) | ((bus & 0xff) << 8)
|
PCI_DEVFN(slot, func))
+def check_pci_opts(opts):
+ def f((k, v)):
+ if k not in [''msitranslate'',
''power_mgmt''] or \
+ not v.lower() in [''0'', ''1'',
''yes'', ''no'']:
+ raise PciDeviceParseError(''Invalid pci option %s=%s:
'' % (k, v))
+
+ map(f, opts)
+
def serialise_pci_opts(opts):
- return reduce(lambda x, y: x+'',''+y, map(lambda (x, y):
x+''=''+y, opts))
+ return '',''.join(map(lambda x:
''=''.join(x), opts))
def split_pci_opts(opts):
- return map(lambda x: x.split(''=''),
opts.split('',''))
+ return map(lambda x: x.split(''=''),
+ filter(lambda x: x != '''',
opts.split('','')))
def pci_opts_list_to_sxp(list):
- [''dev''] + map(lambda x: [''opts'', x],
list)
+ return [''dev''] + map(lambda x: [''opts'',
x], list)
+
+def pci_opts_list_from_sxp(dev):
+ return map(lambda x: sxp.children(x)[0], sxp.children(dev,
''opts''))
def parse_hex(val):
try:
Index: xen-unstable.hg/tools/python/xen/xend/XendConfig.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendConfig.py 2009-06-13
10:32:59.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendConfig.py 2009-06-13
10:33:04.000000000 +1000
@@ -36,6 +36,7 @@ from xen.xend.xenstore.xstransact import
from xen.xend.server.BlktapController import blktap_disk_types
from xen.xend.server.netif import randomMAC
from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
+from xen.util.pci import pci_opts_list_from_sxp
from xen.util import xsconstants
import xen.util.auxbin
@@ -1596,11 +1597,10 @@ class XendConfig(dict):
return ''''
def pci_convert_dict_to_sxp(self, dev, state, sub_state = None):
- sxp = [''pci'', [''dev''] + map(lambda
(x, y): [x, y], dev.items()),
- [''state'', state]]
+ pci_sxp = [''pci'', self.dev_dict_to_sxp(dev),
[''state'', state]]
if sub_state != None:
- sxp.append([''sub_state'', sub_state])
- return sxp
+ pci_sxp.append([''sub_state'', sub_state])
+ return pci_sxp
def pci_convert_sxp_to_dict(self, dev_sxp):
"""Convert pci device sxp to dict
@@ -1649,13 +1649,9 @@ class XendConfig(dict):
pci_devs = []
for pci_dev in sxp.children(dev_sxp, ''dev''):
- pci_dev_info = {}
- for opt_val in pci_dev[1:]:
- try:
- opt, val = opt_val
- pci_dev_info[opt] = val
- except (TypeError, ValueError):
- pass
+ pci_dev_info = dict(pci_dev[1:])
+ if ''opts'' in pci_dev_info:
+ pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
# append uuid to each pci device that does''t already have
one.
if not pci_dev_info.has_key(''uuid''):
dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
@@ -1966,6 +1962,15 @@ class XendConfig(dict):
result.extend([u for u in target[''devices''].keys() if
u not in result])
return result
+ # This includes a generic equivalent of pci_opts_list_to_sxp()
+ def dev_dict_to_sxp(self, dev):
+ def f((key, val)):
+ if isinstance(val, types.ListType):
+ return map(lambda x: [key, x], val)
+ return [[key, val]]
+ dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
+ return dev_sxp
+
def all_devices_sxpr(self, target = None):
"""Returns the SXPR for all devices in the current
configuration."""
sxprs = []
@@ -1988,10 +1993,7 @@ class XendConfig(dict):
if dev_info.has_key(''backend''):
sxpr.append([''backend'',
dev_info[''backend'']])
for pci_dev_info in dev_info[''devs'']:
- pci_dev_sxpr = [''dev'']
- for opt, val in pci_dev_info.items():
- pci_dev_sxpr.append([opt, val])
- sxpr.append(pci_dev_sxpr)
+ sxpr.append(self.dev_dict_to_sxp(pci_dev_info))
sxprs.append((dev_type, sxpr))
else:
sxpr = self.device_sxpr(dev_type = dev_type,
@@ -2118,11 +2120,7 @@ class XendConfig(dict):
slot = sxp.child_value(dev, ''slot'')
func = sxp.child_value(dev, ''func'')
vslot = sxp.child_value(dev, ''vslot'')
- opts = ''''
- for opt in sxp.child_value(dev, ''opts'', []):
- if opts:
- opts += '',''
- opts += ''%s=%s'' % (opt[0], str(opt[1]))
+ opts = pci_opts_list_from_sxp(dev)
pci.append([domain, bus, slot, func, vslot, opts])
self[''platform''][''pci''] = pci
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-13
10:32:59.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-13
10:33:04.000000000 +1000
@@ -222,7 +222,8 @@ class PciController(DevController):
dev_sxpr = [''dev'']
for dev_key, dev_val in dev.items():
if dev_key == ''opts'':
- dev_sxpr.append([''opts'',
split_pci_opts(dev_val)])
+ opts_sxpr = pci_opts_list_to_sxp(split_pci_opts(dev_val))
+ dev_sxpr = sxp.merge(dev_sxpr, opts_sxpr)
else:
dev_sxpr.append([dev_key, dev_val])
sxpr.append(dev_sxpr)
Index: xen-unstable.hg/tools/python/xen/xm/create.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xm/create.py 2009-06-13 10:32:59.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/xm/create.py 2009-06-13 10:33:04.000000000
+1000
@@ -38,6 +38,8 @@ from xen.util import vscsi_util
import xen.util.xsm.xsm as security
from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
from xen.util import utils, auxbin
+from xen.util.pci import split_pci_opts, check_pci_opts, \
+ pci_opts_list_to_sxp
from xen.xm.opts import *
@@ -705,23 +707,18 @@ def configure_pci(config_devs, vals):
"""
config_pci = []
for (domain, bus, slot, func, vslot, opts) in vals.pci:
- config_pci_opts = []
- d = comma_sep_kv_to_dict(opts)
-
- def f(k):
- if k not in [''msitranslate'',
''power_mgmt'']:
- err(''Invalid pci option: '' + k)
-
- config_pci_opts.append([k, d[k]])
-
config_pci_bdf = [''dev'', [''domain'',
domain], [''bus'', bus], \
[''slot'', slot],
[''func'', func],
[''vslot'', vslot]]
- map(f, d.keys())
- if len(config_pci_opts)>0:
- config_pci_bdf.append([''opts'', config_pci_opts])
- config_pci.append(config_pci_bdf)
+ opts_list = split_pci_opts(opts)
+ try:
+ check_pci_opts(opts_list)
+ except PciDeviceParseError, ex:
+ err(str(ex))
+
+ config_opts = pci_opts_list_to_sxp(split_pci_opts(opts))
+ config_pci.append(sxp.merge(config_pci_bdf, config_opts))
if len(config_pci)>0:
config_pci.insert(0, ''pci'')
Index: xen-unstable.hg/tools/python/xen/xm/main.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xm/main.py 2009-06-13 10:32:59.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/xm/main.py 2009-06-13 10:33:04.000000000
+1000
@@ -2504,12 +2504,15 @@ def parse_pci_configuration(args, state,
[''slot'', ''0x''+
pci_dev_info[''slot'']],
[''func'', ''0x''+
pci_dev_info[''func'']],
[''vslot'', ''0x%x'' %
int(vslot, 16)]]
- if len(opts) > 0:
- pci_bdf.append([''opts'', opts])
- pci.append(pci_bdf)
-
except:
raise OptionError("Invalid argument: %s %s" % (pci_dev_str,
vslot))
+
+ try:
+ check_pci_opts(opts)
+ except PciDeviceParseError, ex:
+ raise OptionError(str(ex))
+
+ pci.append(sxp.merge(pci_bdf, pci_opts_list_to_sxp(opts)))
pci.append([''state'', state])
return (dom, pci)
Index: xen-unstable.hg/tools/python/xen/xm/xenapi_create.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xm/xenapi_create.py 2009-06-13
10:32:59.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xm/xenapi_create.py 2009-06-13
10:33:04.000000000 +1000
@@ -26,6 +26,7 @@ from xen.xend.XendAPIConstants import XE
XEN_API_ON_CRASH_BEHAVIOUR
from xen.xm.opts import OptionError
from xen.util import xsconstants
+from xen.util.pci import pci_opts_list_from_sxp
from xen.util.path import SHAREDIR
import xen.util.xsm.xsm as security
@@ -945,12 +946,11 @@ class sxp2xml:
= get_child_by_name(dev_sxp, "func",
"0")
pci.attributes["vslot"] \
= get_child_by_name(dev_sxp, "vslot",
"0")
- for opt in get_child_by_name(dev_sxp, "opts",
""):
- if len(opt) > 0:
- pci_opt = document.createElement("pci_opt")
- pci_opt.attributes["key"] = opt[0]
- pci_opt.attributes["value"] = opt[1]
- pci.appendChild(pci_opt)
+ for opt in pci_opts_list_from_sxp(dev_sxp):
+ pci_opt = document.createElement("pci_opt")
+ pci_opt.attributes["key"] = opt[0]
+ pci_opt.attributes["value"] = opt[1]
+ pci.appendChild(pci_opt)
pcis.append(pci)
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 06/16] xend: pass-through: Remove PciDeviceNotFoundError, it is never used
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 11:24:25.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-15 11:24:25.000000000
+1000
@@ -375,17 +375,6 @@ def check_mmio_bar(devs_list):
return result
-class PciDeviceNotFoundError(Exception):
- def __init__(self,domain,bus,slot,func):
- self.domain = domain
- self.bus = bus
- self.slot = slot
- self.func = func
- self.name = PCI_DEV_FORMAT_STR %(domain, bus, slot, func)
-
- def __str__(self):
- return (''PCI Device %s Not Found'' % (self.name))
-
class PciDeviceParseError(Exception):
def __init__(self,msg):
self.message = msg
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 07/16] xend: pass-through: Use PCIDevice as the parameter for the constructor for PCIQuirk
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-05
16:19:26.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-07
21:49:07.000000000 +1000
@@ -301,8 +301,7 @@ class PciController(DevController):
# if arch.type != "ia64":
# dev.do_FLR()
- PCIQuirk(dev.vendor, dev.device, dev.subvendor, dev.subdevice, domain,
- bus, slot, func)
+ PCIQuirk(dev)
if not self.vm.info.is_hvm():
# Setup IOMMU device assignment
Index: xen-unstable.hg/tools/python/xen/xend/server/pciquirk.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciquirk.py 2009-06-05
16:19:20.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciquirk.py 2009-06-05
17:01:20.000000000 +1000
@@ -11,18 +11,19 @@ PERMISSIVE_CONFIG_FILE = auxbin.xen_conf
PERMISSIVE_SYSFS_NODE = "/sys/bus/pci/drivers/pciback/permissive"
class PCIQuirk:
- def __init__( self, vendor, device, subvendor, subdevice, domain, bus,
slot, func):
- self.vendor = vendor
- self.device = device
- self.subvendor = subvendor
- self.subdevice = subdevice
- self.domain = domain
- self.bus = bus
- self.slot = slot
- self.func = func
-
- self.devid = "%04x:%04x:%04x:%04x" % (vendor, device,
subvendor, subdevice)
- self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot,
func)
+ def __init__(self, dev):
+ self.vendor = dev.vendor
+ self.device = dev.device
+ self.subvendor = dev.subvendor
+ self.subdevice = dev.subdevice
+ self.domain = dev.domain
+ self.bus = dev.bus
+ self.slot = dev.slot
+ self.func = dev.func
+
+ self.devid = "%04x:%04x:%04x:%04x" % (self.vendor,
self.device,
+ self.subvendor, self.subdevice)
+ self.pciid = dev.name
self.quirks = self.__getQuirksByID()
self.__sendQuirks()
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 08/16] xend: pass-through: Common parse_pci_name()
Share some parsing code between different parts of xm.
This has the side-effect that the device specification for
hot-plug may now include the VSLOT and OPTS as per device
specifictions in the domain configuration file.
SEQ:BUS:DEV.FUNC[,OPT...]
e.g. 0000:00:01.00@6
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Wed, 20 May 2009 23:07:42 +1000
* Fix syntax errors in parse_pci_name() and parse_pci_name_bdf6()
- unnoticed as they were resolved by the subsequent patch
"xm: Allow multi-function device specifications to be parsed
* Enhanced error reporting in parse_pci_name()
* Have parse_pci_name_bdf6() return an int rather than a string for vslot in
keeping with the other integer elements of the bdf6 tuple
Fri, 22 May 2009 15:52:50 +1000
* Consolidate get_all_pci_bdf6() and get_all_pci_devices()
Thu, 28 May 2009 23:56:14 +1000
* Up-port
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 11:22:35.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-15 11:23:43.000000000
+1000
@@ -15,6 +15,7 @@ import time
import threading
from xen.util import utils
from xen.xend import sxp
+from xen.xend.XendConstants import AUTO_PHP_SLOT
PROC_PCI_PATH = ''/proc/bus/pci/devices''
PROC_PCI_NUM_RESOURCES = 7
@@ -35,7 +36,6 @@ LSPCI_CMD = ''lspci''
PCI_DEV_REG_EXPRESS_STR =
r"[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}."+ \
r"[0-9a-fA-F]{1}"
-PCI_DEV_FORMAT_STR = ''%04x:%02x:%02x.%01x''
DEV_TYPE_PCIe_ENDPOINT = 0
DEV_TYPE_PCIe_BRIDGE = 1
@@ -148,22 +148,62 @@ def parse_hex(val):
except ValueError:
return None
+def parse_pci_name_extended(pci_dev_str):
+ 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-7]))" +
+ r"(@(?P<vslot>[01]?[0-9a-fA-F]))?" +
+ r"(,(?P<opts>.*))?$", pci_dev_str)
+
+ if pci_match == None:
+ raise PciDeviceParseError("Failed to parse pci device: %s" %
+ pci_dev_str)
+
+ out = {}
+ pci_dev_info = pci_match.groupdict('''')
+ if pci_dev_info[''domain''] == '''':
+ domain = 0
+ else:
+ domain = int(pci_dev_info[''domain''], 16)
+ out[''domain''] = "0x%04x" % domain
+ out[''bus''] = "0x%02x" %
int(pci_dev_info[''bus''], 16)
+ out[''slot''] = "0x%02x" %
int(pci_dev_info[''slot''], 16)
+ out[''func''] = "0x%x" %
int(pci_dev_info[''func''], 16)
+ if pci_dev_info[''vslot''] == '''':
+ vslot = AUTO_PHP_SLOT
+ else:
+ vslot = int(pci_dev_info[''vslot''], 16)
+ out[''vslot''] = "0x%02x" % vslot
+ if pci_dev_info[''opts''] != '''':
+ out[''opts''] =
split_pci_opts(pci_dev_info[''opts''])
+ check_pci_opts(out[''opts''])
+
+ return out
+
def parse_pci_name(pci_name_string):
- 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-7])$", pci_name_string)
- if pci_match is None:
- raise PciDeviceParseError((''Failed to parse pci device name:
%s'' %
- pci_name_string))
- pci_dev_info = pci_match.groupdict(''0'')
-
- domain = parse_hex(pci_dev_info[''domain''])
- bus = parse_hex(pci_dev_info[''bus''])
- slot = parse_hex(pci_dev_info[''slot''])
- func = parse_hex(pci_dev_info[''func''])
+ pci = parse_pci_name_extended(pci_name_string)
+
+ if int(pci[''vslot''], 16) != AUTO_PHP_SLOT:
+ raise PciDeviceParseError(("Failed to parse pci device: %s: "
+
+ "vslot provided where prohibited:
%s") %
+ (pci_name_string,
pci[''vslot'']))
+ if ''opts'' in pci:
+ raise PciDeviceParseError(("Failed to parse pci device: %s: "
+
+ "options provided where prohibited:
%s") %
+ (pci_name_string,
pci[''opts'']))
+
+ return pci
+
+def __pci_dict_to_fmt_str(fmt, dev):
+ return fmt % (int(dev[''domain''], 16),
int(dev[''bus''], 16),
+ int(dev[''slot''], 16),
int(dev[''func''], 16))
- return (domain, bus, slot, func)
+def pci_dict_to_bdf_str(dev):
+ return __pci_dict_to_fmt_str(''%04x:%02x:%02x.%01x'', dev)
+
+def pci_dict_to_xc_str(dev):
+ return __pci_dict_to_fmt_str(''0x%x, 0x%x, 0x%x, 0x%x'',
dev)
def extract_the_exact_pci_names(pci_names):
result = []
@@ -198,27 +238,7 @@ def get_all_pci_names():
return pci_names
def get_all_pci_devices():
- pci_devs = []
- for pci_name in get_all_pci_names():
- 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-7])$", pci_name)
- if pci_match is None:
- raise PciDeviceParseError((''Failed to parse pci device
name: %s'' %
- pci_name))
- pci_dev_info = pci_match.groupdict(''0'')
- domain = parse_hex(pci_dev_info[''domain''])
- bus = parse_hex(pci_dev_info[''bus''])
- slot = parse_hex(pci_dev_info[''slot''])
- func = parse_hex(pci_dev_info[''func''])
- try:
- pci_dev = PciDevice(domain, bus, slot, func)
- except:
- continue
- pci_devs.append(pci_dev)
-
- return pci_devs
+ return map(PciDevice, map(parse_pci_name, get_all_pci_names()))
def _create_lspci_info():
"""Execute ''lspci'' command and parse the
result.
@@ -237,7 +257,7 @@ def _create_lspci_info():
try:
(opt, value) = line.split('':\t'')
if opt == ''Slot'':
- device_name = PCI_DEV_FORMAT_STR % parse_pci_name(value)
+ device_name = pci_dict_to_bdf_str(parse_pci_name(value))
else:
device_info[opt] = value
except:
@@ -287,8 +307,7 @@ def find_all_devices_owned_by_pciback():
pci_list = extract_the_exact_pci_names(pci_names)
dev_list = []
for pci in pci_list:
- (dom, b, d, f) = parse_pci_name(pci)
- dev = PciDevice(dom, b, d, f)
+ dev = PciDevice(parse_pci_name(pci))
dev_list = dev_list + [dev]
return dev_list
@@ -395,12 +414,12 @@ class PciDeviceVslotMissing(Exception):
return ''pci: no vslot: '' + self.message
class PciDevice:
- def __init__(self, domain, bus, slot, func):
- self.domain = domain
- self.bus = bus
- self.slot = slot
- self.func = func
- self.name = PCI_DEV_FORMAT_STR % (domain, bus, slot, func)
+ def __init__(self, dev):
+ self.domain = int(dev[''domain''], 16)
+ self.bus = int(dev[''bus''], 16)
+ self.slot = int(dev[''slot''], 16)
+ self.func = int(dev[''func''], 16)
+ self.name = pci_dict_to_bdf_str(dev)
self.cfg_space_path =
find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+''/''+ \
self.name + SYSFS_PCI_DEV_CONFIG_PATH
self.irq = 0
@@ -442,14 +461,15 @@ class PciDevice:
# We have reached the upmost one.
return None
else:
+ dev = {}
lst = parent.split('':'')
- dom = int(lst[0], 16)
- bus = int(lst[1], 16)
+ dev[''dom''] = int(lst[0], 16)
+ dev[''bus''] = int(lst[1], 16)
lst = lst[2]
lst = lst.split(''.'')
- dev = int(lst[0], 16)
- func = int(lst[1], 16)
- return (dom, bus, dev, func)
+ dev[''slot''] = int(lst[0], 16)
+ dev[''func''] = int(lst[1], 16)
+ return dev
except OSError, (errno, strerr):
raise PciDeviceParseError(''Can not locate the parent of
%s'',
self.name)
@@ -459,15 +479,13 @@ class PciDevice:
dev = self.find_parent()
if dev is None:
return None
- (dom, b, d, f) = dev
- dev = dev_parent = PciDevice(dom, b, d, f)
+ dev = dev_parent = PciDevice(dev)
while dev_parent.dev_type != DEV_TYPE_PCIe_BRIDGE:
parent = dev_parent.find_parent()
if parent is None:
break
- (dom, b, d, f) = parent
dev = dev_parent
- dev_parent = PciDevice(dom, b, d, f)
+ dev_parent = PciDevice(parent)
return dev
def find_all_devices_behind_the_bridge(self, ignore_bridge):
@@ -478,8 +496,7 @@ class PciDevice:
list = [self.name]
for pci_str in dev_list:
- (dom, b, d, f) = parse_pci_name(pci_str)
- dev = PciDevice(dom, b, d, f)
+ dev = PciDevice(parse_pci_name(pci_str))
if dev.dev_type == DEV_TYPE_PCI_BRIDGE or \
dev.dev_type == DEV_TYPE_PCIe_BRIDGE:
sub_list_including_self = \
@@ -595,7 +612,7 @@ class PciDevice:
def find_all_the_multi_functions(self):
sysfs_mnt = find_sysfs_mnt()
- parent = PCI_DEV_FORMAT_STR % self.find_parent()
+ parent = pci_dict_to_bdf_str(self.find_parent())
pci_names = os.popen(''ls '' + sysfs_mnt +
SYSFS_PCI_DEVS_PATH + ''/'' + \
parent + ''/'').read()
funcs = extract_the_exact_pci_names(pci_names)
@@ -753,8 +770,7 @@ class PciDevice:
if len(devs) == 0:
return
for pci_dev in devs:
- (dom, b, d, f) = parse_pci_name(pci_dev)
- dev = PciDevice(dom, b, d, f)
+ dev = PciDevice(parse_pci_name(pci_dev))
if dev.driver == ''pciback'':
continue
err_msg = ''pci: %s must be co-assigned to the same guest
with %s'' + \
@@ -780,7 +796,7 @@ class PciDevice:
funcs = self.find_all_the_multi_functions()
self.devs_check_driver(funcs)
- parent = ''%04x:%02x:%02x.%01x'' %
self.find_parent()
+ parent = pci_dict_to_bdf_str(self.find_parent())
# Do Secondary Bus Reset.
self.do_secondary_bus_reset(parent, funcs)
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
11:22:35.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
11:23:43.000000000 +1000
@@ -39,7 +39,8 @@ from xen.util import asserts, auxbin
from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
import xen.util.xsm.xsm as security
from xen.util import xsconstants
-from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp
+from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
+ pci_dict_to_bdf_str, pci_dict_to_xc_str
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendOptions, XendNode, XendConfig
@@ -310,9 +311,8 @@ def do_FLR(domid):
dev_str_list = get_assigned_pci_devices(domid)
for dev_str in dev_str_list:
- (dom, b, d, f) = parse_pci_name(dev_str)
try:
- dev = PciDevice(dom, b, d, f)
+ dev = PciDevice(parse_pci_name(dev_str))
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -652,23 +652,15 @@ class XendDomainInfo:
raise VmError("device is already inserted")
# Test whether the devices can be assigned with VT-d
- pci_str = "%s, %s, %s, %s" %
(new_dev[''domain''],
- new_dev[''bus''],
- new_dev[''slot''],
- new_dev[''func''])
- bdf = xc.test_assign_device(0, pci_str)
+ 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?")
- bus = (bdf >> 16) & 0xff
- 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("fail to assign device(%s): maybe it has"
" already been assigned to other domain, or
maybe"
- " it doesn''t exist." % (bus, dev,
func))
+ " it doesn''t exist." %
pci_dict_to_bdf_str(new_dev))
# 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
@@ -680,12 +672,8 @@ class XendDomainInfo:
# Test whether the device is owned by pciback. For instance, we
can''t
# hotplug a device being used by Dom0 itself to an HVM guest.
from xen.xend.server.pciif import PciDevice, parse_pci_name
- domain = int(new_dev[''domain''],16)
- bus = int(new_dev[''bus''],16)
- dev = int(new_dev[''slot''],16)
- func = int(new_dev[''func''],16)
try:
- pci_device = PciDevice(domain, bus, dev, func)
+ pci_device = PciDevice(new_dev)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -710,9 +698,8 @@ 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:
- (domain, bus, dev, func) = parse_pci_name(pci_str)
- dev_str = ''0x%x,0x%x,0x%x,0x%x'' % (domain, bus,
dev, func)
- if xc.test_assign_device(0, dev_str) == 0:
+ pci_dev = parse_pci_name(pci_str)
+ if xc.test_assign_device(0, pci_dict_to_xc_str(pci_dev)) == 0:
continue
if not pci_str in assigned_pci_device_str_list:
raise VmError(("pci: failed to pci-attach %s to domain
%s" + \
@@ -742,12 +729,9 @@ class XendDomainInfo:
if new_dev.has_key(''opts''):
opts = '','' +
serialise_pci_opts(new_dev[''opts''])
- bdf_str = "%s:%s:%s.%s@%s%s" %
(new_dev[''domain''],
- new_dev[''bus''],
- new_dev[''slot''],
- new_dev[''func''],
- new_dev[''vslot''],
- opts)
+ bdf_str = "%s@%02x%s" % (pci_dict_to_bdf_str(new_dev),
+ int(new_dev[''vslot''],
16), opts)
+ log.debug("XendDomainInfo.hvm_pci_device_insert_dev: %s"
% bdf_str)
self.image.signalDeviceModel(''pci-ins'',
''pci-inserted'', bdf_str)
vslot =
xstransact.Read("/local/domain/0/device-model/%i/parameter"
@@ -864,9 +848,8 @@ class XendDomainInfo:
vslot = x[''vslot'']
break
if vslot == "":
- raise VmError("Device %04x:%02x:%02x.%01x is not
connected"
- % (int(dev[''domain''],16),
int(dev[''bus''],16),
- int(dev[''slot''],16),
int(dev[''func''],16)))
+ raise VmError("Device %s is not connected" %
+ pci_dict_to_bdf_str(dev))
self.hvm_destroyPCIDevice(int(vslot, 16))
# Update vslot
dev[''vslot''] = vslot
@@ -1152,12 +1135,8 @@ class XendDomainInfo:
# list of D''s co-assignment devices, DD is not assigned (to
domN).
#
from xen.xend.server.pciif import PciDevice
- domain = int(x[''domain''],16)
- bus = int(x[''bus''],16)
- dev = int(x[''slot''],16)
- func = int(x[''func''],16)
try:
- pci_device = PciDevice(domain, bus, dev, func)
+ pci_device = PciDevice(x)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -1172,9 +1151,8 @@ class XendDomainInfo:
)% (pci_device.name,
self.info[''name_label''], pci_str))
- bdf_str = "%s:%s:%s.%s" % (x[''domain''],
x[''bus''], x[''slot''],
x[''func''])
+ bdf_str = pci_dict_to_bdf_str(x)
log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str)
-
if self.domid is not None:
self.image.signalDeviceModel(''pci-rem'',
''pci-removed'', bdf_str)
@@ -1338,21 +1316,12 @@ class XendDomainInfo:
if self.domid is not None:
return get_assigned_pci_devices(self.domid)
- dev_str_list = []
dev_info = self._getDeviceInfo_pci(devid)
if dev_info is None:
- return dev_str_list
+ return []
dev_uuid = sxp.child_value(dev_info, ''uuid'')
pci_conf = self.info[''devices''][dev_uuid][1]
- pci_devs = pci_conf[''devs'']
- for pci_dev in pci_devs:
- domain = int(pci_dev[''domain''], 16)
- bus = int(pci_dev[''bus''], 16)
- slot = int(pci_dev[''slot''], 16)
- func = int(pci_dev[''func''], 16)
- dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot,
func)
- dev_str_list = dev_str_list + [dev_str]
- return dev_str_list
+ return map(pci_dict_to_bdf_str, pci_conf[''devs''])
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@@ -3909,12 +3878,12 @@ class XendDomainInfo:
target_dev = None
new_pci_sxp = [''pci'']
for dev in sxp.children(old_pci_sxp, ''dev''):
- domain = int(sxp.child_value(dev, ''domain''), 16)
- bus = int(sxp.child_value(dev, ''bus''), 16)
- slot = int(sxp.child_value(dev, ''slot''), 16)
- func = int(sxp.child_value(dev, ''func''), 16)
- name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
- if ppci.get_name() == name:
+ pci_dev = {}
+ pci_dev[''domain''] = sxp.child_value(dev,
''domain'')
+ pci_dev[''bus''] = sxp.child_value(dev,
''bus'')
+ pci_dev[''slot''] = sxp.child_value(dev,
''slot'')
+ pci_dev[''func''] = sxp.child_value(dev,
''func'')
+ if ppci.get_name() == pci_dict_to_bdf_str(pci_dev):
target_dev = dev
else:
new_pci_sxp.append(dev)
Index: xen-unstable.hg/tools/python/xen/xend/XendNode.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendNode.py 2009-06-15
11:20:35.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendNode.py 2009-06-15
11:23:43.000000000 +1000
@@ -340,8 +340,7 @@ class XendNode:
except KeyError:
pass
- (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name)
- pci_dev = PciUtil.PciDevice(domain, bus, slot, func)
+ pci_dev = PciUtil.PciDevice(PciUtil.parse_pci_name(pci_name))
ppci_record = {
''domain'': pci_dev.domain,
''bus'': pci_dev.bus,
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-15
11:22:35.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-15
11:23:43.000000000 +1000
@@ -130,13 +130,7 @@ class PciController(DevController):
log.debug(''Reconfiguring PCI device %s.''
% dev)
attaching = False
- (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)
- self.setupOneDevice(domain, bus, slot, func)
+ self.setupOneDevice(parse_pci_name(dev))
self.writeBackend(devid, ''dev-%i'' % devno,
dev)
self.writeBackend(devid, ''state-%i'' % devno,
@@ -248,15 +242,13 @@ class PciController(DevController):
return
#group string format xx:xx.x,xx:xx.x,
- devstr_len = group_str.find('','')
- for i in range(0, len(group_str), devstr_len + 1):
- (bus, slotfunc) = group_str[i:i +
devstr_len].split('':'')
- (slot, func) = slotfunc.split(''.'')
- b = parse_hex(bus)
- d = parse_hex(slot)
- f = parse_hex(func)
+ for i in group_str.split('',''):
+ if i == '''':
+ continue
+ pci_dev = parse_pci_name(i)
+ pci_dev[''domain''] = ''%04x'' %
dev.domain
try:
- sdev = PciDevice(dev.domain, b, d, f)
+ sdev = PciDevice(pci_dev)
except Exception, e:
#no dom0 drivers bound to sdev
continue
@@ -270,13 +262,13 @@ class PciController(DevController):
)%(sdev.name, dev.name))
return
- def setupOneDevice(self, domain, bus, slot, func):
+ def setupOneDevice(self, pci_dev):
""" Attach I/O resources for device to frontend domain
"""
fe_domid = self.getDomid()
try:
- dev = PciDevice(domain, bus, slot, func)
+ dev = PciDevice(pci_dev)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -305,12 +297,11 @@ class PciController(DevController):
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)
+ 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
(%x:%x.%x)"
- % (bus, slot, func))
- log.debug("pci: assign device %x:%x.%x" % (bus, slot,
func))
+ 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))
@@ -366,23 +357,15 @@ class PciController(DevController):
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)]
+ pci_dev_list = config.get(''devs'', [])
+ pci_str_list = map(pci_dict_to_bdf_str, pci_dev_list)
if len(pci_str_list) != len(set(pci_str_list)):
raise VmError(''pci: duplicate devices specified in guest
config?'')
- for (domain, bus, slot, func) in pci_dev_list:
+ for pci_dev in pci_dev_list:
try:
- dev = PciDevice(domain, bus, slot, func)
+ dev = PciDevice(pci_dev)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -427,9 +410,7 @@ class PciController(DevController):
dev.devs_check_driver(devs_str)
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_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:
err_msg = ''pci: %s must be co-assigned
to the''+\
@@ -453,13 +434,13 @@ class PciController(DevController):
return True
- def cleanupOneDevice(self, domain, bus, slot, func):
+ def cleanupOneDevice(self, pci_dev):
""" Detach I/O resources for device from frontend domain
"""
fe_domid = self.getDomid()
try:
- dev = PciDevice(domain, bus, slot, func)
+ dev = PciDevice(pci_dev)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -476,12 +457,11 @@ class PciController(DevController):
# DMA transaction, etc
dev.do_FLR()
- pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot,
func)
- bdf = xc.deassign_device(fe_domid, pci_str)
+ bdf = xc.deassign_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 deassign device from IOMMU
(%x:%x.%x)"
- % (bus, slot, func))
- log.debug("pci: Deassign device %x:%x.%x" % (bus, slot,
func))
+ raise VmError("Failed to deassign device from IOMMU (%s)"
% pci_str)
+ log.debug("pci: Deassign device %s" % pci_str)
for (start, size) in dev.ioports:
log.debug(''pci: disabling ioport
0x%x/0x%x''%(start,size))
@@ -530,15 +510,9 @@ class PciController(DevController):
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)
+ pci_dev = parse_pci_name(self.readBackend(devid,
''dev-%i'' % i))
# In HVM case, I/O resources are disabled in ioemu.
- self.cleanupOneDevice(domain, bus, slot, func)
+ self.cleanupOneDevice(pci_dev)
# Remove xenstore nodes.
list = [''dev'', ''vdev'',
''state'', ''uuid'', ''vslot'']
if self.readBackend(devid, ''opts-%i'' % i) is
not None:
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 09/16] xend: pass-through: Use common parsing code in preprocess_pci()
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xm/create.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xm/create.py 2009-06-13 11:03:40.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/xm/create.py 2009-06-13 11:09:37.000000000
+1000
@@ -38,8 +38,8 @@ from xen.util import vscsi_util
import xen.util.xsm.xsm as security
from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
from xen.util import utils, auxbin
-from xen.util.pci import split_pci_opts, check_pci_opts, \
- pci_opts_list_to_sxp
+from xen.util.pci import pci_opts_list_to_sxp, \
+ parse_pci_name_extended, PciDeviceParseError
from xen.xm.opts import *
@@ -710,14 +710,7 @@ def configure_pci(config_devs, vals):
config_pci_bdf = [''dev'', [''domain'',
domain], [''bus'', bus], \
[''slot'', slot],
[''func'', func],
[''vslot'', vslot]]
-
- opts_list = split_pci_opts(opts)
- try:
- check_pci_opts(opts_list)
- except PciDeviceParseError, ex:
- err(str(ex))
-
- config_opts = pci_opts_list_to_sxp(split_pci_opts(opts))
+ config_opts = pci_opts_list_to_sxp(opts)
config_pci.append(sxp.merge(config_pci_bdf, config_opts))
if len(config_pci)>0:
@@ -1052,33 +1045,18 @@ def preprocess_cpuid(vals, attr_name):
cpuid[input][res[''reg'']] =
res[''val''] # new register
setattr(vals, attr_name, cpuid)
+def pci_dict_to_tuple(dev):
+ return (dev[''domain''], dev[''bus''],
dev[''slot''], dev[''func''],
+ dev[''vslot''], dev.get(''opts'',
[]))
+
def preprocess_pci(vals):
- if not vals.pci: return
- pci = []
- for pci_dev_str in vals.pci:
- 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-7])" + \
- r"(@(?P<vslot>[01]?[0-9a-fA-F]))?" + \
- r"(,(?P<opts>.*))?$", \
- pci_dev_str)
- if pci_match!=None:
- pci_dev_info = pci_match.groupdict('''')
- if pci_dev_info[''domain'']=='''':
- pci_dev_info[''domain'']=''0''
- if pci_dev_info[''vslot'']=='''':
- pci_dev_info[''vslot'']="%02x" %
AUTO_PHP_SLOT
- try:
- pci.append(
(''0x''+pci_dev_info[''domain''], \
-
''0x''+pci_dev_info[''bus''], \
-
''0x''+pci_dev_info[''slot''], \
-
''0x''+pci_dev_info[''func''], \
-
''0x''+pci_dev_info[''vslot''], \
- pci_dev_info[''opts'']))
- except IndexError:
- err(''Error in PCI slot syntax
"%s"''%(pci_dev_str))
- vals.pci = pci
+ if not vals.pci:
+ return
+ try:
+ vals.pci = map(pci_dict_to_tuple,
+ map(parse_pci_name_extended, vals.pci))
+ except PciDeviceParseError, ex:
+ err(str(ex))
def preprocess_vscsi(vals):
if not vals.vscsi: return
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 10/16] xend: pass-through: Add pci_dict_cmp()
pci_dict_cmp() compares the two pci devices in dict format.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 11:24:32.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-15 11:24:34.000000000
+1000
@@ -205,6 +205,10 @@ def pci_dict_to_bdf_str(dev):
def pci_dict_to_xc_str(dev):
return __pci_dict_to_fmt_str(''0x%x, 0x%x, 0x%x, 0x%x'',
dev)
+def pci_dict_cmp(a, b, keys=[''domain'',
''bus'', ''slot'', ''func'']):
+ return reduce(lambda x, y: x and y,
+ map(lambda k: int(a[k], 16) == int(b[k], 16), keys))
+
def extract_the_exact_pci_names(pci_names):
result = []
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
11:24:32.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
11:24:34.000000000 +1000
@@ -40,7 +40,7 @@ from xen.util.blkif import blkdev_uname_
import xen.util.xsm.xsm as security
from xen.util import xsconstants
from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
- pci_dict_to_bdf_str, pci_dict_to_xc_str
+ pci_dict_to_bdf_str, pci_dict_to_xc_str, pci_dict_cmp
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendOptions, XendNode, XendConfig
@@ -645,10 +645,7 @@ class XendDomainInfo:
int(x[''vslot''], 16) != AUTO_PHP_SLOT):
raise VmError("vslot %s already have a device." %
(new_dev[''vslot'']))
- if (int(x[''domain''], 16) ==
int(new_dev[''domain''], 16) and
- int(x[''bus''], 16) ==
int(new_dev[''bus''], 16) and
- int(x[''slot''], 16) ==
int(new_dev[''slot''], 16) and
- int(x[''func''], 16) ==
int(new_dev[''func''], 16) ):
+ if (pci_dict_cmp(x, new_dev)):
raise VmError("device is already inserted")
# Test whether the devices can be assigned with VT-d
@@ -839,23 +836,18 @@ class XendDomainInfo:
existing_dev_uuid = sxp.child_value(existing_dev_info,
''uuid'')
existing_pci_conf =
self.info[''devices''][existing_dev_uuid][1]
existing_pci_devs = existing_pci_conf[''devs'']
- vslot = ""
- for x in existing_pci_devs:
- if ( int(x[''domain''], 16) ==
int(dev[''domain''], 16) and
- int(x[''bus''], 16) ==
int(dev[''bus''], 16) and
- int(x[''slot''], 16) ==
int(dev[''slot''], 16) and
- int(x[''func''], 16) ==
int(dev[''func''], 16) ):
- vslot = x[''vslot'']
- break
- if vslot == "":
+ new_devs = filter(lambda x: pci_dict_cmp(x, dev),
+ existing_pci_devs)
+ if len(new_devs) < 0:
raise VmError("Device %s is not connected" %
pci_dict_to_bdf_str(dev))
- self.hvm_destroyPCIDevice(int(vslot, 16))
+ new_dev = new_devs[0]
+
self.hvm_destroyPCIDevice(int(new_dev[''vslot''], 16))
# Update vslot
- dev[''vslot''] = vslot
+ dev[''vslot''] =
new_dev[''vslot'']
for n in sxp.children(pci_dev):
if(n[0] == ''vslot''):
- n[1] = vslot
+ n[1] = new_dev[''vslot'']
# If pci platform does not exist, create and exit.
if existing_dev_info is None:
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 11/16] xend: pass-through: Move pci conversion functions to pci.py
Move dev_dict_to_sxp(), pci_convert_dict_to_sxp() and
pci_convert_sxp_to_dict() to pci.py, where other similar functions live.
This makes them accessible outside of the XendConfig class.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
tools/python/xen/util/pci.py | 83 ++++++++++++++++++++++++++++
tools/python/xen/xend/XendConfig.py | 91 +------------------------------
tools/python/xen/xend/XendDomainInfo.py | 10 ++-
3 files changed, 94 insertions(+), 90 deletions(-)
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-13 21:39:44.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-13 21:39:56.000000000
+1000
@@ -14,6 +14,7 @@ import struct
import time
import threading
from xen.util import utils
+from xen.xend import uuid
from xen.xend import sxp
from xen.xend.XendConstants import AUTO_PHP_SLOT
@@ -139,6 +140,88 @@ def pci_opts_list_to_sxp(list):
def pci_opts_list_from_sxp(dev):
return map(lambda x: sxp.children(x)[0], sxp.children(dev,
''opts''))
+# This includes a generic equivalent of pci_opts_list_to_sxp()
+def dev_dict_to_sxp(dev):
+ def f((key, val)):
+ if isinstance(val, types.ListType):
+ return map(lambda x: [key, x], val)
+ return [[key, val]]
+ dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
+ return dev_sxp
+
+def pci_convert_dict_to_sxp(dev, state, sub_state = None):
+ pci_sxp = [''pci'', dev_dict_to_sxp(dev),
[''state'', state]]
+ if sub_state != None:
+ pci_sxp.append([''sub_state'', sub_state])
+ return pci_sxp
+
+def pci_convert_sxp_to_dict(dev_sxp):
+ """Convert pci device sxp to dict
+ @param dev_sxp: device configuration
+ @type dev_sxp: SXP object (parsed config)
+ @return: dev_config
+ @rtype: dictionary
+ """
+ # Parsing the device SXP''s. In most cases, the SXP looks
+ # like this:
+ #
+ # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
+ #
+ # However, for PCI devices it looks like this:
+ #
+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
+ #
+ # It seems the reasoning for this difference is because
+ # pciif.py needs all the PCI device configurations at
+ # the same time when creating the devices.
+ #
+ # To further complicate matters, Xen 2.0 configuration format
+ # uses the following for pci device configuration:
+ #
+ # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
+
+ # For PCI device hotplug support, the SXP of PCI devices is
+ # extendend like this:
+ #
+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
+ # [vslot, 0]],
+ # [state, ''Initialising'']]]
+ #
+ # ''vslot'' shows the virtual hotplug slot number which the
PCI device
+ # is inserted in. This is only effective for HVM domains.
+ #
+ # state ''Initialising'' indicates that the device is being
attached,
+ # while state ''Closing'' indicates that the device is
being detached.
+ #
+ # The Dict looks like this:
+ #
+ # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
+ # states: [''Initialising''] }
+
+ dev_config = {}
+
+ pci_devs = []
+ for pci_dev in sxp.children(dev_sxp, ''dev''):
+ pci_dev_info = dict(pci_dev[1:])
+ if ''opts'' in pci_dev_info:
+ pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
+ # append uuid to each pci device that does''t already have one.
+ if not pci_dev_info.has_key(''uuid''):
+ dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
+ pci_dev_info[''uuid''] = dpci_uuid
+ pci_devs.append(pci_dev_info)
+ dev_config[''devs''] = pci_devs
+
+ pci_states = []
+ for pci_state in sxp.children(dev_sxp, ''state''):
+ try:
+ pci_states.append(pci_state[1])
+ except IndexError:
+ raise XendError("Error reading state while parsing pci
sxp")
+ dev_config[''states''] = pci_states
+
+ return dev_config
+
def parse_hex(val):
try:
if isinstance(val, types.StringTypes):
Index: xen-unstable.hg/tools/python/xen/xend/XendConfig.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendConfig.py 2009-06-13
21:39:44.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendConfig.py 2009-06-13
21:39:56.000000000 +1000
@@ -36,7 +36,8 @@ from xen.xend.xenstore.xstransact import
from xen.xend.server.BlktapController import blktap_disk_types
from xen.xend.server.netif import randomMAC
from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
-from xen.util.pci import pci_opts_list_from_sxp
+from xen.util.pci import pci_opts_list_from_sxp, dev_dict_to_sxp, \
+ pci_convert_sxp_to_dict
from xen.util import xsconstants
import xen.util.auxbin
@@ -1296,7 +1297,7 @@ class XendConfig(dict):
pci_devs_uuid = sxp.child_value(config,
''uuid'',
uuid.createString())
- pci_dict = self.pci_convert_sxp_to_dict(config)
+ pci_dict = pci_convert_sxp_to_dict(config)
pci_devs = pci_dict[''devs'']
# create XenAPI DPCI objects.
@@ -1596,79 +1597,6 @@ class XendConfig(dict):
return ''''
- def pci_convert_dict_to_sxp(self, dev, state, sub_state = None):
- pci_sxp = [''pci'', self.dev_dict_to_sxp(dev),
[''state'', state]]
- if sub_state != None:
- pci_sxp.append([''sub_state'', sub_state])
- return pci_sxp
-
- def pci_convert_sxp_to_dict(self, dev_sxp):
- """Convert pci device sxp to dict
- @param dev_sxp: device configuration
- @type dev_sxp: SXP object (parsed config)
- @return: dev_config
- @rtype: dictionary
- """
- # Parsing the device SXP''s. In most cases, the SXP looks
- # like this:
- #
- # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
- #
- # However, for PCI devices it looks like this:
- #
- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
- #
- # It seems the reasoning for this difference is because
- # pciif.py needs all the PCI device configurations at
- # the same time when creating the devices.
- #
- # To further complicate matters, Xen 2.0 configuration format
- # uses the following for pci device configuration:
- #
- # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
-
- # For PCI device hotplug support, the SXP of PCI devices is
- # extendend like this:
- #
- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
- # [vslot, 0]],
- # [state, ''Initialising'']]]
- #
- # ''vslot'' shows the virtual hotplug slot number which
the PCI device
- # is inserted in. This is only effective for HVM domains.
- #
- # state ''Initialising'' indicates that the device is
being attached,
- # while state ''Closing'' indicates that the device is
being detached.
- #
- # The Dict looks like this:
- #
- # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
- # states: [''Initialising''] }
-
- dev_config = {}
-
- pci_devs = []
- for pci_dev in sxp.children(dev_sxp, ''dev''):
- pci_dev_info = dict(pci_dev[1:])
- if ''opts'' in pci_dev_info:
- pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
- # append uuid to each pci device that does''t already have
one.
- if not pci_dev_info.has_key(''uuid''):
- dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
- pci_dev_info[''uuid''] = dpci_uuid
- pci_devs.append(pci_dev_info)
- dev_config[''devs''] = pci_devs
-
- pci_states = []
- for pci_state in sxp.children(dev_sxp, ''state''):
- try:
- pci_states.append(pci_state[1])
- except IndexError:
- raise XendError("Error reading state while parsing pci
sxp")
- dev_config[''states''] = pci_states
-
- return dev_config
-
def vscsi_convert_sxp_to_dict(self, dev_sxp):
"""Convert vscsi device sxp to dict
@param dev_sxp: device configuration
@@ -1839,7 +1767,7 @@ class XendConfig(dict):
dev_type, dev_info = self[''devices''][dev_uuid]
if dev_type == ''pci'': # Special case for pci
- pci_dict = self.pci_convert_sxp_to_dict(config)
+ pci_dict = pci_convert_sxp_to_dict(config)
pci_devs = pci_dict[''devs'']
# destroy existing XenAPI DPCI objects
@@ -1962,15 +1890,6 @@ class XendConfig(dict):
result.extend([u for u in target[''devices''].keys() if
u not in result])
return result
- # This includes a generic equivalent of pci_opts_list_to_sxp()
- def dev_dict_to_sxp(self, dev):
- def f((key, val)):
- if isinstance(val, types.ListType):
- return map(lambda x: [key, x], val)
- return [[key, val]]
- dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
- return dev_sxp
-
def all_devices_sxpr(self, target = None):
"""Returns the SXPR for all devices in the current
configuration."""
sxprs = []
@@ -1993,7 +1912,7 @@ class XendConfig(dict):
if dev_info.has_key(''backend''):
sxpr.append([''backend'',
dev_info[''backend'']])
for pci_dev_info in dev_info[''devs'']:
- sxpr.append(self.dev_dict_to_sxp(pci_dev_info))
+ sxpr.append(dev_dict_to_sxp(pci_dev_info))
sxprs.append((dev_type, sxpr))
else:
sxpr = self.device_sxpr(dev_type = dev_type,
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-13
21:39:44.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-13
21:40:34.000000000 +1000
@@ -40,7 +40,9 @@ from xen.util.blkif import blkdev_uname_
import xen.util.xsm.xsm as security
from xen.util import xsconstants
from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
- pci_dict_to_bdf_str, pci_dict_to_xc_str, pci_dict_cmp
+ pci_dict_to_bdf_str, pci_dict_to_xc_str, \
+ pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \
+ pci_dict_cmp
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendOptions, XendNode, XendConfig
@@ -616,8 +618,8 @@ class XendDomainInfo:
pci_conf = self.info[''devices''][dev_uuid][1]
pci_devs = pci_conf[''devs'']
request = map(lambda x:
- self.info.pci_convert_dict_to_sxp(x,
''Initialising'',
-
''Booting''), pci_devs)
+ pci_convert_dict_to_sxp(x,
''Initialising'', ''Booting''),
+ pci_devs)
for i in request:
self.pci_device_configure(i)
@@ -815,7 +817,7 @@ class XendDomainInfo:
raise XendError("Cannot detach when pci platform does not
exist")
pci_dev = sxp.children(dev_sxp, ''dev'')[0]
- dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp)
+ dev_config = pci_convert_sxp_to_dict(dev_sxp)
dev = dev_config[''devs''][0]
# Do HVM specific processing
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 12/16] xend: pass-through: Use generic code in pci_opts_list_to_sxp()
Use dev_dict_to_sxp() inside pci_opts_list_to_sxp() now that it is
available.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 11:24:37.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-15 11:24:37.000000000
+1000
@@ -135,12 +135,11 @@ def split_pci_opts(opts):
filter(lambda x: x != '''',
opts.split('','')))
def pci_opts_list_to_sxp(list):
- return [''dev''] + map(lambda x: [''opts'',
x], list)
+ return dev_dict_to_sxp({''opts'': list})
def pci_opts_list_from_sxp(dev):
return map(lambda x: sxp.children(x)[0], sxp.children(dev,
''opts''))
-# This includes a generic equivalent of pci_opts_list_to_sxp()
def dev_dict_to_sxp(dev):
def f((key, val)):
if isinstance(val, types.ListType):
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 13/16] xend: pass-through: Add pci_tuple_to_dict()
This will be re-used in subsequent patches.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xm/create.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xm/create.py 2009-06-13 11:13:29.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/xm/create.py 2009-06-13 11:13:42.000000000
+1000
@@ -38,7 +38,7 @@ from xen.util import vscsi_util
import xen.util.xsm.xsm as security
from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
from xen.util import utils, auxbin
-from xen.util.pci import pci_opts_list_to_sxp, \
+from xen.util.pci import dev_dict_to_sxp, \
parse_pci_name_extended, PciDeviceParseError
from xen.xm.opts import *
@@ -706,12 +706,9 @@ def configure_pci(config_devs, vals):
"""Create the config for pci devices.
"""
config_pci = []
- for (domain, bus, slot, func, vslot, opts) in vals.pci:
- config_pci_bdf = [''dev'', [''domain'',
domain], [''bus'', bus], \
- [''slot'', slot],
[''func'', func],
- [''vslot'', vslot]]
- config_opts = pci_opts_list_to_sxp(opts)
- config_pci.append(sxp.merge(config_pci_bdf, config_opts))
+ for pci_tuple in vals.pci:
+ pci_dev = pci_tuple_to_dict(pci_tuple)
+ config_pci.append(dev_dict_to_sxp(pci_dev))
if len(config_pci)>0:
config_pci.insert(0, ''pci'')
@@ -1049,6 +1046,16 @@ def pci_dict_to_tuple(dev):
return (dev[''domain''], dev[''bus''],
dev[''slot''], dev[''func''],
dev[''vslot''], dev.get(''opts'',
[]))
+def pci_tuple_to_dict((domain, bus, slot, func, vslot, opts)):
+ pci_dev = { ''domain'': domain,
+ ''bus'': bus,
+ ''slot'': slot,
+ ''func'': func,
+ ''vslot'': vslot}
+ if len(opts) > 0:
+ pci_dev[''opts''] = opts
+ return pci_dev
+
def preprocess_pci(vals):
if not vals.pci:
return
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 14/16] xend: pass-through: Use common parsing code in parse_pci_configuration()
This will be re-used in subsequent patches.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xm/main.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xm/main.py 2009-06-13 22:30:08.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/xm/main.py 2009-06-14 17:12:19.000000000
+1000
@@ -2486,36 +2486,16 @@ def parse_pci_configuration(args, state,
dom = args[0]
pci_dev_str = args[1]
if len(args) == 3:
- vslot = args[2]
- else:
- vslot = AUTO_PHP_SLOT_STR
- pci=[''pci'']
- 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-7])$", pci_dev_str)
- if pci_match == None:
- raise OptionError("Invalid argument: %s %s" % (pci_dev_str,
vslot))
- pci_dev_info = pci_match.groupdict(''0'')
-
- try:
- pci_bdf =[''dev'', [''domain'',
''0x''+ pci_dev_info[''domain'']], \
- [''bus'', ''0x''+
pci_dev_info[''bus'']],
- [''slot'', ''0x''+
pci_dev_info[''slot'']],
- [''func'', ''0x''+
pci_dev_info[''func'']],
- [''vslot'', ''0x%x'' %
int(vslot, 16)]]
- except:
- raise OptionError("Invalid argument: %s %s" % (pci_dev_str,
vslot))
+ pci_dev_str += ''@'' + args[2]
+ if len(opts) > 0:
+ pci_dev_str += '','' + serialise_pci_opts(opts)
try:
- check_pci_opts(opts)
+ pci_dev = parse_pci_name_extended(pci_dev_str)
except PciDeviceParseError, ex:
raise OptionError(str(ex))
- pci.append(sxp.merge(pci_bdf, pci_opts_list_to_sxp(opts)))
- pci.append([''state'', state])
-
- return (dom, pci)
+ return (dom, pci_convert_dict_to_sxp(pci_dev, state))
def xm_pci_attach(args):
config_pci_opts = []
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 15/16] xend: pass-through: Use common parsing code in getDeviceConfiguration()
This will be re-used in subsequent patches.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-07
21:58:38.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-07
22:12:13.000000000 +1000
@@ -170,31 +170,18 @@ class PciController(DevController):
pci_devs = []
for i in range(int(num_devs)):
- dev_config = self.readBackend(devid, ''dev-%d'' %
i)
+ pci_dev = parse_pci_name(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-7]{1,2})$",
dev_config)
-
- if pci_match!=None:
- pci_dev_info = pci_match.groupdict()
- dev_dict = {''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}
-
- # Per device uuid info
- dev_dict[''uuid''] = self.readBackend(devid,
''uuid-%d'' % i)
- dev_dict[''vslot''] = ''0x%s''
% \
- self.readBackend(devid,
''vslot-%d'' % i)
-
- #append opts info
- opts = self.readBackend(devid, ''opts-%d'' % i)
- if opts is not None:
- dev_dict[''opts''] = opts
+ # Per device uuid info
+ pci_dev[''uuid''] = self.readBackend(devid,
''uuid-%d'' % i)
+ pci_dev[''vslot''] = ''0x%s'' %
self.readBackend(devid, ''vslot-%d'' % i)
+
+ #append opts info
+ opts = self.readBackend(devid, ''opts-%d'' % i)
+ if opts is not None:
+ pci_dev[''opts''] = opts
- pci_devs.append(dev_dict)
+ pci_devs.append(pci_dev)
result[''devs''] = pci_devs
result[''uuid''] = self.readBackend(devid,
''uuid'')
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 01:55 UTC
[Xen-devel] [patch 16/16] xend: pass-through: Clean up hvm_destroyPCIDevice()
There seems to be little need to use the domain, bus, slot and function
to look up the virtual slot to pass as the argument to
hvm_destroyPCIDevice(), only to have hvm_destroyPCIDevice() use
the virtual slot for the sole purpose of looking up the
domain, bus, slot and function.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
11:24:37.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
11:24:43.000000000 +1000
@@ -844,7 +844,7 @@ class XendDomainInfo:
raise VmError("Device %s is not connected" %
pci_dict_to_bdf_str(dev))
new_dev = new_devs[0]
-
self.hvm_destroyPCIDevice(int(new_dev[''vslot''], 16))
+ self.hvm_destroyPCIDevice(new_dev)
# Update vslot
dev[''vslot''] =
new_dev[''vslot'']
for n in sxp.children(pci_dev):
@@ -1098,39 +1098,19 @@ class XendDomainInfo:
for devclass in XendDevices.valid_devices():
self.getDeviceController(devclass).waitForDevices()
- def hvm_destroyPCIDevice(self, vslot):
- log.debug("hvm_destroyPCIDevice called %s", vslot)
+ def hvm_destroyPCIDevice(self, pci_dev):
+ log.debug("hvm_destroyPCIDevice: %s", pci_dev)
if not self.info.is_hvm():
raise VmError("hvm_destroyPCIDevice called on non-HVM
guest")
- #all the PCI devs share one conf node
- devid = ''0''
- vslot = int(vslot)
- dev_info = self._getDeviceInfo_pci(''0'')#from
self.info[''devices'']
- dev_uuid = sxp.child_value(dev_info, ''uuid'')
-
- #delete the pci bdf config under the pci device
- pci_conf = self.info[''devices''][dev_uuid][1]
- pci_len = len(pci_conf[''devs''])
-
- #find the pass-through device with the virtual slot
- devnum = 0
- for x in pci_conf[''devs'']:
- if int(x[''vslot''], 16) == vslot:
- break
- devnum += 1
-
- if devnum >= pci_len:
- raise VmError("Device @ vslot 0x%x doesn''t
exist." % (vslot))
-
# Check the co-assignment.
# To pci-detach a device D from domN, we should ensure: for each DD in
the
# list of D''s co-assignment devices, DD is not assigned (to
domN).
#
from xen.xend.server.pciif import PciDevice
try:
- pci_device = PciDevice(x)
+ pci_device = PciDevice(pci_dev)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it''s resources - "+str(e))
@@ -1145,8 +1125,8 @@ class XendDomainInfo:
)% (pci_device.name,
self.info[''name_label''], pci_str))
- bdf_str = pci_dict_to_bdf_str(x)
- log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str)
+ bdf_str = pci_dict_to_bdf_str(pci_dev)
+ log.info("hvm_destroyPCIDevice:%s:%s!", pci_dev, bdf_str)
if self.domid is not None:
self.image.signalDeviceModel(''pci-rem'',
''pci-removed'', bdf_str)
--
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Masaki Kanno
2009-Jun-15 05:58 UTC
Re: [Xen-devel] [patch 11/16] xend: pass-through: Move pci conversionfunctions to pci.py
Hi Simon, dev_dict_to_sxp method in XendConfig.py is called for both pci devices and vscsi devices. So, I think that the method should be not moved to pci.py. I suggest separating the processing of pci devices and the processing of vscsi devices in all_devices_sxpr method. I attach a patch for separating them. Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com> Best regards, Kan Mon, 15 Jun 2009 11:55:26 +1000, Simon Horman wrote:>Move dev_dict_to_sxp(), pci_convert_dict_to_sxp() and >pci_convert_sxp_to_dict() to pci.py, where other similar functions live. >This makes them accessible outside of the XendConfig class. > >Cc: Dexuan Cui <dexuan.cui@intel.com> >Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com> >Signed-off-by: Simon Horman <horms@verge.net.au> > >--- > > tools/python/xen/util/pci.py | 83 ++++++++++++++++++++++++++++ > tools/python/xen/xend/XendConfig.py | 91 +-------------------------- >---- > tools/python/xen/xend/XendDomainInfo.py | 10 ++- > 3 files changed, 94 insertions(+), 90 deletions(-) > >Index: xen-unstable.hg/tools/python/xen/util/pci.py >==================================================================>--- xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-13 21:39:44. >000000000 +1000 >+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-13 21:39:56. >000000000 +1000 >@@ -14,6 +14,7 @@ import struct > import time > import threading > from xen.util import utils >+from xen.xend import uuid > from xen.xend import sxp > from xen.xend.XendConstants import AUTO_PHP_SLOT > >@@ -139,6 +140,88 @@ def pci_opts_list_to_sxp(list): > def pci_opts_list_from_sxp(dev): > return map(lambda x: sxp.children(x)[0], sxp.children(dev, ''opts'')) > >+# This includes a generic equivalent of pci_opts_list_to_sxp() >+def dev_dict_to_sxp(dev): >+ def f((key, val)): >+ if isinstance(val, types.ListType): >+ return map(lambda x: [key, x], val) >+ return [[key, val]] >+ dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f, dev.items())) >+ return dev_sxp >+ >+def pci_convert_dict_to_sxp(dev, state, sub_state = None): >+ pci_sxp = [''pci'', dev_dict_to_sxp(dev), [''state'', state]] >+ if sub_state != None: >+ pci_sxp.append([''sub_state'', sub_state]) >+ return pci_sxp >+ >+def pci_convert_sxp_to_dict(dev_sxp): >+ """Convert pci device sxp to dict >+ @param dev_sxp: device configuration >+ @type dev_sxp: SXP object (parsed config) >+ @return: dev_config >+ @rtype: dictionary >+ """ >+ # Parsing the device SXP''s. In most cases, the SXP looks >+ # like this: >+ # >+ # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] >+ # >+ # However, for PCI devices it looks like this: >+ # >+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]] >+ # >+ # It seems the reasoning for this difference is because >+ # pciif.py needs all the PCI device configurations at >+ # the same time when creating the devices. >+ # >+ # To further complicate matters, Xen 2.0 configuration format >+ # uses the following for pci device configuration: >+ # >+ # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] >+ >+ # For PCI device hotplug support, the SXP of PCI devices is >+ # extendend like this: >+ # >+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2], >+ # [vslot, 0]], >+ # [state, ''Initialising'']]] >+ # >+ # ''vslot'' shows the virtual hotplug slot number which the PCI device >+ # is inserted in. This is only effective for HVM domains. >+ # >+ # state ''Initialising'' indicates that the device is being attached, >+ # while state ''Closing'' indicates that the device is being detached. >+ # >+ # The Dict looks like this: >+ # >+ # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}], >+ # states: [''Initialising''] } >+ >+ dev_config = {} >+ >+ pci_devs = [] >+ for pci_dev in sxp.children(dev_sxp, ''dev''): >+ pci_dev_info = dict(pci_dev[1:]) >+ if ''opts'' in pci_dev_info: >+ pci_dev_info[''opts''] = pci_opts_list_from_sxp(pci_dev) >+ # append uuid to each pci device that does''t already have one. >+ if not pci_dev_info.has_key(''uuid''): >+ dpci_uuid = pci_dev_info.get(''uuid'', uuid.createString()) >+ pci_dev_info[''uuid''] = dpci_uuid >+ pci_devs.append(pci_dev_info) >+ dev_config[''devs''] = pci_devs >+ >+ pci_states = [] >+ for pci_state in sxp.children(dev_sxp, ''state''): >+ try: >+ pci_states.append(pci_state[1]) >+ except IndexError: >+ raise XendError("Error reading state while parsing pci sxp") >+ dev_config[''states''] = pci_states >+ >+ return dev_config >+ > def parse_hex(val): > try: > if isinstance(val, types.StringTypes): >Index: xen-unstable.hg/tools/python/xen/xend/XendConfig.py >==================================================================>--- xen-unstable.hg.orig/tools/python/xen/xend/XendConfig.py 2009-06-13 21: >39:44.000000000 +1000 >+++ xen-unstable.hg/tools/python/xen/xend/XendConfig.py 2009-06-13 21:39:56>.000000000 +1000 >@@ -36,7 +36,8 @@ from xen.xend.xenstore.xstransact import > from xen.xend.server.BlktapController import blktap_disk_types > from xen.xend.server.netif import randomMAC > from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file >-from xen.util.pci import pci_opts_list_from_sxp >+from xen.util.pci import pci_opts_list_from_sxp, dev_dict_to_sxp, \ >+ pci_convert_sxp_to_dict > from xen.util import xsconstants > import xen.util.auxbin > >@@ -1296,7 +1297,7 @@ class XendConfig(dict): > pci_devs_uuid = sxp.child_value(config, ''uuid'', > uuid.createString()) > >- pci_dict = self.pci_convert_sxp_to_dict(config) >+ pci_dict = pci_convert_sxp_to_dict(config) > pci_devs = pci_dict[''devs''] > > # create XenAPI DPCI objects. >@@ -1596,79 +1597,6 @@ class XendConfig(dict): > > return '''' > >- def pci_convert_dict_to_sxp(self, dev, state, sub_state = None): >- pci_sxp = [''pci'', self.dev_dict_to_sxp(dev), [''state'', state]] >- if sub_state != None: >- pci_sxp.append([''sub_state'', sub_state]) >- return pci_sxp >- >- def pci_convert_sxp_to_dict(self, dev_sxp): >- """Convert pci device sxp to dict >- @param dev_sxp: device configuration >- @type dev_sxp: SXP object (parsed config) >- @return: dev_config >- @rtype: dictionary >- """ >- # Parsing the device SXP''s. In most cases, the SXP looks >- # like this: >- # >- # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] >- # >- # However, for PCI devices it looks like this: >- # >- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]] >- # >- # It seems the reasoning for this difference is because >- # pciif.py needs all the PCI device configurations at >- # the same time when creating the devices. >- # >- # To further complicate matters, Xen 2.0 configuration format >- # uses the following for pci device configuration: >- # >- # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] >- >- # For PCI device hotplug support, the SXP of PCI devices is >- # extendend like this: >- # >- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2], >- # [vslot, 0]], >- # [state, ''Initialising'']]] >- # >- # ''vslot'' shows the virtual hotplug slot number which the PCI device >- # is inserted in. This is only effective for HVM domains. >- # >- # state ''Initialising'' indicates that the device is being attached, >- # while state ''Closing'' indicates that the device is being detached. >- # >- # The Dict looks like this: >- # >- # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}], >- # states: [''Initialising''] } >- >- dev_config = {} >- >- pci_devs = [] >- for pci_dev in sxp.children(dev_sxp, ''dev''): >- pci_dev_info = dict(pci_dev[1:]) >- if ''opts'' in pci_dev_info: >- pci_dev_info[''opts''] = pci_opts_list_from_sxp(pci_dev) >- # append uuid to each pci device that does''t already have one. >- if not pci_dev_info.has_key(''uuid''): >- dpci_uuid = pci_dev_info.get(''uuid'', uuid.createString()) >- pci_dev_info[''uuid''] = dpci_uuid >- pci_devs.append(pci_dev_info) >- dev_config[''devs''] = pci_devs >- >- pci_states = [] >- for pci_state in sxp.children(dev_sxp, ''state''): >- try: >- pci_states.append(pci_state[1]) >- except IndexError: >- raise XendError("Error reading state while parsing pci sxp") >- dev_config[''states''] = pci_states >- >- return dev_config >- > def vscsi_convert_sxp_to_dict(self, dev_sxp): > """Convert vscsi device sxp to dict > @param dev_sxp: device configuration >@@ -1839,7 +1767,7 @@ class XendConfig(dict): > dev_type, dev_info = self[''devices''][dev_uuid] > > if dev_type == ''pci'': # Special case for pci >- pci_dict = self.pci_convert_sxp_to_dict(config) >+ pci_dict = pci_convert_sxp_to_dict(config) > pci_devs = pci_dict[''devs''] > > # destroy existing XenAPI DPCI objects >@@ -1962,15 +1890,6 @@ class XendConfig(dict): > result.extend([u for u in target[''devices''].keys() if u not in >result]) > return result > >- # This includes a generic equivalent of pci_opts_list_to_sxp() >- def dev_dict_to_sxp(self, dev): >- def f((key, val)): >- if isinstance(val, types.ListType): >- return map(lambda x: [key, x], val) >- return [[key, val]] >- dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f, dev.items())) >- return dev_sxp >- > def all_devices_sxpr(self, target = None): > """Returns the SXPR for all devices in the current configuration.""" > sxprs = [] >@@ -1993,7 +1912,7 @@ class XendConfig(dict): > if dev_info.has_key(''backend''): > sxpr.append([''backend'', dev_info[''backend'']]) > for pci_dev_info in dev_info[''devs'']: >- sxpr.append(self.dev_dict_to_sxp(pci_dev_info)) >+ sxpr.append(dev_dict_to_sxp(pci_dev_info)) > sxprs.append((dev_type, sxpr)) > else: > sxpr = self.device_sxpr(dev_type = dev_type, >Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py >==================================================================>--- xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-13> 21:39:44.000000000 +1000 >+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-13 21: >40:34.000000000 +1000 >@@ -40,7 +40,9 @@ from xen.util.blkif import blkdev_uname_ > import xen.util.xsm.xsm as security > from xen.util import xsconstants > from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \ >- pci_dict_to_bdf_str, pci_dict_to_xc_str, >pci_dict_cmp >+ pci_dict_to_bdf_str, pci_dict_to_xc_str, \ >+ pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \ >+ pci_dict_cmp > > from xen.xend import balloon, sxp, uuid, image, arch > from xen.xend import XendOptions, XendNode, XendConfig >@@ -616,8 +618,8 @@ class XendDomainInfo: > pci_conf = self.info[''devices''][dev_uuid][1] > pci_devs = pci_conf[''devs''] > request = map(lambda x: >- self.info.pci_convert_dict_to_sxp(x, ''Initialising'', >- ''Booting''), >pci_devs) >+ pci_convert_dict_to_sxp(x, ''Initialising'', ''Booting''), >+ pci_devs) > > for i in request: > self.pci_device_configure(i) >@@ -815,7 +817,7 @@ class XendDomainInfo: > raise XendError("Cannot detach when pci platform does not >exist") > > pci_dev = sxp.children(dev_sxp, ''dev'')[0] >- dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp) >+ dev_config = pci_convert_sxp_to_dict(dev_sxp) > dev = dev_config[''devs''][0] > > # Do HVM specific processing > >-- > >_______________________________________________ >Xen-devel mailing list >Xen-devel@lists.xensource.com >http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 06:15 UTC
Re: [Xen-devel] [patch 11/16] xend: pass-through: Move pci conversionfunctions to pci.py
On Mon, Jun 15, 2009 at 02:58:14PM +0900, Masaki Kanno wrote: Content-Description: Mail message body> Hi Simon, > > dev_dict_to_sxp method in XendConfig.py is called for both pci > devices and vscsi devices. So, I think that the method should > be not moved to pci.py. > > I suggest separating the processing of pci devices and the > processing of vscsi devices in all_devices_sxpr method. > I attach a patch for separating them.That seems reasonable. I haven''t had time to work through the vscsi, nor am I likely to in the near future. But does the logic in dev_dict_to_sxp() make sense for vscsi? If so, would you be happy it we moved it somewhere else, perhaps into sxp.py? Or create XendSXPDev.py? _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Masaki Kanno
2009-Jun-15 07:02 UTC
Re: [Xen-devel] [patch 11/16] xend: pass-through: Move pciconversionfunctions to pci.py
Hi Simon, Mon, 15 Jun 2009 16:15:59 +1000, Simon Horman wrote:>On Mon, Jun 15, 2009 at 02:58:14PM +0900, Masaki Kanno wrote: >Content-Description: Mail message body >> Hi Simon, >> >> dev_dict_to_sxp method in XendConfig.py is called for both pci >> devices and vscsi devices. So, I think that the method should >> be not moved to pci.py. >> >> I suggest separating the processing of pci devices and the >> processing of vscsi devices in all_devices_sxpr method. >> I attach a patch for separating them. > >That seems reasonable. > >I haven''t had time to work through the vscsi, nor am I likely to in the >near future. But does the logic in dev_dict_to_sxp() make sense for vscsi?Yes. I confirmed that dev_dict_to_sxp method is working for vscsi.>If so, would you be happy it we moved it somewhere else, perhaps >into sxp.py? Or create XendSXPDev.py?XendSXPDev.py ... Best regards, Kan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 09:04 UTC
Re: [Xen-devel] [patch 11/16] xend: pass-through: Move pciconversionfunctions to pci.py
On Mon, Jun 15, 2009 at 04:02:06PM +0900, Masaki Kanno wrote:> Hi Simon, > > Mon, 15 Jun 2009 16:15:59 +1000, Simon Horman wrote: > > >On Mon, Jun 15, 2009 at 02:58:14PM +0900, Masaki Kanno wrote: > >Content-Description: Mail message body > >> Hi Simon, > >> > >> dev_dict_to_sxp method in XendConfig.py is called for both pci > >> devices and vscsi devices. So, I think that the method should > >> be not moved to pci.py. > >> > >> I suggest separating the processing of pci devices and the > >> processing of vscsi devices in all_devices_sxpr method. > >> I attach a patch for separating them. > > > >That seems reasonable. > > > >I haven''t had time to work through the vscsi, nor am I likely to in the > >near future. But does the logic in dev_dict_to_sxp() make sense for vscsi? > > Yes. I confirmed that dev_dict_to_sxp method is working for vscsi. > > > >If so, would you be happy it we moved it somewhere else, perhaps > >into sxp.py? Or create XendSXPDev.py? > > XendSXPDev.py ...Ok, will do. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 11:58 UTC
[Xen-devel] [patch v2] xend: pass-through: Move pci conversion functions to pci.py
Move dev_dict_to_sxp() into XendSXPDev.py. Move pci_convert_dict_to_sxp()
and pci_convert_sxp_to_dict() to pci.py, where other similar functions
live. This makes these functions accessible outside of the XendConfig
class.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Mon, 15 Jun 2009 11:55:26 +1000
* Initial posting
Mon, 15 Jun 2009 20:39:43 +1000
* Move dev_dict_to_sxp into XendSXPDev.py as it is used by
non-pci as well as pci devices
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-13 21:39:44.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-13 21:39:56.000000000
+1000
@@ -14,6 +14,7 @@ import struct
import time
import threading
from xen.util import utils
+from xen.xend import uuid
from xen.xend import sxp
from xen.xend.XendConstants import AUTO_PHP_SLOT
@@ -139,6 +140,88 @@ def pci_opts_list_to_sxp(list):
def pci_opts_list_from_sxp(dev):
return map(lambda x: sxp.children(x)[0], sxp.children(dev,
''opts''))
+# This includes a generic equivalent of pci_opts_list_to_sxp()
+def dev_dict_to_sxp(dev):
+ def f((key, val)):
+ if isinstance(val, types.ListType):
+ return map(lambda x: [key, x], val)
+ return [[key, val]]
+ dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
+ return dev_sxp
+
+def pci_convert_dict_to_sxp(dev, state, sub_state = None):
+ pci_sxp = [''pci'', dev_dict_to_sxp(dev),
[''state'', state]]
+ if sub_state != None:
+ pci_sxp.append([''sub_state'', sub_state])
+ return pci_sxp
+
+def pci_convert_sxp_to_dict(dev_sxp):
+ """Convert pci device sxp to dict
+ @param dev_sxp: device configuration
+ @type dev_sxp: SXP object (parsed config)
+ @return: dev_config
+ @rtype: dictionary
+ """
+ # Parsing the device SXP''s. In most cases, the SXP looks
+ # like this:
+ #
+ # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
+ #
+ # However, for PCI devices it looks like this:
+ #
+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
+ #
+ # It seems the reasoning for this difference is because
+ # pciif.py needs all the PCI device configurations at
+ # the same time when creating the devices.
+ #
+ # To further complicate matters, Xen 2.0 configuration format
+ # uses the following for pci device configuration:
+ #
+ # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
+
+ # For PCI device hotplug support, the SXP of PCI devices is
+ # extendend like this:
+ #
+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
+ # [vslot, 0]],
+ # [state, ''Initialising'']]]
+ #
+ # ''vslot'' shows the virtual hotplug slot number which the
PCI device
+ # is inserted in. This is only effective for HVM domains.
+ #
+ # state ''Initialising'' indicates that the device is being
attached,
+ # while state ''Closing'' indicates that the device is
being detached.
+ #
+ # The Dict looks like this:
+ #
+ # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
+ # states: [''Initialising''] }
+
+ dev_config = {}
+
+ pci_devs = []
+ for pci_dev in sxp.children(dev_sxp, ''dev''):
+ pci_dev_info = dict(pci_dev[1:])
+ if ''opts'' in pci_dev_info:
+ pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
+ # append uuid to each pci device that does''t already have one.
+ if not pci_dev_info.has_key(''uuid''):
+ dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
+ pci_dev_info[''uuid''] = dpci_uuid
+ pci_devs.append(pci_dev_info)
+ dev_config[''devs''] = pci_devs
+
+ pci_states = []
+ for pci_state in sxp.children(dev_sxp, ''state''):
+ try:
+ pci_states.append(pci_state[1])
+ except IndexError:
+ raise XendError("Error reading state while parsing pci
sxp")
+ dev_config[''states''] = pci_states
+
+ return dev_config
+
def parse_hex(val):
try:
if isinstance(val, types.StringTypes):
Index: xen-unstable.hg/tools/python/xen/xend/XendConfig.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendConfig.py 2009-06-13
21:39:44.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendConfig.py 2009-06-13
21:39:56.000000000 +1000
@@ -36,7 +36,8 @@ from xen.xend.xenstore.xstransact import
from xen.xend.server.BlktapController import blktap_disk_types
from xen.xend.server.netif import randomMAC
from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
-from xen.util.pci import pci_opts_list_from_sxp
+from xen.util.pci import pci_opts_list_from_sxp, dev_dict_to_sxp, \
+ pci_convert_sxp_to_dict
from xen.util import xsconstants
import xen.util.auxbin
@@ -1296,7 +1297,7 @@ class XendConfig(dict):
pci_devs_uuid = sxp.child_value(config,
''uuid'',
uuid.createString())
- pci_dict = self.pci_convert_sxp_to_dict(config)
+ pci_dict = pci_convert_sxp_to_dict(config)
pci_devs = pci_dict[''devs'']
# create XenAPI DPCI objects.
@@ -1596,79 +1597,6 @@ class XendConfig(dict):
return ''''
- def pci_convert_dict_to_sxp(self, dev, state, sub_state = None):
- pci_sxp = [''pci'', self.dev_dict_to_sxp(dev),
[''state'', state]]
- if sub_state != None:
- pci_sxp.append([''sub_state'', sub_state])
- return pci_sxp
-
- def pci_convert_sxp_to_dict(self, dev_sxp):
- """Convert pci device sxp to dict
- @param dev_sxp: device configuration
- @type dev_sxp: SXP object (parsed config)
- @return: dev_config
- @rtype: dictionary
- """
- # Parsing the device SXP''s. In most cases, the SXP looks
- # like this:
- #
- # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
- #
- # However, for PCI devices it looks like this:
- #
- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
- #
- # It seems the reasoning for this difference is because
- # pciif.py needs all the PCI device configurations at
- # the same time when creating the devices.
- #
- # To further complicate matters, Xen 2.0 configuration format
- # uses the following for pci device configuration:
- #
- # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
-
- # For PCI device hotplug support, the SXP of PCI devices is
- # extendend like this:
- #
- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
- # [vslot, 0]],
- # [state, ''Initialising'']]]
- #
- # ''vslot'' shows the virtual hotplug slot number which
the PCI device
- # is inserted in. This is only effective for HVM domains.
- #
- # state ''Initialising'' indicates that the device is
being attached,
- # while state ''Closing'' indicates that the device is
being detached.
- #
- # The Dict looks like this:
- #
- # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
- # states: [''Initialising''] }
-
- dev_config = {}
-
- pci_devs = []
- for pci_dev in sxp.children(dev_sxp, ''dev''):
- pci_dev_info = dict(pci_dev[1:])
- if ''opts'' in pci_dev_info:
- pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
- # append uuid to each pci device that does''t already have
one.
- if not pci_dev_info.has_key(''uuid''):
- dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
- pci_dev_info[''uuid''] = dpci_uuid
- pci_devs.append(pci_dev_info)
- dev_config[''devs''] = pci_devs
-
- pci_states = []
- for pci_state in sxp.children(dev_sxp, ''state''):
- try:
- pci_states.append(pci_state[1])
- except IndexError:
- raise XendError("Error reading state while parsing pci
sxp")
- dev_config[''states''] = pci_states
-
- return dev_config
-
def vscsi_convert_sxp_to_dict(self, dev_sxp):
"""Convert vscsi device sxp to dict
@param dev_sxp: device configuration
@@ -1839,7 +1767,7 @@ class XendConfig(dict):
dev_type, dev_info = self[''devices''][dev_uuid]
if dev_type == ''pci'': # Special case for pci
- pci_dict = self.pci_convert_sxp_to_dict(config)
+ pci_dict = pci_convert_sxp_to_dict(config)
pci_devs = pci_dict[''devs'']
# destroy existing XenAPI DPCI objects
@@ -1962,15 +1890,6 @@ class XendConfig(dict):
result.extend([u for u in target[''devices''].keys() if
u not in result])
return result
- # This includes a generic equivalent of pci_opts_list_to_sxp()
- def dev_dict_to_sxp(self, dev):
- def f((key, val)):
- if isinstance(val, types.ListType):
- return map(lambda x: [key, x], val)
- return [[key, val]]
- dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
- return dev_sxp
-
def all_devices_sxpr(self, target = None):
"""Returns the SXPR for all devices in the current
configuration."""
sxprs = []
@@ -1993,7 +1912,7 @@ class XendConfig(dict):
if dev_info.has_key(''backend''):
sxpr.append([''backend'',
dev_info[''backend'']])
for pci_dev_info in dev_info[''devs'']:
- sxpr.append(self.dev_dict_to_sxp(pci_dev_info))
+ sxpr.append(dev_dict_to_sxp(pci_dev_info))
sxprs.append((dev_type, sxpr))
else:
sxpr = self.device_sxpr(dev_type = dev_type,
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-13
21:39:44.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-13
21:40:34.000000000 +1000
@@ -40,7 +40,9 @@ from xen.util.blkif import blkdev_uname_
import xen.util.xsm.xsm as security
from xen.util import xsconstants
from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
- pci_dict_to_bdf_str, pci_dict_to_xc_str, pci_dict_cmp
+ pci_dict_to_bdf_str, pci_dict_to_xc_str, \
+ pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \
+ pci_dict_cmp
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendOptions, XendNode, XendConfig
@@ -616,8 +618,8 @@ class XendDomainInfo:
pci_conf = self.info[''devices''][dev_uuid][1]
pci_devs = pci_conf[''devs'']
request = map(lambda x:
- self.info.pci_convert_dict_to_sxp(x,
''Initialising'',
-
''Booting''), pci_devs)
+ pci_convert_dict_to_sxp(x,
''Initialising'', ''Booting''),
+ pci_devs)
for i in request:
self.pci_device_configure(i)
@@ -815,7 +817,7 @@ class XendDomainInfo:
raise XendError("Cannot detach when pci platform does not
exist")
pci_dev = sxp.children(dev_sxp, ''dev'')[0]
- dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp)
+ dev_config = pci_convert_sxp_to_dict(dev_sxp)
dev = dev_config[''devs''][0]
# Do HVM specific processing
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 11:59 UTC
[Xen-devel] [patch v2] xend: pass-through: Use generic code in pci_opts_list_to_sxp()
Use dev_dict_to_sxp() inside pci_opts_list_to_sxp() now that it is
available.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Mon, 15 Jun 2009 11:55:27 +1000
* Initial posting
Mon, 15 Jun 2009 20:38:21 +1000
* dev_dict_to_sxp() is now in XendSXPDev.py
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 20:13:52.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-15 20:35:32.000000000
+1000
@@ -136,7 +136,7 @@ def split_pci_opts(opts):
filter(lambda x: x != '''',
opts.split('','')))
def pci_opts_list_to_sxp(list):
- return [''dev''] + map(lambda x: [''opts'',
x], list)
+ return dev_dict_to_sxp({''opts'': list})
def pci_opts_list_from_sxp(dev):
return map(lambda x: sxp.children(x)[0], sxp.children(dev,
''opts''))
Index: xen-unstable.hg/tools/python/xen/xend/XendSXPDev.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendSXPDev.py 2009-06-15
20:35:56.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendSXPDev.py 2009-06-15
20:36:06.000000000 +1000
@@ -4,7 +4,6 @@
import types
-# This includes a generic equivalent of pci_opts_list_to_sxp()
def dev_dict_to_sxp(dev):
def f((key, val)):
if isinstance(val, types.ListType):
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-15 23:36 UTC
[Xen-devel] [patch 11/16 v3] xend: pass-through: Move pci conversion functions to pci.py
Move dev_dict_to_sxp() into XendSXPDev.py. Move pci_convert_dict_to_sxp()
and pci_convert_sxp_to_dict() to pci.py, where other similar functions
live. This makes these functions accessible outside of the XendConfig
class.
Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Mon, 15 Jun 2009 11:55:26 +1000
* Initial posting
Mon, 15 Jun 2009 20:39:43 +1000
* Miss-post - XendSXPDev.py change was omitted
Tue, 16 Jun 2009 09:33:17 +1000
* Move dev_dict_to_sxp into XendSXPDev.py.
As pointed out by Masaki Kanno, it is used by non-pci as well as pci devices.
Index: xen-unstable.hg/tools/python/xen/util/pci.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 19:37:07.000000000
+1000
+++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-16 09:31:18.000000000
+1000
@@ -14,8 +14,10 @@ import struct
import time
import threading
from xen.util import utils
+from xen.xend import uuid
from xen.xend import sxp
from xen.xend.XendConstants import AUTO_PHP_SLOT
+from xen.xend.XendSXPDev import dev_dict_to_sxp
PROC_PCI_PATH = ''/proc/bus/pci/devices''
PROC_PCI_NUM_RESOURCES = 7
@@ -139,6 +141,79 @@ def pci_opts_list_to_sxp(list):
def pci_opts_list_from_sxp(dev):
return map(lambda x: sxp.children(x)[0], sxp.children(dev,
''opts''))
+def pci_convert_dict_to_sxp(dev, state, sub_state = None):
+ pci_sxp = [''pci'', dev_dict_to_sxp(dev),
[''state'', state]]
+ if sub_state != None:
+ pci_sxp.append([''sub_state'', sub_state])
+ return pci_sxp
+
+def pci_convert_sxp_to_dict(dev_sxp):
+ """Convert pci device sxp to dict
+ @param dev_sxp: device configuration
+ @type dev_sxp: SXP object (parsed config)
+ @return: dev_config
+ @rtype: dictionary
+ """
+ # Parsing the device SXP''s. In most cases, the SXP looks
+ # like this:
+ #
+ # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
+ #
+ # However, for PCI devices it looks like this:
+ #
+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
+ #
+ # It seems the reasoning for this difference is because
+ # pciif.py needs all the PCI device configurations at
+ # the same time when creating the devices.
+ #
+ # To further complicate matters, Xen 2.0 configuration format
+ # uses the following for pci device configuration:
+ #
+ # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
+
+ # For PCI device hotplug support, the SXP of PCI devices is
+ # extendend like this:
+ #
+ # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
+ # [vslot, 0]],
+ # [state, ''Initialising'']]]
+ #
+ # ''vslot'' shows the virtual hotplug slot number which the
PCI device
+ # is inserted in. This is only effective for HVM domains.
+ #
+ # state ''Initialising'' indicates that the device is being
attached,
+ # while state ''Closing'' indicates that the device is
being detached.
+ #
+ # The Dict looks like this:
+ #
+ # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
+ # states: [''Initialising''] }
+
+ dev_config = {}
+
+ pci_devs = []
+ for pci_dev in sxp.children(dev_sxp, ''dev''):
+ pci_dev_info = dict(pci_dev[1:])
+ if ''opts'' in pci_dev_info:
+ pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
+ # append uuid to each pci device that does''t already have one.
+ if not pci_dev_info.has_key(''uuid''):
+ dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
+ pci_dev_info[''uuid''] = dpci_uuid
+ pci_devs.append(pci_dev_info)
+ dev_config[''devs''] = pci_devs
+
+ pci_states = []
+ for pci_state in sxp.children(dev_sxp, ''state''):
+ try:
+ pci_states.append(pci_state[1])
+ except IndexError:
+ raise XendError("Error reading state while parsing pci
sxp")
+ dev_config[''states''] = pci_states
+
+ return dev_config
+
def parse_hex(val):
try:
if isinstance(val, types.StringTypes):
Index: xen-unstable.hg/tools/python/xen/xend/XendConfig.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendConfig.py 2009-06-15
19:36:53.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendConfig.py 2009-06-16
09:31:17.000000000 +1000
@@ -36,7 +36,8 @@ from xen.xend.xenstore.xstransact import
from xen.xend.server.BlktapController import blktap_disk_types
from xen.xend.server.netif import randomMAC
from xen.util.blkif import blkdev_name_to_number, blkdev_uname_to_file
-from xen.util.pci import pci_opts_list_from_sxp
+from xen.util.pci import pci_opts_list_from_sxp, pci_convert_sxp_to_dict
+from xen.xend.XendSXPDev import dev_dict_to_sxp
from xen.util import xsconstants
import xen.util.auxbin
@@ -1296,7 +1297,7 @@ class XendConfig(dict):
pci_devs_uuid = sxp.child_value(config,
''uuid'',
uuid.createString())
- pci_dict = self.pci_convert_sxp_to_dict(config)
+ pci_dict = pci_convert_sxp_to_dict(config)
pci_devs = pci_dict[''devs'']
# create XenAPI DPCI objects.
@@ -1596,79 +1597,6 @@ class XendConfig(dict):
return ''''
- def pci_convert_dict_to_sxp(self, dev, state, sub_state = None):
- pci_sxp = [''pci'', self.dev_dict_to_sxp(dev),
[''state'', state]]
- if sub_state != None:
- pci_sxp.append([''sub_state'', sub_state])
- return pci_sxp
-
- def pci_convert_sxp_to_dict(self, dev_sxp):
- """Convert pci device sxp to dict
- @param dev_sxp: device configuration
- @type dev_sxp: SXP object (parsed config)
- @return: dev_config
- @rtype: dictionary
- """
- # Parsing the device SXP''s. In most cases, the SXP looks
- # like this:
- #
- # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
- #
- # However, for PCI devices it looks like this:
- #
- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2]]]
- #
- # It seems the reasoning for this difference is because
- # pciif.py needs all the PCI device configurations at
- # the same time when creating the devices.
- #
- # To further complicate matters, Xen 2.0 configuration format
- # uses the following for pci device configuration:
- #
- # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]]
-
- # For PCI device hotplug support, the SXP of PCI devices is
- # extendend like this:
- #
- # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
- # [vslot, 0]],
- # [state, ''Initialising'']]]
- #
- # ''vslot'' shows the virtual hotplug slot number which
the PCI device
- # is inserted in. This is only effective for HVM domains.
- #
- # state ''Initialising'' indicates that the device is
being attached,
- # while state ''Closing'' indicates that the device is
being detached.
- #
- # The Dict looks like this:
- #
- # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
- # states: [''Initialising''] }
-
- dev_config = {}
-
- pci_devs = []
- for pci_dev in sxp.children(dev_sxp, ''dev''):
- pci_dev_info = dict(pci_dev[1:])
- if ''opts'' in pci_dev_info:
- pci_dev_info[''opts''] =
pci_opts_list_from_sxp(pci_dev)
- # append uuid to each pci device that does''t already have
one.
- if not pci_dev_info.has_key(''uuid''):
- dpci_uuid = pci_dev_info.get(''uuid'',
uuid.createString())
- pci_dev_info[''uuid''] = dpci_uuid
- pci_devs.append(pci_dev_info)
- dev_config[''devs''] = pci_devs
-
- pci_states = []
- for pci_state in sxp.children(dev_sxp, ''state''):
- try:
- pci_states.append(pci_state[1])
- except IndexError:
- raise XendError("Error reading state while parsing pci
sxp")
- dev_config[''states''] = pci_states
-
- return dev_config
-
def vscsi_convert_sxp_to_dict(self, dev_sxp):
"""Convert vscsi device sxp to dict
@param dev_sxp: device configuration
@@ -1839,7 +1767,7 @@ class XendConfig(dict):
dev_type, dev_info = self[''devices''][dev_uuid]
if dev_type == ''pci'': # Special case for pci
- pci_dict = self.pci_convert_sxp_to_dict(config)
+ pci_dict = pci_convert_sxp_to_dict(config)
pci_devs = pci_dict[''devs'']
# destroy existing XenAPI DPCI objects
@@ -1962,15 +1890,6 @@ class XendConfig(dict):
result.extend([u for u in target[''devices''].keys() if
u not in result])
return result
- # This includes a generic equivalent of pci_opts_list_to_sxp()
- def dev_dict_to_sxp(self, dev):
- def f((key, val)):
- if isinstance(val, types.ListType):
- return map(lambda x: [key, x], val)
- return [[key, val]]
- dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
- return dev_sxp
-
def all_devices_sxpr(self, target = None):
"""Returns the SXPR for all devices in the current
configuration."""
sxprs = []
@@ -1993,7 +1912,7 @@ class XendConfig(dict):
if dev_info.has_key(''backend''):
sxpr.append([''backend'',
dev_info[''backend'']])
for pci_dev_info in dev_info[''devs'']:
- sxpr.append(self.dev_dict_to_sxp(pci_dev_info))
+ sxpr.append(dev_dict_to_sxp(pci_dev_info))
sxprs.append((dev_type, sxpr))
else:
sxpr = self.device_sxpr(dev_type = dev_type,
Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py
==================================================================---
xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py 2009-06-15
19:37:07.000000000 +1000
+++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-16
09:31:18.000000000 +1000
@@ -40,7 +40,9 @@ from xen.util.blkif import blkdev_uname_
import xen.util.xsm.xsm as security
from xen.util import xsconstants
from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \
- pci_dict_to_bdf_str, pci_dict_to_xc_str, pci_dict_cmp
+ pci_dict_to_bdf_str, pci_dict_to_xc_str, \
+ pci_convert_sxp_to_dict, pci_convert_dict_to_sxp, \
+ pci_dict_cmp
from xen.xend import balloon, sxp, uuid, image, arch
from xen.xend import XendOptions, XendNode, XendConfig
@@ -616,8 +618,8 @@ class XendDomainInfo:
pci_conf = self.info[''devices''][dev_uuid][1]
pci_devs = pci_conf[''devs'']
request = map(lambda x:
- self.info.pci_convert_dict_to_sxp(x,
''Initialising'',
-
''Booting''), pci_devs)
+ pci_convert_dict_to_sxp(x,
''Initialising'', ''Booting''),
+ pci_devs)
for i in request:
self.pci_device_configure(i)
@@ -815,7 +817,7 @@ class XendDomainInfo:
raise XendError("Cannot detach when pci platform does not
exist")
pci_dev = sxp.children(dev_sxp, ''dev'')[0]
- dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp)
+ dev_config = pci_convert_sxp_to_dict(dev_sxp)
dev = dev_config[''devs''][0]
# Do HVM specific processing
Index: xen-unstable.hg/tools/python/xen/xend/XendSXPDev.py
==================================================================--- /dev/null
1970-01-01 00:00:00.000000000 +0000
+++ xen-unstable.hg/tools/python/xen/xend/XendSXPDev.py 2009-06-16
09:31:18.000000000 +1000
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+#
+# Helper functions for dealing with the sxp representation of devices
+
+import types
+
+# This includes a generic equivalent of pci_opts_list_to_sxp()
+def dev_dict_to_sxp(dev):
+ def f((key, val)):
+ if isinstance(val, types.ListType):
+ return map(lambda x: [key, x], val)
+ return [[key, val]]
+ dev_sxp = [''dev''] + reduce(lambda x, y: x + y, map(f,
dev.items()))
+ return dev_sxp
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Keir Fraser
2009-Jun-16 10:43 UTC
Re: [Xen-devel] [patch 08/16] xend: pass-through: Common parse_pci_name()
This patch didn''t apply. I applied patches 1-7 and also patch 9 of your series, but beyond that it was a bit of a trainwreck. Please refresh patch 8 and patches 10+ and resend. Thanks, Keir On 15/06/2009 02:55, "Simon Horman" <horms@verge.net.au> wrote:> Share some parsing code between different parts of xm. > > This has the side-effect that the device specification for > hot-plug may now include the VSLOT and OPTS as per device > specifictions in the domain configuration file. > > SEQ:BUS:DEV.FUNC[,OPT...] > > e.g. 0000:00:01.00@6 > > Cc: Dexuan Cui <dexuan.cui@intel.com> > Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com> > Signed-off-by: Simon Horman <horms@verge.net.au> > > --- > > Wed, 20 May 2009 23:07:42 +1000 > * Fix syntax errors in parse_pci_name() and parse_pci_name_bdf6() > - unnoticed as they were resolved by the subsequent patch > "xm: Allow multi-function device specifications to be parsed > * Enhanced error reporting in parse_pci_name() > * Have parse_pci_name_bdf6() return an int rather than a string for vslot in > keeping with the other integer elements of the bdf6 tuple > > Fri, 22 May 2009 15:52:50 +1000 > * Consolidate get_all_pci_bdf6() and get_all_pci_devices() > > Thu, 28 May 2009 23:56:14 +1000 > * Up-port > > Index: xen-unstable.hg/tools/python/xen/util/pci.py > ==================================================================> --- xen-unstable.hg.orig/tools/python/xen/util/pci.py 2009-06-15 > 11:22:35.000000000 +1000 > +++ xen-unstable.hg/tools/python/xen/util/pci.py 2009-06-15 > 11:23:43.000000000 +1000 > @@ -15,6 +15,7 @@ import time > import threading > from xen.util import utils > from xen.xend import sxp > +from xen.xend.XendConstants import AUTO_PHP_SLOT > > PROC_PCI_PATH = ''/proc/bus/pci/devices'' > PROC_PCI_NUM_RESOURCES = 7 > @@ -35,7 +36,6 @@ LSPCI_CMD = ''lspci'' > > PCI_DEV_REG_EXPRESS_STR = r"[0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}."+ \ > r"[0-9a-fA-F]{1}" > -PCI_DEV_FORMAT_STR = ''%04x:%02x:%02x.%01x'' > > DEV_TYPE_PCIe_ENDPOINT = 0 > DEV_TYPE_PCIe_BRIDGE = 1 > @@ -148,22 +148,62 @@ def parse_hex(val): > except ValueError: > return None > > +def parse_pci_name_extended(pci_dev_str): > + 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-7]))" + > + r"(@(?P<vslot>[01]?[0-9a-fA-F]))?" + > + r"(,(?P<opts>.*))?$", pci_dev_str) > + > + if pci_match == None: > + raise PciDeviceParseError("Failed to parse pci device: %s" % > + pci_dev_str) > + > + out = {} > + pci_dev_info = pci_match.groupdict('''') > + if pci_dev_info[''domain''] == '''': > + domain = 0 > + else: > + domain = int(pci_dev_info[''domain''], 16) > + out[''domain''] = "0x%04x" % domain > + out[''bus''] = "0x%02x" % int(pci_dev_info[''bus''], 16) > + out[''slot''] = "0x%02x" % int(pci_dev_info[''slot''], 16) > + out[''func''] = "0x%x" % int(pci_dev_info[''func''], 16) > + if pci_dev_info[''vslot''] == '''': > + vslot = AUTO_PHP_SLOT > + else: > + vslot = int(pci_dev_info[''vslot''], 16) > + out[''vslot''] = "0x%02x" % vslot > + if pci_dev_info[''opts''] != '''': > + out[''opts''] = split_pci_opts(pci_dev_info[''opts'']) > + check_pci_opts(out[''opts'']) > + > + return out > + > def parse_pci_name(pci_name_string): > - 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-7])$", pci_name_string) > - if pci_match is None: > - raise PciDeviceParseError((''Failed to parse pci device name: %s'' % > - pci_name_string)) > - pci_dev_info = pci_match.groupdict(''0'') > - > - domain = parse_hex(pci_dev_info[''domain'']) > - bus = parse_hex(pci_dev_info[''bus'']) > - slot = parse_hex(pci_dev_info[''slot'']) > - func = parse_hex(pci_dev_info[''func'']) > + pci = parse_pci_name_extended(pci_name_string) > + > + if int(pci[''vslot''], 16) != AUTO_PHP_SLOT: > + raise PciDeviceParseError(("Failed to parse pci device: %s: " + > + "vslot provided where prohibited: %s") % > + (pci_name_string, pci[''vslot''])) > + if ''opts'' in pci: > + raise PciDeviceParseError(("Failed to parse pci device: %s: " + > + "options provided where prohibited: %s") % > + (pci_name_string, pci[''opts''])) > + > + return pci > + > +def __pci_dict_to_fmt_str(fmt, dev): > + return fmt % (int(dev[''domain''], 16), int(dev[''bus''], 16), > + int(dev[''slot''], 16), int(dev[''func''], 16)) > > - return (domain, bus, slot, func) > +def pci_dict_to_bdf_str(dev): > + return __pci_dict_to_fmt_str(''%04x:%02x:%02x.%01x'', dev) > + > +def pci_dict_to_xc_str(dev): > + return __pci_dict_to_fmt_str(''0x%x, 0x%x, 0x%x, 0x%x'', dev) > > def extract_the_exact_pci_names(pci_names): > result = [] > @@ -198,27 +238,7 @@ def get_all_pci_names(): > return pci_names > > def get_all_pci_devices(): > - pci_devs = [] > - for pci_name in get_all_pci_names(): > - 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-7])$", pci_name) > - if pci_match is None: > - raise PciDeviceParseError((''Failed to parse pci device name: %s'' > % > - pci_name)) > - pci_dev_info = pci_match.groupdict(''0'') > - domain = parse_hex(pci_dev_info[''domain'']) > - bus = parse_hex(pci_dev_info[''bus'']) > - slot = parse_hex(pci_dev_info[''slot'']) > - func = parse_hex(pci_dev_info[''func'']) > - try: > - pci_dev = PciDevice(domain, bus, slot, func) > - except: > - continue > - pci_devs.append(pci_dev) > - > - return pci_devs > + return map(PciDevice, map(parse_pci_name, get_all_pci_names())) > > def _create_lspci_info(): > """Execute ''lspci'' command and parse the result. > @@ -237,7 +257,7 @@ def _create_lspci_info(): > try: > (opt, value) = line.split('':\t'') > if opt == ''Slot'': > - device_name = PCI_DEV_FORMAT_STR % parse_pci_name(value) > + device_name = pci_dict_to_bdf_str(parse_pci_name(value)) > else: > device_info[opt] = value > except: > @@ -287,8 +307,7 @@ def find_all_devices_owned_by_pciback(): > pci_list = extract_the_exact_pci_names(pci_names) > dev_list = [] > for pci in pci_list: > - (dom, b, d, f) = parse_pci_name(pci) > - dev = PciDevice(dom, b, d, f) > + dev = PciDevice(parse_pci_name(pci)) > dev_list = dev_list + [dev] > return dev_list > > @@ -395,12 +414,12 @@ class PciDeviceVslotMissing(Exception): > return ''pci: no vslot: '' + self.message > > class PciDevice: > - def __init__(self, domain, bus, slot, func): > - self.domain = domain > - self.bus = bus > - self.slot = slot > - self.func = func > - self.name = PCI_DEV_FORMAT_STR % (domain, bus, slot, func) > + def __init__(self, dev): > + self.domain = int(dev[''domain''], 16) > + self.bus = int(dev[''bus''], 16) > + self.slot = int(dev[''slot''], 16) > + self.func = int(dev[''func''], 16) > + self.name = pci_dict_to_bdf_str(dev) > self.cfg_space_path = find_sysfs_mnt()+SYSFS_PCI_DEVS_PATH+''/''+ \ > self.name + SYSFS_PCI_DEV_CONFIG_PATH > self.irq = 0 > @@ -442,14 +461,15 @@ class PciDevice: > # We have reached the upmost one. > return None > else: > + dev = {} > lst = parent.split('':'') > - dom = int(lst[0], 16) > - bus = int(lst[1], 16) > + dev[''dom''] = int(lst[0], 16) > + dev[''bus''] = int(lst[1], 16) > lst = lst[2] > lst = lst.split(''.'') > - dev = int(lst[0], 16) > - func = int(lst[1], 16) > - return (dom, bus, dev, func) > + dev[''slot''] = int(lst[0], 16) > + dev[''func''] = int(lst[1], 16) > + return dev > except OSError, (errno, strerr): > raise PciDeviceParseError(''Can not locate the parent of %s'', > self.name) > @@ -459,15 +479,13 @@ class PciDevice: > dev = self.find_parent() > if dev is None: > return None > - (dom, b, d, f) = dev > - dev = dev_parent = PciDevice(dom, b, d, f) > + dev = dev_parent = PciDevice(dev) > while dev_parent.dev_type != DEV_TYPE_PCIe_BRIDGE: > parent = dev_parent.find_parent() > if parent is None: > break > - (dom, b, d, f) = parent > dev = dev_parent > - dev_parent = PciDevice(dom, b, d, f) > + dev_parent = PciDevice(parent) > return dev > > def find_all_devices_behind_the_bridge(self, ignore_bridge): > @@ -478,8 +496,7 @@ class PciDevice: > > list = [self.name] > for pci_str in dev_list: > - (dom, b, d, f) = parse_pci_name(pci_str) > - dev = PciDevice(dom, b, d, f) > + dev = PciDevice(parse_pci_name(pci_str)) > if dev.dev_type == DEV_TYPE_PCI_BRIDGE or \ > dev.dev_type == DEV_TYPE_PCIe_BRIDGE: > sub_list_including_self = \ > @@ -595,7 +612,7 @@ class PciDevice: > > def find_all_the_multi_functions(self): > sysfs_mnt = find_sysfs_mnt() > - parent = PCI_DEV_FORMAT_STR % self.find_parent() > + parent = pci_dict_to_bdf_str(self.find_parent()) > pci_names = os.popen(''ls '' + sysfs_mnt + SYSFS_PCI_DEVS_PATH + ''/'' + > \ > parent + ''/'').read() > funcs = extract_the_exact_pci_names(pci_names) > @@ -753,8 +770,7 @@ class PciDevice: > if len(devs) == 0: > return > for pci_dev in devs: > - (dom, b, d, f) = parse_pci_name(pci_dev) > - dev = PciDevice(dom, b, d, f) > + dev = PciDevice(parse_pci_name(pci_dev)) > if dev.driver == ''pciback'': > continue > err_msg = ''pci: %s must be co-assigned to the same guest with %s'' > + \ > @@ -780,7 +796,7 @@ class PciDevice: > funcs = self.find_all_the_multi_functions() > self.devs_check_driver(funcs) > > - parent = ''%04x:%02x:%02x.%01x'' % self.find_parent() > + parent = pci_dict_to_bdf_str(self.find_parent()) > > # Do Secondary Bus Reset. > self.do_secondary_bus_reset(parent, funcs) > Index: xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py > ==================================================================> --- xen-unstable.hg.orig/tools/python/xen/xend/XendDomainInfo.py > 2009-06-15 11:22:35.000000000 +1000 > +++ xen-unstable.hg/tools/python/xen/xend/XendDomainInfo.py 2009-06-15 > 11:23:43.000000000 +1000 > @@ -39,7 +39,8 @@ from xen.util import asserts, auxbin > from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype > import xen.util.xsm.xsm as security > from xen.util import xsconstants > -from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp > +from xen.util.pci import serialise_pci_opts, pci_opts_list_to_sxp, \ > + pci_dict_to_bdf_str, pci_dict_to_xc_str > > from xen.xend import balloon, sxp, uuid, image, arch > from xen.xend import XendOptions, XendNode, XendConfig > @@ -310,9 +311,8 @@ def do_FLR(domid): > dev_str_list = get_assigned_pci_devices(domid) > > for dev_str in dev_str_list: > - (dom, b, d, f) = parse_pci_name(dev_str) > try: > - dev = PciDevice(dom, b, d, f) > + dev = PciDevice(parse_pci_name(dev_str)) > except Exception, e: > raise VmError("pci: failed to locate device and "+ > "parse it''s resources - "+str(e)) > @@ -652,23 +652,15 @@ class XendDomainInfo: > raise VmError("device is already inserted") > > # Test whether the devices can be assigned with VT-d > - pci_str = "%s, %s, %s, %s" % (new_dev[''domain''], > - new_dev[''bus''], > - new_dev[''slot''], > - new_dev[''func'']) > - bdf = xc.test_assign_device(0, pci_str) > + 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?") > - bus = (bdf >> 16) & 0xff > - 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("fail to assign device(%s): maybe it has" > " already been assigned to other domain, or maybe" > - " it doesn''t exist." % (bus, dev, func)) > + " it doesn''t exist." % > pci_dict_to_bdf_str(new_dev)) > > # 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 > @@ -680,12 +672,8 @@ class XendDomainInfo: > # Test whether the device is owned by pciback. For instance, we can''t > # hotplug a device being used by Dom0 itself to an HVM guest. > from xen.xend.server.pciif import PciDevice, parse_pci_name > - domain = int(new_dev[''domain''],16) > - bus = int(new_dev[''bus''],16) > - dev = int(new_dev[''slot''],16) > - func = int(new_dev[''func''],16) > try: > - pci_device = PciDevice(domain, bus, dev, func) > + pci_device = PciDevice(new_dev) > except Exception, e: > raise VmError("pci: failed to locate device and "+ > "parse it''s resources - "+str(e)) > @@ -710,9 +698,8 @@ 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: > - (domain, bus, dev, func) = parse_pci_name(pci_str) > - dev_str = ''0x%x,0x%x,0x%x,0x%x'' % (domain, bus, dev, func) > - if xc.test_assign_device(0, dev_str) == 0: > + pci_dev = parse_pci_name(pci_str) > + if xc.test_assign_device(0, pci_dict_to_xc_str(pci_dev)) == 0: > continue > if not pci_str in assigned_pci_device_str_list: > raise VmError(("pci: failed to pci-attach %s to domain %s" + > \ > @@ -742,12 +729,9 @@ class XendDomainInfo: > if new_dev.has_key(''opts''): > opts = '','' + serialise_pci_opts(new_dev[''opts'']) > > - bdf_str = "%s:%s:%s.%s@%s%s" % (new_dev[''domain''], > - new_dev[''bus''], > - new_dev[''slot''], > - new_dev[''func''], > - new_dev[''vslot''], > - opts) > + bdf_str = "%s@%02x%s" % (pci_dict_to_bdf_str(new_dev), > + int(new_dev[''vslot''], 16), opts) > + log.debug("XendDomainInfo.hvm_pci_device_insert_dev: %s" % > bdf_str) > self.image.signalDeviceModel(''pci-ins'', ''pci-inserted'', bdf_str) > > vslot > xstransact.Read("/local/domain/0/device-model/%i/parameter" > @@ -864,9 +848,8 @@ class XendDomainInfo: > vslot = x[''vslot''] > break > if vslot == "": > - raise VmError("Device %04x:%02x:%02x.%01x is not > connected" > - % (int(dev[''domain''],16), > int(dev[''bus''],16), > - int(dev[''slot''],16), > int(dev[''func''],16))) > + raise VmError("Device %s is not connected" % > + pci_dict_to_bdf_str(dev)) > self.hvm_destroyPCIDevice(int(vslot, 16)) > # Update vslot > dev[''vslot''] = vslot > @@ -1152,12 +1135,8 @@ class XendDomainInfo: > # list of D''s co-assignment devices, DD is not assigned (to domN). > # > from xen.xend.server.pciif import PciDevice > - domain = int(x[''domain''],16) > - bus = int(x[''bus''],16) > - dev = int(x[''slot''],16) > - func = int(x[''func''],16) > try: > - pci_device = PciDevice(domain, bus, dev, func) > + pci_device = PciDevice(x) > except Exception, e: > raise VmError("pci: failed to locate device and "+ > "parse it''s resources - "+str(e)) > @@ -1172,9 +1151,8 @@ class XendDomainInfo: > )% (pci_device.name, self.info[''name_label''], pci_str)) > > > - bdf_str = "%s:%s:%s.%s" % (x[''domain''], x[''bus''], x[''slot''], > x[''func'']) > + bdf_str = pci_dict_to_bdf_str(x) > log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str) > - > if self.domid is not None: > self.image.signalDeviceModel(''pci-rem'', ''pci-removed'', bdf_str) > > @@ -1338,21 +1316,12 @@ class XendDomainInfo: > if self.domid is not None: > return get_assigned_pci_devices(self.domid) > > - dev_str_list = [] > dev_info = self._getDeviceInfo_pci(devid) > if dev_info is None: > - return dev_str_list > + return [] > dev_uuid = sxp.child_value(dev_info, ''uuid'') > pci_conf = self.info[''devices''][dev_uuid][1] > - pci_devs = pci_conf[''devs''] > - for pci_dev in pci_devs: > - domain = int(pci_dev[''domain''], 16) > - bus = int(pci_dev[''bus''], 16) > - slot = int(pci_dev[''slot''], 16) > - func = int(pci_dev[''func''], 16) > - dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) > - dev_str_list = dev_str_list + [dev_str] > - return dev_str_list > + return map(pci_dict_to_bdf_str, pci_conf[''devs'']) > > def setMemoryTarget(self, target): > """Set the memory target of this domain. > @@ -3909,12 +3878,12 @@ class XendDomainInfo: > target_dev = None > new_pci_sxp = [''pci''] > for dev in sxp.children(old_pci_sxp, ''dev''): > - domain = int(sxp.child_value(dev, ''domain''), 16) > - bus = int(sxp.child_value(dev, ''bus''), 16) > - slot = int(sxp.child_value(dev, ''slot''), 16) > - func = int(sxp.child_value(dev, ''func''), 16) > - name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) > - if ppci.get_name() == name: > + pci_dev = {} > + pci_dev[''domain''] = sxp.child_value(dev, ''domain'') > + pci_dev[''bus''] = sxp.child_value(dev, ''bus'') > + pci_dev[''slot''] = sxp.child_value(dev, ''slot'') > + pci_dev[''func''] = sxp.child_value(dev, ''func'') > + if ppci.get_name() == pci_dict_to_bdf_str(pci_dev): > target_dev = dev > else: > new_pci_sxp.append(dev) > Index: xen-unstable.hg/tools/python/xen/xend/XendNode.py > ==================================================================> --- xen-unstable.hg.orig/tools/python/xen/xend/XendNode.py 2009-06-15 > 11:20:35.000000000 +1000 > +++ xen-unstable.hg/tools/python/xen/xend/XendNode.py 2009-06-15 > 11:23:43.000000000 +1000 > @@ -340,8 +340,7 @@ class XendNode: > except KeyError: > pass > > - (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name) > - pci_dev = PciUtil.PciDevice(domain, bus, slot, func) > + pci_dev = PciUtil.PciDevice(PciUtil.parse_pci_name(pci_name)) > ppci_record = { > ''domain'': pci_dev.domain, > ''bus'': pci_dev.bus, > Index: xen-unstable.hg/tools/python/xen/xend/server/pciif.py > ==================================================================> --- xen-unstable.hg.orig/tools/python/xen/xend/server/pciif.py 2009-06-15 > 11:22:35.000000000 +1000 > +++ xen-unstable.hg/tools/python/xen/xend/server/pciif.py 2009-06-15 > 11:23:43.000000000 +1000 > @@ -130,13 +130,7 @@ class PciController(DevController): > log.debug(''Reconfiguring PCI device %s.'' % dev) > attaching = False > > - (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) > - self.setupOneDevice(domain, bus, slot, func) > + self.setupOneDevice(parse_pci_name(dev)) > > self.writeBackend(devid, ''dev-%i'' % devno, dev) > self.writeBackend(devid, ''state-%i'' % devno, > @@ -248,15 +242,13 @@ class PciController(DevController): > return > > #group string format xx:xx.x,xx:xx.x, > - devstr_len = group_str.find('','') > - for i in range(0, len(group_str), devstr_len + 1): > - (bus, slotfunc) = group_str[i:i + devstr_len].split('':'') > - (slot, func) = slotfunc.split(''.'') > - b = parse_hex(bus) > - d = parse_hex(slot) > - f = parse_hex(func) > + for i in group_str.split('',''): > + if i == '''': > + continue > + pci_dev = parse_pci_name(i) > + pci_dev[''domain''] = ''%04x'' % dev.domain > try: > - sdev = PciDevice(dev.domain, b, d, f) > + sdev = PciDevice(pci_dev) > except Exception, e: > #no dom0 drivers bound to sdev > continue > @@ -270,13 +262,13 @@ class PciController(DevController): > )%(sdev.name, dev.name)) > return > > - def setupOneDevice(self, domain, bus, slot, func): > + def setupOneDevice(self, pci_dev): > """ Attach I/O resources for device to frontend domain > """ > fe_domid = self.getDomid() > > try: > - dev = PciDevice(domain, bus, slot, func) > + dev = PciDevice(pci_dev) > except Exception, e: > raise VmError("pci: failed to locate device and "+ > "parse it''s resources - "+str(e)) > @@ -305,12 +297,11 @@ class PciController(DevController): > > 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) > + 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 (%x:%x.%x)" > - % (bus, slot, func)) > - log.debug("pci: assign device %x:%x.%x" % (bus, slot, func)) > + 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)) > @@ -366,23 +357,15 @@ class PciController(DevController): > 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)] > + pci_dev_list = config.get(''devs'', []) > + pci_str_list = map(pci_dict_to_bdf_str, pci_dev_list) > > if len(pci_str_list) != len(set(pci_str_list)): > raise VmError(''pci: duplicate devices specified in guest > config?'') > > - for (domain, bus, slot, func) in pci_dev_list: > + for pci_dev in pci_dev_list: > try: > - dev = PciDevice(domain, bus, slot, func) > + dev = PciDevice(pci_dev) > except Exception, e: > raise VmError("pci: failed to locate device and "+ > "parse it''s resources - "+str(e)) > @@ -427,9 +410,7 @@ class PciController(DevController): > dev.devs_check_driver(devs_str) > 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_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: > err_msg = ''pci: %s must be co-assigned to > the''+\ > @@ -453,13 +434,13 @@ class PciController(DevController): > return True > > > - def cleanupOneDevice(self, domain, bus, slot, func): > + def cleanupOneDevice(self, pci_dev): > """ Detach I/O resources for device from frontend domain > """ > fe_domid = self.getDomid() > > try: > - dev = PciDevice(domain, bus, slot, func) > + dev = PciDevice(pci_dev) > except Exception, e: > raise VmError("pci: failed to locate device and "+ > "parse it''s resources - "+str(e)) > @@ -476,12 +457,11 @@ class PciController(DevController): > # DMA transaction, etc > dev.do_FLR() > > - pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func) > - bdf = xc.deassign_device(fe_domid, pci_str) > + bdf = xc.deassign_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 deassign device from IOMMU (%x:%x.%x)" > - % (bus, slot, func)) > - log.debug("pci: Deassign device %x:%x.%x" % (bus, slot, func)) > + raise VmError("Failed to deassign device from IOMMU (%s)" % > pci_str) > + log.debug("pci: Deassign device %s" % pci_str) > > for (start, size) in dev.ioports: > log.debug(''pci: disabling ioport 0x%x/0x%x''%(start,size)) > @@ -530,15 +510,9 @@ class PciController(DevController): > 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) > + pci_dev = parse_pci_name(self.readBackend(devid, ''dev-%i'' % > i)) > # In HVM case, I/O resources are disabled in ioemu. > - self.cleanupOneDevice(domain, bus, slot, func) > + self.cleanupOneDevice(pci_dev) > # Remove xenstore nodes. > list = [''dev'', ''vdev'', ''state'', ''uuid'', ''vslot''] > if self.readBackend(devid, ''opts-%i'' % i) is not None: > > -- > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-16 11:20 UTC
Re: [Xen-devel] [patch 08/16] xend: pass-through: Common parse_pci_name()
On Tue, Jun 16, 2009 at 11:43:32AM +0100, Keir Fraser wrote:> This patch didn''t apply. I applied patches 1-7 and also patch 9 of your > series, but beyond that it was a bit of a trainwreck. Please refresh patch 8 > and patches 10+ and resend.Which version of what tree are you applying against? _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Jun-16 12:22 UTC
Re: [Xen-devel] [patch 08/16] xend: pass-through: Common parse_pci_name()
On 16/06/2009 12:20, "Simon Horman" <horms@verge.net.au> wrote:> On Tue, Jun 16, 2009 at 11:43:32AM +0100, Keir Fraser wrote: >> This patch didn''t apply. I applied patches 1-7 and also patch 9 of your >> series, but beyond that it was a bit of a trainwreck. Please refresh patch 8 >> and patches 10+ and resend. > > Which version of what tree are you applying against?Xen-unstable tip. Now c/s 19763. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Simon Horman
2009-Jun-16 12:38 UTC
Re: [Xen-devel] [patch 08/16] xend: pass-through: Common parse_pci_name()
On Tue, Jun 16, 2009 at 01:22:55PM +0100, Keir Fraser wrote:> On 16/06/2009 12:20, "Simon Horman" <horms@verge.net.au> wrote: > > > On Tue, Jun 16, 2009 at 11:43:32AM +0100, Keir Fraser wrote: > >> This patch didn''t apply. I applied patches 1-7 and also patch 9 of your > >> series, but beyond that it was a bit of a trainwreck. Please refresh patch 8 > >> and patches 10+ and resend. > > > > Which version of what tree are you applying against? > > Xen-unstable tip. Now c/s 19763.Thanks, I''ll fix things up and repost. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel