Merge branch 'ethtool-more-bug-fixes'

Jakub Kicinski says:

====================
ethtool: more bug fixes

Last week I sent two patch sets - one fixing bugs in RSS handling,
and one fixing CMIS / module handling. This set contains the remaining
fixes. There's a concentration of fixes around PHY and timestamp config
handling but not enough to break those out as separate sets.
====================

Link: https://patch.msgid.link/20260526153533.2779187-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2026-05-27 17:42:18 -07:00
7 changed files with 46 additions and 22 deletions

View File

@@ -472,6 +472,12 @@ static int ethnl_update_profile(struct net_device *dev,
nla_for_each_nested_type(nest, ETHTOOL_A_PROFILE_IRQ_MODERATION,
nests, rem) {
if (i >= NET_DIM_PARAMS_NUM_PROFILES) {
NL_SET_BAD_ATTR(extack, nest);
ret = -E2BIG;
goto err_out;
}
ret = nla_parse_nested(tb, len_irq_moder - 1, nest,
coalesce_irq_moderation_policy,
extack);

View File

@@ -44,6 +44,9 @@ static int fallback_set_params(struct eeprom_req_info *request,
if (offset >= modinfo->eeprom_len)
return -EINVAL;
if (length > modinfo->eeprom_len - offset)
return -EINVAL;
eeprom->cmd = ETHTOOL_GMODULEEEPROM;
eeprom->len = length;
eeprom->offset = offset;
@@ -69,7 +72,7 @@ static int eeprom_fallback(struct eeprom_req_info *request,
if (err < 0)
return err;
data = kmalloc(eeprom.len, GFP_KERNEL);
data = kzalloc(eeprom.len, GFP_KERNEL);
if (!data)
return -ENOMEM;
err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
@@ -141,12 +144,11 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
return 0;
err_ops:
if (ret == -EOPNOTSUPP)
ret = eeprom_fallback(request, reply);
ethnl_ops_complete(dev);
err_free:
kfree(page_data.data);
if (ret == -EOPNOTSUPP)
return eeprom_fallback(request, reply);
return ret;
}

View File

@@ -106,10 +106,8 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_LINKSTATE_HEADER,
info->extack);
if (IS_ERR(phydev)) {
ret = PTR_ERR(phydev);
goto out;
}
if (IS_ERR(phydev))
return PTR_ERR(phydev);
ret = ethnl_ops_begin(dev);
if (ret < 0)

View File

@@ -62,14 +62,14 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
struct phy_device *phydev;
int ret;
ret = ethnl_ops_begin(dev);
if (ret < 0)
return ret;
phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_PSE_HEADER,
info->extack);
if (IS_ERR(phydev))
return -ENODEV;
return PTR_ERR(phydev);
ret = ethnl_ops_begin(dev);
if (ret < 0)
return ret;
ret = pse_get_pse_attributes(phydev, info->extack, data);

View File

@@ -311,7 +311,7 @@ static int strset_prepare_data(const struct ethnl_req_info *req_base,
return 0;
}
phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_HEADER_FLAGS,
phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_STRSET_HEADER,
info->extack);
/* phydev can be NULL, check for errors only */

View File

@@ -69,8 +69,10 @@ static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
if (ret)
goto out;
if (ts_info.phc_index == -1)
return -ENODEV;
if (ts_info.phc_index == -1) {
ret = -ENODEV;
goto out;
}
data->hwprov_desc.index = ts_info.phc_index;
data->hwprov_desc.qualifier = ts_info.phc_qualifier;
@@ -224,16 +226,21 @@ static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info)
reply_len = ret + ethnl_reply_header_size();
rskb = ethnl_reply_init(reply_len, dev, ETHTOOL_MSG_TSCONFIG_SET_REPLY,
ETHTOOL_A_TSCONFIG_HEADER, info, &reply_payload);
if (!rskb)
if (!rskb) {
ret = -ENOMEM;
goto err_cleanup;
}
ret = tsconfig_fill_reply(rskb, &req_info->base, &reply_data->base);
if (ret < 0)
goto err_cleanup;
goto err_free_msg;
genlmsg_end(rskb, reply_payload);
ret = genlmsg_reply(rskb, info);
rskb = NULL;
err_free_msg:
nlmsg_free(rskb);
err_cleanup:
kfree(reply_data);
kfree(req_info);

View File

@@ -83,6 +83,11 @@ tsinfo_parse_request(struct ethnl_req_info *req_base,
if (!tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER])
return 0;
if (req_base->flags & ETHTOOL_FLAG_STATS) {
NL_SET_ERR_MSG(extack, "can't query statistics for a provider");
return -EOPNOTSUPP;
}
return ts_parse_hwtst_provider(tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER],
&req->hwprov_desc, extack, &mod);
}
@@ -402,10 +407,8 @@ static int ethnl_tsinfo_dump_one_netdev(struct sk_buff *skb,
continue;
ehdr = ethnl_tsinfo_prepare_dump(skb, dev, reply_data, cb);
if (IS_ERR(ehdr)) {
ret = PTR_ERR(ehdr);
goto err;
}
if (IS_ERR(ehdr))
return PTR_ERR(ehdr);
reply_data->ts_info.phc_qualifier = ctx->pos_phcqualifier;
ret = ops->get_ts_info(dev, &reply_data->ts_info);
@@ -523,6 +526,12 @@ int ethnl_tsinfo_start(struct netlink_callback *cb)
if (ret < 0)
goto free_reply_data;
if (req_info->base.flags & ETHTOOL_FLAG_STATS) {
NL_SET_ERR_MSG(cb->extack, "stats not supported in dump");
ret = -EOPNOTSUPP;
goto err_dev_put;
}
ctx->req_info = req_info;
ctx->reply_data = reply_data;
ctx->pos_ifindex = 0;
@@ -532,6 +541,8 @@ int ethnl_tsinfo_start(struct netlink_callback *cb)
return 0;
err_dev_put:
ethnl_parse_header_dev_put(&req_info->base);
free_reply_data:
kfree(reply_data);
free_req_info: