vdpa: introduce map ops

Virtio core allows the transport to provide device or transport
specific mapping functions. This patch adds this support to vDPA. We
can simply do this by allowing the vDPA parent to register a
virtio_map_ops.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20250924070045.10361-2-jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
pull/1354/merge
Jason Wang 2025-09-24 15:00:44 +08:00 committed by Michael S. Tsirkin
parent 58aca3dbc7
commit 0d16cc439f
12 changed files with 29 additions and 15 deletions

View File

@ -478,7 +478,8 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return ret; return ret;
eni_vdpa = vdpa_alloc_device(struct eni_vdpa, vdpa, eni_vdpa = vdpa_alloc_device(struct eni_vdpa, vdpa,
dev, &eni_vdpa_ops, 1, 1, NULL, false); dev, &eni_vdpa_ops, NULL,
1, 1, NULL, false);
if (IS_ERR(eni_vdpa)) { if (IS_ERR(eni_vdpa)) {
ENI_ERR(pdev, "failed to allocate vDPA structure\n"); ENI_ERR(pdev, "failed to allocate vDPA structure\n");
return PTR_ERR(eni_vdpa); return PTR_ERR(eni_vdpa);

View File

@ -705,7 +705,8 @@ static int ifcvf_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
vf = &ifcvf_mgmt_dev->vf; vf = &ifcvf_mgmt_dev->vf;
pdev = vf->pdev; pdev = vf->pdev;
adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa,
&pdev->dev, &ifc_vdpa_ops, 1, 1, NULL, false); &pdev->dev, &ifc_vdpa_ops,
NULL, 1, 1, NULL, false);
if (IS_ERR(adapter)) { if (IS_ERR(adapter)) {
IFCVF_ERR(pdev, "Failed to allocate vDPA structure"); IFCVF_ERR(pdev, "Failed to allocate vDPA structure");
return PTR_ERR(adapter); return PTR_ERR(adapter);

View File

@ -3882,7 +3882,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
} }
ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mgtdev->vdpa_ops, ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mgtdev->vdpa_ops,
MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false); NULL, MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, name, false);
if (IS_ERR(ndev)) if (IS_ERR(ndev))
return PTR_ERR(ndev); return PTR_ERR(ndev);

View File

