[PATCH] common/cnxk: fix VFIO MSI-X interrupt setup

pbhagavatula at marvell.com pbhagavatula at marvell.com
Thu May 21 10:26:46 CEST 2026


From: Pavan Nikhilesh <pbhagavatula at marvell.com>

Use heap allocation sized by the configured maximum interrupt count for the
VFIO irq_set buffer, correct handling when irq.count is zero, and use a
minimal stack buffer for per-vector configuration.

Fixes: 1fb9f4ab14b3 ("common/cnxk: remove VLA in interrupt configuration")
Cc: stable at dpdk.org

Signed-off-by: Pavan Nikhilesh <pbhagavatula at marvell.com>
---
 drivers/common/cnxk/roc_platform.c | 39 +++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c
index 1fdbf8f05143..59d662fab43b 100644
--- a/drivers/common/cnxk/roc_platform.c
+++ b/drivers/common/cnxk/roc_platform.c
@@ -13,13 +13,11 @@
 #if defined(__linux__)
 
 #include <inttypes.h>
+#include <stdlib.h>
 #include <sys/eventfd.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 
-#define MSIX_IRQ_SET_BUF_LEN							\
-	(sizeof(struct vfio_irq_set) + sizeof(int) * PLT_MAX_RXTX_INTR_VEC_ID)
-
 static int
 irq_get_info(struct plt_intr_handle *intr_handle)
 {
@@ -39,11 +37,12 @@ irq_get_info(struct plt_intr_handle *intr_handle)
 		     irq.count, PLT_MAX_RXTX_INTR_VEC_ID);
 
 	if (irq.count == 0) {
-		plt_err("HW max=%d > PLT_MAX_RXTX_INTR_VEC_ID: %d", irq.count,
-			PLT_MAX_RXTX_INTR_VEC_ID);
-		plt_intr_max_intr_set(intr_handle, PLT_MAX_RXTX_INTR_VEC_ID);
+		plt_warn("VFIO MSI-X irq.count is 0; using PLT_MAX_RXTX_INTR_VEC_ID=%u",
+			 PLT_MAX_RXTX_INTR_VEC_ID);
+		if (plt_intr_max_intr_set(intr_handle, PLT_MAX_RXTX_INTR_VEC_ID))
+			return -1;
 	} else {
-		if (plt_intr_max_intr_set(intr_handle, irq.count))
+		if (plt_intr_max_intr_set(intr_handle, (int)irq.count))
 			return -1;
 	}
 
@@ -53,7 +52,7 @@ irq_get_info(struct plt_intr_handle *intr_handle)
 static int
 irq_config(struct plt_intr_handle *intr_handle, unsigned int vec)
 {
-	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	char irq_set_buf[sizeof(struct vfio_irq_set) + sizeof(int32_t)];
 	struct vfio_irq_set *irq_set;
 	int len, rc, vfio_dev_fd;
 	int32_t *fd_ptr;
@@ -89,23 +88,34 @@ irq_config(struct plt_intr_handle *intr_handle, unsigned int vec)
 static int
 irq_init(struct plt_intr_handle *intr_handle)
 {
-	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	int max_intr, len, rc, vfio_dev_fd;
 	struct vfio_irq_set *irq_set;
-	int len, rc, vfio_dev_fd;
+	char *irq_set_buf = NULL;
 	int32_t *fd_ptr;
-	uint32_t i;
+	int i;
 
-	len = sizeof(struct vfio_irq_set) + sizeof(int32_t) * plt_intr_max_intr_get(intr_handle);
+	max_intr = plt_intr_max_intr_get(intr_handle);
+	if (max_intr <= 0) {
+		plt_err("Invalid max_intr %d for irq init", max_intr);
+		return -EINVAL;
+	}
+
+	len = sizeof(struct vfio_irq_set) + sizeof(int32_t) * max_intr;
+	irq_set_buf = malloc((size_t)len);
+	if (irq_set_buf == NULL) {
+		plt_err("Failed to alloc irq_set_buf len=%d", len);
+		return -ENOMEM;
+	}
 
 	irq_set = (struct vfio_irq_set *)irq_set_buf;
 	irq_set->argsz = len;
 	irq_set->start = 0;
-	irq_set->count = plt_intr_max_intr_get(intr_handle);
+	irq_set->count = (uint32_t)max_intr;
 	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
 	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
 
 	fd_ptr = (int32_t *)&irq_set->data[0];
-	for (i = 0; i < irq_set->count; i++)
+	for (i = 0; i < max_intr; i++)
 		fd_ptr[i] = -1;
 
 	vfio_dev_fd = plt_intr_dev_fd_get(intr_handle);
@@ -113,6 +123,7 @@ irq_init(struct plt_intr_handle *intr_handle)
 	if (rc)
 		plt_err("Failed to set irqs vector rc=%d", rc);
 
+	free(irq_set_buf);
 	return rc;
 }
 
-- 
2.50.1 (Apple Git-155)



More information about the stable mailing list