From patchwork Thu Dec 22 23:24:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 121298 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C8B9DA0093; Fri, 23 Dec 2022 00:25:21 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1EB1842D2D; Fri, 23 Dec 2022 00:24:59 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 5227242D2A for ; Fri, 23 Dec 2022 00:24:56 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2BMH0QRq027128; Thu, 22 Dec 2022 15:24:55 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=EaBginYGfEGVeMycGSV2gjkpdbWTle393ujVfZcVjJI=; b=JkeK7Gfyd1uUHe3mQqQQmc+ZgZ6SOvb1vlAXhWoMdVZlscbjXwTzfztet5+/PEcVYt+3 pD+V7dXKPMEfdc7rrCfHPf+uKr2zK4TslMVTzOYJNARfxPN52BvEvwDMqv5iIoV55bRF qG/aAi2g0YOn+wXALT+IaeOnErFCRc56Th6eAjbApq+dadOj07/I+OsZKRbXW1ZsqNBG erTMoPW6SztHwTlpMhApBfLW1QYw/LLpks8jGo24KKehY91sED8nxup0X5GDR7/Y5cgz 9D9cTKHP616cZk0iIMgGgt/V3DwLiS+AMcGrDrEv+jJNJI7vv5cwelgrUuIheBY6MoHT ZQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3mhe5runy3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Thu, 22 Dec 2022 15:24:55 -0800 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Thu, 22 Dec 2022 15:24:53 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.42 via Frontend Transport; Thu, 22 Dec 2022 15:24:53 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id CA2473F704E; Thu, 22 Dec 2022 15:24:51 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [RFC PATCH 5/7] raw/vfio_platform: support rawdev configure Date: Fri, 23 Dec 2022 00:24:33 +0100 Message-ID: <20221222232436.643514-6-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221222232436.643514-1-tduszynski@marvell.com> References: <20221222232436.643514-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: NQtBDbxCQe-NiO9cMFYS9UrlQ5jzIolh X-Proofpoint-ORIG-GUID: NQtBDbxCQe-NiO9cMFYS9UrlQ5jzIolh X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-12-22_10,2022-12-22_03,2022-06-22_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for binding device VFIO group to a VFIO container. Signed-off-by: Tomasz Duszynski --- .../raw/vfio_platform/rte_pmd_vfio_platform.h | 6 + drivers/raw/vfio_platform/vfio_platform.c | 147 ++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/drivers/raw/vfio_platform/rte_pmd_vfio_platform.h b/drivers/raw/vfio_platform/rte_pmd_vfio_platform.h index 307a20d9fc..b595171af6 100644 --- a/drivers/raw/vfio_platform/rte_pmd_vfio_platform.h +++ b/drivers/raw/vfio_platform/rte_pmd_vfio_platform.h @@ -17,6 +17,12 @@ extern "C" { #endif +/** vfio platform device configuration */ +struct vfio_platform_dev_config { + /** logical value representing the vfio container */ + int container; +}; + /** * Create a new VFIO container. * diff --git a/drivers/raw/vfio_platform/vfio_platform.c b/drivers/raw/vfio_platform/vfio_platform.c index ae0572dc99..ab5b96a0b0 100644 --- a/drivers/raw/vfio_platform/vfio_platform.c +++ b/drivers/raw/vfio_platform/vfio_platform.c @@ -3,9 +3,11 @@ */ #include +#include #include #include +#include #include #include #include @@ -92,6 +94,29 @@ rte_pmd_vfio_platform_container_destroy(int container) return 0; } +static char * +of_resource_name(const char *dev_name, int index) +{ + char path[PATH_MAX], buf[BUFSIZ] = { }; + int num = 0, ret; + char *name; + + snprintf(path, sizeof(path), VFIO_PLATFORM_SYSFS_BASE "/%s/of_node/reg-names", dev_name); + /* save space for null byte */ + ret = eal_parse_sysfs_string(path, buf, sizeof(buf) - 1); + if (ret) + return NULL; + + for (name = buf; name; name += strlen(name) + 2) { + if (num++ != index) + continue; + + return strdup(name); + } + + return NULL; +} + static void device_release_maps(struct vfio_platform *plat) { @@ -109,6 +134,109 @@ device_release_maps(struct vfio_platform *plat) plat->num_resource = 0; } +static int +device_configure_maps(struct vfio_platform *plat, struct vfio_device_info *dev_info) +{ + struct vfio_region_info reg_info = { .argsz = sizeof(reg_info), }; + struct vfio_platform_resource *res; + unsigned int i; + void *map; + int ret; + + plat->resource = calloc(dev_info->num_regions, sizeof(*plat->resource)); + if (!plat->resource) + return -ENOMEM; + + for (i = 0; i < dev_info->num_regions; i++) { + reg_info.index = i; + ret = ioctl(plat->dev_fd, VFIO_DEVICE_GET_REGION_INFO, ®_info); + if (ret) { + VFIO_PLATFORM_LOG(ERR, "failed to get region info at %d\n", i); + ret = -errno; + goto out; + } + + map = mmap(NULL, reg_info.size, PROT_READ | PROT_WRITE, MAP_SHARED, plat->dev_fd, + reg_info.offset); + if (map == MAP_FAILED) { + ret = -errno; + goto out; + } + + res = &plat->resource[plat->num_resource]; + res->mem.addr = map; + res->mem.len = reg_info.size; + res->name = of_resource_name(plat->device->name, reg_info.index); + plat->num_resource++; + + VFIO_PLATFORM_LOG(DEBUG, "adding resource va=%p len=%lu name = %s\n", + res->mem.addr, res->mem.len, res->name); + } + + return 0; +out: + device_release_maps(plat); + + return ret; +} + +static int +device_configure(struct vfio_platform *plat, struct vfio_platform_dev_config *config) +{ + struct vfio_device_info dev_info = { .argsz = sizeof(dev_info), }; + struct rte_platform_device *pdev = plat->device; + const char *name = pdev->device.name; + int ret; + + ret = rte_vfio_get_group_num(VFIO_PLATFORM_SYSFS_BASE, name, &plat->group); + if (ret != 1) { + VFIO_PLATFORM_LOG(ERR, "failed to read device %s iommu group number\n", name); + return -ENODEV; + } + + container_get(config->container); + plat->group_fd = rte_vfio_container_group_bind(container_fd(config->container), plat->group); + if (plat->group_fd < 0) { + VFIO_PLATFORM_LOG(ERR, "failed to bind group to container\n"); + ret = -ENODEV; + goto out; + } + + ret = rte_vfio_setup_device(VFIO_PLATFORM_SYSFS_BASE, name, &plat->dev_fd, &dev_info); + if (ret) { + VFIO_PLATFORM_LOG(ERR, "failed to setup %s\n", name); + ret = -ENODEV; + goto out_unbind; + } + + if (!(dev_info.flags & VFIO_DEVICE_FLAGS_PLATFORM)) { + VFIO_PLATFORM_LOG(ERR, "device not backed by vfio platform\n"); + ret = -ENOTSUP; + goto out_release; + } + + plat->container = config->container; + + ret = device_configure_maps(plat, &dev_info); + if (ret) { + VFIO_PLATFORM_LOG(ERR, "failed to setup memory maps\n"); + goto out_release; + } + + return 0; + +out_release: + rte_vfio_release_device(VFIO_PLATFORM_SYSFS_BASE, name, plat->dev_fd); +out_unbind: + rte_vfio_container_group_unbind(container_fd(config->container), plat->group); +out: + close(plat->group_fd); + rte_vfio_clear_group(plat->group_fd); + container_put(config->container); + + return ret; +} + static void device_release(struct vfio_platform *plat) { @@ -120,6 +248,24 @@ device_release(struct vfio_platform *plat) container_put(plat->container); } +static int +vfio_rawdev_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config, size_t config_size) +{ + struct vfio_platform_dev_config *dev_config = config; + struct vfio_platform *plat = dev->dev_private; + + if (!dev_config) + return -EINVAL; + + if (sizeof(*dev_config) != config_size) + return -EINVAL; + + if ((unsigned int)dev_config->container >= RTE_DIM(container_tbl)) + return -EINVAL; + + return device_configure(plat, dev_config); +} + static int vfio_rawdev_dev_close(struct rte_rawdev *dev) { @@ -131,6 +277,7 @@ vfio_rawdev_dev_close(struct rte_rawdev *dev) } static const struct rte_rawdev_ops vfio_platform_rawdev_ops = { + .dev_configure = vfio_rawdev_dev_configure, .dev_close = vfio_rawdev_dev_close, };