ia64/xen-unstable

changeset 19006:13c8e6bac9ab

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>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 08 11:25:43 2009 +0000 (2009-01-08)
parents 9671a4d66f40
children 989bd3f2fd72
files tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/pciif.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Jan 08 11:25:06 2009 +0000
     1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Jan 08 11:25:43 2009 +0000
     1.3 @@ -696,10 +696,17 @@ class XendDomainInfo:
     1.4                      " assigned to other domain.' \
     1.5                      )% (pci_device.name, self.domid, pci_str))
     1.6  
     1.7 -        bdf_str = "%s:%s:%s.%s@%s" % (new_dev['domain'],
     1.8 +        opts = ''
     1.9 +        if 'opts' in new_dev and len(new_dev['opts']) > 0:
    1.10 +            config_opts = new_dev['opts']
    1.11 +            config_opts = map(lambda (x, y): x+'='+y, config_opts)
    1.12 +            opts = ',' + reduce(lambda x, y: x+','+y, config_opts)
    1.13 +
    1.14 +        bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'],
    1.15                  new_dev['bus'],
    1.16                  new_dev['slot'],
    1.17                  new_dev['func'],
    1.18 +                opts,
    1.19                  new_dev['vslt'])
    1.20          self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
    1.21  
    1.22 @@ -2234,7 +2241,11 @@ class XendDomainInfo:
    1.23          xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
    1.24  
    1.25          # Test whether the devices can be assigned with VT-d
    1.26 -        pci_str = str(self.info["platform"].get("pci"))
    1.27 +        pci = self.info["platform"].get("pci")
    1.28 +        pci_str = ''
    1.29 +        if pci and len(pci) > 0:
    1.30 +            pci = map(lambda x: x[0:4], pci)  # strip options 
    1.31 +            pci_str = str(pci)
    1.32          if hvm and pci_str:
    1.33              bdf = xc.test_assign_device(self.domid, pci_str)
    1.34              if bdf != 0:
     2.1 --- a/tools/python/xen/xend/server/pciif.py	Thu Jan 08 11:25:06 2009 +0000
     2.2 +++ b/tools/python/xen/xend/server/pciif.py	Thu Jan 08 11:25:43 2009 +0000
     2.3 @@ -75,6 +75,12 @@ class PciController(DevController):
     2.4              slot = parse_hex(pci_config.get('slot', 0))
     2.5              func = parse_hex(pci_config.get('func', 0))            
     2.6  
     2.7 +            opts = pci_config.get('opts', '')
     2.8 +            if len(opts) > 0:
     2.9 +                opts = map(lambda (x, y): x+'='+y, opts)
    2.10 +                opts = reduce(lambda x, y: x+','+y, opts)
    2.11 +                back['opts-%i' % pcidevid] = opts
    2.12 +
    2.13              vslt = pci_config.get('vslt')
    2.14              if vslt is not None:
    2.15                  vslots = vslots + vslt + ";"
    2.16 @@ -108,6 +114,9 @@ class PciController(DevController):
    2.17                  dev = back['dev-%i' % i]
    2.18                  state = states[i]
    2.19                  uuid = back['uuid-%i' %i]
    2.20 +                opts = ''
    2.21 +                if 'opts-%i' % i in back:
    2.22 +                    opts = back['opts-%i' % i]
    2.23              except:
    2.24                  raise XendError('Error reading config')
    2.25  
    2.26 @@ -129,6 +138,8 @@ class PciController(DevController):
    2.27                  self.writeBackend(devid, 'state-%i' % (num_olddevs + i),
    2.28                                    str(xenbusState['Initialising']))
    2.29                  self.writeBackend(devid, 'uuid-%i' % (num_olddevs + i), uuid)
    2.30 +                if len(opts) > 0:
    2.31 +                    self.writeBackend(devid, 'opts-%i' % (num_olddevs + i), opts)
    2.32                  self.writeBackend(devid, 'num_devs', str(num_olddevs + i + 1))
    2.33  
    2.34                  # Update vslots
    2.35 @@ -540,6 +551,9 @@ class PciController(DevController):
    2.36                  self.removeBackend(devid, 'vdev-%i' % i)
    2.37                  self.removeBackend(devid, 'state-%i' % i)
    2.38                  self.removeBackend(devid, 'uuid-%i' % i)
    2.39 +                tmpopts = self.readBackend(devid, 'opts-%i' % i)
    2.40 +                if tmpopts is not None:
    2.41 +                    self.removeBackend(devid, 'opts-%i' % i)
    2.42              else:
    2.43                  if new_num_devs != i:
    2.44                      tmpdev = self.readBackend(devid, 'dev-%i' % i)
    2.45 @@ -556,6 +570,9 @@ class PciController(DevController):
    2.46                      tmpuuid = self.readBackend(devid, 'uuid-%i' % i)
    2.47                      self.writeBackend(devid, 'uuid-%i' % new_num_devs, tmpuuid)
    2.48                      self.removeBackend(devid, 'uuid-%i' % i)
    2.49 +                    tmpopts = self.readBackend(devid, 'opts-%i' % i)
    2.50 +                    if tmpopts is not None:
    2.51 +                        self.removeBackend(devid, 'opts-%i' % i)
    2.52                  new_num_devs = new_num_devs + 1
    2.53  
    2.54          self.writeBackend(devid, 'num_devs', str(new_num_devs))
     3.1 --- a/tools/python/xen/xm/create.py	Thu Jan 08 11:25:06 2009 +0000
     3.2 +++ b/tools/python/xen/xm/create.py	Thu Jan 08 11:25:43 2009 +0000
     3.3 @@ -667,9 +667,20 @@ def configure_pci(config_devs, vals):
     3.4      """Create the config for pci devices.
     3.5      """
     3.6      config_pci = []
     3.7 -    for (domain, bus, slot, func) in vals.pci:
     3.8 -        config_pci.append(['dev', ['domain', domain], ['bus', bus], \
     3.9 -                        ['slot', slot], ['func', func]])
    3.10 +    for (domain, bus, slot, func, opts) in vals.pci:
    3.11 +        config_pci_opts = []
    3.12 +        d = comma_sep_kv_to_dict(opts)
    3.13 +
    3.14 +        def f(k):
    3.15 +            config_pci_opts.append([k, d[k]])
    3.16 +
    3.17 +        config_pci_bdf = ['dev', ['domain', domain], ['bus', bus], \
    3.18 +                          ['slot', slot], ['func', func]]
    3.19 +        map(f, d.keys())
    3.20 +        if len(config_pci_opts)>0:
    3.21 +            config_pci_bdf.append(['opts', config_pci_opts])
    3.22 +
    3.23 +        config_pci.append(config_pci_bdf)
    3.24  
    3.25      if len(config_pci)>0:
    3.26          config_pci.insert(0, 'pci')
    3.27 @@ -991,14 +1002,18 @@ def preprocess_pci(vals):
    3.28          pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
    3.29                  r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
    3.30                  r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
    3.31 -                r"(?P<func>[0-7])$", pci_dev_str)
    3.32 +                r"(?P<func>[0-7])" + \
    3.33 +                r"(,(?P<opts>.*))?$", pci_dev_str)
    3.34          if pci_match!=None:
    3.35 -            pci_dev_info = pci_match.groupdict('0')
    3.36 +            pci_dev_info = pci_match.groupdict('')
    3.37 +            if pci_dev_info['domain']=='':
    3.38 +                pci_dev_info['domain']='0'
    3.39              try:
    3.40                  pci.append( ('0x'+pci_dev_info['domain'], \
    3.41                          '0x'+pci_dev_info['bus'], \
    3.42                          '0x'+pci_dev_info['slot'], \
    3.43 -                        '0x'+pci_dev_info['func']))
    3.44 +                        '0x'+pci_dev_info['func'], \
    3.45 +                        pci_dev_info['opts']))
    3.46              except IndexError:
    3.47                  err('Error in PCI slot syntax "%s"'%(pci_dev_str))
    3.48      vals.pci = pci
     4.1 --- a/tools/python/xen/xm/main.py	Thu Jan 08 11:25:06 2009 +0000
     4.2 +++ b/tools/python/xen/xm/main.py	Thu Jan 08 11:25:43 2009 +0000
     4.3 @@ -187,7 +187,7 @@ SUBCOMMAND_HELP = {
     4.4      'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
     4.5      'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
     4.6      'vtpm-list'     :  ('<Domain> [--long]', 'List virtual TPM devices.'),
     4.7 -    'pci-attach'    :  ('<Domain> <domain:bus:slot.func> [virtual slot]',
     4.8 +    'pci-attach'    :  ('[-o|--options=<opt>] <Domain> <domain:bus:slot.func> [virtual slot]',
     4.9                          'Insert a new pass-through pci device.'),
    4.10      'pci-detach'    :  ('<Domain> <domain:bus:slot.func>',
    4.11                          'Remove a domain\'s pass-through pci device.'),
    4.12 @@ -2428,7 +2428,7 @@ def xm_network_attach(args):
    4.13              vif.append(vif_param)
    4.14          server.xend.domain.device_create(dom, vif)
    4.15  
    4.16 -def parse_pci_configuration(args, state):
    4.17 +def parse_pci_configuration(args, state, opts = ''):
    4.18      dom = args[0]
    4.19      pci_dev_str = args[1]
    4.20      if len(args) == 3:
    4.21 @@ -2443,12 +2443,17 @@ def parse_pci_configuration(args, state)
    4.22      if pci_match == None:
    4.23          raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
    4.24      pci_dev_info = pci_match.groupdict('0')
    4.25 +
    4.26      try:
    4.27 -        pci.append(['dev', ['domain', '0x'+ pci_dev_info['domain']], \
    4.28 +        pci_bdf =['dev', ['domain', '0x'+ pci_dev_info['domain']], \
    4.29                  ['bus', '0x'+ pci_dev_info['bus']],
    4.30                  ['slot', '0x'+ pci_dev_info['slot']],
    4.31                  ['func', '0x'+ pci_dev_info['func']],
    4.32 -                ['vslt', '0x%x' % int(vslt, 16)]])
    4.33 +                ['vslt', '0x%x' % int(vslt, 16)]]
    4.34 +        if len(opts) > 0:
    4.35 +            pci_bdf.append(['opts', opts])
    4.36 +        pci.append(pci_bdf)
    4.37 +
    4.38      except:
    4.39          raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
    4.40      pci.append(['state', state])
    4.41 @@ -2456,8 +2461,22 @@ def parse_pci_configuration(args, state)
    4.42      return (dom, pci)
    4.43  
    4.44  def xm_pci_attach(args):
    4.45 -    arg_check(args, 'pci-attach', 2, 3)
    4.46 -    (dom, pci) = parse_pci_configuration(args, 'Initialising')
    4.47 +    config_pci_opts = []
    4.48 +    (options, params) = getopt.gnu_getopt(args, 'o:', ['options='])
    4.49 +    for (k, v) in options:
    4.50 +        if k in ('-o', '--options'):
    4.51 +            if len(v.split('=')) != 2:
    4.52 +                err("Invalid pci attach option: %s" % v)
    4.53 +                usage('pci-attach')
    4.54 +            config_pci_opts.append(v.split('='))
    4.55 +
    4.56 +    n = len([i for i in params if i != '--'])
    4.57 +    if n < 2 or n > 3:
    4.58 +        err("Invalid argument for 'xm pci-attach'")
    4.59 +        usage('pci-attach')
    4.60 +
    4.61 +    (dom, pci) = parse_pci_configuration(params, 'Initialising',
    4.62 +                     config_pci_opts)
    4.63  
    4.64      if serverType == SERVER_XEN_API:
    4.65