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