diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-05-16 16:34:27 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-05-16 16:34:27 +0100 |
commit | 53f14393388c8228ea9ef88b3a698c24054b8db4 (patch) | |
tree | 08302bd7d1bf1e5b8b7ffd7e80f9d6346cefbb00 | |
parent | eca207adce3e1b0f7aadb9caf1751c93adcaa1ca (diff) | |
download | xen-53f14393388c8228ea9ef88b3a698c24054b8db4.tar.gz xen-53f14393388c8228ea9ef88b3a698c24054b8db4.tar.bz2 xen-53f14393388c8228ea9ef88b3a698c24054b8db4.zip |
[MINIOS] Fix the pagefault handler to detect recursive faults.
Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
-rw-r--r-- | extras/mini-os/console/console.c | 10 | ||||
-rw-r--r-- | extras/mini-os/traps.c | 15 |
2 files changed, 23 insertions, 2 deletions
diff --git a/extras/mini-os/console/console.c b/extras/mini-os/console/console.c index 342a1edd45..29fdd99f3b 100644 --- a/extras/mini-os/console/console.c +++ b/extras/mini-os/console/console.c @@ -45,6 +45,10 @@ #include <xen/io/console.h> +/* Copies all print output to the Xen emergency console apart + of standard dom0 handled console */ +#define USE_XEN_CONSOLE + /* Low level functions defined in xencons_ring.c */ extern int xencons_ring_init(void); extern int xencons_ring_send(const char *data, unsigned len); @@ -117,7 +121,9 @@ void print(int direct, const char *fmt, va_list args) (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); return; } else { - if(!console_initialised) +#ifndef USE_XEN_CONSOLE + if(!console_initialised) +#endif (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); console_print(buf, strlen(buf)); @@ -128,7 +134,7 @@ void printk(const char *fmt, ...) { va_list args; va_start(args, fmt); - print(1, fmt, args); + print(0, fmt, args); va_end(args); } diff --git a/extras/mini-os/traps.c b/extras/mini-os/traps.c index b6f366818e..43dca39268 100644 --- a/extras/mini-os/traps.c +++ b/extras/mini-os/traps.c @@ -120,9 +120,21 @@ void page_walk(unsigned long virt_address) #define read_cr2() \ (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2) +static int handling_pg_fault = 0; + void do_page_fault(struct pt_regs *regs, unsigned long error_code) { unsigned long addr = read_cr2(); + /* If we are already handling a page fault, and got another one + that means we faulted in pagetable walk. Continuing here would cause + a recursive fault */ + if(handling_pg_fault) + { + printk("Page fault in pagetable walk (access to invalid memory?).\n"); + do_exit(); + } + handling_pg_fault = 1; + #if defined(__x86_64__) printk("Page fault at linear address %p, rip %p, code %lx\n", addr, regs->rip, error_code); @@ -130,9 +142,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) printk("Page fault at linear address %p, eip %p, code %lx\n", addr, regs->eip, error_code); #endif + dump_regs(regs); page_walk(addr); do_exit(); + /* We should never get here ... but still */ + handling_pg_fault = 0; } void do_general_protection(struct pt_regs *regs, long error_code) |