diff options
author | Jeff Dike <jdike@addtoit.com> | 2008-02-05 01:31:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-05 12:44:29 -0500 |
commit | 0983a88b9f0ceffb2116ce92c7b273ce2aec7b93 (patch) | |
tree | cf63f0646f64eecc80e5e3cd8d9c16252a751d8e /arch/um | |
parent | 8efa3c9d545ab6adc5c5e001cbd7aee60909b3da (diff) |
uml: install panic notifier earlier
It turns out that if there's a panic early enough, UML will just sit there in
the LED-blinking loop because the panic notifier hadn't been installed yet.
This patch installs it earlier.
It also fixes the problem which exposed the hang, namely that if you give UML
a zero-sized initrd, it will ask alloc_bootmem for zero bytes, and that will
cause the panic.
While I was in initrd.c, I gave it a style makeover.
Prompted by checkpatch, I moved a couple extern declarations of uml_exitcode
to kern_util.h.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/include/kern_util.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/initrd.c | 29 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 41 | ||||
-rw-r--r-- | arch/um/os-Linux/main.c | 2 |
4 files changed, 42 insertions, 32 deletions
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 625ca2924a56..715ffb5b95c1 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/faultinfo.h" | 10 | #include "sysdep/faultinfo.h" |
11 | 11 | ||
12 | extern int uml_exitcode; | ||
13 | |||
12 | extern int ncpus; | 14 | extern int ncpus; |
13 | extern int kmalloc_ok; | 15 | extern int kmalloc_ok; |
14 | extern int nsyscalls; | 16 | extern int nsyscalls; |
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index ae31c62f0323..fa015565001b 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -20,18 +20,27 @@ static int __init read_initrd(void) | |||
20 | long long size; | 20 | long long size; |
21 | int err; | 21 | int err; |
22 | 22 | ||
23 | if(initrd == NULL) | 23 | if (initrd == NULL) |
24 | return 0; | 24 | return 0; |
25 | 25 | ||
26 | err = os_file_size(initrd, &size); | 26 | err = os_file_size(initrd, &size); |
27 | if(err) | 27 | if (err) |
28 | return 0; | 28 | return 0; |
29 | 29 | ||
30 | /* | ||
31 | * This is necessary because alloc_bootmem craps out if you | ||
32 | * ask for no memory. | ||
33 | */ | ||
34 | if (size == 0) { | ||
35 | printk(KERN_ERR "\"%\" is a zero-size initrd\n"); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
30 | area = alloc_bootmem(size); | 39 | area = alloc_bootmem(size); |
31 | if(area == NULL) | 40 | if (area == NULL) |
32 | return 0; | 41 | return 0; |
33 | 42 | ||
34 | if(load_initrd(initrd, area, size) == -1) | 43 | if (load_initrd(initrd, area, size) == -1) |
35 | return 0; | 44 | return 0; |
36 | 45 | ||
37 | initrd_start = (unsigned long) area; | 46 | initrd_start = (unsigned long) area; |
@@ -58,13 +67,15 @@ int load_initrd(char *filename, void *buf, int size) | |||
58 | int fd, n; | 67 | int fd, n; |
59 | 68 | ||
60 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | 69 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); |
61 | if(fd < 0){ | 70 | if (fd < 0) { |
62 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | 71 | printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename, |
72 | -fd); | ||
63 | return -1; | 73 | return -1; |
64 | } | 74 | } |
65 | n = os_read_file(fd, buf, size); | 75 | n = os_read_file(fd, buf, size); |
66 | if(n != size){ | 76 | if (n != size) { |
67 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | 77 | printk(KERN_ERR "Read of %d bytes from '%s' failed, " |
78 | "err = %d\n", size, | ||
68 | filename, -n); | 79 | filename, -n); |
69 | return -1; | 80 | return -1; |
70 | } | 81 | } |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 9ba39ab5f4bd..cb7eef833bc8 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -223,6 +223,23 @@ static void __init uml_postsetup(void) | |||
223 | return; | 223 | return; |
224 | } | 224 | } |
225 | 225 | ||
226 | static int panic_exit(struct notifier_block *self, unsigned long unused1, | ||
227 | void *unused2) | ||
228 | { | ||
229 | bust_spinlocks(1); | ||
230 | show_regs(&(current->thread.regs)); | ||
231 | bust_spinlocks(0); | ||
232 | uml_exitcode = 1; | ||
233 | os_dump_core(); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static struct notifier_block panic_exit_notifier = { | ||
238 | .notifier_call = panic_exit, | ||
239 | .next = NULL, | ||
240 | .priority = 0 | ||
241 | }; | ||
242 | |||
226 | /* Set during early boot */ | 243 | /* Set during early boot */ |
227 | unsigned long brk_start; | 244 | unsigned long brk_start; |
228 | unsigned long end_iomem; | 245 | unsigned long end_iomem; |
@@ -327,6 +344,9 @@ int __init linux_main(int argc, char **argv) | |||
327 | printf("Kernel virtual memory size shrunk to %lu bytes\n", | 344 | printf("Kernel virtual memory size shrunk to %lu bytes\n", |
328 | virtmem_size); | 345 | virtmem_size); |
329 | 346 | ||
347 | atomic_notifier_chain_register(&panic_notifier_list, | ||
348 | &panic_exit_notifier); | ||
349 | |||
330 | uml_postsetup(); | 350 | uml_postsetup(); |
331 | 351 | ||
332 | stack_protections((unsigned long) &init_thread_info); | 352 | stack_protections((unsigned long) &init_thread_info); |
@@ -335,29 +355,8 @@ int __init linux_main(int argc, char **argv) | |||
335 | return start_uml(); | 355 | return start_uml(); |
336 | } | 356 | } |
337 | 357 | ||
338 | extern int uml_exitcode; | ||
339 | |||
340 | static int panic_exit(struct notifier_block *self, unsigned long unused1, | ||
341 | void *unused2) | ||
342 | { | ||
343 | bust_spinlocks(1); | ||
344 | show_regs(&(current->thread.regs)); | ||
345 | bust_spinlocks(0); | ||
346 | uml_exitcode = 1; | ||
347 | os_dump_core(); | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static struct notifier_block panic_exit_notifier = { | ||
352 | .notifier_call = panic_exit, | ||
353 | .next = NULL, | ||
354 | .priority = 0 | ||
355 | }; | ||
356 | |||
357 | void __init setup_arch(char **cmdline_p) | 358 | void __init setup_arch(char **cmdline_p) |
358 | { | 359 | { |
359 | atomic_notifier_chain_register(&panic_notifier_list, | ||
360 | &panic_exit_notifier); | ||
361 | paging_init(); | 360 | paging_init(); |
362 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | 361 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); |
363 | *cmdline_p = command_line; | 362 | *cmdline_p = command_line; |
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index de664e7ff310..abb9b0ffd960 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
@@ -111,8 +111,6 @@ static void setup_env_path(void) | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | extern int uml_exitcode; | ||
115 | |||
116 | extern void scan_elf_aux( char **envp); | 114 | extern void scan_elf_aux( char **envp); |
117 | 115 | ||
118 | int __init main(int argc, char **argv, char **envp) | 116 | int __init main(int argc, char **argv, char **envp) |