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

sysfs.c (23536B)


      1/*
      2 * Copyright (c) 2012 Mellanox Technologies.  All rights reserved.
      3 *
      4 * This software is available to you under a choice of one of two
      5 * licenses.  You may choose to be licensed under the terms of the GNU
      6 * General Public License (GPL) Version 2, available from the file
      7 * COPYING in the main directory of this source tree, or the
      8 * OpenIB.org BSD license below:
      9 *
     10 *     Redistribution and use in source and binary forms, with or
     11 *     without modification, are permitted provided that the following
     12 *     conditions are met:
     13 *
     14 *      - Redistributions of source code must retain the above
     15 *        copyright notice, this list of conditions and the following
     16 *        disclaimer.
     17 *
     18 *      - Redistributions in binary form must reproduce the above
     19 *        copyright notice, this list of conditions and the following
     20 *        disclaimer in the documentation and/or other materials
     21 *        provided with the distribution.
     22 *
     23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     30 * SOFTWARE.
     31 */
     32
     33/*#include "core_priv.h"*/
     34#include "mlx4_ib.h"
     35#include <linux/slab.h>
     36#include <linux/string.h>
     37#include <linux/stat.h>
     38
     39#include <rdma/ib_mad.h>
     40/*show_admin_alias_guid returns the administratively assigned value of that GUID.
     41 * Values returned in buf parameter string:
     42 *	0			- requests opensm to assign a value.
     43 *	ffffffffffffffff	- delete this entry.
     44 *	other			- value assigned by administrator.
     45 */
     46static ssize_t show_admin_alias_guid(struct device *dev,
     47			      struct device_attribute *attr, char *buf)
     48{
     49	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
     50		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
     51	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
     52	struct mlx4_ib_dev *mdev = port->dev;
     53	__be64 sysadmin_ag_val;
     54
     55	sysadmin_ag_val = mlx4_get_admin_guid(mdev->dev,
     56					      mlx4_ib_iov_dentry->entry_num,
     57					      port->num);
     58
     59	return sysfs_emit(buf, "%llx\n", be64_to_cpu(sysadmin_ag_val));
     60}
     61
     62/* store_admin_alias_guid stores the (new) administratively assigned value of that GUID.
     63 * Values in buf parameter string:
     64 *	0			- requests opensm to assign a value.
     65 *	0xffffffffffffffff	- delete this entry.
     66 *	other			- guid value assigned by the administrator.
     67 */
     68static ssize_t store_admin_alias_guid(struct device *dev,
     69				      struct device_attribute *attr,
     70				      const char *buf, size_t count)
     71{
     72	int record_num;/*0-15*/
     73	int guid_index_in_rec; /*0 - 7*/
     74	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
     75		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
     76	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
     77	struct mlx4_ib_dev *mdev = port->dev;
     78	u64 sysadmin_ag_val;
     79	unsigned long flags;
     80
     81	record_num = mlx4_ib_iov_dentry->entry_num / 8;
     82	guid_index_in_rec = mlx4_ib_iov_dentry->entry_num % 8;
     83	if (0 == record_num && 0 == guid_index_in_rec) {
     84		pr_err("GUID 0 block 0 is RO\n");
     85		return count;
     86	}
     87	spin_lock_irqsave(&mdev->sriov.alias_guid.ag_work_lock, flags);
     88	sscanf(buf, "%llx", &sysadmin_ag_val);
     89	*(__be64 *)&mdev->sriov.alias_guid.ports_guid[port->num - 1].
     90		all_rec_per_port[record_num].
     91		all_recs[GUID_REC_SIZE * guid_index_in_rec] =
     92			cpu_to_be64(sysadmin_ag_val);
     93
     94	/* Change the state to be pending for update */
     95	mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].status
     96		= MLX4_GUID_INFO_STATUS_IDLE ;
     97	mlx4_set_admin_guid(mdev->dev, cpu_to_be64(sysadmin_ag_val),
     98			    mlx4_ib_iov_dentry->entry_num,
     99			    port->num);
    100
    101	/* set the record index */
    102	mdev->sriov.alias_guid.ports_guid[port->num - 1].all_rec_per_port[record_num].guid_indexes
    103		|= mlx4_ib_get_aguid_comp_mask_from_ix(guid_index_in_rec);
    104
    105	spin_unlock_irqrestore(&mdev->sriov.alias_guid.ag_work_lock, flags);
    106	mlx4_ib_init_alias_guid_work(mdev, port->num - 1);
    107
    108	return count;
    109}
    110
    111static ssize_t show_port_gid(struct device *dev,
    112			     struct device_attribute *attr,
    113			     char *buf)
    114{
    115	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
    116		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
    117	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
    118	struct mlx4_ib_dev *mdev = port->dev;
    119	union ib_gid gid;
    120	int ret;
    121	__be16 *raw;
    122
    123	ret = __mlx4_ib_query_gid(&mdev->ib_dev, port->num,
    124				  mlx4_ib_iov_dentry->entry_num, &gid, 1);
    125	if (ret)
    126		return ret;
    127
    128	raw = (__be16 *)gid.raw;
    129	return sysfs_emit(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
    130			  be16_to_cpu(raw[0]),
    131			  be16_to_cpu(raw[1]),
    132			  be16_to_cpu(raw[2]),
    133			  be16_to_cpu(raw[3]),
    134			  be16_to_cpu(raw[4]),
    135			  be16_to_cpu(raw[5]),
    136			  be16_to_cpu(raw[6]),
    137			  be16_to_cpu(raw[7]));
    138}
    139
    140static ssize_t show_phys_port_pkey(struct device *dev,
    141				   struct device_attribute *attr,
    142				   char *buf)
    143{
    144	struct mlx4_ib_iov_sysfs_attr *mlx4_ib_iov_dentry =
    145		container_of(attr, struct mlx4_ib_iov_sysfs_attr, dentry);
    146	struct mlx4_ib_iov_port *port = mlx4_ib_iov_dentry->ctx;
    147	struct mlx4_ib_dev *mdev = port->dev;
    148	u16 pkey;
    149	ssize_t ret;
    150
    151	ret = __mlx4_ib_query_pkey(&mdev->ib_dev, port->num,
    152				   mlx4_ib_iov_dentry->entry_num, &pkey, 1);
    153	if (ret)
    154		return ret;
    155
    156	return sysfs_emit(buf, "0x%04x\n", pkey);
    157}
    158
    159#define DENTRY_REMOVE(_dentry)						\
    160do {									\
    161	sysfs_remove_file((_dentry)->kobj, &(_dentry)->dentry.attr);	\
    162} while (0);
    163
    164static int create_sysfs_entry(void *_ctx, struct mlx4_ib_iov_sysfs_attr *_dentry,
    165			      char *_name, struct kobject *_kobj,
    166			      ssize_t (*show)(struct device *dev,
    167					      struct device_attribute *attr,
    168					      char *buf),
    169			      ssize_t (*store)(struct device *dev,
    170					       struct device_attribute *attr,
    171					       const char *buf, size_t count)
    172			      )
    173{
    174	int ret = 0;
    175	struct mlx4_ib_iov_sysfs_attr *vdentry = _dentry;
    176
    177	vdentry->ctx = _ctx;
    178	vdentry->dentry.show = show;
    179	vdentry->dentry.store = store;
    180	sysfs_attr_init(&vdentry->dentry.attr);
    181	vdentry->dentry.attr.name = vdentry->name;
    182	vdentry->dentry.attr.mode = 0;
    183	vdentry->kobj = _kobj;
    184	snprintf(vdentry->name, 15, "%s", _name);
    185
    186	if (vdentry->dentry.store)
    187		vdentry->dentry.attr.mode |= S_IWUSR;
    188
    189	if (vdentry->dentry.show)
    190		vdentry->dentry.attr.mode |= S_IRUGO;
    191
    192	ret = sysfs_create_file(vdentry->kobj, &vdentry->dentry.attr);
    193	if (ret) {
    194		pr_err("failed to create %s\n", vdentry->dentry.attr.name);
    195		vdentry->ctx = NULL;
    196		return ret;
    197	}
    198
    199	return ret;
    200}
    201
    202int add_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
    203		struct attribute *attr)
    204{
    205	struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
    206	int ret;
    207
    208	ret = sysfs_create_file(port->mcgs_parent, attr);
    209	if (ret)
    210		pr_err("failed to create %s\n", attr->name);
    211
    212	return ret;
    213}
    214
    215void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
    216		struct attribute *attr)
    217{
    218	struct mlx4_ib_iov_port *port = &device->iov_ports[port_num - 1];
    219
    220	sysfs_remove_file(port->mcgs_parent, attr);
    221}
    222
    223static int add_port_entries(struct mlx4_ib_dev *device, int port_num)
    224{
    225	int i;
    226	char buff[11];
    227	struct mlx4_ib_iov_port *port = NULL;
    228	int ret = 0 ;
    229	struct ib_port_attr attr;
    230
    231	memset(&attr, 0, sizeof(attr));
    232	/* get the physical gid and pkey table sizes.*/
    233	ret = __mlx4_ib_query_port(&device->ib_dev, port_num, &attr, 1);
    234	if (ret)
    235		goto err;
    236
    237	port = &device->iov_ports[port_num - 1];
    238	port->dev = device;
    239	port->num = port_num;
    240	/* Directory structure:
    241	 * iov -
    242	 *   port num -
    243	 *	admin_guids
    244	 *	gids (operational)
    245	 *	mcg_table
    246	 */
    247	port->dentr_ar = kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar),
    248				 GFP_KERNEL);
    249	if (!port->dentr_ar) {
    250		ret = -ENOMEM;
    251		goto err;
    252	}
    253	sprintf(buff, "%d", port_num);
    254	port->cur_port = kobject_create_and_add(buff,
    255				 kobject_get(device->ports_parent));
    256	if (!port->cur_port) {
    257		ret = -ENOMEM;
    258		goto kobj_create_err;
    259	}
    260	/* admin GUIDs */
    261	port->admin_alias_parent = kobject_create_and_add("admin_guids",
    262						  kobject_get(port->cur_port));
    263	if (!port->admin_alias_parent) {
    264		ret = -ENOMEM;
    265		goto err_admin_guids;
    266	}
    267	for (i = 0 ; i < attr.gid_tbl_len; i++) {
    268		sprintf(buff, "%d", i);
    269		port->dentr_ar->dentries[i].entry_num = i;
    270		ret = create_sysfs_entry(port, &port->dentr_ar->dentries[i],
    271					  buff, port->admin_alias_parent,
    272					  show_admin_alias_guid, store_admin_alias_guid);
    273		if (ret)
    274			goto err_admin_alias_parent;
    275	}
    276
    277	/* gids subdirectory (operational gids) */
    278	port->gids_parent = kobject_create_and_add("gids",
    279						  kobject_get(port->cur_port));
    280	if (!port->gids_parent) {
    281		ret = -ENOMEM;
    282		goto err_gids;
    283	}
    284
    285	for (i = 0 ; i < attr.gid_tbl_len; i++) {
    286		sprintf(buff, "%d", i);
    287		port->dentr_ar->dentries[attr.gid_tbl_len + i].entry_num = i;
    288		ret = create_sysfs_entry(port,
    289					 &port->dentr_ar->dentries[attr.gid_tbl_len + i],
    290					 buff,
    291					 port->gids_parent, show_port_gid, NULL);
    292		if (ret)
    293			goto err_gids_parent;
    294	}
    295
    296	/* physical port pkey table */
    297	port->pkeys_parent =
    298		kobject_create_and_add("pkeys", kobject_get(port->cur_port));
    299	if (!port->pkeys_parent) {
    300		ret = -ENOMEM;
    301		goto err_pkeys;
    302	}
    303
    304	for (i = 0 ; i < attr.pkey_tbl_len; i++) {
    305		sprintf(buff, "%d", i);
    306		port->dentr_ar->dentries[2 * attr.gid_tbl_len + i].entry_num = i;
    307		ret = create_sysfs_entry(port,
    308					 &port->dentr_ar->dentries[2 * attr.gid_tbl_len + i],
    309					 buff, port->pkeys_parent,
    310					 show_phys_port_pkey, NULL);
    311		if (ret)
    312			goto err_pkeys_parent;
    313	}
    314
    315	/* MCGs table */
    316	port->mcgs_parent =
    317		kobject_create_and_add("mcgs", kobject_get(port->cur_port));
    318	if (!port->mcgs_parent) {
    319		ret = -ENOMEM;
    320		goto err_mcgs;
    321	}
    322	return 0;
    323
    324err_mcgs:
    325	kobject_put(port->cur_port);
    326
    327err_pkeys_parent:
    328	kobject_put(port->pkeys_parent);
    329
    330err_pkeys:
    331	kobject_put(port->cur_port);
    332
    333err_gids_parent:
    334	kobject_put(port->gids_parent);
    335
    336err_gids:
    337	kobject_put(port->cur_port);
    338
    339err_admin_alias_parent:
    340	kobject_put(port->admin_alias_parent);
    341
    342err_admin_guids:
    343	kobject_put(port->cur_port);
    344	kobject_put(port->cur_port); /* once more for create_and_add buff */
    345
    346kobj_create_err:
    347	kobject_put(device->ports_parent);
    348	kfree(port->dentr_ar);
    349
    350err:
    351	pr_err("add_port_entries FAILED: for port:%d, error: %d\n",
    352	       port_num, ret);
    353	return ret;
    354}
    355
    356static void get_name(struct mlx4_ib_dev *dev, char *name, int i, int max)
    357{
    358	/* pci_name format is: bus:dev:func -> xxxx:yy:zz.n
    359	 * with no ARI only 3 last bits are used so when the fn is higher than 8
    360	 * need to add it to the dev num, so count in the last number will be
    361	 * modulo 8 */
    362	snprintf(name, max, "%.8s%.2d.%d", pci_name(dev->dev->persist->pdev),
    363		 i / 8, i % 8);
    364}
    365
    366struct mlx4_port {
    367	struct kobject         kobj;
    368	struct mlx4_ib_dev    *dev;
    369	struct attribute_group pkey_group;
    370	struct attribute_group gid_group;
    371	struct device_attribute	enable_smi_admin;
    372	struct device_attribute	smi_enabled;
    373	int		       slave;
    374	u8                     port_num;
    375};
    376
    377
    378static void mlx4_port_release(struct kobject *kobj)
    379{
    380	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
    381	struct attribute *a;
    382	int i;
    383
    384	for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
    385		kfree(a);
    386	kfree(p->pkey_group.attrs);
    387	for (i = 0; (a = p->gid_group.attrs[i]); ++i)
    388		kfree(a);
    389	kfree(p->gid_group.attrs);
    390	kfree(p);
    391}
    392
    393struct port_attribute {
    394	struct attribute attr;
    395	ssize_t (*show)(struct mlx4_port *, struct port_attribute *, char *buf);
    396	ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
    397			 const char *buf, size_t count);
    398};
    399
    400static ssize_t port_attr_show(struct kobject *kobj,
    401			      struct attribute *attr, char *buf)
    402{
    403	struct port_attribute *port_attr =
    404		container_of(attr, struct port_attribute, attr);
    405	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
    406
    407	if (!port_attr->show)
    408		return -EIO;
    409	return port_attr->show(p, port_attr, buf);
    410}
    411
    412static ssize_t port_attr_store(struct kobject *kobj,
    413			       struct attribute *attr,
    414			       const char *buf, size_t size)
    415{
    416	struct port_attribute *port_attr =
    417		container_of(attr, struct port_attribute, attr);
    418	struct mlx4_port *p = container_of(kobj, struct mlx4_port, kobj);
    419
    420	if (!port_attr->store)
    421		return -EIO;
    422	return port_attr->store(p, port_attr, buf, size);
    423}
    424
    425static const struct sysfs_ops port_sysfs_ops = {
    426	.show = port_attr_show,
    427	.store = port_attr_store,
    428};
    429
    430static struct kobj_type port_type = {
    431	.release    = mlx4_port_release,
    432	.sysfs_ops  = &port_sysfs_ops,
    433};
    434
    435struct port_table_attribute {
    436	struct port_attribute	attr;
    437	char			name[8];
    438	int			index;
    439};
    440
    441static ssize_t show_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
    442			      char *buf)
    443{
    444	struct port_table_attribute *tab_attr =
    445		container_of(attr, struct port_table_attribute, attr);
    446	struct pkey_mgt *m = &p->dev->pkeys;
    447	u8 key = m->virt2phys_pkey[p->slave][p->port_num - 1][tab_attr->index];
    448
    449	if (key >= p->dev->dev->caps.pkey_table_len[p->port_num])
    450		return sysfs_emit(buf, "none\n");
    451	return sysfs_emit(buf, "%d\n", key);
    452}
    453
    454static ssize_t store_port_pkey(struct mlx4_port *p, struct port_attribute *attr,
    455			       const char *buf, size_t count)
    456{
    457	struct port_table_attribute *tab_attr =
    458		container_of(attr, struct port_table_attribute, attr);
    459	int idx;
    460	int err;
    461
    462	/* do not allow remapping Dom0 virtual pkey table */
    463	if (p->slave == mlx4_master_func_num(p->dev->dev))
    464		return -EINVAL;
    465
    466	if (!strncasecmp(buf, "no", 2))
    467		idx = p->dev->dev->phys_caps.pkey_phys_table_len[p->port_num] - 1;
    468	else if (sscanf(buf, "%i", &idx) != 1 ||
    469		 idx >= p->dev->dev->caps.pkey_table_len[p->port_num] ||
    470		 idx < 0)
    471		return -EINVAL;
    472
    473	p->dev->pkeys.virt2phys_pkey[p->slave][p->port_num - 1]
    474				    [tab_attr->index] = idx;
    475	mlx4_sync_pkey_table(p->dev->dev, p->slave, p->port_num,
    476			     tab_attr->index, idx);
    477	err = mlx4_gen_pkey_eqe(p->dev->dev, p->slave, p->port_num);
    478	if (err) {
    479		pr_err("mlx4_gen_pkey_eqe failed for slave %d,"
    480		       " port %d, index %d\n", p->slave, p->port_num, idx);
    481		return err;
    482	}
    483	return count;
    484}
    485
    486static ssize_t show_port_gid_idx(struct mlx4_port *p,
    487				 struct port_attribute *attr, char *buf)
    488{
    489	return sysfs_emit(buf, "%d\n", p->slave);
    490}
    491
    492static struct attribute **
    493alloc_group_attrs(ssize_t (*show)(struct mlx4_port *,
    494				  struct port_attribute *, char *buf),
    495		  ssize_t (*store)(struct mlx4_port *, struct port_attribute *,
    496				   const char *buf, size_t count),
    497		  int len)
    498{
    499	struct attribute **tab_attr;
    500	struct port_table_attribute *element;
    501	int i;
    502
    503	tab_attr = kcalloc(1 + len, sizeof (struct attribute *), GFP_KERNEL);
    504	if (!tab_attr)
    505		return NULL;
    506
    507	for (i = 0; i < len; i++) {
    508		element = kzalloc(sizeof (struct port_table_attribute),
    509				  GFP_KERNEL);
    510		if (!element)
    511			goto err;
    512		if (snprintf(element->name, sizeof (element->name),
    513			     "%d", i) >= sizeof (element->name)) {
    514			kfree(element);
    515			goto err;
    516		}
    517		sysfs_attr_init(&element->attr.attr);
    518		element->attr.attr.name  = element->name;
    519		if (store) {
    520			element->attr.attr.mode  = S_IWUSR | S_IRUGO;
    521			element->attr.store	 = store;
    522		} else
    523			element->attr.attr.mode  = S_IRUGO;
    524
    525		element->attr.show       = show;
    526		element->index		 = i;
    527		tab_attr[i] = &element->attr.attr;
    528	}
    529	return tab_attr;
    530
    531err:
    532	while (--i >= 0)
    533		kfree(tab_attr[i]);
    534	kfree(tab_attr);
    535	return NULL;
    536}
    537
    538static ssize_t sysfs_show_smi_enabled(struct device *dev,
    539				      struct device_attribute *attr, char *buf)
    540{
    541	struct mlx4_port *p =
    542		container_of(attr, struct mlx4_port, smi_enabled);
    543
    544	return sysfs_emit(buf, "%d\n",
    545			  !!mlx4_vf_smi_enabled(p->dev->dev, p->slave,
    546						p->port_num));
    547}
    548
    549static ssize_t sysfs_show_enable_smi_admin(struct device *dev,
    550					   struct device_attribute *attr,
    551					   char *buf)
    552{
    553	struct mlx4_port *p =
    554		container_of(attr, struct mlx4_port, enable_smi_admin);
    555
    556	return sysfs_emit(buf, "%d\n",
    557			  !!mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave,
    558							 p->port_num));
    559}
    560
    561static ssize_t sysfs_store_enable_smi_admin(struct device *dev,
    562					    struct device_attribute *attr,
    563					    const char *buf, size_t count)
    564{
    565	struct mlx4_port *p =
    566		container_of(attr, struct mlx4_port, enable_smi_admin);
    567	int enable;
    568
    569	if (sscanf(buf, "%i", &enable) != 1 ||
    570	    enable < 0 || enable > 1)
    571		return -EINVAL;
    572
    573	if (mlx4_vf_set_enable_smi_admin(p->dev->dev, p->slave, p->port_num, enable))
    574		return -EINVAL;
    575	return count;
    576}
    577
    578static int add_vf_smi_entries(struct mlx4_port *p)
    579{
    580	int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
    581			IB_LINK_LAYER_ETHERNET;
    582	int ret;
    583
    584	/* do not display entries if eth transport, or if master */
    585	if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
    586		return 0;
    587
    588	sysfs_attr_init(&p->smi_enabled.attr);
    589	p->smi_enabled.show = sysfs_show_smi_enabled;
    590	p->smi_enabled.store = NULL;
    591	p->smi_enabled.attr.name = "smi_enabled";
    592	p->smi_enabled.attr.mode = 0444;
    593	ret = sysfs_create_file(&p->kobj, &p->smi_enabled.attr);
    594	if (ret) {
    595		pr_err("failed to create smi_enabled\n");
    596		return ret;
    597	}
    598
    599	sysfs_attr_init(&p->enable_smi_admin.attr);
    600	p->enable_smi_admin.show = sysfs_show_enable_smi_admin;
    601	p->enable_smi_admin.store = sysfs_store_enable_smi_admin;
    602	p->enable_smi_admin.attr.name = "enable_smi_admin";
    603	p->enable_smi_admin.attr.mode = 0644;
    604	ret = sysfs_create_file(&p->kobj, &p->enable_smi_admin.attr);
    605	if (ret) {
    606		pr_err("failed to create enable_smi_admin\n");
    607		sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
    608		return ret;
    609	}
    610	return 0;
    611}
    612
    613static void remove_vf_smi_entries(struct mlx4_port *p)
    614{
    615	int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) ==
    616			IB_LINK_LAYER_ETHERNET;
    617
    618	if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev))
    619		return;
    620
    621	sysfs_remove_file(&p->kobj, &p->smi_enabled.attr);
    622	sysfs_remove_file(&p->kobj, &p->enable_smi_admin.attr);
    623}
    624
    625static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
    626{
    627	struct mlx4_port *p;
    628	int i;
    629	int ret;
    630	int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) ==
    631			IB_LINK_LAYER_ETHERNET;
    632
    633	p = kzalloc(sizeof *p, GFP_KERNEL);
    634	if (!p)
    635		return -ENOMEM;
    636
    637	p->dev = dev;
    638	p->port_num = port_num;
    639	p->slave = slave;
    640
    641	ret = kobject_init_and_add(&p->kobj, &port_type,
    642				   kobject_get(dev->dev_ports_parent[slave]),
    643				   "%d", port_num);
    644	if (ret)
    645		goto err_alloc;
    646
    647	p->pkey_group.name  = "pkey_idx";
    648	p->pkey_group.attrs =
    649		alloc_group_attrs(show_port_pkey,
    650				  is_eth ? NULL : store_port_pkey,
    651				  dev->dev->caps.pkey_table_len[port_num]);
    652	if (!p->pkey_group.attrs) {
    653		ret = -ENOMEM;
    654		goto err_alloc;
    655	}
    656
    657	ret = sysfs_create_group(&p->kobj, &p->pkey_group);
    658	if (ret)
    659		goto err_free_pkey;
    660
    661	p->gid_group.name  = "gid_idx";
    662	p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
    663	if (!p->gid_group.attrs) {
    664		ret = -ENOMEM;
    665		goto err_free_pkey;
    666	}
    667
    668	ret = sysfs_create_group(&p->kobj, &p->gid_group);
    669	if (ret)
    670		goto err_free_gid;
    671
    672	ret = add_vf_smi_entries(p);
    673	if (ret)
    674		goto err_free_gid;
    675
    676	list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]);
    677	return 0;
    678
    679err_free_gid:
    680	kfree(p->gid_group.attrs[0]);
    681	kfree(p->gid_group.attrs);
    682
    683err_free_pkey:
    684	for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i)
    685		kfree(p->pkey_group.attrs[i]);
    686	kfree(p->pkey_group.attrs);
    687
    688err_alloc:
    689	kobject_put(dev->dev_ports_parent[slave]);
    690	kfree(p);
    691	return ret;
    692}
    693
    694static int register_one_pkey_tree(struct mlx4_ib_dev *dev, int slave)
    695{
    696	char name[32];
    697	int err;
    698	int port;
    699	struct kobject *p, *t;
    700	struct mlx4_port *mport;
    701	struct mlx4_active_ports actv_ports;
    702
    703	get_name(dev, name, slave, sizeof name);
    704
    705	dev->pkeys.device_parent[slave] =
    706		kobject_create_and_add(name, kobject_get(dev->iov_parent));
    707
    708	if (!dev->pkeys.device_parent[slave]) {
    709		err = -ENOMEM;
    710		goto fail_dev;
    711	}
    712
    713	INIT_LIST_HEAD(&dev->pkeys.pkey_port_list[slave]);
    714
    715	dev->dev_ports_parent[slave] =
    716		kobject_create_and_add("ports",
    717				       kobject_get(dev->pkeys.device_parent[slave]));
    718
    719	if (!dev->dev_ports_parent[slave]) {
    720		err = -ENOMEM;
    721		goto err_ports;
    722	}
    723
    724	actv_ports = mlx4_get_active_ports(dev->dev, slave);
    725
    726	for (port = 1; port <= dev->dev->caps.num_ports; ++port) {
    727		if (!test_bit(port - 1, actv_ports.ports))
    728			continue;
    729		err = add_port(dev, port, slave);
    730		if (err)
    731			goto err_add;
    732	}
    733	return 0;
    734
    735err_add:
    736	list_for_each_entry_safe(p, t,
    737				 &dev->pkeys.pkey_port_list[slave],
    738				 entry) {
    739		list_del(&p->entry);
    740		mport = container_of(p, struct mlx4_port, kobj);
    741		sysfs_remove_group(p, &mport->pkey_group);
    742		sysfs_remove_group(p, &mport->gid_group);
    743		remove_vf_smi_entries(mport);
    744		kobject_put(p);
    745	}
    746	kobject_put(dev->dev_ports_parent[slave]);
    747
    748err_ports:
    749	kobject_put(dev->pkeys.device_parent[slave]);
    750	/* extra put for the device_parent create_and_add */
    751	kobject_put(dev->pkeys.device_parent[slave]);
    752
    753fail_dev:
    754	kobject_put(dev->iov_parent);
    755	return err;
    756}
    757
    758static int register_pkey_tree(struct mlx4_ib_dev *device)
    759{
    760	int i;
    761
    762	if (!mlx4_is_master(device->dev))
    763		return 0;
    764
    765	for (i = 0; i <= device->dev->persist->num_vfs; ++i)
    766		register_one_pkey_tree(device, i);
    767
    768	return 0;
    769}
    770
    771static void unregister_pkey_tree(struct mlx4_ib_dev *device)
    772{
    773	int slave;
    774	struct kobject *p, *t;
    775	struct mlx4_port *port;
    776
    777	if (!mlx4_is_master(device->dev))
    778		return;
    779
    780	for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) {
    781		list_for_each_entry_safe(p, t,
    782					 &device->pkeys.pkey_port_list[slave],
    783					 entry) {
    784			list_del(&p->entry);
    785			port = container_of(p, struct mlx4_port, kobj);
    786			sysfs_remove_group(p, &port->pkey_group);
    787			sysfs_remove_group(p, &port->gid_group);
    788			remove_vf_smi_entries(port);
    789			kobject_put(p);
    790			kobject_put(device->dev_ports_parent[slave]);
    791		}
    792		kobject_put(device->dev_ports_parent[slave]);
    793		kobject_put(device->pkeys.device_parent[slave]);
    794		kobject_put(device->pkeys.device_parent[slave]);
    795		kobject_put(device->iov_parent);
    796	}
    797}
    798
    799int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *dev)
    800{
    801	unsigned int i;
    802	int ret = 0;
    803
    804	if (!mlx4_is_master(dev->dev))
    805		return 0;
    806
    807	dev->iov_parent = kobject_create_and_add("iov", &dev->ib_dev.dev.kobj);
    808	if (!dev->iov_parent) {
    809		ret = -ENOMEM;
    810		goto err;
    811	}
    812	dev->ports_parent =
    813		kobject_create_and_add("ports",
    814				       kobject_get(dev->iov_parent));
    815	if (!dev->ports_parent) {
    816		ret = -ENOMEM;
    817		goto err_ports;
    818	}
    819
    820	rdma_for_each_port(&dev->ib_dev, i) {
    821		ret = add_port_entries(dev, i);
    822		if (ret)
    823			goto err_add_entries;
    824	}
    825
    826	ret = register_pkey_tree(dev);
    827	if (ret)
    828		goto err_add_entries;
    829	return 0;
    830
    831err_add_entries:
    832	kobject_put(dev->ports_parent);
    833
    834err_ports:
    835	kobject_put(dev->iov_parent);
    836err:
    837	pr_err("mlx4_ib_device_register_sysfs error (%d)\n", ret);
    838	return ret;
    839}
    840
    841static void unregister_alias_guid_tree(struct mlx4_ib_dev *device)
    842{
    843	struct mlx4_ib_iov_port *p;
    844	int i;
    845
    846	if (!mlx4_is_master(device->dev))
    847		return;
    848
    849	for (i = 0; i < device->dev->caps.num_ports; i++) {
    850		p = &device->iov_ports[i];
    851		kobject_put(p->admin_alias_parent);
    852		kobject_put(p->gids_parent);
    853		kobject_put(p->pkeys_parent);
    854		kobject_put(p->mcgs_parent);
    855		kobject_put(p->cur_port);
    856		kobject_put(p->cur_port);
    857		kobject_put(p->cur_port);
    858		kobject_put(p->cur_port);
    859		kobject_put(p->cur_port);
    860		kobject_put(p->dev->ports_parent);
    861		kfree(p->dentr_ar);
    862	}
    863}
    864
    865void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev *device)
    866{
    867	unregister_alias_guid_tree(device);
    868	unregister_pkey_tree(device);
    869	kobject_put(device->ports_parent);
    870	kobject_put(device->iov_parent);
    871	kobject_put(device->iov_parent);
    872}