Lines Matching +full:add +full:- +full:vdpa
1 // SPDX-License-Identifier: GPL-2.0-only
3 * vDPA bus.
13 #include <linux/vdpa.h>
14 #include <uapi/linux/vdpa.h>
20 /* A global mutex that protects vdpa management device and device level operations. */
26 down_write(&vdev->cf_lock); in vdpa_set_status()
27 vdev->config->set_status(vdev, status); in vdpa_set_status()
28 up_write(&vdev->cf_lock); in vdpa_set_status()
37 struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver); in vdpa_dev_probe()
38 const struct vdpa_config_ops *ops = vdev->config; in vdpa_dev_probe()
42 d->dma_mask = &d->coherent_dma_mask; in vdpa_dev_probe()
47 max_num = ops->get_vq_num_max(vdev); in vdpa_dev_probe()
48 if (ops->get_vq_num_min) in vdpa_dev_probe()
49 min_num = ops->get_vq_num_min(vdev); in vdpa_dev_probe()
51 return -EINVAL; in vdpa_dev_probe()
53 if (drv && drv->probe) in vdpa_dev_probe()
54 ret = drv->probe(vdev); in vdpa_dev_probe()
62 struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver); in vdpa_dev_remove()
64 if (drv && drv->remove) in vdpa_dev_remove()
65 drv->remove(vdev); in vdpa_dev_remove()
73 if (vdev->driver_override) in vdpa_dev_match()
74 return strcmp(vdev->driver_override, drv->name) == 0; in vdpa_dev_match()
76 /* Currently devices must be supported by all vDPA bus drivers */ in vdpa_dev_match()
87 ret = driver_set_override(dev, &vdev->driver_override, buf, count); in driver_override_store()
101 len = snprintf(buf, PAGE_SIZE, "%s\n", vdev->driver_override); in driver_override_show()
119 .name = "vdpa",
129 const struct vdpa_config_ops *ops = vdev->config; in vdpa_release_dev()
131 if (ops->free) in vdpa_release_dev()
132 ops->free(vdev); in vdpa_release_dev()
134 ida_free(&vdpa_index_ida, vdev->index); in vdpa_release_dev()
135 kfree(vdev->driver_override); in vdpa_release_dev()
140 * __vdpa_alloc_device - allocate and initilaize a vDPA device
148 * @name: name of the vdpa device; optional.
164 int err = -EINVAL; in __vdpa_alloc_device()
169 if (!!config->dma_map != !!config->dma_unmap) in __vdpa_alloc_device()
172 /* It should only work for the device that use on-chip IOMMU */ in __vdpa_alloc_device()
173 if (use_va && !(config->dma_map || config->set_map)) in __vdpa_alloc_device()
176 err = -ENOMEM; in __vdpa_alloc_device()
185 vdev->dev.bus = &vdpa_bus; in __vdpa_alloc_device()
186 vdev->dev.parent = parent; in __vdpa_alloc_device()
187 vdev->dev.release = vdpa_release_dev; in __vdpa_alloc_device()
188 vdev->index = err; in __vdpa_alloc_device()
189 vdev->config = config; in __vdpa_alloc_device()
190 vdev->features_valid = false; in __vdpa_alloc_device()
191 vdev->use_va = use_va; in __vdpa_alloc_device()
192 vdev->ngroups = ngroups; in __vdpa_alloc_device()
193 vdev->nas = nas; in __vdpa_alloc_device()
196 err = dev_set_name(&vdev->dev, "%s", name); in __vdpa_alloc_device()
198 err = dev_set_name(&vdev->dev, "vdpa%u", vdev->index); in __vdpa_alloc_device()
202 init_rwsem(&vdev->cf_lock); in __vdpa_alloc_device()
203 device_initialize(&vdev->dev); in __vdpa_alloc_device()
208 ida_free(&vdpa_index_ida, vdev->index); in __vdpa_alloc_device()
220 return (strcmp(dev_name(&vdev->dev), data) == 0); in vdpa_name_match()
227 vdev->nvqs = nvqs; in __vdpa_register_device()
230 dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match); in __vdpa_register_device()
233 return -EEXIST; in __vdpa_register_device()
235 return device_add(&vdev->dev); in __vdpa_register_device()
239 * _vdpa_register_device - register a vDPA device with vdpa lock held
242 * callback after setting up valid mgmtdev for this vdpa device.
243 * @vdev: the vdpa device to be registered to vDPA bus
246 * Return: Returns an error when fail to add device to vDPA bus
250 if (!vdev->mdev) in _vdpa_register_device()
251 return -EINVAL; in _vdpa_register_device()
258 * vdpa_register_device - register a vDPA device
260 * @vdev: the vdpa device to be registered to vDPA bus
263 * Return: Returns an error when fail to add to vDPA bus
277 * _vdpa_unregister_device - unregister a vDPA device
280 * @vdev: the vdpa device to be unregisted from vDPA bus
285 WARN_ON(!vdev->mdev); in _vdpa_unregister_device()
286 device_unregister(&vdev->dev); in _vdpa_unregister_device()
291 * vdpa_unregister_device - unregister a vDPA device
292 * @vdev: the vdpa device to be unregisted from vDPA bus
297 device_unregister(&vdev->dev); in vdpa_unregister_device()
303 * __vdpa_register_driver - register a vDPA device driver
304 * @drv: the vdpa device driver to be registered
311 drv->driver.bus = &vdpa_bus; in __vdpa_register_driver()
312 drv->driver.owner = owner; in __vdpa_register_driver()
314 return driver_register(&drv->driver); in __vdpa_register_driver()
319 * vdpa_unregister_driver - unregister a vDPA device driver
320 * @drv: the vdpa device driver to be unregistered
324 driver_unregister(&drv->driver); in vdpa_unregister_driver()
329 * vdpa_mgmtdev_register - register a vdpa management device
331 * @mdev: Pointer to vdpa management device
332 * vdpa_mgmtdev_register() register a vdpa management device which supports
333 * vdpa device management.
339 if (!mdev->device || !mdev->ops || !mdev->ops->dev_add || !mdev->ops->dev_del) in vdpa_mgmtdev_register()
340 return -EINVAL; in vdpa_mgmtdev_register()
342 INIT_LIST_HEAD(&mdev->list); in vdpa_mgmtdev_register()
344 list_add_tail(&mdev->list, &mdev_head); in vdpa_mgmtdev_register()
353 struct vdpa_mgmt_dev *mdev = vdev->mdev; in vdpa_match_remove()
356 mdev->ops->dev_del(mdev, vdev); in vdpa_match_remove()
364 list_del(&mdev->list); in vdpa_mgmtdev_unregister()
377 const struct vdpa_config_ops *ops = vdev->config; in vdpa_get_config_unlocked()
383 if (!vdev->features_valid) in vdpa_get_config_unlocked()
385 ops->get_config(vdev, offset, buf, len); in vdpa_get_config_unlocked()
389 * vdpa_get_config - Get one or more device configuration fields.
390 * @vdev: vdpa device to operate on
398 down_read(&vdev->cf_lock); in vdpa_get_config()
400 up_read(&vdev->cf_lock); in vdpa_get_config()
405 * vdpa_set_config - Set one or more device configuration fields.
406 * @vdev: vdpa device to operate on
414 down_write(&vdev->cf_lock); in vdpa_set_config()
415 vdev->config->set_config(vdev, offset, buf, length); in vdpa_set_config()
416 up_write(&vdev->cf_lock); in vdpa_set_config()
426 if ((busname && !mdev->device->bus) || (!busname && mdev->device->bus)) in mgmtdev_handle_match()
429 if (!busname && strcmp(dev_name(mdev->device), devname) == 0) in mgmtdev_handle_match()
432 if (busname && (strcmp(mdev->device->bus->name, busname) == 0) && in mgmtdev_handle_match()
433 (strcmp(dev_name(mdev->device), devname) == 0)) in mgmtdev_handle_match()
446 return ERR_PTR(-EINVAL); in vdpa_mgmtdev_get_from_attr()
455 return ERR_PTR(-ENODEV); in vdpa_mgmtdev_get_from_attr()
460 if (mdev->device->bus && in vdpa_nl_mgmtdev_handle_fill()
461 nla_put_string(msg, VDPA_ATTR_MGMTDEV_BUS_NAME, mdev->device->bus->name)) in vdpa_nl_mgmtdev_handle_fill()
462 return -EMSGSIZE; in vdpa_nl_mgmtdev_handle_fill()
463 if (nla_put_string(msg, VDPA_ATTR_MGMTDEV_DEV_NAME, dev_name(mdev->device))) in vdpa_nl_mgmtdev_handle_fill()
464 return -EMSGSIZE; in vdpa_nl_mgmtdev_handle_fill()
474 for (int i = 0; mdev->id_table[i].device; i++) { in vdpa_mgmtdev_get_classes()
475 if (mdev->id_table[i].device > 63) in vdpa_mgmtdev_get_classes()
477 supported_classes |= BIT_ULL(mdev->id_table[i].device); in vdpa_mgmtdev_get_classes()
494 return -EMSGSIZE; in vdpa_mgmtdev_fill()
502 err = -EMSGSIZE; in vdpa_mgmtdev_fill()
506 mdev->max_supported_vqs)) { in vdpa_mgmtdev_fill()
507 err = -EMSGSIZE; in vdpa_mgmtdev_fill()
511 mdev->supported_features, VDPA_ATTR_PAD)) { in vdpa_mgmtdev_fill()
512 err = -EMSGSIZE; in vdpa_mgmtdev_fill()
532 return -ENOMEM; in vdpa_nl_cmd_mgmtdev_get_doit()
535 mdev = vdpa_mgmtdev_get_from_attr(info->attrs); in vdpa_nl_cmd_mgmtdev_get_doit()
538 NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified mgmt device"); in vdpa_nl_cmd_mgmtdev_get_doit()
543 err = vdpa_mgmtdev_fill(mdev, msg, info->snd_portid, info->snd_seq, 0); in vdpa_nl_cmd_mgmtdev_get_doit()
559 int start = cb->args[0]; in vdpa_nl_cmd_mgmtdev_get_dumpit()
569 err = vdpa_mgmtdev_fill(mdev, msg, NETLINK_CB(cb->skb).portid, in vdpa_nl_cmd_mgmtdev_get_dumpit()
570 cb->nlh->nlmsg_seq, NLM_F_MULTI); in vdpa_nl_cmd_mgmtdev_get_dumpit()
577 cb->args[0] = idx; in vdpa_nl_cmd_mgmtdev_get_dumpit()
578 return msg->len; in vdpa_nl_cmd_mgmtdev_get_dumpit()
586 * Bitmask for all per-device features: feature bits VIRTIO_TRANSPORT_F_START
589 * "holes" are reserved for other type of features than per-device, this
593 ((1ULL << VIRTIO_TRANSPORT_F_START) - 1))
598 struct nlattr **nl_attrs = info->attrs; in vdpa_nl_cmd_dev_add_set_doit()
606 if (!info->attrs[VDPA_ATTR_DEV_NAME]) in vdpa_nl_cmd_dev_add_set_doit()
607 return -EINVAL; in vdpa_nl_cmd_dev_add_set_doit()
609 name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); in vdpa_nl_cmd_dev_add_set_doit()
625 NL_SET_ERR_MSG_MOD(info->extack, in vdpa_nl_cmd_dev_add_set_doit()
627 return -EINVAL; in vdpa_nl_cmd_dev_add_set_doit()
647 NL_SET_ERR_MSG_FMT_MOD(info->extack, in vdpa_nl_cmd_dev_add_set_doit()
650 return -EINVAL; in vdpa_nl_cmd_dev_add_set_doit()
662 return -EPERM; in vdpa_nl_cmd_dev_add_set_doit()
665 mdev = vdpa_mgmtdev_get_from_attr(info->attrs); in vdpa_nl_cmd_dev_add_set_doit()
667 NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified management device"); in vdpa_nl_cmd_dev_add_set_doit()
672 if ((config.mask & mdev->config_attr_mask) != config.mask) { in vdpa_nl_cmd_dev_add_set_doit()
673 NL_SET_ERR_MSG_FMT_MOD(info->extack, in vdpa_nl_cmd_dev_add_set_doit()
675 config.mask & ~mdev->config_attr_mask); in vdpa_nl_cmd_dev_add_set_doit()
676 err = -EOPNOTSUPP; in vdpa_nl_cmd_dev_add_set_doit()
683 NL_SET_ERR_MSG_MOD(info->extack, in vdpa_nl_cmd_dev_add_set_doit()
685 err = -EINVAL; in vdpa_nl_cmd_dev_add_set_doit()
692 NL_SET_ERR_MSG_MOD(info->extack, in vdpa_nl_cmd_dev_add_set_doit()
693 "Management device supports multi-class while device features specified are ambiguous"); in vdpa_nl_cmd_dev_add_set_doit()
694 err = -EINVAL; in vdpa_nl_cmd_dev_add_set_doit()
698 err = mdev->ops->dev_add(mdev, name, &config); in vdpa_nl_cmd_dev_add_set_doit()
712 if (!info->attrs[VDPA_ATTR_DEV_NAME]) in vdpa_nl_cmd_dev_del_set_doit()
713 return -EINVAL; in vdpa_nl_cmd_dev_del_set_doit()
714 name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); in vdpa_nl_cmd_dev_del_set_doit()
719 NL_SET_ERR_MSG_MOD(info->extack, "device not found"); in vdpa_nl_cmd_dev_del_set_doit()
720 err = -ENODEV; in vdpa_nl_cmd_dev_del_set_doit()
724 if (!vdev->mdev) { in vdpa_nl_cmd_dev_del_set_doit()
725 NL_SET_ERR_MSG_MOD(info->extack, "Only user created device can be deleted by user"); in vdpa_nl_cmd_dev_del_set_doit()
726 err = -EINVAL; in vdpa_nl_cmd_dev_del_set_doit()
729 mdev = vdev->mdev; in vdpa_nl_cmd_dev_del_set_doit()
730 mdev->ops->dev_del(mdev, vdev); in vdpa_nl_cmd_dev_del_set_doit()
751 return -EMSGSIZE; in vdpa_dev_fill()
753 err = vdpa_nl_mgmtdev_handle_fill(msg, vdev->mdev); in vdpa_dev_fill()
757 device_id = vdev->config->get_device_id(vdev); in vdpa_dev_fill()
758 vendor_id = vdev->config->get_vendor_id(vdev); in vdpa_dev_fill()
759 max_vq_size = vdev->config->get_vq_num_max(vdev); in vdpa_dev_fill()
760 if (vdev->config->get_vq_num_min) in vdpa_dev_fill()
761 min_vq_size = vdev->config->get_vq_num_min(vdev); in vdpa_dev_fill()
763 err = -EMSGSIZE; in vdpa_dev_fill()
764 if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev))) in vdpa_dev_fill()
770 if (nla_put_u32(msg, VDPA_ATTR_DEV_MAX_VQS, vdev->nvqs)) in vdpa_dev_fill()
793 if (!info->attrs[VDPA_ATTR_DEV_NAME]) in vdpa_nl_cmd_dev_get_doit()
794 return -EINVAL; in vdpa_nl_cmd_dev_get_doit()
795 devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); in vdpa_nl_cmd_dev_get_doit()
798 return -ENOMEM; in vdpa_nl_cmd_dev_get_doit()
803 NL_SET_ERR_MSG_MOD(info->extack, "device not found"); in vdpa_nl_cmd_dev_get_doit()
804 err = -ENODEV; in vdpa_nl_cmd_dev_get_doit()
808 if (!vdev->mdev) { in vdpa_nl_cmd_dev_get_doit()
809 err = -EINVAL; in vdpa_nl_cmd_dev_get_doit()
812 err = vdpa_dev_fill(vdev, msg, info->snd_portid, info->snd_seq, 0, info->extack); in vdpa_nl_cmd_dev_get_doit()
842 if (!vdev->mdev) in vdpa_dev_dump()
844 if (info->idx < info->start_idx) { in vdpa_dev_dump()
845 info->idx++; in vdpa_dev_dump()
848 err = vdpa_dev_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid, in vdpa_dev_dump()
849 info->cb->nlh->nlmsg_seq, NLM_F_MULTI, info->cb->extack); in vdpa_dev_dump()
853 info->idx++; in vdpa_dev_dump()
863 info.start_idx = cb->args[0]; in vdpa_nl_cmd_dev_get_dumpit()
869 cb->args[0] = info.idx; in vdpa_nl_cmd_dev_get_dumpit()
870 return msg->len; in vdpa_nl_cmd_dev_get_dumpit()
882 val_u16 = __virtio16_to_cpu(true, config->max_virtqueue_pairs); in vdpa_dev_net_mq_config_fill()
895 val_u16 = __virtio16_to_cpu(true, config->mtu); in vdpa_dev_net_mtu_config_fill()
907 sizeof(config->mac), config->mac); in vdpa_dev_net_mac_config_fill()
918 val_u16 = __virtio16_to_cpu(true, config->status); in vdpa_dev_net_status_config_fill()
927 vdev->config->get_config(vdev, 0, &config, sizeof(config)); in vdpa_dev_net_config_fill()
929 features_device = vdev->config->get_device_features(vdev); in vdpa_dev_net_config_fill()
933 return -EMSGSIZE; in vdpa_dev_net_config_fill()
936 return -EMSGSIZE; in vdpa_dev_net_config_fill()
939 return -EMSGSIZE; in vdpa_dev_net_config_fill()
942 return -EMSGSIZE; in vdpa_dev_net_config_fill()
957 down_read(&vdev->cf_lock); in vdpa_dev_config_fill()
961 err = -EMSGSIZE; in vdpa_dev_config_fill()
965 if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev))) { in vdpa_dev_config_fill()
966 err = -EMSGSIZE; in vdpa_dev_config_fill()
970 device_id = vdev->config->get_device_id(vdev); in vdpa_dev_config_fill()
972 err = -EMSGSIZE; in vdpa_dev_config_fill()
977 status = vdev->config->get_status(vdev); in vdpa_dev_config_fill()
979 features_driver = vdev->config->get_driver_features(vdev); in vdpa_dev_config_fill()
982 err = -EMSGSIZE; in vdpa_dev_config_fill()
992 err = -EOPNOTSUPP; in vdpa_dev_config_fill()
998 up_read(&vdev->cf_lock); in vdpa_dev_config_fill()
1005 up_read(&vdev->cf_lock); in vdpa_dev_config_fill()
1017 status = vdev->config->get_status(vdev); in vdpa_fill_stats_rec()
1019 NL_SET_ERR_MSG_MOD(info->extack, "feature negotiation not complete"); in vdpa_fill_stats_rec()
1020 return -EAGAIN; in vdpa_fill_stats_rec()
1024 features = vdev->config->get_driver_features(vdev); in vdpa_fill_stats_rec()
1027 return -EMSGSIZE; in vdpa_fill_stats_rec()
1034 return -EMSGSIZE; in vdpa_fill_stats_rec()
1036 err = vdev->config->get_vendor_vq_stats(vdev, index, msg, info->extack); in vdpa_fill_stats_rec()
1048 down_read(&vdev->cf_lock); in vendor_stats_fill()
1049 if (!vdev->config->get_vendor_vq_stats) { in vendor_stats_fill()
1050 err = -EOPNOTSUPP; in vendor_stats_fill()
1056 up_read(&vdev->cf_lock); in vendor_stats_fill()
1067 u32 portid = info->snd_portid; in vdpa_dev_vendor_stats_fill()
1068 u32 seq = info->snd_seq; in vdpa_dev_vendor_stats_fill()
1074 return -EMSGSIZE; in vdpa_dev_vendor_stats_fill()
1076 if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev))) { in vdpa_dev_vendor_stats_fill()
1077 err = -EMSGSIZE; in vdpa_dev_vendor_stats_fill()
1081 device_id = vdev->config->get_device_id(vdev); in vdpa_dev_vendor_stats_fill()
1083 err = -EMSGSIZE; in vdpa_dev_vendor_stats_fill()
1090 NL_SET_ERR_MSG_MOD(info->extack, "queue index exceeds max value"); in vdpa_dev_vendor_stats_fill()
1091 err = -ERANGE; in vdpa_dev_vendor_stats_fill()
1098 err = -EOPNOTSUPP; in vdpa_dev_vendor_stats_fill()
1118 if (!info->attrs[VDPA_ATTR_DEV_NAME]) in vdpa_nl_cmd_dev_config_get_doit()
1119 return -EINVAL; in vdpa_nl_cmd_dev_config_get_doit()
1120 devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); in vdpa_nl_cmd_dev_config_get_doit()
1123 return -ENOMEM; in vdpa_nl_cmd_dev_config_get_doit()
1128 NL_SET_ERR_MSG_MOD(info->extack, "device not found"); in vdpa_nl_cmd_dev_config_get_doit()
1129 err = -ENODEV; in vdpa_nl_cmd_dev_config_get_doit()
1133 if (!vdev->mdev) { in vdpa_nl_cmd_dev_config_get_doit()
1134 NL_SET_ERR_MSG_MOD(info->extack, "unmanaged vdpa device"); in vdpa_nl_cmd_dev_config_get_doit()
1135 err = -EINVAL; in vdpa_nl_cmd_dev_config_get_doit()
1138 err = vdpa_dev_config_fill(vdev, msg, info->snd_portid, info->snd_seq, in vdpa_nl_cmd_dev_config_get_doit()
1139 0, info->extack); in vdpa_nl_cmd_dev_config_get_doit()
1158 if (!vdev->mdev) in vdpa_dev_config_dump()
1160 if (info->idx < info->start_idx) { in vdpa_dev_config_dump()
1161 info->idx++; in vdpa_dev_config_dump()
1164 err = vdpa_dev_config_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid, in vdpa_dev_config_dump()
1165 info->cb->nlh->nlmsg_seq, NLM_F_MULTI, in vdpa_dev_config_dump()
1166 info->cb->extack); in vdpa_dev_config_dump()
1170 info->idx++; in vdpa_dev_config_dump()
1181 info.start_idx = cb->args[0]; in vdpa_nl_cmd_dev_config_get_dumpit()
1187 cb->args[0] = info.idx; in vdpa_nl_cmd_dev_config_get_dumpit()
1188 return msg->len; in vdpa_nl_cmd_dev_config_get_dumpit()
1201 if (!info->attrs[VDPA_ATTR_DEV_NAME]) in vdpa_nl_cmd_dev_stats_get_doit()
1202 return -EINVAL; in vdpa_nl_cmd_dev_stats_get_doit()
1204 if (!info->attrs[VDPA_ATTR_DEV_QUEUE_INDEX]) in vdpa_nl_cmd_dev_stats_get_doit()
1205 return -EINVAL; in vdpa_nl_cmd_dev_stats_get_doit()
1207 devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); in vdpa_nl_cmd_dev_stats_get_doit()
1210 return -ENOMEM; in vdpa_nl_cmd_dev_stats_get_doit()
1212 index = nla_get_u32(info->attrs[VDPA_ATTR_DEV_QUEUE_INDEX]); in vdpa_nl_cmd_dev_stats_get_doit()
1216 NL_SET_ERR_MSG_MOD(info->extack, "device not found"); in vdpa_nl_cmd_dev_stats_get_doit()
1217 err = -ENODEV; in vdpa_nl_cmd_dev_stats_get_doit()
1221 if (!vdev->mdev) { in vdpa_nl_cmd_dev_stats_get_doit()
1222 NL_SET_ERR_MSG_MOD(info->extack, "unmanaged vdpa device"); in vdpa_nl_cmd_dev_stats_get_doit()
1223 err = -EINVAL; in vdpa_nl_cmd_dev_stats_get_doit()