Commit 1f865f72 authored by Anton Blanchard's avatar Anton Blanchard

ppc64: threaded coredump support

parent 8f98f591
...@@ -67,18 +67,34 @@ enable_kernel_fp(void) ...@@ -67,18 +67,34 @@ enable_kernel_fp(void)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
} }
int #ifdef CONFIG_SMP
dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs) static void smp_unlazy_onefpu(void *arg)
{ {
/* struct pt_regs *regs = current->thread.regs;
* XXX temporary workaround until threaded coredumps for ppc64
* are implemented - Anton
*/
if (!regs) if (!regs)
return 0; return;
if (regs->msr & MSR_FP) if (regs->msr & MSR_FP)
giveup_fpu(current); giveup_fpu(current);
memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs)); }
void dump_smp_unlazy_fpu(void)
{
smp_call_function(smp_unlazy_onefpu, NULL, 1, 1);
}
#endif
int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
{
struct pt_regs *regs = tsk->thread.regs;
if (!regs)
return 0;
if (tsk == current && (regs->msr & MSR_FP))
giveup_fpu(current);
memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
return 1; return 1;
} }
......
...@@ -98,17 +98,38 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; ...@@ -98,17 +98,38 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_ET_DYN_BASE (0x08000000) #define ELF_ET_DYN_BASE (0x08000000)
/* Common routine for both 32-bit and 64-bit processes */ /* Common routine for both 32-bit and 64-bit processes */
#define ELF_CORE_COPY_REGS(gregs, regs) ppc64_elf_core_copy_regs(gregs, regs); static inline void ppc64_elf_core_copy_regs(elf_gregset_t elf_regs,
static inline void struct pt_regs *regs)
ppc64_elf_core_copy_regs(elf_gregset_t dstRegs, struct pt_regs* srcRegs)
{ {
int i; int i;
int gprs = sizeof(struct pt_regs)/sizeof(elf_greg_t64);
int numGPRS = ((sizeof(struct pt_regs)/sizeof(elf_greg_t64)) < ELF_NGREG) ? (sizeof(struct pt_regs)/sizeof(elf_greg_t64)) : ELF_NGREG; if (gprs > ELF_NGREG)
gprs = ELF_NGREG;
for (i=0; i < numGPRS; i++) for (i=0; i < gprs; i++)
dstRegs[i] = (elf_greg_t)((elf_greg_t64 *)srcRegs)[i]; elf_regs[i] = (elf_greg_t)((elf_greg_t64 *)regs)[i];
} }
#define ELF_CORE_COPY_REGS(gregs, regs) ppc64_elf_core_copy_regs(gregs, regs);
static inline int dump_task_regs(struct task_struct *tsk,
elf_gregset_t *elf_regs)
{
struct pt_regs *regs = tsk->thread.regs;
if (regs)
ppc64_elf_core_copy_regs(*elf_regs, regs);
return 1;
}
#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
#ifdef CONFIG_SMP
extern void dump_smp_unlazy_fpu(void);
#define ELF_CORE_SYNC dump_smp_unlazy_fpu
#endif
/* This yields a mask that user programs can use to figure out what /* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. This could be done in userspace, instruction set this cpu supports. This could be done in userspace,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment