From patchwork Thu Jan 15 05:15:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ouyang Changchun X-Patchwork-Id: 2321 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 30DD95A7F; Thu, 15 Jan 2015 06:17:06 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 32CAD5A1F for ; Thu, 15 Jan 2015 06:16:22 +0100 (CET) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 14 Jan 2015 21:11:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,401,1418112000"; d="scan'208";a="662128078" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga002.fm.intel.com with ESMTP; 14 Jan 2015 21:16:15 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t0F5GD4f001895; Thu, 15 Jan 2015 13:16:13 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t0F5GBtm015363; Thu, 15 Jan 2015 13:16:13 +0800 Received: (from couyang@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t0F5GAJI015359; Thu, 15 Jan 2015 13:16:10 +0800 From: Ouyang Changchun To: dev@dpdk.org Date: Thu, 15 Jan 2015 13:15:25 +0800 Message-Id: <1421298930-15210-18-git-send-email-changchun.ouyang@intel.com> X-Mailer: git-send-email 1.7.12.2 In-Reply-To: <1421298930-15210-1-git-send-email-changchun.ouyang@intel.com> References: <1421298930-15210-1-git-send-email-changchun.ouyang@intel.com> Subject: [dpdk-dev] [PATCH 17/22] virtio: Use port IO to get PCI resource. X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Make virtio not require UIO for some security reasons, this is to match 6Wind's virtio-net-pmd. Signed-off-by: Changchun Ouyang --- config/common_linuxapp | 2 + lib/librte_eal/common/include/rte_pci.h | 4 ++ lib/librte_eal/linuxapp/eal/eal_pci.c | 5 +- lib/librte_pmd_virtio/virtio_ethdev.c | 91 ++++++++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 2 deletions(-) diff --git a/config/common_linuxapp b/config/common_linuxapp index 6243d4b..a3227a2 100644 --- a/config/common_linuxapp +++ b/config/common_linuxapp @@ -125,6 +125,8 @@ CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n CONFIG_RTE_EAL_IGB_UIO=y CONFIG_RTE_EAL_VFIO=y +# Only for VIRTIO PMD currently +CONFIG_RTE_EAL_PORT_IO=n # # Special configurations in PCI Config Space for high performance diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index 66ed793..19abc1f 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -193,6 +193,10 @@ struct rte_pci_driver { /** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */ #define RTE_PCI_DRV_NEED_MAPPING 0x0001 +/** Device needs port IO(done with /proc/ioports) */ +#ifdef RTE_EAL_PORT_IO +#define RTE_PCI_DRV_PORT_IO 0x0002 +#endif /** Device driver must be registered several times until failure - deprecated */ #pragma GCC poison RTE_PCI_DRV_MULTIPLE /** Device needs to be unbound even if no module is provided */ diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index b5f5410..5db0059 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -574,7 +574,10 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d /* map resources for devices that use igb_uio */ ret = pci_map_device(dev); if (ret != 0) - return ret; +#ifdef RTE_EAL_PORT_IO + if ((dr->drv_flags & RTE_PCI_DRV_PORT_IO) == 0) +#endif + return ret; } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND && rte_eal_process_type() == RTE_PROC_PRIMARY) { /* unbind current driver */ diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c b/lib/librte_pmd_virtio/virtio_ethdev.c index 1ec29e1..15324c9 100644 --- a/lib/librte_pmd_virtio/virtio_ethdev.c +++ b/lib/librte_pmd_virtio/virtio_ethdev.c @@ -961,6 +961,71 @@ static int virtio_resource_init(struct rte_pci_device *pci_dev) start, size); return 0; } + +#ifdef RTE_EAL_PORT_IO +/* Extract port I/O numbers from proc/ioports */ +static int virtio_resource_init_by_portio(struct rte_pci_device *pci_dev) +{ + uint16_t start, end; + int size; + FILE *fp; + char *line = NULL; + char pci_id[16]; + int found = 0; + size_t linesz; + + snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT, + pci_dev->addr.domain, + pci_dev->addr.bus, + pci_dev->addr.devid, + pci_dev->addr.function); + + fp = fopen("/proc/ioports", "r"); + if (fp == NULL) { + PMD_INIT_LOG(ERR, "%s(): can't open ioports", __func__); + return -1; + } + + while (getdelim(&line, &linesz, '\n', fp) > 0) { + char *ptr = line; + char *left; + int n; + + n = strcspn(ptr, ":"); + ptr[n] = 0; + left = &ptr[n+1]; + + while (*left && isspace(*left)) + left++; + + if (!strncmp(left, pci_id, strlen(pci_id))) { + found = 1; + + while (*ptr && isspace(*ptr)) + ptr++; + + sscanf(ptr, "%04hx-%04hx", &start, &end); + size = end - start + 1; + + break; + } + } + + free(line); + fclose(fp); + + if (!found) + return -1; + + pci_dev->mem_resource[0].addr = (void *)(uintptr_t)(uint32_t)start; + pci_dev->mem_resource[0].len = (uint64_t)size; + PMD_INIT_LOG(DEBUG, + "PCI Port IO found start=0x%lx with size=0x%lx", + start, size); + return 0; +} +#endif + #else static int virtio_has_msix(const struct rte_pci_addr *loc __rte_unused) @@ -974,6 +1039,14 @@ static int virtio_resource_init(struct rte_pci_device *pci_dev __rte_unused) /* no setup required */ return 0; } + +#ifdef RTE_EAL_PORT_IO +static int virtio_resource_init_by_portio(struct rte_pci_device *pci_dev) +{ + /* no setup required */ + return 0; +} +#endif #endif /* @@ -1039,7 +1112,10 @@ eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv, pci_dev = eth_dev->pci_dev; if (virtio_resource_init(pci_dev) < 0) - return -1; +#ifdef RTE_EAL_PORT_IO + if (virtio_resource_init_by_portio(pci_dev) < 0) +#endif + return -1; hw->use_msix = virtio_has_msix(&pci_dev->addr); hw->io_base = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr; @@ -1132,6 +1208,18 @@ eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv, return 0; } +#ifdef RTE_EAL_PORT_IO +static struct eth_driver rte_virtio_pmd = { + { + .name = "rte_virtio_pmd", + .id_table = pci_id_virtio_map, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_PORT_IO | + RTE_PCI_DRV_INTR_LSC, + }, + .eth_dev_init = eth_virtio_dev_init, + .dev_private_size = sizeof(struct virtio_hw), +}; +#else static struct eth_driver rte_virtio_pmd = { { .name = "rte_virtio_pmd", @@ -1141,6 +1229,7 @@ static struct eth_driver rte_virtio_pmd = { .eth_dev_init = eth_virtio_dev_init, .dev_private_size = sizeof(struct virtio_hw), }; +#endif /* * Driver initialization routine.