aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--arch/powerpc/mm/hugetlbpage.c3
-rw-r--r--include/asm-generic/vmlinux.lds.h35
-rw-r--r--include/linux/module.h32
-rw-r--r--include/linux/moduleparam.h58
-rw-r--r--init/main.c65
-rw-r--r--kernel/module.c37
-rw-r--r--kernel/params.c39
8 files changed, 172 insertions, 99 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 58eac231fe6..e2f8c297a8a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1869,6 +1869,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1869 shutdown the other cpus. Instead use the REBOOT_VECTOR 1869 shutdown the other cpus. Instead use the REBOOT_VECTOR
1870 irq. 1870 irq.
1871 1871
1872 nomodule Disable module load
1873
1872 nopat [X86] Disable PAT (page attribute table extension of 1874 nopat [X86] Disable PAT (page attribute table extension of
1873 pagetables) support. 1875 pagetables) support.
1874 1876
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 57c7465e656..a3e62872769 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 798603e8ec3..8aeadf6b553 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/module.h b/include/linux/module.h
index 4598bf03e98..fbcafe2ee13 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -21,8 +21,6 @@
21#include <linux/percpu.h> 21#include <linux/percpu.h>
22#include <asm/module.h> 22#include <asm/module.h>
23 23
24#include <trace/events/module.h>
25
26/* Not Yet Implemented */ 24/* Not Yet Implemented */
27#define MODULE_SUPPORTED_DEVICE(name) 25#define MODULE_SUPPORTED_DEVICE(name)
28 26
@@ -452,33 +450,11 @@ void symbol_put_addr(void *addr);
452 450
453/* Sometimes we know we already have a refcount, and it's easier not 451/* Sometimes we know we already have a refcount, and it's easier not
454 to handle the error case (which only happens with rmmod --wait). */ 452 to handle the error case (which only happens with rmmod --wait). */
455static inline void __module_get(struct module *module) 453extern void __module_get(struct module *module);
456{
457 if (module) {
458 preempt_disable();
459 __this_cpu_inc(module->refptr->incs);
460 trace_module_get(module, _THIS_IP_);
461 preempt_enable();
462 }
463}
464
465static inline int try_module_get(struct module *module)
466{
467 int ret = 1;
468
469 if (module) {
470 preempt_disable();
471 454
472 if (likely(module_is_live(module))) { 455/* This is the Right Way to get a module: if it fails, it's being removed,
473 __this_cpu_inc(module->refptr->incs); 456 * so pretend it's not there. */
474 trace_module_get(module, _THIS_IP_); 457extern bool try_module_get(struct module *module);
475 } else
476 ret = 0;
477
478 preempt_enable();
479 }
480 return ret;
481}
482 458
483extern void module_put(struct module *module); 459extern void module_put(struct module *module);
484 460
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index c47f4d60db0..ea36486378d 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -47,14 +47,11 @@ struct kernel_param_ops {
47 void (*free)(void *arg); 47 void (*free)(void *arg);
48}; 48};
49 49
50/* Flag bits for kernel_param.flags */
51#define KPARAM_ISBOOL 2
52
53struct kernel_param { 50struct kernel_param {
54 const char *name; 51 const char *name;
55 const struct kernel_param_ops *ops; 52 const struct kernel_param_ops *ops;
56 u16 perm; 53 u16 perm;
57 u16 flags; 54 s16 level;
58 union { 55 union {
59 void *arg; 56 void *arg;
60 const struct kparam_string *str; 57 const struct kparam_string *str;
@@ -131,8 +128,40 @@ struct kparam_array
131 * The ops can have NULL set or get functions. 128 * The ops can have NULL set or get functions.
132 */ 129 */
133#define module_param_cb(name, ops, arg, perm) \ 130#define module_param_cb(name, ops, arg, perm) \
134 __module_param_call(MODULE_PARAM_PREFIX, \ 131 __module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, 0)
135 name, ops, arg, __same_type((arg), bool *), perm) 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)
136 165
137/* 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
138 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
@@ -146,7 +175,7 @@ struct kparam_array
146 175
147/* This is the fundamental function for registering boot/module 176/* This is the fundamental function for registering boot/module
148 parameters. */ 177 parameters. */
149#define __module_param_call(prefix, name, ops, arg, isbool, perm) \ 178#define __module_param_call(prefix, name, ops, arg, perm, level) \
150 /* Default value instead of permissions? */ \ 179 /* Default value instead of permissions? */ \
151 static int __param_perm_check_##name __attribute__((unused)) = \ 180 static int __param_perm_check_##name __attribute__((unused)) = \
152 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ 181 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
@@ -155,8 +184,7 @@ struct kparam_array
155 static struct kernel_param __moduleparam_const __param_##name \ 184 static struct kernel_param __moduleparam_const __param_##name \
156 __used \ 185 __used \
157 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ 186 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
158 = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ 187 = { __param_str_##name, ops, perm, level, { arg } }
159 { arg } }
160 188
161/* Obsolete - use module_param_cb() */ 189/* Obsolete - use module_param_cb() */
162#define module_param_call(name, set, get, arg, perm) \ 190#define module_param_call(name, set, get, arg, perm) \
@@ -164,8 +192,7 @@ struct kparam_array
164 { (void *)set, (void *)get }; \ 192 { (void *)set, (void *)get }; \
165 __module_param_call(MODULE_PARAM_PREFIX, \ 193 __module_param_call(MODULE_PARAM_PREFIX, \
166 name, &__param_ops_##name, arg, \ 194 name, &__param_ops_##name, arg, \
167 __same_type(arg, bool *), \ 195 (perm) + sizeof(__check_old_set_param(set))*0, 0)
168 (perm) + sizeof(__check_old_set_param(set))*0)
169 196
170/* 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. */
171static inline int 198static inline int
@@ -245,8 +272,7 @@ static inline void __kernel_param_unlock(void)
245 */ 272 */
246#define core_param(name, var, type, perm) \ 273#define core_param(name, var, type, perm) \
247 param_check_##type(name, &(var)); \ 274 param_check_##type(name, &(var)); \
248 __module_param_call("", name, &param_ops_##type, \ 275 __module_param_call("", name, &param_ops_##type, &var, perm, 0)
249 &var, __same_type(var, bool), perm)
250#endif /* !MODULE */ 276#endif /* !MODULE */
251 277
252/** 278/**
@@ -264,7 +290,7 @@ static inline void __kernel_param_unlock(void)
264 = { len, string }; \ 290 = { len, string }; \
265 __module_param_call(MODULE_PARAM_PREFIX, name, \ 291 __module_param_call(MODULE_PARAM_PREFIX, name, \
266 &param_ops_string, \ 292 &param_ops_string, \
267 .str = &__param_string_##name, 0, perm); \ 293 .str = &__param_string_##name, perm, 0); \
268 __MODULE_PARM_TYPE(name, "string") 294 __MODULE_PARM_TYPE(name, "string")
269 295
270/** 296/**
@@ -292,6 +318,8 @@ extern int parse_args(const char *name,
292 char *args, 318 char *args,
293 const struct kernel_param *params, 319 const struct kernel_param *params,
294 unsigned num, 320 unsigned num,
321 s16 level_min,
322 s16 level_max,
295 int (*unknown)(char *param, char *val)); 323 int (*unknown)(char *param, char *val));
296 324
297/* Called by module remove. */ 325/* Called by module remove. */
@@ -403,7 +431,7 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
403 __module_param_call(MODULE_PARAM_PREFIX, name, \ 431 __module_param_call(MODULE_PARAM_PREFIX, name, \
404 &param_array_ops, \ 432 &param_array_ops, \
405 .arr = &__param_arr_##name, \ 433 .arr = &__param_arr_##name, \
406 __same_type(array[0], bool), perm); \ 434 perm, 0); \
407 __MODULE_PARM_TYPE(name, "array of " #type) 435 __MODULE_PARM_TYPE(name, "array of " #type)
408 436
409extern 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 c24805c824b..439715858ba 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 2c932760fd3..78ac6ec1e42 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -105,6 +105,7 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
105 105
106/* Block module loading/unloading? */ 106/* Block module loading/unloading? */
107int modules_disabled = 0; 107int modules_disabled = 0;
108core_param(nomodule, modules_disabled, bint, 0);
108 109
109/* Waiting for a module to finish initializing? */ 110/* Waiting for a module to finish initializing? */
110static DECLARE_WAIT_QUEUE_HEAD(module_wq); 111static DECLARE_WAIT_QUEUE_HEAD(module_wq);
@@ -903,6 +904,36 @@ static ssize_t show_refcnt(struct module_attribute *mattr,
903static struct module_attribute modinfo_refcnt = 904static struct module_attribute modinfo_refcnt =
904 __ATTR(refcnt, 0444, show_refcnt, NULL); 905 __ATTR(refcnt, 0444, show_refcnt, NULL);
905 906
907void __module_get(struct module *module)
908{
909 if (module) {
910 preempt_disable();
911 __this_cpu_inc(module->refptr->incs);
912 trace_module_get(module, _RET_IP_);
913 preempt_enable();
914 }
915}
916EXPORT_SYMBOL(__module_get);
917
918bool try_module_get(struct module *module)
919{
920 bool ret = true;
921
922 if (module) {
923 preempt_disable();
924
925 if (likely(module_is_live(module))) {
926 __this_cpu_inc(module->refptr->incs);
927 trace_module_get(module, _RET_IP_);
928 } else
929 ret = false;
930
931 preempt_enable();
932 }
933 return ret;
934}
935EXPORT_SYMBOL(try_module_get);
936
906void module_put(struct module *module) 937void module_put(struct module *module)
907{ 938{
908 if (module) { 939 if (module) {
@@ -2380,8 +2411,7 @@ static int copy_and_check(struct load_info *info,
2380 return -ENOEXEC; 2411 return -ENOEXEC;
2381 2412
2382 /* Suck in entire file: we'll want most of it. */ 2413 /* Suck in entire file: we'll want most of it. */
2383 /* vmalloc barfs on "unusual" numbers. Check here */ 2414 if ((hdr = vmalloc(len)) == NULL)
2384 if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
2385 return -ENOMEM; 2415 return -ENOMEM;
2386 2416
2387 if (copy_from_user(hdr, umod, len) != 0) { 2417 if (copy_from_user(hdr, umod, len) != 0) {
@@ -2922,7 +2952,8 @@ static struct module *load_module(void __user *umod,
2922 mutex_unlock(&module_mutex); 2952 mutex_unlock(&module_mutex);
2923 2953
2924 /* Module is ready to execute: parsing args may do that. */ 2954 /* Module is ready to execute: parsing args may do that. */
2925 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL); 2955 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
2956 -32768, 32767, NULL);
2926 if (err < 0) 2957 if (err < 0)
2927 goto unlink; 2958 goto unlink;
2928 2959
diff --git a/kernel/params.c b/kernel/params.c
index 47f5bf12434..f37d8263134 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);
@@ -297,35 +305,18 @@ EXPORT_SYMBOL(param_ops_charp);
297/* Actually could be a bool or an int, for historical reasons. */ 305/* Actually could be a bool or an int, for historical reasons. */
298int param_set_bool(const char *val, const struct kernel_param *kp) 306int param_set_bool(const char *val, const struct kernel_param *kp)
299{ 307{
300 bool v;
301 int ret;
302
303 /* No equals means "set"... */ 308 /* No equals means "set"... */
304 if (!val) val = "1"; 309 if (!val) val = "1";
305 310
306 /* One of =[yYnN01] */ 311 /* One of =[yYnN01] */
307 ret = strtobool(val, &v); 312 return strtobool(val, kp->arg);
308 if (ret)
309 return ret;
310
311 if (kp->flags & KPARAM_ISBOOL)
312 *(bool *)kp->arg = v;
313 else
314 *(int *)kp->arg = v;
315 return 0;
316} 313}
317EXPORT_SYMBOL(param_set_bool); 314EXPORT_SYMBOL(param_set_bool);
318 315
319int param_get_bool(char *buffer, const struct kernel_param *kp) 316int param_get_bool(char *buffer, const struct kernel_param *kp)
320{ 317{
321 bool val;
322 if (kp->flags & KPARAM_ISBOOL)
323 val = *(bool *)kp->arg;
324 else
325 val = *(int *)kp->arg;
326
327 /* Y and N chosen as being relatively non-coder friendly */ 318 /* Y and N chosen as being relatively non-coder friendly */
328 return sprintf(buffer, "%c", val ? 'Y' : 'N'); 319 return sprintf(buffer, "%c", *(bool *)kp->arg ? 'Y' : 'N');
329} 320}
330EXPORT_SYMBOL(param_get_bool); 321EXPORT_SYMBOL(param_get_bool);
331 322
@@ -343,7 +334,6 @@ int param_set_invbool(const char *val, const struct kernel_param *kp)
343 struct kernel_param dummy; 334 struct kernel_param dummy;
344 335
345 dummy.arg = &boolval; 336 dummy.arg = &boolval;
346 dummy.flags = KPARAM_ISBOOL;
347 ret = param_set_bool(val, &dummy); 337 ret = param_set_bool(val, &dummy);
348 if (ret == 0) 338 if (ret == 0)
349 *(bool *)kp->arg = !boolval; 339 *(bool *)kp->arg = !boolval;
@@ -372,7 +362,6 @@ int param_set_bint(const char *val, const struct kernel_param *kp)
372 /* Match bool exactly, by re-using it. */ 362 /* Match bool exactly, by re-using it. */
373 boolkp = *kp; 363 boolkp = *kp;
374 boolkp.arg = &v; 364 boolkp.arg = &v;
375 boolkp.flags |= KPARAM_ISBOOL;
376 365
377 ret = param_set_bool(val, &boolkp); 366 ret = param_set_bool(val, &boolkp);
378 if (ret == 0) 367 if (ret == 0)
@@ -393,7 +382,7 @@ static int param_array(const char *name,
393 unsigned int min, unsigned int max, 382 unsigned int min, unsigned int max,
394 void *elem, int elemsize, 383 void *elem, int elemsize,
395 int (*set)(const char *, const struct kernel_param *kp), 384 int (*set)(const char *, const struct kernel_param *kp),
396 u16 flags, 385 s16 level,
397 unsigned int *num) 386 unsigned int *num)
398{ 387{
399 int ret; 388 int ret;
@@ -403,7 +392,7 @@ static int param_array(const char *name,
403 /* Get the name right for errors. */ 392 /* Get the name right for errors. */
404 kp.name = name; 393 kp.name = name;
405 kp.arg = elem; 394 kp.arg = elem;
406 kp.flags = flags; 395 kp.level = level;
407 396
408 *num = 0; 397 *num = 0;
409 /* We expect a comma-separated list of values. */ 398 /* We expect a comma-separated list of values. */
@@ -444,7 +433,7 @@ static int param_array_set(const char *val, const struct kernel_param *kp)
444 unsigned int temp_num; 433 unsigned int temp_num;
445 434
446 return param_array(kp->name, val, 1, arr->max, arr->elem, 435 return param_array(kp->name, val, 1, arr->max, arr->elem,
447 arr->elemsize, arr->ops->set, kp->flags, 436 arr->elemsize, arr->ops->set, kp->level,
448 arr->num ?: &temp_num); 437 arr->num ?: &temp_num);
449} 438}
450 439