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