#define VDEV_MP_KEY "bus_vdev_mp"
-int vdev_logtype_bus;
-
/* Forward declare to access virtual bus name */
static struct rte_bus rte_vdev_bus;
return driver == NULL;
}
+static int
+vdev_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+ struct rte_vdev_device *vdev = RTE_DEV_TO_VDEV(dev);
+ const struct rte_vdev_driver *driver;
+
+ if (!vdev) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ if (!vdev->device.driver) {
+ VDEV_LOG(DEBUG, "no driver attach to device %s", dev->name);
+ return 1;
+ }
+
+ driver = container_of(vdev->device.driver, const struct rte_vdev_driver,
+ driver);
+
+ if (driver->dma_map)
+ return driver->dma_map(vdev, addr, iova, len);
+
+ return 0;
+}
+
+static int
+vdev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
+{
+ struct rte_vdev_device *vdev = RTE_DEV_TO_VDEV(dev);
+ const struct rte_vdev_driver *driver;
+
+ if (!vdev) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ if (!vdev->device.driver) {
+ VDEV_LOG(DEBUG, "no driver attach to device %s", dev->name);
+ return 1;
+ }
+
+ driver = container_of(vdev->device.driver, const struct rte_vdev_driver,
+ driver);
+
+ if (driver->dma_unmap)
+ return driver->dma_unmap(vdev, addr, iova, len);
+
+ return 0;
+}
+
static int
vdev_probe_all_drivers(struct rte_vdev_device *dev)
{
const char *name;
struct rte_vdev_driver *driver;
+ enum rte_iova_mode iova_mode;
int ret;
+ if (rte_dev_is_probed(&dev->device))
+ return -EEXIST;
+
name = rte_vdev_device_name(dev);
VDEV_LOG(DEBUG, "Search driver to probe device %s", name);
if (vdev_parse(name, &driver))
return -1;
+
+ iova_mode = rte_eal_iova_mode();
+ if ((driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA) && (iova_mode == RTE_IOVA_PA)) {
+ VDEV_LOG(ERR, "%s requires VA IOVA mode but current mode is PA, not initializing",
+ name);
+ return -1;
+ }
+
ret = driver->probe(dev);
if (ret == 0)
dev->device.driver = &driver->driver;
else
devargs->args = strdup("");
- ret = snprintf(devargs->name, sizeof(devargs->name), "%s", name);
+ ret = strlcpy(devargs->name, name, sizeof(devargs->name));
if (ret < 0 || ret >= (int)sizeof(devargs->name)) {
free(devargs->args);
free(devargs);
if (rte_mp_action_register(VDEV_MP_KEY, vdev_action) < 0 &&
rte_errno != EEXIST) {
+ /* for primary, unsupported IPC is not an error */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+ rte_errno == ENOTSUP)
+ goto scan;
VDEV_LOG(ERR, "Failed to add vdev mp action");
return -1;
}
/* Fall through to allow private vdevs in secondary process */
}
+scan:
/* call custom scan callbacks if any */
rte_spinlock_lock(&vdev_custom_scan_lock);
TAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) {
* by calling rte_devargs_insert() with
* devargs.bus = rte_bus_find_by_name("vdev");
* devargs.type = RTE_DEVTYPE_VIRTUAL;
- * devargs.policy = RTE_DEV_WHITELISTED;
+ * devargs.policy = RTE_DEV_ALLOWED;
*/
custom_scan->callback(custom_scan->user_arg);
}
vdev_probe(void)
{
struct rte_vdev_device *dev;
- int ret = 0;
+ int r, ret = 0;
/* call the init function for each virtual device */
TAILQ_FOREACH(dev, &vdev_device_list, next) {
* we call each driver probe.
*/
- if (rte_dev_is_probed(&dev->device))
- continue;
-
- if (vdev_probe_all_drivers(dev)) {
+ r = vdev_probe_all_drivers(dev);
+ if (r != 0) {
+ if (r == -EEXIST)
+ continue;
VDEV_LOG(ERR, "failed to initialize %s device",
rte_vdev_device_name(dev));
ret = -1;
return rte_vdev_uninit(dev->name);
}
+static enum rte_iova_mode
+vdev_get_iommu_class(void)
+{
+ const char *name;
+ struct rte_vdev_device *dev;
+ struct rte_vdev_driver *driver;
+
+ TAILQ_FOREACH(dev, &vdev_device_list, next) {
+ name = rte_vdev_device_name(dev);
+ if (vdev_parse(name, &driver))
+ continue;
+
+ if (driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA)
+ return RTE_IOVA_VA;
+ }
+
+ return RTE_IOVA_DC;
+}
+
static struct rte_bus rte_vdev_bus = {
.scan = vdev_scan,
.probe = vdev_probe,
.plug = vdev_plug,
.unplug = vdev_unplug,
.parse = vdev_parse,
+ .dma_map = vdev_dma_map,
+ .dma_unmap = vdev_dma_unmap,
+ .get_iommu_class = vdev_get_iommu_class,
.dev_iterate = rte_vdev_dev_iterate,
};
RTE_REGISTER_BUS(vdev, rte_vdev_bus);
-
-RTE_INIT(vdev_init_log)
-{
- vdev_logtype_bus = rte_log_register("bus.vdev");
- if (vdev_logtype_bus >= 0)
- rte_log_set_level(vdev_logtype_bus, RTE_LOG_NOTICE);
-}
+RTE_LOG_REGISTER(vdev_logtype_bus, bus.vdev, NOTICE);