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

ctcm_sysfs.c (5324B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright IBM Corp. 2007, 2007
      4 * Authors:	Peter Tiedemann (ptiedem@de.ibm.com)
      5 *
      6 */
      7
      8#undef DEBUG
      9#undef DEBUGDATA
     10#undef DEBUGCCW
     11
     12#define KMSG_COMPONENT "ctcm"
     13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
     14
     15#include <linux/device.h>
     16#include <linux/sysfs.h>
     17#include <linux/slab.h>
     18#include "ctcm_main.h"
     19
     20/*
     21 * sysfs attributes
     22 */
     23
     24static ssize_t ctcm_buffer_show(struct device *dev,
     25				struct device_attribute *attr, char *buf)
     26{
     27	struct ctcm_priv *priv = dev_get_drvdata(dev);
     28
     29	if (!priv)
     30		return -ENODEV;
     31	return sprintf(buf, "%d\n", priv->buffer_size);
     32}
     33
     34static ssize_t ctcm_buffer_write(struct device *dev,
     35		struct device_attribute *attr, const char *buf, size_t count)
     36{
     37	struct net_device *ndev;
     38	unsigned int bs1;
     39	struct ctcm_priv *priv = dev_get_drvdata(dev);
     40	int rc;
     41
     42	if (!(priv && priv->channel[CTCM_READ] &&
     43	      priv->channel[CTCM_READ]->netdev)) {
     44		CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev");
     45		return -ENODEV;
     46	}
     47	ndev = priv->channel[CTCM_READ]->netdev;
     48
     49	rc = kstrtouint(buf, 0, &bs1);
     50	if (rc)
     51		goto einval;
     52	if (bs1 > CTCM_BUFSIZE_LIMIT)
     53					goto einval;
     54	if (bs1 < (576 + LL_HEADER_LENGTH + 2))
     55					goto einval;
     56	priv->buffer_size = bs1;	/* just to overwrite the default */
     57
     58	if ((ndev->flags & IFF_RUNNING) &&
     59	    (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
     60					goto einval;
     61
     62	priv->channel[CTCM_READ]->max_bufsize = bs1;
     63	priv->channel[CTCM_WRITE]->max_bufsize = bs1;
     64	if (!(ndev->flags & IFF_RUNNING))
     65		ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
     66	priv->channel[CTCM_READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
     67	priv->channel[CTCM_WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
     68
     69	CTCM_DBF_DEV(SETUP, ndev, buf);
     70	return count;
     71
     72einval:
     73	CTCM_DBF_DEV(SETUP, ndev, "buff_err");
     74	return -EINVAL;
     75}
     76
     77static void ctcm_print_statistics(struct ctcm_priv *priv)
     78{
     79	char *sbuf;
     80	char *p;
     81
     82	if (!priv)
     83		return;
     84	sbuf = kmalloc(2048, GFP_KERNEL);
     85	if (sbuf == NULL)
     86		return;
     87	p = sbuf;
     88
     89	p += sprintf(p, "  Device FSM state: %s\n",
     90		     fsm_getstate_str(priv->fsm));
     91	p += sprintf(p, "  RX channel FSM state: %s\n",
     92		     fsm_getstate_str(priv->channel[CTCM_READ]->fsm));
     93	p += sprintf(p, "  TX channel FSM state: %s\n",
     94		     fsm_getstate_str(priv->channel[CTCM_WRITE]->fsm));
     95	p += sprintf(p, "  Max. TX buffer used: %ld\n",
     96		     priv->channel[WRITE]->prof.maxmulti);
     97	p += sprintf(p, "  Max. chained SKBs: %ld\n",
     98		     priv->channel[WRITE]->prof.maxcqueue);
     99	p += sprintf(p, "  TX single write ops: %ld\n",
    100		     priv->channel[WRITE]->prof.doios_single);
    101	p += sprintf(p, "  TX multi write ops: %ld\n",
    102		     priv->channel[WRITE]->prof.doios_multi);
    103	p += sprintf(p, "  Netto bytes written: %ld\n",
    104		     priv->channel[WRITE]->prof.txlen);
    105	p += sprintf(p, "  Max. TX IO-time: %u\n",
    106		     jiffies_to_usecs(priv->channel[WRITE]->prof.tx_time));
    107
    108	printk(KERN_INFO "Statistics for %s:\n%s",
    109				priv->channel[CTCM_WRITE]->netdev->name, sbuf);
    110	kfree(sbuf);
    111	return;
    112}
    113
    114static ssize_t stats_show(struct device *dev,
    115			  struct device_attribute *attr, char *buf)
    116{
    117	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
    118	struct ctcm_priv *priv = dev_get_drvdata(dev);
    119
    120	if (!priv || gdev->state != CCWGROUP_ONLINE)
    121		return -ENODEV;
    122	ctcm_print_statistics(priv);
    123	return sprintf(buf, "0\n");
    124}
    125
    126static ssize_t stats_write(struct device *dev, struct device_attribute *attr,
    127				const char *buf, size_t count)
    128{
    129	struct ctcm_priv *priv = dev_get_drvdata(dev);
    130	if (!priv)
    131		return -ENODEV;
    132	/* Reset statistics */
    133	memset(&priv->channel[WRITE]->prof, 0,
    134				sizeof(priv->channel[CTCM_WRITE]->prof));
    135	return count;
    136}
    137
    138static ssize_t ctcm_proto_show(struct device *dev,
    139				struct device_attribute *attr, char *buf)
    140{
    141	struct ctcm_priv *priv = dev_get_drvdata(dev);
    142	if (!priv)
    143		return -ENODEV;
    144
    145	return sprintf(buf, "%d\n", priv->protocol);
    146}
    147
    148static ssize_t ctcm_proto_store(struct device *dev,
    149		struct device_attribute *attr, const char *buf, size_t count)
    150{
    151	int value, rc;
    152	struct ctcm_priv *priv = dev_get_drvdata(dev);
    153
    154	if (!priv)
    155		return -ENODEV;
    156	rc = kstrtoint(buf, 0, &value);
    157	if (rc ||
    158	    !((value == CTCM_PROTO_S390)  ||
    159	      (value == CTCM_PROTO_LINUX) ||
    160	      (value == CTCM_PROTO_MPC) ||
    161	      (value == CTCM_PROTO_OS390)))
    162		return -EINVAL;
    163	priv->protocol = value;
    164	CTCM_DBF_DEV(SETUP, dev, buf);
    165
    166	return count;
    167}
    168
    169static const char *ctcm_type[] = {
    170	"not a channel",
    171	"CTC/A",
    172	"FICON channel",
    173	"ESCON channel",
    174	"unknown channel type",
    175	"unsupported channel type",
    176};
    177
    178static ssize_t ctcm_type_show(struct device *dev,
    179				struct device_attribute *attr, char *buf)
    180{
    181	struct ccwgroup_device *cgdev;
    182
    183	cgdev = to_ccwgroupdev(dev);
    184	if (!cgdev)
    185		return -ENODEV;
    186
    187	return sprintf(buf, "%s\n",
    188			ctcm_type[cgdev->cdev[0]->id.driver_info]);
    189}
    190
    191static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write);
    192static DEVICE_ATTR(protocol, 0644, ctcm_proto_show, ctcm_proto_store);
    193static DEVICE_ATTR(type, 0444, ctcm_type_show, NULL);
    194static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
    195
    196static struct attribute *ctcm_attr[] = {
    197	&dev_attr_protocol.attr,
    198	&dev_attr_type.attr,
    199	&dev_attr_buffer.attr,
    200	&dev_attr_stats.attr,
    201	NULL,
    202};
    203
    204static struct attribute_group ctcm_attr_group = {
    205	.attrs = ctcm_attr,
    206};
    207const struct attribute_group *ctcm_attr_groups[] = {
    208	&ctcm_attr_group,
    209	NULL,
    210};