aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/moduleparam.h2
-rw-r--r--init/main.c33
-rw-r--r--kernel/module.c12
-rw-r--r--kernel/params.c25
4 files changed, 53 insertions, 19 deletions
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 204a67743804..b1990c5524e1 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -321,7 +321,7 @@ extern bool parameq(const char *name1, const char *name2);
321extern bool parameqn(const char *name1, const char *name2, size_t n); 321extern bool parameqn(const char *name1, const char *name2, size_t n);
322 322
323/* Called on module insert or kernel boot */ 323/* Called on module insert or kernel boot */
324extern int parse_args(const char *name, 324extern char *parse_args(const char *name,
325 char *args, 325 char *args,
326 const struct kernel_param *params, 326 const struct kernel_param *params,
327 unsigned num, 327 unsigned num,
diff --git a/init/main.c b/init/main.c
index 9c7fd4c9249f..e9d458b5d77b 100644
--- a/init/main.c
+++ b/init/main.c
@@ -252,6 +252,27 @@ static int __init repair_env_string(char *param, char *val, const char *unused)
252 return 0; 252 return 0;
253} 253}
254 254
255/* Anything after -- gets handed straight to init. */
256static int __init set_init_arg(char *param, char *val, const char *unused)
257{
258 unsigned int i;
259
260 if (panic_later)
261 return 0;
262
263 repair_env_string(param, val, unused);
264
265 for (i = 0; argv_init[i]; i++) {
266 if (i == MAX_INIT_ARGS) {
267 panic_later = "init";
268 panic_param = param;
269 return 0;
270 }
271 }
272 argv_init[i] = param;
273 return 0;
274}
275
255/* 276/*
256 * Unknown boot options get handed to init, unless they look like 277 * Unknown boot options get handed to init, unless they look like
257 * unused parameters (modprobe will find them in /proc/cmdline). 278 * unused parameters (modprobe will find them in /proc/cmdline).
@@ -478,7 +499,7 @@ static void __init mm_init(void)
478 499
479asmlinkage void __init start_kernel(void) 500asmlinkage void __init start_kernel(void)
480{ 501{
481 char * command_line; 502 char * command_line, *after_dashes;
482 extern const struct kernel_param __start___param[], __stop___param[]; 503 extern const struct kernel_param __start___param[], __stop___param[];
483 504
484 /* 505 /*
@@ -519,9 +540,13 @@ asmlinkage void __init start_kernel(void)
519 540
520 pr_notice("Kernel command line: %s\n", boot_command_line); 541 pr_notice("Kernel command line: %s\n", boot_command_line);
521 parse_early_param(); 542 parse_early_param();
522 parse_args("Booting kernel", static_command_line, __start___param, 543 after_dashes = parse_args("Booting kernel",
523 __stop___param - __start___param, 544 static_command_line, __start___param,
524 -1, -1, &unknown_bootoption); 545 __stop___param - __start___param,
546 -1, -1, &unknown_bootoption);
547 if (after_dashes)
548 parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
549 set_init_arg);
525 550
526 jump_label_init(); 551 jump_label_init();
527 552
diff --git a/kernel/module.c b/kernel/module.c
index 11869408f79b..66e4e0d260a9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3193,6 +3193,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
3193{ 3193{
3194 struct module *mod; 3194 struct module *mod;
3195 long err; 3195 long err;
3196 char *after_dashes;
3196 3197
3197 err = module_sig_check(info); 3198 err = module_sig_check(info);
3198 if (err) 3199 if (err)
@@ -3277,10 +3278,15 @@ static int load_module(struct load_info *info, const char __user *uargs,
3277 goto ddebug_cleanup; 3278 goto ddebug_cleanup;
3278 3279
3279 /* Module is ready to execute: parsing args may do that. */ 3280 /* Module is ready to execute: parsing args may do that. */
3280 err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, 3281 after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
3281 -32768, 32767, unknown_module_param_cb); 3282 -32768, 32767, unknown_module_param_cb);
3282 if (err < 0) 3283 if (IS_ERR(after_dashes)) {
3284 err = PTR_ERR(after_dashes);
3283 goto bug_cleanup; 3285 goto bug_cleanup;
3286 } else if (after_dashes) {
3287 pr_warn("%s: parameters '%s' after `--' ignored\n",
3288 mod->name, after_dashes);
3289 }
3284 3290
3285 /* Link in to syfs. */ 3291 /* Link in to syfs. */
3286 err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); 3292 err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
diff --git a/kernel/params.c b/kernel/params.c
index b00142e7f3ba..1e52ca233fd9 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -177,13 +177,13 @@ static char *next_arg(char *args, char **param, char **val)
177} 177}
178 178
179/* Args looks like "foo=bar,bar2 baz=fuz wiz". */ 179/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
180int parse_args(const char *doing, 180char *parse_args(const char *doing,
181 char *args, 181 char *args,
182 const struct kernel_param *params, 182 const struct kernel_param *params,
183 unsigned num, 183 unsigned num,
184 s16 min_level, 184 s16 min_level,
185 s16 max_level, 185 s16 max_level,
186 int (*unknown)(char *param, char *val, const char *doing)) 186 int (*unknown)(char *param, char *val, const char *doing))
187{ 187{
188 char *param, *val; 188 char *param, *val;
189 189
@@ -198,6 +198,9 @@ int parse_args(const char *doing,
198 int irq_was_disabled; 198 int irq_was_disabled;
199 199
200 args = next_arg(args, &param, &val); 200 args = next_arg(args, &param, &val);
201 /* Stop at -- */
202 if (!val && strcmp(param, "--") == 0)
203 return args;
201 irq_was_disabled = irqs_disabled(); 204 irq_was_disabled = irqs_disabled();
202 ret = parse_one(param, val, doing, params, num, 205 ret = parse_one(param, val, doing, params, num,
203 min_level, max_level, unknown); 206 min_level, max_level, unknown);
@@ -208,22 +211,22 @@ int parse_args(const char *doing,
208 switch (ret) { 211 switch (ret) {
209 case -ENOENT: 212 case -ENOENT:
210 pr_err("%s: Unknown parameter `%s'\n", doing, param); 213 pr_err("%s: Unknown parameter `%s'\n", doing, param);
211 return ret; 214 return ERR_PTR(ret);
212 case -ENOSPC: 215 case -ENOSPC:
213 pr_err("%s: `%s' too large for parameter `%s'\n", 216 pr_err("%s: `%s' too large for parameter `%s'\n",
214 doing, val ?: "", param); 217 doing, val ?: "", param);
215 return ret; 218 return ERR_PTR(ret);
216 case 0: 219 case 0:
217 break; 220 break;
218 default: 221 default:
219 pr_err("%s: `%s' invalid for parameter `%s'\n", 222 pr_err("%s: `%s' invalid for parameter `%s'\n",
220 doing, val ?: "", param); 223 doing, val ?: "", param);
221 return ret; 224 return ERR_PTR(ret);
222 } 225 }
223 } 226 }
224 227
225 /* All parsed OK. */ 228 /* All parsed OK. */
226 return 0; 229 return NULL;
227} 230}
228 231
229/* Lazy bastard, eh? */ 232/* Lazy bastard, eh? */