diff options
author | Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> | 2005-09-30 14:58:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-30 15:41:18 -0400 |
commit | be662a18b7763496a052d489206af9ca2c2e1ac2 (patch) | |
tree | 73b0777d900e2f6b10642acd1e6a0d8017cc61e8 /arch | |
parent | 79dfa4a5a2eea5035de793b1633031750fe8d3ff (diff) |
[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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/include/sysdep-i386/sigcontext.h | 10 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/sigcontext.h | 5 | ||||
-rw-r--r-- | arch/um/kernel/trap_kern.c | 5 |
3 files changed, 17 insertions, 3 deletions
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index 1fe729265167..23fd2644d7ed 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #ifndef __SYS_SIGCONTEXT_I386_H | 6 | #ifndef __SYS_SIGCONTEXT_I386_H |
7 | #define __SYS_SIGCONTEXT_I386_H | 7 | #define __SYS_SIGCONTEXT_I386_H |
8 | 8 | ||
9 | #include "uml-config.h" | ||
9 | #include <sysdep/sc.h> | 10 | #include <sysdep/sc.h> |
10 | 11 | ||
11 | #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) | 12 | #define IP_RESTART_SYSCALL(ip) ((ip) -= 2) |
@@ -26,7 +27,14 @@ | |||
26 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) | 27 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) |
27 | 28 | ||
28 | /* This is Page Fault */ | 29 | /* This is Page Fault */ |
29 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) | 30 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) |
31 | |||
32 | /* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ | ||
33 | #ifdef UML_CONFIG_MODE_SKAS | ||
34 | #define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) | ||
35 | #else | ||
36 | #define SEGV_MAYBE_FIXABLE(fi) 0 | ||
37 | #endif | ||
30 | 38 | ||
31 | extern unsigned long *sc_sigmask(void *sc_ptr); | 39 | extern unsigned long *sc_sigmask(void *sc_ptr); |
32 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); | 40 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); |
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h index 2a78260d15a0..41073235e7ad 100644 --- a/arch/um/include/sysdep-x86_64/sigcontext.h +++ b/arch/um/include/sysdep-x86_64/sigcontext.h | |||
@@ -31,7 +31,10 @@ | |||
31 | #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) | 31 | #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) |
32 | 32 | ||
33 | /* This is Page Fault */ | 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 | extern unsigned long *sc_sigmask(void *sc_ptr); | 39 | extern unsigned long *sc_sigmask(void *sc_ptr); |
37 | 40 | ||
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index d297429ac360..95c8f8733baf 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
@@ -26,6 +26,9 @@ | |||
26 | #include "mconsole_kern.h" | 26 | #include "mconsole_kern.h" |
27 | #include "mem.h" | 27 | #include "mem.h" |
28 | #include "mem_kern.h" | 28 | #include "mem_kern.h" |
29 | #ifdef CONFIG_MODE_SKAS | ||
30 | #include "skas.h" | ||
31 | #endif | ||
29 | 32 | ||
30 | /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ | 33 | /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ |
31 | int handle_page_fault(unsigned long address, unsigned long ip, | 34 | int handle_page_fault(unsigned long address, unsigned long ip, |
@@ -134,7 +137,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |||
134 | else if(current->mm == NULL) | 137 | else if(current->mm == NULL) |
135 | panic("Segfault with no mm"); | 138 | panic("Segfault with no mm"); |
136 | 139 | ||
137 | if (SEGV_IS_FIXABLE(&fi)) | 140 | if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) |
138 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | 141 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); |
139 | else { | 142 | else { |
140 | err = -EFAULT; | 143 | err = -EFAULT; |