cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

debug.c (3375B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2
      3#include "netlink.h"
      4#include "common.h"
      5#include "bitset.h"
      6
      7struct debug_req_info {
      8	struct ethnl_req_info		base;
      9};
     10
     11struct debug_reply_data {
     12	struct ethnl_reply_data		base;
     13	u32				msg_mask;
     14};
     15
     16#define DEBUG_REPDATA(__reply_base) \
     17	container_of(__reply_base, struct debug_reply_data, base)
     18
     19const struct nla_policy ethnl_debug_get_policy[] = {
     20	[ETHTOOL_A_DEBUG_HEADER]	=
     21		NLA_POLICY_NESTED(ethnl_header_policy),
     22};
     23
     24static int debug_prepare_data(const struct ethnl_req_info *req_base,
     25			      struct ethnl_reply_data *reply_base,
     26			      struct genl_info *info)
     27{
     28	struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
     29	struct net_device *dev = reply_base->dev;
     30	int ret;
     31
     32	if (!dev->ethtool_ops->get_msglevel)
     33		return -EOPNOTSUPP;
     34
     35	ret = ethnl_ops_begin(dev);
     36	if (ret < 0)
     37		return ret;
     38	data->msg_mask = dev->ethtool_ops->get_msglevel(dev);
     39	ethnl_ops_complete(dev);
     40
     41	return 0;
     42}
     43
     44static int debug_reply_size(const struct ethnl_req_info *req_base,
     45			    const struct ethnl_reply_data *reply_base)
     46{
     47	const struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
     48	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
     49
     50	return ethnl_bitset32_size(&data->msg_mask, NULL, NETIF_MSG_CLASS_COUNT,
     51				   netif_msg_class_names, compact);
     52}
     53
     54static int debug_fill_reply(struct sk_buff *skb,
     55			    const struct ethnl_req_info *req_base,
     56			    const struct ethnl_reply_data *reply_base)
     57{
     58	const struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
     59	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
     60
     61	return ethnl_put_bitset32(skb, ETHTOOL_A_DEBUG_MSGMASK, &data->msg_mask,
     62				  NULL, NETIF_MSG_CLASS_COUNT,
     63				  netif_msg_class_names, compact);
     64}
     65
     66const struct ethnl_request_ops ethnl_debug_request_ops = {
     67	.request_cmd		= ETHTOOL_MSG_DEBUG_GET,
     68	.reply_cmd		= ETHTOOL_MSG_DEBUG_GET_REPLY,
     69	.hdr_attr		= ETHTOOL_A_DEBUG_HEADER,
     70	.req_info_size		= sizeof(struct debug_req_info),
     71	.reply_data_size	= sizeof(struct debug_reply_data),
     72
     73	.prepare_data		= debug_prepare_data,
     74	.reply_size		= debug_reply_size,
     75	.fill_reply		= debug_fill_reply,
     76};
     77
     78/* DEBUG_SET */
     79
     80const struct nla_policy ethnl_debug_set_policy[] = {
     81	[ETHTOOL_A_DEBUG_HEADER]	=
     82		NLA_POLICY_NESTED(ethnl_header_policy),
     83	[ETHTOOL_A_DEBUG_MSGMASK]	= { .type = NLA_NESTED },
     84};
     85
     86int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info)
     87{
     88	struct ethnl_req_info req_info = {};
     89	struct nlattr **tb = info->attrs;
     90	struct net_device *dev;
     91	bool mod = false;
     92	u32 msg_mask;
     93	int ret;
     94
     95	ret = ethnl_parse_header_dev_get(&req_info,
     96					 tb[ETHTOOL_A_DEBUG_HEADER],
     97					 genl_info_net(info), info->extack,
     98					 true);
     99	if (ret < 0)
    100		return ret;
    101	dev = req_info.dev;
    102	ret = -EOPNOTSUPP;
    103	if (!dev->ethtool_ops->get_msglevel || !dev->ethtool_ops->set_msglevel)
    104		goto out_dev;
    105
    106	rtnl_lock();
    107	ret = ethnl_ops_begin(dev);
    108	if (ret < 0)
    109		goto out_rtnl;
    110
    111	msg_mask = dev->ethtool_ops->get_msglevel(dev);
    112	ret = ethnl_update_bitset32(&msg_mask, NETIF_MSG_CLASS_COUNT,
    113				    tb[ETHTOOL_A_DEBUG_MSGMASK],
    114				    netif_msg_class_names, info->extack, &mod);
    115	if (ret < 0 || !mod)
    116		goto out_ops;
    117
    118	dev->ethtool_ops->set_msglevel(dev, msg_mask);
    119	ethtool_notify(dev, ETHTOOL_MSG_DEBUG_NTF, NULL);
    120
    121out_ops:
    122	ethnl_ops_complete(dev);
    123out_rtnl:
    124	rtnl_unlock();
    125out_dev:
    126	ethnl_parse_header_dev_put(&req_info);
    127	return ret;
    128}