diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/process.c | 28 |
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 | ||
152 | int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) | 152 | int 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, ¤t->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 */ |