A duplicated interrupt handle is allocated with the default event array
size, but the source may have been grown with rte_intr_event_list_update()
when the device has more vectors than the default. The duplicate then
reports the default nb_intr and its arrays are too small for the source
contents.

Grow the duplicate to the size of the source before copying.

Fixes: b7c984291611 ("interrupts: add allocator and accessors")
Cc: [email protected]

Signed-off-by: Anatoly Burakov <[email protected]>
---
 lib/eal/common/eal_common_interrupts.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/lib/eal/common/eal_common_interrupts.c 
b/lib/eal/common/eal_common_interrupts.c
index 6368ef17714..4520ff59bd7 100644
--- a/lib/eal/common/eal_common_interrupts.c
+++ b/lib/eal/common/eal_common_interrupts.c
@@ -115,17 +115,25 @@ struct rte_intr_handle *rte_intr_instance_dup(const 
struct rte_intr_handle *src)
        }
 
        intr_handle = rte_intr_instance_alloc(src->alloc_flags);
-       if (intr_handle != NULL) {
-               intr_handle->fd = src->fd;
-               intr_handle->dev_fd = src->dev_fd;
-               intr_handle->type = src->type;
-               intr_handle->max_intr = src->max_intr;
-               intr_handle->nb_efd = src->nb_efd;
-               intr_handle->efd_counter_size = src->efd_counter_size;
-               memcpy(intr_handle->efds, src->efds, src->nb_intr);
-               memcpy(intr_handle->elist, src->elist, src->nb_intr);
+       if (intr_handle == NULL)
+               return NULL;
+
+       /* The source may have been grown beyond the default array size. */
+       if (src->nb_intr > intr_handle->nb_intr &&
+                       rte_intr_event_list_update(intr_handle, src->nb_intr) 
!= 0) {
+               rte_intr_instance_free(intr_handle);
+               return NULL;
        }
 
+       intr_handle->fd = src->fd;
+       intr_handle->dev_fd = src->dev_fd;
+       intr_handle->type = src->type;
+       intr_handle->max_intr = src->max_intr;
+       intr_handle->nb_efd = src->nb_efd;
+       intr_handle->efd_counter_size = src->efd_counter_size;
+       memcpy(intr_handle->efds, src->efds, src->nb_intr);
+       memcpy(intr_handle->elist, src->elist, src->nb_intr);
+
        return intr_handle;
 }
 
-- 
2.52.0

Reply via email to