[PATCH v5 10/14] arm64: usercopy: Store the arguments on stack

From: Oliver Swede
Date: Mon Sep 14 2020 - 11:14:29 EST


Use the stack to preserve the initial arguments to the usercopy
functions before the copy routine modifies the relevant registers.
The values in x0 (dst), x1 (src) and x2 (count) may be modified
in the code paths for large copy sizes, and saving them before
the copy begins enables restoration by the fixup routines to
ensure they have the required information to backtrack effectively.

The stack is used instead of other general-purpose registers due to
resource constraints as all scratch registers x0-x17 defined by the
PCS in the ABI are utilized by the imported copy routine.

The stack pointer is restored to its initial position either from
the fixup code in the case of a fault, or at the end of the copy
algorithm otherwise. The .Luaccess_finish directive is also moved
to copy_template_user.S as the code is common to all usercopy
functions.

Signed-off-by: Oliver Swede <oli.swede@xxxxxxx>
---
arch/arm64/lib/copy_from_user.S | 3 ---
arch/arm64/lib/copy_in_user.S | 3 ---
arch/arm64/lib/copy_template_user.S | 6 ++++++
arch/arm64/lib/copy_to_user.S | 3 ---
arch/arm64/lib/copy_user_fixup.S | 1 +
5 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
index fa319f27a42b..cd3042e98394 100644
--- a/arch/arm64/lib/copy_from_user.S
+++ b/arch/arm64/lib/copy_from_user.S
@@ -110,9 +110,6 @@

SYM_FUNC_START(__arch_copy_from_user)
#include "copy_template_user.S"
-.Luaccess_finish:
- mov x0, #0
- ret
SYM_FUNC_END(__arch_copy_from_user)
EXPORT_SYMBOL(__arch_copy_from_user)
#include "copy_user_fixup.S"
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
index 6b9bb6091dd8..fe035e513b34 100644
--- a/arch/arm64/lib/copy_in_user.S
+++ b/arch/arm64/lib/copy_in_user.S
@@ -117,9 +117,6 @@

SYM_FUNC_START(__arch_copy_in_user)
#include "copy_template_user.S"
-.Luaccess_finish:
- mov x0, #0
- ret
SYM_FUNC_END(__arch_copy_in_user)
EXPORT_SYMBOL(__arch_copy_in_user)
#include "copy_user_fixup.S"
diff --git a/arch/arm64/lib/copy_template_user.S b/arch/arm64/lib/copy_template_user.S
index 3db24dcdab05..1d13daf314b0 100644
--- a/arch/arm64/lib/copy_template_user.S
+++ b/arch/arm64/lib/copy_template_user.S
@@ -21,4 +21,10 @@
L(copy_non_uao):
#undef L
#define L(l) .Lnuao ## l
+ str x2, [sp, #-16]! // count
+ stp x0, x1, [sp, #-16]! // dstin, src
#include "copy_template.S"
+.Luaccess_finish:
+ add sp, sp, 32
+ mov x0, #0
+ ret
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
index 23af6af254da..de0af211b3ba 100644
--- a/arch/arm64/lib/copy_to_user.S
+++ b/arch/arm64/lib/copy_to_user.S
@@ -110,9 +110,6 @@

SYM_FUNC_START(__arch_copy_to_user)
#include "copy_template_user.S"
-.Luaccess_finish:
- mov x0, #0
- ret
SYM_FUNC_END(__arch_copy_to_user)
EXPORT_SYMBOL(__arch_copy_to_user)
#include "copy_user_fixup.S"
diff --git a/arch/arm64/lib/copy_user_fixup.S b/arch/arm64/lib/copy_user_fixup.S
index 32fae9e2e799..a528b7d7d1bd 100644
--- a/arch/arm64/lib/copy_user_fixup.S
+++ b/arch/arm64/lib/copy_user_fixup.S
@@ -10,5 +10,6 @@ addr .req x15
ccmp addr, srcend, #0x0, ge
csel x0, srcend, dstend, lt
sub x0, x0, addr
+ add sp, sp, 32
ret

--
2.17.1