WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [PCI] xend parses the user-space PCI back

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [PCI] xend parses the user-space PCI backend policy files and sends
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Jul 2006 16:22:03 +0000
Delivery-date: Fri, 28 Jul 2006 09:34:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 8cd5771109048d31fc650615073abe7ad6388772
# Parent  4f6d858ea570435f75527fa7f62a02e642ffbb69
[PCI] xend parses the user-space PCI backend policy files and sends
the corresponding fields to the PCI bus manager via sysfs nodes:

/sys/bus/pci/drivers/pciback/quirks
/sys/bus/pci/drivers/pciback/permissive

xend reads the policy file every time it creates a new domain that was
assigned a PCI device.

Signed-off-by: Chris Bookholt <hap10@xxxxxxxxxxxxxx>
---
 tools/python/xen/util/pci.py             |   97 ++++++++++----------
 tools/python/xen/xend/server/pciif.py    |    7 +
 tools/python/xen/xend/server/pciquirk.py |  145 +++++++++++++++++++++++++++++++
 3 files changed, 198 insertions(+), 51 deletions(-)

diff -r 4f6d858ea570 -r 8cd577110904 tools/python/xen/util/pci.py
--- a/tools/python/xen/util/pci.py      Fri Jul 28 12:56:10 2006 +0100
+++ b/tools/python/xen/util/pci.py      Fri Jul 28 12:57:55 2006 +0100
@@ -16,6 +16,10 @@ SYSFS_PCI_DEV_RESOURCE_PATH = '/resource
 SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'
 SYSFS_PCI_DEV_IRQ_PATH = '/irq'
 SYSFS_PCI_DEV_DRIVER_DIR_PATH = '/driver'
+SYSFS_PCI_DEV_VENDOR_PATH = '/vendor'
+SYSFS_PCI_DEV_DEVICE_PATH = '/device'
+SYSFS_PCI_DEV_SUBVENDOR_PATH = '/subsystem_vendor'
+SYSFS_PCI_DEV_SUBDEVICE_PATH = '/subsystem_device'
 
 PCI_BAR_IO = 0x01
 PCI_BAR_IO_MASK = ~0x03
@@ -66,9 +70,12 @@ class PciDevice:
         self.iomem = []
         self.ioports = []
         self.driver = None
+        self.vendor = None
+        self.device = None
+        self.subvendor = None
+        self.subdevice = None
 
-        if not self.get_info_from_sysfs():
-            self.get_info_from_proc()
+        self.get_info_from_sysfs()
 
     def get_info_from_sysfs(self):
         try:
@@ -85,7 +92,7 @@ class PciDevice:
         try:
             resource_file = open(path,'r')
 
-            for i in range(7):
+            for i in range(PROC_PCI_NUM_RESOURCES):
                 line = resource_file.readline()
                 sline = line.split()
                 if len(sline)<3:
@@ -122,53 +129,39 @@ class PciDevice:
             raise PciDeviceParseError(('Failed to read %s: %s (%d)' %
                 (path, strerr, errno)))
 
+        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
+                self.name+SYSFS_PCI_DEV_VENDOR_PATH
+        try:
+            self.vendor = int(open(path,'r').readline(), 16)
+        except IOError, (errno, strerr):
+            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
+                (path, strerr, errno)))
+
+        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
+                self.name+SYSFS_PCI_DEV_DEVICE_PATH
+        try:
+            self.device = int(open(path,'r').readline(), 16)
+        except IOError, (errno, strerr):
+            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
+                (path, strerr, errno)))
+
+        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
+                self.name+SYSFS_PCI_DEV_SUBVENDOR_PATH
+        try:
+            self.subvendor = int(open(path,'r').readline(), 16)
+        except IOError, (errno, strerr):
+            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
+                (path, strerr, errno)))
+
+        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
+                self.name+SYSFS_PCI_DEV_SUBDEVICE_PATH
+        try:
+            self.subdevice = int(open(path,'r').readline(), 16)
+        except IOError, (errno, strerr):
+            raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
+                (path, strerr, errno)))
+
         return True