@ -508,8 +508,8 @@ static int octep_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
u64 device_features; u64 device_features;
int ret; int ret;
oct_vdpa = vdpa_alloc_device(struct octep_vdpa, vdpa, &pdev->dev, &octep_vdpa_ops, 1, 1, oct_vdpa = vdpa_alloc_device(struct octep_vdpa, vdpa, &pdev->dev, &octep_vdpa_ops,
NULL, false); NULL, 1, 1, NULL, false);
if (IS_ERR(oct_vdpa)) { if (IS_ERR(oct_vdpa)) {
dev_err(&pdev->dev, "Failed to allocate vDPA structure for octep vdpa device"); dev_err(&pdev->dev, "Failed to allocate vDPA structure for octep vdpa device");
return PTR_ERR(oct_vdpa); return PTR_ERR(oct_vdpa);

View File

@ -632,7 +632,8 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
} }
pdsv = vdpa_alloc_device(struct pds_vdpa_device, vdpa_dev, pdsv = vdpa_alloc_device(struct pds_vdpa_device, vdpa_dev,
dev, &pds_vdpa_ops, 1, 1, name, false); dev, &pds_vdpa_ops, NULL,
1, 1, name, false);
if (IS_ERR(pdsv)) { if (IS_ERR(pdsv)) {
dev_err(dev, "Failed to allocate vDPA structure: %pe\n", pdsv); dev_err(dev, "Failed to allocate vDPA structure: %pe\n", pdsv);
return PTR_ERR(pdsv); return PTR_ERR(pdsv);

View File

@ -1008,8 +1008,8 @@ static int snet_vdpa_probe_vf(struct pci_dev *pdev)
} }
/* Allocate vdpa device */ /* Allocate vdpa device */
snet = vdpa_alloc_device(struct snet, vdpa, &pdev->dev, &snet_config_ops, 1, 1, NULL, snet = vdpa_alloc_device(struct snet, vdpa, &pdev->dev, &snet_config_ops,
false); NULL, 1, 1, NULL, false);
if (!snet) { if (!snet) {
SNET_ERR(pdev, "Failed to allocate a vdpa device\n"); SNET_ERR(pdev, "Failed to allocate a vdpa device\n");
ret = -ENOMEM; ret = -ENOMEM;

View File

@ -142,6 +142,7 @@ static void vdpa_release_dev(struct device *d)
* initialized but before registered. * initialized but before registered.
* @parent: the parent device * @parent: the parent device
* @config: the bus operations that is supported by this device * @config: the bus operations that is supported by this device
* @map: the map operations that is supported by this device
* @ngroups: number of groups supported by this device * @ngroups: number of groups supported by this device
* @nas: number of address spaces supported by this device * @nas: number of address spaces supported by this device
* @size: size of the parent structure that contains private data * @size: size of the parent structure that contains private data
@ -156,6 +157,7 @@ static void vdpa_release_dev(struct device *d)
*/ */
struct vdpa_device *__vdpa_alloc_device(struct device *parent, struct vdpa_device *__vdpa_alloc_device(struct device *parent,
const struct vdpa_config_ops *config, const struct vdpa_config_ops *config,
const struct virtio_map_ops *map,
unsigned int ngroups, unsigned int nas, unsigned int ngroups, unsigned int nas,
size_t size, const char *name, size_t size, const char *name,
bool use_va) bool use_va)
@ -187,6 +189,7 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
vdev->dev.release = vdpa_release_dev; vdev->dev.release = vdpa_release_dev;
vdev->index = err; vdev->index = err;
vdev->config = config; vdev->config = config;
vdev->map = map;
vdev->features_valid = false; vdev->features_valid = false;
vdev->use_va = use_va; vdev->use_va = use_va;
vdev->ngroups = ngroups; vdev->ngroups = ngroups;

View File

@ -215,7 +215,7 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr,
else else
ops = &vdpasim_config_ops; ops = &vdpasim_config_ops;
vdpa = __vdpa_alloc_device(NULL, ops, vdpa = __vdpa_alloc_device(NULL, ops, NULL,
dev_attr->ngroups, dev_attr->nas, dev_attr->ngroups, dev_attr->nas,
dev_attr->alloc_size, dev_attr->alloc_size,
dev_attr->name, use_va); dev_attr->name, use_va);

View File

@ -2009,7 +2009,8 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
return -EEXIST; return -EEXIST;
vdev = vdpa_alloc_device(struct vduse_vdpa, vdpa, dev->dev, vdev = vdpa_alloc_device(struct vduse_vdpa, vdpa, dev->dev,
&vduse_vdpa_config_ops, 1, 1, name, true); &vduse_vdpa_config_ops, NULL,
1, 1, name, true);
if (IS_ERR(vdev)) if (IS_ERR(vdev))
return PTR_ERR(vdev); return PTR_ERR(vdev);

View File

@ -511,7 +511,8 @@ static int vp_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
int ret, i; int ret, i;
vp_vdpa = vdpa_alloc_device(struct vp_vdpa, vdpa, vp_vdpa = vdpa_alloc_device(struct vp_vdpa, vdpa,
dev, &vp_vdpa_ops, 1, 1, name, false); dev, &vp_vdpa_ops, NULL,
1, 1, name, false);
if (IS_ERR(vp_vdpa)) { if (IS_ERR(vp_vdpa)) {
dev_err(dev, "vp_vdpa: Failed to allocate vDPA structure\n"); dev_err(dev, "vp_vdpa: Failed to allocate vDPA structure\n");

View File

@ -466,9 +466,11 @@ static int virtio_vdpa_probe(struct vdpa_device *vdpa)
if (!vd_dev) if (!vd_dev)
return -ENOMEM; return -ENOMEM;
vd_dev->vdev.dev.parent = vdpa_get_map(vdpa).dma_dev; vd_dev->vdev.dev.parent = vdpa->map ? &vdpa->dev :
vdpa_get_map(vdpa).dma_dev;
vd_dev->vdev.dev.release = virtio_vdpa_release_dev; vd_dev->vdev.dev.release = virtio_vdpa_release_dev;
vd_dev->vdev.config = &virtio_vdpa_config_ops; vd_dev->vdev.config = &virtio_vdpa_config_ops;
vd_dev->vdev.map = vdpa->map;
vd_dev->vdpa = vdpa; vd_dev->vdpa = vdpa;
vd_dev->vdev.id.device = ops->get_device_id(vdpa); vd_dev->vdev.id.device = ops->get_device_id(vdpa);

View File

@ -76,6 +76,7 @@ struct vdpa_mgmt_dev;
* because core frees it; use driver_set_override() to * because core frees it; use driver_set_override() to
* set or clear it. * set or clear it.
* @config: the configuration ops for this device. * @config: the configuration ops for this device.
* @map: the map ops for this device
* @cf_lock: Protects get and set access to configuration layout. * @cf_lock: Protects get and set access to configuration layout.
* @index: device index * @index: device index
* @features_valid: were features initialized? for legacy guests * @features_valid: were features initialized? for legacy guests
@ -91,6 +92,7 @@ struct vdpa_device {
union virtio_map vmap; union virtio_map vmap;
const char *driver_override; const char *driver_override;
const struct vdpa_config_ops *config; const struct vdpa_config_ops *config;
const struct virtio_map_ops *map;
struct rw_semaphore cf_lock; /* Protects get/set config */ struct rw_semaphore cf_lock; /* Protects get/set config */
unsigned int index; unsigned int index;
bool features_valid; bool features_valid;
@ -447,6 +449,7 @@ struct vdpa_config_ops {
struct vdpa_device *__vdpa_alloc_device(struct device *parent, struct vdpa_device *__vdpa_alloc_device(struct device *parent,
const struct vdpa_config_ops *config, const struct vdpa_config_ops *config,
const struct virtio_map_ops *map,
unsigned int ngroups, unsigned int nas, unsigned int ngroups, unsigned int nas,
size_t size, const char *name, size_t size, const char *name,
bool use_va); bool use_va);
@ -458,6 +461,7 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
* @member: the name of struct vdpa_device within the @dev_struct * @member: the name of struct vdpa_device within the @dev_struct
* @parent: the parent device * @parent: the parent device
* @config: the bus operations that is supported by this device * @config: the bus operations that is supported by this device
* @map: the map operations that is supported by this device
* @ngroups: the number of virtqueue groups supported by this device * @ngroups: the number of virtqueue groups supported by this device
* @nas: the number of address spaces * @nas: the number of address spaces
* @name: name of the vdpa device * @name: name of the vdpa device
@ -465,10 +469,10 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
* *
* Return allocated data structure or ERR_PTR upon error * Return allocated data structure or ERR_PTR upon error
*/ */
#define vdpa_alloc_device(dev_struct, member, parent, config, ngroups, nas, \ #define vdpa_alloc_device(dev_struct, member, parent, config, map, \
name, use_va) \ ngroups, nas, name, use_va) \
container_of((__vdpa_alloc_device( \ container_of((__vdpa_alloc_device( \
parent, config, ngroups, nas, \ parent, config, map, ngroups, nas, \
(sizeof(dev_struct) + \ (sizeof(dev_struct) + \
BUILD_BUG_ON_ZERO(offsetof( \ BUILD_BUG_ON_ZERO(offsetof( \
dev_struct, member))), name, use_va)), \ dev_struct, member))), name, use_va)), \