Commit d8ca2fa5 authored by Parav Pandit's avatar Parav Pandit Committed by Michael S. Tsirkin

vdpa: Enable user to set mac and mtu of vdpa device

$ vdpa dev add name bar mgmtdev vdpasim_net mac 00:11:22:33:44:55 mtu 9000

$ vdpa dev config show
bar: mac 00:11:22:33:44:55 link up link_announce false mtu 9000

$ vdpa dev config show -jp
{
    "config": {
        "bar": {
            "mac": "00:11:22:33:44:55",
            "link ": "up",
            "link_announce ": false,
            "mtu": 9000,
        }
    }
}
Signed-off-by: default avatarParav Pandit <parav@nvidia.com>
Reviewed-by: default avatarEli Cohen <elic@nvidia.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>

Link: https://lore.kernel.org/r/20211026175519.87795-5-parav@nvidia.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarStefano Garzarella <sgarzare@redhat.com>
parent 960deb33
...@@ -499,7 +499,8 @@ static u32 get_dev_type(struct pci_dev *pdev) ...@@ -499,7 +499,8 @@ static u32 get_dev_type(struct pci_dev *pdev)
return dev_type; return dev_type;
} }
static int ifcvf_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name) static int ifcvf_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
const struct vdpa_dev_set_config *config)
{ {
struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev; struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev;
struct ifcvf_adapter *adapter; struct ifcvf_adapter *adapter;
......
...@@ -2482,7 +2482,8 @@ static int event_handler(struct notifier_block *nb, unsigned long event, void *p ...@@ -2482,7 +2482,8 @@ static int event_handler(struct notifier_block *nb, unsigned long event, void *p
return ret; return ret;
} }
static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name) static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
const struct vdpa_dev_set_config *add_config)
{ {
struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct mlx5_vdpa_mgmtdev, mgtdev); struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct mlx5_vdpa_mgmtdev, mgtdev);
struct virtio_net_config *config; struct virtio_net_config *config;
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <uapi/linux/vdpa.h> #include <uapi/linux/vdpa.h>
#include <net/genetlink.h> #include <net/genetlink.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/virtio_net.h>
#include <linux/virtio_ids.h> #include <linux/virtio_ids.h>
static LIST_HEAD(mdev_head); static LIST_HEAD(mdev_head);
...@@ -480,9 +479,15 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) ...@@ -480,9 +479,15 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
return msg->len; return msg->len;
} }
#define VDPA_DEV_NET_ATTRS_MASK ((1 << VDPA_ATTR_DEV_NET_CFG_MACADDR) | \
(1 << VDPA_ATTR_DEV_NET_CFG_MTU))
static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info) static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info)
{ {
struct vdpa_dev_set_config config = {};
struct nlattr **nl_attrs = info->attrs;
struct vdpa_mgmt_dev *mdev; struct vdpa_mgmt_dev *mdev;
const u8 *macaddr;
const char *name; const char *name;
int err = 0; int err = 0;
...@@ -491,6 +496,26 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i ...@@ -491,6 +496,26 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i
name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
memcpy(config.net.mac, macaddr, sizeof(config.net.mac));
config.mask |= (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR);
}
if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU]) {
config.net.mtu =
nla_get_u16(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU]);
config.mask |= (1 << VDPA_ATTR_DEV_NET_CFG_MTU);
}
/* Skip checking capability if user didn't prefer to configure any
* device networking attributes. It is likely that user might have used
* a device specific method to configure such attributes or using device
* default attributes.
*/
if ((config.mask & VDPA_DEV_NET_ATTRS_MASK) &&
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
mutex_lock(&vdpa_dev_mutex); mutex_lock(&vdpa_dev_mutex);
mdev = vdpa_mgmtdev_get_from_attr(info->attrs); mdev = vdpa_mgmtdev_get_from_attr(info->attrs);
if (IS_ERR(mdev)) { if (IS_ERR(mdev)) {
...@@ -498,8 +523,14 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i ...@@ -498,8 +523,14 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i
err = PTR_ERR(mdev); err = PTR_ERR(mdev);
goto err; goto err;
} }
if ((config.mask & mdev->config_attr_mask) != config.mask) {
NL_SET_ERR_MSG_MOD(info->extack,
"All provided attributes are not supported");
err = -EOPNOTSUPP;
goto err;
}
err = mdev->ops->dev_add(mdev, name); err = mdev->ops->dev_add(mdev, name, &config);
err: err:
mutex_unlock(&vdpa_dev_mutex); mutex_unlock(&vdpa_dev_mutex);
return err; return err;
...@@ -835,6 +866,9 @@ static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = { ...@@ -835,6 +866,9 @@ static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
[VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING }, [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
[VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING }, [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
[VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING }, [VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING },
[VDPA_ATTR_DEV_NET_CFG_MACADDR] = NLA_POLICY_ETH_ADDR,
/* virtio spec 1.1 section 5.1.4.1 for valid MTU range */
[VDPA_ATTR_DEV_NET_CFG_MTU] = NLA_POLICY_MIN(NLA_U16, 68),
}; };
static const struct genl_ops vdpa_nl_ops[] = { static const struct genl_ops vdpa_nl_ops[] = {
......
...@@ -248,7 +248,8 @@ static struct device vdpasim_blk_mgmtdev = { ...@@ -248,7 +248,8 @@ static struct device vdpasim_blk_mgmtdev = {
.release = vdpasim_blk_mgmtdev_release, .release = vdpasim_blk_mgmtdev_release,
}; };
static int vdpasim_blk_dev_add(struct vdpa_mgmt_dev *mdev, const char *name) static int vdpasim_blk_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
const struct vdpa_dev_set_config *config)
{ {
struct vdpasim_dev_attr dev_attr = {}; struct vdpasim_dev_attr dev_attr = {};
struct vdpasim *simdev; struct vdpasim *simdev;
......
...@@ -126,7 +126,8 @@ static struct device vdpasim_net_mgmtdev = { ...@@ -126,7 +126,8 @@ static struct device vdpasim_net_mgmtdev = {
.release = vdpasim_net_mgmtdev_release, .release = vdpasim_net_mgmtdev_release,
}; };
static int vdpasim_net_dev_add(struct vdpa_mgmt_dev *mdev, const char *name) static int vdpasim_net_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
const struct vdpa_dev_set_config *config)
{ {
struct vdpasim_dev_attr dev_attr = {}; struct vdpasim_dev_attr dev_attr = {};
struct vdpasim *simdev; struct vdpasim *simdev;
......
...@@ -1503,7 +1503,8 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name) ...@@ -1503,7 +1503,8 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
return 0; return 0;
} }
static int vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name) static int vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
const struct vdpa_dev_set_config *config)
{ {
struct vduse_dev *dev; struct vduse_dev *dev;
int ret; int ret;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/vhost_iotlb.h> #include <linux/vhost_iotlb.h>
#include <linux/virtio_net.h>
#include <linux/if_ether.h>
/** /**
* struct vdpa_calllback - vDPA callback definition. * struct vdpa_calllback - vDPA callback definition.
...@@ -93,6 +95,14 @@ struct vdpa_iova_range { ...@@ -93,6 +95,14 @@ struct vdpa_iova_range {
u64 last; u64 last;
}; };
struct vdpa_dev_set_config {
struct {
u8 mac[ETH_ALEN];
u16 mtu;
} net;
u64 mask;
};
/** /**
* Corresponding file area for device memory mapping * Corresponding file area for device memory mapping
* @file: vma->vm_file for the mapping * @file: vma->vm_file for the mapping
...@@ -397,6 +407,7 @@ void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, ...@@ -397,6 +407,7 @@ void vdpa_set_config(struct vdpa_device *dev, unsigned int offset,
* @dev_add: Add a vdpa device using alloc and register * @dev_add: Add a vdpa device using alloc and register
* @mdev: parent device to use for device addition * @mdev: parent device to use for device addition
* @name: name of the new vdpa device * @name: name of the new vdpa device
* @config: config attributes to apply to the device under creation
* Driver need to add a new device using _vdpa_register_device() * Driver need to add a new device using _vdpa_register_device()
* after fully initializing the vdpa device. Driver must return 0 * after fully initializing the vdpa device. Driver must return 0
* on success or appropriate error code. * on success or appropriate error code.
...@@ -407,7 +418,8 @@ void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, ...@@ -407,7 +418,8 @@ void vdpa_set_config(struct vdpa_device *dev, unsigned int offset,
* _vdpa_unregister_device(). * _vdpa_unregister_device().
*/ */
struct vdpa_mgmtdev_ops { struct vdpa_mgmtdev_ops {
int (*dev_add)(struct vdpa_mgmt_dev *mdev, const char *name); int (*dev_add)(struct vdpa_mgmt_dev *mdev, const char *name,
const struct vdpa_dev_set_config *config);
void (*dev_del)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev); void (*dev_del)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev);
}; };
...@@ -416,12 +428,15 @@ struct vdpa_mgmtdev_ops { ...@@ -416,12 +428,15 @@ struct vdpa_mgmtdev_ops {
* @device: Management parent device * @device: Management parent device
* @ops: operations supported by management device * @ops: operations supported by management device
* @id_table: Pointer to device id table of supported ids * @id_table: Pointer to device id table of supported ids
* @config_attr_mask: bit mask of attributes of type enum vdpa_attr that
* management device support during dev_add callback
* @list: list entry * @list: list entry
*/ */
struct vdpa_mgmt_dev { struct vdpa_mgmt_dev {
struct device *device; struct device *device;
const struct vdpa_mgmtdev_ops *ops; const struct vdpa_mgmtdev_ops *ops;
const struct virtio_device_id *id_table; const struct virtio_device_id *id_table;
u64 config_attr_mask;
struct list_head list; struct list_head list;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment