get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/52145/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 52145,
    "url": "http://patches.dpdk.org/api/patches/52145/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190403071844.21126-4-tiwei.bie@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20190403071844.21126-4-tiwei.bie@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190403071844.21126-4-tiwei.bie@intel.com",
    "date": "2019-04-03T07:18:44",
    "name": "[RFC,3/3] bus/pci: add mdev support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4b37b6fe11bb422ca5268c0b7b8b74e3a9ffb7fc",
    "submitter": {
        "id": 617,
        "url": "http://patches.dpdk.org/api/people/617/?format=api",
        "name": "Tiwei Bie",
        "email": "tiwei.bie@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20190403071844.21126-4-tiwei.bie@intel.com/mbox/",
    "series": [
        {
            "id": 4075,
            "url": "http://patches.dpdk.org/api/series/4075/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4075",
            "date": "2019-04-03T07:18:41",
            "name": "Add mdev (Mediated device) support in DPDK",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/4075/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/52145/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/52145/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 5A2AA5F29;\n\tWed,  3 Apr 2019 09:19:36 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id 6B6CD5B2A\n\tfor <dev@dpdk.org>; Wed,  3 Apr 2019 09:19:28 +0200 (CEST)",
            "from orsmga007.jf.intel.com ([10.7.209.58])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t03 Apr 2019 00:19:28 -0700",
            "from dpdk-tbie.sh.intel.com ([10.67.104.173])\n\tby orsmga007.jf.intel.com with ESMTP; 03 Apr 2019 00:19:26 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.60,303,1549958400\"; d=\"scan'208\";a=\"128206262\"",
        "From": "Tiwei Bie <tiwei.bie@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "cunming.liang@intel.com, bruce.richardson@intel.com,\n\talejandro.lucero@netronome.com",
        "Date": "Wed,  3 Apr 2019 15:18:44 +0800",
        "Message-Id": "<20190403071844.21126-4-tiwei.bie@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20190403071844.21126-1-tiwei.bie@intel.com>",
        "References": "<20190403071844.21126-1-tiwei.bie@intel.com>",
        "Subject": "[dpdk-dev] [RFC 3/3] bus/pci: add mdev support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch adds the mdev support in PCI bus driver. A mdev\ndriver is introduced to probe the mdev devices whose device\nAPI is \"vfio-pci\" on the mdev bus.\n\nPS. There are some hacks in this patch for now.\n\nSigned-off-by: Cunming Liang <cunming.liang@intel.com>\nSigned-off-by: Tiwei Bie <tiwei.bie@intel.com>\n---\n drivers/bus/pci/Makefile              |   3 +\n drivers/bus/pci/linux/Makefile        |   4 +\n drivers/bus/pci/linux/pci_vfio.c      |  35 ++-\n drivers/bus/pci/linux/pci_vfio_mdev.c | 305 ++++++++++++++++++++++++++\n drivers/bus/pci/meson.build           |   4 +-\n drivers/bus/pci/pci_common.c          |  17 +-\n drivers/bus/pci/private.h             |   9 +\n drivers/bus/pci/rte_bus_pci.h         |  11 +-\n 8 files changed, 370 insertions(+), 18 deletions(-)\n create mode 100644 drivers/bus/pci/linux/pci_vfio_mdev.c",
    "diff": "diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile\nindex de53ce1bf..085ec9066 100644\n--- a/drivers/bus/pci/Makefile\n+++ b/drivers/bus/pci/Makefile\n@@ -27,6 +27,9 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API\n \n LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n LDLIBS += -lrte_ethdev -lrte_pci -lrte_kvargs\n+ifeq ($(CONFIG_RTE_LIBRTE_MDEV_BUS),y)\n+LDLIBS += -lrte_bus_mdev\n+endif\n \n include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile\n SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))\ndiff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile\nindex 90404468b..88bbc2390 100644\n--- a/drivers/bus/pci/linux/Makefile\n+++ b/drivers/bus/pci/linux/Makefile\n@@ -4,3 +4,7 @@\n SRCS += pci.c\n SRCS += pci_uio.c\n SRCS += pci_vfio.c\n+\n+ifeq ($(CONFIG_RTE_LIBRTE_MDEV_BUS),y)\n+\tSRCS += pci_vfio_mdev.c\n+endif\ndiff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c\nindex ebf6ccd3c..c2c4c6a50 100644\n--- a/drivers/bus/pci/linux/pci_vfio.c\n+++ b/drivers/bus/pci/linux/pci_vfio.c\n@@ -13,6 +13,9 @@\n \n #include <rte_log.h>\n #include <rte_pci.h>\n+#ifdef RTE_LIBRTE_MDEV_BUS\n+#include <rte_bus_mdev.h>\n+#endif\n #include <rte_bus_pci.h>\n #include <rte_eal_memconfig.h>\n #include <rte_malloc.h>\n@@ -20,6 +23,7 @@\n #include <rte_eal.h>\n #include <rte_bus.h>\n #include <rte_spinlock.h>\n+#include <rte_uuid.h>\n \n #include \"eal_filesystem.h\"\n \n@@ -648,6 +652,7 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)\n {\n \tstruct vfio_device_info device_info = { .argsz = sizeof(device_info) };\n \tchar pci_addr[PATH_MAX] = {0};\n+\tconst char *sysfs_path;\n \tint vfio_dev_fd;\n \tstruct rte_pci_addr *loc = &dev->addr;\n \tint i, ret;\n@@ -663,10 +668,20 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)\n #endif\n \n \t/* store PCI address string */\n-\tsnprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,\n+\tif (dev->use_uuid) {\n+#ifdef RTE_LIBRTE_MDEV_BUS\n+\t\tsysfs_path = rte_mdev_get_sysfs_path();\n+\t\trte_uuid_unparse(dev->uuid, pci_addr, sizeof(pci_addr));\n+#else\n+\t\treturn -1;\n+#endif\n+\t} else {\n+\t\tsysfs_path = rte_pci_get_sysfs_path();\n+\t\tsnprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,\n \t\t\tloc->domain, loc->bus, loc->devid, loc->function);\n+\t}\n \n-\tret = rte_vfio_setup_device(rte_pci_get_sysfs_path(), pci_addr,\n+\tret = rte_vfio_setup_device(sysfs_path, pci_addr,\n \t\t\t\t\t&vfio_dev_fd, &device_info);\n \tif (ret)\n \t\treturn ret;\n@@ -793,6 +808,7 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)\n {\n \tstruct vfio_device_info device_info = { .argsz = sizeof(device_info) };\n \tchar pci_addr[PATH_MAX] = {0};\n+\tconst char *sysfs_path;\n \tint vfio_dev_fd;\n \tstruct rte_pci_addr *loc = &dev->addr;\n \tint i, ret;\n@@ -808,8 +824,19 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)\n #endif\n \n \t/* store PCI address string */\n-\tsnprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,\n+\tif (dev->use_uuid) {\n+#ifdef RTE_LIBRTE_MDEV_BUS\n+\t\tsysfs_path = rte_mdev_get_sysfs_path();\n+\t\trte_uuid_unparse(dev->uuid, pci_addr, sizeof(pci_addr));\n+#else\n+\t\treturn -1;\n+#endif\n+\t} else {\n+\t\tsysfs_path = rte_pci_get_sysfs_path();\n+\t\tsnprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,\n \t\t\tloc->domain, loc->bus, loc->devid, loc->function);\n+\t}\n+\n \n \t/* if we're in a secondary process, just find our tailq entry */\n \tTAILQ_FOREACH(vfio_res, vfio_res_list, next) {\n@@ -825,7 +852,7 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)\n \t\treturn -1;\n \t}\n \n-\tret = rte_vfio_setup_device(rte_pci_get_sysfs_path(), pci_addr,\n+\tret = rte_vfio_setup_device(sysfs_path, pci_addr,\n \t\t\t\t\t&vfio_dev_fd, &device_info);\n \tif (ret)\n \t\treturn ret;\ndiff --git a/drivers/bus/pci/linux/pci_vfio_mdev.c b/drivers/bus/pci/linux/pci_vfio_mdev.c\nnew file mode 100644\nindex 000000000..92498c2fe\n--- /dev/null\n+++ b/drivers/bus/pci/linux/pci_vfio_mdev.c\n@@ -0,0 +1,305 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2019 Intel Corporation\n+ */\n+\n+#include <string.h>\n+#include <dirent.h>\n+#include <fcntl.h>\n+#include <sys/ioctl.h>\n+#include <linux/pci_regs.h>\n+\n+#include <rte_log.h>\n+#include <rte_pci.h>\n+#include <rte_eal_memconfig.h>\n+#include <rte_malloc.h>\n+#include <rte_devargs.h>\n+#include <rte_memcpy.h>\n+#include <rte_vfio.h>\n+#include <rte_bus_mdev.h>\n+\n+#include \"eal_private.h\"\n+#include \"eal_filesystem.h\"\n+\n+#include \"private.h\"\n+\n+extern struct rte_pci_bus rte_pci_bus;\n+\n+static int\n+get_pci_id(const char *sysfs_base, const char *dev_addr,\n+\t   struct rte_pci_id *pci_id)\n+{\n+\tint ret = 0;\n+\tint iommu_group_num;\n+\tint vfio_group_fd;\n+\tint vfio_dev_fd;\n+\tint container;\n+\tint class;\n+\tchar name[PATH_MAX];\n+\tstruct vfio_group_status group_status = {\n+\t\t.argsz = sizeof(group_status) };\n+\n+\tcontainer = open(\"/dev/vfio/vfio\", O_RDWR);\n+\tif (container < 0) {\n+\t\tRTE_LOG(WARNING, EAL, \"Failed to open VFIO container\\n\");\n+\t\tret = -1;\n+\t\tgoto out;\n+\t}\n+\n+\tif (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION) {\n+\t\t/* Unknown API version */\n+\t\tRTE_LOG(WARNING, EAL, \"Unknown VFIO API version\\n\");\n+\t\tret = -1;\n+\t\tgoto close_container;\n+\t}\n+\n+\tif (rte_vfio_get_group_num(sysfs_base, dev_addr,\n+\t\t\t\t   &iommu_group_num) <= 0) {\n+\t\tRTE_LOG(WARNING, EAL, \"%s not managed by VFIO driver\\n\",\n+\t\t\tdev_addr);\n+\t\tret = -1;\n+\t\tgoto close_container;\n+\t}\n+\n+\tsnprintf(name, sizeof(name), \"/dev/vfio/%d\", iommu_group_num);\n+\n+\tvfio_group_fd = open(name, O_RDWR);\n+\tif (vfio_group_fd < 0) {\n+\t\tret = -1;\n+\t\tgoto close_container;\n+\t}\n+\n+\t/* if group_fd == 0, that means the device isn't managed by VFIO */\n+\tif (vfio_group_fd == 0) {\n+\t\tRTE_LOG(WARNING, EAL, \"%s not managed by VFIO driver\\n\",\n+\t\t\tdev_addr);\n+\t\tret = -1;\n+\t\tgoto close_group;\n+\t}\n+\n+\tif (ioctl(vfio_group_fd, VFIO_GROUP_GET_STATUS, &group_status)) {\n+\t\tRTE_LOG(ERR, EAL, \"%s cannot get group status, error %i (%s)\\n\",\n+\t\t\tdev_addr, errno, strerror(errno));\n+\t\tret = -1;\n+\t\tgoto close_group;\n+\t}\n+\n+\tif (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) {\n+\t\tRTE_LOG(ERR, EAL, \"%s VFIO group is not viable!\\n\", dev_addr);\n+\t\tret = -1;\n+\t\tgoto close_group;\n+\t}\n+\n+\tif (!(group_status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET)) {\n+\t\tif (ioctl(vfio_group_fd, VFIO_GROUP_SET_CONTAINER,\n+\t\t\t    &container)) {\n+\t\t\tRTE_LOG(ERR, EAL, \"%s cannot add VFIO group to container, error %i (%s)\\n\",\n+\t\t\t\tdev_addr, errno, strerror(errno));\n+\t\t\tret = -1;\n+\t\t\tgoto close_group;\n+\t\t}\n+\t}\n+\n+\tif (ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)) {\n+\t\tRTE_LOG(ERR, EAL, \"%s cannot set iommu, error %i (%s)\\n\",\n+\t\t\tdev_addr, errno, strerror(errno));\n+\t\tret = -1;\n+\t\tgoto close_group;\n+\t}\n+\n+\tvfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, dev_addr);\n+\tif (vfio_dev_fd < 0) {\n+\t\t/* if we cannot get a device fd, this implies a problem with\n+\t\t * the VFIO group or the container not having IOMMU configured.\n+\t\t */\n+\t\tRTE_LOG(ERR, EAL, \"Getting a vfio_dev_fd for %s failed errno %d\\n\",\n+\t\t\tdev_addr, errno);\n+\t\tret = -1;\n+\t\tgoto close_group;\n+\t}\n+\n+\t/* vendor_id */\n+\tif (pread64(vfio_dev_fd, &pci_id->vendor_id, sizeof(uint16_t),\n+\t\t      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +\n+\t\t      PCI_VENDOR_ID) != sizeof(uint16_t)) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot read VendorID from PCI config space\\n\");\n+\t\tret = -1;\n+\t\tgoto close_device;\n+\t}\n+\n+\t/* device_id */\n+\tif (pread64(vfio_dev_fd, &pci_id->device_id, sizeof(uint16_t),\n+\t\t      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +\n+\t\t      PCI_DEVICE_ID) != sizeof(uint16_t)) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot read DeviceID from PCI config space\\n\");\n+\t\tret = -1;\n+\t\tgoto close_device;\n+\t}\n+\n+\t/* subsystem_vendor_id */\n+\tif (pread64(vfio_dev_fd, &pci_id->subsystem_vendor_id, sizeof(uint16_t),\n+\t\t      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +\n+\t\t      PCI_SUBSYSTEM_VENDOR_ID) != sizeof(uint16_t)) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot read SubVendorID from PCI config space\\n\");\n+\t\tret = -1;\n+\t\tgoto close_device;\n+\t}\n+\n+\t/* subsystem_device_id */\n+\tif (pread64(vfio_dev_fd, &pci_id->subsystem_device_id, sizeof(uint16_t),\n+\t\t      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +\n+\t\t      PCI_SUBSYSTEM_ID) != sizeof(uint16_t)) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot read SubDeviceID from PCI config space\\n\");\n+\t\tret = -1;\n+\t\tgoto close_device;\n+\t}\n+\n+\t/* class_id */\n+\tif (pread64(vfio_dev_fd, &class, sizeof(uint32_t),\n+\t\t      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +\n+\t\t      PCI_CLASS_REVISION) != sizeof(uint32_t)) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot read ClassID from PCI config space\\n\");\n+\t\tret = -1;\n+\t\tgoto close_device;\n+\t}\n+\tpci_id->class_id = class >> 8;\n+\n+close_device:\n+\tif (close(vfio_dev_fd) < 0) {\n+\t\tRTE_LOG(INFO, EAL, \"Error when closing VFIO device for %s\\n\",\n+\t\t\tdev_addr);\n+\t\tret = -1;\n+\t}\n+\n+close_group:\n+\tif (close(vfio_group_fd) < 0) {\n+\t\tRTE_LOG(INFO, EAL, \"Error when closing VFIO group for %s\\n\",\n+\t\t\tdev_addr);\n+\t\tret = -1;\n+\t}\n+\n+close_container:\n+\tif (close(container) < 0) {\n+\t\tRTE_LOG(INFO, EAL, \"Error when closing VFIO container\\n\");\n+\t\tret = -1;\n+\t}\n+\n+out:\n+\treturn ret;\n+}\n+\n+static int vfio_pci_probe(struct rte_mdev_driver *mdev_drv __rte_unused,\n+\t\t\t  struct rte_mdev_device *mdev_dev)\n+{\n+\tchar name[RTE_UUID_STRLEN];\n+\tstruct rte_pci_device *dev;\n+\tstruct rte_bus *bus;\n+\tint ret;\n+\n+\tbus = rte_bus_find_by_name(\"pci\");\n+\tif (bus == NULL) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot find bus pci\\n\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tif (bus->plug == NULL) {\n+\t\tRTE_LOG(ERR, EAL, \"Function plug not supported by bus (%s)\\n\",\n+\t\t\tbus->name);\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tdev = malloc(sizeof(*dev));\n+\tif (dev == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tmemset(dev, 0, sizeof(*dev));\n+\tdev->device.bus = &rte_pci_bus.bus;\n+\trte_uuid_unparse(mdev_dev->addr, name, sizeof(name));\n+\n+\tif (get_pci_id(rte_mdev_get_sysfs_path(), name, &dev->id)) {\n+\t\tfree(dev);\n+\t\treturn -1;\n+\t}\n+\n+\tsnprintf(dev->name, sizeof(dev->name), \"%s\", name);\n+\tdev->device.name = dev->name;\n+\tdev->kdrv = RTE_KDRV_VFIO;\n+\tdev->use_uuid = 1;\n+\trte_uuid_copy(dev->uuid, mdev_dev->addr);\n+\n+\t// TODO: dev->device.devargs, etc\n+\n+\tmemset(&dev->addr, -1, sizeof(dev->addr)); // XXX: TODO\n+\n+\t/* device is valid, add to the list (sorted) */\n+\tif (TAILQ_EMPTY(&rte_pci_bus.device_list)) {\n+\t\trte_pci_add_device(dev);\n+\t} else {\n+\t\tstruct rte_pci_device *dev2;\n+\t\tint ret;\n+\n+\t\tTAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {\n+\t\t\t// XXX\n+\t\t\tret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);\n+\t\t\tif (ret == 0)\n+\t\t\t\tret = strncmp(dev->name, dev2->name,\n+\t\t\t\t\t      sizeof(dev->name));\n+\t\t\tif (ret > 0)\n+\t\t\t\tcontinue;\n+\t\t\tif (ret < 0) {\n+\t\t\t\trte_pci_insert_device(dev2, dev);\n+\t\t\t\tgoto plug;\n+\t\t\t}\n+\t\t\t/* already registered */\n+\t\t\tfree(dev);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\trte_pci_add_device(dev);\n+\t}\n+\n+plug:\n+\tret = bus->plug(&dev->device);\n+\tif (ret != 0) {\n+\t\trte_pci_remove_device(dev);\n+\t\tfree(dev);\n+\t} else {\n+\t\tmdev_dev->private = dev;\n+\t}\n+\treturn ret;\n+}\n+\n+static int vfio_pci_remove(struct rte_mdev_device *mdev_dev)\n+{\n+\tstruct rte_pci_device *dev = mdev_dev->private;\n+\tstruct rte_bus *bus;\n+\tint ret;\n+\n+\tif (dev == NULL)\n+\t\treturn 0;\n+\n+\tbus = rte_bus_find_by_name(\"pci\");\n+\tif (bus == NULL) {\n+\t\tRTE_LOG(ERR, EAL, \"Cannot find bus pci\\n\");\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tif (bus->unplug == NULL) {\n+\t\tRTE_LOG(ERR, EAL, \"Function unplug not supported by bus (%s)\\n\",\n+\t\t\tbus->name);\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tret = bus->unplug(&dev->device);\n+\tif (ret == 0)\n+\t\tmdev_dev->private = NULL;\n+\n+\treturn ret;\n+}\n+\n+static struct rte_mdev_driver vfio_pci_drv = {\n+\t.dev_api = RTE_MDEV_DEV_API_VFIO_PCI,\n+\t.probe = vfio_pci_probe,\n+\t.remove = vfio_pci_remove\n+};\n+\n+RTE_MDEV_REGISTER_DRIVER(mdev_vfio_pci, vfio_pci_drv);\ndiff --git a/drivers/bus/pci/meson.build b/drivers/bus/pci/meson.build\nindex a3140ff97..c3e884657 100644\n--- a/drivers/bus/pci/meson.build\n+++ b/drivers/bus/pci/meson.build\n@@ -11,8 +11,10 @@ sources = files('pci_common.c',\n if host_machine.system() == 'linux'\n \tsources += files('linux/pci.c',\n \t\t\t'linux/pci_uio.c',\n-\t\t\t'linux/pci_vfio.c')\n+\t\t\t'linux/pci_vfio.c',\n+\t\t\t'linux/pci_vfio_mdev.c')\n \tincludes += include_directories('linux')\n+\tdeps += ['bus_mdev']\n else\n \tsources += files('bsd/pci.c')\n \tincludes += include_directories('bsd')\ndiff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c\nindex 704b9d71a..6b47333e6 100644\n--- a/drivers/bus/pci/pci_common.c\n+++ b/drivers/bus/pci/pci_common.c\n@@ -124,21 +124,17 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,\n {\n \tint ret;\n \tbool already_probed;\n-\tstruct rte_pci_addr *loc;\n \n \tif ((dr == NULL) || (dev == NULL))\n \t\treturn -EINVAL;\n \n-\tloc = &dev->addr;\n-\n \t/* The device is not blacklisted; Check if driver supports it */\n \tif (!rte_pci_match(dr, dev))\n \t\t/* Match of device and driver failed */\n \t\treturn 1;\n \n-\tRTE_LOG(INFO, EAL, \"PCI device \"PCI_PRI_FMT\" on NUMA socket %i\\n\",\n-\t\t\tloc->domain, loc->bus, loc->devid, loc->function,\n-\t\t\tdev->device.numa_node);\n+\tRTE_LOG(INFO, EAL, \"PCI device %s on NUMA socket %i\\n\",\n+\t\tdev->name, dev->device.numa_node);\n \n \t/* no initialization when blacklisted, return without error */\n \tif (dev->device.devargs != NULL &&\n@@ -208,7 +204,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,\n static int\n rte_pci_detach_dev(struct rte_pci_device *dev)\n {\n-\tstruct rte_pci_addr *loc;\n \tstruct rte_pci_driver *dr;\n \tint ret = 0;\n \n@@ -216,11 +211,9 @@ rte_pci_detach_dev(struct rte_pci_device *dev)\n \t\treturn -EINVAL;\n \n \tdr = dev->driver;\n-\tloc = &dev->addr;\n \n-\tRTE_LOG(DEBUG, EAL, \"PCI device \"PCI_PRI_FMT\" on NUMA socket %i\\n\",\n-\t\t\tloc->domain, loc->bus, loc->devid,\n-\t\t\tloc->function, dev->device.numa_node);\n+\tRTE_LOG(DEBUG, EAL, \"PCI device %s on NUMA socket %i\\n\",\n+\t\tdev->name, dev->device.numa_node);\n \n \tRTE_LOG(DEBUG, EAL, \"  remove driver: %x:%x %s\\n\", dev->id.vendor_id,\n \t\t\tdev->id.device_id, dr->driver.name);\n@@ -387,7 +380,7 @@ rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,\n }\n \n /* Remove a device from PCI bus */\n-static void\n+void\n rte_pci_remove_device(struct rte_pci_device *pci_dev)\n {\n \tTAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);\ndiff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h\nindex 13c3324bb..d5815ee44 100644\n--- a/drivers/bus/pci/private.h\n+++ b/drivers/bus/pci/private.h\n@@ -67,6 +67,15 @@ void rte_pci_add_device(struct rte_pci_device *pci_dev);\n void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,\n \t\tstruct rte_pci_device *new_pci_dev);\n \n+/**\n+ * Remove a PCI device from the PCI Bus.\n+ *\n+ * @param pci_dev\n+ *\tPCI device to remove\n+ * @return void\n+ */\n+void rte_pci_remove_device(struct rte_pci_device *pci_dev);\n+\n /**\n  * Update a pci device object by asking the kernel for the latest information.\n  *\ndiff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h\nindex 06e004cd3..465a44935 100644\n--- a/drivers/bus/pci/rte_bus_pci.h\n+++ b/drivers/bus/pci/rte_bus_pci.h\n@@ -51,6 +51,13 @@ TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);\n \n struct rte_devargs;\n \n+/* It's RTE_UUID_STRLEN, which is bigger than PCI_PRI_STR_SIZE. */\n+#define RTE_PCI_NAME_LEN\t\t(36 + 1)\n+\n+// XXX: we can't include rte_uuid.h directly due to the conflicts\n+//      introduced by stdbool.h\n+typedef unsigned char rte_uuid_t[16];\n+\n /**\n  * A structure describing a PCI device.\n  */\n@@ -58,6 +65,8 @@ struct rte_pci_device {\n \tTAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */\n \tstruct rte_device device;           /**< Inherit core device */\n \tstruct rte_pci_addr addr;           /**< PCI location. */\n+\trte_uuid_t uuid;                    /**< Mdev location. */\n+\tuint8_t use_uuid;                   /**< True if uuid field valid. */\n \tstruct rte_pci_id id;               /**< PCI ID. */\n \tstruct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];\n \t\t\t\t\t    /**< PCI Memory Resource */\n@@ -65,7 +74,7 @@ struct rte_pci_device {\n \tstruct rte_pci_driver *driver;      /**< PCI driver used in probing */\n \tuint16_t max_vfs;                   /**< sriov enable if not zero */\n \tenum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */\n-\tchar name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */\n+\tchar name[RTE_PCI_NAME_LEN];        /**< PCI/Mdev location (ASCII) */\n \tstruct rte_intr_handle vfio_req_intr_handle;\n \t\t\t\t/**< Handler of VFIO request interrupt */\n };\n",
    "prefixes": [
        "RFC",
        "3/3"
    ]
}