get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 85392,
    "url": "https://patches.dpdk.org/api/patches/85392/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20201218073851.93609-4-chenbo.xia@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20201218073851.93609-4-chenbo.xia@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201218073851.93609-4-chenbo.xia@intel.com",
    "date": "2020-12-18T07:38:45",
    "name": "[3/9] vfio_user: implement device and region related APIs",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5a88c675a73c48b6cbed00a06f28b2aab73e71db",
    "submitter": {
        "id": 1276,
        "url": "https://patches.dpdk.org/api/people/1276/?format=api",
        "name": "Chenbo Xia",
        "email": "chenbo.xia@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20201218073851.93609-4-chenbo.xia@intel.com/mbox/",
    "series": [
        {
            "id": 14361,
            "url": "https://patches.dpdk.org/api/series/14361/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=14361",
            "date": "2020-12-18T07:38:42",
            "name": "Introduce vfio-user library",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/14361/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/85392/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/85392/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 93316A09F6;\n\tFri, 18 Dec 2020 08:55:14 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id F0FD0CA64;\n\tFri, 18 Dec 2020 08:54:18 +0100 (CET)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n by dpdk.org (Postfix) with ESMTP id C6EA1CA63\n for <dev@dpdk.org>; Fri, 18 Dec 2020 08:54:17 +0100 (CET)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 17 Dec 2020 23:54:17 -0800",
            "from npg-dpdk-virtio-xiachenbo-nw.sh.intel.com ([10.67.119.123])\n by fmsmga008.fm.intel.com with ESMTP; 17 Dec 2020 23:54:14 -0800"
        ],
        "IronPort-SDR": [
            "\n 8z9hqLxhUjkyyK9hwf9lsEgoblvUJpjiF504+KsGlibsZ69+cTbnIvNjimrHIeRYUxSHp4dyD0\n tZ+Lv9J191Mg==",
            "\n lQNiTY8hYCVSiZgVLptY2bANvNT1CDcEh50plGl/yEAFOzg2sHBmd6+9z06TmetZEfylfmoE5P\n VDsRsudzb3LA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9838\"; a=\"260126150\"",
            "E=Sophos;i=\"5.78,429,1599548400\"; d=\"scan'208\";a=\"260126150\"",
            "E=Sophos;i=\"5.78,429,1599548400\"; d=\"scan'208\";a=\"340270339\""
        ],
        "X-ExtLoop1": "1",
        "From": "Chenbo Xia <chenbo.xia@intel.com>",
        "To": "dev@dpdk.org,\n\tthomas@monjalon.net,\n\tdavid.marchand@redhat.com",
        "Cc": "stephen@networkplumber.org, cunming.liang@intel.com, xiuchun.lu@intel.com,\n miao.li@intel.com, jingjing.wu@intel.com",
        "Date": "Fri, 18 Dec 2020 15:38:45 +0800",
        "Message-Id": "<20201218073851.93609-4-chenbo.xia@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20201218073851.93609-1-chenbo.xia@intel.com>",
        "References": "<20201218073851.93609-1-chenbo.xia@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 3/9] vfio_user: implement device and region\n\trelated APIs",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch introduces device and region related APIs, which are\nrte_vfio_user_set_dev_info() and rte_vfio_user_set_reg_info().\nThe corresponding vfio-user command handling is also added with\nthe definition of all vfio-user command identity.\n\nSigned-off-by: Chenbo Xia <chenbo.xia@intel.com>\nSigned-off-by: Xiuchun Lu <xiuchun.lu@intel.com>\n---\n lib/librte_vfio_user/rte_vfio_user.h    |  60 ++++++\n lib/librte_vfio_user/version.map        |   2 +\n lib/librte_vfio_user/vfio_user_base.c   |  12 ++\n lib/librte_vfio_user/vfio_user_base.h   |  32 +++-\n lib/librte_vfio_user/vfio_user_server.c | 232 ++++++++++++++++++++++++\n lib/librte_vfio_user/vfio_user_server.h |   2 +\n 6 files changed, 339 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/lib/librte_vfio_user/rte_vfio_user.h b/lib/librte_vfio_user/rte_vfio_user.h\nindex 0d4f6c1be2..8a999c7aa0 100644\n--- a/lib/librte_vfio_user/rte_vfio_user.h\n+++ b/lib/librte_vfio_user/rte_vfio_user.h\n@@ -5,13 +5,35 @@\n #ifndef _RTE_VFIO_USER_H\n #define _RTE_VFIO_USER_H\n \n+#include <linux/vfio.h>\n+\n #include <rte_compat.h>\n \n+struct rte_vfio_user_reg_info;\n+\n+typedef ssize_t (*rte_vfio_user_reg_acc_t)(struct rte_vfio_user_reg_info *reg,\n+\t\tchar *buf, size_t count, loff_t pos, bool iswrite);\n+\n+struct rte_vfio_user_reg_info {\n+\trte_vfio_user_reg_acc_t rw;\n+\tvoid *base;\n+\tint fd;\n+\tstruct vfio_region_info *info;\n+\tvoid *priv;\n+};\n+\n+struct rte_vfio_user_regions {\n+\tuint32_t reg_num;\n+\tstruct rte_vfio_user_reg_info reg_info[];\n+};\n+\n /**\n  *  Below APIs are for vfio-user server (device provider) to use:\n  *\t*rte_vfio_user_register\n  *\t*rte_vfio_user_unregister\n  *\t*rte_vfio_user_start\n+ *\t*rte_vfio_user_set_dev_info\n+ *\t*rte_vfio_user_set_reg_info\n  */\n \n /**\n@@ -48,4 +70,42 @@ int rte_vfio_user_unregister(const char *sock_addr);\n __rte_experimental\n int rte_vfio_user_start(const char *sock_addr);\n \n+/**\n+ * Set the device information for a vfio-user device.\n+ *\n+ * This information must be set before calling rte_vfio_user_start, and should\n+ * not be updated after start. Update after start can be done by unregistration\n+ * and re-registration, and then the device-level change can be detected by\n+ * vfio-user client.\n+ *\n+ * @param sock_addr\n+ *   Unix domain socket address\n+ * @param dev_info\n+ *   Device information for the vfio-user device\n+ * @return\n+ *   0 on success, -1 on failure\n+ */\n+__rte_experimental\n+int rte_vfio_user_set_dev_info(const char *sock_addr,\n+\tstruct vfio_device_info *dev_info);\n+\n+/**\n+ * Set the region information for a vfio-user device.\n+ *\n+ * This information must be set before calling rte_vfio_user_start, and should\n+ * not be updated after start. Update after start can be done by unregistration\n+ * and re-registration, and then the device-level change can be detected by\n+ * vfio-user client.\n+ *\n+ * @param sock_addr\n+ *   Unix domain socket address\n+ * @param reg\n+ *   Region information for the vfio-user device\n+ * @return\n+ *   0 on success, -1 on failure\n+ */\n+__rte_experimental\n+int rte_vfio_user_set_reg_info(const char *sock_addr,\n+\tstruct rte_vfio_user_regions *reg);\n+\n #endif\ndiff --git a/lib/librte_vfio_user/version.map b/lib/librte_vfio_user/version.map\nindex e53095eda8..0f4f5acba5 100644\n--- a/lib/librte_vfio_user/version.map\n+++ b/lib/librte_vfio_user/version.map\n@@ -4,6 +4,8 @@ EXPERIMENTAL {\n \trte_vfio_user_register;\n \trte_vfio_user_unregister;\n \trte_vfio_user_start;\n+\trte_vfio_user_set_dev_info;\n+\trte_vfio_user_set_reg_info;\n \n \tlocal: *;\n };\ndiff --git a/lib/librte_vfio_user/vfio_user_base.c b/lib/librte_vfio_user/vfio_user_base.c\nindex bbad553e0a..4960589519 100644\n--- a/lib/librte_vfio_user/vfio_user_base.c\n+++ b/lib/librte_vfio_user/vfio_user_base.c\n@@ -13,6 +13,18 @@ int vfio_user_log_level;\n const char *vfio_user_msg_str[VFIO_USER_MAX] = {\n \t[VFIO_USER_NONE] = \"VFIO_USER_NONE\",\n \t[VFIO_USER_VERSION] = \"VFIO_USER_VERSION\",\n+\t[VFIO_USER_DMA_MAP] = \"VFIO_USER_DMA_MAP\",\n+\t[VFIO_USER_DMA_UNMAP] = \"VFIO_USER_DMA_UNMAP\",\n+\t[VFIO_USER_DEVICE_GET_INFO] = \"VFIO_USER_DEVICE_GET_INFO\",\n+\t[VFIO_USER_DEVICE_GET_REGION_INFO] = \"VFIO_USER_GET_REGION_INFO\",\n+\t[VFIO_USER_DEVICE_GET_IRQ_INFO] = \"VFIO_USER_DEVICE_GET_IRQ_INFO\",\n+\t[VFIO_USER_DEVICE_SET_IRQS] = \"VFIO_USER_DEVICE_SET_IRQS\",\n+\t[VFIO_USER_REGION_READ] = \"VFIO_USER_REGION_READ\",\n+\t[VFIO_USER_REGION_WRITE] = \"VFIO_USER_REGION_WRITE\",\n+\t[VFIO_USER_DMA_READ] = \"VFIO_USER_DMA_READ\",\n+\t[VFIO_USER_DMA_WRITE] = \"VFIO_USER_DMA_WRITE\",\n+\t[VFIO_USER_VM_INTERRUPT] = \"VFIO_USER_VM_INTERRUPT\",\n+\t[VFIO_USER_DEVICE_RESET] = \"VFIO_USER_DEVICE_RESET\",\n };\n \n inline void vfio_user_close_msg_fds(VFIO_USER_MSG *msg)\ndiff --git a/lib/librte_vfio_user/vfio_user_base.h b/lib/librte_vfio_user/vfio_user_base.h\nindex 926cecfa7a..0d8abde816 100644\n--- a/lib/librte_vfio_user/vfio_user_base.h\n+++ b/lib/librte_vfio_user/vfio_user_base.h\n@@ -11,6 +11,8 @@\n \n #define VFIO_USER_VERSION_MAJOR 1\n #define VFIO_USER_VERSION_MINOR 0\n+#define VFIO_USER_MAX_RSVD 512\n+#define VFIO_USER_MAX_RW_DATA 512\n #define VFIO_USER_MAX_FD 1024\n #define VFIO_USER_MAX_VERSION_DATA 512\n \n@@ -30,7 +32,19 @@ struct vfio_user_socket {\n typedef enum VFIO_USER_CMD_TYPE {\n \tVFIO_USER_NONE = 0,\n \tVFIO_USER_VERSION = 1,\n-\tVFIO_USER_MAX = 2,\n+\tVFIO_USER_DMA_MAP = 2,\n+\tVFIO_USER_DMA_UNMAP = 3,\n+\tVFIO_USER_DEVICE_GET_INFO = 4,\n+\tVFIO_USER_DEVICE_GET_REGION_INFO = 5,\n+\tVFIO_USER_DEVICE_GET_IRQ_INFO = 6,\n+\tVFIO_USER_DEVICE_SET_IRQS = 7,\n+\tVFIO_USER_REGION_READ = 8,\n+\tVFIO_USER_REGION_WRITE = 9,\n+\tVFIO_USER_DMA_READ = 10,\n+\tVFIO_USER_DMA_WRITE = 11,\n+\tVFIO_USER_VM_INTERRUPT = 12,\n+\tVFIO_USER_DEVICE_RESET = 13,\n+\tVFIO_USER_MAX = 14,\n } VFIO_USER_CMD_TYPE;\n \n struct vfio_user_version {\n@@ -40,6 +54,19 @@ struct vfio_user_version {\n \tuint8_t ver_data[VFIO_USER_MAX_VERSION_DATA];\n };\n \n+struct vfio_user_reg {\n+\tstruct vfio_region_info reg_info;\n+\t/* Reserved for region capability list */\n+\tuint8_t rsvd[VFIO_USER_MAX_RSVD];\n+};\n+\n+struct vfio_user_reg_rw {\n+\tuint64_t reg_offset;\n+\tuint32_t reg_idx;\n+\tuint32_t size;\n+\tchar data[VFIO_USER_MAX_RW_DATA];\n+};\n+\n typedef struct vfio_user_msg {\n \tuint16_t msg_id;\n \tuint16_t cmd;\n@@ -52,6 +79,9 @@ typedef struct vfio_user_msg {\n \tuint32_t err;\t\t\t\t/* Valid in reply, optional */\n \tunion {\n \t\tstruct vfio_user_version ver;\n+\t\tstruct vfio_device_info dev_info;\n+\t\tstruct vfio_user_reg reg_info;\n+\t\tstruct vfio_user_reg_rw reg_rw;\n \t} payload;\n \tint fds[VFIO_USER_MAX_FD];\n \tint fd_num;\ndiff --git a/lib/librte_vfio_user/vfio_user_server.c b/lib/librte_vfio_user/vfio_user_server.c\nindex 545c779fb0..d882f2ccbe 100644\n--- a/lib/librte_vfio_user/vfio_user_server.c\n+++ b/lib/librte_vfio_user/vfio_user_server.c\n@@ -5,6 +5,7 @@\n #include <unistd.h>\n #include <fcntl.h>\n #include <pthread.h>\n+#include <inttypes.h>\n #include <sys/socket.h>\n #include <sys/un.h>\n \n@@ -38,9 +39,155 @@ static int vfio_user_negotiate_version(struct vfio_user_server *dev,\n \t\treturn -ENOTSUP;\n }\n \n+static int vfio_user_device_get_info(struct vfio_user_server *dev,\n+\tVFIO_USER_MSG *msg)\n+{\n+\tstruct vfio_device_info *dev_info = &msg->payload.dev_info;\n+\n+\tif (vfio_user_check_msg_fdnum(msg, 0) != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (msg->size != sizeof(*dev_info) + VFIO_USER_MSG_HDR_SIZE) {\n+\t\tVFIO_USER_LOG(ERR, \"Invalid message for get dev info\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(dev_info, dev->dev_info, sizeof(*dev_info));\n+\n+\tVFIO_USER_LOG(DEBUG, \"Device info: argsz(0x%x), flags(0x%x), \"\n+\t\t\"regions(%u), irqs(%u)\\n\", dev_info->argsz, dev_info->flags,\n+\t\tdev_info->num_regions, dev_info->num_irqs);\n+\n+\treturn 0;\n+}\n+\n+static int vfio_user_device_get_reg_info(struct vfio_user_server *dev,\n+\tVFIO_USER_MSG *msg)\n+{\n+\tstruct vfio_user_reg *reg = &msg->payload.reg_info;\n+\tstruct rte_vfio_user_reg_info *reg_info;\n+\tstruct vfio_region_info *vinfo;\n+\n+\tif (vfio_user_check_msg_fdnum(msg, 0) != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (msg->size > sizeof(*reg) + VFIO_USER_MSG_HDR_SIZE ||\n+\t\tdev->reg->reg_num <= reg->reg_info.index) {\n+\t\tVFIO_USER_LOG(ERR, \"Invalid message for get dev info\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treg_info = &dev->reg->reg_info[reg->reg_info.index];\n+\tvinfo = reg_info->info;\n+\tmemcpy(reg, vinfo, vinfo->argsz);\n+\n+\tif (reg_info->fd != -1) {\n+\t\tmsg->fd_num = 1;\n+\t\tmsg->fds[0] = reg_info->fd;\n+\t}\n+\n+\tVFIO_USER_LOG(DEBUG, \"Region(%u) info: addr(0x%\" PRIx64 \"), fd(%d), \"\n+\t\t\"sz(0x%llx), argsz(0x%x), c_off(0x%x), flags(0x%x) \"\n+\t\t\"off(0x%llx)\\n\", vinfo->index, (uint64_t)reg_info->base,\n+\t\treg_info->fd, vinfo->size, vinfo->argsz, vinfo->cap_offset,\n+\t\tvinfo->flags, vinfo->offset);\n+\n+\treturn 0;\n+}\n+\n+static int vfio_user_region_read(struct vfio_user_server *dev,\n+\tVFIO_USER_MSG *msg)\n+{\n+\tstruct vfio_user_reg_rw *rw = &msg->payload.reg_rw;\n+\tstruct rte_vfio_user_regions *reg = dev->reg;\n+\tstruct rte_vfio_user_reg_info *reg_info;\n+\tsize_t count;\n+\n+\tif (vfio_user_check_msg_fdnum(msg, 0) != 0)\n+\t\treturn -EINVAL;\n+\n+\treg_info = &reg->reg_info[rw->reg_idx];\n+\n+\tif (rw->reg_idx >= reg->reg_num ||\n+\t\trw->size > VFIO_USER_MAX_RW_DATA ||\n+\t\trw->reg_offset >= reg_info->info->size ||\n+\t\trw->reg_offset + rw->size > reg_info->info->size) {\n+\t\tVFIO_USER_LOG(ERR, \"Invalid read region request\\n\");\n+\t\trw->size = 0;\n+\t\treturn 0;\n+\t}\n+\n+\tVFIO_USER_LOG(DEBUG, \"Read Region(%u): offset(0x%\" PRIx64 \"),\"\n+\t\t\"size(0x%x)\\n\", rw->reg_idx, rw->reg_offset, rw->size);\n+\n+\tif (reg_info->rw) {\n+\t\tcount = reg_info->rw(reg_info, msg->payload.reg_rw.data,\n+\t\t\t\trw->size, rw->reg_offset, 0);\n+\t\trw->size = count;\n+\t\tmsg->size += count;\n+\t\treturn 0;\n+\t}\n+\n+\tmemcpy(&msg->payload.reg_rw.data,\n+\t\t(uint8_t *)reg_info->base + rw->reg_offset, rw->size);\n+\tmsg->size += rw->size;\n+\treturn 0;\n+}\n+\n+static int vfio_user_region_write(struct vfio_user_server *dev,\n+\tVFIO_USER_MSG *msg)\n+{\n+\tstruct vfio_user_reg_rw *rw = &msg->payload.reg_rw;\n+\tstruct rte_vfio_user_regions *reg = dev->reg;\n+\tstruct rte_vfio_user_reg_info *reg_info;\n+\tsize_t count;\n+\n+\tif (vfio_user_check_msg_fdnum(msg, 0) != 0)\n+\t\treturn -EINVAL;\n+\n+\tif (rw->reg_idx >= reg->reg_num) {\n+\t\tVFIO_USER_LOG(ERR, \"Write a non-existed region\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treg_info = &reg->reg_info[rw->reg_idx];\n+\n+\tVFIO_USER_LOG(DEBUG, \"Write Region(%u): offset(0x%\" PRIx64 \"),\"\n+\t\t\"size(0x%x)\\n\", rw->reg_idx, rw->reg_offset, rw->size);\n+\n+\tif (reg_info->rw) {\n+\t\tcount = reg_info->rw(reg_info, msg->payload.reg_rw.data,\n+\t\t\t\trw->size, rw->reg_offset, 1);\n+\t\tif (count < rw->size) {\n+\t\t\tVFIO_USER_LOG(ERR, \"Write region %d failed\\n\",\n+\t\t\t\trw->reg_idx);\n+\t\t\treturn -EIO;\n+\t\t}\n+\t\trw->size = 0;\n+\t\treturn 0;\n+\t}\n+\n+\tmemcpy((uint8_t *)reg_info->base + rw->reg_offset,\n+\t\t&msg->payload.reg_rw.data, rw->size);\n+\trw->size = 0;\n+\treturn 0;\n+}\n+\n static vfio_user_msg_handler_t vfio_user_msg_handlers[VFIO_USER_MAX] = {\n \t[VFIO_USER_NONE] = NULL,\n \t[VFIO_USER_VERSION] = vfio_user_negotiate_version,\n+\t[VFIO_USER_DMA_MAP] = NULL,\n+\t[VFIO_USER_DMA_UNMAP] = NULL,\n+\t[VFIO_USER_DEVICE_GET_INFO] = vfio_user_device_get_info,\n+\t[VFIO_USER_DEVICE_GET_REGION_INFO] = vfio_user_device_get_reg_info,\n+\t[VFIO_USER_DEVICE_GET_IRQ_INFO] = NULL,\n+\t[VFIO_USER_DEVICE_SET_IRQS] = NULL,\n+\t[VFIO_USER_REGION_READ] = vfio_user_region_read,\n+\t[VFIO_USER_REGION_WRITE] = vfio_user_region_write,\n+\t[VFIO_USER_DMA_READ] = NULL,\n+\t[VFIO_USER_DMA_WRITE] = NULL,\n+\t[VFIO_USER_VM_INTERRUPT] = NULL,\n+\t[VFIO_USER_DEVICE_RESET] = NULL,\n };\n \n static struct vfio_user_server_socket *\n@@ -549,6 +696,13 @@ vfio_user_start_server(struct vfio_user_server_socket *sk)\n \t\treturn 0;\n \t}\n \n+\t/* All the info must be set before start */\n+\tif (!dev->dev_info || !dev->reg) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to start, \"\n+\t\t\t\"dev/reg info must be set before start\\n\");\n+\t\treturn -1;\n+\t}\n+\n \tunlink(path);\n \tret = bind(fd, (struct sockaddr *)&sk->un, sizeof(sk->un));\n \tif (ret < 0) {\n@@ -688,3 +842,81 @@ int rte_vfio_user_start(const char *sock_addr)\n \tpthread_mutex_unlock(&vfio_ep_sock.mutex);\n \treturn -1;\n }\n+\n+int rte_vfio_user_set_dev_info(const char *sock_addr,\n+\tstruct vfio_device_info *dev_info)\n+{\n+\tstruct vfio_user_server *dev;\n+\tstruct vfio_user_server_socket *sk;\n+\tint dev_id;\n+\n+\tif (!dev_info)\n+\t\treturn -1;\n+\n+\tpthread_mutex_lock(&vfio_ep_sock.mutex);\n+\tsk = find_vfio_user_socket(sock_addr);\n+\tpthread_mutex_unlock(&vfio_ep_sock.mutex);\n+\n+\tif (!sk) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set device info with sock_addr \"\n+\t\t\t\"%s: addr not registered.\\n\", sock_addr);\n+\t\treturn -1;\n+\t}\n+\n+\tdev_id = sk->sock.dev_id;\n+\tdev = vfio_user_get_device(dev_id);\n+\tif (!dev) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set device info:\"\n+\t\t\t\"device %d not found.\\n\", dev_id);\n+\t\treturn -1;\n+\t}\n+\n+\tif (dev->started) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set device info for device %d\\n\"\n+\t\t\t \", device already started\\n\", dev_id);\n+\t\treturn -1;\n+\t}\n+\n+\tdev->dev_info = dev_info;\n+\n+\treturn 0;\n+}\n+\n+int rte_vfio_user_set_reg_info(const char *sock_addr,\n+\tstruct rte_vfio_user_regions *reg)\n+{\n+\tstruct vfio_user_server *dev;\n+\tstruct vfio_user_server_socket *sk;\n+\tint dev_id;\n+\n+\tif (!reg)\n+\t\treturn -1;\n+\n+\tpthread_mutex_lock(&vfio_ep_sock.mutex);\n+\tsk = find_vfio_user_socket(sock_addr);\n+\tpthread_mutex_unlock(&vfio_ep_sock.mutex);\n+\n+\tif (!sk) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set region info with sock_addr:\"\n+\t\t\t\"%s: addr not registered.\\n\", sock_addr);\n+\t\treturn -1;\n+\t}\n+\n+\tdev_id = sk->sock.dev_id;\n+\tdev = vfio_user_get_device(dev_id);\n+\tif (!dev) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set region info:\"\n+\t\t\t\"device %d not found.\\n\", dev_id);\n+\t\treturn -1;\n+\t}\n+\n+\tif (dev->started) {\n+\t\tVFIO_USER_LOG(ERR, \"Failed to set region info for device %d\\n\"\n+\t\t\t \", device already started\\n\", dev_id);\n+\t\treturn -1;\n+\t}\n+\n+\tdev->reg = reg;\n+\n+\treturn 0;\n+}\ndiff --git a/lib/librte_vfio_user/vfio_user_server.h b/lib/librte_vfio_user/vfio_user_server.h\nindex 00e3f6353d..e8fb61cb3e 100644\n--- a/lib/librte_vfio_user/vfio_user_server.h\n+++ b/lib/librte_vfio_user/vfio_user_server.h\n@@ -16,6 +16,8 @@ struct vfio_user_server {\n \tuint32_t msg_id;\n \tchar sock_addr[PATH_MAX];\n \tstruct vfio_user_version ver;\n+\tstruct vfio_device_info *dev_info;\n+\tstruct rte_vfio_user_regions *reg;\n };\n \n typedef int (*event_handler)(int fd, void *data);\n",
    "prefixes": [
        "3/9"
    ]
}