aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/process.c28
-rw-r--r--include/asm-powerpc/elf.h8
-rw-r--r--include/linux/elf.h1
3 files changed, 34 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 7949c203cb89..ea6ad7a2a7e3 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)
149 } 149 }
150} 150}
151 151
152int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) 152int dump_task_altivec(struct task_struct *tsk, elf_vrregset_t *vrregs)
153{ 153{
154 flush_altivec_to_thread(current); 154 /* ELF_NVRREG includes the VSCR and VRSAVE which we need to save
155 memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs)); 155 * separately, see below */
156 const int nregs = ELF_NVRREG - 2;
157 elf_vrreg_t *reg;
158 u32 *dest;
159
160 if (tsk == current)
161 flush_altivec_to_thread(tsk);
162
163 reg = (elf_vrreg_t *)vrregs;
164
165 /* copy the 32 vr registers */
166 memcpy(reg, &tsk->thread.vr[0], nregs * sizeof(*reg));
167 reg += nregs;
168
169 /* copy the vscr */
170 memcpy(reg, &tsk->thread.vscr, sizeof(*reg));
171 reg++;
172
173 /* vrsave is stored in the high 32bit slot of the final 128bits */
174 memset(reg, 0, sizeof(*reg));
175 dest = (u32 *)reg;
176 *dest = tsk->thread.vrsave;
177
156 return 1; 178 return 1;
157} 179}
158#endif /* CONFIG_ALTIVEC */ 180#endif /* CONFIG_ALTIVEC */
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index e42820d6d25b..5b9e3f41d649 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -212,6 +212,14 @@ static inline int dump_task_regs(struct task_struct *tsk,
212extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); 212extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
213#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) 213#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
214 214
215typedef elf_vrregset_t elf_fpxregset_t;
216
217#ifdef CONFIG_ALTIVEC
218extern int dump_task_altivec(struct task_struct *, elf_vrregset_t *vrregs);
219#define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_altivec(tsk, regs)
220#define ELF_CORE_XFPREG_TYPE NT_PPC_VMX
221#endif
222
215#endif /* __KERNEL__ */ 223#endif /* __KERNEL__ */
216 224
217/* ELF_HWCAP yields a mask that user programs can use to figure out what 225/* ELF_HWCAP yields a mask that user programs can use to figure out what
diff --git a/include/linux/elf.h b/include/linux/elf.h
index d2da84acf45d..0eb9ed2f4189 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -355,6 +355,7 @@ typedef struct elf64_shdr {
355#define NT_TASKSTRUCT 4 355#define NT_TASKSTRUCT 4
356#define NT_AUXV 6 356#define NT_AUXV 6
357#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ 357#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
358#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
358 359
359 360
360/* Note header in a PT_NOTE section */ 361/* Note header in a PT_NOTE section */