-        
-    def get_info_from_proc(self):
-        bus_devfn = '%02x%02x' % (self.bus,PCI_DEVFN(self.slot,self.func))
-
-        # /proc/bus/pci/devices doesn't expose domains
-        if self.domain!=0:
-            raise PciDeviceParseError("Can't yet detect resource usage by "+
-                    "devices in other domains through proc!")
-
-        try:
-            proc_pci_file = open(PROC_PCI_PATH,'r')
-        except IOError, (errno, strerr):
-            raise PciDeviceParseError(('Failed to open %s: %s (%d)' %
-                (PROC_PCI_PATH, strerr, errno)))
-
-        for line in proc_pci_file:
-            sline = line.split()
-            if len(sline)<(PROC_PCI_NUM_RESOURCES*2+3):
-                continue
-
-            if sline[0]==bus_devfn:
-                self.dissect_proc_pci_line(sline)
-                break
-        else:
-            raise PciDeviceNotFoundError(self.domain, self.bus,
-                    self.slot, self.func)
-
-    def dissect_proc_pci_line(self, sline):
-        self.irq = int(sline[2],16)
-        start_idx = 3
-        for i in range(PROC_PCI_NUM_RESOURCES):
-            flags = int(sline[start_idx+i],16)
-            size = int(sline[start_idx+i+PROC_PCI_NUM_RESOURCES],16)
-            if flags&PCI_BAR_IO:
-                start = flags&PCI_BAR_IO_MASK
-                if start!=0:
-                    self.ioports.append( (start,size) )
-            else:
-                start = flags&PCI_BAR_MEM_MASK
-                if start!=0:
-                    self.iomem.append( (start,size) )
-
-        # detect driver module name
-        driver_idx = PROC_PCI_NUM_RESOURCES*2+3
-        if len(sline)>driver_idx:
-            self.driver = sline[driver_idx]
 
     def __str__(self):
         str = "PCI Device %s\n" % (self.name)
@@ -176,7 +169,11 @@ class PciDevice:
             str = str + "IO Port 0x%02x [size=%d]\n"%(start,size)
         for (start,size) in self.iomem:
             str = str + "IO Mem 0x%02x [size=%d]\n"%(start,size)
-        str = str + "IRQ %d"%(self.irq)
+        str = str + "IRQ %d\n"%(self.irq)
+        str = str + "Vendor ID 0x%04x\n"%(self.vendor)
+        str = str + "Device ID 0x%04x\n"%(self.device)
+        str = str + "Sybsystem Vendor ID 0x%04x\n"%(self.subvendor)
+        str = str + "Subsystem Device ID 0x%04x"%(self.subdevice)
         return str
 
 def main():
diff -r 4f6d858ea570 -r 8cd577110904 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Fri Jul 28 12:56:10 2006 +0100
+++ b/tools/python/xen/xend/server/pciif.py     Fri Jul 28 12:57:55 2006 +0100
@@ -32,6 +32,8 @@ from xen.util.pci import PciDevice
 from xen.util.pci import PciDevice
 import resource
 import re
+
+from xen.xend.server.pciquirk import *
 
 xc = xen.lowlevel.xc.xc()
 
@@ -150,7 +152,10 @@ class PciController(DevController):
                     "bind your slot/device to the PCI backend using sysfs" \
                     )%(dev.name))
 
-        for (start, size) in dev.ioports:
+        PCIQuirk(dev.vendor, dev.device, dev.subvendor, dev.subdevice, domain, 
+                bus, slot, func)
+
+       for (start, size) in dev.ioports:
             log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))
             rc = xc.domain_ioport_permission(dom = fe_domid, first_port = 
start,
                     nr_ports = size, allow_access = True)
