aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
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 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 */