diff options
-rw-r--r-- | arch/arm/include/asm/thread_info.h | 4 | ||||
-rw-r--r-- | arch/arm/kernel/signal.c | 20 | ||||
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 17 |
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 | ||
124 | extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, | 124 | extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, |
125 | struct user_vfp_exc __user *); | 125 | struct user_vfp_exc __user *); |
126 | extern int vfp_restore_user_hwstate(struct user_vfp __user *, | 126 | extern 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 | ||
151 | static int restore_vfp_context(char __user **auxp) | 151 | static 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. */ |
600 | int vfp_restore_user_hwstate(struct user_vfp __user *ufp, | 600 | int 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 | /* |