summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTAKADA Yoshihito <takada@mbf.nifty.com>2008-06-30 08:44:45 +0400
committerIngo Molnar <mingo@elte.hu>2008-06-30 16:35:18 +0400
commit11dbc963a8f6128595d0f6ecf138dc369e144997 (patch)
tree091abd0516fb39941422b2041fbb5fba5b00e284
parentfcb43042ef55d2f46b0efa5d7746967cef38f056 (diff)
downloadlinux-11dbc963a8f6128595d0f6ecf138dc369e144997.tar.xz
ptrace GET/SET FPXREGS broken
When I update kernel 2.6.25 from 2.6.24, gdb does not work. On 2.6.25, ptrace(PTRACE_GETFPXREGS, ...) returns ENODEV. But 2.6.24 kernel's ptrace() returns EIO. It is issue of compatibility. I attached test program as pt.c and patch for fix it. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #include <sys/ptrace.h> #include <sys/types.h> struct user_fxsr_struct { unsigned short cwd; unsigned short swd; unsigned short twd; unsigned short fop; long fip; long fcs; long foo; long fos; long mxcsr; long reserved; long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ long padding[56]; }; int main(void) { pid_t pid; pid = fork(); switch(pid){ case -1:/* error */ break; case 0:/* child */ child(); break; default: parent(pid); break; } return 0; } int child(void) { ptrace(PTRACE_TRACEME); kill(getpid(), SIGSTOP); sleep(10); return 0; } int parent(pid_t pid) { int ret; struct user_fxsr_struct fpxregs; ret = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpxregs); if(ret < 0){ printf("%d: %s.\n", errno, strerror(errno)); } kill(pid, SIGCONT); wait(pid); return 0; } /* in the kerel, at kernel/i387.c get_fpxregs() */ Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/i387.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index eb9ddd8efb82..95e80e5033c3 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -162,7 +162,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
int ret;
if (!cpu_has_fxsr)
- return -ENODEV;
+ return -EIO;
ret = init_fpu(target);
if (ret)
@@ -179,7 +179,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
int ret;
if (!cpu_has_fxsr)
- return -ENODEV;
+ return -EIO;
ret = init_fpu(target);
if (ret)