xref: /dpdk/lib/vhost/vdpa.c (revision b3f923fe1710e448c073f03aad2c087ffb6c7a5c)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2018 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson /**
699a2dd95SBruce Richardson  * @file
799a2dd95SBruce Richardson  *
899a2dd95SBruce Richardson  * Device specific vhost lib
999a2dd95SBruce Richardson  */
1099a2dd95SBruce Richardson 
1199a2dd95SBruce Richardson #include <sys/queue.h>
1299a2dd95SBruce Richardson 
13fbd59c8eSDavid Marchand #include <dev_driver.h>
1499a2dd95SBruce Richardson #include <rte_class.h>
1599a2dd95SBruce Richardson #include <rte_malloc.h>
1699a2dd95SBruce Richardson #include <rte_spinlock.h>
1799a2dd95SBruce Richardson #include <rte_tailq.h>
1899a2dd95SBruce Richardson 
1999a2dd95SBruce Richardson #include "rte_vdpa.h"
2094c16e89SMaxime Coquelin #include "vdpa_driver.h"
2199a2dd95SBruce Richardson #include "vhost.h"
2219639c3bSHao Chen #include "iotlb.h"
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson /** Double linked list of vDPA devices. */
2599a2dd95SBruce Richardson TAILQ_HEAD(vdpa_device_list, rte_vdpa_device);
2699a2dd95SBruce Richardson 
27148303e2SDavid Marchand static struct vdpa_device_list vdpa_device_list__ =
28148303e2SDavid Marchand 	TAILQ_HEAD_INITIALIZER(vdpa_device_list__);
2999a2dd95SBruce Richardson static rte_spinlock_t vdpa_device_list_lock = RTE_SPINLOCK_INITIALIZER;
30148303e2SDavid Marchand static struct vdpa_device_list * const vdpa_device_list
31148303e2SDavid Marchand 	__rte_guarded_by(&vdpa_device_list_lock) = &vdpa_device_list__;
3299a2dd95SBruce Richardson 
3399a2dd95SBruce Richardson static struct rte_vdpa_device *
3499a2dd95SBruce Richardson __vdpa_find_device_by_name(const char *name)
35148303e2SDavid Marchand 	__rte_exclusive_locks_required(&vdpa_device_list_lock)
3699a2dd95SBruce Richardson {
3799a2dd95SBruce Richardson 	struct rte_vdpa_device *dev, *ret = NULL;
3899a2dd95SBruce Richardson 
3999a2dd95SBruce Richardson 	if (name == NULL)
4099a2dd95SBruce Richardson 		return NULL;
4199a2dd95SBruce Richardson 
42148303e2SDavid Marchand 	TAILQ_FOREACH(dev, vdpa_device_list, next) {
4399a2dd95SBruce Richardson 		if (!strncmp(dev->device->name, name, RTE_DEV_NAME_MAX_LEN)) {
4499a2dd95SBruce Richardson 			ret = dev;
4599a2dd95SBruce Richardson 			break;
4699a2dd95SBruce Richardson 		}
4799a2dd95SBruce Richardson 	}
4899a2dd95SBruce Richardson 
4999a2dd95SBruce Richardson 	return ret;
5099a2dd95SBruce Richardson }
5199a2dd95SBruce Richardson 
5299a2dd95SBruce Richardson struct rte_vdpa_device *
5399a2dd95SBruce Richardson rte_vdpa_find_device_by_name(const char *name)
5499a2dd95SBruce Richardson {
5599a2dd95SBruce Richardson 	struct rte_vdpa_device *dev;
5699a2dd95SBruce Richardson 
5799a2dd95SBruce Richardson 	rte_spinlock_lock(&vdpa_device_list_lock);
5899a2dd95SBruce Richardson 	dev = __vdpa_find_device_by_name(name);
5999a2dd95SBruce Richardson 	rte_spinlock_unlock(&vdpa_device_list_lock);
6099a2dd95SBruce Richardson 
6199a2dd95SBruce Richardson 	return dev;
6299a2dd95SBruce Richardson }
6399a2dd95SBruce Richardson 
6499a2dd95SBruce Richardson struct rte_device *
6599a2dd95SBruce Richardson rte_vdpa_get_rte_device(struct rte_vdpa_device *vdpa_dev)
6699a2dd95SBruce Richardson {
6799a2dd95SBruce Richardson 	if (vdpa_dev == NULL)
6899a2dd95SBruce Richardson 		return NULL;
6999a2dd95SBruce Richardson 
7099a2dd95SBruce Richardson 	return vdpa_dev->device;
7199a2dd95SBruce Richardson }
7299a2dd95SBruce Richardson 
7399a2dd95SBruce Richardson struct rte_vdpa_device *
7499a2dd95SBruce Richardson rte_vdpa_register_device(struct rte_device *rte_dev,
7599a2dd95SBruce Richardson 		struct rte_vdpa_dev_ops *ops)
7699a2dd95SBruce Richardson {
7799a2dd95SBruce Richardson 	struct rte_vdpa_device *dev;
78f92ab3f0SAndy Pei 	int ret = 0;
7999a2dd95SBruce Richardson 
8099a2dd95SBruce Richardson 	if (ops == NULL)
8199a2dd95SBruce Richardson 		return NULL;
8299a2dd95SBruce Richardson 
8399a2dd95SBruce Richardson 	/* Check mandatory ops are implemented */
8499a2dd95SBruce Richardson 	if (!ops->get_queue_num || !ops->get_features ||
8599a2dd95SBruce Richardson 			!ops->get_protocol_features || !ops->dev_conf ||
8699a2dd95SBruce Richardson 			!ops->dev_close || !ops->set_vring_state ||
8799a2dd95SBruce Richardson 			!ops->set_features) {
880e21c7c0SDavid Marchand 		VHOST_CONFIG_LOG(rte_dev->name, ERR,
890e21c7c0SDavid Marchand 			"Some mandatory vDPA ops aren't implemented");
9099a2dd95SBruce Richardson 		return NULL;
9199a2dd95SBruce Richardson 	}
9299a2dd95SBruce Richardson 
9399a2dd95SBruce Richardson 	rte_spinlock_lock(&vdpa_device_list_lock);
9499a2dd95SBruce Richardson 	/* Check the device hasn't been register already */
9599a2dd95SBruce Richardson 	dev = __vdpa_find_device_by_name(rte_dev->name);
9699a2dd95SBruce Richardson 	if (dev) {
9799a2dd95SBruce Richardson 		dev = NULL;
9899a2dd95SBruce Richardson 		goto out_unlock;
9999a2dd95SBruce Richardson 	}
10099a2dd95SBruce Richardson 
10199a2dd95SBruce Richardson 	dev = rte_zmalloc(NULL, sizeof(*dev), 0);
10299a2dd95SBruce Richardson 	if (!dev)
10399a2dd95SBruce Richardson 		goto out_unlock;
10499a2dd95SBruce Richardson 
10599a2dd95SBruce Richardson 	dev->device = rte_dev;
10699a2dd95SBruce Richardson 	dev->ops = ops;
107f92ab3f0SAndy Pei 
108f92ab3f0SAndy Pei 	if (ops->get_dev_type) {
109f92ab3f0SAndy Pei 		ret = ops->get_dev_type(dev, &dev->type);
110f92ab3f0SAndy Pei 		if (ret) {
1110e21c7c0SDavid Marchand 			VHOST_CONFIG_LOG(rte_dev->name, ERR,
1120e21c7c0SDavid Marchand 					 "Failed to get vdpa dev type.");
113f92ab3f0SAndy Pei 			ret = -1;
114f92ab3f0SAndy Pei 			goto out_unlock;
115f92ab3f0SAndy Pei 		}
116f92ab3f0SAndy Pei 	} else {
117f92ab3f0SAndy Pei 		/** by default, we assume vdpa device is a net device */
118f92ab3f0SAndy Pei 		dev->type = RTE_VHOST_VDPA_DEVICE_TYPE_NET;
119f92ab3f0SAndy Pei 	}
120f92ab3f0SAndy Pei 
121148303e2SDavid Marchand 	TAILQ_INSERT_TAIL(vdpa_device_list, dev, next);
12299a2dd95SBruce Richardson out_unlock:
12399a2dd95SBruce Richardson 	rte_spinlock_unlock(&vdpa_device_list_lock);
12499a2dd95SBruce Richardson 
12599a2dd95SBruce Richardson 	return dev;
12699a2dd95SBruce Richardson }
12799a2dd95SBruce Richardson 
12899a2dd95SBruce Richardson int
12999a2dd95SBruce Richardson rte_vdpa_unregister_device(struct rte_vdpa_device *dev)
13099a2dd95SBruce Richardson {
13199a2dd95SBruce Richardson 	struct rte_vdpa_device *cur_dev, *tmp_dev;
13299a2dd95SBruce Richardson 	int ret = -1;
13399a2dd95SBruce Richardson 
13499a2dd95SBruce Richardson 	rte_spinlock_lock(&vdpa_device_list_lock);
135148303e2SDavid Marchand 	RTE_TAILQ_FOREACH_SAFE(cur_dev, vdpa_device_list, next, tmp_dev) {
13699a2dd95SBruce Richardson 		if (dev != cur_dev)
13799a2dd95SBruce Richardson 			continue;
13899a2dd95SBruce Richardson 
139148303e2SDavid Marchand 		TAILQ_REMOVE(vdpa_device_list, dev, next);
14099a2dd95SBruce Richardson 		rte_free(dev);
14199a2dd95SBruce Richardson 		ret = 0;
14299a2dd95SBruce Richardson 		break;
14399a2dd95SBruce Richardson 	}
14499a2dd95SBruce Richardson 	rte_spinlock_unlock(&vdpa_device_list_lock);
14599a2dd95SBruce Richardson 
14699a2dd95SBruce Richardson 	return ret;
14799a2dd95SBruce Richardson }
14899a2dd95SBruce Richardson 
14999a2dd95SBruce Richardson int
15099a2dd95SBruce Richardson rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m)
15199a2dd95SBruce Richardson {
15299a2dd95SBruce Richardson 	struct virtio_net *dev = get_device(vid);
15399a2dd95SBruce Richardson 	uint16_t idx, idx_m, desc_id;
15499a2dd95SBruce Richardson 	struct vhost_virtqueue *vq;
15599a2dd95SBruce Richardson 	struct vring_desc desc;
15699a2dd95SBruce Richardson 	struct vring_desc *desc_ring;
15799a2dd95SBruce Richardson 	struct vring_desc *idesc = NULL;
15899a2dd95SBruce Richardson 	struct vring *s_vring;
15999a2dd95SBruce Richardson 	uint64_t dlen;
16099a2dd95SBruce Richardson 	uint32_t nr_descs;
16199a2dd95SBruce Richardson 	int ret;
16299a2dd95SBruce Richardson 
16399a2dd95SBruce Richardson 	if (!dev || !vring_m)
16499a2dd95SBruce Richardson 		return -1;
16599a2dd95SBruce Richardson 
16699a2dd95SBruce Richardson 	if (qid >= dev->nr_vring)
16799a2dd95SBruce Richardson 		return -1;
16899a2dd95SBruce Richardson 
16999a2dd95SBruce Richardson 	if (vq_is_packed(dev))
17099a2dd95SBruce Richardson 		return -1;
17199a2dd95SBruce Richardson 
17299a2dd95SBruce Richardson 	s_vring = (struct vring *)vring_m;
17399a2dd95SBruce Richardson 	vq = dev->virtqueue[qid];
17499a2dd95SBruce Richardson 	idx = vq->used->idx;
17599a2dd95SBruce Richardson 	idx_m = s_vring->used->idx;
17699a2dd95SBruce Richardson 	ret = (uint16_t)(idx_m - idx);
177*b3f923feSBill Xiang 	vq->used->flags = s_vring->used->flags;
17899a2dd95SBruce Richardson 
17999a2dd95SBruce Richardson 	while (idx != idx_m) {
18099a2dd95SBruce Richardson 		/* copy used entry, used ring logging is not covered here */
18199a2dd95SBruce Richardson 		vq->used->ring[idx & (vq->size - 1)] =
18299a2dd95SBruce Richardson 			s_vring->used->ring[idx & (vq->size - 1)];
18399a2dd95SBruce Richardson 
18499a2dd95SBruce Richardson 		desc_id = vq->used->ring[idx & (vq->size - 1)].id;
18599a2dd95SBruce Richardson 		desc_ring = vq->desc;
18699a2dd95SBruce Richardson 		nr_descs = vq->size;
18799a2dd95SBruce Richardson 
18899a2dd95SBruce Richardson 		if (unlikely(desc_id >= vq->size))
18999a2dd95SBruce Richardson 			return -1;
19099a2dd95SBruce Richardson 
19199a2dd95SBruce Richardson 		if (vq->desc[desc_id].flags & VRING_DESC_F_INDIRECT) {
19299a2dd95SBruce Richardson 			dlen = vq->desc[desc_id].len;
19399a2dd95SBruce Richardson 			nr_descs = dlen / sizeof(struct vring_desc);
19499a2dd95SBruce Richardson 			if (unlikely(nr_descs > vq->size))
19599a2dd95SBruce Richardson 				return -1;
19699a2dd95SBruce Richardson 
19719639c3bSHao Chen 			vhost_user_iotlb_rd_lock(vq);
19899a2dd95SBruce Richardson 			desc_ring = (struct vring_desc *)(uintptr_t)
19999a2dd95SBruce Richardson 				vhost_iova_to_vva(dev, vq,
20099a2dd95SBruce Richardson 						vq->desc[desc_id].addr, &dlen,
20199a2dd95SBruce Richardson 						VHOST_ACCESS_RO);
20219639c3bSHao Chen 			vhost_user_iotlb_rd_unlock(vq);
20399a2dd95SBruce Richardson 			if (unlikely(!desc_ring))
20499a2dd95SBruce Richardson 				return -1;
20599a2dd95SBruce Richardson 
20699a2dd95SBruce Richardson 			if (unlikely(dlen < vq->desc[desc_id].len)) {
20719639c3bSHao Chen 				vhost_user_iotlb_rd_lock(vq);
20899a2dd95SBruce Richardson 				idesc = vhost_alloc_copy_ind_table(dev, vq,
20999a2dd95SBruce Richardson 						vq->desc[desc_id].addr,
21099a2dd95SBruce Richardson 						vq->desc[desc_id].len);
21119639c3bSHao Chen 				vhost_user_iotlb_rd_unlock(vq);
21299a2dd95SBruce Richardson 				if (unlikely(!idesc))
21399a2dd95SBruce Richardson 					return -1;
21499a2dd95SBruce Richardson 
21599a2dd95SBruce Richardson 				desc_ring = idesc;
21699a2dd95SBruce Richardson 			}
21799a2dd95SBruce Richardson 
21899a2dd95SBruce Richardson 			desc_id = 0;
21999a2dd95SBruce Richardson 		}
22099a2dd95SBruce Richardson 
22199a2dd95SBruce Richardson 		/* dirty page logging for DMA writeable buffer */
22299a2dd95SBruce Richardson 		do {
22399a2dd95SBruce Richardson 			if (unlikely(desc_id >= vq->size))
22499a2dd95SBruce Richardson 				goto fail;
22599a2dd95SBruce Richardson 			if (unlikely(nr_descs-- == 0))
22699a2dd95SBruce Richardson 				goto fail;
22799a2dd95SBruce Richardson 			desc = desc_ring[desc_id];
22819639c3bSHao Chen 			if (desc.flags & VRING_DESC_F_WRITE) {
22919639c3bSHao Chen 				vhost_user_iotlb_rd_lock(vq);
23099a2dd95SBruce Richardson 				vhost_log_write_iova(dev, vq, desc.addr,
23199a2dd95SBruce Richardson 						     desc.len);
23219639c3bSHao Chen 				vhost_user_iotlb_rd_unlock(vq);
23319639c3bSHao Chen 			}
23499a2dd95SBruce Richardson 			desc_id = desc.next;
23599a2dd95SBruce Richardson 		} while (desc.flags & VRING_DESC_F_NEXT);
23699a2dd95SBruce Richardson 
23799a2dd95SBruce Richardson 		if (unlikely(idesc)) {
23899a2dd95SBruce Richardson 			free_ind_table(idesc);
23999a2dd95SBruce Richardson 			idesc = NULL;
24099a2dd95SBruce Richardson 		}
24199a2dd95SBruce Richardson 
24299a2dd95SBruce Richardson 		idx++;
24399a2dd95SBruce Richardson 	}
24499a2dd95SBruce Richardson 
24599a2dd95SBruce Richardson 	/* used idx is the synchronization point for the split vring */
2465147b641STyler Retzlaff 	rte_atomic_store_explicit((unsigned short __rte_atomic *)&vq->used->idx,
2475147b641STyler Retzlaff 		idx_m, rte_memory_order_release);
24899a2dd95SBruce Richardson 
24999a2dd95SBruce Richardson 	if (dev->features & (1ULL << VIRTIO_RING_F_EVENT_IDX))
25099a2dd95SBruce Richardson 		vring_used_event(s_vring) = idx_m;
25199a2dd95SBruce Richardson 
25299a2dd95SBruce Richardson 	return ret;
25399a2dd95SBruce Richardson 
25499a2dd95SBruce Richardson fail:
25599a2dd95SBruce Richardson 	if (unlikely(idesc))
25699a2dd95SBruce Richardson 		free_ind_table(idesc);
25799a2dd95SBruce Richardson 	return -1;
25899a2dd95SBruce Richardson }
25999a2dd95SBruce Richardson 
26099a2dd95SBruce Richardson int
26199a2dd95SBruce Richardson rte_vdpa_get_queue_num(struct rte_vdpa_device *dev, uint32_t *queue_num)
26299a2dd95SBruce Richardson {
26399a2dd95SBruce Richardson 	if (dev == NULL || dev->ops == NULL || dev->ops->get_queue_num == NULL)
26499a2dd95SBruce Richardson 		return -1;
26599a2dd95SBruce Richardson 
26699a2dd95SBruce Richardson 	return dev->ops->get_queue_num(dev, queue_num);
26799a2dd95SBruce Richardson }
26899a2dd95SBruce Richardson 
26999a2dd95SBruce Richardson int
27099a2dd95SBruce Richardson rte_vdpa_get_features(struct rte_vdpa_device *dev, uint64_t *features)
27199a2dd95SBruce Richardson {
27299a2dd95SBruce Richardson 	if (dev == NULL || dev->ops == NULL || dev->ops->get_features == NULL)
27399a2dd95SBruce Richardson 		return -1;
27499a2dd95SBruce Richardson 
27599a2dd95SBruce Richardson 	return dev->ops->get_features(dev, features);
27699a2dd95SBruce Richardson }
27799a2dd95SBruce Richardson 
27899a2dd95SBruce Richardson int
27999a2dd95SBruce Richardson rte_vdpa_get_protocol_features(struct rte_vdpa_device *dev, uint64_t *features)
28099a2dd95SBruce Richardson {
28199a2dd95SBruce Richardson 	if (dev == NULL || dev->ops == NULL ||
28299a2dd95SBruce Richardson 			dev->ops->get_protocol_features == NULL)
28399a2dd95SBruce Richardson 		return -1;
28499a2dd95SBruce Richardson 
28599a2dd95SBruce Richardson 	return dev->ops->get_protocol_features(dev, features);
28699a2dd95SBruce Richardson }
28799a2dd95SBruce Richardson 
28899a2dd95SBruce Richardson int
28999a2dd95SBruce Richardson rte_vdpa_get_stats_names(struct rte_vdpa_device *dev,
29099a2dd95SBruce Richardson 		struct rte_vdpa_stat_name *stats_names,
29199a2dd95SBruce Richardson 		unsigned int size)
29299a2dd95SBruce Richardson {
29399a2dd95SBruce Richardson 	if (!dev)
29499a2dd95SBruce Richardson 		return -EINVAL;
29599a2dd95SBruce Richardson 
2968f1d23ecSDavid Marchand 	if (dev->ops->get_stats_names == NULL)
2978f1d23ecSDavid Marchand 		return -ENOTSUP;
29899a2dd95SBruce Richardson 
29999a2dd95SBruce Richardson 	return dev->ops->get_stats_names(dev, stats_names, size);
30099a2dd95SBruce Richardson }
30199a2dd95SBruce Richardson 
30299a2dd95SBruce Richardson int
30399a2dd95SBruce Richardson rte_vdpa_get_stats(struct rte_vdpa_device *dev, uint16_t qid,
30499a2dd95SBruce Richardson 		struct rte_vdpa_stat *stats, unsigned int n)
30599a2dd95SBruce Richardson {
30699a2dd95SBruce Richardson 	if (!dev || !stats || !n)
30799a2dd95SBruce Richardson 		return -EINVAL;
30899a2dd95SBruce Richardson 
3098f1d23ecSDavid Marchand 	if (dev->ops->get_stats == NULL)
3108f1d23ecSDavid Marchand 		return -ENOTSUP;
31199a2dd95SBruce Richardson 
31299a2dd95SBruce Richardson 	return dev->ops->get_stats(dev, qid, stats, n);
31399a2dd95SBruce Richardson }
31499a2dd95SBruce Richardson 
31599a2dd95SBruce Richardson int
31699a2dd95SBruce Richardson rte_vdpa_reset_stats(struct rte_vdpa_device *dev, uint16_t qid)
31799a2dd95SBruce Richardson {
31899a2dd95SBruce Richardson 	if (!dev)
31999a2dd95SBruce Richardson 		return -EINVAL;
32099a2dd95SBruce Richardson 
3218f1d23ecSDavid Marchand 	if (dev->ops->reset_stats == NULL)
3228f1d23ecSDavid Marchand 		return -ENOTSUP;
32399a2dd95SBruce Richardson 
32499a2dd95SBruce Richardson 	return dev->ops->reset_stats(dev, qid);
32599a2dd95SBruce Richardson }
32699a2dd95SBruce Richardson 
32799a2dd95SBruce Richardson static int
32899a2dd95SBruce Richardson vdpa_dev_match(struct rte_vdpa_device *dev,
32999a2dd95SBruce Richardson 	      const struct rte_device *rte_dev)
33099a2dd95SBruce Richardson {
33199a2dd95SBruce Richardson 	if (dev->device == rte_dev)
33299a2dd95SBruce Richardson 		return 0;
33399a2dd95SBruce Richardson 
33499a2dd95SBruce Richardson 	return -1;
33599a2dd95SBruce Richardson }
33699a2dd95SBruce Richardson 
33799a2dd95SBruce Richardson /* Generic rte_vdpa_dev comparison function. */
33899a2dd95SBruce Richardson typedef int (*rte_vdpa_cmp_t)(struct rte_vdpa_device *,
33999a2dd95SBruce Richardson 		const struct rte_device *rte_dev);
34099a2dd95SBruce Richardson 
34199a2dd95SBruce Richardson static struct rte_vdpa_device *
34299a2dd95SBruce Richardson vdpa_find_device(const struct rte_vdpa_device *start, rte_vdpa_cmp_t cmp,
34399a2dd95SBruce Richardson 		struct rte_device *rte_dev)
34499a2dd95SBruce Richardson {
34599a2dd95SBruce Richardson 	struct rte_vdpa_device *dev;
34699a2dd95SBruce Richardson 
34799a2dd95SBruce Richardson 	rte_spinlock_lock(&vdpa_device_list_lock);
34899a2dd95SBruce Richardson 	if (start == NULL)
349148303e2SDavid Marchand 		dev = TAILQ_FIRST(vdpa_device_list);
35099a2dd95SBruce Richardson 	else
35199a2dd95SBruce Richardson 		dev = TAILQ_NEXT(start, next);
35299a2dd95SBruce Richardson 
35399a2dd95SBruce Richardson 	while (dev != NULL) {
35499a2dd95SBruce Richardson 		if (cmp(dev, rte_dev) == 0)
35599a2dd95SBruce Richardson 			break;
35699a2dd95SBruce Richardson 
35799a2dd95SBruce Richardson 		dev = TAILQ_NEXT(dev, next);
35899a2dd95SBruce Richardson 	}
35999a2dd95SBruce Richardson 	rte_spinlock_unlock(&vdpa_device_list_lock);
36099a2dd95SBruce Richardson 
36199a2dd95SBruce Richardson 	return dev;
36299a2dd95SBruce Richardson }
36399a2dd95SBruce Richardson 
36499a2dd95SBruce Richardson static void *
36599a2dd95SBruce Richardson vdpa_dev_iterate(const void *start,
36699a2dd95SBruce Richardson 		const char *str,
36799a2dd95SBruce Richardson 		const struct rte_dev_iterator *it)
36899a2dd95SBruce Richardson {
36999a2dd95SBruce Richardson 	struct rte_vdpa_device *vdpa_dev = NULL;
37099a2dd95SBruce Richardson 
37199a2dd95SBruce Richardson 	RTE_SET_USED(str);
37299a2dd95SBruce Richardson 
37399a2dd95SBruce Richardson 	vdpa_dev = vdpa_find_device(start, vdpa_dev_match, it->device);
37499a2dd95SBruce Richardson 
37599a2dd95SBruce Richardson 	return vdpa_dev;
37699a2dd95SBruce Richardson }
37799a2dd95SBruce Richardson 
37899a2dd95SBruce Richardson static struct rte_class rte_class_vdpa = {
37999a2dd95SBruce Richardson 	.dev_iterate = vdpa_dev_iterate,
38099a2dd95SBruce Richardson };
38199a2dd95SBruce Richardson 
38299a2dd95SBruce Richardson RTE_REGISTER_CLASS(vdpa, rte_class_vdpa);
383