aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/lib
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2012-03-05 06:49:32 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2012-09-17 08:42:11 -0400
commit0aea86a2176c22647a5b683768f858d880d5e05b (patch)
tree6ffad0914ef41e69c672a0862f5a10a9e9f3cb43 /arch/arm64/lib
parent2c020ed8d148f7562c01abaf875c9bbfb9a40a83 (diff)
arm64: User access library functions
This patch add support for various user access functions. These functions use the standard LDR/STR instructions and not the LDRT/STRT variants in order to allow kernel addresses (after set_fs(KERNEL_DS)). Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Nicolas Pitre <nico@linaro.org> Acked-by: Olof Johansson <olof@lixom.net> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm64/lib')
-rw-r--r--arch/arm64/lib/clear_user.S58
-rw-r--r--arch/arm64/lib/copy_from_user.S66
-rw-r--r--arch/arm64/lib/copy_in_user.S63
-rw-r--r--arch/arm64/lib/copy_to_user.S61
-rw-r--r--arch/arm64/lib/strncpy_from_user.S50
-rw-r--r--arch/arm64/lib/strnlen_user.S47
6 files changed, 345 insertions, 0 deletions
diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
new file mode 100644
index 000000000000..6e0ed93d51fe
--- /dev/null
+++ b/arch/arm64/lib/clear_user.S
@@ -0,0 +1,58 @@
1/*
2 * Based on arch/arm/lib/clear_user.S
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/linkage.h>
19#include <asm/assembler.h>
20
21 .text
22
23/* Prototype: int __clear_user(void *addr, size_t sz)
24 * Purpose : clear some user memory
25 * Params : addr - user memory address to clear
26 * : sz - number of bytes to clear
27 * Returns : number of bytes NOT cleared
28 *
29 * Alignment fixed up by hardware.
30 */
31ENTRY(__clear_user)
32 mov x2, x1 // save the size for fixup return
33 subs x1, x1, #8
34 b.mi 2f
351:
36USER(9f, str xzr, [x0], #8 )
37 subs x1, x1, #8
38 b.pl 1b
392: adds x1, x1, #4
40 b.mi 3f
41USER(9f, str wzr, [x0], #4 )
42 sub x1, x1, #4
433: adds x1, x1, #2
44 b.mi 4f
45USER(9f, strh wzr, [x0], #2 )
46 sub x1, x1, #2
474: adds x1, x1, #1
48 b.mi 5f
49 strb wzr, [x0]
505: mov x0, #0
51 ret
52ENDPROC(__clear_user)
53
54 .section .fixup,"ax"
55 .align 2
569: mov x0, x2 // return the original size
57 ret
58 .previous
diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
new file mode 100644
index 000000000000..5e27add9d362
--- /dev/null
+++ b/arch/arm64/lib/copy_from_user.S
@@ -0,0 +1,66 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <asm/assembler.h>
19
20/*
21 * Copy from user space to a kernel buffer (alignment handled by the hardware)
22 *
23 * Parameters:
24 * x0 - to
25 * x1 - from
26 * x2 - n
27 * Returns:
28 * x0 - bytes not copied
29 */
30ENTRY(__copy_from_user)
31 add x4, x1, x2 // upper user buffer boundary
32 subs x2, x2, #8
33 b.mi 2f
341:
35USER(9f, ldr x3, [x1], #8 )
36 subs x2, x2, #8
37 str x3, [x0], #8
38 b.pl 1b
392: adds x2, x2, #4
40 b.mi 3f
41USER(9f, ldr w3, [x1], #4 )
42 sub x2, x2, #4
43 str w3, [x0], #4
443: adds x2, x2, #2
45 b.mi 4f
46USER(9f, ldrh w3, [x1], #2 )
47 sub x2, x2, #2
48 strh w3, [x0], #2
494: adds x2, x2, #1
50 b.mi 5f
51USER(9f, ldrb w3, [x1] )
52 strb w3, [x0]
535: mov x0, #0
54 ret
55ENDPROC(__copy_from_user)
56
57 .section .fixup,"ax"
58 .align 2
599: sub x2, x4, x1
60 mov x3, x2
6110: strb wzr, [x0], #1 // zero remaining buffer space
62 subs x3, x3, #1
63 b.ne 10b
64 mov x0, x2 // bytes not copied
65 ret
66 .previous
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
new file mode 100644
index 000000000000..84b6c9bb9b93
--- /dev/null
+++ b/arch/arm64/lib/copy_in_user.S
@@ -0,0 +1,63 @@
1/*
2 * Copy from user space to user space
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/linkage.h>
20#include <asm/assembler.h>
21
22/*
23 * Copy from user space to user space (alignment handled by the hardware)
24 *
25 * Parameters:
26 * x0 - to
27 * x1 - from
28 * x2 - n
29 * Returns:
30 * x0 - bytes not copied
31 */
32ENTRY(__copy_in_user)
33 add x4, x0, x2 // upper user buffer boundary
34 subs x2, x2, #8
35 b.mi 2f
361:
37USER(9f, ldr x3, [x1], #8 )
38 subs x2, x2, #8
39USER(9f, str x3, [x0], #8 )
40 b.pl 1b
412: adds x2, x2, #4
42 b.mi 3f
43USER(9f, ldr w3, [x1], #4 )
44 sub x2, x2, #4
45USER(9f, str w3, [x0], #4 )
463: adds x2, x2, #2
47 b.mi 4f
48USER(9f, ldrh w3, [x1], #2 )
49 sub x2, x2, #2
50USER(9f, strh w3, [x0], #2 )
514: adds x2, x2, #1
52 b.mi 5f
53USER(9f, ldrb w3, [x1] )
54USER(9f, strb w3, [x0] )
555: mov x0, #0
56 ret
57ENDPROC(__copy_in_user)
58
59 .section .fixup,"ax"
60 .align 2
619: sub x0, x4, x0 // bytes not copied
62 ret
63 .previous
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
new file mode 100644
index 000000000000..a0aeeb9b7a28
--- /dev/null
+++ b/arch/arm64/lib/copy_to_user.S
@@ -0,0 +1,61 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/linkage.h>
18#include <asm/assembler.h>
19
20/*
21 * Copy to user space from a kernel buffer (alignment handled by the hardware)
22 *
23 * Parameters:
24 * x0 - to
25 * x1 - from
26 * x2 - n
27 * Returns:
28 * x0 - bytes not copied
29 */
30ENTRY(__copy_to_user)
31 add x4, x0, x2 // upper user buffer boundary
32 subs x2, x2, #8
33 b.mi 2f
341:
35 ldr x3, [x1], #8
36 subs x2, x2, #8
37USER(9f, str x3, [x0], #8 )
38 b.pl 1b
392: adds x2, x2, #4
40 b.mi 3f
41 ldr w3, [x1], #4
42 sub x2, x2, #4
43USER(9f, str w3, [x0], #4 )
443: adds x2, x2, #2
45 b.mi 4f
46 ldrh w3, [x1], #2
47 sub x2, x2, #2
48USER(9f, strh w3, [x0], #2 )
494: adds x2, x2, #1
50 b.mi 5f
51 ldrb w3, [x1]
52USER(9f, strb w3, [x0] )
535: mov x0, #0
54 ret
55ENDPROC(__copy_to_user)
56
57 .section .fixup,"ax"
58 .align 2
599: sub x0, x4, x0 // bytes not copied
60 ret
61 .previous
diff --git a/arch/arm64/lib/strncpy_from_user.S b/arch/arm64/lib/strncpy_from_user.S
new file mode 100644
index 000000000000..56e448a831a0
--- /dev/null
+++ b/arch/arm64/lib/strncpy_from_user.S
@@ -0,0 +1,50 @@
1/*
2 * Based on arch/arm/lib/strncpy_from_user.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22#include <asm/errno.h>
23
24 .text
25 .align 5
26
27/*
28 * Copy a string from user space to kernel space.
29 * x0 = dst, x1 = src, x2 = byte length
30 * returns the number of characters copied (strlen of copied string),
31 * -EFAULT on exception, or "len" if we fill the whole buffer
32 */
33ENTRY(__strncpy_from_user)
34 mov x4, x1
351: subs x2, x2, #1
36 bmi 2f
37USER(9f, ldrb w3, [x1], #1 )
38 strb w3, [x0], #1
39 cbnz w3, 1b
40 sub x1, x1, #1 // take NUL character out of count
412: sub x0, x1, x4
42 ret
43ENDPROC(__strncpy_from_user)
44
45 .section .fixup,"ax"
46 .align 0
479: strb wzr, [x0] // null terminate
48 mov x0, #-EFAULT
49 ret
50 .previous
diff --git a/arch/arm64/lib/strnlen_user.S b/arch/arm64/lib/strnlen_user.S
new file mode 100644
index 000000000000..7f7b176a5646
--- /dev/null
+++ b/arch/arm64/lib/strnlen_user.S
@@ -0,0 +1,47 @@
1/*
2 * Based on arch/arm/lib/strnlen_user.S
3 *
4 * Copyright (C) 1995-2000 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22#include <asm/errno.h>
23
24 .text
25 .align 5
26
27/* Prototype: unsigned long __strnlen_user(const char *str, long n)
28 * Purpose : get length of a string in user memory
29 * Params : str - address of string in user memory
30 * Returns : length of string *including terminator*
31 * or zero on exception, or n if too long
32 */
33ENTRY(__strnlen_user)
34 mov x2, x0
351: subs x1, x1, #1
36 b.mi 2f
37USER(9f, ldrb w3, [x0], #1 )
38 cbnz w3, 1b
392: sub x0, x0, x2
40 ret
41ENDPROC(__strnlen_user)
42
43 .section .fixup,"ax"
44 .align 0
459: mov x0, #0
46 ret
47 .previous