aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/mm/hugetlbpage.c3
-rw-r--r--include/asm-generic/vmlinux.lds.h35
-rw-r--r--include/linux/moduleparam.h51
-rw-r--r--init/main.c65
-rw-r--r--kernel/module.c3
-rw-r--r--kernel/params.c16
6 files changed, 132 insertions, 41 deletions
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 57c7465e656e..a3e628727697 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -310,7 +310,8 @@ void __init reserve_hugetlb_gpages(void)
310 int i; 310 int i;
311 311
312 strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); 312 strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE);
313 parse_args("hugetlb gpages", cmdline, NULL, 0, &do_gpage_early_setup); 313 parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0,
314 &do_gpage_early_setup);
314 315
315 /* 316 /*
316 * Walk gpage list in reverse, allocating larger page sizes first. 317 * Walk gpage list in reverse, allocating larger page sizes first.
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 798603e8ec38..8aeadf6b553a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -616,30 +616,23 @@
616 *(.init.setup) \ 616 *(.init.setup) \
617 VMLINUX_SYMBOL(__setup_end) = .; 617 VMLINUX_SYMBOL(__setup_end) = .;
618 618
619#define INITCALLS \ 619#define INIT_CALLS_LEVEL(level) \
620 *(.initcallearly.init) \ 620 VMLINUX_SYMBOL(__initcall##level##_start) = .; \
621 VMLINUX_SYMBOL(__early_initcall_end) = .; \ 621 *(.initcall##level##.init) \
622 *(.initcall0.init) \ 622 *(.initcall##level##s.init) \
623 *(.initcall0s.init) \
624 *(.initcall1.init) \
625 *(.initcall1s.init) \
626 *(.initcall2.init) \
627 *(.initcall2s.init) \
628 *(.initcall3.init) \
629 *(.initcall3s.init) \
630 *(.initcall4.init) \
631 *(.initcall4s.init) \
632 *(.initcall5.init) \
633 *(.initcall5s.init) \
634 *(.initcallrootfs.init) \
635 *(.initcall6.init) \
636 *(.initcall6s.init) \
637 *(.initcall7.init) \
638 *(.initcall7s.init)
639 623
640#define INIT_CALLS \ 624#define INIT_CALLS \
641 VMLINUX_SYMBOL(__initcall_start) = .; \ 625 VMLINUX_SYMBOL(__initcall_start) = .; \
642 INITCALLS \ 626 *(.initcallearly.init) \
627 INIT_CALLS_LEVEL(0) \
628 INIT_CALLS_LEVEL(1) \
629 INIT_CALLS_LEVEL(2) \
630 INIT_CALLS_LEVEL(3) \
631 INIT_CALLS_LEVEL(4) \
632 INIT_CALLS_LEVEL(5) \
633 INIT_CALLS_LEVEL(rootfs) \
634 INIT_CALLS_LEVEL(6) \
635 INIT_CALLS_LEVEL(7) \
643 VMLINUX_SYMBOL(__initcall_end) = .; 636 VMLINUX_SYMBOL(__initcall_end) = .;
644 637
645#define CON_INITCALL \ 638#define CON_INITCALL \
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 4daa895648d9..ea36486378d8 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -51,7 +51,7 @@ struct kernel_param {
51 const char *name; 51 const char *name;
52 const struct kernel_param_ops *ops; 52 const struct kernel_param_ops *ops;
53 u16 perm; 53 u16 perm;
54 u16 flags; 54 s16 level;
55 union { 55 union {
56 void *arg; 56 void *arg;
57 const struct kparam_string *str; 57 const struct kparam_string *str;
@@ -128,7 +128,40 @@ struct kparam_array
128 * The ops can have NULL set or get functions. 128 * The ops can have NULL set or get functions.
129 */ 129 */
130#define module_param_cb(name, ops, arg, perm) \ 130#define module_param_cb(name, ops, arg, perm) \
131 __module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm) 131 __module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, 0)
132
133/**
134 * <level>_param_cb - general callback for a module/cmdline parameter
135 * to be evaluated before certain initcall level
136 * @name: a valid C identifier which is the parameter name.
137 * @ops: the set & get operations for this parameter.
138 * @perm: visibility in sysfs.
139 *
140 * The ops can have NULL set or get functions.
141 */
142#define __level_param_cb(name, ops, arg, perm, level) \
143 __module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, level)
144
145#define core_param_cb(name, ops, arg, perm) \
146 __level_param_cb(name, ops, arg, perm, 1)
147
148#define postcore_param_cb(name, ops, arg, perm) \
149 __level_param_cb(name, ops, arg, perm, 2)
150
151#define arch_param_cb(name, ops, arg, perm) \
152 __level_param_cb(name, ops, arg, perm, 3)
153
154#define subsys_param_cb(name, ops, arg, perm) \
155 __level_param_cb(name, ops, arg, perm, 4)
156
157#define fs_param_cb(name, ops, arg, perm) \
158 __level_param_cb(name, ops, arg, perm, 5)
159
160#define device_param_cb(name, ops, arg, perm) \
161 __level_param_cb(name, ops, arg, perm, 6)
162
163#define late_param_cb(name, ops, arg, perm) \
164 __level_param_cb(name, ops, arg, perm, 7)
132 165
133/* On alpha, ia64 and ppc64 relocations to global data cannot go into 166/* On alpha, ia64 and ppc64 relocations to global data cannot go into
134 read-only sections (which is part of respective UNIX ABI on these 167 read-only sections (which is part of respective UNIX ABI on these
@@ -142,7 +175,7 @@ struct kparam_array
142 175
143/* This is the fundamental function for registering boot/module 176/* This is the fundamental function for registering boot/module
144 parameters. */ 177 parameters. */
145#define __module_param_call(prefix, name, ops, arg, perm) \ 178#define __module_param_call(prefix, name, ops, arg, perm, level) \
146 /* Default value instead of permissions? */ \ 179 /* Default value instead of permissions? */ \
147 static int __param_perm_check_##name __attribute__((unused)) = \ 180 static int __param_perm_check_##name __attribute__((unused)) = \
148 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ 181 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
@@ -151,7 +184,7 @@ struct kparam_array
151 static struct kernel_param __moduleparam_const __param_##name \ 184 static struct kernel_param __moduleparam_const __param_##name \
152 __used \ 185 __used \
153 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ 186 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
154 = { __param_str_##name, ops, perm, 0, { arg } } 187 = { __param_str_##name, ops, perm, level, { arg } }
155 188
156/* Obsolete - use module_param_cb() */ 189/* Obsolete - use module_param_cb() */
157#define module_param_call(name, set, get, arg, perm) \ 190#define module_param_call(name, set, get, arg, perm) \
@@ -159,7 +192,7 @@ struct kparam_array
159 { (void *)set, (void *)get }; \ 192 { (void *)set, (void *)get }; \
160 __module_param_call(MODULE_PARAM_PREFIX, \ 193 __module_param_call(MODULE_PARAM_PREFIX, \
161 name, &__param_ops_##name, arg, \ 194 name, &__param_ops_##name, arg, \
162 (perm) + sizeof(__check_old_set_param(set))*0) 195 (perm) + sizeof(__check_old_set_param(set))*0, 0)
163 196
164/* We don't get oldget: it's often a new-style param_get_uint, etc. */ 197/* We don't get oldget: it's often a new-style param_get_uint, etc. */
165static inline int 198static inline int
@@ -239,7 +272,7 @@ static inline void __kernel_param_unlock(void)
239 */ 272 */
240#define core_param(name, var, type, perm) \ 273#define core_param(name, var, type, perm) \
241 param_check_##type(name, &(var)); \ 274 param_check_##type(name, &(var)); \
242 __module_param_call("", name, &param_ops_##type, &var, perm) 275 __module_param_call("", name, &param_ops_##type, &var, perm, 0)
243#endif /* !MODULE */ 276#endif /* !MODULE */
244 277
245/** 278/**
@@ -257,7 +290,7 @@ static inline void __kernel_param_unlock(void)
257 = { len, string }; \ 290 = { len, string }; \
258 __module_param_call(MODULE_PARAM_PREFIX, name, \ 291 __module_param_call(MODULE_PARAM_PREFIX, name, \
259 &param_ops_string, \ 292 &param_ops_string, \
260 .str = &__param_string_##name, perm); \ 293 .str = &__param_string_##name, perm, 0); \
261 __MODULE_PARM_TYPE(name, "string") 294 __MODULE_PARM_TYPE(name, "string")
262 295
263/** 296/**
@@ -285,6 +318,8 @@ extern int parse_args(const char *name,
285 char *args, 318 char *args,
286 const struct kernel_param *params, 319 const struct kernel_param *params,
287 unsigned num, 320 unsigned num,
321 s16 level_min,
322 s16 level_max,
288 int (*unknown)(char *param, char *val)); 323 int (*unknown)(char *param, char *val));
289 324
290/* Called by module remove. */ 325/* Called by module remove. */
@@ -396,7 +431,7 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
396 __module_param_call(MODULE_PARAM_PREFIX, name, \ 431 __module_param_call(MODULE_PARAM_PREFIX, name, \
397 &param_array_ops, \ 432 &param_array_ops, \
398 .arr = &__param_arr_##name, \ 433 .arr = &__param_arr_##name, \
399 perm); \ 434 perm, 0); \
400 __MODULE_PARM_TYPE(name, "array of " #type) 435 __MODULE_PARM_TYPE(name, "array of " #type)
401 436
402extern struct kernel_param_ops param_array_ops; 437extern struct kernel_param_ops param_array_ops;
diff --git a/init/main.c b/init/main.c
index c24805c824b9..439715858ba0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -400,7 +400,7 @@ static int __init do_early_param(char *param, char *val)
400 400
401void __init parse_early_options(char *cmdline) 401void __init parse_early_options(char *cmdline)
402{ 402{
403 parse_args("early options", cmdline, NULL, 0, do_early_param); 403 parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param);
404} 404}
405 405
406/* Arch code calls this early on, or if not, just before other parsing. */ 406/* Arch code calls this early on, or if not, just before other parsing. */
@@ -503,7 +503,7 @@ asmlinkage void __init start_kernel(void)
503 parse_early_param(); 503 parse_early_param();
504 parse_args("Booting kernel", static_command_line, __start___param, 504 parse_args("Booting kernel", static_command_line, __start___param,
505 __stop___param - __start___param, 505 __stop___param - __start___param,
506 &unknown_bootoption); 506 0, 0, &unknown_bootoption);
507 507
508 jump_label_init(); 508 jump_label_init();
509 509
@@ -699,16 +699,69 @@ int __init_or_module do_one_initcall(initcall_t fn)
699} 699}
700 700
701 701
702extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; 702extern initcall_t __initcall_start[];
703extern initcall_t __initcall0_start[];
704extern initcall_t __initcall1_start[];
705extern initcall_t __initcall2_start[];
706extern initcall_t __initcall3_start[];
707extern initcall_t __initcall4_start[];
708extern initcall_t __initcall5_start[];
709extern initcall_t __initcall6_start[];
710extern initcall_t __initcall7_start[];
711extern initcall_t __initcall_end[];
712
713static initcall_t *initcall_levels[] __initdata = {
714 __initcall0_start,
715 __initcall1_start,
716 __initcall2_start,
717 __initcall3_start,
718 __initcall4_start,
719 __initcall5_start,
720 __initcall6_start,
721 __initcall7_start,
722 __initcall_end,
723};
724
725static char *initcall_level_names[] __initdata = {
726 "early parameters",
727 "core parameters",
728 "postcore parameters",
729 "arch parameters",
730 "subsys parameters",
731 "fs parameters",
732 "device parameters",
733 "late parameters",
734};
735
736static int __init ignore_unknown_bootoption(char *param, char *val)
737{
738 return 0;
739}
703 740
704static void __init do_initcalls(void) 741static void __init do_initcall_level(int level)
705{ 742{
743 extern const struct kernel_param __start___param[], __stop___param[];
706 initcall_t *fn; 744 initcall_t *fn;
707 745
708 for (fn = __early_initcall_end; fn < __initcall_end; fn++) 746 strcpy(static_command_line, saved_command_line);
747 parse_args(initcall_level_names[level],
748 static_command_line, __start___param,
749 __stop___param - __start___param,
750 level, level,
751 ignore_unknown_bootoption);
752
753 for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
709 do_one_initcall(*fn); 754 do_one_initcall(*fn);
710} 755}
711 756
757static void __init do_initcalls(void)
758{
759 int level;
760
761 for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
762 do_initcall_level(level);
763}
764
712/* 765/*
713 * Ok, the machine is now initialized. None of the devices 766 * Ok, the machine is now initialized. None of the devices
714 * have been touched yet, but the CPU subsystem is up and 767 * have been touched yet, but the CPU subsystem is up and
@@ -732,7 +785,7 @@ static void __init do_pre_smp_initcalls(void)
732{ 785{
733 initcall_t *fn; 786 initcall_t *fn;
734 787
735 for (fn = __initcall_start; fn < __early_initcall_end; fn++) 788 for (fn = __initcall_start; fn < __initcall0_start; fn++)
736 do_one_initcall(*fn); 789 do_one_initcall(*fn);
737} 790}
738 791
diff --git a/kernel/module.c b/kernel/module.c
index 7e31da9750c0..6f6651a54590 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2923,7 +2923,8 @@ static struct module *load_module(void __user *umod,
2923 mutex_unlock(&module_mutex); 2923 mutex_unlock(&module_mutex);
2924 2924
2925 /* Module is ready to execute: parsing args may do that. */ 2925 /* Module is ready to execute: parsing args may do that. */
2926 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL); 2926 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
2927 -32768, 32767, NULL);
2927 if (err < 0) 2928 if (err < 0)
2928 goto unlink; 2929 goto unlink;
2929 2930
diff --git a/kernel/params.c b/kernel/params.c
index 508828afb874..f37d82631347 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -87,6 +87,8 @@ static int parse_one(char *param,
87 char *val, 87 char *val,
88 const struct kernel_param *params, 88 const struct kernel_param *params,
89 unsigned num_params, 89 unsigned num_params,
90 s16 min_level,
91 s16 max_level,
90 int (*handle_unknown)(char *param, char *val)) 92 int (*handle_unknown)(char *param, char *val))
91{ 93{
92 unsigned int i; 94 unsigned int i;
@@ -95,6 +97,9 @@ static int parse_one(char *param,
95 /* Find parameter */ 97 /* Find parameter */
96 for (i = 0; i < num_params; i++) { 98 for (i = 0; i < num_params; i++) {
97 if (parameq(param, params[i].name)) { 99 if (parameq(param, params[i].name)) {
100 if (params[i].level < min_level
101 || params[i].level > max_level)
102 return 0;
98 /* No one handled NULL, so do it here. */ 103 /* No one handled NULL, so do it here. */
99 if (!val && params[i].ops->set != param_set_bool 104 if (!val && params[i].ops->set != param_set_bool
100 && params[i].ops->set != param_set_bint) 105 && params[i].ops->set != param_set_bint)
@@ -174,6 +179,8 @@ int parse_args(const char *name,
174 char *args, 179 char *args,
175 const struct kernel_param *params, 180 const struct kernel_param *params,
176 unsigned num, 181 unsigned num,
182 s16 min_level,
183 s16 max_level,
177 int (*unknown)(char *param, char *val)) 184 int (*unknown)(char *param, char *val))
178{ 185{
179 char *param, *val; 186 char *param, *val;
@@ -189,7 +196,8 @@ int parse_args(const char *name,
189 196
190 args = next_arg(args, &param, &val); 197 args = next_arg(args, &param, &val);
191 irq_was_disabled = irqs_disabled(); 198 irq_was_disabled = irqs_disabled();
192 ret = parse_one(param, val, params, num, unknown); 199 ret = parse_one(param, val, params, num,
200 min_level, max_level, unknown);
193 if (irq_was_disabled && !irqs_disabled()) { 201 if (irq_was_disabled && !irqs_disabled()) {
194 printk(KERN_WARNING "parse_args(): option '%s' enabled " 202 printk(KERN_WARNING "parse_args(): option '%s' enabled "
195 "irq's!\n", param); 203 "irq's!\n", param);
@@ -374,7 +382,7 @@ static int param_array(const char *name,
374 unsigned int min, unsigned int max, 382 unsigned int min, unsigned int max,
375 void *elem, int elemsize, 383 void *elem, int elemsize,
376 int (*set)(const char *, const struct kernel_param *kp), 384 int (*set)(const char *, const struct kernel_param *kp),
377 u16 flags, 385 s16 level,
378 unsigned int *num) 386 unsigned int *num)
379{ 387{
380 int ret; 388 int ret;
@@ -384,7 +392,7 @@ static int param_array(const char *name,
384 /* Get the name right for errors. */ 392 /* Get the name right for errors. */
385 kp.name = name; 393 kp.name = name;
386 kp.arg = elem; 394 kp.arg = elem;
387 kp.flags = flags; 395 kp.level = level;
388 396
389 *num = 0; 397 *num = 0;
390 /* We expect a comma-separated list of values. */ 398 /* We expect a comma-separated list of values. */
@@ -425,7 +433,7 @@ static int param_array_set(const char *val, const struct kernel_param *kp)
425 unsigned int temp_num; 433 unsigned int temp_num;
426 434
427 return param_array(kp->name, val, 1, arr->max, arr->elem, 435 return param_array(kp->name, val, 1, arr->max, arr->elem,
428 arr->elemsize, arr->ops->set, kp->flags, 436 arr->elemsize, arr->ops->set, kp->level,
429 arr->num ?: &temp_num); 437 arr->num ?: &temp_num);
430} 438}
431 439