.. | .. |
---|
26 | 26 | #define USER_DS MAKE_MM_SEG(0x80000000UL) |
---|
27 | 27 | #define KERNEL_DS MAKE_MM_SEG(0) |
---|
28 | 28 | |
---|
29 | | -#define get_ds() (KERNEL_DS) |
---|
30 | 29 | |
---|
31 | 30 | #define get_fs() (current_thread_info()->addr_limit) |
---|
32 | 31 | #define set_fs(seg) (current_thread_info()->addr_limit = (seg)) |
---|
33 | 32 | |
---|
34 | | -#define segment_eq(a, b) ((a).seg == (b).seg) |
---|
| 33 | +#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) |
---|
35 | 34 | |
---|
36 | 35 | #define __access_ok(addr, len) \ |
---|
37 | 36 | (((signed long)(((long)get_fs().seg) & \ |
---|
38 | 37 | ((long)(addr) | (((long)(addr)) + (len)) | (len)))) == 0) |
---|
39 | 38 | |
---|
40 | | -#define access_ok(type, addr, len) \ |
---|
| 39 | +#define access_ok(addr, len) \ |
---|
41 | 40 | likely(__access_ok((unsigned long)(addr), (unsigned long)(len))) |
---|
42 | 41 | |
---|
43 | 42 | # define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n" |
---|
.. | .. |
---|
70 | 69 | static inline unsigned long __must_check clear_user(void __user *to, |
---|
71 | 70 | unsigned long n) |
---|
72 | 71 | { |
---|
73 | | - if (!access_ok(VERIFY_WRITE, to, n)) |
---|
| 72 | + if (!access_ok(to, n)) |
---|
74 | 73 | return n; |
---|
75 | 74 | return __clear_user(to, n); |
---|
76 | 75 | } |
---|
.. | .. |
---|
90 | 89 | /* Optimized macros */ |
---|
91 | 90 | #define __get_user_asm(val, insn, addr, err) \ |
---|
92 | 91 | { \ |
---|
| 92 | + unsigned long __gu_val; \ |
---|
93 | 93 | __asm__ __volatile__( \ |
---|
94 | 94 | " movi %0, %3\n" \ |
---|
95 | 95 | "1: " insn " %1, 0(%2)\n" \ |
---|
.. | .. |
---|
98 | 98 | " .section __ex_table,\"a\"\n" \ |
---|
99 | 99 | " .word 1b, 2b\n" \ |
---|
100 | 100 | " .previous" \ |
---|
101 | | - : "=&r" (err), "=r" (val) \ |
---|
| 101 | + : "=&r" (err), "=r" (__gu_val) \ |
---|
102 | 102 | : "r" (addr), "i" (-EFAULT)); \ |
---|
| 103 | + val = (__force __typeof__(*(addr)))__gu_val; \ |
---|
103 | 104 | } |
---|
104 | 105 | |
---|
105 | | -#define __get_user_unknown(val, size, ptr, err) do { \ |
---|
| 106 | +extern void __get_user_unknown(void); |
---|
| 107 | + |
---|
| 108 | +#define __get_user_8(val, ptr, err) do { \ |
---|
| 109 | + u64 __val = 0; \ |
---|
106 | 110 | err = 0; \ |
---|
107 | | - if (__copy_from_user(&(val), ptr, size)) { \ |
---|
| 111 | + if (raw_copy_from_user(&(__val), ptr, sizeof(val))) { \ |
---|
108 | 112 | err = -EFAULT; \ |
---|
| 113 | + } else { \ |
---|
| 114 | + val = (typeof(val))(typeof((val) - (val)))__val; \ |
---|
109 | 115 | } \ |
---|
110 | 116 | } while (0) |
---|
111 | 117 | |
---|
.. | .. |
---|
121 | 127 | case 4: \ |
---|
122 | 128 | __get_user_asm(val, "ldw", ptr, err); \ |
---|
123 | 129 | break; \ |
---|
| 130 | + case 8: \ |
---|
| 131 | + __get_user_8(val, ptr, err); \ |
---|
| 132 | + break; \ |
---|
124 | 133 | default: \ |
---|
125 | | - __get_user_unknown(val, size, ptr, err); \ |
---|
| 134 | + __get_user_unknown(); \ |
---|
126 | 135 | break; \ |
---|
127 | 136 | } \ |
---|
128 | 137 | } while (0) |
---|
.. | .. |
---|
131 | 140 | ({ \ |
---|
132 | 141 | long __gu_err = -EFAULT; \ |
---|
133 | 142 | const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ |
---|
134 | | - unsigned long __gu_val = 0; \ |
---|
135 | | - __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\ |
---|
136 | | - (x) = (__force __typeof__(x))__gu_val; \ |
---|
| 143 | + __get_user_common(x, sizeof(*(ptr)), __gu_ptr, __gu_err); \ |
---|
137 | 144 | __gu_err; \ |
---|
138 | 145 | }) |
---|
139 | 146 | |
---|
.. | .. |
---|
141 | 148 | ({ \ |
---|
142 | 149 | long __gu_err = -EFAULT; \ |
---|
143 | 150 | const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ |
---|
144 | | - unsigned long __gu_val = 0; \ |
---|
145 | | - if (access_ok(VERIFY_READ, __gu_ptr, sizeof(*__gu_ptr))) \ |
---|
146 | | - __get_user_common(__gu_val, sizeof(*__gu_ptr), \ |
---|
| 151 | + if (access_ok( __gu_ptr, sizeof(*__gu_ptr))) \ |
---|
| 152 | + __get_user_common(x, sizeof(*__gu_ptr), \ |
---|
147 | 153 | __gu_ptr, __gu_err); \ |
---|
148 | | - (x) = (__force __typeof__(x))__gu_val; \ |
---|
149 | 154 | __gu_err; \ |
---|
150 | 155 | }) |
---|
151 | 156 | |
---|
.. | .. |
---|
168 | 173 | long __pu_err = -EFAULT; \ |
---|
169 | 174 | __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \ |
---|
170 | 175 | __typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x); \ |
---|
171 | | - if (access_ok(VERIFY_WRITE, __pu_ptr, sizeof(*__pu_ptr))) { \ |
---|
| 176 | + if (access_ok(__pu_ptr, sizeof(*__pu_ptr))) { \ |
---|
172 | 177 | switch (sizeof(*__pu_ptr)) { \ |
---|
173 | 178 | case 1: \ |
---|
174 | 179 | __put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \ |
---|