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

phc_vclocks.c (2435B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2021 NXP
      4 */
      5#include "netlink.h"
      6#include "common.h"
      7
      8struct phc_vclocks_req_info {
      9	struct ethnl_req_info		base;
     10};
     11
     12struct phc_vclocks_reply_data {
     13	struct ethnl_reply_data		base;
     14	int				num;
     15	int				*index;
     16};
     17
     18#define PHC_VCLOCKS_REPDATA(__reply_base) \
     19	container_of(__reply_base, struct phc_vclocks_reply_data, base)
     20
     21const struct nla_policy ethnl_phc_vclocks_get_policy[] = {
     22	[ETHTOOL_A_PHC_VCLOCKS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
     23};
     24
     25static int phc_vclocks_prepare_data(const struct ethnl_req_info *req_base,
     26				    struct ethnl_reply_data *reply_base,
     27				    struct genl_info *info)
     28{
     29	struct phc_vclocks_reply_data *data = PHC_VCLOCKS_REPDATA(reply_base);
     30	struct net_device *dev = reply_base->dev;
     31	int ret;
     32
     33	ret = ethnl_ops_begin(dev);
     34	if (ret < 0)
     35		return ret;
     36	data->num = ethtool_get_phc_vclocks(dev, &data->index);
     37	ethnl_ops_complete(dev);
     38
     39	return ret;
     40}
     41
     42static int phc_vclocks_reply_size(const struct ethnl_req_info *req_base,
     43				  const struct ethnl_reply_data *reply_base)
     44{
     45	const struct phc_vclocks_reply_data *data =
     46		PHC_VCLOCKS_REPDATA(reply_base);
     47	int len = 0;
     48
     49	if (data->num > 0) {
     50		len += nla_total_size(sizeof(u32));
     51		len += nla_total_size(sizeof(s32) * data->num);
     52	}
     53
     54	return len;
     55}
     56
     57static int phc_vclocks_fill_reply(struct sk_buff *skb,
     58				  const struct ethnl_req_info *req_base,
     59				  const struct ethnl_reply_data *reply_base)
     60{
     61	const struct phc_vclocks_reply_data *data =
     62		PHC_VCLOCKS_REPDATA(reply_base);
     63
     64	if (data->num <= 0)
     65		return 0;
     66
     67	if (nla_put_u32(skb, ETHTOOL_A_PHC_VCLOCKS_NUM, data->num) ||
     68	    nla_put(skb, ETHTOOL_A_PHC_VCLOCKS_INDEX,
     69		    sizeof(s32) * data->num, data->index))
     70		return -EMSGSIZE;
     71
     72	return 0;
     73}
     74
     75static void phc_vclocks_cleanup_data(struct ethnl_reply_data *reply_base)
     76{
     77	const struct phc_vclocks_reply_data *data =
     78		PHC_VCLOCKS_REPDATA(reply_base);
     79
     80	kfree(data->index);
     81}
     82
     83const struct ethnl_request_ops ethnl_phc_vclocks_request_ops = {
     84	.request_cmd		= ETHTOOL_MSG_PHC_VCLOCKS_GET,
     85	.reply_cmd		= ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY,
     86	.hdr_attr		= ETHTOOL_A_PHC_VCLOCKS_HEADER,
     87	.req_info_size		= sizeof(struct phc_vclocks_req_info),
     88	.reply_data_size	= sizeof(struct phc_vclocks_reply_data),
     89
     90	.prepare_data		= phc_vclocks_prepare_data,
     91	.reply_size		= phc_vclocks_reply_size,
     92	.fill_reply		= phc_vclocks_fill_reply,
     93	.cleanup_data		= phc_vclocks_cleanup_data,
     94};