From: Jie Liu <[email protected]>

Implement DMA mapping and unmapping functionality using ioctl
calls. This allows the driver to configure the hardware's IOMMU/DMA
tables, ensuring the device can safely access memory buffers
allocated by the userspace.

The mapping is established during device initialization or queue
setup and is revoked during device closure to prevent memory
leaks and ensure hardware security.

Signed-off-by: Jie Liu <[email protected]>
---
 drivers/common/sxe2/sxe2_common.c          |  50 +++++++++-
 drivers/common/sxe2/sxe2_ioctl_chnl.c      | 104 +++++++++++++++++++++
 drivers/common/sxe2/sxe2_ioctl_chnl_func.h |   9 ++
 3 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/drivers/common/sxe2/sxe2_common.c 
b/drivers/common/sxe2/sxe2_common.c
index c309a890ad..f394c832d7 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -442,7 +442,7 @@ static int32_t sxe2_common_pci_remove(struct rte_pci_device 
*pci_dev)
        cdev = sxe2_rtedev_to_cdev(&pci_dev->device);
        if (cdev == NULL) {
                ret = -ENODEV;
-               PMD_LOG_ERR(COM, "Fail to get remove device.");
+               PMD_LOG_ERR(COM, "Fail to get device when remove.");
                goto l_end;
        }
 
@@ -466,12 +466,60 @@ static int32_t sxe2_common_pci_remove(struct 
rte_pci_device *pci_dev)
        return ret;
 }
 
+static int32_t sxe2_common_pci_dma_map(struct rte_pci_device *pci_dev,
+               void *addr,     uint64_t iova, size_t len)
+{
+       struct sxe2_common_device *cdev;
+       int32_t ret = -1;
+
+       cdev = sxe2_rtedev_to_cdev(&pci_dev->device);
+       if (cdev == NULL) {
+               ret = -ENODEV;
+               PMD_LOG_ERR(COM, "Fail to get device when dma map.");
+               goto l_end;
+       }
+
+       ret = sxe2_drv_dev_dma_map(cdev, (uint64_t)(uintptr_t)addr, iova, len);
+       if (ret) {
+               PMD_LOG_ERR(COM, "Fail to map dma map, ret=%d", ret);
+               goto l_end;
+       }
+
+l_end:
+       return ret;
+}
+
+static int32_t sxe2_common_pci_dma_unmap(struct rte_pci_device *pci_dev,
+               void *addr __rte_unused, uint64_t iova, size_t len __rte_unused)
+{
+       struct sxe2_common_device *cdev;
+       int32_t ret = -1;
+
+       cdev = sxe2_rtedev_to_cdev(&pci_dev->device);
+       if (cdev == NULL) {
+               ret = -ENODEV;
+               PMD_LOG_ERR(COM, "Fail to get device when dma unmap.");
+               goto l_end;
+       }
+
+       ret = sxe2_drv_dev_dma_unmap(cdev, iova);
+       if (ret) {
+               PMD_LOG_ERR(COM, "Fail to unmap dma map, ret=%d", ret);
+               goto l_end;
+       }
+
+l_end:
+       return ret;
+}
+
 static struct rte_pci_driver sxe2_common_pci_driver = {
        .driver = {
                   .name = SXE2_COMMON_PCI_DRIVER_NAME,
        },
        .probe = sxe2_common_pci_probe,
        .remove = sxe2_common_pci_remove,
+       .dma_map = sxe2_common_pci_dma_map,
+       .dma_unmap = sxe2_common_pci_dma_unmap,
 };
 
 static uint32_t sxe2_common_pci_id_table_size_get(const struct rte_pci_id 
*id_table)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c 
b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 48acc41509..08df9373d7 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -219,3 +219,107 @@ sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void 
*virt, uint64_t len)
 l_end:
        return ret;
 }
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_dma_map)
+int32_t
+sxe2_drv_dev_dma_map(struct sxe2_common_device *cdev, uint64_t vaddr,
+                       uint64_t iova, uint64_t size)
+{
+       struct sxe2_ioctl_iommu_dma_map cmd_params;
+       enum rte_iova_mode iova_mode;
+       int32_t ret = 0;
+       int32_t cmd_fd = 0;
+
+       if (cdev->config.kernel_reset) {
+               ret = -EPERM;
+               PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+               goto l_end;
+       }
+
+       iova_mode = rte_eal_iova_mode();
+       if (iova_mode == RTE_IOVA_PA) {
+               if (cdev->config.support_iommu) {
+                       PMD_LOG_ERR(COM, "iommu not support pa mode");
+                       ret = -EIO;
+               }
+               goto l_end;
+       } else if (iova_mode == RTE_IOVA_VA) {
+               if (!cdev->config.support_iommu) {
+                       PMD_LOG_ERR(COM, "no iommu not support va mode, please 
use pa mode.");
+                       ret = -EIO;
+                       goto l_end;
+               }
+       }
+
+       cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+       if (cmd_fd < 0) {
+               ret = -EBADF;
+               PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+               goto l_end;
+       }
+
+       memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_iommu_dma_map));
+       cmd_params.vaddr = vaddr;
+       cmd_params.iova = iova;
+       cmd_params.size = size;
+
+       (void)pthread_mutex_lock(&cdev->config.lock);
+       ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_MAP, &cmd_params);
+       if (ret < 0) {
+               PMD_LOG_ERR(COM, "Failed to dma map, fd=%d, ret=%d, err:%s",
+                               cmd_fd, ret, strerror(errno));
+               ret = -EIO;
+               (void)pthread_mutex_unlock(&cdev->config.lock);
+               goto l_end;
+       }
+       (void)pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+       return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_dma_unmap)
+int32_t
+sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
+{
+       int32_t ret = 0;
+       int32_t cmd_fd = 0;
+       struct sxe2_ioctl_iommu_dma_unmap cmd_params;
+
+       if (cdev->config.kernel_reset) {
+               ret = -EPERM;
+               PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+               goto l_end;
+       }
+
+       if (!cdev->config.support_iommu)
+               goto l_end;
+
+       cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+       if (cmd_fd < 0) {
+               ret = -EBADF;
+               PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+               goto l_end;
+       }
+
+       PMD_LOG_DEBUG(COM, "fd %d dma unmap iova=0x%"PRIX64"",
+               cmd_fd, iova);
+
+       memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_iommu_dma_unmap));
+       cmd_params.iova = iova;
+
+       (void)pthread_mutex_lock(&cdev->config.lock);
+       ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_UNMAP, &cmd_params);
+       if (ret < 0) {
+               PMD_LOG_INFO(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
+                               cmd_fd, ret, strerror(errno));
+               ret = -EIO;
+               (void)pthread_mutex_unlock(&cdev->config.lock);
+               goto l_end;
+       }
+       (void)pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+       return ret;
+}
+
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl_func.h 
b/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
index 710ca1a8d0..ed9ceb1f5a 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
@@ -46,6 +46,15 @@ __rte_internal
 int32_t
 sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len);
 
+__rte_internal
+int32_t
+sxe2_drv_dev_dma_map(struct sxe2_common_device *cdev, uint64_t vaddr,
+               uint64_t iova, uint64_t size);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.47.3

Reply via email to