aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/devlink.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 283c3ed9f25e..1d7502a5a651 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -116,6 +116,8 @@ static struct devlink *devlink_get_from_attrs(struct net *net,
116 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); 116 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
117 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); 117 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
118 118
119 lockdep_assert_held(&devlink_mutex);
120
119 list_for_each_entry(devlink, &devlink_list, list) { 121 list_for_each_entry(devlink, &devlink_list, list) {
120 if (strcmp(devlink->dev->bus->name, busname) == 0 && 122 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
121 strcmp(dev_name(devlink->dev), devname) == 0 && 123 strcmp(dev_name(devlink->dev), devname) == 0 &&
@@ -3645,27 +3647,35 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3645 if (err) 3647 if (err)
3646 goto out_free; 3648 goto out_free;
3647 3649
3650 mutex_lock(&devlink_mutex);
3648 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); 3651 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
3649 if (IS_ERR(devlink)) 3652 if (IS_ERR(devlink)) {
3650 goto out_free; 3653 err = PTR_ERR(devlink);
3654 goto out_dev;
3655 }
3651 3656
3652 mutex_lock(&devlink_mutex);
3653 mutex_lock(&devlink->lock); 3657 mutex_lock(&devlink->lock);
3654 3658
3655 if (!attrs[DEVLINK_ATTR_REGION_NAME] || 3659 if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
3656 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) 3660 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
3661 err = -EINVAL;
3657 goto out_unlock; 3662 goto out_unlock;
3663 }
3658 3664
3659 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]); 3665 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
3660 region = devlink_region_get_by_name(devlink, region_name); 3666 region = devlink_region_get_by_name(devlink, region_name);
3661 if (!region) 3667 if (!region) {
3668 err = -EINVAL;
3662 goto out_unlock; 3669 goto out_unlock;
3670 }
3663 3671
3664 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 3672 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3665 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 3673 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
3666 DEVLINK_CMD_REGION_READ); 3674 DEVLINK_CMD_REGION_READ);
3667 if (!hdr) 3675 if (!hdr) {
3676 err = -EMSGSIZE;
3668 goto out_unlock; 3677 goto out_unlock;
3678 }
3669 3679
3670 err = devlink_nl_put_handle(skb, devlink); 3680 err = devlink_nl_put_handle(skb, devlink);
3671 if (err) 3681 if (err)
@@ -3676,8 +3686,10 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3676 goto nla_put_failure; 3686 goto nla_put_failure;
3677 3687
3678 chunks_attr = nla_nest_start(skb, DEVLINK_ATTR_REGION_CHUNKS); 3688 chunks_attr = nla_nest_start(skb, DEVLINK_ATTR_REGION_CHUNKS);
3679 if (!chunks_attr) 3689 if (!chunks_attr) {
3690 err = -EMSGSIZE;
3680 goto nla_put_failure; 3691 goto nla_put_failure;
3692 }
3681 3693
3682 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 3694 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
3683 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 3695 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
@@ -3700,8 +3712,10 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3700 goto nla_put_failure; 3712 goto nla_put_failure;
3701 3713
3702 /* Check if there was any progress done to prevent infinite loop */ 3714 /* Check if there was any progress done to prevent infinite loop */
3703 if (ret_offset == start_offset) 3715 if (ret_offset == start_offset) {
3716 err = -EINVAL;
3704 goto nla_put_failure; 3717 goto nla_put_failure;
3718 }
3705 3719
3706 *((u64 *)&cb->args[0]) = ret_offset; 3720 *((u64 *)&cb->args[0]) = ret_offset;
3707 3721
@@ -3717,10 +3731,11 @@ nla_put_failure:
3717 genlmsg_cancel(skb, hdr); 3731 genlmsg_cancel(skb, hdr);
3718out_unlock: 3732out_unlock:
3719 mutex_unlock(&devlink->lock); 3733 mutex_unlock(&devlink->lock);
3734out_dev:
3720 mutex_unlock(&devlink_mutex); 3735 mutex_unlock(&devlink_mutex);
3721out_free: 3736out_free:
3722 kfree(attrs); 3737 kfree(attrs);
3723 return 0; 3738 return err;
3724} 3739}
3725 3740
3726struct devlink_info_req { 3741struct devlink_info_req {