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