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

rtrs-srv-sysfs.c (7943B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * RDMA Transport Layer
      4 *
      5 * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
      6 * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
      7 * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
      8 */
      9#undef pr_fmt
     10#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
     11
     12#include "rtrs-pri.h"
     13#include "rtrs-srv.h"
     14#include "rtrs-log.h"
     15
     16static void rtrs_srv_release(struct kobject *kobj)
     17{
     18	struct rtrs_srv_path *srv_path;
     19
     20	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
     21	kfree(srv_path);
     22}
     23
     24static struct kobj_type ktype = {
     25	.sysfs_ops	= &kobj_sysfs_ops,
     26	.release	= rtrs_srv_release,
     27};
     28
     29static ssize_t rtrs_srv_disconnect_show(struct kobject *kobj,
     30					struct kobj_attribute *attr, char *buf)
     31{
     32	return sysfs_emit(buf, "Usage: echo 1 > %s\n", attr->attr.name);
     33}
     34
     35static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
     36					  struct kobj_attribute *attr,
     37					  const char *buf, size_t count)
     38{
     39	struct rtrs_srv_path *srv_path;
     40	struct rtrs_path *s;
     41	char str[MAXHOSTNAMELEN];
     42
     43	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
     44	s = &srv_path->s;
     45	if (!sysfs_streq(buf, "1")) {
     46		rtrs_err(s, "%s: invalid value: '%s'\n",
     47			  attr->attr.name, buf);
     48		return -EINVAL;
     49	}
     50
     51	sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr, str,
     52			sizeof(str));
     53
     54	rtrs_info(s, "disconnect for path %s requested\n", str);
     55	/* first remove sysfs itself to avoid deadlock */
     56	sysfs_remove_file_self(&srv_path->kobj, &attr->attr);
     57	close_path(srv_path);
     58
     59	return count;
     60}
     61
     62static struct kobj_attribute rtrs_srv_disconnect_attr =
     63	__ATTR(disconnect, 0644,
     64	       rtrs_srv_disconnect_show, rtrs_srv_disconnect_store);
     65
     66static ssize_t rtrs_srv_hca_port_show(struct kobject *kobj,
     67				       struct kobj_attribute *attr,
     68				       char *page)
     69{
     70	struct rtrs_srv_path *srv_path;
     71	struct rtrs_con *usr_con;
     72
     73	srv_path = container_of(kobj, typeof(*srv_path), kobj);
     74	usr_con = srv_path->s.con[0];
     75
     76	return sysfs_emit(page, "%u\n", usr_con->cm_id->port_num);
     77}
     78
     79static struct kobj_attribute rtrs_srv_hca_port_attr =
     80	__ATTR(hca_port, 0444, rtrs_srv_hca_port_show, NULL);
     81
     82static ssize_t rtrs_srv_hca_name_show(struct kobject *kobj,
     83				       struct kobj_attribute *attr,
     84				       char *page)
     85{
     86	struct rtrs_srv_path *srv_path;
     87
     88	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
     89
     90	return sysfs_emit(page, "%s\n", srv_path->s.dev->ib_dev->name);
     91}
     92
     93static struct kobj_attribute rtrs_srv_hca_name_attr =
     94	__ATTR(hca_name, 0444, rtrs_srv_hca_name_show, NULL);
     95
     96static ssize_t rtrs_srv_src_addr_show(struct kobject *kobj,
     97				       struct kobj_attribute *attr,
     98				       char *page)
     99{
    100	struct rtrs_srv_path *srv_path;
    101	int cnt;
    102
    103	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
    104	cnt = sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr,
    105			      page, PAGE_SIZE);
    106	return cnt + sysfs_emit_at(page, cnt, "\n");
    107}
    108
    109static struct kobj_attribute rtrs_srv_src_addr_attr =
    110	__ATTR(src_addr, 0444, rtrs_srv_src_addr_show, NULL);
    111
    112static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
    113				       struct kobj_attribute *attr,
    114				       char *page)
    115{
    116	struct rtrs_srv_path *srv_path;
    117	int len;
    118
    119	srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
    120	len = sockaddr_to_str((struct sockaddr *)&srv_path->s.src_addr, page,
    121			      PAGE_SIZE);
    122	len += sysfs_emit_at(page, len, "\n");
    123	return len;
    124}
    125
    126static struct kobj_attribute rtrs_srv_dst_addr_attr =
    127	__ATTR(dst_addr, 0444, rtrs_srv_dst_addr_show, NULL);
    128
    129static struct attribute *rtrs_srv_path_attrs[] = {
    130	&rtrs_srv_hca_name_attr.attr,
    131	&rtrs_srv_hca_port_attr.attr,
    132	&rtrs_srv_src_addr_attr.attr,
    133	&rtrs_srv_dst_addr_attr.attr,
    134	&rtrs_srv_disconnect_attr.attr,
    135	NULL,
    136};
    137
    138static const struct attribute_group rtrs_srv_path_attr_group = {
    139	.attrs = rtrs_srv_path_attrs,
    140};
    141
    142STAT_ATTR(struct rtrs_srv_stats, rdma,
    143	  rtrs_srv_stats_rdma_to_str,
    144	  rtrs_srv_reset_rdma_stats);
    145
    146static struct attribute *rtrs_srv_stats_attrs[] = {
    147	&rdma_attr.attr,
    148	NULL,
    149};
    150
    151static const struct attribute_group rtrs_srv_stats_attr_group = {
    152	.attrs = rtrs_srv_stats_attrs,
    153};
    154
    155static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
    156{
    157	struct rtrs_srv_sess *srv = srv_path->srv;
    158	int err = 0;
    159
    160	mutex_lock(&srv->paths_mutex);
    161	if (srv->dev_ref++) {
    162		/*
    163		 * Device needs to be registered only on the first session
    164		 */
    165		goto unlock;
    166	}
    167	srv->dev.class = rtrs_dev_class;
    168	err = dev_set_name(&srv->dev, "%s", srv_path->s.sessname);
    169	if (err)
    170		goto unlock;
    171
    172	/*
    173	 * Suppress user space notification until
    174	 * sysfs files are created
    175	 */
    176	dev_set_uevent_suppress(&srv->dev, true);
    177	err = device_add(&srv->dev);
    178	if (err) {
    179		pr_err("device_add(): %d\n", err);
    180		put_device(&srv->dev);
    181		goto unlock;
    182	}
    183	srv->kobj_paths = kobject_create_and_add("paths", &srv->dev.kobj);
    184	if (!srv->kobj_paths) {
    185		err = -ENOMEM;
    186		pr_err("kobject_create_and_add(): %d\n", err);
    187		device_del(&srv->dev);
    188		put_device(&srv->dev);
    189		goto unlock;
    190	}
    191	dev_set_uevent_suppress(&srv->dev, false);
    192	kobject_uevent(&srv->dev.kobj, KOBJ_ADD);
    193unlock:
    194	mutex_unlock(&srv->paths_mutex);
    195
    196	return err;
    197}
    198
    199static void
    200rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
    201{
    202	struct rtrs_srv_sess *srv = srv_path->srv;
    203
    204	mutex_lock(&srv->paths_mutex);
    205	if (!--srv->dev_ref) {
    206		kobject_del(srv->kobj_paths);
    207		kobject_put(srv->kobj_paths);
    208		mutex_unlock(&srv->paths_mutex);
    209		device_del(&srv->dev);
    210		put_device(&srv->dev);
    211	} else {
    212		put_device(&srv->dev);
    213		mutex_unlock(&srv->paths_mutex);
    214	}
    215}
    216
    217static void rtrs_srv_path_stats_release(struct kobject *kobj)
    218{
    219	struct rtrs_srv_stats *stats;
    220
    221	stats = container_of(kobj, struct rtrs_srv_stats, kobj_stats);
    222
    223	kfree(stats);
    224}
    225
    226static struct kobj_type ktype_stats = {
    227	.sysfs_ops = &kobj_sysfs_ops,
    228	.release = rtrs_srv_path_stats_release,
    229};
    230
    231static int rtrs_srv_create_stats_files(struct rtrs_srv_path *srv_path)
    232{
    233	int err;
    234	struct rtrs_path *s = &srv_path->s;
    235
    236	err = kobject_init_and_add(&srv_path->stats->kobj_stats, &ktype_stats,
    237				   &srv_path->kobj, "stats");
    238	if (err) {
    239		rtrs_err(s, "kobject_init_and_add(): %d\n", err);
    240		kobject_put(&srv_path->stats->kobj_stats);
    241		return err;
    242	}
    243	err = sysfs_create_group(&srv_path->stats->kobj_stats,
    244				 &rtrs_srv_stats_attr_group);
    245	if (err) {
    246		rtrs_err(s, "sysfs_create_group(): %d\n", err);
    247		goto err;
    248	}
    249
    250	return 0;
    251
    252err:
    253	kobject_del(&srv_path->stats->kobj_stats);
    254	kobject_put(&srv_path->stats->kobj_stats);
    255
    256	return err;
    257}
    258
    259int rtrs_srv_create_path_files(struct rtrs_srv_path *srv_path)
    260{
    261	struct rtrs_srv_sess *srv = srv_path->srv;
    262	struct rtrs_path *s = &srv_path->s;
    263	char str[NAME_MAX];
    264	int err;
    265	struct rtrs_addr path = {
    266		.src = &srv_path->s.dst_addr,
    267		.dst = &srv_path->s.src_addr,
    268	};
    269
    270	rtrs_addr_to_str(&path, str, sizeof(str));
    271	err = rtrs_srv_create_once_sysfs_root_folders(srv_path);
    272	if (err)
    273		return err;
    274
    275	err = kobject_init_and_add(&srv_path->kobj, &ktype, srv->kobj_paths,
    276				   "%s", str);
    277	if (err) {
    278		rtrs_err(s, "kobject_init_and_add(): %d\n", err);
    279		goto destroy_root;
    280	}
    281	err = sysfs_create_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
    282	if (err) {
    283		rtrs_err(s, "sysfs_create_group(): %d\n", err);
    284		goto put_kobj;
    285	}
    286	err = rtrs_srv_create_stats_files(srv_path);
    287	if (err)
    288		goto remove_group;
    289
    290	return 0;
    291
    292remove_group:
    293	sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
    294put_kobj:
    295	kobject_del(&srv_path->kobj);
    296destroy_root:
    297	kobject_put(&srv_path->kobj);
    298	rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
    299
    300	return err;
    301}
    302
    303void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path)
    304{
    305	if (srv_path->kobj.state_in_sysfs) {
    306		kobject_del(&srv_path->stats->kobj_stats);
    307		kobject_put(&srv_path->stats->kobj_stats);
    308		sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
    309		kobject_put(&srv_path->kobj);
    310
    311		rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
    312	}
    313}