ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state
authorJulien Thierry <julien.thierry@arm.com>
Tue, 11 Sep 2018 09:12:18 +0000 (10:12 +0100)
committerRussell King <rmk+kernel@armlinux.org.uk>
Fri, 5 Oct 2018 09:51:15 +0000 (10:51 +0100)
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: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
arch/arm/include/asm/thread_info.h
arch/arm/kernel/signal.c
arch/arm/vfp/vfpmodule.c

index 9b37b6ab27fe052eb8225c811688700c6ae99bb3..8f55dc520a3e5512cd1474f4a5c3c2d7e72698e8 100644 (file)
@@ -121,8 +121,8 @@ extern void vfp_flush_hwstate(struct thread_info *);
 struct user_vfp;
 struct user_vfp_exc;
 
-extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
-                                          struct user_vfp_exc __user *);
+extern int vfp_preserve_user_clear_hwstate(struct user_vfp *,
+                                          struct user_vfp_exc *);
 extern int vfp_restore_user_hwstate(struct user_vfp *,
                                    struct user_vfp_exc *);
 #endif
index 240a30e167fd4ffea60b36959f3744b0e754ad41..a5c5235ed39c35c22ce2c0778104b04de7cedb73 100644 (file)
@@ -137,17 +137,18 @@ static int restore_iwmmxt_context(char __user **auxp)
 
 static int preserve_vfp_context(struct vfp_sigframe __user *frame)
 {
-       const unsigned long magic = VFP_MAGIC;
-       const unsigned long size = VFP_STORAGE_SIZE;
+       struct vfp_sigframe kframe;
        int err = 0;
 
-       __put_user_error(magic, &frame->magic, err);
-       __put_user_error(size, &frame->size, err);
+       memset(&kframe, 0, sizeof(kframe));
+       kframe.magic = VFP_MAGIC;
+       kframe.size = VFP_STORAGE_SIZE;
 
+       err = vfp_preserve_user_clear_hwstate(&kframe.ufp, &kframe.ufp_exc);
        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)
index 859d50ea17d3d0a74e5b956cb67c23eb0ebbcde0..3b75f1d8a491abb9e27b0c60e6b75cf2a3d30434 100644 (file)
@@ -554,12 +554,11 @@ void vfp_flush_hwstate(struct thread_info *thread)
  * Save the current VFP state into the provided structures and prepare
  * for entry into a new function (signal handler).
  */
-int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
-                                   struct user_vfp_exc __user *ufp_exc)
+int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
+                                   struct user_vfp_exc *ufp_exc)
 {
        struct thread_info *thread = current_thread_info();
        struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
-       int err = 0;
 
        /* Ensure that the saved hwstate is up-to-date. */
        vfp_sync_hwstate(thread);
@@ -568,22 +567,19 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
         * Copy the floating point registers. There can be unused
         * registers see asm/hwcap.h for details.
         */
-       err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs,
-                             sizeof(hwstate->fpregs));
+       memcpy(&ufp->fpregs, &hwstate->fpregs, sizeof(hwstate->fpregs));
+
        /*
         * Copy the status and control register.
         */
-       __put_user_error(hwstate->fpscr, &ufp->fpscr, err);
+       ufp->fpscr = hwstate->fpscr;
 
        /*
         * Copy the exception registers.
         */
-       __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err);
-       __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
-       __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
-
-       if (err)
-               return -EFAULT;
+       ufp_exc->fpexc = hwstate->fpexc;
+       ufp_exc->fpinst = hwstate->fpinst;
+       ufp_exc->fpinst2 = ufp_exc->fpinst2;
 
        /* Ensure that VFP is disabled. */
        vfp_flush_hwstate(thread);