Commit 6d3ccf78 authored by Julien Thierry's avatar Julien Thierry Committed by Greg Kroah-Hartman

ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state

Commit 3aa2df6e upstream.

Use __copy_to_user() rather than __put_user_error() for individual
members when saving VFP state.
This has the benefit of disabling/enabling PAN once per copied struct
intead of once per write.
Signed-off-by: default avatarJulien Thierry <julien.thierry@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid A. Long <dave.long@linaro.org>
Reviewed-by: default avatarJulien Thierry <julien.thierry@arm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent a26e4c1f
...@@ -124,8 +124,8 @@ extern void vfp_flush_hwstate(struct thread_info *); ...@@ -124,8 +124,8 @@ extern void vfp_flush_hwstate(struct thread_info *);
struct user_vfp; struct user_vfp;
struct user_vfp_exc; struct user_vfp_exc;
extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, extern int vfp_preserve_user_clear_hwstate(struct user_vfp *,
struct user_vfp_exc __user *); struct user_vfp_exc *);
extern int vfp_restore_user_hwstate(struct user_vfp *, extern int vfp_restore_user_hwstate(struct user_vfp *,
struct user_vfp_exc *); struct user_vfp_exc *);
#endif #endif
......
...@@ -136,17 +136,18 @@ static int restore_iwmmxt_context(char __user **auxp) ...@@ -136,17 +136,18 @@ static int restore_iwmmxt_context(char __user **auxp)
static int preserve_vfp_context(struct vfp_sigframe __user *frame) static int preserve_vfp_context(struct vfp_sigframe __user *frame)
{ {
const unsigned long magic = VFP_MAGIC; struct vfp_sigframe kframe;
const unsigned long size = VFP_STORAGE_SIZE;
int err = 0; int err = 0;
__put_user_error(magic, &frame->magic, err); memset(&kframe, 0, sizeof(kframe));
__put_user_error(size, &frame->size, err); kframe.magic = VFP_MAGIC;
kframe.size = VFP_STORAGE_SIZE;
err = vfp_preserve_user_clear_hwstate(&kframe.ufp, &kframe.ufp_exc);
if (err) if (err)
return -EFAULT; return err;
return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); return __copy_to_user(frame, &kframe, sizeof(kframe));
} }
static int restore_vfp_context(char __user **auxp) static int restore_vfp_context(char __user **auxp)
......
...@@ -554,12 +554,11 @@ void vfp_flush_hwstate(struct thread_info *thread) ...@@ -554,12 +554,11 @@ void vfp_flush_hwstate(struct thread_info *thread)
* Save the current VFP state into the provided structures and prepare * Save the current VFP state into the provided structures and prepare
* for entry into a new function (signal handler). * for entry into a new function (signal handler).
*/ */
int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
struct user_vfp_exc __user *ufp_exc) struct user_vfp_exc *ufp_exc)
{ {
struct thread_info *thread = current_thread_info(); struct thread_info *thread = current_thread_info();
struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
int err = 0;
/* Ensure that the saved hwstate is up-to-date. */ /* Ensure that the saved hwstate is up-to-date. */
vfp_sync_hwstate(thread); vfp_sync_hwstate(thread);
...@@ -568,22 +567,19 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, ...@@ -568,22 +567,19 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
* Copy the floating point registers. There can be unused * Copy the floating point registers. There can be unused
* registers see asm/hwcap.h for details. * registers see asm/hwcap.h for details.
*/ */
err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs, memcpy(&ufp->fpregs, &hwstate->fpregs, sizeof(hwstate->fpregs));
sizeof(hwstate->fpregs));
/* /*
* Copy the status and control register. * Copy the status and control register.
*/ */
__put_user_error(hwstate->fpscr, &ufp->fpscr, err); ufp->fpscr = hwstate->fpscr;
/* /*
* Copy the exception registers. * Copy the exception registers.
*/ */
__put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err); ufp_exc->fpexc = hwstate->fpexc;
__put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); ufp_exc->fpinst = hwstate->fpinst;
__put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); ufp_exc->fpinst2 = ufp_exc->fpinst2;
if (err)
return -EFAULT;
/* Ensure that VFP is disabled. */ /* Ensure that VFP is disabled. */
vfp_flush_hwstate(thread); vfp_flush_hwstate(thread);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment