def get_page(self): page, page_sz = super(IOMemMgr, self).get_page() first_paddr = self.get_paddr(page) for i in range(0, page_sz, 4096): assert self.get_paddr(page + i) == (first_paddr + i) dma_map = c.vfio_iommu_type1_dma_map() dma_map.argsz = c.sizeof(c.vfio_iommu_type1_dma_map) dma_map.vaddr = page dma_map.size = page_sz dma_map.iova = self.get_paddr(page) dma_map.flags = c.VFIO_DMA_MAP_FLAG_READ | c.VFIO_DMA_MAP_FLAG_WRITE res = c.ioctl(self.container, c.VFIO_IOMMU_MAP_DMA, c.byref(dma_map)) e = c.errno.value while res: if e != c.EAGAIN: raise Exception( "iommu dma map failed, errno: %x (whereas EAGAIN is %x" % (e, c.EAGAIN)) res = c.ioctl(self.container, c.VFIO_IOMMU_MAP_DMA, c.byref(dma_map)) e = c.errno.value print "[+] mapped page sz %d at vaddr %x paddr %x for dma" % ( page_sz, page, dma_map.iova) return page, page_sz
def _dev_open(self): print "[+] opening vfio group" group = os.open("/dev/vfio/%d" % self.groupno, os.O_RDWR) group_status = c.vfio_group_status() group_status.argsz = c.sizeof(c.vfio_group_status) ioctl(group, c.VFIO_GROUP_GET_STATUS, group_status) if not (group_status.flags & c.VFIO_GROUP_FLAGS_VIABLE): raise Exception("vfio group %d is not viable" % self.groupno) self.group = group ioctl(group, c.VFIO_GROUP_SET_CONTAINER, struct.pack("I", self.container)) ioctl(self.container, c.VFIO_SET_IOMMU, c.VFIO_TYPE1_IOMMU) iommu_info = c.vfio_iommu_type1_info() iommu_info.argsz = c.sizeof(c.vfio_iommu_type1_info) ioctl(self.container, c.VFIO_IOMMU_GET_INFO, iommu_info) self.iommu_info = iommu_info print "[+] opening vfio device" device = c.ioctl(group, c.VFIO_GROUP_GET_DEVICE_FD, self.bdf) self.device = device device_info = c.vfio_device_info() device_info.argsz = c.sizeof(c.vfio_device_info) ioctl(device, c.VFIO_DEVICE_GET_INFO, device_info) self.device_info = device_info self.show_regions() self.show_irqs() self.setup_irqs()
def get_page(self): page, page_sz = super(IOMemMgr, self).get_page() first_paddr = self.get_paddr(page) for i in range(0, page_sz, 4096): assert self.get_paddr(page + i) == (first_paddr + i) dma_map = c.vfio_iommu_type1_dma_map() dma_map.argsz = c.sizeof(c.vfio_iommu_type1_dma_map) dma_map.vaddr = page dma_map.size = page_sz dma_map.iova = self.get_paddr(page) dma_map.flags = c.VFIO_DMA_MAP_FLAG_READ | c.VFIO_DMA_MAP_FLAG_WRITE res = c.ioctl(self.container, c.VFIO_IOMMU_MAP_DMA, c.byref(dma_map)) e = c.errno.value while res: if e != c.EAGAIN: raise Exception("iommu dma map failed, errno: %x (whereas EAGAIN is %x" % (e, c.EAGAIN)) res = c.ioctl(self.container, c.VFIO_IOMMU_MAP_DMA, c.byref(dma_map)) e = c.errno.value print "[+] mapped page sz %d at vaddr %x paddr %x for dma" % (page_sz, page, dma_map.iova) return page, page_sz
def _dev_open(self): print "[+] opening vfio group" group = os.open("/dev/vfio/%d" % self.groupno, os.O_RDWR) group_status = c.vfio_group_status() group_status.argsz = c.sizeof(c.vfio_group_status) ioctl(group, c.VFIO_GROUP_GET_STATUS, group_status) if not (group_status.flags & c.VFIO_GROUP_FLAGS_VIABLE): raise Exception("vfio group %d is not viable" % self.groupno) self.group = group ioctl(group, c.VFIO_GROUP_SET_CONTAINER, struct.pack("I", self.container)) ioctl(self.container, c.VFIO_SET_IOMMU, c.VFIO_TYPE1_IOMMU) iommu_info = c.vfio_iommu_type1_info() iommu_info.argsz = c.sizeof(c.vfio_iommu_type1_info) ioctl(self.container, c.VFIO_IOMMU_GET_INFO, iommu_info) self.iommu_info = iommu_info print "[+] opening vfio device" device = c.ioctl(group, c.VFIO_GROUP_GET_DEVICE_FD, self.bdf) self.device = device device_info = c.vfio_device_info() device_info.argsz = c.sizeof(c.vfio_device_info) ioctl(device, c.VFIO_DEVICE_GET_INFO, device_info) print "[+] enumerating vfio device regions" self.regions = [] for i in range(device_info.num_regions - 1): r = c.vfio_region_info() r.argsz = c.sizeof(c.vfio_region_info) r.index = i ioctl(device, c.VFIO_DEVICE_GET_REGION_INFO, r) self.regions += [r] flags = "" if r.flags & c.VFIO_REGION_INFO_FLAG_READ: flags += "R" if r.flags & c.VFIO_REGION_INFO_FLAG_WRITE: flags += "W" if r.flags & c.VFIO_REGION_INFO_FLAG_MMAP: flags += "M" t = "region %d" % r.index if i == c.VFIO_PCI_BAR0_REGION_INDEX: bar0 = c.mmap(0, r.size, c.PROT_READ | c.PROT_WRITE, c.MAP_SHARED | c.MAP_LOCKED, device, r.offset) self.bar0 = bar0 self.bar0_sz = r.size t = "pci bar 0" elif i == c.VFIO_PCI_BAR2_REGION_INDEX: bar2 = c.mmap64(0, r.size, c.PROT_READ | c.PROT_WRITE, c.MAP_PRIVATE, device, r.offset) if 0xffffffffffffffff != bar2: self.bar2 = bar2 self.bar2_sz = r.size t = "pci bar 2" elif i == c.VFIO_PCI_CONFIG_REGION_INDEX: self.config_offset = r.offset t = "pci config" print "[*] %s [%s]: size %04x, ofs %x, resv %x" % (t, flags, r.size, r.offset, r.resv) self.show_irqs() print "[+] enabling msi-x" irq_set = c.vfio_irq_set() c.resize(irq_set, c.sizeof(c.vfio_irq_set) + c.sizeof(c.c_uint)) irq_set.argsz = c.sizeof(c.vfio_irq_set) + c.sizeof(c.c_uint) irq_set.index = c.VFIO_PCI_MSIX_IRQ_INDEX irq_set.start = 0 irq_set.count = 1 irq_set.flags = c.VFIO_IRQ_SET_DATA_EVENTFD | c.VFIO_IRQ_SET_ACTION_TRIGGER self.eventfd = c.eventfd(0, 0) c.cast(c.addressof(irq_set.data), c.POINTER(c.c_uint))[0] = self.eventfd ioctl(self.device, c.VFIO_DEVICE_SET_IRQS, irq_set)