summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/thread_info.h4
-rw-r--r--arch/arm/kernel/signal.c20
-rw-r--r--arch/arm/vfp/vfpmodule.c17
3 files changed, 17 insertions, 24 deletions
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index e71cc35de163..9b37b6ab27fe 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -123,8 +123,8 @@ struct user_vfp_exc;
123 123
124extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, 124extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
125 struct user_vfp_exc __user *); 125 struct user_vfp_exc __user *);
126extern int vfp_restore_user_hwstate(struct user_vfp __user *, 126extern int vfp_restore_user_hwstate(struct user_vfp *,
127 struct user_vfp_exc __user *); 127 struct user_vfp_exc *);
128#endif 128#endif
129 129
130/* 130/*
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 0ae74207e43e..db62c51250ad 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -150,22 +150,18 @@ static int preserve_vfp_context(struct vfp_sigframe __user *frame)
150 150
151static int restore_vfp_context(char __user **auxp) 151static int restore_vfp_context(char __user **auxp)
152{ 152{
153 struct vfp_sigframe __user *frame = 153 struct vfp_sigframe frame;
154 (struct vfp_sigframe __user *)*auxp; 154 int err;
155 unsigned long magic;
156 unsigned long size;
157 int err = 0;
158
159 __get_user_error(magic, &frame->magic, err);
160 __get_user_error(size, &frame->size, err);
161 155
156 err = __copy_from_user(&frame, *auxp, sizeof(frame));
162 if (err) 157 if (err)
163 return -EFAULT; 158 return err;
164 if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) 159
160 if (frame.magic != VFP_MAGIC || frame.size != VFP_STORAGE_SIZE)
165 return -EINVAL; 161 return -EINVAL;
166 162
167 *auxp += size; 163 *auxp += sizeof(frame);
168 return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc); 164 return vfp_restore_user_hwstate(&frame.ufp, &frame.ufp_exc);
169} 165}
170 166
171#endif 167#endif
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 4c375e11ae95..859d50ea17d3 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -597,13 +597,11 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
597} 597}
598 598
599/* Sanitise and restore the current VFP state from the provided structures. */ 599/* Sanitise and restore the current VFP state from the provided structures. */
600int vfp_restore_user_hwstate(struct user_vfp __user *ufp, 600int vfp_restore_user_hwstate(struct user_vfp *ufp, struct user_vfp_exc *ufp_exc)
601 struct user_vfp_exc __user *ufp_exc)
602{ 601{
603 struct thread_info *thread = current_thread_info(); 602 struct thread_info *thread = current_thread_info();
604 struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; 603 struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
605 unsigned long fpexc; 604 unsigned long fpexc;
606 int err = 0;
607 605
608 /* Disable VFP to avoid corrupting the new thread state. */ 606 /* Disable VFP to avoid corrupting the new thread state. */
609 vfp_flush_hwstate(thread); 607 vfp_flush_hwstate(thread);
@@ -612,17 +610,16 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
612 * Copy the floating point registers. There can be unused 610 * Copy the floating point registers. There can be unused
613 * registers see asm/hwcap.h for details. 611 * registers see asm/hwcap.h for details.
614 */ 612 */
615 err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs, 613 memcpy(&hwstate->fpregs, &ufp->fpregs, sizeof(hwstate->fpregs));
616 sizeof(hwstate->fpregs));
617 /* 614 /*
618 * Copy the status and control register. 615 * Copy the status and control register.
619 */ 616 */
620 __get_user_error(hwstate->fpscr, &ufp->fpscr, err); 617 hwstate->fpscr = ufp->fpscr;
621 618
622 /* 619 /*
623 * Sanitise and restore the exception registers. 620 * Sanitise and restore the exception registers.
624 */ 621 */
625 __get_user_error(fpexc, &ufp_exc->fpexc, err); 622 fpexc = ufp_exc->fpexc;
626 623
627 /* Ensure the VFP is enabled. */ 624 /* Ensure the VFP is enabled. */
628 fpexc |= FPEXC_EN; 625 fpexc |= FPEXC_EN;
@@ -631,10 +628,10 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
631 fpexc &= ~(FPEXC_EX | FPEXC_FP2V); 628 fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
632 hwstate->fpexc = fpexc; 629 hwstate->fpexc = fpexc;
633 630
634 __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); 631 hwstate->fpinst = ufp_exc->fpinst;
635 __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); 632 hwstate->fpinst2 = ufp_exc->fpinst2;
636 633
637 return err ? -EFAULT : 0; 634 return 0;
638} 635}
639 636
640/* 637/*