Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Helpers for initial module or kernel cmdline parsing
0003    Copyright (C) 2001 Rusty Russell.
0004 
0005 */
0006 #include <linux/kernel.h>
0007 #include <linux/string.h>
0008 #include <linux/errno.h>
0009 #include <linux/module.h>
0010 #include <linux/moduleparam.h>
0011 #include <linux/device.h>
0012 #include <linux/err.h>
0013 #include <linux/slab.h>
0014 #include <linux/ctype.h>
0015 #include <linux/security.h>
0016 
0017 #ifdef CONFIG_SYSFS
0018 /* Protects all built-in parameters, modules use their own param_lock */
0019 static DEFINE_MUTEX(param_lock);
0020 
0021 /* Use the module's mutex, or if built-in use the built-in mutex */
0022 #ifdef CONFIG_MODULES
0023 #define KPARAM_MUTEX(mod)   ((mod) ? &(mod)->param_lock : &param_lock)
0024 #else
0025 #define KPARAM_MUTEX(mod)   (&param_lock)
0026 #endif
0027 
0028 static inline void check_kparam_locked(struct module *mod)
0029 {
0030     BUG_ON(!mutex_is_locked(KPARAM_MUTEX(mod)));
0031 }
0032 #else
0033 static inline void check_kparam_locked(struct module *mod)
0034 {
0035 }
0036 #endif /* !CONFIG_SYSFS */
0037 
0038 /* This just allows us to keep track of which parameters are kmalloced. */
0039 struct kmalloced_param {
0040     struct list_head list;
0041     char val[];
0042 };
0043 static LIST_HEAD(kmalloced_params);
0044 static DEFINE_SPINLOCK(kmalloced_params_lock);
0045 
0046 static void *kmalloc_parameter(unsigned int size)
0047 {
0048     struct kmalloced_param *p;
0049 
0050     p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
0051     if (!p)
0052         return NULL;
0053 
0054     spin_lock(&kmalloced_params_lock);
0055     list_add(&p->list, &kmalloced_params);
0056     spin_unlock(&kmalloced_params_lock);
0057 
0058     return p->val;
0059 }
0060 
0061 /* Does nothing if parameter wasn't kmalloced above. */
0062 static void maybe_kfree_parameter(void *param)
0063 {
0064     struct kmalloced_param *p;
0065 
0066     spin_lock(&kmalloced_params_lock);
0067     list_for_each_entry(p, &kmalloced_params, list) {
0068         if (p->val == param) {
0069             list_del(&p->list);
0070             kfree(p);
0071             break;
0072         }
0073     }
0074     spin_unlock(&kmalloced_params_lock);
0075 }
0076 
0077 static char dash2underscore(char c)
0078 {
0079     if (c == '-')
0080         return '_';
0081     return c;
0082 }
0083 
0084 bool parameqn(const char *a, const char *b, size_t n)
0085 {
0086     size_t i;
0087 
0088     for (i = 0; i < n; i++) {
0089         if (dash2underscore(a[i]) != dash2underscore(b[i]))
0090             return false;
0091     }
0092     return true;
0093 }
0094 
0095 bool parameq(const char *a, const char *b)
0096 {
0097     return parameqn(a, b, strlen(a)+1);
0098 }
0099 
0100 static bool param_check_unsafe(const struct kernel_param *kp)
0101 {
0102     if (kp->flags & KERNEL_PARAM_FL_HWPARAM &&
0103         security_locked_down(LOCKDOWN_MODULE_PARAMETERS))
0104         return false;
0105 
0106     if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
0107         pr_notice("Setting dangerous option %s - tainting kernel\n",
0108               kp->name);
0109         add_taint(TAINT_USER, LOCKDEP_STILL_OK);
0110     }
0111 
0112     return true;
0113 }
0114 
0115 static int parse_one(char *param,
0116              char *val,
0117              const char *doing,
0118              const struct kernel_param *params,
0119              unsigned num_params,
0120              s16 min_level,
0121              s16 max_level,
0122              void *arg,
0123              int (*handle_unknown)(char *param, char *val,
0124                      const char *doing, void *arg))
0125 {
0126     unsigned int i;
0127     int err;
0128 
0129     /* Find parameter */
0130     for (i = 0; i < num_params; i++) {
0131         if (parameq(param, params[i].name)) {
0132             if (params[i].level < min_level
0133                 || params[i].level > max_level)
0134                 return 0;
0135             /* No one handled NULL, so do it here. */
0136             if (!val &&
0137                 !(params[i].ops->flags & KERNEL_PARAM_OPS_FL_NOARG))
0138                 return -EINVAL;
0139             pr_debug("handling %s with %p\n", param,
0140                 params[i].ops->set);
0141             kernel_param_lock(params[i].mod);
0142             if (param_check_unsafe(&params[i]))
0143                 err = params[i].ops->set(val, &params[i]);
0144             else
0145                 err = -EPERM;
0146             kernel_param_unlock(params[i].mod);
0147             return err;
0148         }
0149     }
0150 
0151     if (handle_unknown) {
0152         pr_debug("doing %s: %s='%s'\n", doing, param, val);
0153         return handle_unknown(param, val, doing, arg);
0154     }
0155 
0156     pr_debug("Unknown argument '%s'\n", param);
0157     return -ENOENT;
0158 }
0159 
0160 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
0161 char *parse_args(const char *doing,
0162          char *args,
0163          const struct kernel_param *params,
0164          unsigned num,
0165          s16 min_level,
0166          s16 max_level,
0167          void *arg,
0168          int (*unknown)(char *param, char *val,
0169                 const char *doing, void *arg))
0170 {
0171     char *param, *val, *err = NULL;
0172 
0173     /* Chew leading spaces */
0174     args = skip_spaces(args);
0175 
0176     if (*args)
0177         pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args);
0178 
0179     while (*args) {
0180         int ret;
0181         int irq_was_disabled;
0182 
0183         args = next_arg(args, &param, &val);
0184         /* Stop at -- */
0185         if (!val && strcmp(param, "--") == 0)
0186             return err ?: args;
0187         irq_was_disabled = irqs_disabled();
0188         ret = parse_one(param, val, doing, params, num,
0189                 min_level, max_level, arg, unknown);
0190         if (irq_was_disabled && !irqs_disabled())
0191             pr_warn("%s: option '%s' enabled irq's!\n",
0192                 doing, param);
0193 
0194         switch (ret) {
0195         case 0:
0196             continue;
0197         case -ENOENT:
0198             pr_err("%s: Unknown parameter `%s'\n", doing, param);
0199             break;
0200         case -ENOSPC:
0201             pr_err("%s: `%s' too large for parameter `%s'\n",
0202                    doing, val ?: "", param);
0203             break;
0204         default:
0205             pr_err("%s: `%s' invalid for parameter `%s'\n",
0206                    doing, val ?: "", param);
0207             break;
0208         }
0209 
0210         err = ERR_PTR(ret);
0211     }
0212 
0213     return err;
0214 }
0215 
0216 /* Lazy bastard, eh? */
0217 #define STANDARD_PARAM_DEF(name, type, format, strtolfn)            \
0218     int param_set_##name(const char *val, const struct kernel_param *kp) \
0219     {                               \
0220         return strtolfn(val, 0, (type *)kp->arg);       \
0221     }                               \
0222     int param_get_##name(char *buffer, const struct kernel_param *kp) \
0223     {                               \
0224         return scnprintf(buffer, PAGE_SIZE, format "\n",    \
0225                 *((type *)kp->arg));            \
0226     }                               \
0227     const struct kernel_param_ops param_ops_##name = {          \
0228         .set = param_set_##name,                \
0229         .get = param_get_##name,                \
0230     };                              \
0231     EXPORT_SYMBOL(param_set_##name);                \
0232     EXPORT_SYMBOL(param_get_##name);                \
0233     EXPORT_SYMBOL(param_ops_##name)
0234 
0235 
0236 STANDARD_PARAM_DEF(byte,    unsigned char,      "%hhu",     kstrtou8);
0237 STANDARD_PARAM_DEF(short,   short,          "%hi",      kstrtos16);
0238 STANDARD_PARAM_DEF(ushort,  unsigned short,     "%hu",      kstrtou16);
0239 STANDARD_PARAM_DEF(int,     int,            "%i",       kstrtoint);
0240 STANDARD_PARAM_DEF(uint,    unsigned int,       "%u",       kstrtouint);
0241 STANDARD_PARAM_DEF(long,    long,           "%li",      kstrtol);
0242 STANDARD_PARAM_DEF(ulong,   unsigned long,      "%lu",      kstrtoul);
0243 STANDARD_PARAM_DEF(ullong,  unsigned long long, "%llu",     kstrtoull);
0244 STANDARD_PARAM_DEF(hexint,  unsigned int,       "%#08x",    kstrtouint);
0245 
0246 int param_set_uint_minmax(const char *val, const struct kernel_param *kp,
0247         unsigned int min, unsigned int max)
0248 {
0249     unsigned int num;
0250     int ret;
0251 
0252     if (!val)
0253         return -EINVAL;
0254     ret = kstrtouint(val, 0, &num);
0255     if (ret)
0256         return ret;
0257     if (num < min || num > max)
0258         return -EINVAL;
0259     *((unsigned int *)kp->arg) = num;
0260     return 0;
0261 }
0262 EXPORT_SYMBOL_GPL(param_set_uint_minmax);
0263 
0264 int param_set_charp(const char *val, const struct kernel_param *kp)
0265 {
0266     if (strlen(val) > 1024) {
0267         pr_err("%s: string parameter too long\n", kp->name);
0268         return -ENOSPC;
0269     }
0270 
0271     maybe_kfree_parameter(*(char **)kp->arg);
0272 
0273     /* This is a hack.  We can't kmalloc in early boot, and we
0274      * don't need to; this mangled commandline is preserved. */
0275     if (slab_is_available()) {
0276         *(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
0277         if (!*(char **)kp->arg)
0278             return -ENOMEM;
0279         strcpy(*(char **)kp->arg, val);
0280     } else
0281         *(const char **)kp->arg = val;
0282 
0283     return 0;
0284 }
0285 EXPORT_SYMBOL(param_set_charp);
0286 
0287 int param_get_charp(char *buffer, const struct kernel_param *kp)
0288 {
0289     return scnprintf(buffer, PAGE_SIZE, "%s\n", *((char **)kp->arg));
0290 }
0291 EXPORT_SYMBOL(param_get_charp);
0292 
0293 void param_free_charp(void *arg)
0294 {
0295     maybe_kfree_parameter(*((char **)arg));
0296 }
0297 EXPORT_SYMBOL(param_free_charp);
0298 
0299 const struct kernel_param_ops param_ops_charp = {
0300     .set = param_set_charp,
0301     .get = param_get_charp,
0302     .free = param_free_charp,
0303 };
0304 EXPORT_SYMBOL(param_ops_charp);
0305 
0306 /* Actually could be a bool or an int, for historical reasons. */
0307 int param_set_bool(const char *val, const struct kernel_param *kp)
0308 {
0309     /* No equals means "set"... */
0310     if (!val) val = "1";
0311 
0312     /* One of =[yYnN01] */
0313     return strtobool(val, kp->arg);
0314 }
0315 EXPORT_SYMBOL(param_set_bool);
0316 
0317 int param_get_bool(char *buffer, const struct kernel_param *kp)
0318 {
0319     /* Y and N chosen as being relatively non-coder friendly */
0320     return sprintf(buffer, "%c\n", *(bool *)kp->arg ? 'Y' : 'N');
0321 }
0322 EXPORT_SYMBOL(param_get_bool);
0323 
0324 const struct kernel_param_ops param_ops_bool = {
0325     .flags = KERNEL_PARAM_OPS_FL_NOARG,
0326     .set = param_set_bool,
0327     .get = param_get_bool,
0328 };
0329 EXPORT_SYMBOL(param_ops_bool);
0330 
0331 int param_set_bool_enable_only(const char *val, const struct kernel_param *kp)
0332 {
0333     int err = 0;
0334     bool new_value;
0335     bool orig_value = *(bool *)kp->arg;
0336     struct kernel_param dummy_kp = *kp;
0337 
0338     dummy_kp.arg = &new_value;
0339 
0340     err = param_set_bool(val, &dummy_kp);
0341     if (err)
0342         return err;
0343 
0344     /* Don't let them unset it once it's set! */
0345     if (!new_value && orig_value)
0346         return -EROFS;
0347 
0348     if (new_value)
0349         err = param_set_bool(val, kp);
0350 
0351     return err;
0352 }
0353 EXPORT_SYMBOL_GPL(param_set_bool_enable_only);
0354 
0355 const struct kernel_param_ops param_ops_bool_enable_only = {
0356     .flags = KERNEL_PARAM_OPS_FL_NOARG,
0357     .set = param_set_bool_enable_only,
0358     .get = param_get_bool,
0359 };
0360 EXPORT_SYMBOL_GPL(param_ops_bool_enable_only);
0361 
0362 /* This one must be bool. */
0363 int param_set_invbool(const char *val, const struct kernel_param *kp)
0364 {
0365     int ret;
0366     bool boolval;
0367     struct kernel_param dummy;
0368 
0369     dummy.arg = &boolval;
0370     ret = param_set_bool(val, &dummy);
0371     if (ret == 0)
0372         *(bool *)kp->arg = !boolval;
0373     return ret;
0374 }
0375 EXPORT_SYMBOL(param_set_invbool);
0376 
0377 int param_get_invbool(char *buffer, const struct kernel_param *kp)
0378 {
0379     return sprintf(buffer, "%c\n", (*(bool *)kp->arg) ? 'N' : 'Y');
0380 }
0381 EXPORT_SYMBOL(param_get_invbool);
0382 
0383 const struct kernel_param_ops param_ops_invbool = {
0384     .set = param_set_invbool,
0385     .get = param_get_invbool,
0386 };
0387 EXPORT_SYMBOL(param_ops_invbool);
0388 
0389 int param_set_bint(const char *val, const struct kernel_param *kp)
0390 {
0391     /* Match bool exactly, by re-using it. */
0392     struct kernel_param boolkp = *kp;
0393     bool v;
0394     int ret;
0395 
0396     boolkp.arg = &v;
0397 
0398     ret = param_set_bool(val, &boolkp);
0399     if (ret == 0)
0400         *(int *)kp->arg = v;
0401     return ret;
0402 }
0403 EXPORT_SYMBOL(param_set_bint);
0404 
0405 const struct kernel_param_ops param_ops_bint = {
0406     .flags = KERNEL_PARAM_OPS_FL_NOARG,
0407     .set = param_set_bint,
0408     .get = param_get_int,
0409 };
0410 EXPORT_SYMBOL(param_ops_bint);
0411 
0412 /* We break the rule and mangle the string. */
0413 static int param_array(struct module *mod,
0414                const char *name,
0415                const char *val,
0416                unsigned int min, unsigned int max,
0417                void *elem, int elemsize,
0418                int (*set)(const char *, const struct kernel_param *kp),
0419                s16 level,
0420                unsigned int *num)
0421 {
0422     int ret;
0423     struct kernel_param kp;
0424     char save;
0425 
0426     /* Get the name right for errors. */
0427     kp.name = name;
0428     kp.arg = elem;
0429     kp.level = level;
0430 
0431     *num = 0;
0432     /* We expect a comma-separated list of values. */
0433     do {
0434         int len;
0435 
0436         if (*num == max) {
0437             pr_err("%s: can only take %i arguments\n", name, max);
0438             return -EINVAL;
0439         }
0440         len = strcspn(val, ",");
0441 
0442         /* nul-terminate and parse */
0443         save = val[len];
0444         ((char *)val)[len] = '\0';
0445         check_kparam_locked(mod);
0446         ret = set(val, &kp);
0447 
0448         if (ret != 0)
0449             return ret;
0450         kp.arg += elemsize;
0451         val += len+1;
0452         (*num)++;
0453     } while (save == ',');
0454 
0455     if (*num < min) {
0456         pr_err("%s: needs at least %i arguments\n", name, min);
0457         return -EINVAL;
0458     }
0459     return 0;
0460 }
0461 
0462 static int param_array_set(const char *val, const struct kernel_param *kp)
0463 {
0464     const struct kparam_array *arr = kp->arr;
0465     unsigned int temp_num;
0466 
0467     return param_array(kp->mod, kp->name, val, 1, arr->max, arr->elem,
0468                arr->elemsize, arr->ops->set, kp->level,
0469                arr->num ?: &temp_num);
0470 }
0471 
0472 static int param_array_get(char *buffer, const struct kernel_param *kp)
0473 {
0474     int i, off, ret;
0475     const struct kparam_array *arr = kp->arr;
0476     struct kernel_param p = *kp;
0477 
0478     for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
0479         /* Replace \n with comma */
0480         if (i)
0481             buffer[off - 1] = ',';
0482         p.arg = arr->elem + arr->elemsize * i;
0483         check_kparam_locked(p.mod);
0484         ret = arr->ops->get(buffer + off, &p);
0485         if (ret < 0)
0486             return ret;
0487         off += ret;
0488     }
0489     buffer[off] = '\0';
0490     return off;
0491 }
0492 
0493 static void param_array_free(void *arg)
0494 {
0495     unsigned int i;
0496     const struct kparam_array *arr = arg;
0497 
0498     if (arr->ops->free)
0499         for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
0500             arr->ops->free(arr->elem + arr->elemsize * i);
0501 }
0502 
0503 const struct kernel_param_ops param_array_ops = {
0504     .set = param_array_set,
0505     .get = param_array_get,
0506     .free = param_array_free,
0507 };
0508 EXPORT_SYMBOL(param_array_ops);
0509 
0510 int param_set_copystring(const char *val, const struct kernel_param *kp)
0511 {
0512     const struct kparam_string *kps = kp->str;
0513 
0514     if (strlen(val)+1 > kps->maxlen) {
0515         pr_err("%s: string doesn't fit in %u chars.\n",
0516                kp->name, kps->maxlen-1);
0517         return -ENOSPC;
0518     }
0519     strcpy(kps->string, val);
0520     return 0;
0521 }
0522 EXPORT_SYMBOL(param_set_copystring);
0523 
0524 int param_get_string(char *buffer, const struct kernel_param *kp)
0525 {
0526     const struct kparam_string *kps = kp->str;
0527     return scnprintf(buffer, PAGE_SIZE, "%s\n", kps->string);
0528 }
0529 EXPORT_SYMBOL(param_get_string);
0530 
0531 const struct kernel_param_ops param_ops_string = {
0532     .set = param_set_copystring,
0533     .get = param_get_string,
0534 };
0535 EXPORT_SYMBOL(param_ops_string);
0536 
0537 /* sysfs output in /sys/modules/XYZ/parameters/ */
0538 #define to_module_attr(n) container_of(n, struct module_attribute, attr)
0539 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
0540 
0541 struct param_attribute
0542 {
0543     struct module_attribute mattr;
0544     const struct kernel_param *param;
0545 };
0546 
0547 struct module_param_attrs
0548 {
0549     unsigned int num;
0550     struct attribute_group grp;
0551     struct param_attribute attrs[];
0552 };
0553 
0554 #ifdef CONFIG_SYSFS
0555 #define to_param_attr(n) container_of(n, struct param_attribute, mattr)
0556 
0557 static ssize_t param_attr_show(struct module_attribute *mattr,
0558                    struct module_kobject *mk, char *buf)
0559 {
0560     int count;
0561     struct param_attribute *attribute = to_param_attr(mattr);
0562 
0563     if (!attribute->param->ops->get)
0564         return -EPERM;
0565 
0566     kernel_param_lock(mk->mod);
0567     count = attribute->param->ops->get(buf, attribute->param);
0568     kernel_param_unlock(mk->mod);
0569     return count;
0570 }
0571 
0572 /* sysfs always hands a nul-terminated string in buf.  We rely on that. */
0573 static ssize_t param_attr_store(struct module_attribute *mattr,
0574                 struct module_kobject *mk,
0575                 const char *buf, size_t len)
0576 {
0577     int err;
0578     struct param_attribute *attribute = to_param_attr(mattr);
0579 
0580     if (!attribute->param->ops->set)
0581         return -EPERM;
0582 
0583     kernel_param_lock(mk->mod);
0584     if (param_check_unsafe(attribute->param))
0585         err = attribute->param->ops->set(buf, attribute->param);
0586     else
0587         err = -EPERM;
0588     kernel_param_unlock(mk->mod);
0589     if (!err)
0590         return len;
0591     return err;
0592 }
0593 #endif
0594 
0595 #ifdef CONFIG_MODULES
0596 #define __modinit
0597 #else
0598 #define __modinit __init
0599 #endif
0600 
0601 #ifdef CONFIG_SYSFS
0602 void kernel_param_lock(struct module *mod)
0603 {
0604     mutex_lock(KPARAM_MUTEX(mod));
0605 }
0606 
0607 void kernel_param_unlock(struct module *mod)
0608 {
0609     mutex_unlock(KPARAM_MUTEX(mod));
0610 }
0611 
0612 EXPORT_SYMBOL(kernel_param_lock);
0613 EXPORT_SYMBOL(kernel_param_unlock);
0614 
0615 /*
0616  * add_sysfs_param - add a parameter to sysfs
0617  * @mk: struct module_kobject
0618  * @kp: the actual parameter definition to add to sysfs
0619  * @name: name of parameter
0620  *
0621  * Create a kobject if for a (per-module) parameter if mp NULL, and
0622  * create file in sysfs.  Returns an error on out of memory.  Always cleans up
0623  * if there's an error.
0624  */
0625 static __modinit int add_sysfs_param(struct module_kobject *mk,
0626                      const struct kernel_param *kp,
0627                      const char *name)
0628 {
0629     struct module_param_attrs *new_mp;
0630     struct attribute **new_attrs;
0631     unsigned int i;
0632 
0633     /* We don't bother calling this with invisible parameters. */
0634     BUG_ON(!kp->perm);
0635 
0636     if (!mk->mp) {
0637         /* First allocation. */
0638         mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL);
0639         if (!mk->mp)
0640             return -ENOMEM;
0641         mk->mp->grp.name = "parameters";
0642         /* NULL-terminated attribute array. */
0643         mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]),
0644                         GFP_KERNEL);
0645         /* Caller will cleanup via free_module_param_attrs */
0646         if (!mk->mp->grp.attrs)
0647             return -ENOMEM;
0648     }
0649 
0650     /* Enlarge allocations. */
0651     new_mp = krealloc(mk->mp,
0652               sizeof(*mk->mp) +
0653               sizeof(mk->mp->attrs[0]) * (mk->mp->num + 1),
0654               GFP_KERNEL);
0655     if (!new_mp)
0656         return -ENOMEM;
0657     mk->mp = new_mp;
0658 
0659     /* Extra pointer for NULL terminator */
0660     new_attrs = krealloc(mk->mp->grp.attrs,
0661                  sizeof(mk->mp->grp.attrs[0]) * (mk->mp->num + 2),
0662                  GFP_KERNEL);
0663     if (!new_attrs)
0664         return -ENOMEM;
0665     mk->mp->grp.attrs = new_attrs;
0666 
0667     /* Tack new one on the end. */
0668     memset(&mk->mp->attrs[mk->mp->num], 0, sizeof(mk->mp->attrs[0]));
0669     sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr);
0670     mk->mp->attrs[mk->mp->num].param = kp;
0671     mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show;
0672     /* Do not allow runtime DAC changes to make param writable. */
0673     if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0)
0674         mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store;
0675     else
0676         mk->mp->attrs[mk->mp->num].mattr.store = NULL;
0677     mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name;
0678     mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm;
0679     mk->mp->num++;
0680 
0681     /* Fix up all the pointers, since krealloc can move us */
0682     for (i = 0; i < mk->mp->num; i++)
0683         mk->mp->grp.attrs[i] = &mk->mp->attrs[i].mattr.attr;
0684     mk->mp->grp.attrs[mk->mp->num] = NULL;
0685     return 0;
0686 }
0687 
0688 #ifdef CONFIG_MODULES
0689 static void free_module_param_attrs(struct module_kobject *mk)
0690 {
0691     if (mk->mp)
0692         kfree(mk->mp->grp.attrs);
0693     kfree(mk->mp);
0694     mk->mp = NULL;
0695 }
0696 
0697 /*
0698  * module_param_sysfs_setup - setup sysfs support for one module
0699  * @mod: module
0700  * @kparam: module parameters (array)
0701  * @num_params: number of module parameters
0702  *
0703  * Adds sysfs entries for module parameters under
0704  * /sys/module/[mod->name]/parameters/
0705  */
0706 int module_param_sysfs_setup(struct module *mod,
0707                  const struct kernel_param *kparam,
0708                  unsigned int num_params)
0709 {
0710     int i, err;
0711     bool params = false;
0712 
0713     for (i = 0; i < num_params; i++) {
0714         if (kparam[i].perm == 0)
0715             continue;
0716         err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
0717         if (err) {
0718             free_module_param_attrs(&mod->mkobj);
0719             return err;
0720         }
0721         params = true;
0722     }
0723 
0724     if (!params)
0725         return 0;
0726 
0727     /* Create the param group. */
0728     err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
0729     if (err)
0730         free_module_param_attrs(&mod->mkobj);
0731     return err;
0732 }
0733 
0734 /*
0735  * module_param_sysfs_remove - remove sysfs support for one module
0736  * @mod: module
0737  *
0738  * Remove sysfs entries for module parameters and the corresponding
0739  * kobject.
0740  */
0741 void module_param_sysfs_remove(struct module *mod)
0742 {
0743     if (mod->mkobj.mp) {
0744         sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
0745         /* We are positive that no one is using any param
0746          * attrs at this point.  Deallocate immediately. */
0747         free_module_param_attrs(&mod->mkobj);
0748     }
0749 }
0750 #endif
0751 
0752 void destroy_params(const struct kernel_param *params, unsigned num)
0753 {
0754     unsigned int i;
0755 
0756     for (i = 0; i < num; i++)
0757         if (params[i].ops->free)
0758             params[i].ops->free(params[i].arg);
0759 }
0760 
0761 static struct module_kobject * __init locate_module_kobject(const char *name)
0762 {
0763     struct module_kobject *mk;
0764     struct kobject *kobj;
0765     int err;
0766 
0767     kobj = kset_find_obj(module_kset, name);
0768     if (kobj) {
0769         mk = to_module_kobject(kobj);
0770     } else {
0771         mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
0772         BUG_ON(!mk);
0773 
0774         mk->mod = THIS_MODULE;
0775         mk->kobj.kset = module_kset;
0776         err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
0777                        "%s", name);
0778 #ifdef CONFIG_MODULES
0779         if (!err)
0780             err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
0781 #endif
0782         if (err) {
0783             kobject_put(&mk->kobj);
0784             pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n",
0785                 name, err);
0786             return NULL;
0787         }
0788 
0789         /* So that we hold reference in both cases. */
0790         kobject_get(&mk->kobj);
0791     }
0792 
0793     return mk;
0794 }
0795 
0796 static void __init kernel_add_sysfs_param(const char *name,
0797                       const struct kernel_param *kparam,
0798                       unsigned int name_skip)
0799 {
0800     struct module_kobject *mk;
0801     int err;
0802 
0803     mk = locate_module_kobject(name);
0804     if (!mk)
0805         return;
0806 
0807     /* We need to remove old parameters before adding more. */
0808     if (mk->mp)
0809         sysfs_remove_group(&mk->kobj, &mk->mp->grp);
0810 
0811     /* These should not fail at boot. */
0812     err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
0813     BUG_ON(err);
0814     err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
0815     BUG_ON(err);
0816     kobject_uevent(&mk->kobj, KOBJ_ADD);
0817     kobject_put(&mk->kobj);
0818 }
0819 
0820 /*
0821  * param_sysfs_builtin - add sysfs parameters for built-in modules
0822  *
0823  * Add module_parameters to sysfs for "modules" built into the kernel.
0824  *
0825  * The "module" name (KBUILD_MODNAME) is stored before a dot, the
0826  * "parameter" name is stored behind a dot in kernel_param->name. So,
0827  * extract the "module" name for all built-in kernel_param-eters,
0828  * and for all who have the same, call kernel_add_sysfs_param.
0829  */
0830 static void __init param_sysfs_builtin(void)
0831 {
0832     const struct kernel_param *kp;
0833     unsigned int name_len;
0834     char modname[MODULE_NAME_LEN];
0835 
0836     for (kp = __start___param; kp < __stop___param; kp++) {
0837         char *dot;
0838 
0839         if (kp->perm == 0)
0840             continue;
0841 
0842         dot = strchr(kp->name, '.');
0843         if (!dot) {
0844             /* This happens for core_param() */
0845             strcpy(modname, "kernel");
0846             name_len = 0;
0847         } else {
0848             name_len = dot - kp->name + 1;
0849             strlcpy(modname, kp->name, name_len);
0850         }
0851         kernel_add_sysfs_param(modname, kp, name_len);
0852     }
0853 }
0854 
0855 ssize_t __modver_version_show(struct module_attribute *mattr,
0856                   struct module_kobject *mk, char *buf)
0857 {
0858     struct module_version_attribute *vattr =
0859         container_of(mattr, struct module_version_attribute, mattr);
0860 
0861     return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version);
0862 }
0863 
0864 extern const struct module_version_attribute __start___modver[];
0865 extern const struct module_version_attribute __stop___modver[];
0866 
0867 static void __init version_sysfs_builtin(void)
0868 {
0869     const struct module_version_attribute *vattr;
0870     struct module_kobject *mk;
0871     int err;
0872 
0873     for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
0874         mk = locate_module_kobject(vattr->module_name);
0875         if (mk) {
0876             err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
0877             WARN_ON_ONCE(err);
0878             kobject_uevent(&mk->kobj, KOBJ_ADD);
0879             kobject_put(&mk->kobj);
0880         }
0881     }
0882 }
0883 
0884 /* module-related sysfs stuff */
0885 
0886 static ssize_t module_attr_show(struct kobject *kobj,
0887                 struct attribute *attr,
0888                 char *buf)
0889 {
0890     struct module_attribute *attribute;
0891     struct module_kobject *mk;
0892     int ret;
0893 
0894     attribute = to_module_attr(attr);
0895     mk = to_module_kobject(kobj);
0896 
0897     if (!attribute->show)
0898         return -EIO;
0899 
0900     ret = attribute->show(attribute, mk, buf);
0901 
0902     return ret;
0903 }
0904 
0905 static ssize_t module_attr_store(struct kobject *kobj,
0906                 struct attribute *attr,
0907                 const char *buf, size_t len)
0908 {
0909     struct module_attribute *attribute;
0910     struct module_kobject *mk;
0911     int ret;
0912 
0913     attribute = to_module_attr(attr);
0914     mk = to_module_kobject(kobj);
0915 
0916     if (!attribute->store)
0917         return -EIO;
0918 
0919     ret = attribute->store(attribute, mk, buf, len);
0920 
0921     return ret;
0922 }
0923 
0924 static const struct sysfs_ops module_sysfs_ops = {
0925     .show = module_attr_show,
0926     .store = module_attr_store,
0927 };
0928 
0929 static int uevent_filter(struct kobject *kobj)
0930 {
0931     const struct kobj_type *ktype = get_ktype(kobj);
0932 
0933     if (ktype == &module_ktype)
0934         return 1;
0935     return 0;
0936 }
0937 
0938 static const struct kset_uevent_ops module_uevent_ops = {
0939     .filter = uevent_filter,
0940 };
0941 
0942 struct kset *module_kset;
0943 int module_sysfs_initialized;
0944 
0945 static void module_kobj_release(struct kobject *kobj)
0946 {
0947     struct module_kobject *mk = to_module_kobject(kobj);
0948     complete(mk->kobj_completion);
0949 }
0950 
0951 struct kobj_type module_ktype = {
0952     .release   =    module_kobj_release,
0953     .sysfs_ops =    &module_sysfs_ops,
0954 };
0955 
0956 /*
0957  * param_sysfs_init - wrapper for built-in params support
0958  */
0959 static int __init param_sysfs_init(void)
0960 {
0961     module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
0962     if (!module_kset) {
0963         printk(KERN_WARNING "%s (%d): error creating kset\n",
0964             __FILE__, __LINE__);
0965         return -ENOMEM;
0966     }
0967     module_sysfs_initialized = 1;
0968 
0969     version_sysfs_builtin();
0970     param_sysfs_builtin();
0971 
0972     return 0;
0973 }
0974 subsys_initcall(param_sysfs_init);
0975 
0976 #endif /* CONFIG_SYSFS */