Add new UAPI to support the mac address from vdpa tool
Function vdpa_nl_cmd_dev_attr_set_doit() will get the
new MAC address from the vdpa tool and then set it to the device.
The usage is: vdpa dev set name vdpa_name mac **:**:**:**:**:**
Here is example:
root@L1# vdpa -jp dev config show vdpa0
{
"config": {
"vdpa0": {
"mac": "82:4d:e9:5d:d7:e6",
"link ": "up",
"link_announce ": false,
"mtu": 1500
}
}
}
root@L1# vdpa dev set name vdpa0 mac 00:11:22:33:44:55
root@L1# vdpa -jp dev config show vdpa0
{
"config": {
"vdpa0": {
"mac": "00:11:22:33:44:55",
"link ": "up",
"link_announce ": false,
"mtu": 1500
}
}
}
Signed-off-by: Cindy Lu <lulu@redhat.com>
---
drivers/vdpa/vdpa.c | 81 +++++++++++++++++++++++++++++++++++++++
include/linux/vdpa.h | 9 +++++
include/uapi/linux/vdpa.h | 1 +
3 files changed, 91 insertions(+)
diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
index a7612e0783b3..ca97ad43e1bd 100644
--- a/drivers/vdpa/vdpa.c
+++ b/drivers/vdpa/vdpa.c
@@ -1149,6 +1149,82 @@ static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info
return err;
}
+static int vdpa_dev_net_device_attr_set(struct vdpa_device *vdev,
+ struct genl_info *info)
+{
+ struct vdpa_dev_set_config set_config = {};
+ const u8 *macaddr;
+ struct vdpa_mgmt_dev *mdev = vdev->mdev;
+ struct nlattr **nl_attrs = info->attrs;
+ int err;
+
+ if (!vdev->mdev)
+ return -EINVAL;
+
+ down_write(&vdev->cf_lock);
+ if ((mdev->supported_features & BIT_ULL(VIRTIO_NET_F_MAC)) &&
+ nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
+ set_config.mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR);
+ macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
+ memcpy(set_config.net.mac, macaddr, ETH_ALEN);
+
+ if (mdev->ops->dev_set_attr) {
+ err = mdev->ops->dev_set_attr(mdev, vdev, &set_config);
+ } else {
+ NL_SET_ERR_MSG_FMT_MOD(info->extack,
+ "features 0x%llx not supported",
+ BIT_ULL(VIRTIO_NET_F_MAC));
+ err = -EINVAL;
+ }
+ }
+ up_write(&vdev->cf_lock);
+
+ return err;
+}
+static int vdpa_nl_cmd_dev_attr_set_doit(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ const char *name;
+ int err = 0;
+ struct device *dev;
+ struct vdpa_device *vdev;
+ u64 classes;
+
+ if (!info->attrs[VDPA_ATTR_DEV_NAME])
+ return -EINVAL;
+
+ name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
+
+ down_write(&vdpa_dev_lock);
+ dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match);
+ if (!dev) {
+ NL_SET_ERR_MSG_MOD(info->extack, "device not found");
+ err = -ENODEV;
+ goto dev_err;
+ }
+ vdev = container_of(dev, struct vdpa_device, dev);
+ if (!vdev->mdev) {
+ NL_SET_ERR_MSG_MOD(
+ info->extack,
+ "Fail to find the specified management device");
+ err = -EINVAL;
+ goto mdev_err;
+ }
+ classes = vdpa_mgmtdev_get_classes(vdev->mdev, NULL);
+ if (classes & BIT_ULL(VIRTIO_ID_NET)) {
+ err = vdpa_dev_net_device_attr_set(vdev, info);
+ } else {
+ NL_SET_ERR_MSG_FMT_MOD(info->extack, "%s device not supported",
+ name);
+ }
+
+mdev_err:
+ put_device(dev);
+dev_err:
+ up_write(&vdpa_dev_lock);
+ return err;
+}
+
static int vdpa_dev_config_dump(struct device *dev, void *data)
{
struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev);
@@ -1285,6 +1361,11 @@ static const struct genl_ops vdpa_nl_ops[] = {
.doit = vdpa_nl_cmd_dev_stats_get_doit,
.flags = GENL_ADMIN_PERM,
},
+ {
+ .cmd = VDPA_CMD_DEV_ATTR_SET,
+ .doit = vdpa_nl_cmd_dev_attr_set_doit,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_family vdpa_nl_family __ro_after_init = {
diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index db15ac07f8a6..14afa6d59098 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -576,11 +576,20 @@ void vdpa_set_status(struct vdpa_device *vdev, u8 status);
* @dev: vdpa device to remove
* Driver need to remove the specified device by calling
* _vdpa_unregister_device().
+ * @dev_set_attr: change a vdpa device's attr after it was create
+ * @mdev: parent device to use for device
+ * @dev: vdpa device structure
+ * @config:Attributes to be set for the device.
+ * The driver needs to check the mask of the structure and then set
+ * the related information to the vdpa device. The driver must return 0
+ * if set successfully.
*/
struct vdpa_mgmtdev_ops {
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);
+ int (*dev_set_attr)(struct vdpa_mgmt_dev *mdev, struct vdpa_device *dev,
+ const struct vdpa_dev_set_config *config);
};
/**
diff --git a/include/uapi/linux/vdpa.h b/include/uapi/linux/vdpa.h
index 54b649ab0f22..76b3a1fd13f3 100644
--- a/include/uapi/linux/vdpa.h
+++ b/include/uapi/linux/vdpa.h
@@ -19,6 +19,7 @@ enum vdpa_command {
VDPA_CMD_DEV_GET, /* can dump */
VDPA_CMD_DEV_CONFIG_GET, /* can dump */
VDPA_CMD_DEV_VSTATS_GET,
+ VDPA_CMD_DEV_ATTR_SET,
};
enum vdpa_attr {
--
2.45.0
Hi Cindy,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linus/master]
[also build test WARNING on horms-ipvs/master v6.10-rc7 next-20240703]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Cindy-Lu/vdpa-support-set-mac-address-from-vdpa-tool/20240708-144942
base: linus/master
patch link: https://lore.kernel.org/r/20240708064820.88955-2-lulu%40redhat.com
patch subject: [PATCH v3 1/2] vdpa: support set mac address from vdpa tool
config: i386-buildonly-randconfig-005-20240708 (https://download.01.org/0day-ci/archive/20240708/202407081733.FCiMubD8-lkp@intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240708/202407081733.FCiMubD8-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407081733.FCiMubD8-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/vdpa/vdpa.c:1377:6: warning: variable 'err' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
1377 | if ((mdev->supported_features & BIT_ULL(VIRTIO_NET_F_MAC)) &&
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1378 | nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/vdpa/vdpa.c:1394:9: note: uninitialized use occurs here
1394 | return err;
| ^~~
drivers/vdpa/vdpa.c:1377:2: note: remove the 'if' if its condition is always true
1377 | if ((mdev->supported_features & BIT_ULL(VIRTIO_NET_F_MAC)) &&
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1378 | nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/vdpa/vdpa.c:1377:6: warning: variable 'err' is used uninitialized whenever '&&' condition is false [-Wsometimes-uninitialized]
1377 | if ((mdev->supported_features & BIT_ULL(VIRTIO_NET_F_MAC)) &&
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/vdpa/vdpa.c:1394:9: note: uninitialized use occurs here
1394 | return err;
| ^~~
drivers/vdpa/vdpa.c:1377:6: note: remove the '&&' if its condition is always true
1377 | if ((mdev->supported_features & BIT_ULL(VIRTIO_NET_F_MAC)) &&
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/vdpa/vdpa.c:1371:9: note: initialize the variable 'err' to silence this warning
1371 | int err;
| ^
| = 0
2 warnings generated.
vim +1377 drivers/vdpa/vdpa.c
1363
1364 static int vdpa_dev_net_device_attr_set(struct vdpa_device *vdev,
1365 struct genl_info *info)
1366 {
1367 struct vdpa_dev_set_config set_config = {};
1368 const u8 *macaddr;
1369 struct vdpa_mgmt_dev *mdev = vdev->mdev;
1370 struct nlattr **nl_attrs = info->attrs;
1371 int err;
1372
1373 if (!vdev->mdev)
1374 return -EINVAL;
1375
1376 down_write(&vdev->cf_lock);
> 1377 if ((mdev->supported_features & BIT_ULL(VIRTIO_NET_F_MAC)) &&
1378 nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]) {
1379 set_config.mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR);
1380 macaddr = nla_data(nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR]);
1381 memcpy(set_config.net.mac, macaddr, ETH_ALEN);
1382
1383 if (mdev->ops->dev_set_attr) {
1384 err = mdev->ops->dev_set_attr(mdev, vdev, &set_config);
1385 } else {
1386 NL_SET_ERR_MSG_FMT_MOD(info->extack,
1387 "features 0x%llx not supported",
1388 BIT_ULL(VIRTIO_NET_F_MAC));
1389 err = -EINVAL;
1390 }
1391 }
1392 up_write(&vdev->cf_lock);
1393
1394 return err;
1395 }
1396 static int vdpa_nl_cmd_dev_attr_set_doit(struct sk_buff *skb,
1397 struct genl_info *info)
1398 {
1399 const char *name;
1400 int err = 0;
1401 struct device *dev;
1402 struct vdpa_device *vdev;
1403 u64 classes;
1404
1405 if (!info->attrs[VDPA_ATTR_DEV_NAME])
1406 return -EINVAL;
1407
1408 name = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]);
1409
1410 down_write(&vdpa_dev_lock);
1411 dev = bus_find_device(&vdpa_bus, NULL, name, vdpa_name_match);
1412 if (!dev) {
1413 NL_SET_ERR_MSG_MOD(info->extack, "device not found");
1414 err = -ENODEV;
1415 goto dev_err;
1416 }
1417 vdev = container_of(dev, struct vdpa_device, dev);
1418 if (!vdev->mdev) {
1419 NL_SET_ERR_MSG_MOD(
1420 info->extack,
1421 "Fail to find the specified management device");
1422 err = -EINVAL;
1423 goto mdev_err;
1424 }
1425 classes = vdpa_mgmtdev_get_classes(vdev->mdev, NULL);
1426 if (classes & BIT_ULL(VIRTIO_ID_NET)) {
1427 err = vdpa_dev_net_device_attr_set(vdev, info);
1428 } else {
1429 NL_SET_ERR_MSG_FMT_MOD(info->extack, "%s device not supported",
1430 name);
1431 }
1432
1433 mdev_err:
1434 put_device(dev);
1435 dev_err:
1436 up_write(&vdpa_dev_lock);
1437 return err;
1438 }
1439
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Mon, Jul 8, 2024 at 2:48 PM Cindy Lu <lulu@redhat.com> wrote:
>
> Add new UAPI to support the mac address from vdpa tool
> Function vdpa_nl_cmd_dev_attr_set_doit() will get the
> new MAC address from the vdpa tool and then set it to the device.
>
> The usage is: vdpa dev set name vdpa_name mac **:**:**:**:**:**
>
> Here is example:
> root@L1# vdpa -jp dev config show vdpa0
> {
> "config": {
> "vdpa0": {
> "mac": "82:4d:e9:5d:d7:e6",
> "link ": "up",
> "link_announce ": false,
> "mtu": 1500
> }
> }
> }
>
> root@L1# vdpa dev set name vdpa0 mac 00:11:22:33:44:55
>
> root@L1# vdpa -jp dev config show vdpa0
> {
> "config": {
> "vdpa0": {
> "mac": "00:11:22:33:44:55",
> "link ": "up",
> "link_announce ": false,
> "mtu": 1500
> }
> }
> }
>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Thanks
© 2016 - 2026 Red Hat, Inc.