28 #include <linux/vfio.h>
29 #include <sys/ioctl.h>
30 #include <sys/eventfd.h>
51 if (signum == SIGINT || signum == SIGTERM) {
52 DOCA_LOG_INFO(
"Signal %d received, preparing to exit", signum);
68 struct vfio_irq_info irq_info = {
69 .argsz =
sizeof(irq_info),
70 .index = VFIO_PCI_MSIX_IRQ_INDEX,
72 int status = ioctl(
resources->device_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
74 DOCA_LOG_ERR(
"Failed to get IRQ set %u info. Status=%d, errno=%d",
75 VFIO_PCI_MSIX_IRQ_INDEX,
80 if (irq_info.count == 0) {
85 const size_t fd_table_size = (
sizeof(int) * irq_info.count);
86 resources->msix_vector_to_fd = malloc(fd_table_size);
88 DOCA_LOG_ERR(
"Failed to allocate msix to fd table, with %u entries", irq_info.count);
92 struct vfio_irq_set *irq_set = malloc(
sizeof(
struct vfio_irq_set) + fd_table_size);
93 if (irq_set ==
NULL) {
94 DOCA_LOG_ERR(
"Failed to allocate vfio_irq_set, with space for %u fds", irq_info.count);
96 goto cleanup_fd_table;
98 irq_set->argsz =
sizeof(
struct vfio_irq_set) + fd_table_size;
99 irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
100 irq_set->index = irq_info.index;
102 irq_set->count = irq_info.count;
104 irq_set_data = (
int *)&irq_set->data[0];
105 for (idx = 0; idx < irq_set->count; ++idx) {
106 resources->msix_vector_to_fd[idx] = eventfd(0, EFD_NONBLOCK);
107 if (
resources->msix_vector_to_fd[idx] == -1) {
108 DOCA_LOG_ERR(
"Failed to create eventfd for MSI-X index %u", idx);
110 goto cleanup_irq_set;
113 irq_set_data[idx] =
resources->msix_vector_to_fd[idx];
116 status = ioctl(
resources->device_fd, VFIO_DEVICE_SET_IRQS, irq_set);
118 DOCA_LOG_ERR(
"Failed to set MSI-X IRQs. Status=%d, errno=%d", status, errno);
120 goto cleanup_irq_set;
147 DOCA_LOG_ERR(
"Received error while reading MSI-X vector index %u. errno %d", msix_idx, errno);
151 DOCA_LOG_INFO(
"Event received for MSI-X vector index %u new value %ld", msix_idx,
value);
DOCA_LOG_REGISTER(DEVEMU_PCI_DEVICE_MSIX_HOST)
doca_error_t devemu_pci_device_msix_host(const char *pci_address, int vfio_group)
static void read_msix_events(struct devemu_host_resources *resources, uint16_t msix_idx)
static void signal_handler(int signum)
static doca_error_t map_msix_to_fds(struct devemu_host_resources *resources)
void devemu_host_resources_cleanup(struct devemu_host_resources *resources)
doca_error_t init_vfio_device(struct devemu_host_resources *resources, int vfio_group, const char *pci_address)
struct rdma_resources resources
enum doca_error doca_error_t
DOCA API return codes.
@ DOCA_ERROR_INVALID_VALUE
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
#define PCI_TYPE_NUM_MSIX