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