Make virtio not require UIO for some security reasons, this is to match 6Wind's 
virtio-net-pmd.

Signed-off-by: Changchun Ouyang <changchun.ouyang at intel.com>
---
 lib/librte_eal/common/include/rte_pci.h |  2 +
 lib/librte_eal/linuxapp/eal/eal_pci.c   |  3 +-
 lib/librte_pmd_virtio/virtio_ethdev.c   | 75 ++++++++++++++++++++++++++++++++-
 3 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_pci.h 
b/lib/librte_eal/common/include/rte_pci.h
index 66ed793..2021b3b 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -193,6 +193,8 @@ 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) */
+#define RTE_PCI_DRV_IO_PORT 0x0002
 /** 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..dd60793 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -573,7 +573,8 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, 
struct rte_pci_device *d
 #endif
                        /* map resources for devices that use igb_uio */
                        ret = pci_map_device(dev);
-                       if (ret != 0)
+                       if ((ret != 0) &&
+                               ((dr->drv_flags & RTE_PCI_DRV_IO_PORT) == 0))
                                return ret;
                } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
                           rte_eal_process_type() == RTE_PROC_PRIMARY) {
diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c 
b/lib/librte_pmd_virtio/virtio_ethdev.c
index 1ec29e1..4490a06 100644
--- a/lib/librte_pmd_virtio/virtio_ethdev.c
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c
@@ -961,6 +961,69 @@ static int virtio_resource_init(struct rte_pci_device 
*pci_dev)
                     start, size);
        return 0;
 }
+
+/* Extract I/O port numbers from proc/ioports */
+static int virtio_resource_init_by_ioport(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;
+}
+
 #else
 static int
 virtio_has_msix(const struct rte_pci_addr *loc __rte_unused)
@@ -974,6 +1037,12 @@ static int virtio_resource_init(struct rte_pci_device 
*pci_dev __rte_unused)
        /* no setup required */
        return 0;
 }
+
+static int virtio_resource_init_by_ioport(struct rte_pci_device *pci_dev)
+{
+       /* no setup required */
+       return 0;
+}
 #endif

 /*
@@ -1039,7 +1108,8 @@ 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;
+               if (virtio_resource_init_by_ioport(pci_dev) < 0)
+                       return -1;

        hw->use_msix = virtio_has_msix(&pci_dev->addr);
        hw->io_base = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr;
@@ -1136,7 +1206,8 @@ 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_INTR_LSC,
+               .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IO_PORT |\
+                        RTE_PCI_DRV_INTR_LSC,
        },
        .eth_dev_init = eth_virtio_dev_init,
        .dev_private_size = sizeof(struct virtio_hw),
-- 
1.8.4.2

Reply via email to