debuggers.hg
changeset 17574: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>
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,