Esempio n. 1
0
    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
Esempio n. 2
0
    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()
Esempio n. 3
0
    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
Esempio n. 4
0
    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()
Esempio n. 5
0
    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)