From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from netronome.com (host-79-78-33-110.static.as9105.net [79.78.33.110]) by dpdk.org (Postfix) with ESMTP id C313A47CD for ; Wed, 26 Apr 2017 12:49:48 +0200 (CEST) Received: from netronome.com (localhost [127.0.0.1]) by netronome.com (8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id v3QAnmbT025593; Wed, 26 Apr 2017 11:49:48 +0100 Received: (from alucero@localhost) by netronome.com (8.14.4/8.14.4/Submit) id v3QAnl77025592; Wed, 26 Apr 2017 11:49:47 +0100 From: Alejandro Lucero To: dev@dpdk.org Cc: anatoly.burakov@intel.com Date: Wed, 26 Apr 2017 11:49:47 +0100 Message-Id: <1493203787-25555-1-git-send-email-alejandro.lucero@netronome.com> X-Mailer: git-send-email 1.9.1 Subject: [dpdk-dev] [PATCH] vfio: fix device unplug when several devices per vfio group X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Apr 2017 10:49:49 -0000 VFIO allows a secure way of assigning devices to user space and those devices which can not be isolated from other ones are set in same VFIO group. Releasing or unplugging a device should be aware of remaining devices is the same group for avoiding to close such a group. Fixes: 94c0776b1bad ("vfio: support hotplug") Signed-off-by: Alejandro Lucero --- lib/librte_eal/linuxapp/eal/eal_vfio.c | 32 ++++++++++++++++++++++++-------- lib/librte_eal/linuxapp/eal/eal_vfio.h | 1 + 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c index 6e2e84c..6e24273 100644 --- a/lib/librte_eal/linuxapp/eal/eal_vfio.c +++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c @@ -184,6 +184,7 @@ if (vfio_cfg.vfio_groups[i].fd == vfio_group_fd) { vfio_cfg.vfio_groups[i].group_no = -1; vfio_cfg.vfio_groups[i].fd = -1; + vfio_cfg.vfio_groups[i].devices = 0; vfio_cfg.vfio_active_groups--; return 0; } @@ -353,6 +354,7 @@ clear_group(vfio_group_fd); return -1; } + vfio_cfg.vfio_groups[vfio_group_fd].devices++; return 0; } @@ -390,17 +392,30 @@ * code will unset the container and the IOMMU mappings. */ - if (close(vfio_group_fd) < 0) - RTE_LOG(INFO, EAL, "Error when closing vfio_group_fd for %s\n", - dev_addr); - - if (close(vfio_dev_fd) < 0) + /* Closing a device */ + if (close(vfio_dev_fd) < 0) { RTE_LOG(INFO, EAL, "Error when closing vfio_dev_fd for %s\n", dev_addr); + return -1; + } - if (clear_group(vfio_group_fd) < 0) - RTE_LOG(INFO, EAL, "Error when clearing group for %s\n", - dev_addr); + /* An VFIO group can have several devices attached. Just when there is + * no devices remaining should the group be closed. + */ + if (--vfio_cfg.vfio_groups[vfio_group_fd].devices == 0) { + + if (close(vfio_group_fd) < 0) { + RTE_LOG(INFO, EAL, "Error when closing vfio_group_fd for %s\n", + dev_addr); + return -1; + } + + if (clear_group(vfio_group_fd) < 0) { + RTE_LOG(INFO, EAL, "Error when clearing group for %s\n", + dev_addr); + return -1; + } + } return 0; } @@ -415,6 +430,7 @@ for (i = 0; i < VFIO_MAX_GROUPS; i++) { vfio_cfg.vfio_groups[i].fd = -1; vfio_cfg.vfio_groups[i].group_no = -1; + vfio_cfg.vfio_groups[i].devices = 0; } /* inform the user that we are probing for VFIO */ diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h index 7fcec2c..2c7cb94 100644 --- a/lib/librte_eal/linuxapp/eal/eal_vfio.h +++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h @@ -103,6 +103,7 @@ struct vfio_iommu_spapr_tce_remove { struct vfio_group { int group_no; int fd; + int devices; }; struct vfio_config { -- 1.9.1