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>
---
 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 2f9643b..a412457 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -100,6 +100,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 8cd2d51..b905532 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.
-- 
1.8.4.2

Reply via email to