[PATCH] uml: fix page faults in SKAS3 mode.

I hadn't been running a SKAS3 host when testing the "uml: fix hang in TT mode
on fault" patch (commit 546fe1cbf91d4d62e3849517c31a2327c992e5c5), and I
didn't think enough to the missing trap_no in SKAS3 mode.

In fact, the resulting kernel doesn't work at all in SKAS3 mode.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Paolo 'Blaisorblade' Giarrusso and committed by Linus Torvalds be662a18 79dfa4a5

+17 -3
+9 -1
arch/um/include/sysdep-i386/sigcontext.h
··· 6 6 #ifndef __SYS_SIGCONTEXT_I386_H 7 7 #define __SYS_SIGCONTEXT_I386_H 8 8 9 + #include "uml-config.h" 9 10 #include <sysdep/sc.h> 10 11 11 12 #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) ··· 27 26 #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) 28 27 29 28 /* This is Page Fault */ 30 - #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 29 + #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 30 + 31 + /* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ 32 + #ifdef UML_CONFIG_MODE_SKAS 33 + #define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) 34 + #else 35 + #define SEGV_MAYBE_FIXABLE(fi) 0 36 + #endif 31 37 32 38 extern unsigned long *sc_sigmask(void *sc_ptr); 33 39 extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
+4 -1
arch/um/include/sysdep-x86_64/sigcontext.h
··· 31 31 #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) 32 32 33 33 /* This is Page Fault */ 34 - #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 34 + #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 35 + 36 + /* No broken SKAS API, which doesn't pass trap_no, here. */ 37 + #define SEGV_MAYBE_FIXABLE(fi) 0 35 38 36 39 extern unsigned long *sc_sigmask(void *sc_ptr); 37 40
+4 -1
arch/um/kernel/trap_kern.c
··· 26 26 #include "mconsole_kern.h" 27 27 #include "mem.h" 28 28 #include "mem_kern.h" 29 + #ifdef CONFIG_MODE_SKAS 30 + #include "skas.h" 31 + #endif 29 32 30 33 /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ 31 34 int handle_page_fault(unsigned long address, unsigned long ip, ··· 137 134 else if(current->mm == NULL) 138 135 panic("Segfault with no mm"); 139 136 140 - if (SEGV_IS_FIXABLE(&fi)) 137 + if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) 141 138 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); 142 139 else { 143 140 err = -EFAULT;