Ejemplo n.º 1
0
    def _open_device(self):
        self.cfgfd = os.open(self.dd + "/config", os.O_RDWR)
        try: self.barfd = os.open(self.dd + "/resource0_wc", os.O_RDWR)
        except: self.barfd = os.open(self.dd + "/resource0", os.O_RDWR)

        bar0 = c.mmap(0, 64 * 1024, c.PROT_READ | c.PROT_WRITE, c.MAP_SHARED | c.MAP_LOCKED, self.barfd, 0)
        if -1 == bar0: raise Exception("failed to mmap bar 0")
        self.bar0 = bar0

        try:
            self.barfd2 = os.open(self.dd + "/resource2_wc", os.O_RDWR)
            self.bar2 = c.mmap(0, 64 * 1024, c.PROT_READ | c.PROT_WRITE, c.MAP_SHARED | c.MAP_LOCKED, self.barfd2, 0)
        except:
            pass
Ejemplo n.º 2
0
    def _open_device(self):
        with file(self.dd + "/enable", "w") as f:
            f.write('1')
            self.cfgfd = os.open(self.dd + "/config", os.O_RDWR)
            try: self.barfd = os.open(self.dd + "/resource0_wc", os.O_RDWR)
            except: self.barfd = os.open(self.dd + "/resource0", os.O_RDWR)

            bar0 = c.mmap(0, 64 * 1024, c.PROT_READ | c.PROT_WRITE, c.MAP_SHARED | c.MAP_LOCKED, self.barfd, 0)
            if -1 == bar0: raise Exception("failed to mmap bar 0")
            self.bar0 = bar0

            try:
                self.barfd2 = os.open(self.dd + "/resource2_wc", os.O_RDWR)
                self.bar2 = c.mmap(0, 64 * 1024, c.PROT_READ | c.PROT_WRITE, c.MAP_SHARED | c.MAP_LOCKED, self.barfd2, 0)
            except:
                pass
Ejemplo n.º 3
0
 def __attempt_hugetlb(self):
     flags = c.MAP_ANONYMOUS | c.MAP_PRIVATE | c.MAP_LOCKED | c.MAP_HUGETLB
     flags |= (21 << c.MAP_HUGE_SHIFT)
     prot = c.PROT_READ | c.PROT_WRITE
     sz = 2048 * 1024
     a = c.mmap(0, sz, prot, flags, -1, 0)
     if a != c.MAP_FAILED:
         print "[+] huge pages available"
         c.munmap(a, sz)
         self._hugetlb_available = True
         self._hugetlb_pgsz = sz
     else:
         print "[-] huge pages unavailable"
         self._hugetlb_available = False
Ejemplo n.º 4
0
    def show_regions(self):
        print "[+] enumerating vfio device regions"
        self.regions = []
        for i in range(self.device_info.num_regions - 1):
            r = c.vfio_region_info()
            r.argsz = c.sizeof(c.vfio_region_info)
            r.index = i

            ioctl(self.device, c.VFIO_DEVICE_GET_REGION_INFO, r)
            if r.size == 0:
                continue
            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"

            if r.flags & c.VFIO_REGION_INFO_FLAG_CAPS:
                flags += "*"

            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, self.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, self.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"
            elif i == c.VFIO_PCI_ROM_REGION_INDEX:
                t = "rom bar"
            else:
                t += " (type 0x%x)" % i
            print "[*] %s [%s]: size %04x, ofs %x" % (t, flags, r.size,
                                                      r.offset)
Ejemplo n.º 5
0
    def show_regions(self):
        print "[+] enumerating vfio device regions"
        self.regions = []
        for i in range(self.device_info.num_regions - 1):
            r = c.vfio_region_info()
            r.argsz = c.sizeof(c.vfio_region_info)
            r.index = i

            ioctl(self.device, c.VFIO_DEVICE_GET_REGION_INFO, r)
            if r.size == 0:
                continue
            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"
                
            if r.flags & c.VFIO_REGION_INFO_FLAG_CAPS:
                flags += "*"

            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, self.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, self.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"
            elif i == c.VFIO_PCI_ROM_REGION_INDEX:
                t = "rom bar"
            else:
                t += " (type 0x%x)" % i
            print "[*] %s [%s]: size %04x, ofs %x" % (t, flags, r.size, r.offset)
