UML - Tidy fault code
PATCH 1/4 UML - Tidy fault code
Tidying in preparation for the segfault register dumping patch which follows.
void * pointers are changed to union uml_pt_regs *. This makes the types match reality, except in arch_fixup, which is changed to operate on a union uml_pt_regs. This fixes a bug in the call from segv_handler, which passes a union uml_pt_regs, to segv, which expects to pass a struct sigcontext to arch_fixup.
Whitespace and other style fixes.
There's also a errno printk fix.
--
arch/um/include/arch.h | 2 +- arch/um/include/kern_util.h | 2 +- arch/um/kernel/trap.c | 35 ++++++++++++++++++----------------- arch/um/os-Linux/skas/trap.c | 17 ++++++++--------- arch/um/sys-i386/fault.c | 18 ++---------------- arch/um/sys-i386/signal.c | 41 +++++++++++++++-------------------------- arch/um/sys-x86_64/fault.c | 30 +++++++++++++++++------------- arch/um/sys-x86_64/signal.c | 2 +- 8 files changed, 63 insertions(+), 84 deletions(-)
arch/um/include/arch.h +1 -1
@@ -9,7 +9,7 @@#include "sysdep/ptrace.h" extern void arch_check_bugs (void ); -extern int arch_fixup (unsigned long address,void *sc_ptr); +extern int arch_fixup (unsigned long address,union uml_pt_regs *regs);extern int arch_handle_signal (int sig,union uml_pt_regs *regs);#endif
arch/um/include/kern_util.h +1 -1
@@ -43,7 +43,7 @@ extern unsigned long alloc_stack(int ordextern int do_signal (void );extern int is_stack_fault (unsigned long sp);extern unsigned long segv (struct faultinfo fi,unsigned long ip, -int is_user,void *sc); +int is_user,union uml_pt_regs *regs);extern int handle_page_fault (unsigned long address,unsigned long ip,int is_write,int is_user,int *code_out);extern void syscall_ready (void );
arch/um/kernel/trap.c +18 -17
@@ -72,8 +72,8 @@ good_area: goto out;/* Don't require VM_READ|VM_EXEC for write faults! */ -if (!is_write && !(vma->vm_flags & (VM_READ |VM_EXEC ))) - goto out; +if (!is_write && !(vma->vm_flags & (VM_READ |VM_EXEC ))) + goto out; do { survive:
@@ -157,18 +157,19 @@ static void segv_handler(int sig, union* the info in the regs. A pointer to the info then would * give us bad data! */ -unsigned long segv (struct faultinfo fi,unsigned long ip,int is_user,void *sc) +unsigned long segv (struct faultinfo fi,unsigned long ip,int is_user, +union uml_pt_regs *regs) {struct siginfo si;void *catcher;int err; -int is_write =FAULT_WRITE (fi); -unsigned long address =FAULT_ADDRESS (fi); +int is_write =FAULT_WRITE (fi); +unsigned long address =FAULT_ADDRESS (fi); -if (!is_user && (address >= start_vm) && (address < end_vm)){ -flush_tlb_kernel_vm (); -return (0 ); - } +if (!is_user && (address >= start_vm) && (address < end_vm)){ +flush_tlb_kernel_vm (); +return 0 ; + }else if (current->mm ==NULL )panic ("Segfault with no mm" );
@@ -183,17 +184,17 @@ unsigned long segv(struct faultinfo fi, catcher = current->thread.fault_catcher;if (!err) -return (0 ); +return 0 ;else if (catcher !=NULL ){ current->thread.fault_addr = (void *) address;do_longjmp (catcher,1 ); }else if (current->thread.fault_addr !=NULL )panic ("fault_addr set but no fault catcher" ); -else if (!is_user &&arch_fixup (ip, sc)) -return (0 ); +else if (!is_user &&arch_fixup (ip, regs)) +return 0 ; -if (!is_user) +if (!is_user)panic ("Kernel mode fault at addr 0x%lx, ip 0x%lx" , address, ip);
@@ -202,7 +203,7 @@ unsigned long segv(struct faultinfo fi, si.si_errno =0 ; si.si_code =BUS_ADRERR ; si.si_addr = (void __user *)address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi;force_sig_info (SIGBUS , &si, current); }else if (err == -ENOMEM ) {printk ("VM: killing process %s\n" , current->comm);
@@ -211,10 +212,10 @@ unsigned long segv(struct faultinfo fi,BUG_ON (err != -EFAULT ); si.si_signo =SIGSEGV ; si.si_addr = (void __user *) address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi;force_sig_info (SIGSEGV , &si, current); } -return (0 ); +return 0 ; }void relay_signal (int sig,union uml_pt_regs *regs)
@@ -229,7 +230,7 @@ void relay_signal(int sig, union uml_pt_panic ("Kernel mode signal %d" , sig); } - current->thread.arch.faultinfo = *UPT_FAULTINFO (regs); + current->thread.arch.faultinfo = *UPT_FAULTINFO (regs);force_sig (sig, current); }
arch/um/os-Linux/skas/trap.c +8 -9
@@ -18,10 +18,9 @@void sig_handler_common_skas (int sig,void *sc_ptr) {struct sigcontext *sc = sc_ptr; -struct skas_regs *r; +union uml_pt_regs *r;void (*handler)(int ,union uml_pt_regs *); -int save_errno = errno; -int save_user; +int save_user, save_errno = errno;/* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled,
@@ -31,13 +30,13 @@ void sig_handler_common_skas(int sig, voif (sig ==SIGSEGV )change_sig (SIGSEGV ,1 ); - r = &TASK_REGS (get_current ())->skas; - save_user = r->is_user; - r->is_user =0 ; + r =TASK_REGS (get_current ()); + save_user = r->skas.is_user; + r->skas.is_user =0 ;if ( sig ==SIGFPE || sig ==SIGSEGV || sig ==SIGBUS || sig ==SIGILL || sig ==SIGTRAP ) { -GET_FAULTINFO_FROM_SC (r->faultinfo, sc); +GET_FAULTINFO_FROM_SC (r->skas.faultinfo, sc); }change_sig (SIGUSR1 ,1 );
@@ -49,10 +48,10 @@ void sig_handler_common_skas(int sig, vo sig != SIGVTALRM && sig != SIGALRM)unblock_signals (); -handler (sig, (union uml_pt_regs *) r); +handler (sig, r); errno = save_errno; - r->is_user = save_user; + r->skas.is_user = save_user; }extern int ptrace_faultinfo;
arch/um/sys-i386/fault.c +2 -16
@@ -3,9 +3,7 @@* Licensed under the GPL */ -#include <signal.h> #include "sysdep/ptrace.h" -#include "sysdep/sigcontext.h" /* These two are from asm-um/uaccess.h and linux/module.h, check them. */ struct exception_table_entry
@@ -17,26 +15,14 @@ struct exception_table_entryconst struct exception_table_entry *search_exception_tables (unsigned long add);/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup (unsigned long address,void *sc_ptr) +int arch_fixup (unsigned long address,union uml_pt_regs *regs) { -struct sigcontext *sc = sc_ptr;const struct exception_table_entry *fixup; fixup =search_exception_tables (address);if (fixup !=0 ){ - sc->eip = fixup->fixup; +UPT_IP (regs) = fixup->fixup;return (1 ); }return (0 ); } - -/* -* Overrides for Emacs so that we follow Linus's tabbing style. -* Emacs will notice this stuff at the end of the file and automatically -* adjust the settings for this buffer only. This must remain at the end -* of the file. -* --------------------------------------------------------------------------- -* Local variables: -* c-file-style: "linux" -* End: -*/
arch/um/sys-x86_64/fault.c +17 -13
@@ -4,20 +4,24 @@* Licensed under the GPL */ -#include "user.h" +#include "sysdep/ptrace.h" -int arch_fixup (unsigned long address,void *sc_ptr) +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ +struct exception_table_entry { -/* XXX search_exception_tables() */ +unsigned long insn; +unsigned long fixup; +}; + +const struct exception_table_entry *search_exception_tables (unsigned long add); +int arch_fixup (unsigned long address,union uml_pt_regs *regs) +{ +const struct exception_table_entry *fixup; + + fixup =search_exception_tables (address); +if (fixup !=0 ){ +UPT_IP (regs) = fixup->fixup; +return (1 ); + }return (0 ); } - -/* Overrides for Emacs so that we follow Linus's tabbing style. -* Emacs will notice this stuff at the end of the file and automatically -* adjust the settings for this buffer only. This must remain at the end -* of the file. -* --------------------------------------------------------------------------- -* Local variables: -* c-file-style: "linux" -* End: -*/
arch/um/sys-x86_64/signal.c +1 -1
@@ -51,7 +51,7 @@ static int copy_sc_from_user_skas(struct#undef GETREG -return (err); +return err; } int copy_sc_to_user_skas(struct sigcontext __user *to,
arch/um/sys-i386/signal.c +15 -26
105 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
User-mode-linux-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel