From: Yunjian Wang Date: Tue, 19 May 2020 03:42:00 +0000 (+0800) Subject: vfio: fix group descriptor check X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=1f16fa99aa36e043e395184d6ad37a348eafeba7;p=dpdk.git vfio: fix group descriptor check The issue is that a file descriptor at 0 is a valid one. Currently the file not found, the return value will be set to 0. As a result, it is impossible to distinguish between a correct descriptor and a failed return value. Fix it to return -ENOENT instead of 0. Fixes: b758423bc4fe ("vfio: fix race condition with sysfs") Fixes: ff0b67d1c868 ("vfio: DMA mapping") Cc: stable@dpdk.org Signed-off-by: Yunjian Wang Reviewed-by: Anatoly Burakov --- diff --git a/lib/librte_eal/linux/eal_vfio.c b/lib/librte_eal/linux/eal_vfio.c index e07979936e..380f2f44aa 100644 --- a/lib/librte_eal/linux/eal_vfio.c +++ b/lib/librte_eal/linux/eal_vfio.c @@ -295,7 +295,7 @@ vfio_open_group_fd(int iommu_group_num) strerror(errno)); return -1; } - return 0; + return -ENOENT; } /* noiommu group found */ } @@ -320,12 +320,12 @@ vfio_open_group_fd(int iommu_group_num) vfio_group_fd = mp_rep->fds[0]; } else if (p->result == SOCKET_NO_FD) { RTE_LOG(ERR, EAL, " bad VFIO group fd\n"); - vfio_group_fd = 0; + vfio_group_fd = -ENOENT; } } free(mp_reply.msgs); - if (vfio_group_fd < 0) + if (vfio_group_fd < 0 && vfio_group_fd != -ENOENT) RTE_LOG(ERR, EAL, " cannot request group fd\n"); return vfio_group_fd; } @@ -381,9 +381,9 @@ vfio_get_group_fd(struct vfio_config *vfio_cfg, } vfio_group_fd = vfio_open_group_fd(iommu_group_num); - if (vfio_group_fd <= 0) { + if (vfio_group_fd < 0) { RTE_LOG(ERR, EAL, "Failed to open group %d\n", iommu_group_num); - return -1; + return vfio_group_fd; } cur_grp->group_num = iommu_group_num; @@ -733,11 +733,14 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr, /* get the actual group fd */ vfio_group_fd = rte_vfio_get_group_fd(iommu_group_num); - if (vfio_group_fd < 0) + if (vfio_group_fd < 0 && vfio_group_fd != -ENOENT) return -1; - /* if group_fd == 0, that means the device isn't managed by VFIO */ - if (vfio_group_fd == 0) { + /* + * if vfio_group_fd == -ENOENT, that means the device + * isn't managed by VFIO + */ + if (vfio_group_fd == -ENOENT) { RTE_LOG(WARNING, EAL, " %s not managed by VFIO driver, skipping\n", dev_addr); return 1; @@ -975,10 +978,10 @@ rte_vfio_release_device(const char *sysfs_base, const char *dev_addr, /* get the actual group fd */ vfio_group_fd = rte_vfio_get_group_fd(iommu_group_num); - if (vfio_group_fd <= 0) { + if (vfio_group_fd < 0) { RTE_LOG(INFO, EAL, "rte_vfio_get_group_fd failed for %s\n", dev_addr); - ret = -1; + ret = vfio_group_fd; goto out; } diff --git a/lib/librte_eal/linux/eal_vfio_mp_sync.c b/lib/librte_eal/linux/eal_vfio_mp_sync.c index 5f2a5fc1d9..6254696ae5 100644 --- a/lib/librte_eal/linux/eal_vfio_mp_sync.c +++ b/lib/librte_eal/linux/eal_vfio_mp_sync.c @@ -44,9 +44,9 @@ vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer) r->req = SOCKET_REQ_GROUP; r->group_num = m->group_num; fd = rte_vfio_get_group_fd(m->group_num); - if (fd < 0) + if (fd < 0 && fd != -ENOENT) r->result = SOCKET_ERR; - else if (fd == 0) + else if (fd == -ENOENT) /* if VFIO group exists but isn't bound to VFIO driver */ r->result = SOCKET_NO_FD; else {