ia64/xen-unstable

changeset 17543:a0ebceaf41ff

MSI 4/6: remove io_mem permission for MSI-X, since MSI-X
facilities are allocted through and located in PCI BAR.

Signed-off-by: Jiang Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Shan Haitao <haitao.shan@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 01 10:32:10 2008 +0100 (2008-05-01)
parents 86c0353f19d0
children ad55c06c9bbc
files tools/python/xen/util/pci.py tools/python/xen/xend/server/pciif.py
line diff
     1.1 --- a/tools/python/xen/util/pci.py	Thu May 01 10:31:29 2008 +0100
     1.2 +++ b/tools/python/xen/util/pci.py	Thu May 01 10:32:10 2008 +0100
     1.3 @@ -7,6 +7,7 @@
     1.4  
     1.5  import sys
     1.6  import os, os.path
     1.7 +import resource
     1.8  
     1.9  PROC_MNT_PATH = '/proc/mounts'
    1.10  PROC_PCI_PATH = '/proc/bus/pci/devices'
    1.11 @@ -14,6 +15,7 @@ PROC_PCI_NUM_RESOURCES = 7
    1.12  
    1.13  SYSFS_PCI_DEVS_PATH = '/bus/pci/devices'
    1.14  SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'
    1.15 +SYSFS_PCI_DEV_CONFIG_PATH = '/config'
    1.16  SYSFS_PCI_DEV_IRQ_PATH = '/irq'
    1.17  SYSFS_PCI_DEV_DRIVER_DIR_PATH = '/driver'
    1.18  SYSFS_PCI_DEV_VENDOR_PATH = '/vendor'
    1.19 @@ -24,7 +26,20 @@ SYSFS_PCI_DEV_SUBDEVICE_PATH = '/subsyst
    1.20  PCI_BAR_IO = 0x01
    1.21  PCI_BAR_IO_MASK = ~0x03
    1.22  PCI_BAR_MEM_MASK = ~0x0f
    1.23 +PCI_STATUS_CAP_MASK = 0x10
    1.24 +PCI_STATUS_OFFSET = 0x6
    1.25 +PCI_CAP_OFFSET = 0x34
    1.26 +MSIX_BIR_MASK = 0x7
    1.27  
    1.28 +#Calculate PAGE_SHIFT: number of bits to shift an address to get the page number
    1.29 +PAGE_SIZE = resource.getpagesize()
    1.30 +PAGE_SHIFT = 0
    1.31 +t = PAGE_SIZE
    1.32 +while not (t&1):
    1.33 +    t>>=1
    1.34 +    PAGE_SHIFT+=1
    1.35 +
    1.36 +PAGE_MASK=~(PAGE_SIZE - 1)
    1.37  # Definitions from Linux: include/linux/pci.h
    1.38  def PCI_DEVFN(slot, func):
    1.39      return ((((slot) & 0x1f) << 3) | ((func) & 0x07))
    1.40 @@ -74,10 +89,72 @@ class PciDevice:
    1.41          self.device = None
    1.42          self.subvendor = None
    1.43          self.subdevice = None
    1.44 -
    1.45 +        self.msix = 0
    1.46 +        self.msix_iomem = []
    1.47          self.get_info_from_sysfs()
    1.48  
    1.49 +    def find_capability(self, type):
    1.50 +        try:
    1.51 +            sysfs_mnt = find_sysfs_mnt()
    1.52 +        except IOError, (errno, strerr):
    1.53 +            raise PciDeviceParseError(('Failed to locate sysfs mount: %s (%d)' %
    1.54 +                (PROC_PCI_PATH, strerr, errno)))
    1.55 +
    1.56 +        if sysfs_mnt == None:
    1.57 +            return False
    1.58 +        path = sysfs_mnt+SYSFS_PCI_DEVS_PATH+'/'+ \
    1.59 +               self.name+SYSFS_PCI_DEV_CONFIG_PATH
    1.60 +        try:
    1.61 +            conf_file = open(path, 'rb')
    1.62 +            conf_file.seek(PCI_STATUS_OFFSET)
    1.63 +            status = ord(conf_file.read(1))
    1.64 +            if status&PCI_STATUS_CAP_MASK:
    1.65 +                conf_file.seek(PCI_CAP_OFFSET)
    1.66 +                capa_pointer = ord(conf_file.read(1))
    1.67 +                while capa_pointer:
    1.68 +                    conf_file.seek(capa_pointer)
    1.69 +                    capa_id = ord(conf_file.read(1))
    1.70 +                    capa_pointer = ord(conf_file.read(1))
    1.71 +                    if capa_id == type:
    1.72 +                        # get the type
    1.73 +                        message_cont_lo = ord(conf_file.read(1))
    1.74 +                        message_cont_hi = ord(conf_file.read(1))
    1.75 +                        self.msix=1
    1.76 +                        self.msix_entries = message_cont_lo + \
    1.77 +                                            message_cont_hi << 8
    1.78 +                        t_off=conf_file.read(4)
    1.79 +                        p_off=conf_file.read(4)
    1.80 +                        self.table_offset=ord(t_off[0]) | (ord(t_off[1])<<8) | \
    1.81 +                                          (ord(t_off[2])<<16)|  \
    1.82 +                                          (ord(t_off[3])<<24)
    1.83 +                        self.pba_offset=ord(p_off[0]) | (ord(p_off[1]) << 8)| \
    1.84 +                                        (ord(p_off[2])<<16) | \
    1.85 +                                        (ord(p_off[3])<<24)
    1.86 +                        self.table_index = self.table_offset & MSIX_BIR_MASK
    1.87 +                        self.table_offset = self.table_offset & ~MSIX_BIR_MASK
    1.88 +                        self.pba_index = self.pba_offset & MSIX_BIR_MASK
    1.89 +                        self.pba_offset = self.pba_offset & ~MSIX_BIR_MASK
    1.90 +                        break
    1.91 +        except IOError, (errno, strerr):
    1.92 +            raise PciDeviceParseError(('Failed to locate sysfs mount: %s (%d)' %
    1.93 +                (PROC_PCI_PATH, strerr, errno)))
    1.94 +
    1.95 +    def remove_msix_iomem(self, index, start, size):
    1.96 +        if (index == self.table_index):
    1.97 +            table_start = start+self.table_offset
    1.98 +            table_end = table_start + self.msix_entries * 16
    1.99 +            table_start = table_start & PAGE_MASK
   1.100 +            table_end = (table_end + PAGE_SIZE) & PAGE_MASK
   1.101 +            self.msix_iomem.append((table_start, table_end-table_start))
   1.102 +        if (index==self.pba_index):
   1.103 +            pba_start = start + self.pba_offset
   1.104 +            pba_end = pba_start + self.msix_entries/8
   1.105 +            pba_start = pba_start & PAGE_MASK
   1.106 +            pba_end = (pba_end + PAGE_SIZE) & PAGE_MASK
   1.107 +            self.msix_iomem.append((pba_start, pba_end-pba_start))
   1.108 +
   1.109      def get_info_from_sysfs(self):
   1.110 +        self.find_capability(0x11)
   1.111          try:
   1.112              sysfs_mnt = find_sysfs_mnt()
   1.113          except IOError, (errno, strerr):
   1.114 @@ -108,6 +185,10 @@ class PciDevice:
   1.115                          self.ioports.append( (start,size) )
   1.116                      else:
   1.117                          self.iomem.append( (start,size) )
   1.118 +                    if (self.msix):
   1.119 +                        self.remove_msix_iomem(i, start, size)
   1.120 +
   1.121 +
   1.122  
   1.123          except IOError, (errno, strerr):
   1.124              raise PciDeviceParseError(('Failed to open & read %s: %s (%d)' %
     2.1 --- a/tools/python/xen/xend/server/pciif.py	Thu May 01 10:31:29 2008 +0100
     2.2 +++ b/tools/python/xen/xend/server/pciif.py	Thu May 01 10:32:10 2008 +0100
     2.3 @@ -278,6 +278,19 @@ class PciController(DevController):
     2.4                  raise VmError(('pci: failed to map irq on device '+
     2.5                              '%s - errno=%d')%(dev.name,rc))
     2.6  
     2.7 +        if dev.msix:
     2.8 +            for (start, size) in dev.msix_iomem:
     2.9 +                start_pfn = start>>PAGE_SHIFT
    2.10 +                nr_pfns = (size+(PAGE_SIZE-1))>>PAGE_SHIFT
    2.11 +                log.debug('pci-msix: remove permission for 0x%x/0x%x 0x%x/0x%x' % \
    2.12 +                         (start,size, start_pfn, nr_pfns))
    2.13 +                rc = xc.domain_iomem_permission(domid = fe_domid,
    2.14 +                                                first_pfn = start_pfn,
    2.15 +                                                nr_pfns = nr_pfns,
    2.16 +                                                allow_access = False)
    2.17 +                if rc<0:
    2.18 +                    raise VmError(('pci: failed to remove msi-x iomem'))
    2.19 +
    2.20          if dev.irq>0:
    2.21              log.debug('pci: enabling irq %d'%dev.irq)
    2.22              rc = xc.domain_irq_permission(domid =  fe_domid, pirq = dev.irq,