Ejemplo n.º 6
0
 def __attempt_hugetlb(self):
     try:
         with open("/proc/sys/vm/nr_hugepages", "r+") as hp:
             a = int(hp.read())
             if a < 20:
                 hp.seek(0)
                 hp.write('20')
     except: pass
     flags = c.MAP_ANONYMOUS | c.MAP_PRIVATE | c.MAP_LOCKED | c.MAP_HUGETLB | c.MAP_32BIT
     flags |= (21 << c.MAP_HUGE_SHIFT)
     prot = c.PROT_READ | c.PROT_WRITE
     sz = 2048 * 1024
     a = c.mmap(0, sz, prot, flags, -1, 0)
     if a != c.MAP_FAILED:
         print "[+] huge pages available"
         c.munmap(a, sz)
         self._hugetlb_available = True
         self._hugetlb_pgsz = sz
     else:
         print "[-] huge pages unavailable"
         self._hugetlb_available = False
Ejemplo n.º 7
0
 def __attempt_hugetlb(self):
     try:
         with open("/proc/sys/vm/nr_hugepages", "r+") as hp:
             a = int(hp.read())
             if a < 20:
                 hp.seek(0)
                 hp.write('20')
     except:
         pass
     flags = c.MAP_ANONYMOUS | c.MAP_PRIVATE | c.MAP_LOCKED | c.MAP_HUGETLB | c.MAP_32BIT
     flags |= (21 << c.MAP_HUGE_SHIFT)
     prot = c.PROT_READ | c.PROT_WRITE
     sz = 2048 * 1024
     a = c.mmap(0, sz, prot, flags, -1, 0)
     if a != c.MAP_FAILED:
         print "[+] huge pages available"
         c.munmap(a, sz)
         self._hugetlb_available = True
         self._hugetlb_pgsz = sz
     else:
         print "[-] huge pages unavailable"
         self._hugetlb_available = False
Ejemplo n.º 8
0
    def get_page(self):
        if self._hugetlb_available:
            assert self.page_sz == self._hugetlb_pgsz
            prot = c.PROT_READ | c.PROT_WRITE
            flags = c.MAP_ANONYMOUS | c.MAP_PRIVATE | c.MAP_LOCKED | c.MAP_HUGETLB | c.MAP_32BIT
            flags |= (21 << c.MAP_HUGE_SHIFT)
            sz = self._hugetlb_pgsz
            page = c.mmap(0, sz, prot, flags, -1, 0)
            if c.MAP_FAILED == page:
                e = c.errno.value
                raise Exception("mmap: 0x%x" % e)
        else:
            assert self.page_sz == self._page_sz
            page = c.valloc(self._page_sz)
            if 0 == page:
                    raise Exception("valloc")
            if -1 == c.mlock(page, self._page_sz):
                    raise Exception("mlock")

        c.memset(page, 0xFF, self.page_sz)

        self.locked_pages += [page]
        return (page, self.page_sz)
Ejemplo n.º 9
0
    def get_page(self):
        if self._hugetlb_available:
            assert self.page_sz == self._hugetlb_pgsz
            prot = c.PROT_READ | c.PROT_WRITE
            flags = c.MAP_ANONYMOUS | c.MAP_PRIVATE | c.MAP_LOCKED | c.MAP_HUGETLB
            flags |= (21 << c.MAP_HUGE_SHIFT)
            sz = self._hugetlb_pgsz
            page = c.mmap(0, sz, prot, flags, -1, 0)
            if c.MAP_FAILED == page:
                e = c.errno.value
                raise Exception("mmap: 0x%x" % e)
        else:
            assert self.page_sz == self._page_sz
            page = c.valloc(self._page_sz)
            if 0 == page:
                    raise Exception("valloc")
            if -1 == c.mlock(page, self._page_sz):
                    raise Exception("mlock")

        c.memset(page, 0xFF, self.page_sz)

        self.locked_pages += [page]
        return (page, self.page_sz)
Ejemplo n.º 10
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)