]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ptrace GET/SET FPXREGS broken
authorTAKADA Yoshihito <takada@mbf.nifty.com>
Mon, 30 Jun 2008 16:22:07 +0000 (18:22 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 3 Jul 2008 03:46:16 +0000 (20:46 -0700)
Commit 11dbc963a8f6128595d0f6ecf138dc369e144997 upstream

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/x86/kernel/i387.c

index d2e39e69aaf860e39e391e899ea349c5e8632ee2..5f04579b5caa9bd65e8c386892f8069cf124939b 100644 (file)
@@ -130,7 +130,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
                void *kbuf, void __user *ubuf)
 {
        if (!cpu_has_fxsr)
-               return -ENODEV;
+               return -EIO;
 
        init_fpu(target);
 
@@ -145,7 +145,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
        int ret;
 
        if (!cpu_has_fxsr)
-               return -ENODEV;
+               return -EIO;
 
        init_fpu(target);
        set_stopped_child_used_math(target);