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

params.c (23634B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* Helpers for initial module or kernel cmdline parsing
      3   Copyright (C) 2001 Rusty Russell.
      4
      5*/
      6#include <linux/kernel.h>
      7#include <linux/string.h>
      8#include <linux/errno.h>
      9#include <linux/module.h>
     10#include <linux/moduleparam.h>
     11#include <linux/device.h>
     12#include <linux/err.h>
     13#include <linux/slab.h>
     14#include <linux/ctype.h>
     15#include <linux/security.h>
     16
     17#ifdef CONFIG_SYSFS
     18/* Protects all built-in parameters, modules use their own param_lock */
     19static DEFINE_MUTEX(param_lock);
     20
     21/* Use the module's mutex, or if built-in use the built-in mutex */
     22#ifdef CONFIG_MODULES
     23#define KPARAM_MUTEX(mod)	((mod) ? &(mod)->param_lock : &param_lock)
     24#else
     25#define KPARAM_MUTEX(mod)	(&param_lock)
     26#endif
     27
     28static inline void check_kparam_locked(struct module *mod)
     29{
     30	BUG_ON(!mutex_is_locked(KPARAM_MUTEX(mod)));
     31}
     32#else
     33static inline void check_kparam_locked(struct module *mod)
     34{
     35}
     36#endif /* !CONFIG_SYSFS */
     37
     38/* This just allows us to keep track of which parameters are kmalloced. */
     39struct kmalloced_param {
     40	struct list_head list;
     41	char val[];
     42};
     43static LIST_HEAD(kmalloced_params);
     44static DEFINE_SPINLOCK(kmalloced_params_lock);
     45
     46static void *kmalloc_parameter(unsigned int size)
     47{
     48	struct kmalloced_param *p;
     49
     50	p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
     51	if (!p)
     52		return NULL;
     53
     54	spin_lock(&kmalloced_params_lock);
     55	list_add(&p->list, &kmalloced_params);
     56	spin_unlock(&kmalloced_params_lock);
     57
     58	return p->val;
     59}
     60
     61/* Does nothing if parameter wasn't kmalloced above. */
     62static void maybe_kfree_parameter(void *param)
     63{
     64	struct kmalloced_param *p;
     65
     66	spin_lock(&kmalloced_params_lock);
     67	list_for_each_entry(p, &kmalloced_params, list) {
     68		if (p->val == param) {
     69			list_del(&p->list);
     70			kfree(p);
     71			break;
     72		}
     73	}
     74	spin_unlock(&kmalloced_params_lock);
     75}
     76
     77static char dash2underscore(char c)
     78{
     79	if (c == '-')
     80		return '_';
     81	return c;
     82}
     83
     84bool parameqn(const char *a, const char *b, size_t n)
     85{
     86	size_t i;
     87
     88	for (i = 0; i < n; i++) {
     89		if (dash2underscore(a[i]) != dash2underscore(b[i]))
     90			return false;
     91	}
     92	return true;
     93}
     94
     95bool parameq(const char *a, const char *b)
     96{
     97	return parameqn(a, b, strlen(a)+1);
     98}
     99
    100static bool param_check_unsafe(const struct kernel_param *kp)
    101{
    102	if (kp->flags & KERNEL_PARAM_FL_HWPARAM &&
    103	    security_locked_down(LOCKDOWN_MODULE_PARAMETERS))
    104		return false;
    105
    106	if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
    107		pr_notice("Setting dangerous option %s - tainting kernel\n",
    108			  kp->name);
    109		add_taint(TAINT_USER, LOCKDEP_STILL_OK);
    110	}
    111
    112	return true;
    113}
    114
    115static int parse_one(char *param,
    116		     char *val,
    117		     const char *doing,
    118		     const struct kernel_param *params,
    119		     unsigned num_params,
    120		     s16 min_level,
    121		     s16 max_level,
    122		     void *arg,
    123		     int (*handle_unknown)(char *param, char *val,
    124				     const char *doing, void *arg))
    125{
    126	unsigned int i;
    127	int err;
    128
    129	/* Find parameter */
    130	for (i = 0; i < num_params; i++) {
    131		if (parameq(param, params[i].name)) {
    132			if (params[i].level < min_level
    133			    || params[i].level > max_level)
    134				return 0;
    135			/* No one handled NULL, so do it here. */
    136			if (!val &&
    137			    !(params[i].ops->flags & KERNEL_PARAM_OPS_FL_NOARG))
    138				return -EINVAL;
    139			pr_debug("handling %s with %p\n", param,
    140				params[i].ops->set);
    141			kernel_param_lock(params[i].mod);
    142			if (param_check_unsafe(&params[i]))
    143				err = params[i].ops->set(val, &params[i]);
    144			else
    145				err = -EPERM;
    146			kernel_param_unlock(params[i].mod);
    147			return err;
    148		}
    149	}
    150
    151	if (handle_unknown) {
    152		pr_debug("doing %s: %s='%s'\n", doing, param, val);
    153		return handle_unknown(param, val, doing, arg);
    154	}
    155
    156	pr_debug("Unknown argument '%s'\n", param);
    157	return -ENOENT;
    158}
    159
    160/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
    161char *parse_args(const char *doing,
    162		 char *args,
    163		 const struct kernel_param *params,
    164		 unsigned num,
    165		 s16 min_level,
    166		 s16 max_level,
    167		 void *arg,
    168		 int (*unknown)(char *param, char *val,
    169				const char *doing, void *arg))
    170{
    171	char *param, *val, *err = NULL;
    172
    173	/* Chew leading spaces */
    174	args = skip_spaces(args);
    175
    176	if (*args)
    177		pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args);
    178
    179	while (*args) {
    180		int ret;
    181		int irq_was_disabled;
    182
    183		args = next_arg(args, &param, &val);
    184		/* Stop at -- */
    185		if (!val && strcmp(param, "--") == 0)
    186			return err ?: args;
    187		irq_was_disabled = irqs_disabled();
    188		ret = parse_one(param, val, doing, params, num,
    189				min_level, max_level, arg, unknown);
    190		if (irq_was_disabled && !irqs_disabled())
    191			pr_warn("%s: option '%s' enabled irq's!\n",
    192				doing, param);
    193
    194		switch (ret) {
    195		case 0:
    196			continue;
    197		case -ENOENT:
    198			pr_err("%s: Unknown parameter `%s'\n", doing, param);
    199			break;
    200		case -ENOSPC:
    201			pr_err("%s: `%s' too large for parameter `%s'\n",
    202			       doing, val ?: "", param);
    203			break;
    204		default:
    205			pr_err("%s: `%s' invalid for parameter `%s'\n",
    206			       doing, val ?: "", param);
    207			break;
    208		}
    209
    210		err = ERR_PTR(ret);
    211	}
    212
    213	return err;
    214}
    215
    216/* Lazy bastard, eh? */
    217#define STANDARD_PARAM_DEF(name, type, format, strtolfn)      		\
    218	int param_set_##name(const char *val, const struct kernel_param *kp) \
    219	{								\
    220		return strtolfn(val, 0, (type *)kp->arg);		\
    221	}								\
    222	int param_get_##name(char *buffer, const struct kernel_param *kp) \
    223	{								\
    224		return scnprintf(buffer, PAGE_SIZE, format "\n",	\
    225				*((type *)kp->arg));			\
    226	}								\
    227	const struct kernel_param_ops param_ops_##name = {			\
    228		.set = param_set_##name,				\
    229		.get = param_get_##name,				\
    230	};								\
    231	EXPORT_SYMBOL(param_set_##name);				\
    232	EXPORT_SYMBOL(param_get_##name);				\
    233	EXPORT_SYMBOL(param_ops_##name)
    234
    235
    236STANDARD_PARAM_DEF(byte,	unsigned char,		"%hhu",		kstrtou8);
    237STANDARD_PARAM_DEF(short,	short,			"%hi",		kstrtos16);
    238STANDARD_PARAM_DEF(ushort,	unsigned short,		"%hu",		kstrtou16);
    239STANDARD_PARAM_DEF(int,		int,			"%i",		kstrtoint);
    240STANDARD_PARAM_DEF(uint,	unsigned int,		"%u",		kstrtouint);
    241STANDARD_PARAM_DEF(long,	long,			"%li",		kstrtol);
    242STANDARD_PARAM_DEF(ulong,	unsigned long,		"%lu",		kstrtoul);
    243STANDARD_PARAM_DEF(ullong,	unsigned long long,	"%llu",		kstrtoull);
    244STANDARD_PARAM_DEF(hexint,	unsigned int,		"%#08x", 	kstrtouint);
    245
    246int param_set_uint_minmax(const char *val, const struct kernel_param *kp,
    247		unsigned int min, unsigned int max)
    248{
    249	unsigned int num;
    250	int ret;
    251
    252	if (!val)
    253		return -EINVAL;
    254	ret = kstrtouint(val, 0, &num);
    255	if (ret)
    256		return ret;
    257	if (num < min || num > max)
    258		return -EINVAL;
    259	*((unsigned int *)kp->arg) = num;
    260	return 0;
    261}
    262EXPORT_SYMBOL_GPL(param_set_uint_minmax);
    263
    264int param_set_charp(const char *val, const struct kernel_param *kp)
    265{
    266	if (strlen(val) > 1024) {
    267		pr_err("%s: string parameter too long\n", kp->name);
    268		return -ENOSPC;
    269	}
    270
    271	maybe_kfree_parameter(*(char **)kp->arg);
    272
    273	/* This is a hack.  We can't kmalloc in early boot, and we
    274	 * don't need to; this mangled commandline is preserved. */
    275	if (slab_is_available()) {
    276		*(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
    277		if (!*(char **)kp->arg)
    278			return -ENOMEM;
    279		strcpy(*(char **)kp->arg, val);
    280	} else
    281		*(const char **)kp->arg = val;
    282
    283	return 0;
    284}
    285EXPORT_SYMBOL(param_set_charp);
    286
    287int param_get_charp(char *buffer, const struct kernel_param *kp)
    288{
    289	return scnprintf(buffer, PAGE_SIZE, "%s\n", *((char **)kp->arg));
    290}
    291EXPORT_SYMBOL(param_get_charp);
    292
    293void param_free_charp(void *arg)
    294{
    295	maybe_kfree_parameter(*((char **)arg));
    296}
    297EXPORT_SYMBOL(param_free_charp);
    298
    299const struct kernel_param_ops param_ops_charp = {
    300	.set = param_set_charp,
    301	.get = param_get_charp,
    302	.free = param_free_charp,
    303};
    304EXPORT_SYMBOL(param_ops_charp);
    305
    306/* Actually could be a bool or an int, for historical reasons. */
    307int param_set_bool(const char *val, const struct kernel_param *kp)
    308{
    309	/* No equals means "set"... */
    310	if (!val) val = "1";
    311
    312	/* One of =[yYnN01] */
    313	return strtobool(val, kp->arg);
    314}
    315EXPORT_SYMBOL(param_set_bool);
    316
    317int param_get_bool(char *buffer, const struct kernel_param *kp)
    318{
    319	/* Y and N chosen as being relatively non-coder friendly */
    320	return sprintf(buffer, "%c\n", *(bool *)kp->arg ? 'Y' : 'N');
    321}
    322EXPORT_SYMBOL(param_get_bool);
    323
    324const struct kernel_param_ops param_ops_bool = {
    325	.flags = KERNEL_PARAM_OPS_FL_NOARG,
    326	.set = param_set_bool,
    327	.get = param_get_bool,
    328};
    329EXPORT_SYMBOL(param_ops_bool);
    330
    331int param_set_bool_enable_only(const char *val, const struct kernel_param *kp)
    332{
    333	int err = 0;
    334	bool new_value;
    335	bool orig_value = *(bool *)kp->arg;
    336	struct kernel_param dummy_kp = *kp;
    337
    338	dummy_kp.arg = &new_value;
    339
    340	err = param_set_bool(val, &dummy_kp);
    341	if (err)
    342		return err;
    343
    344	/* Don't let them unset it once it's set! */
    345	if (!new_value && orig_value)
    346		return -EROFS;
    347
    348	if (new_value)
    349		err = param_set_bool(val, kp);
    350
    351	return err;
    352}
    353EXPORT_SYMBOL_GPL(param_set_bool_enable_only);
    354
    355const struct kernel_param_ops param_ops_bool_enable_only = {
    356	.flags = KERNEL_PARAM_OPS_FL_NOARG,
    357	.set = param_set_bool_enable_only,
    358	.get = param_get_bool,
    359};
    360EXPORT_SYMBOL_GPL(param_ops_bool_enable_only);
    361
    362/* This one must be bool. */
    363int param_set_invbool(const char *val, const struct kernel_param *kp)
    364{
    365	int ret;
    366	bool boolval;
    367	struct kernel_param dummy;
    368
    369	dummy.arg = &boolval;
    370	ret = param_set_bool(val, &dummy);
    371	if (ret == 0)
    372		*(bool *)kp->arg = !boolval;
    373	return ret;
    374}
    375EXPORT_SYMBOL(param_set_invbool);
    376
    377int param_get_invbool(char *buffer, const struct kernel_param *kp)
    378{
    379	return sprintf(buffer, "%c\n", (*(bool *)kp->arg) ? 'N' : 'Y');
    380}
    381EXPORT_SYMBOL(param_get_invbool);
    382
    383const struct kernel_param_ops param_ops_invbool = {
    384	.set = param_set_invbool,
    385	.get = param_get_invbool,
    386};
    387EXPORT_SYMBOL(param_ops_invbool);
    388
    389int param_set_bint(const char *val, const struct kernel_param *kp)
    390{
    391	/* Match bool exactly, by re-using it. */
    392	struct kernel_param boolkp = *kp;
    393	bool v;
    394	int ret;
    395
    396	boolkp.arg = &v;
    397
    398	ret = param_set_bool(val, &boolkp);
    399	if (ret == 0)
    400		*(int *)kp->arg = v;
    401	return ret;
    402}
    403EXPORT_SYMBOL(param_set_bint);
    404
    405const struct kernel_param_ops param_ops_bint = {
    406	.flags = KERNEL_PARAM_OPS_FL_NOARG,
    407	.set = param_set_bint,
    408	.get = param_get_int,
    409};
    410EXPORT_SYMBOL(param_ops_bint);
    411
    412/* We break the rule and mangle the string. */
    413static int param_array(struct module *mod,
    414		       const char *name,
    415		       const char *val,
    416		       unsigned int min, unsigned int max,
    417		       void *elem, int elemsize,
    418		       int (*set)(const char *, const struct kernel_param *kp),
    419		       s16 level,
    420		       unsigned int *num)
    421{
    422	int ret;
    423	struct kernel_param kp;
    424	char save;
    425
    426	/* Get the name right for errors. */
    427	kp.name = name;
    428	kp.arg = elem;
    429	kp.level = level;
    430
    431	*num = 0;
    432	/* We expect a comma-separated list of values. */
    433	do {
    434		int len;
    435
    436		if (*num == max) {
    437			pr_err("%s: can only take %i arguments\n", name, max);
    438			return -EINVAL;
    439		}
    440		len = strcspn(val, ",");
    441
    442		/* nul-terminate and parse */
    443		save = val[len];
    444		((char *)val)[len] = '\0';
    445		check_kparam_locked(mod);
    446		ret = set(val, &kp);
    447
    448		if (ret != 0)
    449			return ret;
    450		kp.arg += elemsize;
    451		val += len+1;
    452		(*num)++;
    453	} while (save == ',');
    454
    455	if (*num < min) {
    456		pr_err("%s: needs at least %i arguments\n", name, min);
    457		return -EINVAL;
    458	}
    459	return 0;
    460}
    461
    462static int param_array_set(const char *val, const struct kernel_param *kp)
    463{
    464	const struct kparam_array *arr = kp->arr;
    465	unsigned int temp_num;
    466
    467	return param_array(kp->mod, kp->name, val, 1, arr->max, arr->elem,
    468			   arr->elemsize, arr->ops->set, kp->level,
    469			   arr->num ?: &temp_num);
    470}
    471
    472static int param_array_get(char *buffer, const struct kernel_param *kp)
    473{
    474	int i, off, ret;
    475	const struct kparam_array *arr = kp->arr;
    476	struct kernel_param p = *kp;
    477
    478	for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
    479		/* Replace \n with comma */
    480		if (i)
    481			buffer[off - 1] = ',';
    482		p.arg = arr->elem + arr->elemsize * i;
    483		check_kparam_locked(p.mod);
    484		ret = arr->ops->get(buffer + off, &p);
    485		if (ret < 0)
    486			return ret;
    487		off += ret;
    488	}
    489	buffer[off] = '\0';
    490	return off;
    491}
    492
    493static void param_array_free(void *arg)
    494{
    495	unsigned int i;
    496	const struct kparam_array *arr = arg;
    497
    498	if (arr->ops->free)
    499		for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
    500			arr->ops->free(arr->elem + arr->elemsize * i);
    501}
    502
    503const struct kernel_param_ops param_array_ops = {
    504	.set = param_array_set,
    505	.get = param_array_get,
    506	.free = param_array_free,
    507};
    508EXPORT_SYMBOL(param_array_ops);
    509
    510int param_set_copystring(const char *val, const struct kernel_param *kp)
    511{
    512	const struct kparam_string *kps = kp->str;
    513
    514	if (strlen(val)+1 > kps->maxlen) {
    515		pr_err("%s: string doesn't fit in %u chars.\n",
    516		       kp->name, kps->maxlen-1);
    517		return -ENOSPC;
    518	}
    519	strcpy(kps->string, val);
    520	return 0;
    521}
    522EXPORT_SYMBOL(param_set_copystring);
    523
    524int param_get_string(char *buffer, const struct kernel_param *kp)
    525{
    526	const struct kparam_string *kps = kp->str;
    527	return scnprintf(buffer, PAGE_SIZE, "%s\n", kps->string);
    528}
    529EXPORT_SYMBOL(param_get_string);
    530
    531const struct kernel_param_ops param_ops_string = {
    532	.set = param_set_copystring,
    533	.get = param_get_string,
    534};
    535EXPORT_SYMBOL(param_ops_string);
    536
    537/* sysfs output in /sys/modules/XYZ/parameters/ */
    538#define to_module_attr(n) container_of(n, struct module_attribute, attr)
    539#define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
    540
    541struct param_attribute
    542{
    543	struct module_attribute mattr;
    544	const struct kernel_param *param;
    545};
    546
    547struct module_param_attrs
    548{
    549	unsigned int num;
    550	struct attribute_group grp;
    551	struct param_attribute attrs[];
    552};
    553
    554#ifdef CONFIG_SYSFS
    555#define to_param_attr(n) container_of(n, struct param_attribute, mattr)
    556
    557static ssize_t param_attr_show(struct module_attribute *mattr,
    558			       struct module_kobject *mk, char *buf)
    559{
    560	int count;
    561	struct param_attribute *attribute = to_param_attr(mattr);
    562
    563	if (!attribute->param->ops->get)
    564		return -EPERM;
    565
    566	kernel_param_lock(mk->mod);
    567	count = attribute->param->ops->get(buf, attribute->param);
    568	kernel_param_unlock(mk->mod);
    569	return count;
    570}
    571
    572/* sysfs always hands a nul-terminated string in buf.  We rely on that. */
    573static ssize_t param_attr_store(struct module_attribute *mattr,
    574				struct module_kobject *mk,
    575				const char *buf, size_t len)
    576{
    577 	int err;
    578	struct param_attribute *attribute = to_param_attr(mattr);
    579
    580	if (!attribute->param->ops->set)
    581		return -EPERM;
    582
    583	kernel_param_lock(mk->mod);
    584	if (param_check_unsafe(attribute->param))
    585		err = attribute->param->ops->set(buf, attribute->param);
    586	else
    587		err = -EPERM;
    588	kernel_param_unlock(mk->mod);
    589	if (!err)
    590		return len;
    591	return err;
    592}
    593#endif
    594
    595#ifdef CONFIG_MODULES
    596#define __modinit
    597#else
    598#define __modinit __init
    599#endif
    600
    601#ifdef CONFIG_SYSFS
    602void kernel_param_lock(struct module *mod)
    603{
    604	mutex_lock(KPARAM_MUTEX(mod));
    605}
    606
    607void kernel_param_unlock(struct module *mod)
    608{
    609	mutex_unlock(KPARAM_MUTEX(mod));
    610}
    611
    612EXPORT_SYMBOL(kernel_param_lock);
    613EXPORT_SYMBOL(kernel_param_unlock);
    614
    615/*
    616 * add_sysfs_param - add a parameter to sysfs
    617 * @mk: struct module_kobject
    618 * @kp: the actual parameter definition to add to sysfs
    619 * @name: name of parameter
    620 *
    621 * Create a kobject if for a (per-module) parameter if mp NULL, and
    622 * create file in sysfs.  Returns an error on out of memory.  Always cleans up
    623 * if there's an error.
    624 */
    625static __modinit int add_sysfs_param(struct module_kobject *mk,
    626				     const struct kernel_param *kp,
    627				     const char *name)
    628{
    629	struct module_param_attrs *new_mp;
    630	struct attribute **new_attrs;
    631	unsigned int i;
    632
    633	/* We don't bother calling this with invisible parameters. */
    634	BUG_ON(!kp->perm);
    635
    636	if (!mk->mp) {
    637		/* First allocation. */
    638		mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL);
    639		if (!mk->mp)
    640			return -ENOMEM;
    641		mk->mp->grp.name = "parameters";
    642		/* NULL-terminated attribute array. */
    643		mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]),
    644					    GFP_KERNEL);
    645		/* Caller will cleanup via free_module_param_attrs */
    646		if (!mk->mp->grp.attrs)
    647			return -ENOMEM;
    648	}
    649
    650	/* Enlarge allocations. */
    651	new_mp = krealloc(mk->mp,
    652			  sizeof(*mk->mp) +
    653			  sizeof(mk->mp->attrs[0]) * (mk->mp->num + 1),
    654			  GFP_KERNEL);
    655	if (!new_mp)
    656		return -ENOMEM;
    657	mk->mp = new_mp;
    658
    659	/* Extra pointer for NULL terminator */
    660	new_attrs = krealloc(mk->mp->grp.attrs,
    661			     sizeof(mk->mp->grp.attrs[0]) * (mk->mp->num + 2),
    662			     GFP_KERNEL);
    663	if (!new_attrs)
    664		return -ENOMEM;
    665	mk->mp->grp.attrs = new_attrs;
    666
    667	/* Tack new one on the end. */
    668	memset(&mk->mp->attrs[mk->mp->num], 0, sizeof(mk->mp->attrs[0]));
    669	sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr);
    670	mk->mp->attrs[mk->mp->num].param = kp;
    671	mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show;
    672	/* Do not allow runtime DAC changes to make param writable. */
    673	if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0)
    674		mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store;
    675	else
    676		mk->mp->attrs[mk->mp->num].mattr.store = NULL;
    677	mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name;
    678	mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm;
    679	mk->mp->num++;
    680
    681	/* Fix up all the pointers, since krealloc can move us */
    682	for (i = 0; i < mk->mp->num; i++)
    683		mk->mp->grp.attrs[i] = &mk->mp->attrs[i].mattr.attr;
    684	mk->mp->grp.attrs[mk->mp->num] = NULL;
    685	return 0;
    686}
    687
    688#ifdef CONFIG_MODULES
    689static void free_module_param_attrs(struct module_kobject *mk)
    690{
    691	if (mk->mp)
    692		kfree(mk->mp->grp.attrs);
    693	kfree(mk->mp);
    694	mk->mp = NULL;
    695}
    696
    697/*
    698 * module_param_sysfs_setup - setup sysfs support for one module
    699 * @mod: module
    700 * @kparam: module parameters (array)
    701 * @num_params: number of module parameters
    702 *
    703 * Adds sysfs entries for module parameters under
    704 * /sys/module/[mod->name]/parameters/
    705 */
    706int module_param_sysfs_setup(struct module *mod,
    707			     const struct kernel_param *kparam,
    708			     unsigned int num_params)
    709{
    710	int i, err;
    711	bool params = false;
    712
    713	for (i = 0; i < num_params; i++) {
    714		if (kparam[i].perm == 0)
    715			continue;
    716		err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
    717		if (err) {
    718			free_module_param_attrs(&mod->mkobj);
    719			return err;
    720		}
    721		params = true;
    722	}
    723
    724	if (!params)
    725		return 0;
    726
    727	/* Create the param group. */
    728	err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
    729	if (err)
    730		free_module_param_attrs(&mod->mkobj);
    731	return err;
    732}
    733
    734/*
    735 * module_param_sysfs_remove - remove sysfs support for one module
    736 * @mod: module
    737 *
    738 * Remove sysfs entries for module parameters and the corresponding
    739 * kobject.
    740 */
    741void module_param_sysfs_remove(struct module *mod)
    742{
    743	if (mod->mkobj.mp) {
    744		sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
    745		/* We are positive that no one is using any param
    746		 * attrs at this point.  Deallocate immediately. */
    747		free_module_param_attrs(&mod->mkobj);
    748	}
    749}
    750#endif
    751
    752void destroy_params(const struct kernel_param *params, unsigned num)
    753{
    754	unsigned int i;
    755
    756	for (i = 0; i < num; i++)
    757		if (params[i].ops->free)
    758			params[i].ops->free(params[i].arg);
    759}
    760
    761static struct module_kobject * __init locate_module_kobject(const char *name)
    762{
    763	struct module_kobject *mk;
    764	struct kobject *kobj;
    765	int err;
    766
    767	kobj = kset_find_obj(module_kset, name);
    768	if (kobj) {
    769		mk = to_module_kobject(kobj);
    770	} else {
    771		mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
    772		BUG_ON(!mk);
    773
    774		mk->mod = THIS_MODULE;
    775		mk->kobj.kset = module_kset;
    776		err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
    777					   "%s", name);
    778#ifdef CONFIG_MODULES
    779		if (!err)
    780			err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
    781#endif
    782		if (err) {
    783			kobject_put(&mk->kobj);
    784			pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n",
    785				name, err);
    786			return NULL;
    787		}
    788
    789		/* So that we hold reference in both cases. */
    790		kobject_get(&mk->kobj);
    791	}
    792
    793	return mk;
    794}
    795
    796static void __init kernel_add_sysfs_param(const char *name,
    797					  const struct kernel_param *kparam,
    798					  unsigned int name_skip)
    799{
    800	struct module_kobject *mk;
    801	int err;
    802
    803	mk = locate_module_kobject(name);
    804	if (!mk)
    805		return;
    806
    807	/* We need to remove old parameters before adding more. */
    808	if (mk->mp)
    809		sysfs_remove_group(&mk->kobj, &mk->mp->grp);
    810
    811	/* These should not fail at boot. */
    812	err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
    813	BUG_ON(err);
    814	err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
    815	BUG_ON(err);
    816	kobject_uevent(&mk->kobj, KOBJ_ADD);
    817	kobject_put(&mk->kobj);
    818}
    819
    820/*
    821 * param_sysfs_builtin - add sysfs parameters for built-in modules
    822 *
    823 * Add module_parameters to sysfs for "modules" built into the kernel.
    824 *
    825 * The "module" name (KBUILD_MODNAME) is stored before a dot, the
    826 * "parameter" name is stored behind a dot in kernel_param->name. So,
    827 * extract the "module" name for all built-in kernel_param-eters,
    828 * and for all who have the same, call kernel_add_sysfs_param.
    829 */
    830static void __init param_sysfs_builtin(void)
    831{
    832	const struct kernel_param *kp;
    833	unsigned int name_len;
    834	char modname[MODULE_NAME_LEN];
    835
    836	for (kp = __start___param; kp < __stop___param; kp++) {
    837		char *dot;
    838
    839		if (kp->perm == 0)
    840			continue;
    841
    842		dot = strchr(kp->name, '.');
    843		if (!dot) {
    844			/* This happens for core_param() */
    845			strcpy(modname, "kernel");
    846			name_len = 0;
    847		} else {
    848			name_len = dot - kp->name + 1;
    849			strlcpy(modname, kp->name, name_len);
    850		}
    851		kernel_add_sysfs_param(modname, kp, name_len);
    852	}
    853}
    854
    855ssize_t __modver_version_show(struct module_attribute *mattr,
    856			      struct module_kobject *mk, char *buf)
    857{
    858	struct module_version_attribute *vattr =
    859		container_of(mattr, struct module_version_attribute, mattr);
    860
    861	return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version);
    862}
    863
    864extern const struct module_version_attribute __start___modver[];
    865extern const struct module_version_attribute __stop___modver[];
    866
    867static void __init version_sysfs_builtin(void)
    868{
    869	const struct module_version_attribute *vattr;
    870	struct module_kobject *mk;
    871	int err;
    872
    873	for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
    874		mk = locate_module_kobject(vattr->module_name);
    875		if (mk) {
    876			err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
    877			WARN_ON_ONCE(err);
    878			kobject_uevent(&mk->kobj, KOBJ_ADD);
    879			kobject_put(&mk->kobj);
    880		}
    881	}
    882}
    883
    884/* module-related sysfs stuff */
    885
    886static ssize_t module_attr_show(struct kobject *kobj,
    887				struct attribute *attr,
    888				char *buf)
    889{
    890	struct module_attribute *attribute;
    891	struct module_kobject *mk;
    892	int ret;
    893
    894	attribute = to_module_attr(attr);
    895	mk = to_module_kobject(kobj);
    896
    897	if (!attribute->show)
    898		return -EIO;
    899
    900	ret = attribute->show(attribute, mk, buf);
    901
    902	return ret;
    903}
    904
    905static ssize_t module_attr_store(struct kobject *kobj,
    906				struct attribute *attr,
    907				const char *buf, size_t len)
    908{
    909	struct module_attribute *attribute;
    910	struct module_kobject *mk;
    911	int ret;
    912
    913	attribute = to_module_attr(attr);
    914	mk = to_module_kobject(kobj);
    915
    916	if (!attribute->store)
    917		return -EIO;
    918
    919	ret = attribute->store(attribute, mk, buf, len);
    920
    921	return ret;
    922}
    923
    924static const struct sysfs_ops module_sysfs_ops = {
    925	.show = module_attr_show,
    926	.store = module_attr_store,
    927};
    928
    929static int uevent_filter(struct kobject *kobj)
    930{
    931	const struct kobj_type *ktype = get_ktype(kobj);
    932
    933	if (ktype == &module_ktype)
    934		return 1;
    935	return 0;
    936}
    937
    938static const struct kset_uevent_ops module_uevent_ops = {
    939	.filter = uevent_filter,
    940};
    941
    942struct kset *module_kset;
    943int module_sysfs_initialized;
    944
    945static void module_kobj_release(struct kobject *kobj)
    946{
    947	struct module_kobject *mk = to_module_kobject(kobj);
    948	complete(mk->kobj_completion);
    949}
    950
    951struct kobj_type module_ktype = {
    952	.release   =	module_kobj_release,
    953	.sysfs_ops =	&module_sysfs_ops,
    954};
    955
    956/*
    957 * param_sysfs_init - wrapper for built-in params support
    958 */
    959static int __init param_sysfs_init(void)
    960{
    961	module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
    962	if (!module_kset) {
    963		printk(KERN_WARNING "%s (%d): error creating kset\n",
    964			__FILE__, __LINE__);
    965		return -ENOMEM;
    966	}
    967	module_sysfs_initialized = 1;
    968
    969	version_sysfs_builtin();
    970	param_sysfs_builtin();
    971
    972	return 0;
    973}
    974subsys_initcall(param_sysfs_init);
    975
    976#endif /* CONFIG_SYSFS */