linux/drivers/vdpa/vdpa.c
<<
>>
Prefs
   1// 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>
  14#include <uapi/linux/vdpa.h>
  15#include <net/genetlink.h>
  16#include <linux/mod_devicetable.h>
  17
  18static LIST_HEAD(mdev_head);
  19/* A global mutex that protects vdpa management device and device level operations. */
  20static DEFINE_MUTEX(vdpa_dev_mutex);
  21static DEFINE_IDA(vdpa_index_ida);
  22
  23static struct genl_family vdpa_nl_family;
  24
  25static int vdpa_dev_probe(struct device *d)
  26{
  27        struct vdpa_device *vdev = dev_to_vdpa(d);
  28        struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver);
  29        int ret = 0;
  30
  31        if (drv && drv->probe)
  32                ret = drv->probe(vdev);
  33
  34        return ret;
  35}
  36
  37static int vdpa_dev_remove(struct device *d)
  38{
  39        struct vdpa_device *vdev = dev_to_vdpa(d);
  40        struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver);
  41
  42        if (drv && drv->remove)
  43                drv->remove(vdev);
  44
  45        return 0;
  46}
  47
  48static struct bus_type vdpa_bus = {
  49        .name  = "vdpa",
  50        .probe = vdpa_dev_probe,
  51        .remove = vdpa_dev_remove,
  52};
  53
  54static void vdpa_release_dev(struct device *d)
  55{
  56        struct vdpa_device *vdev = dev_to_vdpa(d);
  57        const struct vdpa_config_ops *ops = vdev->config;
  58
  59        if (ops->free)
  60                ops->free(vdev);
  61
  62        ida_simple_remove(&vdpa_index_ida, vdev->index);
  63        kfree(vdev);
  64}
  65
  66/**
  67 * __vdpa_alloc_device - allocate and initilaize a vDPA device
  68 * This allows driver to some prepartion after device is
  69 * initialized but before registered.
  70 * @parent: the parent device
  71 * @config: the bus operations that is supported by this device
  72 * @size: size of the parent structure that contains private data
  73 * @name: name of the vdpa device; optional.
  74 *
  75 * Driver should use vdpa_alloc_device() wrapper macro instead of
  76 * using this directly.
  77 *
  78 * Return: Returns an error when parent/config/dma_dev is not set or fail to get
  79 *         ida.
  80 */
  81struct vdpa_device *__vdpa_alloc_device(struct device *parent,
  82                                        const struct vdpa_config_ops *config,
  83                                        size_t size, const char *name)
  84{
  85        struct vdpa_device *vdev;
  86        int err = -EINVAL;
  87
  88        if (!config)
  89                goto err;
  90
  91        if (!!config->dma_map != !!config->dma_unmap)
  92                goto err;
  93
  94        err = -ENOMEM;
  95        vdev = kzalloc(size, GFP_KERNEL);
  96        if (!vdev)
  97                goto err;
  98
  99        err = ida_alloc(&vdpa_index_ida, GFP_KERNEL);
 100        if (err < 0)
 101                goto err_ida;
 102
 103        vdev->dev.bus = &vdpa_bus;
 104        vdev->dev.parent = parent;
 105        vdev->dev.release = vdpa_release_dev;
 106        vdev->index = err;
 107        vdev->config = config;
 108        vdev->features_valid = false;
 109
 110        if (name)
 111                err = dev_set_name(&vdev->dev, "%s", name);
 112        else
 113                err = dev_set_name(&vdev->dev, "vdpa%u", vdev->index);
 114        if (err)
 115                goto err_name;
 116
 117        device_initialize(&vdev->dev);
 118
 119        return vdev;
 120
 121err_name:
 122        ida_simple_remove(&vdpa_index_ida, vdev->index);
 123err_ida:
 124        kfree(vdev);
 125err:
 126        return ERR_PTR(err);
 127}
 128EXPORT_SYMBOL_GPL(__vdpa_alloc_device);
 129
 130static int vdpa_name_match(struct device *dev, const void *data)
 131{
 132        struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
 133
 134        return (strcmp(dev_name(&vdev->dev), data) == 0);
 135}
 136
 137static int __vdpa_register_device(struct vdpa_device *vdev, int nvqs)
 138{
 139        struct device *dev;
 140
 141        vdev->nvqs = nvqs;
 142
 143        lockdep_assert_held(&vdpa_dev_mutex);
 144        dev = bus_find_device(&vdpa_bus, NULL, dev_name(&vdev->dev), vdpa_name_match);
 145        if (dev) {
 146                put_device(dev);
 147                return -EEXIST;
 148        }
 149        return device_add(&vdev->dev);
 150}
 151
 152/**
 153 * _vdpa_register_device - register a vDPA device with vdpa lock held
 154 * Caller must have a succeed call of vdpa_alloc_device() before.
 155 * Caller must invoke this routine in the management device dev_add()
 156 * callback after setting up valid mgmtdev for this vdpa device.
 157 * @vdev: the vdpa device to be registered to vDPA bus
 158 * @nvqs: number of virtqueues supported by this device
 159 *
 160 * Return: Returns an error when fail to add device to vDPA bus
 161 */
 162int _vdpa_register_device(struct vdpa_device *vdev, int nvqs)
 163{
 164        if (!vdev->mdev)
 165                return -EINVAL;
 166
 167        return __vdpa_register_device(vdev, nvqs);
 168}
 169EXPORT_SYMBOL_GPL(_vdpa_register_device);
 170
 171/**
 172 * vdpa_register_device - register a vDPA device
 173 * Callers must have a succeed call of vdpa_alloc_device() before.
 174 * @vdev: the vdpa device to be registered to vDPA bus
 175 * @nvqs: number of virtqueues supported by this device
 176 *
 177 * Return: Returns an error when fail to add to vDPA bus
 178 */
 179int vdpa_register_device(struct vdpa_device *vdev, int nvqs)
 180{
 181        int err;
 182
 183        mutex_lock(&vdpa_dev_mutex);
 184        err = __vdpa_register_device(vdev, nvqs);
 185        mutex_unlock(&vdpa_dev_mutex);
 186        return err;
 187}
 188EXPORT_SYMBOL_GPL(vdpa_register_device);
 189
 190/**
 191 * _vdpa_unregister_device - unregister a vDPA device
 192 * Caller must invoke this routine as part of management device dev_del()
 193 * callback.
 194 * @vdev: the vdpa device to be unregisted from vDPA bus
 195 */
 196void _vdpa_unregister_device(struct vdpa_device *vdev)
 197{
 198        lockdep_assert_held(&vdpa_dev_mutex);
 199        WARN_ON(!vdev->mdev);
 200        device_unregister(&vdev->dev);
 201}
 202EXPORT_SYMBOL_GPL(_vdpa_unregister_device);
 203
 204/**
 205 * vdpa_unregister_device - unregister a vDPA device
 206 * @vdev: the vdpa device to be unregisted from vDPA bus
 207 */
 208void vdpa_unregister_device(struct vdpa_device *vdev)
 209{
 210        mutex_lock(&vdpa_dev_mutex);
 211        device_unregister(&vdev->dev);
 212        mutex_unlock(&vdpa_dev_mutex);
 213}
 214EXPORT_SYMBOL_GPL(vdpa_unregister_device);
 215
 216/**
 217 * __vdpa_register_driver - register a vDPA device driver
 218 * @drv: the vdpa device driver to be registered
 219 * @owner: module owner of the driver
 220 *
 221 * Return: Returns an err when fail to do the registration
 222 */
 223int __vdpa_register_driver(struct vdpa_driver *drv, struct module *owner)
 224{
 225        drv->driver.bus = &vdpa_bus;
 226        drv->driver.owner = owner;
 227
 228        return driver_register(&drv->driver);
 229}
 230EXPORT_SYMBOL_GPL(__vdpa_register_driver);
 231
 232/**
 233 * vdpa_unregister_driver - unregister a vDPA device driver
 234 * @drv: the vdpa device driver to be unregistered
 235 */
 236void vdpa_unregister_driver(struct vdpa_driver *drv)
 237{
 238        driver_unregister(&drv->driver);
 239}
 240EXPORT_SYMBOL_GPL(vdpa_unregister_driver);
 241
 242/**
 243 * vdpa_mgmtdev_register - register a vdpa management device
 244 *
 245 * @mdev: Pointer to vdpa management device
 246 * vdpa_mgmtdev_register() register a vdpa management device which supports
 247 * vdpa device management.
 248 * Return: Returns 0 on success or failure when required callback ops are not
 249 *         initialized.
 250 */
 251int vdpa_mgmtdev_register(struct vdpa_mgmt_dev *mdev)
 252{
 253        if (!mdev->device || !mdev->ops || !mdev->ops->dev_add || !mdev->ops->dev_del)
 254                return -EINVAL;
 255
 256        INIT_LIST_HEAD(&mdev->list);
 257        mutex_lock(&vdpa_dev_mutex);
 258        list_add_tail(&mdev->list, &mdev_head);
 259        mutex_unlock(&vdpa_dev_mutex);
 260        return 0;
 261}
 262EXPORT_SYMBOL_GPL(vdpa_mgmtdev_register);
 263
 264static int vdpa_match_remove(struct device *dev, void *data)
 265{
 266        struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
 267        struct vdpa_mgmt_dev *mdev = vdev->mdev;
 268
 269        if (mdev == data)
 270                mdev->ops->dev_del(mdev, vdev);
 271        return 0;
 272}
 273
 274void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev)
 275{
 276        mutex_lock(&vdpa_dev_mutex);
 277
 278        list_del(&mdev->list);
 279
 280        /* Filter out all the entries belong to this management device and delete it. */
 281        bus_for_each_dev(&vdpa_bus, NULL, mdev, vdpa_match_remove);
 282
 283        mutex_unlock(&vdpa_dev_mutex);
 284}
 285EXPORT_SYMBOL_GPL(vdpa_mgmtdev_unregister);
 286
 287static bool mgmtdev_handle_match(const struct vdpa_mgmt_dev *mdev,
 288                                 const char *busname, const char *devname)
 289{
 290        /* Bus name is optional for simulated management device, so ignore the
 291         * device with bus if bus attribute is provided.
 292         */
 293        if ((busname && !mdev->device->bus) || (!busname && mdev->device->bus))
 294                return false;
 295
 296        if (!busname && strcmp(dev_name(mdev->device), devname) == 0)
 297                return true;
 298
 299        if (busname && (strcmp(mdev->device->bus->name, busname) == 0) &&
 300            (strcmp(dev_name(mdev->device), devname) == 0))
 301                return true;
 302
 303        return false;
 304}
 305
 306static struct vdpa_mgmt_dev *vdpa_mgmtdev_get_from_attr(struct nlattr **attrs)
 307{
 308        struct vdpa_mgmt_dev *mdev;
 309        const char *busname = NULL;
 310        const char *devname;
 311
 312        if (!attrs[VDPA_ATTR_MGMTDEV_DEV_NAME])
 313                return ERR_PTR(-EINVAL);
 314        devname = nla_data(attrs[VDPA_ATTR_MGMTDEV_DEV_NAME]);
 315        if (attrs[VDPA_ATTR_MGMTDEV_BUS_NAME])
 316                busname = nla_data(attrs[VDPA_ATTR_MGMTDEV_BUS_NAME]);
 317
 318        list_for_each_entry(mdev, &mdev_head, list) {
 319                if (mgmtdev_handle_match(mdev, busname, devname))
 320                        return mdev;
 321        }
 322        return ERR_PTR(-ENODEV);
 323}
 324
 325static int vdpa_nl_mgmtdev_handle_fill(struct sk_buff *msg, const struct vdpa_mgmt_dev *mdev)
 326{
 327        if (mdev->device->bus &&
 328            nla_put_string(msg, VDPA_ATTR_MGMTDEV_BUS_NAME, mdev->device->bus->name))
 329                return -EMSGSIZE;
 330        if (nla_put_string(msg, VDPA_ATTR_MGMTDEV_DEV_NAME, dev_name(mdev->device)))
 331                return -EMSGSIZE;
 332        return 0;
 333}
 334
 335static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *msg,
 336                             u32 portid, u32 seq, int flags)
 337{
 338        u64 supported_classes = 0;
 339        void *hdr;
 340        int i = 0;
 341        int err;
 342
 343        hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_MGMTDEV_NEW);
 344        if (!hdr)
 345                return -EMSGSIZE;
 346        err = vdpa_nl_mgmtdev_handle_fill(msg, mdev);
 347        if (err)
 348                goto msg_err;
 349
 350        while (mdev->id_table[i].device) {
 351                supported_classes |= BIT(mdev->id_table[i].device);
 352                i++;
 353        }
 354
 355        if (nla_put_u64_64bit(msg, VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES,
 356                              supported_classes, VDPA_ATTR_UNSPEC)) {
 357                err = -EMSGSIZE;
 358                goto msg_err;
 359        }
 360
 361        genlmsg_end(msg, hdr);
 362        return 0;
 363
 364msg_err:
 365        genlmsg_cancel(msg, hdr);
 366        return err;
 367}
 368
 369static int vdpa_nl_cmd_mgmtdev_get_doit(struct sk_buff *skb, struct genl_info *info)
 370{
 371        struct vdpa_mgmt_dev *mdev;
 372        struct sk_buff *msg;
 373        int err;
 374
 375        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 376        if (!msg)
 377                return -ENOMEM;
 378
 379        mutex_lock(&vdpa_dev_mutex);
 380        mdev = vdpa_mgmtdev_get_from_attr(info->attrs);
 381        if (IS_ERR(mdev)) {
 382                mutex_unlock(&vdpa_dev_mutex);
 383                NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified mgmt device");
 384                err = PTR_ERR(mdev);
 385                goto out;
 386        }
 387
 388        err = vdpa_mgmtdev_fill(mdev, msg, info->snd_portid, info->snd_seq, 0);
 389        mutex_unlock(&vdpa_dev_mutex);
 390        if (err)
 391                goto out;
 392        err = genlmsg_reply(msg, info);
 393        return err;
 394
 395out:
 396        nlmsg_free(msg);
 397        return err;
 398}
 399
 400static int
 401vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
 402{
 403        struct vdpa_mgmt_dev *mdev;
 404        int start = cb->args[0];
 405        int idx = 0;
 406        int err;
 407
 408        mutex_lock(&vdpa_dev_mutex);
 409        list_for_each_entry(mdev, &mdev_head, list) {
 410                if (idx < start) {
 411                        idx++;
 412                        continue;
 413                }
 414                err = vdpa_mgmtdev_fill(mdev, msg, NETLINK_CB(cb->skb).portid,
 415                                        cb->nlh->nlmsg_seq, NLM_F_MULTI);
 416                if (err)
 417                        goto out;
 418                idx++;
 419        }
 420out:
 421        mutex_unlock(&vdpa_dev_mutex);
 422        cb->args[0] = idx;
 423        return msg->len;
 424}
 425
 426static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info)
 427{
 428        struct vdpa_mgmt_dev *mdev;
 429        const char *name;
 430        int err = 0;
 431
 432        if (!info->attrs[VDPA_ATTR_DEV_NAME])
 433                return -EINVAL;
 434
 435        name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
 436
 437        mutex_lock(&vdpa_dev_mutex);
 438        mdev = vdpa_mgmtdev_get_from_attr(info->attrs);
 439        if (IS_ERR(mdev)) {
 440                NL_SET_ERR_MSG_MOD(info->extack, "Fail to find the specified management device");
 441                err = PTR_ERR(mdev);
 442                goto err;
 443        }
 444
 445        err = mdev->ops->dev_add(mdev, name);
 446err:
 447        mutex_unlock(&vdpa_dev_mutex);
 448        return err;
 449}
 450
 451static int vdpa_nl_cmd_dev_del_set_doit(struct sk_buff *skb, struct genl_info *info)
 452{
 453        struct vdpa_mgmt_dev *mdev;
 454        struct vdpa_device *vdev;
 455        struct device *dev;
 456        const char *name;
 457        int err = 0;
 458
 459        if (!info->attrs[VDPA_ATTR_DEV_NAME])
 460                return -EINVAL;
 461        name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
 462
 463        mutex_lock(&vdpa_dev_mutex);
 464        dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match);
 465        if (!dev) {
 466                NL_SET_ERR_MSG_MOD(info->extack, "device not found");
 467                err = -ENODEV;
 468                goto dev_err;
 469        }
 470        vdev = container_of(dev, struct vdpa_device, dev);
 471        if (!vdev->mdev) {
 472                NL_SET_ERR_MSG_MOD(info->extack, "Only user created device can be deleted by user");
 473                err = -EINVAL;
 474                goto mdev_err;
 475        }
 476        mdev = vdev->mdev;
 477        mdev->ops->dev_del(mdev, vdev);
 478mdev_err:
 479        put_device(dev);
 480dev_err:
 481        mutex_unlock(&vdpa_dev_mutex);
 482        return err;
 483}
 484
 485static int
 486vdpa_dev_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq,
 487              int flags, struct netlink_ext_ack *extack)
 488{
 489        u16 max_vq_size;
 490        u32 device_id;
 491        u32 vendor_id;
 492        void *hdr;
 493        int err;
 494
 495        hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_DEV_NEW);
 496        if (!hdr)
 497                return -EMSGSIZE;
 498
 499        err = vdpa_nl_mgmtdev_handle_fill(msg, vdev->mdev);
 500        if (err)
 501                goto msg_err;
 502
 503        device_id = vdev->config->get_device_id(vdev);
 504        vendor_id = vdev->config->get_vendor_id(vdev);
 505        max_vq_size = vdev->config->get_vq_num_max(vdev);
 506
 507        err = -EMSGSIZE;
 508        if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev)))
 509                goto msg_err;
 510        if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id))
 511                goto msg_err;
 512        if (nla_put_u32(msg, VDPA_ATTR_DEV_VENDOR_ID, vendor_id))
 513                goto msg_err;
 514        if (nla_put_u32(msg, VDPA_ATTR_DEV_MAX_VQS, vdev->nvqs))
 515                goto msg_err;
 516        if (nla_put_u16(msg, VDPA_ATTR_DEV_MAX_VQ_SIZE, max_vq_size))
 517                goto msg_err;
 518
 519        genlmsg_end(msg, hdr);
 520        return 0;
 521
 522msg_err:
 523        genlmsg_cancel(msg, hdr);
 524        return err;
 525}
 526
 527static int vdpa_nl_cmd_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
 528{
 529        struct vdpa_device *vdev;
 530        struct sk_buff *msg;
 531        const char *devname;
 532        struct device *dev;
 533        int err;
 534
 535        if (!info->attrs[VDPA_ATTR_DEV_NAME])
 536                return -EINVAL;
 537        devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
 538        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 539        if (!msg)
 540                return -ENOMEM;
 541
 542        mutex_lock(&vdpa_dev_mutex);
 543        dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match);
 544        if (!dev) {
 545                NL_SET_ERR_MSG_MOD(info->extack, "device not found");
 546                err = -ENODEV;
 547                goto err;
 548        }
 549        vdev = container_of(dev, struct vdpa_device, dev);
 550        if (!vdev->mdev) {
 551                err = -EINVAL;
 552                goto mdev_err;
 553        }
 554        err = vdpa_dev_fill(vdev, msg, info->snd_portid, info->snd_seq, 0, info->extack);
 555        if (!err)
 556                err = genlmsg_reply(msg, info);
 557mdev_err:
 558        put_device(dev);
 559err:
 560        mutex_unlock(&vdpa_dev_mutex);
 561        if (err)
 562                nlmsg_free(msg);
 563        return err;
 564}
 565
 566struct vdpa_dev_dump_info {
 567        struct sk_buff *msg;
 568        struct netlink_callback *cb;
 569        int start_idx;
 570        int idx;
 571};
 572
 573static int vdpa_dev_dump(struct device *dev, void *data)
 574{
 575        struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
 576        struct vdpa_dev_dump_info *info = data;
 577        int err;
 578
 579        if (!vdev->mdev)
 580                return 0;
 581        if (info->idx < info->start_idx) {
 582                info->idx++;
 583                return 0;
 584        }
 585        err = vdpa_dev_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid,
 586                            info->cb->nlh->nlmsg_seq, NLM_F_MULTI, info->cb->extack);
 587        if (err)
 588                return err;
 589
 590        info->idx++;
 591        return 0;
 592}
 593
 594static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
 595{
 596        struct vdpa_dev_dump_info info;
 597
 598        info.msg = msg;
 599        info.cb = cb;
 600        info.start_idx = cb->args[0];
 601        info.idx = 0;
 602
 603        mutex_lock(&vdpa_dev_mutex);
 604        bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_dump);
 605        mutex_unlock(&vdpa_dev_mutex);
 606        cb->args[0] = info.idx;
 607        return msg->len;
 608}
 609
 610static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
 611        [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
 612        [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
 613        [VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING },
 614};
 615
 616static const struct genl_ops vdpa_nl_ops[] = {
 617        {
 618                .cmd = VDPA_CMD_MGMTDEV_GET,
 619                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 620                .doit = vdpa_nl_cmd_mgmtdev_get_doit,
 621                .dumpit = vdpa_nl_cmd_mgmtdev_get_dumpit,
 622        },
 623        {
 624                .cmd = VDPA_CMD_DEV_NEW,
 625                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 626                .doit = vdpa_nl_cmd_dev_add_set_doit,
 627                .flags = GENL_ADMIN_PERM,
 628        },
 629        {
 630                .cmd = VDPA_CMD_DEV_DEL,
 631                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 632                .doit = vdpa_nl_cmd_dev_del_set_doit,
 633                .flags = GENL_ADMIN_PERM,
 634        },
 635        {
 636                .cmd = VDPA_CMD_DEV_GET,
 637                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 638                .doit = vdpa_nl_cmd_dev_get_doit,
 639                .dumpit = vdpa_nl_cmd_dev_get_dumpit,
 640        },
 641};
 642
 643static struct genl_family vdpa_nl_family __ro_after_init = {
 644        .name = VDPA_GENL_NAME,
 645        .version = VDPA_GENL_VERSION,
 646        .maxattr = VDPA_ATTR_MAX,
 647        .policy = vdpa_nl_policy,
 648        .netnsok = false,
 649        .module = THIS_MODULE,
 650        .ops = vdpa_nl_ops,
 651        .n_ops = ARRAY_SIZE(vdpa_nl_ops),
 652};
 653
 654static int vdpa_init(void)
 655{
 656        int err;
 657
 658        err = bus_register(&vdpa_bus);
 659        if (err)
 660                return err;
 661        err = genl_register_family(&vdpa_nl_family);
 662        if (err)
 663                goto err;
 664        return 0;
 665
 666err:
 667        bus_unregister(&vdpa_bus);
 668        return err;
 669}
 670
 671static void __exit vdpa_exit(void)
 672{
 673        genl_unregister_family(&vdpa_nl_family);
 674        bus_unregister(&vdpa_bus);
 675        ida_destroy(&vdpa_index_ida);
 676}
 677core_initcall(vdpa_init);
 678module_exit(vdpa_exit);
 679
 680MODULE_AUTHOR("Jason Wang <jasowang@redhat.com>");
 681MODULE_LICENSE("GPL v2");
 682