On Mon, 1 Aug 2016 10:24:52 +0000 chris thompson <the_cartograp...@hotmail.com> wrote:
> Hi, > > I'm trying to talk to my PCI-e card (USB3 host controller) from userland, and > have been successful accessing the PCI Config registers and device memory, > and able to register eventfd file descriptors for legacy interrupts (IRQx) > and Error interrupts - including stimulating these via the ioctl calls. > Unfortunately the MSI and MSI-X interrupts return EINVAL (invalid argument) > when trying to register them. > > Sample from the code: > printf("\nInterrupts:\n"); > int * irq_fds[VFIO_PCI_NUM_IRQS]; > int num_irqs[VFIO_PCI_NUM_IRQS]; > for (i = 0; i < device_info.num_irqs; i++) { > struct vfio_irq_info irq = { .argsz = sizeof(irq) }; > irq.index = i; > ioctl(device, VFIO_DEVICE_GET_IRQ_INFO, &irq); > printf("argsz 0x%x, flags 0x%x, index 0x%x, count 0x%x,\n", irq.argsz, > irq.flags, irq.index, irq.count); > num_irqs[i] = irq.count; > irq_fds[i]=(int*)malloc(irq.count * sizeof(int)); > int j; > for(j=0; j<irq.count; j++) > { > irq_fds[i][j] = eventfd(0, 0); > printf("config IRQ %u : %u\n", i, j); > struct vfio_irq_set *irq_setup; > unsigned int size = sizeof(struct vfio_irq_set) + sizeof(int); > irq_setup = malloc(size); > irq_setup->argsz = size; > irq_setup->flags = VFIO_IRQ_SET_DATA_EVENTFD | > VFIO_IRQ_SET_ACTION_TRIGGER ; > irq_setup->index = i; > irq_setup->start = j; > irq_setup->count = 1; > *(int*)(irq_setup->data)=irq_fds[i][j]; > int ret = ioctl(device, VFIO_DEVICE_SET_IRQS, irq_setup); > if(ret){ printf("failed to register interrupt %u : %u, error %i %s\n", i, > j, ret, strerror(errno)); } > free(irq_setup); > } > } > > Which gives the output: > > Interrupts: > argsz 0x10, flags 0x7, index 0x0, count 0x1, > config IRQ 0 : 0 > argsz 0x10, flags 0x9, index 0x1, count 0x40, > config IRQ 1 : 0 > failed to register interrupt 1 : 0, error -1 Invalid argument > config IRQ 1 : 1 > failed to register interrupt 1 : 1, error -1 Invalid argument > config IRQ 1 : 2 > ... > > Does anyone know a likely reason that I can't register these? From what I've > read my IOMMUs all support IRQ remapping: > [ 0.016443] dmar: IOMMU 0: reg_base_addr fed90000 ver 1:0 cap > c0000020e60262 ecap f0101a > [ 0.016450] dmar: IOMMU 1: reg_base_addr fed91000 ver 1:0 cap > c9008020660262 ecap f0105a > > The hardware is an Intel i5 2500 in an HP 8200 Elite small form-factor PC, > running Ubuntu 14.04 on the 3.13 kernel. include/uapi/linux/vfio.h: * The NORESIZE flag indicates that the interrupt lines within the index * are setup as a set and new subindexes cannot be enabled without first * disabling the entire index. This is used for interrupts like PCI MSI * and MSI-X where the driver may only use a subset of the available * indexes, but VFIO needs to enable a specific number of vectors * upfront. In the case of MSI-X, where the user can enable MSI-X and * then add and unmask vectors, it's up to userspace to make the decision * whether to allocate the maximum supported number of vectors or tear * down setup and incrementally increase the vectors as each is enabled. struct vfio_irq_info { __u32 argsz; __u32 flags; #define VFIO_IRQ_INFO_EVENTFD (1 << 0) #define VFIO_IRQ_INFO_MASKABLE (1 << 1) #define VFIO_IRQ_INFO_AUTOMASKED (1 << 2) #define VFIO_IRQ_INFO_NORESIZE (1 << 3) <---- __u32 index; /* IRQ index */ __u32 count; /* Number of IRQs within this index */ }; _______________________________________________ vfio-users mailing list vfio-users@redhat.com https://www.redhat.com/mailman/listinfo/vfio-users