linux/kernel/params.c
<<
>>
Prefs
   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 kset *kset, struct kobject *kobj)
 930{
 931        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 */
 977