get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 113510,
    "url": "http://patches.dpdk.org/api/patches/113510/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220628135339.2882914-2-skori@marvell.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": "<20220628135339.2882914-2-skori@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220628135339.2882914-2-skori@marvell.com",
    "date": "2022-06-28T13:53:39",
    "name": "[2/2] bus/pci: support region based device mapping",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "eec86cf6a9be0349cea21abd000152b75a9f1fde",
    "submitter": {
        "id": 1318,
        "url": "http://patches.dpdk.org/api/people/1318/?format=api",
        "name": "Sunil Kumar Kori",
        "email": "skori@marvell.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/20220628135339.2882914-2-skori@marvell.com/mbox/",
    "series": [
        {
            "id": 23809,
            "url": "http://patches.dpdk.org/api/series/23809/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=23809",
            "date": "2022-06-28T13:53:39",
            "name": "[1/2] doc: announce region based device mapping support",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/23809/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/113510/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/113510/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 58434A056D;\n\tTue, 28 Jun 2022 15:54:01 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 3C80F40691;\n\tTue, 28 Jun 2022 15:54:01 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174])\n by mails.dpdk.org (Postfix) with ESMTP id 6012D400D7\n for <dev@dpdk.org>; Tue, 28 Jun 2022 15:53:59 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id\n 25SACARl020960;\n Tue, 28 Jun 2022 06:53:58 -0700",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3gyxcq18na-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Tue, 28 Jun 2022 06:53:58 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18;\n Tue, 28 Jun 2022 06:53:56 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend\n Transport; Tue, 28 Jun 2022 06:53:56 -0700",
            "from localhost.localdomain (unknown [10.28.34.25])\n by maili.marvell.com (Postfix) with ESMTP id 6A2FE3F7092;\n Tue, 28 Jun 2022 06:53:55 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=fLv72A3Id3YP32KctDsgPIGH9/cPoYG05vxoVTH8N98=;\n b=T90MfmTkgMKR6funp1egwrBZx5ropTh5obdXXqH+3cVkJafk/WGIq/rC7l4R0zHXtQ7y\n n3zqEEiQED/nEggwyifl6o9zguFc6KyKg2F+mZG/c7AisTNNy+VjhWg8lcfME7Gf/2Kw\n b+bU9yMWZibfrHny74TjXLDT1ihssNIpI5vpD4lPZsXfQD3wZltNFlyxUI71ed7dLwWx\n w2wmU2RPEDTyuW055YFo2kXfe3HRrzN3KoCfIAhLIWdVLslCbfUi/SpppjzCklntVqJh\n sqikOhIjkDP2n8WKdy/Fl0MPnIz2SzGy4z9cQVEZQkoNDLt9e2JZaNjPq/gAba4TXJLm OA==",
        "From": "<skori@marvell.com>",
        "To": "Anatoly Burakov <anatoly.burakov@intel.com>, Gaetan Rivet <grive@u256.net>",
        "CC": "<dev@dpdk.org>, Sunil Kumar Kori <skori@marvell.com>",
        "Subject": "[PATCH 2/2] bus/pci: support region based device mapping",
        "Date": "Tue, 28 Jun 2022 19:23:39 +0530",
        "Message-ID": "<20220628135339.2882914-2-skori@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220628135339.2882914-1-skori@marvell.com>",
        "References": "<20220628135339.2882914-1-skori@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "8O4rTij0WPIMqYIBO60cSopw6Y4xWhTU",
        "X-Proofpoint-ORIG-GUID": "8O4rTij0WPIMqYIBO60cSopw6Y4xWhTU",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1\n definitions=2022-06-28_07,2022-06-28_01,2022-06-22_01",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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"
    },
    "content": "From: Sunil Kumar Kori <skori@marvell.com>\n\nThis commit allows driver to define a list of sparse memory\nregions to map for a given device instead mapping the whole BAR.\n\nTo do that, a driver must register itself with following information:\n\n * rte_pci_driver::drv_flags - RTE_PCI_DRV_NEED_REGION_MAPPING must be set.\n * rte_pci_driver::regions - It contains list of regions. Region\n   information are explained below.\n * rte_pci_driver::valid_bars: It contains information about BARs for which\n   entries are mentioned in rte_pci_driver::regions.\n\nEach entry in region map specifies a particular area in given BAR to map\ninto the virtual space assigned for given device. Regions may lie within\nthe same BAR or in different BARs.\n\nIt results a sparse virtual memory reservation with only valid areas in\nit being defined by the region tables.\n\nExample:\nIf user wishes to map BAR 2 region at offset 0x20000000000 of length\n0x2000000 and BAR 4 region at offset 0x40000000000 of length 0x10000\nthen following information need to be set in driver while registering:\n\nstatic struct rte_pci_region_map xyz_pci_nic_regions[] = {\n\t{0x20000000000, 0x2000000, 2, false},\n\t{0x40000000000, 0x10000, 4, false},\n\t{0x0, 0x0, 0x0, false},\n};\n\nstatic struct rte_pci_driver xyz_pci_nic = {\n\t.valid_bars = {false, false, true, false, true, false},\n\t.regions = xyz_pci_nic_regions,\n\t.drv_flags = RTE_PCI_DRV_NEED_REGION_MAPPINGA | RTE_PCI_DRV_XYZ\n}\n\nAnd resultant mapping will be reflected as given below:\n* (X + 0x20000000000) to (X + 0x20000000000 + 0x2000000)\n* (Y + 0x40000000000) to (Y + 0x40000000000 + 0x10000)\n\nSigned-off-by: Sunil Kumar Kori <skori@marvell.com>\n---\n drivers/bus/pci/linux/pci.c      |  30 +++++++-\n drivers/bus/pci/linux/pci_vfio.c | 117 ++++++++++++++++++++++++++-----\n drivers/bus/pci/pci_common.c     |   4 +-\n drivers/bus/pci/private.h        |   5 ++\n drivers/bus/pci/rte_bus_pci.h    |  25 +++++++\n lib/pci/rte_pci.h                |  15 ++++\n 6 files changed, 176 insertions(+), 20 deletions(-)",
    "diff": "diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c\nindex e521459870..e6eb172e92 100644\n--- a/drivers/bus/pci/linux/pci.c\n+++ b/drivers/bus/pci/linux/pci.c\n@@ -173,7 +173,7 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)\n {\n \tFILE *f;\n \tchar buf[BUFSIZ];\n-\tint i;\n+\tint i, j;\n \tuint64_t phys_addr, end_addr, flags;\n \n \tf = fopen(filename, \"r\");\n@@ -198,6 +198,14 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)\n \t\t\tdev->mem_resource[i].len = end_addr - phys_addr + 1;\n \t\t\t/* not mapped for now */\n \t\t\tdev->mem_resource[i].addr = NULL;\n+\n+\t\t\t/* update the same in regions too */\n+\t\t\tfor (j = 0; j < PCI_MAX_REGION_PER_RESOURCE; j++) {\n+\t\t\t\tdev->regions[i][j].phys_addr = phys_addr;\n+\t\t\t\tdev->regions[i][j].len = end_addr - phys_addr + 1;\n+\t\t\t\t/* not mapped for now */\n+\t\t\t\tdev->regions[i][j].addr = NULL;\n+\t\t\t}\n \t\t}\n \t}\n \tfclose(f);\n@@ -640,6 +648,26 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,\n \treturn iova_mode;\n }\n \n+bool\n+pci_device_get_region_info(const struct rte_pci_driver *drv,\n+\tuint32_t bar_idx, uint64_t *offset, uint64_t *size)\n+{\n+\tstruct rte_pci_region_map *region;\n+\tbool is_present = false;\n+\n+\tfor (region = drv->regions; region->size != 0; region++) {\n+\t\tif ((region->bar_idx == bar_idx) && (region->mapped == false)) {\n+\t\t\t*offset = region->offset;\n+\t\t\t*size = region->size;\n+\t\t\tregion->mapped = true;\n+\t\t\tis_present = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn is_present;\n+}\n+\n /* Read PCI config space. */\n int rte_pci_read_config(const struct rte_pci_device *device,\n \t\tvoid *buf, size_t len, off_t offset)\ndiff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c\nindex cd0d0b1670..90cbfbd699 100644\n--- a/drivers/bus/pci/linux/pci_vfio.c\n+++ b/drivers/bus/pci/linux/pci_vfio.c\n@@ -509,21 +509,28 @@ pci_rte_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)\n \n static int\n pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,\n-\t\tint bar_index, int additional_flags)\n+\t\tint bar_index, int reg_idx, bool map_reg, int additional_flags)\n {\n \tstruct memreg {\n \t\tuint64_t offset;\n \t\tsize_t   size;\n \t} memreg[2] = {};\n-\tvoid *bar_addr;\n+\tvoid *bar_addr = NULL;\n+\tstruct pci_map *region = &vfio_res->regions[bar_index][reg_idx];\n \tstruct pci_msix_table *msix_table = &vfio_res->msix_table;\n \tstruct pci_map *bar = &vfio_res->maps[bar_index];\n \n-\tif (bar->size == 0) {\n+\tif (!map_reg && bar->size == 0) {\n \t\tRTE_LOG(DEBUG, EAL, \"Bar size is 0, skip BAR%d\\n\", bar_index);\n \t\treturn 0;\n \t}\n \n+\tif (map_reg && region->size == 0) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Region size is 0, skip BAR:REG=(%d:%d)\\n\",\n+\t\t\tbar_index, reg_idx);\n+\t\treturn 0;\n+\t}\n+\n \tif (msix_table->bar_index == bar_index) {\n \t\t/*\n \t\t * VFIO will not let us map the MSI-X table,\n@@ -571,12 +578,19 @@ pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,\n \t\t\tmemreg[0].offset, memreg[0].size,\n \t\t\tmemreg[1].offset, memreg[1].size);\n \t} else {\n-\t\tmemreg[0].offset = bar->offset;\n-\t\tmemreg[0].size = bar->size;\n+\t\tif (map_reg) {\n+\t\t\tbar_addr = region->addr;\n+\t\t\tmemreg[0].offset = region->offset;\n+\t\t\tmemreg[0].size = region->size;\n+\t\t} else {\n+\t\t\tbar_addr = bar->addr;\n+\t\t\tmemreg[0].offset = bar->offset;\n+\t\t\tmemreg[0].size = bar->size;\n+\t\t}\n \t}\n \n \t/* reserve the address using an inaccessible mapping */\n-\tbar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |\n+\tbar_addr = mmap(bar_addr, memreg[0].size, 0, MAP_PRIVATE |\n \t\t\tMAP_ANONYMOUS | additional_flags, -1, 0);\n \tif (bar_addr != MAP_FAILED) {\n \t\tvoid *map_addr = NULL;\n@@ -627,7 +641,11 @@ pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,\n \t\treturn -1;\n \t}\n \n-\tbar->addr = bar_addr;\n+\tif (map_reg)\n+\t\tregion->addr = bar_addr;\n+\telse\n+\t\tbar->addr = bar_addr;\n+\n \treturn 0;\n }\n \n@@ -727,12 +745,15 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)\n \tchar pci_addr[PATH_MAX] = {0};\n \tint vfio_dev_fd;\n \tstruct rte_pci_addr *loc = &dev->addr;\n+\tstruct rte_pci_driver *drv = dev->driver;\n \tint i, ret;\n \tstruct mapped_pci_resource *vfio_res = NULL;\n \tstruct mapped_pci_res_list *vfio_res_list =\n \t\tRTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);\n \n+\tstruct rte_pci_region_map *drv_reg;\n \tstruct pci_map *maps;\n+\tbool map_reg;\n \n \tif (rte_intr_fd_set(dev->intr_handle, -1))\n \t\treturn -1;\n@@ -791,9 +812,18 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)\n \t\t}\n \t}\n \n+\tmap_reg = drv->drv_flags & RTE_PCI_DRV_NEED_REGION_MAPPING ? true : false;\n+\tif (map_reg) {\n+\t\tfor (drv_reg = drv->regions; drv_reg->size != 0; drv_reg++)\n+\t\t\tdrv_reg->mapped = false;\n+\t}\n+\n \tfor (i = 0; i < vfio_res->nb_maps; i++) {\n \t\tstruct vfio_region_info *reg = NULL;\n-\t\tvoid *bar_addr;\n+\t\tstruct pci_map *region = NULL;\n+\t\tuint64_t offset = 0, size = 0;\n+\t\tvoid *bar_addr = NULL;\n+\t\tuint32_t reg_idx = 0;\n \n \t\tret = pci_vfio_get_region_info(vfio_dev_fd, &reg, i);\n \t\tif (ret < 0) {\n@@ -821,22 +851,41 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)\n \t\t\tcontinue;\n \t\t}\n \n+next_region:\n+\t\t/* skip BARs if driver requested for region mapping and\n+\t\t * entry in regions table is not available\n+\t\t */\n+\t\tif (map_reg && drv->valid_bars[i] == true &&\n+\t\t    (pci_device_get_region_info(drv, i, &offset, &size) == false)) {\n+\t\t\tfree(reg);\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\t/* try mapping somewhere close to the end of hugepages */\n \t\tif (pci_map_addr == NULL)\n \t\t\tpci_map_addr = pci_find_max_end_va();\n \n \t\tbar_addr = pci_map_addr;\n-\t\tpci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg->size);\n+\n+\t\tif (map_reg && drv->valid_bars[i] == true) {\n+\t\t\tregion = &vfio_res->regions[i][reg_idx];\n+\t\t\tpci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) size);\n+\t\t\tregion->addr = bar_addr;\n+\t\t\tregion->path = NULL; /* vfio doesn't have per-resource paths */\n+\t\t\tregion->offset = offset;\n+\t\t\tregion->size = size;\n+\t\t} else {\n+\t\t\tpci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg->size);\n+\t\t\tmaps[i].addr = bar_addr;\n+\t\t\tmaps[i].path = NULL; /* vfio doesn't have per-resource paths */\n+\t\t\tmaps[i].offset = reg->offset;\n+\t\t\tmaps[i].size = reg->size;\n+\t\t}\n \n \t\tpci_map_addr = RTE_PTR_ALIGN(pci_map_addr,\n \t\t\t\t\tsysconf(_SC_PAGE_SIZE));\n \n-\t\tmaps[i].addr = bar_addr;\n-\t\tmaps[i].offset = reg->offset;\n-\t\tmaps[i].size = reg->size;\n-\t\tmaps[i].path = NULL; /* vfio doesn't have per-resource paths */\n-\n-\t\tret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);\n+\t\tret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, reg_idx, map_reg, 0);\n \t\tif (ret < 0) {\n \t\t\tRTE_LOG(ERR, EAL, \"%s mapping BAR%i failed: %s\\n\",\n \t\t\t\t\tpci_addr, i, strerror(errno));\n@@ -844,8 +893,15 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)\n \t\t\tgoto err_vfio_res;\n \t\t}\n \n-\t\tdev->mem_resource[i].addr = maps[i].addr;\n+\t\tif (map_reg && (drv->valid_bars[i] == true)) {\n+\t\t\tdev->regions[i][reg_idx].addr = region->addr;\n+\t\t\tdev->regions[i][reg_idx].len = region->size;\n+\t\t\treg_idx++;\n+\t\t\tgoto next_region;\n+\t\t}\n \n+\t\tdev->mem_resource[i].addr = maps[i].addr;\n+\t\treg_idx = 0;\n \t\tfree(reg);\n \t}\n \n@@ -877,14 +933,19 @@ 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+\tstruct rte_pci_driver *drv = dev->driver;\n \tint vfio_dev_fd;\n \tstruct rte_pci_addr *loc = &dev->addr;\n-\tint i, ret;\n+\tint i, ret, j = 0;\n \tstruct mapped_pci_resource *vfio_res = NULL;\n \tstruct mapped_pci_res_list *vfio_res_list =\n \t\tRTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);\n \n+\tstruct rte_pci_region_map *drv_reg;\n+\tuint64_t offset = 0, size = 0;\n+\tstruct pci_map *region;\n \tstruct pci_map *maps;\n+\tbool map_reg = false;\n \n \tif (rte_intr_fd_set(dev->intr_handle, -1))\n \t\treturn -1;\n@@ -918,16 +979,36 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)\n \n \t/* map BARs */\n \tmaps = vfio_res->maps;\n+\tfor (drv_reg = drv->regions; drv_reg->size != 0; drv_reg++)\n+\t\tdrv_reg->mapped = false;\n \n \tfor (i = 0; i < vfio_res->nb_maps; i++) {\n-\t\tret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);\n+next_region:\n+\t\tif (drv->drv_flags & RTE_PCI_DRV_NEED_REGION_MAPPING &&\n+\t\t    drv->valid_bars[i] == true) {\n+\t\t\tmap_reg = pci_device_get_region_info(drv, i, &offset, &size);\n+\t\t\tif (map_reg == false)\n+\t\t\t\tcontinue;\n+\t\t\tregion = &vfio_res->regions[i][j];\n+\t\t}\n+\n+\t\tret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, j, map_reg,\n+\t\t\t\t\tMAP_FIXED);\n \t\tif (ret < 0) {\n \t\t\tRTE_LOG(ERR, EAL, \"%s mapping BAR%i failed: %s\\n\",\n \t\t\t\t\tpci_addr, i, strerror(errno));\n \t\t\tgoto err_vfio_dev_fd;\n \t\t}\n \n+\t\tif (map_reg) {\n+\t\t\tdev->regions[i][j].addr = region->addr;\n+\t\t\tj++;\n+\t\t\tmap_reg = false;\n+\t\t\tgoto next_region;\n+\t\t}\n+\n \t\tdev->mem_resource[i].addr = maps[i].addr;\n+\t\tj = 0;\n \t}\n \n \t/* we need save vfio_dev_fd, so it can be used during release */\ndiff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c\nindex 37ab879779..656b35ec30 100644\n--- a/drivers/bus/pci/pci_common.c\n+++ b/drivers/bus/pci/pci_common.c\n@@ -248,7 +248,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,\n \t\t * to use driver flags for adjusting configuration.\n \t\t */\n \t\tdev->driver = dr;\n-\t\tif (dev->driver->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {\n+\t\tif (dev->driver->drv_flags & RTE_PCI_DRV_NEED_MAPPING ||\n+\t\t    dev->driver->drv_flags & RTE_PCI_DRV_NEED_REGION_MAPPING) {\n \t\t\tret = rte_pci_map_device(dev);\n \t\t\tif (ret != 0) {\n \t\t\t\tdev->driver = NULL;\n@@ -256,6 +257,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,\n \t\t\t\tdev->vfio_req_intr_handle = NULL;\n \t\t\t\trte_intr_instance_free(dev->intr_handle);\n \t\t\t\tdev->intr_handle = NULL;\n+\t\t\t\tdev->driver = NULL;\n \t\t\t\treturn ret;\n \t\t\t}\n \t\t}\ndiff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h\nindex 0fbef8e1d8..3cd6b2b90b 100644\n--- a/drivers/bus/pci/private.h\n+++ b/drivers/bus/pci/private.h\n@@ -98,6 +98,7 @@ struct mapped_pci_resource {\n \tint nb_maps;\n \tstruct pci_map maps[PCI_MAX_RESOURCE];\n \tstruct pci_msix_table msix_table;\n+\tstruct pci_map regions[PCI_MAX_RESOURCE][PCI_MAX_REGION_PER_RESOURCE];\n };\n \n /** mapped pci device list */\n@@ -236,6 +237,10 @@ enum rte_iova_mode\n pci_device_iova_mode(const struct rte_pci_driver *pci_drv,\n \t\t     const struct rte_pci_device *pci_dev);\n \n+bool\n+pci_device_get_region_info(const struct rte_pci_driver *drv, uint32_t bar_idx,\n+\tuint64_t *offset, uint64_t *size);\n+\n /**\n  * Get iommu class of PCI devices on the bus.\n  * And return their preferred iova mapping mode.\ndiff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h\nindex 1c6a8fdd7b..a39dc3f026 100644\n--- a/drivers/bus/pci/rte_bus_pci.h\n+++ b/drivers/bus/pci/rte_bus_pci.h\n@@ -76,6 +76,8 @@ struct rte_pci_device {\n \tchar name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */\n \tstruct rte_intr_handle *vfio_req_intr_handle;\n \t\t\t\t/**< Handler of VFIO request interrupt */\n+\tstruct rte_mem_resource regions[PCI_MAX_RESOURCE][PCI_MAX_REGION_PER_RESOURCE];\n+\t\t\t\t\t    /**< PCI Memory regions per resource */\n };\n \n /**\n@@ -167,6 +169,8 @@ struct rte_pci_driver {\n \tpci_dma_map_t *dma_map;\t\t   /**< device dma map function. */\n \tpci_dma_unmap_t *dma_unmap;\t   /**< device dma unmap function. */\n \tconst struct rte_pci_id *id_table; /**< ID table, NULL terminated. */\n+\tstruct rte_pci_region_map *regions; /**< MAP table, NULL terminated. */\n+\tbool valid_bars[PCI_MAX_RESOURCE]; /**< Valid BARs which has region config */\n \tuint32_t drv_flags;                /**< Flags RTE_PCI_DRV_*. */\n };\n \n@@ -193,6 +197,27 @@ struct rte_pci_bus {\n #define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020\n /** Device driver needs IOVA as VA and cannot work with IOVA as PA */\n #define RTE_PCI_DRV_NEED_IOVA_AS_VA 0x0040\n+/** Device needs PCI BAR mapping for given region (done with either IGB_UIO or VFIO)\n+ * i.e. if regions for a given device is defined as:\n+\n+  .regions = {\n+    {\n+      .bar_idx = PCI_BAR_0,\n+      .offset = 0x1000,\n+      .size = 0x100\n+    },\n+    {\n+      .bar_idx = PCI_BAR_0,\n+      .offset = 0x5000,\n+      .size = 0x1000\n+    }\n+  },\n+\n+then the only valid address mappings will be:\n+* X + 0x1000 to X + 0x10FF\n+* X + 0x5000 to X + 0x5FFF\n+*/\n+#define RTE_PCI_DRV_NEED_REGION_MAPPING 0x0080\n \n /**\n  * Map the PCI device resources in user space virtual memory address\ndiff --git a/lib/pci/rte_pci.h b/lib/pci/rte_pci.h\nindex 5088157e74..9d29113f2b 100644\n--- a/lib/pci/rte_pci.h\n+++ b/lib/pci/rte_pci.h\n@@ -74,6 +74,9 @@ extern \"C\" {\n /** Maximum number of PCI resources. */\n #define PCI_MAX_RESOURCE 6\n \n+/** Maximum number of regions per resource. */\n+#define PCI_MAX_REGION_PER_RESOURCE 8\n+\n /**\n  * A structure describing an ID for a PCI driver. Each driver provides a\n  * table of these IDs for each device that it supports.\n@@ -96,6 +99,18 @@ struct rte_pci_addr {\n \tuint8_t function;               /**< Device function. */\n };\n \n+/**\n+ * A structure describing region mapping information. Driver provides a\n+ * table of these mapping if it supports region mapping i.e. drv_flags is set\n+ * to RTE_PCI_DRV_NEED_REGION_MAPPING.\n+ */\n+struct rte_pci_region_map {\n+\tuint64_t offset;  /**< Offset from where mapping is to be done. */\n+\tuint64_t size;    /**< Memory size. */\n+\tuint8_t bar_idx;  /**< BAR number. */\n+\tuint8_t mapped;   /**< Is region mapped or not */\n+};\n+\n /** Any PCI device identifier (vendor, device, ...) */\n #define RTE_PCI_ANY_ID (0xffff)\n /** @deprecated Replaced with RTE_PCI_ANY_ID */\n",
    "prefixes": [
        "2/2"
    ]
}