aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2008-06-12 18:21:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-06-12 21:05:40 -0400
commitf1ef9167ca4494a8c6d71d0031c73e9c8841eadd (patch)
treea4c5a1420501a54ddd5bcf44ff7224e3293e8d3e /arch/um
parent14c8a77e1bbd693446dad297d2ae2dd22f187e4f (diff)
uml: work around broken host PTRACE_SYSEMU
Fedora broke PTRACE_SYSEMU again, and UML crashes as a result when it doesn't need to. This patch makes the PTRACE_SYSEMU check fail gracefully and makes UML fall back to PTRACE_SYSCALL. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/os-Linux/start_up.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b4b36e0f2e89..183db26d01bf 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -121,8 +121,10 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
121{ 121{
122 int status, n, ret = 0; 122 int status, n, ret = 0;
123 123
124 if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) 124 if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
125 fatal_perror("stop_ptraced_child : ptrace failed"); 125 perror("stop_ptraced_child : ptrace failed");
126 return -1;
127 }
126 CATCH_EINTR(n = waitpid(pid, &status, 0)); 128 CATCH_EINTR(n = waitpid(pid, &status, 0));
127 if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 129 if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
128 int exit_with = WEXITSTATUS(status); 130 int exit_with = WEXITSTATUS(status);
@@ -212,7 +214,7 @@ static void __init check_sysemu(void)
212 if (n < 0) 214 if (n < 0)
213 fatal_perror("check_sysemu : wait failed"); 215 fatal_perror("check_sysemu : wait failed");
214 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) 216 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
215 fatal("check_sysemu : expected SIGTRAP, got status = %d", 217 fatal("check_sysemu : expected SIGTRAP, got status = %d\n",
216 status); 218 status);
217 219
218 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 220 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
@@ -254,9 +256,11 @@ static void __init check_sysemu(void)
254 256
255 if (WIFSTOPPED(status) && 257 if (WIFSTOPPED(status) &&
256 (WSTOPSIG(status) == (SIGTRAP|0x80))) { 258 (WSTOPSIG(status) == (SIGTRAP|0x80))) {
257 if (!count) 259 if (!count) {
258 fatal("check_ptrace : SYSEMU_SINGLESTEP " 260 non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
259 "doesn't singlestep"); 261 "doesn't singlestep");
262 goto fail;
263 }
260 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, 264 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
261 os_getpid()); 265 os_getpid());
262 if (n < 0) 266 if (n < 0)
@@ -266,9 +270,12 @@ static void __init check_sysemu(void)
266 } 270 }
267 else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) 271 else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
268 count++; 272 count++;
269 else 273 else {
270 fatal("check_ptrace : expected SIGTRAP or " 274 non_fatal("check_ptrace : expected SIGTRAP or "
271 "(SIGTRAP | 0x80), got status = %d", status); 275 "(SIGTRAP | 0x80), got status = %d\n",
276 status);
277 goto fail;
278 }
272 } 279 }
273 if (stop_ptraced_child(pid, 0, 0) < 0) 280 if (stop_ptraced_child(pid, 0, 0) < 0)
274 goto fail_stopped; 281 goto fail_stopped;