Commit 0983a88b authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

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: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8efa3c9d
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h" #include "sysdep/faultinfo.h"
extern int uml_exitcode;
extern int ncpus; extern int ncpus;
extern int kmalloc_ok; extern int kmalloc_ok;
extern int nsyscalls; extern int nsyscalls;
......
/* /*
* 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 * Licensed under the GPL
*/ */
...@@ -20,18 +20,27 @@ static int __init read_initrd(void) ...@@ -20,18 +20,27 @@ static int __init read_initrd(void)
long long size; long long size;
int err; int err;
if(initrd == NULL) if (initrd == NULL)
return 0; return 0;
err = os_file_size(initrd, &size); err = os_file_size(initrd, &size);
if(err) if (err)
return 0; 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); area = alloc_bootmem(size);
if(area == NULL) if (area == NULL)
return 0; return 0;
if(load_initrd(initrd, area, size) == -1) if (load_initrd(initrd, area, size) == -1)
return 0; return 0;
initrd_start = (unsigned long) area; initrd_start = (unsigned long) area;
...@@ -58,13 +67,15 @@ int load_initrd(char *filename, void *buf, int size) ...@@ -58,13 +67,15 @@ int load_initrd(char *filename, void *buf, int size)
int fd, n; int fd, n;
fd = os_open_file(filename, of_read(OPENFLAGS()), 0); fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if(fd < 0){ if (fd < 0) {
printk("Opening '%s' failed - err = %d\n", filename, -fd); printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
-fd);
return -1; return -1;
} }
n = os_read_file(fd, buf, size); n = os_read_file(fd, buf, size);
if(n != size){ if (n != size) {
printk("Read of %d bytes from '%s' failed, err = %d\n", size, printk(KERN_ERR "Read of %d bytes from '%s' failed, "
"err = %d\n", size,
filename, -n); filename, -n);
return -1; return -1;
} }
......
...@@ -223,6 +223,23 @@ static void __init uml_postsetup(void) ...@@ -223,6 +223,23 @@ static void __init uml_postsetup(void)
return; 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 */ /* Set during early boot */
unsigned long brk_start; unsigned long brk_start;
unsigned long end_iomem; unsigned long end_iomem;
...@@ -327,6 +344,9 @@ int __init linux_main(int argc, char **argv) ...@@ -327,6 +344,9 @@ int __init linux_main(int argc, char **argv)
printf("Kernel virtual memory size shrunk to %lu bytes\n", printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size); virtmem_size);
atomic_notifier_chain_register(&panic_notifier_list,
&panic_exit_notifier);
uml_postsetup(); uml_postsetup();
stack_protections((unsigned long) &init_thread_info); stack_protections((unsigned long) &init_thread_info);
...@@ -335,29 +355,8 @@ int __init linux_main(int argc, char **argv) ...@@ -335,29 +355,8 @@ int __init linux_main(int argc, char **argv)
return start_uml(); 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) void __init setup_arch(char **cmdline_p)
{ {
atomic_notifier_chain_register(&panic_notifier_list,
&panic_exit_notifier);
paging_init(); paging_init();
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line; *cmdline_p = command_line;
......
...@@ -111,8 +111,6 @@ static void setup_env_path(void) ...@@ -111,8 +111,6 @@ static void setup_env_path(void)
} }
} }
extern int uml_exitcode;
extern void scan_elf_aux( char **envp); extern void scan_elf_aux( char **envp);
int __init main(int argc, char **argv, char **envp) int __init main(int argc, char **argv, char **envp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment