aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/trap_kern.c
diff options
context:
space:
mode:
authorPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>2005-09-23 00:44:16 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-23 01:17:36 -0400
commit546fe1cbf91d4d62e3849517c31a2327c992e5c5 (patch)
treec2be2cd1eb19e04c49d22ec77119973fa8f0ea13 /arch/um/kernel/trap_kern.c
parent69e1e688f5698287b45fbff22a01de91b20804cd (diff)
[PATCH] uml: fix hang in TT mode on fault
The current code doesn't handle well general protection faults on the host - it thinks that cr2 is always the address of a page fault. While actually, on general protection faults, that address is not accessible, so we'd better assume we couldn't satisfy the fault. Currently instead we think we've fixed it, so we go back, retry the instruction and fault again endlessly. This leads to the kernel hanging when doing copy_from_user(dest, -1, ...) in TT mode, since reading *(-1) causes a GFP, and we don't support kernel preemption. Thanks to Luo Xin for testing UML with LTP and reporting the failures he got. Cc: Luo Xin <luothing@sina.com> Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Cc: Jeff Dike <jdike@addtoit.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/kernel/trap_kern.c')
-rw-r--r--arch/um/kernel/trap_kern.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 87cc6fd76ced..90690b9b1f30 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -18,6 +18,7 @@
18#include "asm/a.out.h" 18#include "asm/a.out.h"
19#include "asm/current.h" 19#include "asm/current.h"
20#include "asm/irq.h" 20#include "asm/irq.h"
21#include "sysdep/sigcontext.h"
21#include "user_util.h" 22#include "user_util.h"
22#include "kern_util.h" 23#include "kern_util.h"
23#include "kern.h" 24#include "kern.h"
@@ -125,7 +126,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
125 } 126 }
126 else if(current->mm == NULL) 127 else if(current->mm == NULL)
127 panic("Segfault with no mm"); 128 panic("Segfault with no mm");
128 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); 129
130 if (SEGV_IS_FIXABLE(&fi))
131 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
132 else {
133 err = -EFAULT;
134 /* A thread accessed NULL, we get a fault, but CR2 is invalid.
135 * This code is used in __do_copy_from_user() of TT mode. */
136 address = 0;
137 }
129 138
130 catcher = current->thread.fault_catcher; 139 catcher = current->thread.fault_catcher;
131 if(!err) 140 if(!err)