blob: 09bbe53c3ac4ec193717af888f58a0ba1347e636 [file] [log] [blame]
Jason Wang961e9c82020-03-26 22:01:21 +08001// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * vDPA bus.
4 *
5 * Copyright (c) 2020, Red Hat. All rights reserved.
6 * Author: Jason Wang <jasowang@redhat.com>
7 *
8 */
9
10#include <linux/module.h>
11#include <linux/idr.h>
12#include <linux/slab.h>
13#include <linux/vdpa.h>
Parav Pandit33b34752021-01-05 12:32:00 +020014#include <uapi/linux/vdpa.h>
15#include <net/genetlink.h>
16#include <linux/mod_devicetable.h>
Parav Panditad69dd02021-10-26 20:55:13 +030017#include <linux/virtio_ids.h>
Jason Wang961e9c82020-03-26 22:01:21 +080018
Parav Pandit33b34752021-01-05 12:32:00 +020019static LIST_HEAD(mdev_head);
Parav Panditfd70a402021-01-05 12:31:59 +020020/* A global mutex that protects vdpa management device and device level operations. */
21static DEFINE_MUTEX(vdpa_dev_mutex);
Jason Wang961e9c82020-03-26 22:01:21 +080022static DEFINE_IDA(vdpa_index_ida);
23
Parav Pandit33b34752021-01-05 12:32:00 +020024static struct genl_family vdpa_nl_family;
25
Jason Wang961e9c82020-03-26 22:01:21 +080026static int vdpa_dev_probe(struct device *d)
27{
28 struct vdpa_device *vdev = dev_to_vdpa(d);
29 struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver);
Wu Zongyongc53e5d12021-10-29 17:14:46 +080030 const struct vdpa_config_ops *ops = vdev->config;
31 u32 max_num, min_num = 1;
Jason Wang961e9c82020-03-26 22:01:21 +080032 int ret = 0;
33
Wu Zongyongc53e5d12021-10-29 17:14:46 +080034 max_num = ops->get_vq_num_max(vdev);
35 if (ops->get_vq_num_min)
36 min_num = ops->get_vq_num_min(vdev);
37 if (max_num < min_num)
38 return -EINVAL;
39
Jason Wang961e9c82020-03-26 22:01:21 +080040 if (drv && drv->probe)
41 ret = drv->probe(vdev);
42
43 return ret;
44}
45
Uwe Kleine-Königfc7a6202021-07-13 21:35:22 +020046static void vdpa_dev_remove(struct device *d)
Jason Wang961e9c82020-03-26 22:01:21 +080047{
48 struct vdpa_device *vdev = dev_to_vdpa(d);
49 struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver);
50
51 if (drv && drv->remove)
52 drv->remove(vdev);
Jason Wang961e9c82020-03-26 22:01:21 +080053}
54
55static struct bus_type vdpa_bus = {
56 .name = "vdpa",
57 .probe = vdpa_dev_probe,
58 .remove = vdpa_dev_remove,
59};
60
61static void vdpa_release_dev(struct device *d)
62{
63 struct vdpa_device *vdev = dev_to_vdpa(d);
64 const struct vdpa_config_ops *ops = vdev->config;
65
66 if (ops->free)
67 ops->free(vdev);
68
69 ida_simple_remove(&vdpa_index_ida, vdev->index);
Parav Panditad69dd02021-10-26 20:55:13 +030070 mutex_destroy(&vdev->cf_mutex);
Jason Wang961e9c82020-03-26 22:01:21 +080071 kfree(vdev);
72}
73
74/**
75 * __vdpa_alloc_device - allocate and initilaize a vDPA device
76 * This allows driver to some prepartion after device is
77 * initialized but before registered.
78 * @parent: the parent device
79 * @config: the bus operations that is supported by this device
80 * @size: size of the parent structure that contains private data
Parav Panditfd70a402021-01-05 12:31:59 +020081 * @name: name of the vdpa device; optional.
Xie Yongjid8945ec2021-08-31 18:36:31 +080082 * @use_va: indicate whether virtual address must be used by this device
Jason Wang961e9c82020-03-26 22:01:21 +080083 *
Jason Wang24eae8e2020-05-27 14:05:28 +080084 * Driver should use vdpa_alloc_device() wrapper macro instead of
Jason Wang961e9c82020-03-26 22:01:21 +080085 * using this directly.
86 *
Parav Panditc0a54b42021-04-06 20:04:45 +030087 * Return: Returns an error when parent/config/dma_dev is not set or fail to get
88 * ida.
Jason Wang961e9c82020-03-26 22:01:21 +080089 */
90struct vdpa_device *__vdpa_alloc_device(struct device *parent,
91 const struct vdpa_config_ops *config,
Xie Yongjid8945ec2021-08-31 18:36:31 +080092 size_t size, const char *name,
93 bool use_va)
Jason Wang961e9c82020-03-26 22:01:21 +080094{
95 struct vdpa_device *vdev;
96 int err = -EINVAL;
97
98 if (!config)
99 goto err;
100
101 if (!!config->dma_map != !!config->dma_unmap)
102 goto err;
103
Xie Yongjid8945ec2021-08-31 18:36:31 +0800104 /* It should only work for the device that use on-chip IOMMU */
105 if (use_va && !(config->dma_map || config->set_map))
106 goto err;
107
Jason Wang961e9c82020-03-26 22:01:21 +0800108 err = -ENOMEM;
109 vdev = kzalloc(size, GFP_KERNEL);
110 if (!vdev)
111 goto err;
112
Parav Pandit418edde2020-11-12 08:40:00 +0200113 err = ida_alloc(&vdpa_index_ida, GFP_KERNEL);
Jason Wang961e9c82020-03-26 22:01:21 +0800114 if (err < 0)
115 goto err_ida;
116
117 vdev->dev.bus = &vdpa_bus;
118 vdev->dev.parent = parent;
119 vdev->dev.release = vdpa_release_dev;
120 vdev->index = err;
121 vdev->config = config;
Michael S. Tsirkin452639a2020-07-27 10:51:55 -0400122 vdev->features_valid = false;
Xie Yongjid8945ec2021-08-31 18:36:31 +0800123 vdev->use_va = use_va;
Jason Wang961e9c82020-03-26 22:01:21 +0800124
Parav Panditfd70a402021-01-05 12:31:59 +0200125 if (name)
126 err = dev_set_name(&vdev->dev, "%s", name);
127 else
128 err = dev_set_name(&vdev->dev, "vdpa%u", vdev->index);
Jason Wang961e9c82020-03-26 22:01:21 +0800129 if (err)
130 goto err_name;
131
Parav Panditad69dd02021-10-26 20:55:13 +0300132 mutex_init(&vdev->cf_mutex);
Jason Wang961e9c82020-03-26 22:01:21 +0800133 device_initialize(&vdev->dev);
134
135 return vdev;
136
137err_name:
138 ida_simple_remove(&vdpa_index_ida, vdev->index);
139err_ida:
140 kfree(vdev);
141err:
142 return ERR_PTR(err);
143}
144EXPORT_SYMBOL_GPL(__vdpa_alloc_device);
145
Parav Panditfd70a402021-01-05 12:31:59 +0200146static int vdpa_name_match(struct device *dev, const void *data)
147{
148 struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
149
150 return (strcmp(dev_name(&vdev->dev), data) == 0);
151}
152
Jason Wangf00bdce2021-02-23 14:19:04 +0800153static int __vdpa_register_device(struct vdpa_device *vdev, int nvqs)
Parav Pandit903f7bc2021-01-05 12:32:01 +0200154{
155 struct device *dev;
156
Jason Wangf00bdce2021-02-23 14:19:04 +0800157 vdev->nvqs = nvqs;
158
Parav Pandit903f7bc2021-01-05 12:32:01 +0200159 lockdep_assert_held(&vdpa_dev_mutex);
160 dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match);
161 if (dev) {
162 put_device(dev);
163 return -EEXIST;
164 }
165 return device_add(&vdev->dev);
166}
167
168/**
169 * _vdpa_register_device - register a vDPA device with vdpa lock held
170 * Caller must have a succeed call of vdpa_alloc_device() before.
171 * Caller must invoke this routine in the management device dev_add()
172 * callback after setting up valid mgmtdev for this vdpa device.
173 * @vdev: the vdpa device to be registered to vDPA bus
Jason Wangf00bdce2021-02-23 14:19:04 +0800174 * @nvqs: number of virtqueues supported by this device
Parav Pandit903f7bc2021-01-05 12:32:01 +0200175 *
Parav Panditc0a54b42021-04-06 20:04:45 +0300176 * Return: Returns an error when fail to add device to vDPA bus
Parav Pandit903f7bc2021-01-05 12:32:01 +0200177 */
Jason Wangf00bdce2021-02-23 14:19:04 +0800178int _vdpa_register_device(struct vdpa_device *vdev, int nvqs)
Parav Pandit903f7bc2021-01-05 12:32:01 +0200179{
180 if (!vdev->mdev)
181 return -EINVAL;
182
Jason Wangf00bdce2021-02-23 14:19:04 +0800183 return __vdpa_register_device(vdev, nvqs);
Parav Pandit903f7bc2021-01-05 12:32:01 +0200184}
185EXPORT_SYMBOL_GPL(_vdpa_register_device);
186
Jason Wang961e9c82020-03-26 22:01:21 +0800187/**
188 * vdpa_register_device - register a vDPA device
Jason Wangac8b85f2020-04-13 17:37:38 +0800189 * Callers must have a succeed call of vdpa_alloc_device() before.
Jason Wang961e9c82020-03-26 22:01:21 +0800190 * @vdev: the vdpa device to be registered to vDPA bus
Jason Wangf00bdce2021-02-23 14:19:04 +0800191 * @nvqs: number of virtqueues supported by this device
Jason Wang961e9c82020-03-26 22:01:21 +0800192 *
Parav Panditc0a54b42021-04-06 20:04:45 +0300193 * Return: Returns an error when fail to add to vDPA bus
Jason Wang961e9c82020-03-26 22:01:21 +0800194 */
Jason Wangf00bdce2021-02-23 14:19:04 +0800195int vdpa_register_device(struct vdpa_device *vdev, int nvqs)
Jason Wang961e9c82020-03-26 22:01:21 +0800196{
Parav Panditfd70a402021-01-05 12:31:59 +0200197 int err;
198
199 mutex_lock(&vdpa_dev_mutex);
Jason Wangf00bdce2021-02-23 14:19:04 +0800200 err = __vdpa_register_device(vdev, nvqs);
Parav Panditfd70a402021-01-05 12:31:59 +0200201 mutex_unlock(&vdpa_dev_mutex);
202 return err;
Jason Wang961e9c82020-03-26 22:01:21 +0800203}
204EXPORT_SYMBOL_GPL(vdpa_register_device);
205
206/**
Parav Pandit903f7bc2021-01-05 12:32:01 +0200207 * _vdpa_unregister_device - unregister a vDPA device
208 * Caller must invoke this routine as part of management device dev_del()
209 * callback.
210 * @vdev: the vdpa device to be unregisted from vDPA bus
211 */
212void _vdpa_unregister_device(struct vdpa_device *vdev)
213{
214 lockdep_assert_held(&vdpa_dev_mutex);
215 WARN_ON(!vdev->mdev);
216 device_unregister(&vdev->dev);
217}
218EXPORT_SYMBOL_GPL(_vdpa_unregister_device);
219
220/**
Jason Wang961e9c82020-03-26 22:01:21 +0800221 * vdpa_unregister_device - unregister a vDPA device
222 * @vdev: the vdpa device to be unregisted from vDPA bus
223 */
224void vdpa_unregister_device(struct vdpa_device *vdev)
225{
Parav Panditfd70a402021-01-05 12:31:59 +0200226 mutex_lock(&vdpa_dev_mutex);
Jason Wang961e9c82020-03-26 22:01:21 +0800227 device_unregister(&vdev->dev);
Parav Panditfd70a402021-01-05 12:31:59 +0200228 mutex_unlock(&vdpa_dev_mutex);
Jason Wang961e9c82020-03-26 22:01:21 +0800229}
230EXPORT_SYMBOL_GPL(vdpa_unregister_device);
231
232/**
233 * __vdpa_register_driver - register a vDPA device driver
234 * @drv: the vdpa device driver to be registered
235 * @owner: module owner of the driver
236 *
Parav Panditc0a54b42021-04-06 20:04:45 +0300237 * Return: Returns an err when fail to do the registration
Jason Wang961e9c82020-03-26 22:01:21 +0800238 */
239int __vdpa_register_driver(struct vdpa_driver *drv, struct module *owner)
240{
241 drv->driver.bus = &vdpa_bus;
242 drv->driver.owner = owner;
243
244 return driver_register(&drv->driver);
245}
246EXPORT_SYMBOL_GPL(__vdpa_register_driver);
247
248/**
249 * vdpa_unregister_driver - unregister a vDPA device driver
250 * @drv: the vdpa device driver to be unregistered
251 */
252void vdpa_unregister_driver(struct vdpa_driver *drv)
253{
254 driver_unregister(&drv->driver);
255}
256EXPORT_SYMBOL_GPL(vdpa_unregister_driver);
257
Parav Pandit33b34752021-01-05 12:32:00 +0200258/**
259 * vdpa_mgmtdev_register - register a vdpa management device
260 *
261 * @mdev: Pointer to vdpa management device
262 * vdpa_mgmtdev_register() register a vdpa management device which supports
263 * vdpa device management.
Parav Panditc0a54b42021-04-06 20:04:45 +0300264 * Return: Returns 0 on success or failure when required callback ops are not
265 * initialized.
Parav Pandit33b34752021-01-05 12:32:00 +0200266 */
267int vdpa_mgmtdev_register(struct vdpa_mgmt_dev *mdev)
268{
269 if (!mdev->device || !mdev->ops || !mdev->ops->dev_add || !mdev->ops->dev_del)
270 return -EINVAL;
271
272 INIT_LIST_HEAD(&mdev->list);
273 mutex_lock(&vdpa_dev_mutex);
274 list_add_tail(&mdev->list, &mdev_head);
275 mutex_unlock(&vdpa_dev_mutex);
276 return 0;
277}
278EXPORT_SYMBOL_GPL(vdpa_mgmtdev_register);
279
Parav Pandit903f7bc2021-01-05 12:32:01 +0200280static int vdpa_match_remove(struct device *dev, void *data)
281{
282 struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
283 struct vdpa_mgmt_dev *mdev = vdev->mdev;
284
285 if (mdev == data)
286 mdev->ops->dev_del(mdev, vdev);
287 return 0;
288}
289
Parav Pandit33b34752021-01-05 12:32:00 +0200290void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev)
291{
292 mutex_lock(&vdpa_dev_mutex);
Parav Pandit903f7bc2021-01-05 12:32:01 +0200293
Parav Pandit33b34752021-01-05 12:32:00 +0200294 list_del(&mdev->list);
Parav Pandit903f7bc2021-01-05 12:32:01 +0200295
296 /* Filter out all the entries belong to this management device and delete it. */
297 bus_for_each_dev(&vdpa_bus, NULL, mdev, vdpa_match_remove);
298
Parav Pandit33b34752021-01-05 12:32:00 +0200299 mutex_unlock(&vdpa_dev_mutex);
300}
301EXPORT_SYMBOL_GPL(vdpa_mgmtdev_unregister);
302
Parav Pandit6dbb1f12021-10-26 20:55:12 +0300303/**
304 * vdpa_get_config - Get one or more device configuration fields.
305 * @vdev: vdpa device to operate on
306 * @offset: starting byte offset of the field
307 * @buf: buffer pointer to read to
308 * @len: length of the configuration fields in bytes
309 */
310void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset,
311 void *buf, unsigned int len)
312{
313 const struct vdpa_config_ops *ops = vdev->config;
314
Parav Panditad69dd02021-10-26 20:55:13 +0300315 mutex_lock(&vdev->cf_mutex);
Parav Pandit6dbb1f12021-10-26 20:55:12 +0300316 /*
317 * Config accesses aren't supposed to trigger before features are set.
318 * If it does happen we assume a legacy guest.
319 */
320 if (!vdev->features_valid)
321 vdpa_set_features(vdev, 0);
322 ops->get_config(vdev, offset, buf, len);
Parav Panditad69dd02021-10-26 20:55:13 +0300323 mutex_unlock(&vdev->cf_mutex);
Parav Pandit6dbb1f12021-10-26 20:55:12 +0300324}
325EXPORT_SYMBOL_GPL(vdpa_get_config);
326
327/**
328 * vdpa_set_config - Set one or more device configuration fields.
329 * @vdev: vdpa device to operate on
330 * @offset: starting byte offset of the field
331 * @buf: buffer pointer to read from
332 * @length: length of the configuration fields in bytes
333 */
334void vdpa_set_config(struct vdpa_device *vdev, unsigned int offset,
335 const void *buf, unsigned int length)
336{
Parav Panditad69dd02021-10-26 20:55:13 +0300337 mutex_lock(&vdev->cf_mutex);
Parav Pandit6dbb1f12021-10-26 20:55:12 +0300338 vdev->config->set_config(vdev, offset, buf, length);
Parav Panditad69dd02021-10-26 20:55:13 +0300339 mutex_unlock(&vdev->cf_mutex);
Parav Pandit6dbb1f12021-10-26 20:55:12 +0300340}
341EXPORT_SYMBOL_GPL(vdpa_set_config);
342
Parav Pandit33b34752021-01-05 12:32:00 +0200343static bool mgmtdev_handle_match(const struct vdpa_mgmt_dev *mdev,
344 const char *busname, const char *devname)
345{
346 /* Bus name is optional for simulated management device, so ignore the
347 * device with bus if bus attribute is provided.
348 */
349 if ((busname && !mdev->device->bus) || (!busname && mdev->device->bus))
350 return false;
351
352 if (!busname && strcmp(dev_name(mdev->device), devname) == 0)
353 return true;
354
355 if (busname && (strcmp(mdev->device->bus->name, busname) == 0) &&
356 (strcmp(dev_name(mdev->device), devname) == 0))
357 return true;
358
359 return false;
360}
361
362static struct vdpa_mgmt_dev *vdpa_mgmtdev_get_from_attr(struct nlattr **attrs)
363{
364 struct vdpa_mgmt_dev *mdev;
365 const char *busname = NULL;
366 const char *devname;
367
368 if (!attrs[VDPA_ATTR_MGMTDEV_DEV_NAME])
369 return ERR_PTR(-EINVAL);
370 devname = nla_data(attrs[VDPA_ATTR_MGMTDEV_DEV_NAME]);
371 if (attrs[VDPA_ATTR_MGMTDEV_BUS_NAME])
372 busname = nla_data(attrs[VDPA_ATTR_MGMTDEV_BUS_NAME]);
373
374 list_for_each_entry(mdev, &mdev_head, list) {
375 if (mgmtdev_handle_match(mdev, busname, devname))
376 return mdev;
377 }
378 return ERR_PTR(-ENODEV);
379}
380
381static int vdpa_nl_mgmtdev_handle_fill(struct sk_buff *msg, const struct vdpa_mgmt_dev *mdev)
382{
383 if (mdev->device->bus &&
384 nla_put_string(msg, VDPA_ATTR_MGMTDEV_BUS_NAME, mdev->device->bus->name))
385 return -EMSGSIZE;
386 if (nla_put_string(msg, VDPA_ATTR_MGMTDEV_DEV_NAME, dev_name(mdev->device)))
387 return -EMSGSIZE;
388 return 0;
389}
390
391static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *msg,
392 u32 portid, u32 seq, int flags)
393{
394 u64 supported_classes = 0;
395 void *hdr;
396 int i = 0;
397 int err;
398
399 hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_MGMTDEV_NEW);
400 if (!hdr)
401 return -EMSGSIZE;
402 err = vdpa_nl_mgmtdev_handle_fill(msg, mdev);
403 if (err)
404 goto msg_err;
405
406 while (mdev->id_table[i].device) {
Parav Panditbb476202021-11-30 06:29:49 +0200407 if (mdev->id_table[i].device <= 63)
408 supported_classes |= BIT_ULL(mdev->id_table[i].device);
Parav Pandit33b34752021-01-05 12:32:00 +0200409 i++;
410 }
411
412 if (nla_put_u64_64bit(msg, VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES,
413 supported_classes, VDPA_ATTR_UNSPEC)) {
414 err = -EMSGSIZE;
415 goto msg_err;
416 }
417
418 genlmsg_end(msg, hdr);
419 return 0;
420
421msg_err:
422 genlmsg_cancel(msg, hdr);
423 return err;
424}
425
426static int vdpa_nl_cmd_mgmtdev_get_doit(struct sk_buff *skb, struct genl_info *info)
427{
428 struct vdpa_mgmt_dev *mdev;
429 struct sk_buff *msg;
430 int err;
431
432 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
433 if (!msg)
434 return -ENOMEM;
435
436 mutex_lock(&vdpa_dev_mutex);
437 mdev = vdpa_mgmtdev_get_from_attr(info->attrs);
438 if (IS_ERR(mdev)) {
439 mutex_unlock(&vdpa_dev_mutex);
440 NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified mgmt device");
441 err = PTR_ERR(mdev);
442 goto out;
443 }
444
445 err = vdpa_mgmtdev_fill(mdev, msg, info->snd_portid, info->snd_seq, 0);
446 mutex_unlock(&vdpa_dev_mutex);
447 if (err)
448 goto out;
449 err = genlmsg_reply(msg, info);
450 return err;
451
452out:
453 nlmsg_free(msg);
454 return err;
455}
456
457static int
458vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
459{
460 struct vdpa_mgmt_dev *mdev;
461 int start = cb->args[0];
462 int idx = 0;
463 int err;
464
465 mutex_lock(&vdpa_dev_mutex);
466 list_for_each_entry(mdev, &mdev_head, list) {
467 if (idx < start) {
468 idx++;
469 continue;
470 }
471 err = vdpa_mgmtdev_fill(mdev, msg, NETLINK_CB(cb->skb).portid,
472 cb->nlh->nlmsg_seq, NLM_F_MULTI);
473 if (err)
474 goto out;
475 idx++;
476 }
477out:
478 mutex_unlock(&vdpa_dev_mutex);
479 cb->args[0] = idx;
480 return msg->len;
481}
482
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300483#define VDPA_DEV_NET_ATTRS_MASK ((1 << VDPA_ATTR_DEV_NET_CFG_MACADDR) | \
484 (1 << VDPA_ATTR_DEV_NET_CFG_MTU))
485
Parav Pandit903f7bc2021-01-05 12:32:01 +0200486static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info)
487{
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300488 struct vdpa_dev_set_config config = {};
489 struct nlattr **nl_attrs = info->attrs;
Parav Pandit903f7bc2021-01-05 12:32:01 +0200490 struct vdpa_mgmt_dev *mdev;
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300491 const u8 *macaddr;
Parav Pandit903f7bc2021-01-05 12:32:01 +0200492 const char *name;
493 int err = 0;
494
495 if (!info->attrs[VDPA_ATTR_DEV_NAME])
496 return -EINVAL;
497
498 name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
499
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300500 if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
501 macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
502 memcpy(config.net.mac, macaddr, sizeof(config.net.mac));
503 config.mask |= (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR);
504 }
505 if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU]) {
506 config.net.mtu =
507 nla_get_u16(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU]);
508 config.mask |= (1 << VDPA_ATTR_DEV_NET_CFG_MTU);
509 }
510
511 /* Skip checking capability if user didn't prefer to configure any
512 * device networking attributes. It is likely that user might have used
513 * a device specific method to configure such attributes or using device
514 * default attributes.
515 */
516 if ((config.mask & VDPA_DEV_NET_ATTRS_MASK) &&
517 !netlink_capable(skb, CAP_NET_ADMIN))
518 return -EPERM;
519
Parav Pandit903f7bc2021-01-05 12:32:01 +0200520 mutex_lock(&vdpa_dev_mutex);
521 mdev = vdpa_mgmtdev_get_from_attr(info->attrs);
522 if (IS_ERR(mdev)) {
523 NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified management device");
524 err = PTR_ERR(mdev);
525 goto err;
526 }
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300527 if ((config.mask & mdev->config_attr_mask) != config.mask) {
528 NL_SET_ERR_MSG_MOD(info->extack,
529 "All provided attributes are not supported");
530 err = -EOPNOTSUPP;
531 goto err;
532 }
Parav Pandit903f7bc2021-01-05 12:32:01 +0200533
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300534 err = mdev->ops->dev_add(mdev, name, &config);
Parav Pandit903f7bc2021-01-05 12:32:01 +0200535err:
536 mutex_unlock(&vdpa_dev_mutex);
537 return err;
538}
539
540static int vdpa_nl_cmd_dev_del_set_doit(struct sk_buff *skb, struct genl_info *info)
541{
542 struct vdpa_mgmt_dev *mdev;
543 struct vdpa_device *vdev;
544 struct device *dev;
545 const char *name;
546 int err = 0;
547
548 if (!info->attrs[VDPA_ATTR_DEV_NAME])
549 return -EINVAL;
550 name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
551
552 mutex_lock(&vdpa_dev_mutex);
553 dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match);
554 if (!dev) {
555 NL_SET_ERR_MSG_MOD(info->extack, "device not found");
556 err = -ENODEV;
557 goto dev_err;
558 }
559 vdev = container_of(dev, struct vdpa_device, dev);
560 if (!vdev->mdev) {
561 NL_SET_ERR_MSG_MOD(info->extack, "Only user created device can be deleted by user");
562 err = -EINVAL;
563 goto mdev_err;
564 }
565 mdev = vdev->mdev;
566 mdev->ops->dev_del(mdev, vdev);
567mdev_err:
568 put_device(dev);
569dev_err:
570 mutex_unlock(&vdpa_dev_mutex);
571 return err;
572}
573
Parav Panditbc0d90e2021-01-05 12:32:02 +0200574static int
575vdpa_dev_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq,
576 int flags, struct netlink_ext_ack *extack)
577{
578 u16 max_vq_size;
Wu Zongyonge47be842021-10-29 17:14:48 +0800579 u16 min_vq_size = 1;
Parav Panditbc0d90e2021-01-05 12:32:02 +0200580 u32 device_id;
581 u32 vendor_id;
582 void *hdr;
583 int err;
584
585 hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_DEV_NEW);
586 if (!hdr)
587 return -EMSGSIZE;
588
589 err = vdpa_nl_mgmtdev_handle_fill(msg, vdev->mdev);
590 if (err)
591 goto msg_err;
592
593 device_id = vdev->config->get_device_id(vdev);
594 vendor_id = vdev->config->get_vendor_id(vdev);
595 max_vq_size = vdev->config->get_vq_num_max(vdev);
Wu Zongyonge47be842021-10-29 17:14:48 +0800596 if (vdev->config->get_vq_num_min)
597 min_vq_size = vdev->config->get_vq_num_min(vdev);
Parav Panditbc0d90e2021-01-05 12:32:02 +0200598
599 err = -EMSGSIZE;
600 if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev)))
601 goto msg_err;
602 if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id))
603 goto msg_err;
604 if (nla_put_u32(msg, VDPA_ATTR_DEV_VENDOR_ID, vendor_id))
605 goto msg_err;
606 if (nla_put_u32(msg, VDPA_ATTR_DEV_MAX_VQS, vdev->nvqs))
607 goto msg_err;
608 if (nla_put_u16(msg, VDPA_ATTR_DEV_MAX_VQ_SIZE, max_vq_size))
609 goto msg_err;
Wu Zongyonge47be842021-10-29 17:14:48 +0800610 if (nla_put_u16(msg, VDPA_ATTR_DEV_MIN_VQ_SIZE, min_vq_size))
611 goto msg_err;
Parav Panditbc0d90e2021-01-05 12:32:02 +0200612
613 genlmsg_end(msg, hdr);
614 return 0;
615
616msg_err:
617 genlmsg_cancel(msg, hdr);
618 return err;
619}
620
621static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
622{
623 struct vdpa_device *vdev;
624 struct sk_buff *msg;
625 const char *devname;
626 struct device *dev;
627 int err;
628
629 if (!info->attrs[VDPA_ATTR_DEV_NAME])
630 return -EINVAL;
631 devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
632 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
633 if (!msg)
634 return -ENOMEM;
635
636 mutex_lock(&vdpa_dev_mutex);
637 dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match);
638 if (!dev) {
639 NL_SET_ERR_MSG_MOD(info->extack, "device not found");
640 err = -ENODEV;
641 goto err;
642 }
643 vdev = container_of(dev, struct vdpa_device, dev);
644 if (!vdev->mdev) {
645 err = -EINVAL;
646 goto mdev_err;
647 }
648 err = vdpa_dev_fill(vdev, msg, info->snd_portid, info->snd_seq, 0, info->extack);
649 if (!err)
650 err = genlmsg_reply(msg, info);
651mdev_err:
652 put_device(dev);
653err:
654 mutex_unlock(&vdpa_dev_mutex);
655 if (err)
656 nlmsg_free(msg);
657 return err;
658}
659
660struct vdpa_dev_dump_info {
661 struct sk_buff *msg;
662 struct netlink_callback *cb;
663 int start_idx;
664 int idx;
665};
666
667static int vdpa_dev_dump(struct device *dev, void *data)
668{
669 struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
670 struct vdpa_dev_dump_info *info = data;
671 int err;
672
673 if (!vdev->mdev)
674 return 0;
675 if (info->idx < info->start_idx) {
676 info->idx++;
677 return 0;
678 }
679 err = vdpa_dev_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid,
680 info->cb->nlh->nlmsg_seq, NLM_F_MULTI, info->cb->extack);
681 if (err)
682 return err;
683
684 info->idx++;
685 return 0;
686}
687
688static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
689{
690 struct vdpa_dev_dump_info info;
691
692 info.msg = msg;
693 info.cb = cb;
694 info.start_idx = cb->args[0];
695 info.idx = 0;
696
697 mutex_lock(&vdpa_dev_mutex);
698 bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_dump);
699 mutex_unlock(&vdpa_dev_mutex);
700 cb->args[0] = info.idx;
701 return msg->len;
702}
703
Parav Panditad69dd02021-10-26 20:55:13 +0300704static int vdpa_dev_net_mq_config_fill(struct vdpa_device *vdev,
705 struct sk_buff *msg, u64 features,
706 const struct virtio_net_config *config)
707{
708 u16 val_u16;
709
710 if ((features & (1ULL << VIRTIO_NET_F_MQ)) == 0)
711 return 0;
712
713 val_u16 = le16_to_cpu(config->max_virtqueue_pairs);
714 return nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MAX_VQP, val_u16);
715}
716
717static int vdpa_dev_net_config_fill(struct vdpa_device *vdev, struct sk_buff *msg)
718{
719 struct virtio_net_config config = {};
720 u64 features;
721 u16 val_u16;
722
723 vdpa_get_config(vdev, 0, &config, sizeof(config));
724
725 if (nla_put(msg, VDPA_ATTR_DEV_NET_CFG_MACADDR, sizeof(config.mac),
726 config.mac))
727 return -EMSGSIZE;
728
729 val_u16 = le16_to_cpu(config.status);
730 if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_STATUS, val_u16))
731 return -EMSGSIZE;
732
733 val_u16 = le16_to_cpu(config.mtu);
734 if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MTU, val_u16))
735 return -EMSGSIZE;
736
737 features = vdev->config->get_features(vdev);
738
739 return vdpa_dev_net_mq_config_fill(vdev, msg, features, &config);
740}
741
742static int
743vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq,
744 int flags, struct netlink_ext_ack *extack)
745{
746 u32 device_id;
747 void *hdr;
748 int err;
749
750 hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags,
751 VDPA_CMD_DEV_CONFIG_GET);
752 if (!hdr)
753 return -EMSGSIZE;
754
755 if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev))) {
756 err = -EMSGSIZE;
757 goto msg_err;
758 }
759
760 device_id = vdev->config->get_device_id(vdev);
761 if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id)) {
762 err = -EMSGSIZE;
763 goto msg_err;
764 }
765
766 switch (device_id) {
767 case VIRTIO_ID_NET:
768 err = vdpa_dev_net_config_fill(vdev, msg);
769 break;
770 default:
771 err = -EOPNOTSUPP;
772 break;
773 }
774 if (err)
775 goto msg_err;
776
777 genlmsg_end(msg, hdr);
778 return 0;
779
780msg_err:
781 genlmsg_cancel(msg, hdr);
782 return err;
783}
784
785static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info *info)
786{
787 struct vdpa_device *vdev;
788 struct sk_buff *msg;
789 const char *devname;
790 struct device *dev;
791 int err;
792
793 if (!info->attrs[VDPA_ATTR_DEV_NAME])
794 return -EINVAL;
795 devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
796 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
797 if (!msg)
798 return -ENOMEM;
799
800 mutex_lock(&vdpa_dev_mutex);
801 dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match);
802 if (!dev) {
803 NL_SET_ERR_MSG_MOD(info->extack, "device not found");
804 err = -ENODEV;
805 goto dev_err;
806 }
807 vdev = container_of(dev, struct vdpa_device, dev);
808 if (!vdev->mdev) {
809 NL_SET_ERR_MSG_MOD(info->extack, "unmanaged vdpa device");
810 err = -EINVAL;
811 goto mdev_err;
812 }
813 err = vdpa_dev_config_fill(vdev, msg, info->snd_portid, info->snd_seq,
814 0, info->extack);
815 if (!err)
816 err = genlmsg_reply(msg, info);
817
818mdev_err:
819 put_device(dev);
820dev_err:
821 mutex_unlock(&vdpa_dev_mutex);
822 if (err)
823 nlmsg_free(msg);
824 return err;
825}
826
827static int vdpa_dev_config_dump(struct device *dev, void *data)
828{
829 struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
830 struct vdpa_dev_dump_info *info = data;
831 int err;
832
833 if (!vdev->mdev)
834 return 0;
835 if (info->idx < info->start_idx) {
836 info->idx++;
837 return 0;
838 }
839 err = vdpa_dev_config_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid,
840 info->cb->nlh->nlmsg_seq, NLM_F_MULTI,
841 info->cb->extack);
842 if (err)
843 return err;
844
845 info->idx++;
846 return 0;
847}
848
849static int
850vdpa_nl_cmd_dev_config_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
851{
852 struct vdpa_dev_dump_info info;
853
854 info.msg = msg;
855 info.cb = cb;
856 info.start_idx = cb->args[0];
857 info.idx = 0;
858
859 mutex_lock(&vdpa_dev_mutex);
860 bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_config_dump);
861 mutex_unlock(&vdpa_dev_mutex);
862 cb->args[0] = info.idx;
863 return msg->len;
864}
865
Parav Pandit33b34752021-01-05 12:32:00 +0200866static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
867 [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
868 [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
Parav Pandit903f7bc2021-01-05 12:32:01 +0200869 [VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING },
Parav Panditd8ca2fa2021-10-26 20:55:15 +0300870 [VDPA_ATTR_DEV_NET_CFG_MACADDR] = NLA_POLICY_ETH_ADDR,
871 /* virtio spec 1.1 section 5.1.4.1 for valid MTU range */
872 [VDPA_ATTR_DEV_NET_CFG_MTU] = NLA_POLICY_MIN(NLA_U16, 68),
Parav Pandit33b34752021-01-05 12:32:00 +0200873};
874
875static const struct genl_ops vdpa_nl_ops[] = {
876 {
877 .cmd = VDPA_CMD_MGMTDEV_GET,
878 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
879 .doit = vdpa_nl_cmd_mgmtdev_get_doit,
880 .dumpit = vdpa_nl_cmd_mgmtdev_get_dumpit,
881 },
Parav Pandit903f7bc2021-01-05 12:32:01 +0200882 {
883 .cmd = VDPA_CMD_DEV_NEW,
884 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
885 .doit = vdpa_nl_cmd_dev_add_set_doit,
886 .flags = GENL_ADMIN_PERM,
887 },
888 {
889 .cmd = VDPA_CMD_DEV_DEL,
890 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
891 .doit = vdpa_nl_cmd_dev_del_set_doit,
892 .flags = GENL_ADMIN_PERM,
893 },
Parav Panditbc0d90e2021-01-05 12:32:02 +0200894 {
895 .cmd = VDPA_CMD_DEV_GET,
896 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
897 .doit = vdpa_nl_cmd_dev_get_doit,
898 .dumpit = vdpa_nl_cmd_dev_get_dumpit,
899 },
Parav Panditad69dd02021-10-26 20:55:13 +0300900 {
901 .cmd = VDPA_CMD_DEV_CONFIG_GET,
902 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
903 .doit = vdpa_nl_cmd_dev_config_get_doit,
904 .dumpit = vdpa_nl_cmd_dev_config_get_dumpit,
905 },
Parav Pandit33b34752021-01-05 12:32:00 +0200906};
907
908static struct genl_family vdpa_nl_family __ro_after_init = {
909 .name = VDPA_GENL_NAME,
910 .version = VDPA_GENL_VERSION,
911 .maxattr = VDPA_ATTR_MAX,
912 .policy = vdpa_nl_policy,
913 .netnsok = false,
914 .module = THIS_MODULE,
915 .ops = vdpa_nl_ops,
916 .n_ops = ARRAY_SIZE(vdpa_nl_ops),
917};
918
Jason Wang961e9c82020-03-26 22:01:21 +0800919static int vdpa_init(void)
920{
Parav Pandit33b34752021-01-05 12:32:00 +0200921 int err;
922
923 err = bus_register(&vdpa_bus);
924 if (err)
925 return err;
926 err = genl_register_family(&vdpa_nl_family);
927 if (err)
928 goto err;
929 return 0;
930
931err:
932 bus_unregister(&vdpa_bus);
933 return err;
Jason Wang961e9c82020-03-26 22:01:21 +0800934}
935
936static void __exit vdpa_exit(void)
937{
Parav Pandit33b34752021-01-05 12:32:00 +0200938 genl_unregister_family(&vdpa_nl_family);
Jason Wang961e9c82020-03-26 22:01:21 +0800939 bus_unregister(&vdpa_bus);
940 ida_destroy(&vdpa_index_ida);
941}
942core_initcall(vdpa_init);
943module_exit(vdpa_exit);
944
945MODULE_AUTHOR("Jason Wang <jasowang@redhat.com>");
946MODULE_LICENSE("GPL v2");