Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d1254b12c93e1e586137a2ffef71fd33cf273f35
Commit:     d1254b12c93e1e586137a2ffef71fd33cf273f35
Parent:     c7ec16da5adc1c1b341b2a83bde7add17dcf811a
Author:     Jeff Dike <[EMAIL PROTECTED]>
AuthorDate: Thu Aug 30 23:56:20 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri Aug 31 01:42:22 2007 -0700

    uml: fix x86_64 core dump crash
    
    Stop UML crashing when trying to dump a process core on x86_64.  This is the
    minimal fix to stop the crash - more things are broken here, and patches are
    forthcoming.
    
    The immediate thing to do is define ELF_CORE_COPY_REGS and
    ELF_CORE_COPY_FPREGS.  Defining ELF_CORE_COPY_FPREGS allows dump_fpu to go
    away.  It is defined in terms of save_fp_registers, so that needs to be 
added.
    
    Signed-off-by: Jeff Dike <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 arch/um/os-Linux/sys-x86_64/registers.c |   15 +++++++++++
 arch/um/sys-x86_64/ptrace.c             |    6 ----
 include/asm-um/elf-x86_64.h             |   40 +++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/arch/um/os-Linux/sys-x86_64/registers.c 
b/arch/um/os-Linux/sys-x86_64/registers.c
index e6fc217..9467315 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -4,6 +4,7 @@
  */
 
 #include <errno.h>
+#include <sys/ptrace.h>
 #include <string.h>
 #include "ptrace_user.h"
 #include "uml-config.h"
@@ -17,6 +18,20 @@
 static unsigned long exec_regs[MAX_REG_NR];
 static unsigned long exec_fp_regs[HOST_FP_SIZE];
 
+int save_fp_registers(int pid, unsigned long *fp_regs)
+{
+       if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
+               return -errno;
+       return 0;
+}
+
+int restore_fp_registers(int pid, unsigned long *fp_regs)
+{
+       if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
+               return -errno;
+       return 0;
+}
+
 void init_thread_registers(union uml_pt_regs *to)
 {
        memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 55b66e0..1970d78 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -156,12 +156,6 @@ int is_syscall(unsigned long addr)
        return(instr == 0x050f);
 }
 
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
-{
-       panic("dump_fpu");
-       return(1);
-}
-
 int get_fpregs(unsigned long buf, struct task_struct *child)
 {
        panic("get_fpregs");
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h
index 8a8246d..bfe27aa 100644
--- a/include/asm-um/elf-x86_64.h
+++ b/include/asm-um/elf-x86_64.h
@@ -6,7 +6,9 @@
 #ifndef __UM_ELF_X86_64_H
 #define __UM_ELF_X86_64_H
 
+#include <linux/sched.h>
 #include <asm/user.h>
+#include "skas.h"
 
 /* x86-64 relocation types, taken from asm-x86_64/elf.h */
 #define R_X86_64_NONE          0       /* No reloc */
@@ -64,6 +66,44 @@ typedef struct { } elf_fpregset_t;
        PT_REGS_R15(regs) = 0; \
 } while (0)
 
+#define ELF_CORE_COPY_REGS(pr_reg, regs)               \
+       (pr_reg)[0] = (regs)->regs.gp[0];                       \
+       (pr_reg)[1] = (regs)->regs.gp[1];                       \
+       (pr_reg)[2] = (regs)->regs.gp[2];                       \
+       (pr_reg)[3] = (regs)->regs.gp[3];                       \
+       (pr_reg)[4] = (regs)->regs.gp[4];                       \
+       (pr_reg)[5] = (regs)->regs.gp[5];                       \
+       (pr_reg)[6] = (regs)->regs.gp[6];                       \
+       (pr_reg)[7] = (regs)->regs.gp[7];                       \
+       (pr_reg)[8] = (regs)->regs.gp[8];                       \
+       (pr_reg)[9] = (regs)->regs.gp[9];                       \
+       (pr_reg)[10] = (regs)->regs.gp[10];                     \
+       (pr_reg)[11] = (regs)->regs.gp[11];                     \
+       (pr_reg)[12] = (regs)->regs.gp[12];                     \
+       (pr_reg)[13] = (regs)->regs.gp[13];                     \
+       (pr_reg)[14] = (regs)->regs.gp[14];                     \
+       (pr_reg)[15] = (regs)->regs.gp[15];                     \
+       (pr_reg)[16] = (regs)->regs.gp[16];                     \
+       (pr_reg)[17] = (regs)->regs.gp[17];                     \
+       (pr_reg)[18] = (regs)->regs.gp[18];                     \
+       (pr_reg)[19] = (regs)->regs.gp[19];                     \
+       (pr_reg)[20] = (regs)->regs.gp[20];                     \
+       (pr_reg)[21] = current->thread.arch.fs;                 \
+       (pr_reg)[22] = 0;                                       \
+       (pr_reg)[23] = 0;                                       \
+       (pr_reg)[24] = 0;                                       \
+       (pr_reg)[25] = 0;                                       \
+       (pr_reg)[26] = 0;
+
+static inline int elf_core_copy_fpregs(struct task_struct *t,
+                                      elf_fpregset_t *fpu)
+{
+       int cpu = current_thread->cpu;
+       return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
+}
+
+#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu)
+
 #ifdef TIF_IA32 /* XXX */
 #error XXX, indeed
         clear_thread_flag(TIF_IA32);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to