aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-01-18 04:42:16 -0500
committerVineet Gupta <vgupta@synopsys.com>2013-02-11 09:30:31 -0500
commit43697cb0973da144156e7d11ddd035aee226ee30 (patch)
tree8c2d6bd2541e536ccd5d04dc2e1b0c7dd5adb66a
parent10a6007bda48e3524e24ce1ad46dc7be1add6a0e (diff)
ARC: uaccess friends
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r--arch/arc/include/asm/segment.h24
-rw-r--r--arch/arc/include/asm/uaccess.h646
-rw-r--r--arch/arc/mm/extable.c63
3 files changed, 733 insertions, 0 deletions
diff --git a/arch/arc/include/asm/segment.h b/arch/arc/include/asm/segment.h
new file mode 100644
index 000000000000..da2c45979817
--- /dev/null
+++ b/arch/arc/include/asm/segment.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
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
9#ifndef __ASMARC_SEGMENT_H
10#define __ASMARC_SEGMENT_H
11
12#ifndef __ASSEMBLY__
13
14typedef unsigned long mm_segment_t;
15
16#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
17
18#define KERNEL_DS MAKE_MM_SEG(0)
19#define USER_DS MAKE_MM_SEG(TASK_SIZE)
20
21#define segment_eq(a, b) ((a) == (b))
22
23#endif /* __ASSEMBLY__ */
24#endif /* __ASMARC_SEGMENT_H */
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h
new file mode 100644
index 000000000000..f13bca44f27a
--- /dev/null
+++ b/arch/arc/include/asm/uaccess.h
@@ -0,0 +1,646 @@
1/*
2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
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 * vineetg: June 2010
9 * -__clear_user( ) called multiple times during elf load was byte loop
10 * converted to do as much word clear as possible.
11 *
12 * vineetg: Dec 2009
13 * -Hand crafted constant propagation for "constant" copy sizes
14 * -stock kernel shrunk by 33K at -O3
15 *
16 * vineetg: Sept 2009
17 * -Added option to (UN)inline copy_(to|from)_user to reduce code sz
18 * -kernel shrunk by 200K even at -O3 (gcc 4.2.1)
19 * -Enabled when doing -Os
20 *
21 * Amit Bhor, Sameer Dhavale: Codito Technologies 2004
22 */
23
24#ifndef _ASM_ARC_UACCESS_H
25#define _ASM_ARC_UACCESS_H
26
27#include <linux/sched.h>
28#include <asm/errno.h>
29#include <linux/string.h> /* for generic string functions */
30
31
32#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
33
34/*
35 * Algorthmically, for __user_ok() we want do:
36 * (start < TASK_SIZE) && (start+len < TASK_SIZE)
37 * where TASK_SIZE could either be retrieved from thread_info->addr_limit or
38 * emitted directly in code.
39 *
40 * This can however be rewritten as follows:
41 * (len <= TASK_SIZE) && (start+len < TASK_SIZE)
42 *
43 * Because it essentially checks if buffer end is within limit and @len is
44 * non-ngeative, which implies that buffer start will be within limit too.
45 *
46 * The reason for rewriting being, for majorit yof cases, @len is generally
47 * compile time constant, causing first sub-expression to be compile time
48 * subsumed.
49 *
50 * The second part would generate weird large LIMMs e.g. (0x6000_0000 - 0x10),
51 * so we check for TASK_SIZE using get_fs() since the addr_limit load from mem
52 * would already have been done at this call site for __kernel_ok()
53 *
54 */
55#define __user_ok(addr, sz) (((sz) <= TASK_SIZE) && \
56 (((addr)+(sz)) <= get_fs()))
57#define __access_ok(addr, sz) (unlikely(__kernel_ok) || \
58 likely(__user_ok((addr), (sz))))
59
60static inline unsigned long
61__arc_copy_from_user(void *to, const void __user *from, unsigned long n)
62{
63 long res = 0;
64 char val;
65 unsigned long tmp1, tmp2, tmp3, tmp4;
66 unsigned long orig_n = n;
67
68 if (n == 0)
69 return 0;
70
71 /* unaligned */
72 if (((unsigned long)to & 0x3) || ((unsigned long)from & 0x3)) {
73
74 unsigned char tmp;
75
76 __asm__ __volatile__ (
77 " mov.f lp_count, %0 \n"
78 " lpnz 2f \n"
79 "1: ldb.ab %1, [%3, 1] \n"
80 " stb.ab %1, [%2, 1] \n"
81 " sub %0,%0,1 \n"
82 "2: ;nop \n"
83 " .section .fixup, \"ax\" \n"
84 " .align 4 \n"
85 "3: j 2b \n"
86 " .previous \n"
87 " .section __ex_table, \"a\" \n"
88 " .align 4 \n"
89 " .word 1b, 3b \n"
90 " .previous \n"
91
92 : "+r" (n),
93 /*
94 * Note as an '&' earlyclobber operand to make sure the
95 * temporary register inside the loop is not the same as
96 * FROM or TO.
97 */
98 "=&r" (tmp), "+r" (to), "+r" (from)
99 :
100 : "lp_count", "lp_start", "lp_end", "memory");
101
102 return n;
103 }
104
105 /*
106 * Hand-crafted constant propagation to reduce code sz of the
107 * laddered copy 16x,8,4,2,1
108 */
109 if (__builtin_constant_p(orig_n)) {
110 res = orig_n;
111
112 if (orig_n / 16) {
113 orig_n = orig_n % 16;
114
115 __asm__ __volatile__(
116 " lsr lp_count, %7,4 \n"
117 " lp 3f \n"
118 "1: ld.ab %3, [%2, 4] \n"
119 "11: ld.ab %4, [%2, 4] \n"
120 "12: ld.ab %5, [%2, 4] \n"
121 "13: ld.ab %6, [%2, 4] \n"
122 " st.ab %3, [%1, 4] \n"
123 " st.ab %4, [%1, 4] \n"
124 " st.ab %5, [%1, 4] \n"
125 " st.ab %6, [%1, 4] \n"
126 " sub %0,%0,16 \n"
127 "3: ;nop \n"
128 " .section .fixup, \"ax\" \n"
129 " .align 4 \n"
130 "4: j 3b \n"
131 " .previous \n"
132 " .section __ex_table, \"a\" \n"
133 " .align 4 \n"
134 " .word 1b, 4b \n"
135 " .word 11b,4b \n"
136 " .word 12b,4b \n"
137 " .word 13b,4b \n"
138 " .previous \n"
139 : "+r" (res), "+r"(to), "+r"(from),
140 "=r"(tmp1), "=r"(tmp2), "=r"(tmp3), "=r"(tmp4)
141 : "ir"(n)
142 : "lp_count", "memory");
143 }
144 if (orig_n / 8) {
145 orig_n = orig_n % 8;
146
147 __asm__ __volatile__(
148 "14: ld.ab %3, [%2,4] \n"
149 "15: ld.ab %4, [%2,4] \n"
150 " st.ab %3, [%1,4] \n"
151 " st.ab %4, [%1,4] \n"
152 " sub %0,%0,8 \n"
153 "31: ;nop \n"
154 " .section .fixup, \"ax\" \n"
155 " .align 4 \n"
156 "4: j 31b \n"
157 " .previous \n"
158 " .section __ex_table, \"a\" \n"
159 " .align 4 \n"
160 " .word 14b,4b \n"
161 " .word 15b,4b \n"
162