diff options
author | jdike <jdike> | 2003-08-29 16:44:43 +0000 |
---|---|---|
committer | jdike <jdike> | 2003-08-29 16:44:43 +0000 |
commit | b33c69da3229290b727ebbb014f2082a8f8598f5 (patch) | |
tree | 528d189e48cbdf69bb01d838f0ceecab92908216 | |
parent | f866b36b98c39fb08a6726cdb9ac17d243739979 (diff) | |
download | uml-history-b33c69da3229290b727ebbb014f2082a8f8598f5.tar.gz |
Added support for fixing faults on physical memory.
-rw-r--r-- | arch/um/kernel/trap_kern.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 187456b..642b144 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c @@ -21,6 +21,8 @@ #include "chan_kern.h" #include "mconsole_kern.h" #include "2_5compat.h" +#include "mem.h" +#include "mem_kern.h" unsigned long handle_page_fault(unsigned long address, unsigned long ip, int is_write, int is_user, int *code_out) @@ -85,6 +87,33 @@ unsigned long handle_page_fault(unsigned long address, unsigned long ip, return(handled); } +LIST_HEAD(physmem_remappers); + +void register_remapper(struct remapper *info) +{ + list_add(&info->list, &physmem_remappers); +} + +static int check_remapped_addr(unsigned long address, int is_write) +{ + struct remapper *remapper; + struct list_head *ele; + __u64 offset; + int fd; + + fd = phys_mapping(__pa(address), &offset); + if(fd == -1) + return(0); + + list_for_each(ele, &physmem_remappers){ + remapper = list_entry(ele, struct remapper, list); + if((*remapper->proc)(fd, address, is_write, offset)) + return(1); + } + + return(0); +} + unsigned long segv(unsigned long address, unsigned long ip, int is_write, int is_user, void *sc) { @@ -96,7 +125,9 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, flush_tlb_kernel_vm(); return(0); } - if(current->mm == NULL) + else if(check_remapped_addr(address & PAGE_MASK, is_write)) + return(0); + else if(current->mm == NULL) panic("Segfault with no mm"); handled = handle_page_fault(address, ip, is_write, is_user, @@ -109,9 +140,8 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, current->thread.fault_addr = (void *) address; do_longjmp(catcher, 1); } - else if(current->thread.fault_addr != NULL){ + else if(current->thread.fault_addr != NULL) panic("fault_addr set but no fault catcher"); - } else if(arch_fixup(ip, sc)) return(0); |