summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
authorMark Nelson <markn@au1.ibm.com>2007-10-16 23:25:40 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 08:42:44 -0700
commit1f7d6668c29b1dfa307a44844f9bb38356fc989b (patch)
tree7e8feb874806710834619756dba698cd2697cd1f /arch/powerpc/kernel/process.c
parent5b20cd80b4ce1674b7abe5ac91db23346118176d (diff)
powerpc: add Altivec/VMX state to coredumps
Update dump_task_altivec() (which has so far never been put to use) so that it dumps the Altivec/VMX registers (VR[0] - VR[31], VSCR and VRSAVE) in the same format as the ptrace get_vrregs(), and add the appropriate glue typedef and #defines to make it work. A new note type of NT_PPC_VMX was chosen to be 0x100 (arbitrarily) because it allows the low range values to be used for more generic purposes and 0x100 seems an adequate starting point for PowerPC extensions. Signed-off-by: Mark Nelson <markn@au1.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: Andi Kleen <ak@suse.de> Cc: <linux-arch@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 7949c203cb8..ea6ad7a2a7e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -149,10 +149,32 @@ void flush_altivec_to_thread(struct task_struct *tsk)
}
}
-int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+int dump_task_altivec(struct task_struct *tsk, elf_vrregset_t *vrregs)
{
- flush_altivec_to_thread(current);
- memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
+ /* ELF_NVRREG includes the VSCR and VRSAVE which we need to save
+ * separately, see below */
+ const int nregs = ELF_NVRREG - 2;
+ elf_vrreg_t *reg;
+ u32 *dest;
+
+ if (tsk == current)
+ flush_altivec_to_thread(tsk);
+
+ reg = (elf_vrreg_t *)vrregs;
+
+ /* copy the 32 vr registers */
+ memcpy(reg, &tsk->thread.vr[0], nregs * sizeof(*reg));
+ reg += nregs;
+
+ /* copy the vscr */
+ memcpy(reg, &tsk->thread.vscr, sizeof(*reg));
+ reg++;
+
+ /* vrsave is stored in the high 32bit slot of the final 128bits */
+ memset(reg, 0, sizeof(*reg));
+ dest = (u32 *)reg;
+ *dest = tsk->thread.vrsave;
+
return 1;
}
#endif /* CONFIG_ALTIVEC */