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

configfs_sample.c (9137B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * configfs_example_macros.c - This file is a demonstration module
      4 *      containing a number of configfs subsystems.  It uses the helper
      5 *      macros defined by configfs.h
      6 *
      7 * Based on sysfs:
      8 *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
      9 *
     10 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
     11 */
     12
     13#include <linux/init.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/slab.h>
     17#include <linux/configfs.h>
     18
     19/*
     20 * 01-childless
     21 *
     22 * This first example is a childless subsystem.  It cannot create
     23 * any config_items.  It just has attributes.
     24 *
     25 * Note that we are enclosing the configfs_subsystem inside a container.
     26 * This is not necessary if a subsystem has no attributes directly
     27 * on the subsystem.  See the next example, 02-simple-children, for
     28 * such a subsystem.
     29 */
     30
     31struct childless {
     32	struct configfs_subsystem subsys;
     33	int showme;
     34	int storeme;
     35};
     36
     37static inline struct childless *to_childless(struct config_item *item)
     38{
     39	return container_of(to_configfs_subsystem(to_config_group(item)),
     40			    struct childless, subsys);
     41}
     42
     43static ssize_t childless_showme_show(struct config_item *item, char *page)
     44{
     45	struct childless *childless = to_childless(item);
     46	ssize_t pos;
     47
     48	pos = sprintf(page, "%d\n", childless->showme);
     49	childless->showme++;
     50
     51	return pos;
     52}
     53
     54static ssize_t childless_storeme_show(struct config_item *item, char *page)
     55{
     56	return sprintf(page, "%d\n", to_childless(item)->storeme);
     57}
     58
     59static ssize_t childless_storeme_store(struct config_item *item,
     60		const char *page, size_t count)
     61{
     62	struct childless *childless = to_childless(item);
     63	int ret;
     64
     65	ret = kstrtoint(page, 10, &childless->storeme);
     66	if (ret)
     67		return ret;
     68
     69	return count;
     70}
     71
     72static ssize_t childless_description_show(struct config_item *item, char *page)
     73{
     74	return sprintf(page,
     75"[01-childless]\n"
     76"\n"
     77"The childless subsystem is the simplest possible subsystem in\n"
     78"configfs.  It does not support the creation of child config_items.\n"
     79"It only has a few attributes.  In fact, it isn't much different\n"
     80"than a directory in /proc.\n");
     81}
     82
     83CONFIGFS_ATTR_RO(childless_, showme);
     84CONFIGFS_ATTR(childless_, storeme);
     85CONFIGFS_ATTR_RO(childless_, description);
     86
     87static struct configfs_attribute *childless_attrs[] = {
     88	&childless_attr_showme,
     89	&childless_attr_storeme,
     90	&childless_attr_description,
     91	NULL,
     92};
     93
     94static const struct config_item_type childless_type = {
     95	.ct_attrs	= childless_attrs,
     96	.ct_owner	= THIS_MODULE,
     97};
     98
     99static struct childless childless_subsys = {
    100	.subsys = {
    101		.su_group = {
    102			.cg_item = {
    103				.ci_namebuf = "01-childless",
    104				.ci_type = &childless_type,
    105			},
    106		},
    107	},
    108};
    109
    110/* ----------------------------------------------------------------- */
    111
    112/*
    113 * 02-simple-children
    114 *
    115 * This example merely has a simple one-attribute child.  Note that
    116 * there is no extra attribute structure, as the child's attribute is
    117 * known from the get-go.  Also, there is no container for the
    118 * subsystem, as it has no attributes of its own.
    119 */
    120
    121struct simple_child {
    122	struct config_item item;
    123	int storeme;
    124};
    125
    126static inline struct simple_child *to_simple_child(struct config_item *item)
    127{
    128	return container_of(item, struct simple_child, item);
    129}
    130
    131static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
    132{
    133	return sprintf(page, "%d\n", to_simple_child(item)->storeme);
    134}
    135
    136static ssize_t simple_child_storeme_store(struct config_item *item,
    137		const char *page, size_t count)
    138{
    139	struct simple_child *simple_child = to_simple_child(item);
    140	int ret;
    141
    142	ret = kstrtoint(page, 10, &simple_child->storeme);
    143	if (ret)
    144		return ret;
    145
    146	return count;
    147}
    148
    149CONFIGFS_ATTR(simple_child_, storeme);
    150
    151static struct configfs_attribute *simple_child_attrs[] = {
    152	&simple_child_attr_storeme,
    153	NULL,
    154};
    155
    156static void simple_child_release(struct config_item *item)
    157{
    158	kfree(to_simple_child(item));
    159}
    160
    161static struct configfs_item_operations simple_child_item_ops = {
    162	.release	= simple_child_release,
    163};
    164
    165static const struct config_item_type simple_child_type = {
    166	.ct_item_ops	= &simple_child_item_ops,
    167	.ct_attrs	= simple_child_attrs,
    168	.ct_owner	= THIS_MODULE,
    169};
    170
    171struct simple_children {
    172	struct config_group group;
    173};
    174
    175static inline struct simple_children *to_simple_children(struct config_item *item)
    176{
    177	return container_of(to_config_group(item),
    178			    struct simple_children, group);
    179}
    180
    181static struct config_item *simple_children_make_item(struct config_group *group,
    182		const char *name)
    183{
    184	struct simple_child *simple_child;
    185
    186	simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
    187	if (!simple_child)
    188		return ERR_PTR(-ENOMEM);
    189
    190	config_item_init_type_name(&simple_child->item, name,
    191				   &simple_child_type);
    192
    193	return &simple_child->item;
    194}
    195
    196static ssize_t simple_children_description_show(struct config_item *item,
    197		char *page)
    198{
    199	return sprintf(page,
    200"[02-simple-children]\n"
    201"\n"
    202"This subsystem allows the creation of child config_items.  These\n"
    203"items have only one attribute that is readable and writeable.\n");
    204}
    205
    206CONFIGFS_ATTR_RO(simple_children_, description);
    207
    208static struct configfs_attribute *simple_children_attrs[] = {
    209	&simple_children_attr_description,
    210	NULL,
    211};
    212
    213static void simple_children_release(struct config_item *item)
    214{
    215	kfree(to_simple_children(item));
    216}
    217
    218static struct configfs_item_operations simple_children_item_ops = {
    219	.release	= simple_children_release,
    220};
    221
    222/*
    223 * Note that, since no extra work is required on ->drop_item(),
    224 * no ->drop_item() is provided.
    225 */
    226static struct configfs_group_operations simple_children_group_ops = {
    227	.make_item	= simple_children_make_item,
    228};
    229
    230static const struct config_item_type simple_children_type = {
    231	.ct_item_ops	= &simple_children_item_ops,
    232	.ct_group_ops	= &simple_children_group_ops,
    233	.ct_attrs	= simple_children_attrs,
    234	.ct_owner	= THIS_MODULE,
    235};
    236
    237static struct configfs_subsystem simple_children_subsys = {
    238	.su_group = {
    239		.cg_item = {
    240			.ci_namebuf = "02-simple-children",
    241			.ci_type = &simple_children_type,
    242		},
    243	},
    244};
    245
    246/* ----------------------------------------------------------------- */
    247
    248/*
    249 * 03-group-children
    250 *
    251 * This example reuses the simple_children group from above.  However,
    252 * the simple_children group is not the subsystem itself, it is a
    253 * child of the subsystem.  Creation of a group in the subsystem creates
    254 * a new simple_children group.  That group can then have simple_child
    255 * children of its own.
    256 */
    257
    258static struct config_group *group_children_make_group(
    259		struct config_group *group, const char *name)
    260{
    261	struct simple_children *simple_children;
    262
    263	simple_children = kzalloc(sizeof(struct simple_children),
    264				  GFP_KERNEL);
    265	if (!simple_children)
    266		return ERR_PTR(-ENOMEM);
    267
    268	config_group_init_type_name(&simple_children->group, name,
    269				    &simple_children_type);
    270
    271	return &simple_children->group;
    272}
    273
    274static ssize_t group_children_description_show(struct config_item *item,
    275		char *page)
    276{
    277	return sprintf(page,
    278"[03-group-children]\n"
    279"\n"
    280"This subsystem allows the creation of child config_groups.  These\n"
    281"groups are like the subsystem simple-children.\n");
    282}
    283
    284CONFIGFS_ATTR_RO(group_children_, description);
    285
    286static struct configfs_attribute *group_children_attrs[] = {
    287	&group_children_attr_description,
    288	NULL,
    289};
    290
    291/*
    292 * Note that, since no extra work is required on ->drop_item(),
    293 * no ->drop_item() is provided.
    294 */
    295static struct configfs_group_operations group_children_group_ops = {
    296	.make_group	= group_children_make_group,
    297};
    298
    299static const struct config_item_type group_children_type = {
    300	.ct_group_ops	= &group_children_group_ops,
    301	.ct_attrs	= group_children_attrs,
    302	.ct_owner	= THIS_MODULE,
    303};
    304
    305static struct configfs_subsystem group_children_subsys = {
    306	.su_group = {
    307		.cg_item = {
    308			.ci_namebuf = "03-group-children",
    309			.ci_type = &group_children_type,
    310		},
    311	},
    312};
    313
    314/* ----------------------------------------------------------------- */
    315
    316/*
    317 * We're now done with our subsystem definitions.
    318 * For convenience in this module, here's a list of them all.  It
    319 * allows the init function to easily register them.  Most modules
    320 * will only have one subsystem, and will only call register_subsystem
    321 * on it directly.
    322 */
    323static struct configfs_subsystem *example_subsys[] = {
    324	&childless_subsys.subsys,
    325	&simple_children_subsys,
    326	&group_children_subsys,
    327	NULL,
    328};
    329
    330static int __init configfs_example_init(void)
    331{
    332	struct configfs_subsystem *subsys;
    333	int ret, i;
    334
    335	for (i = 0; example_subsys[i]; i++) {
    336		subsys = example_subsys[i];
    337
    338		config_group_init(&subsys->su_group);
    339		mutex_init(&subsys->su_mutex);
    340		ret = configfs_register_subsystem(subsys);
    341		if (ret) {
    342			pr_err("Error %d while registering subsystem %s\n",
    343			       ret, subsys->su_group.cg_item.ci_namebuf);
    344			goto out_unregister;
    345		}
    346	}
    347
    348	return 0;
    349
    350out_unregister:
    351	for (i--; i >= 0; i--)
    352		configfs_unregister_subsystem(example_subsys[i]);
    353
    354	return ret;
    355}
    356
    357static void __exit configfs_example_exit(void)
    358{
    359	int i;
    360
    361	for (i = 0; example_subsys[i]; i++)
    362		configfs_unregister_subsystem(example_subsys[i]);
    363}
    364
    365module_init(configfs_example_init);
    366module_exit(configfs_example_exit);
    367MODULE_LICENSE("GPL");