summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2008-02-04 22:31:08 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 09:44:29 -0800
commit0983a88b9f0ceffb2116ce92c7b273ce2aec7b93 (patch)
treecf63f0646f64eecc80e5e3cd8d9c16252a751d8e
parent8efa3c9d545ab6adc5c5e001cbd7aee60909b3da (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.h2
-rw-r--r--arch/um/kernel/initrd.c29
-rw-r--r--arch/um/kernel/um_arch.c41
-rw-r--r--arch/um/os-Linux/main.c2
4 files changed, 42 insertions, 32 deletions
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 625ca2924a5..715ffb5b95c 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -9,6 +9,8 @@
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
+extern int uml_exitcode;
+
extern int ncpus;
extern int kmalloc_ok;
extern int nsyscalls;
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index ae31c62f032..fa015565001 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -20,18 +20,27 @@ static int __init read_initrd(void)
long long size;
int err;
- if(initrd == NULL)
+ if (initrd == NULL)
return 0;
err = os_file_size(initrd, &size);
- if(err)
+ if (err)
return 0;
+ /*
+ * This is necessary because alloc_bootmem craps out if you
+ * ask for no memory.
+ */
+ if (size == 0) {
+ printk(KERN_ERR "\"%\" is a zero-size initrd\n");
+ return 0;
+ }
+
area = alloc_bootmem(size);
- if(area == NULL)
+ if (area == NULL)
return 0;
- if(load_initrd(initrd, area, size) == -1)
+ if (load_initrd(initrd, area, size) == -1)
return 0;
initrd_start = (unsigned long) area;
@@ -58,13 +67,15 @@ int load_initrd(char *filename, void *buf, int size)
int fd, n;
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Opening '%s' failed - err = %d\n", filename, -fd);
+ if (fd < 0) {
+ printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
+ -fd);
return -1;
}
n = os_read_file(fd, buf, size);
- if(n != size){
- printk("Read of %d bytes from '%s' failed, err = %d\n", size,
+ if (n != size) {
+ printk(KERN_ERR "Read of %d bytes from '%s' failed, "
+ "err = %d\n", size,
filename, -n);
return -1;
}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 9ba39ab5f4b..cb7eef833bc 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)
return;
}
+static int panic_exit(struct notifier_block *self, unsigned long unused1,
+ void *unused2)
+{
+ bust_spinlocks(1);
+ show_regs(&(current->thread.regs));
+ bust_spinlocks(0);
+ uml_exitcode = 1;
+ os_dump_core();
+ return 0;
+}
+
+static struct notifier_block panic_exit_notifier = {
+ .notifier_call = panic_exit,
+ .next = NULL,
+ .priority = 0
+};
+
/* Set during early boot */
unsigned long brk_start;
unsigned long end_iomem;
@@ -327,6 +344,9 @@ int __init linux_main(int argc, char **argv)
printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size);
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &panic_exit_notifier);
+
uml_postsetup();
stack_protections((unsigned long) &init_thread_info);
@@ -335,29 +355,8 @@ int __init linux_main(int argc, char **argv)
return start_uml();
}
-extern int uml_exitcode;
-
-static int panic_exit(struct notifier_block *self, unsigned long unused1,
- void *unused2)
-{
- bust_spinlocks(1);
- show_regs(&(current->thread.regs));
- bust_spinlocks(0);
- uml_exitcode = 1;
- os_dump_core();
- return 0;
-}
-
-static struct notifier_block panic_exit_notifier = {
- .notifier_call = panic_exit,
- .next = NULL,
- .priority = 0
-};
-
void __init setup_arch(char **cmdline_p)
{
- atomic_notifier_chain_register(&panic_notifier_list,
- &panic_exit_notifier);
paging_init();
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index de664e7ff31..abb9b0ffd96 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)
}
}
-extern int uml_exitcode;
-
extern void scan_elf_aux( char **envp);
int __init main(int argc, char **argv, char **envp)