linuxdriverpcivfio

what is "num_regions" returned by the ioctl (VFIO_DEVICE_GET_REGION_INFO) in vfio


I am trying to understand how vfio works on pci. I have read https://www.kernel.org/doc/Documentation/vfio.txt, and I am writting a test based on it. At some point,my code looks like this:

/* Get pci device information (number of regions and interrupts...) */
ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_INFO, &device_info);
if (ret) {
        printf("  %s cannot get device info, "
                        "error %i (%s)\n", pci_addr, errno, strerror(errno));
        close(vfio_dev_fd);
        return -1;
}
printf ("found %d regions in the device\n", device_info.num_regions);

What I do not understand is that the last printf shows 9 (nine) regions! Looking at the config space of my PCI device I can see:

cat /sys/bus/pci/devices/0000\:06\:00.0/config | hd
00000000  e4 14 81 16 00 04 10 00  10 00 00 02 10 00 00 00  |................|
00000010  04 00 de f3 00 00 00 00  04 00 df f3 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 28 10 6e 02  |............(.n.|
00000030  00 00 00 00 48 00 00 00  00 00 00 00 0a 01 00 00  |....H...........|
00000040

I am new to PCI, but my interpretation of this is that there are only two BARSs on this board (0 and 2). And I though that max number of regions (BARs?) was 6 on PCI.

There is nevertheless a little indication that I am misunderstanding something: the kernel doc mentioned above states:

For PCI devices, config space is a region

So that could lead to 3 regions for the board I am looking at... Still it says 9... What is a PCI region for pci_vfio? how are they numbered and accessed?...

Thanks.


Solution

  • From vfio.h:

    /*
     * The VFIO-PCI bus driver makes use of the following fixed region and
     * IRQ index mapping.  Unimplemented regions return a size of zero.
     * Unimplemented IRQ types return a count of zero.
     */
    
    enum {
        VFIO_PCI_BAR0_REGION_INDEX,
        VFIO_PCI_BAR1_REGION_INDEX,
        VFIO_PCI_BAR2_REGION_INDEX,
        VFIO_PCI_BAR3_REGION_INDEX,
        VFIO_PCI_BAR4_REGION_INDEX,
        VFIO_PCI_BAR5_REGION_INDEX,
        VFIO_PCI_ROM_REGION_INDEX,
        VFIO_PCI_CONFIG_REGION_INDEX,
        /*
         * Expose VGA regions defined for PCI base class 03, subclass 00.
         * This includes I/O port ranges 0x3b0 to 0x3bb and 0x3c0 to 0x3df
         * as well as the MMIO range 0xa0000 to 0xbffff.  Each implemented
         * range is found at it's identity mapped offset from the region
         * offset, for example 0x3b0 is region_info.offset + 0x3b0.  Areas
         * between described ranges are unimplemented.
         */
        VFIO_PCI_VGA_REGION_INDEX,
        VFIO_PCI_NUM_REGIONS
    };
    

    So, these additional regions are a way to provide access to configuration space, option ROM and VGA-specific I/O (ports and legacy framebuffer 0xa0000...0xbffff window).