aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r--arch/arm/kernel/signal.c55
1 files changed, 4 insertions, 51 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 7cb532fc8aa4..d68d1b694680 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -180,44 +180,23 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
180 180
181static int preserve_vfp_context(struct vfp_sigframe __user *frame) 181static int preserve_vfp_context(struct vfp_sigframe __user *frame)
182{ 182{
183 struct thread_info *thread = current_thread_info();
184 struct vfp_hard_struct *h = &thread->vfpstate.hard;
185 const unsigned long magic = VFP_MAGIC; 183 const unsigned long magic = VFP_MAGIC;
186 const unsigned long size = VFP_STORAGE_SIZE; 184 const unsigned long size = VFP_STORAGE_SIZE;
187 int err = 0; 185 int err = 0;
188 186
189 vfp_sync_hwstate(thread);
190 __put_user_error(magic, &frame->magic, err); 187 __put_user_error(magic, &frame->magic, err);
191 __put_user_error(size, &frame->size, err); 188 __put_user_error(size, &frame->size, err);
192 189
193 /* 190 if (err)
194 * Copy the floating point registers. There can be unused 191 return -EFAULT;
195 * registers see asm/hwcap.h for details.
196 */
197 err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
198 sizeof(h->fpregs));
199 /*
200 * Copy the status and control register.
201 */
202 __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
203
204 /*
205 * Copy the exception registers.
206 */
207 __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
208 __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
209 __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
210 192
211 return err ? -EFAULT : 0; 193 return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
212} 194}
213 195
214static int restore_vfp_context(struct vfp_sigframe __user *frame) 196static int restore_vfp_context(struct vfp_sigframe __user *frame)
215{ 197{
216 struct thread_info *thread = current_thread_info();
217 struct vfp_hard_struct *h = &thread->vfpstate.hard;
218 unsigned long magic; 198 unsigned long magic;
219 unsigned long size; 199 unsigned long size;
220 unsigned long fpexc;
221 int err = 0; 200 int err = 0;
222 201
223 __get_user_error(magic, &frame->magic, err); 202 __get_user_error(magic, &frame->magic, err);
@@ -228,33 +207,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
228 if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) 207 if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
229 return -EINVAL; 208 return -EINVAL;
230 209
231 vfp_flush_hwstate(thread); 210 return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
232
233 /*
234 * Copy the floating point registers. There can be unused
235 * registers see asm/hwcap.h for details.
236 */
237 err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
238 sizeof(h->fpregs));
239 /*
240 * Copy the status and control register.
241 */
242 __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
243
244 /*
245 * Sanitise and restore the exception registers.
246 */
247 __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
248 /* Ensure the VFP is enabled. */
249 fpexc |= FPEXC_EN;
250 /* Ensure FPINST2 is invalid and the exception flag is cleared. */
251 fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
252 h->fpexc = fpexc;
253
254 __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
255 __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
256
257 return err ? -EFAULT : 0;
258} 211}
259 212
260#endif 213#endif