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 | |
| 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>
| -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) |
