mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
pci: add pci option support for XML-RPC server
Allow the per-device options for passthrough pci devices
for exmaple, in domain config file:
pci = ['01:00.0,opt1=val1,opt2=val2', '01:00.1' ]
or in the PCI hotplug case:
xm pci-attach -o opt1=val1 --options=opt2=val2 <domid> 01:00.0 6
This patch is for xml-rpc server
Signed-off-by: Qing He <qing.he@intel.com>
This commit is contained in:
1 parent
11f8ac5ebf
commit
925b2ca585
4 files changed
+76
-14
No files matched your search
@@ -696,10 +696,17 @@ class XendDomainInfo:
|
||||
" assigned to other domain.' \
|
||||
)% (pci_device.name, self.domid, pci_str))
|
||||
|
||||
bdf_str = "%s:%s:%s.%s@%s" % (new_dev['domain'],
|
||||
opts = ''
|
||||
if 'opts' in new_dev and len(new_dev['opts']) > 0:
|
||||
config_opts = new_dev['opts']
|
||||
config_opts = map(lambda (x, y): x+'='+y, config_opts)
|
||||
opts = ',' + reduce(lambda x, y: x+','+y, config_opts)
|
||||
|
||||
bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'],
|
||||
new_dev['bus'],
|
||||
new_dev['slot'],
|
||||
new_dev['func'],
|
||||
opts,
|
||||
new_dev['vslt'])
|
||||
self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
|
||||
|
||||
@@ -2234,7 +2241,11 @@ class XendDomainInfo:
|
||||
xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
|
||||
|
||||
# Test whether the devices can be assigned with VT-d
|
||||
pci_str = str(self.info["platform"].get("pci"))
|
||||
pci = self.info["platform"].get("pci")
|
||||
pci_str = ''
|
||||
if pci and len(pci) > 0:
|
||||
pci = map(lambda x: x[0:4], pci) # strip options
|
||||
pci_str = str(pci)
|
||||
if hvm and pci_str:
|
||||
bdf = xc.test_assign_device(self.domid, pci_str)
|
||||
if bdf != 0:
|
||||
|
||||
@@ -75,6 +75,12 @@ class PciController(DevController):
|
||||
slot = parse_hex(pci_config.get('slot', 0))
|
||||
func = parse_hex(pci_config.get('func', 0))
|
||||
|
||||
opts = pci_config.get('opts', '')
|
||||
if len(opts) > 0:
|
||||
opts = map(lambda (x, y): x+'='+y, opts)
|
||||
opts = reduce(lambda x, y: x+','+y, opts)
|
||||
back['opts-%i' % pcidevid] = opts
|
||||
|
||||
vslt = pci_config.get('vslt')
|
||||
if vslt is not None:
|
||||
vslots = vslots + vslt + ";"
|
||||
@@ -108,6 +114,9 @@ class PciController(DevController):
|
||||
dev = back['dev-%i' % i]
|
||||
state = states[i]
|
||||
uuid = back['uuid-%i' %i]
|
||||
opts = ''
|
||||
if 'opts-%i' % i in back:
|
||||
opts = back['opts-%i' % i]
|
||||
except:
|
||||
raise XendError('Error reading config')
|
||||
|
||||
@@ -129,6 +138,8 @@ class PciController(DevController):
|
||||
self.writeBackend(devid, 'state-%i' % (num_olddevs + i),
|
||||
str(xenbusState['Initialising']))
|
||||
self.writeBackend(devid, 'uuid-%i' % (num_olddevs + i), uuid)
|
||||
if len(opts) > 0:
|
||||
self.writeBackend(devid, 'opts-%i' % (num_olddevs + i), opts)
|
||||
self.writeBackend(devid, 'num_devs', str(num_olddevs + i + 1))
|
||||
|
||||
# Update vslots
|
||||
@@ -540,6 +551,9 @@ class PciController(DevController):
|
||||
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)
|
||||
else:
|
||||
if new_num_devs != i:
|
||||
tmpdev = self.readBackend(devid, 'dev-%i' % i)
|
||||
@@ -556,6 +570,9 @@ class PciController(DevController):
|
||||
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
|
||||
|
||||
self.writeBackend(devid, 'num_devs', str(new_num_devs))
|
||||
|
||||
@@ -667,9 +667,20 @@ def configure_pci(config_devs, vals):
|
||||
"""Create the config for pci devices.
|
||||
"""
|
||||
config_pci = []
|
||||
for (domain, bus, slot, func) in vals.pci:
|
||||
config_pci.append(['dev', ['domain', domain], ['bus', bus], \
|
||||
['slot', slot], ['func', func]])
|
||||
for (domain, bus, slot, func, opts) in vals.pci:
|
||||
config_pci_opts = []
|
||||
d = comma_sep_kv_to_dict(opts)
|
||||
|
||||
def f(k):
|
||||
config_pci_opts.append([k, d[k]])
|
||||
|
||||
config_pci_bdf = ['dev', ['domain', domain], ['bus', bus], \
|
||||
['slot', slot], ['func', func]]
|
||||
map(f, d.keys())
|
||||
if len(config_pci_opts)>0:
|
||||
config_pci_bdf.append(['opts', config_pci_opts])
|
||||
|
||||
config_pci.append(config_pci_bdf)
|
||||
|
||||
if len(config_pci)>0:
|
||||
config_pci.insert(0, 'pci')
|
||||
@@ -991,14 +1002,18 @@ def preprocess_pci(vals):
|
||||
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)
|
||||
r"(?P<func>[0-7])" + \
|
||||
r"(,(?P<opts>.*))?$", pci_dev_str)
|
||||
if pci_match!=None:
|
||||
pci_dev_info = pci_match.groupdict('0')
|
||||
pci_dev_info = pci_match.groupdict('')
|
||||
if pci_dev_info['domain']=='':
|
||||
pci_dev_info['domain']='0'
|
||||
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['func'], \
|
||||
pci_dev_info['opts']))
|
||||
except IndexError:
|
||||
err('Error in PCI slot syntax "%s"'%(pci_dev_str))
|
||||
vals.pci = pci
|
||||
|
||||
@@ -187,7 +187,7 @@ SUBCOMMAND_HELP = {
|
||||
'vnet-delete' : ('<VnetId>', 'Delete a Vnet.'),
|
||||
'vnet-list' : ('[-l|--long]', 'List Vnets.'),
|
||||
'vtpm-list' : ('<Domain> [--long]', 'List virtual TPM devices.'),
|
||||
'pci-attach' : ('<Domain> <domain:bus:slot.func> [virtual slot]',
|
||||
'pci-attach' : ('[-o|--options=<opt>] <Domain> <domain:bus:slot.func> [virtual slot]',
|
||||
'Insert a new pass-through pci device.'),
|
||||
'pci-detach' : ('<Domain> <domain:bus:slot.func>',
|
||||
'Remove a domain\'s pass-through pci device.'),
|
||||
@@ -2428,7 +2428,7 @@ def xm_network_attach(args):
|
||||
vif.append(vif_param)
|
||||
server.xend.domain.device_create(dom, vif)
|
||||
|
||||
def parse_pci_configuration(args, state):
|
||||
def parse_pci_configuration(args, state, opts = ''):
|
||||
dom = args[0]
|
||||
pci_dev_str = args[1]
|
||||
if len(args) == 3:
|
||||
@@ -2443,12 +2443,17 @@ def parse_pci_configuration(args, state):
|
||||
if pci_match == None:
|
||||
raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
|
||||
pci_dev_info = pci_match.groupdict('0')
|
||||
|
||||
try:
|
||||
pci.append(['dev', ['domain', '0x'+ pci_dev_info['domain']], \
|
||||
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']],
|
||||
['vslt', '0x%x' % int(vslt, 16)]])
|
||||
['vslt', '0x%x' % int(vslt, 16)]]
|
||||
if len(opts) > 0:
|
||||
pci_bdf.append(['opts', opts])
|
||||
pci.append(pci_bdf)
|
||||
|
||||
except:
|
||||
raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
|
||||
pci.append(['state', state])
|
||||
@@ -2456,8 +2461,22 @@ def parse_pci_configuration(args, state):
|
||||
return (dom, pci)
|
||||
|
||||
def xm_pci_attach(args):
|
||||
arg_check(args, 'pci-attach', 2, 3)
|
||||
(dom, pci) = parse_pci_configuration(args, 'Initialising')
|
||||
config_pci_opts = []
|
||||
(options, params) = getopt.gnu_getopt(args, 'o:', ['options='])
|
||||
for (k, v) in options:
|
||||
if k in ('-o', '--options'):
|
||||
if len(v.split('=')) != 2:
|
||||
err("Invalid pci attach option: %s" % v)
|
||||
usage('pci-attach')
|
||||
config_pci_opts.append(v.split('='))
|
||||
|
||||
n = len([i for i in params if i != '--'])
|
||||
if n < 2 or n > 3:
|
||||
err("Invalid argument for 'xm pci-attach'")
|
||||
usage('pci-attach')
|
||||
|
||||
(dom, pci) = parse_pci_configuration(params, 'Initialising',
|
||||
config_pci_opts)
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
|
||||
|
||||