ARM: 7399/1: vfp: move user vfp state save/restore code out of signal.c
The user VFP state must be preserved (subject to ucontext modifications) across invocation of a signal handler and this is currently handled by vfp_{preserve,restore}_context in signal.c Since this code requires intimate low-level knowledge of the VFP state, this patch moves it into vfpmodule.c. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:

committed by
Russell King

parent
ab4d536890
commit
2498814fcb
@@ -180,44 +180,23 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
|
||||
|
||||
static int preserve_vfp_context(struct vfp_sigframe __user *frame)
|
||||
{
|
||||
struct thread_info *thread = current_thread_info();
|
||||
struct vfp_hard_struct *h = &thread->vfpstate.hard;
|
||||
const unsigned long magic = VFP_MAGIC;
|
||||
const unsigned long size = VFP_STORAGE_SIZE;
|
||||
int err = 0;
|
||||
|
||||
vfp_sync_hwstate(thread);
|
||||
__put_user_error(magic, &frame->magic, err);
|
||||
__put_user_error(size, &frame->size, err);
|
||||
|
||||
/*
|
||||
* Copy the floating point registers. There can be unused
|
||||
* registers see asm/hwcap.h for details.
|
||||
*/
|
||||
err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
|
||||
sizeof(h->fpregs));
|
||||
/*
|
||||
* Copy the status and control register.
|
||||
*/
|
||||
__put_user_error(h->fpscr, &frame->ufp.fpscr, err);
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
* Copy the exception registers.
|
||||
*/
|
||||
__put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
|
||||
__put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
|
||||
__put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
|
||||
|
||||
return err ? -EFAULT : 0;
|
||||
return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
|
||||
}
|
||||
|
||||
static int restore_vfp_context(struct vfp_sigframe __user *frame)
|
||||
{
|
||||
struct thread_info *thread = current_thread_info();
|
||||
struct vfp_hard_struct *h = &thread->vfpstate.hard;
|
||||
unsigned long magic;
|
||||
unsigned long size;
|
||||
unsigned long fpexc;
|
||||
int err = 0;
|
||||
|
||||
__get_user_error(magic, &frame->magic, err);
|
||||
@@ -228,33 +207,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
|
||||
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
vfp_flush_hwstate(thread);
|
||||
|
||||
/*
|
||||
* Copy the floating point registers. There can be unused
|
||||
* registers see asm/hwcap.h for details.
|
||||
*/
|
||||
err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
|
||||
sizeof(h->fpregs));
|
||||
/*
|
||||
* Copy the status and control register.
|
||||
*/
|
||||
__get_user_error(h->fpscr, &frame->ufp.fpscr, err);
|
||||
|
||||
/*
|
||||
* Sanitise and restore the exception registers.
|
||||
*/
|
||||
__get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
|
||||
/* Ensure the VFP is enabled. */
|
||||
fpexc |= FPEXC_EN;
|
||||
/* Ensure FPINST2 is invalid and the exception flag is cleared. */
|
||||
fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
|
||||
h->fpexc = fpexc;
|
||||
|
||||
__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
|
||||
__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
|
||||
|
||||
return err ? -EFAULT : 0;
|
||||
return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user