set up interrupt support (but not enable interrupts) */
| 178 | |
| 179 | /* set up interrupt support (but not enable interrupts) */ |
| 180 | static int |
| 181 | pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd) |
| 182 | { |
| 183 | int i, ret, intr_idx; |
| 184 | enum rte_intr_mode intr_mode; |
| 185 | |
| 186 | /* default to invalid index */ |
| 187 | intr_idx = VFIO_PCI_NUM_IRQS; |
| 188 | |
| 189 | /* Get default / configured intr_mode */ |
| 190 | intr_mode = rte_eal_vfio_intr_mode(); |
| 191 | |
| 192 | /* get interrupt type from internal config (MSI-X by default, can be |
| 193 | * overridden from the command line |
| 194 | */ |
| 195 | switch (intr_mode) { |
| 196 | case RTE_INTR_MODE_MSIX: |
| 197 | intr_idx = VFIO_PCI_MSIX_IRQ_INDEX; |
| 198 | break; |
| 199 | case RTE_INTR_MODE_MSI: |
| 200 | intr_idx = VFIO_PCI_MSI_IRQ_INDEX; |
| 201 | break; |
| 202 | case RTE_INTR_MODE_LEGACY: |
| 203 | intr_idx = VFIO_PCI_INTX_IRQ_INDEX; |
| 204 | break; |
| 205 | /* don't do anything if we want to automatically determine interrupt type */ |
| 206 | case RTE_INTR_MODE_NONE: |
| 207 | break; |
| 208 | default: |
| 209 | RTE_LOG(ERR, EAL, "Unknown default interrupt type!\n"); |
| 210 | return -1; |
| 211 | } |
| 212 | |
| 213 | /* start from MSI-X interrupt type */ |
| 214 | for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) { |
| 215 | struct vfio_irq_info irq = { .argsz = sizeof(irq) }; |
| 216 | int fd = -1; |
| 217 | |
| 218 | /* skip interrupt modes we don't want */ |
| 219 | if (intr_mode != RTE_INTR_MODE_NONE && |
| 220 | i != intr_idx) |
| 221 | continue; |
| 222 | |
| 223 | irq.index = i; |
| 224 | |
| 225 | ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq); |
| 226 | if (ret < 0) { |
| 227 | RTE_LOG(ERR, EAL, "Cannot get VFIO IRQ info, error " |
| 228 | "%i (%s)\n", errno, strerror(errno)); |
| 229 | return -1; |
| 230 | } |
| 231 | |
| 232 | /* if this vector cannot be used with eventfd, fail if we explicitly |
| 233 | * specified interrupt type, otherwise continue */ |
| 234 | if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) { |
| 235 | if (intr_mode != RTE_INTR_MODE_NONE) { |
| 236 | RTE_LOG(ERR, EAL, |
| 237 | "Interrupt vector does not support eventfd!\n"); |
no test coverage detected