diff -r 4f6d858ea570 -r 8cd577110904 tools/python/xen/xend/server/pciquirk.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/pciquirk.py  Fri Jul 28 12:57:55 2006 +0100
@@ -0,0 +1,145 @@
+from xen.xend.XendLogging import log
+from xen.xend.XendError import XendError
+import sys
+import os.path
+from xen.xend.sxp import *
+
+QUIRK_SYSFS_NODE = "/sys/bus/pci/drivers/pciback/quirks"
+QUIRK_CONFIG_FILE = "/etc/xen/xend-pci-quirks.sxp"
+PERMISSIVE_CONFIG_FILE = "/etc/xen/xend-pci-permissive.sxp"
+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)
+
+        self.quirks = self.__getQuirksByID( )
+
+       self.__sendQuirks( )
+       self.__sendPermDevs( )
+
+    def __matchPCIdev( self, list ):
+        ret = False
+        if list == None:
+            return False
+        for id in list:
+            if id.startswith( self.devid[:9] ): # id's vendor and device ID 
match
+                skey = id.split(':')
+                size = len(skey)
+                if (size == 2):                # subvendor/subdevice not 
suplied
+                    ret = True
+                    break
+                elif (size == 4):      # check subvendor/subdevice
+                    # check subvendor
+                   subven = '%04x' % self.subvendor
+                    if ((skey[2] != 'FFFF') and 
+                        (skey[2] != 'ffff') and 
+                        (skey[2] != subven)):
+                            continue
+                    # check subdevice
+                   subdev = '%04x' % self.subdevice
+                    if ((skey[3] != 'FFFF') and 
+                        (skey[3] != 'ffff') and 
+                        (skey[3] != subdev)):
+                            continue
+                    ret = True
+                    break
+                else:
+                    log.debug("WARNING: invalid configuration entry: %s" % id)
+                    ret = False
+                    break
+        return ret
+        
+    def __getQuirksByID( self ):
+        if os.path.exists(QUIRK_CONFIG_FILE):
+            try:
+                fin = file(QUIRK_CONFIG_FILE, 'rb')
+                try:
+                    pci_quirks_config = parse(fin)
+                finally:
+                    fin.close()
+                if pci_quirks_config is None:
+                    pci_quirks_config = ['xend-pci-quirks']
+                else:
+                    pci_quirks_config.insert(0, 'xend-pci-quirks')
+                self.pci_quirks_config = pci_quirks_config
+            except Exception, ex:
+                raise XendError("Reading config file %s: %s" %
+                               (QUIRK_CONFIG_FILE, str(ex)))
+        else:
+            log.info("Config file does not exist: %s" % QUIRK_CONFIG_FILE)
+            self.pci_quirks_config = ['xend-pci-quirks']
+
+        devices = children(self.pci_quirks_config)
+        for dev in devices:
+            ids = child_at(child(dev,'pci_ids'),0)
+            fields = child_at(child(dev,'pci_config_space_fields'),0)
+           if self.__matchPCIdev( ids ):
+                log.info("Quirks found for PCI device [%s]" % self.devid)
+                return fields
+
+        log.info("NO quirks found for PCI device [%s]" % self.devid)
+        return []
+
+    def __sendQuirks(self):
+        for quirk in self.quirks:
+            log.debug("Quirk Info: %04x:%02x:%02x.%1x-%s" % (self.domain,
+                   self.bus, self.slot, self.func, quirk))
+            try:
+                f = file(QUIRK_SYSFS_NODE ,"w")
+                f.write( "%04x:%02x:%02x.%1x-%s" % (self.domain, self.bus,
+                       self.slot, self.func, quirk) )
+                f.close()
+            except Exception, e:
+                raise VmError("pci: failed to open/write/close quirks sysfs " 
+ \
+                       "node - " + str(e))
+
+    def __devIsUnconstrained( self ):
+        if os.path.exists(PERMISSIVE_CONFIG_FILE):
+            try:
+                fin = file(PERMISSIVE_CONFIG_FILE, 'rb')
+                try:
+                    pci_perm_dev_config = parse(fin)
+                finally:
+                    fin.close()
+                if pci_perm_dev_config is None:
+                    pci_perm_dev_config = ['']
+                else:
+                    pci_perm_dev_config.insert(0, '')
+                self.pci_perm_dev_config = pci_perm_dev_config
+            except Exception, ex:
+                raise XendError("Reading config file %s: %s" %
+                               (PERMISSIVE_CONFIG_FILE,str(ex)))
+        else:
+            log.info("Config file does not exist: %s" % PERMISSIVE_CONFIG_FILE)
+            self.pci_perm_dev_config = ['xend-pci-perm-devs']
+
+        devices = child_at(child(pci_perm_dev_config, 
'unconstrained_dev_ids'),0)
+       if self.__matchPCIdev( devices ):
+            log.debug("Permissive mode enabled for PCI device [%s]" % 
self.devid)
+            return True
+        log.debug("Permissive mode NOT enabled for PCI device [%s]" % 
self.devid)
+        return False
+
+    def __sendPermDevs(self):
+       if self.__devIsUnconstrained( ):
+            log.debug("Unconstrained device: %04x:%02x:%02x.%1x" % 
(self.domain,
+                   self.bus, self.slot, self.func))
+            try:
+                f = file(PERMISSIVE_SYSFS_NODE ,"w")
+                f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus,
+                       self.slot, self.func) )
+                f.close()
+            except Exception, e:
+                raise VmError("pci: failed to open/write/close permissive " + \
+               "sysfs node: " + str(e))

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [PCI] xend parses the user-space PCI backend policy files and sends, Xen patchbot-unstable <=