get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 32473,
    "url": "https://patches.dpdk.org/api/patches/32473/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/2d5b9ea71a32658efa24766933d07b5d2e29f25f.1513681966.git.anatoly.burakov@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": "<2d5b9ea71a32658efa24766933d07b5d2e29f25f.1513681966.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/2d5b9ea71a32658efa24766933d07b5d2e29f25f.1513681966.git.anatoly.burakov@intel.com",
    "date": "2017-12-19T11:14:49",
    "name": "[dpdk-dev,RFC,v2,22/23] vfio: allow to map other memory regions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "48203a9ce86a33313f57cf4e2a86b8cc2a3f3a63",
    "submitter": {
        "id": 4,
        "url": "https://patches.dpdk.org/api/people/4/?format=api",
        "name": "Anatoly Burakov",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/2d5b9ea71a32658efa24766933d07b5d2e29f25f.1513681966.git.anatoly.burakov@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/32473/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/32473/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 BDDA81B22B;\n\tTue, 19 Dec 2017 12:15:32 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 2FEFA1B01F\n\tfor <dev@dpdk.org>; Tue, 19 Dec 2017 12:14:57 +0100 (CET)",
            "from orsmga004.jf.intel.com ([10.7.209.38])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Dec 2017 03:14:56 -0800",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby orsmga004.jf.intel.com with ESMTP; 19 Dec 2017 03:14:54 -0800",
            "from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com\n\t[10.237.217.45])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\tvBJBErtE003154; Tue, 19 Dec 2017 11:14:53 GMT",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id vBJBErVr010341;\n\tTue, 19 Dec 2017 11:14:53 GMT",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id vBJBEriT010337;\n\tTue, 19 Dec 2017 11:14:53 GMT"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.45,426,1508828400\"; d=\"scan'208\";a=\"160064549\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "andras.kovacs@ericsson.com, laszlo.vadkeri@ericsson.com,\n\tkeith.wiles@intel.com, benjamin.walker@intel.com,\n\tbruce.richardson@intel.com, thomas@monjalon.net,\n\tPawel Wodkowski <pawelx.wodkowski@intel.com>",
        "Date": "Tue, 19 Dec 2017 11:14:49 +0000",
        "Message-Id": "<2d5b9ea71a32658efa24766933d07b5d2e29f25f.1513681966.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1513681966.git.anatoly.burakov@intel.com>",
            "<cover.1513681966.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1513681966.git.anatoly.burakov@intel.com>",
            "<cover.1513681966.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [RFC v2 22/23] vfio: allow to map other memory regions",
        "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://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Currently it is not possible to use memory that is not owned by DPDK to\nperform DMA. This scenarion might be used in vhost applications (like\nSPDK) where guest send its own memory table. To fill this gap provide\nAPI to allow registering arbitrary address in VFIO container.\n\nSigned-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n lib/librte_eal/linuxapp/eal/eal_vfio.c | 150 ++++++++++++++++++++++++++++-----\n lib/librte_eal/linuxapp/eal/eal_vfio.h |  11 +++\n 2 files changed, 140 insertions(+), 21 deletions(-)",
    "diff": "diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c\nindex 09dfc68..15d28ad 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c\n@@ -40,6 +40,7 @@\n #include <rte_memory.h>\n #include <rte_eal_memconfig.h>\n #include <rte_vfio.h>\n+#include <rte_iommu.h>\n \n #include \"eal_filesystem.h\"\n #include \"eal_vfio.h\"\n@@ -51,17 +52,35 @@\n static struct vfio_config vfio_cfg;\n \n static int vfio_type1_dma_map(int);\n+static int vfio_type1_dma_mem_map(int, uint64_t, uint64_t, uint64_t, int);\n static int vfio_spapr_dma_map(int);\n static int vfio_noiommu_dma_map(int);\n+static int vfio_noiommu_dma_mem_map(int, uint64_t, uint64_t, uint64_t, int);\n \n /* IOMMU types we support */\n static const struct vfio_iommu_type iommu_types[] = {\n \t/* x86 IOMMU, otherwise known as type 1 */\n-\t{ RTE_VFIO_TYPE1, \"Type 1\", &vfio_type1_dma_map},\n+\t{\n+\t\t.type_id = RTE_VFIO_TYPE1,\n+\t\t.name = \"Type 1\",\n+\t\t.dma_map_func = &vfio_type1_dma_map,\n+\t\t.dma_user_map_func = &vfio_type1_dma_mem_map\n+\t},\n \t/* ppc64 IOMMU, otherwise known as spapr */\n-\t{ RTE_VFIO_SPAPR, \"sPAPR\", &vfio_spapr_dma_map},\n+\t{\n+\t\t.type_id = RTE_VFIO_SPAPR,\n+\t\t.name = \"sPAPR\",\n+\t\t.dma_map_func = &vfio_spapr_dma_map,\n+\t\t.dma_user_map_func = NULL\n+\t\t// TODO: work with PPC64 people on enabling this, window size!\n+\t},\n \t/* IOMMU-less mode */\n-\t{ RTE_VFIO_NOIOMMU, \"No-IOMMU\", &vfio_noiommu_dma_map},\n+\t{\n+\t\t.type_id = RTE_VFIO_NOIOMMU,\n+\t\t.name = \"No-IOMMU\",\n+\t\t.dma_map_func = &vfio_noiommu_dma_map,\n+\t\t.dma_user_map_func = &vfio_noiommu_dma_mem_map\n+\t},\n };\n \n int\n@@ -362,9 +381,10 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,\n \t\t */\n \t\tif (internal_config.process_type == RTE_PROC_PRIMARY &&\n \t\t\t\tvfio_cfg.vfio_active_groups == 1) {\n+\t\t\tconst struct vfio_iommu_type *t;\n+\n \t\t\t/* select an IOMMU type which we will be using */\n-\t\t\tconst struct vfio_iommu_type *t =\n-\t\t\t\tvfio_set_iommu_type(vfio_cfg.vfio_container_fd);\n+\t\t\tt = vfio_set_iommu_type(vfio_cfg.vfio_container_fd);\n \t\t\tif (!t) {\n \t\t\t\tRTE_LOG(ERR, EAL,\n \t\t\t\t\t\"  %s failed to select IOMMU type\\n\",\n@@ -382,6 +402,8 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,\n \t\t\t\tclear_group(vfio_group_fd);\n \t\t\t\treturn -1;\n \t\t\t}\n+\n+\t\t\tvfio_cfg.vfio_iommu_type = t;\n \t\t}\n \t}\n \n@@ -694,13 +716,52 @@ vfio_get_group_no(const char *sysfs_base,\n }\n \n static int\n+vfio_type1_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova,\n+\t\tuint64_t len, int do_map)\n+{\n+\tstruct vfio_iommu_type1_dma_map dma_map;\n+\tstruct vfio_iommu_type1_dma_unmap dma_unmap;\n+\tint ret;\n+\n+\tif (do_map != 0) {\n+\t\tmemset(&dma_map, 0, sizeof(dma_map));\n+\t\tdma_map.argsz = sizeof(struct vfio_iommu_type1_dma_map);\n+\t\tdma_map.vaddr = vaddr;\n+\t\tdma_map.size = len;\n+\t\tdma_map.iova = iova;\n+\t\tdma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;\n+\n+\t\tret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);\n+\t\tif (ret) {\n+\t\t\tRTE_LOG(ERR, EAL, \"  cannot set up DMA remapping, error %i (%s)\\n\",\n+\t\t\t\terrno, strerror(errno));\n+\t\t\t\treturn -1;\n+\t\t}\n+\n+\t} else {\n+\t\tmemset(&dma_unmap, 0, sizeof(dma_unmap));\n+\t\tdma_unmap.argsz = sizeof(struct vfio_iommu_type1_dma_unmap);\n+\t\tdma_unmap.size = len;\n+\t\tdma_unmap.iova = iova;\n+\n+\t\tret = ioctl(vfio_container_fd, VFIO_IOMMU_UNMAP_DMA, &dma_unmap);\n+\t\tif (ret) {\n+\t\t\tRTE_LOG(ERR, EAL, \"  cannot clear DMA remapping, error %i (%s)\\n\",\n+\t\t\t\t\terrno, strerror(errno));\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n vfio_type1_dma_map(int vfio_container_fd)\n {\n-\tint i, ret;\n+\tint i;\n \n \t/* map all DPDK segments for DMA. use 1:1 PA to IOVA mapping */\n \tfor (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {\n-\t\tstruct vfio_iommu_type1_dma_map dma_map;\n \t\tconst struct rte_memseg_list *msl;\n \t\tconst struct rte_fbarray *arr;\n \t\tint ms_idx, next_idx;\n@@ -727,21 +788,9 @@ vfio_type1_dma_map(int vfio_container_fd)\n \t\t\tlen = ms->hugepage_sz;\n \t\t\thw_addr = ms->iova;\n \n-\t\t\tmemset(&dma_map, 0, sizeof(dma_map));\n-\t\t\tdma_map.argsz = sizeof(struct vfio_iommu_type1_dma_map);\n-\t\t\tdma_map.vaddr = addr;\n-\t\t\tdma_map.size = len;\n-\t\t\tdma_map.iova = hw_addr;\n-\t\t\tdma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;\n-\n-\t\t\tret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map);\n-\n-\t\t\tif (ret) {\n-\t\t\t\tRTE_LOG(ERR, EAL, \"  cannot set up DMA remapping, \"\n-\t\t\t\t\t\t  \"error %i (%s)\\n\", errno,\n-\t\t\t\t\t\t  strerror(errno));\n+\t\t\tif (vfio_type1_dma_mem_map(vfio_container_fd, addr,\n+\t\t\t\t\thw_addr, len, 1))\n \t\t\t\treturn -1;\n-\t\t\t}\n \t\t}\n \t}\n \n@@ -892,6 +941,49 @@ vfio_noiommu_dma_map(int __rte_unused vfio_container_fd)\n \treturn 0;\n }\n \n+static int\n+vfio_noiommu_dma_mem_map(int __rte_unused vfio_container_fd,\n+\t\t\t uint64_t __rte_unused vaddr,\n+\t\t\t uint64_t __rte_unused iova, uint64_t __rte_unused len,\n+\t\t\t int __rte_unused do_map)\n+{\n+\t/* No-IOMMU mode does not need DMA mapping */\n+\treturn 0;\n+}\n+\n+static int\n+vfio_dma_mem_map(uint64_t vaddr, uint64_t iova, uint64_t len, int do_map)\n+{\n+\tconst struct vfio_iommu_type *t = vfio_cfg.vfio_iommu_type;\n+\n+\tif (!t) {\n+\t\tRTE_LOG(ERR, EAL, \"  VFIO support not initialized\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (!t->dma_user_map_func) {\n+\t\tRTE_LOG(ERR, EAL,\n+\t\t\t\"  VFIO custom DMA region maping not supported by IOMMU %s\\n\",\n+\t\t\tt->name);\n+\t\treturn -1;\n+\t}\n+\n+\treturn t->dma_user_map_func(vfio_cfg.vfio_container_fd, vaddr, iova,\n+\t\t\tlen, do_map);\n+}\n+\n+int\n+rte_iommu_dma_map(uint64_t vaddr, uint64_t iova, uint64_t len)\n+{\n+\treturn vfio_dma_mem_map(vaddr, iova, len, 1);\n+}\n+\n+int\n+rte_iommu_dma_unmap(uint64_t vaddr, uint64_t iova, uint64_t len)\n+{\n+\treturn vfio_dma_mem_map(vaddr, iova, len, 0);\n+}\n+\n int\n rte_vfio_noiommu_is_enabled(void)\n {\n@@ -911,4 +1003,20 @@ rte_vfio_noiommu_is_enabled(void)\n \treturn ret;\n }\n \n+#else\n+\n+int\n+rte_iommu_dma_map(uint64_t __rte_unused vaddr, __rte_unused uint64_t iova,\n+\t\t  __rte_unused uint64_t len)\n+{\n+\treturn 0;\n+}\n+\n+int\n+rte_iommu_dma_unmap(uint64_t __rte_unused vaddr, uint64_t __rte_unused iova,\n+\t\t    __rte_unused uint64_t len)\n+{\n+\treturn 0;\n+}\n+\n #endif\ndiff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h\nindex ba7892b..bb669f0 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h\n+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h\n@@ -48,6 +48,7 @@\n \n #ifdef VFIO_PRESENT\n \n+#include <stdint.h>\n #include <linux/vfio.h>\n \n #define RTE_VFIO_TYPE1 VFIO_TYPE1_IOMMU\n@@ -139,6 +140,7 @@ struct vfio_config {\n \tint vfio_enabled;\n \tint vfio_container_fd;\n \tint vfio_active_groups;\n+\tconst struct vfio_iommu_type *vfio_iommu_type;\n \tstruct vfio_group vfio_groups[VFIO_MAX_GROUPS];\n };\n \n@@ -148,9 +150,18 @@ struct vfio_config {\n  * */\n typedef int (*vfio_dma_func_t)(int);\n \n+/* Custom memory region DMA mapping function prototype.\n+ * Takes VFIO container fd, virtual address, phisical address, length and\n+ * operation type (0 to unmap 1 for map) as a parameters.\n+ * Returns 0 on success, -1 on error.\n+ **/\n+typedef int (*vfio_dma_user_func_t)(int fd, uint64_t vaddr, uint64_t iova,\n+\t\tuint64_t len, int do_map);\n+\n struct vfio_iommu_type {\n \tint type_id;\n \tconst char *name;\n+\tvfio_dma_user_func_t dma_user_map_func;\n \tvfio_dma_func_t dma_map_func;\n };\n \n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "v2",
        "22/23"
    ]
}