diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-05-21 10:15:24 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-05-21 10:15:24 -0400 |
commit | 4175160b065e74572819a320dcd34129224a4e1c (patch) | |
tree | 3298e2c9a7c7db33bf28617875e5429e17eec61c /arch/arm/include | |
parent | ddf90a2ff2c4a9da99acc898a4afeab3e4251fcd (diff) | |
parent | 0ec8e7aa8f63f0cacd545fcd7f40f93fde2c0e6e (diff) |
Merge branch 'misc' into for-linus
Conflicts:
arch/arm/kernel/ptrace.c
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/cacheflush.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/cmpxchg.h | 73 | ||||
-rw-r--r-- | arch/arm/include/asm/mach/time.h | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/pgtable-3level.h | 2 | ||||
-rw-r--r-- | arch/arm/include/asm/ptrace.h | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/syscall.h | 93 |
6 files changed, 119 insertions, 65 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index d5d8d5c72682..004c1bc95d2b 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -101,7 +101,7 @@ struct cpu_cache_fns { | |||
101 | void (*flush_user_range)(unsigned long, unsigned long, unsigned int); | 101 | void (*flush_user_range)(unsigned long, unsigned long, unsigned int); |
102 | 102 | ||
103 | void (*coherent_kern_range)(unsigned long, unsigned long); | 103 | void (*coherent_kern_range)(unsigned long, unsigned long); |
104 | void (*coherent_user_range)(unsigned long, unsigned long); | 104 | int (*coherent_user_range)(unsigned long, unsigned long); |
105 | void (*flush_kern_dcache_area)(void *, size_t); | 105 | void (*flush_kern_dcache_area)(void *, size_t); |
106 | 106 | ||
107 | void (*dma_map_area)(const void *, size_t, int); | 107 | void (*dma_map_area)(const void *, size_t, int); |
@@ -142,7 +142,7 @@ extern void __cpuc_flush_kern_all(void); | |||
142 | extern void __cpuc_flush_user_all(void); | 142 | extern void __cpuc_flush_user_all(void); |
143 | extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); | 143 | extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); |
144 | extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); | 144 | extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); |
145 | extern void __cpuc_coherent_user_range(unsigned long, unsigned long); | 145 | extern int __cpuc_coherent_user_range(unsigned long, unsigned long); |
146 | extern void __cpuc_flush_dcache_area(void *, size_t); | 146 | extern void __cpuc_flush_dcache_area(void *, size_t); |
147 | 147 | ||
148 | /* | 148 | /* |
@@ -249,7 +249,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr | |||
249 | * Harvard caches are synchronised for the user space address range. | 249 | * Harvard caches are synchronised for the user space address range. |
250 | * This is used for the ARM private sys_cacheflush system call. | 250 | * This is used for the ARM private sys_cacheflush system call. |
251 | */ | 251 | */ |
252 | #define flush_cache_user_range(vma,start,end) \ | 252 | #define flush_cache_user_range(start,end) \ |
253 | __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) | 253 | __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) |
254 | 254 | ||
255 | /* | 255 | /* |
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h index d41d7cbf0ada..7eb18c1d8d6c 100644 --- a/arch/arm/include/asm/cmpxchg.h +++ b/arch/arm/include/asm/cmpxchg.h | |||
@@ -229,66 +229,19 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, | |||
229 | (unsigned long)(n), \ | 229 | (unsigned long)(n), \ |
230 | sizeof(*(ptr)))) | 230 | sizeof(*(ptr)))) |
231 | 231 | ||
232 | #ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ | 232 | #define cmpxchg64(ptr, o, n) \ |
233 | 233 | ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr), \ | |
234 | /* | 234 | atomic64_t, \ |
235 | * Note : ARMv7-M (currently unsupported by Linux) does not support | 235 | counter), \ |
236 | * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should | 236 | (unsigned long)(o), \ |
237 | * not be allowed to use __cmpxchg64. | 237 | (unsigned long)(n))) |
238 | */ | 238 | |
239 | static inline unsigned long long __cmpxchg64(volatile void *ptr, | 239 | #define cmpxchg64_local(ptr, o, n) \ |
240 | unsigned long long old, | 240 | ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr), \ |
241 | unsigned long long new) | 241 | local64_t, \ |
242 | { | 242 | a), \ |
243 | register unsigned long long oldval asm("r0"); | 243 | (unsigned long)(o), \ |
244 | register unsigned long long __old asm("r2") = old; | 244 | (unsigned long)(n))) |
245 | register unsigned long long __new asm("r4") = new; | ||
246 | unsigned long res; | ||
247 | |||
248 | do { | ||
249 | asm volatile( | ||
250 | " @ __cmpxchg8\n" | ||
251 | " ldrexd %1, %H1, [%2]\n" | ||
252 | " mov %0, #0\n" | ||
253 | " teq %1, %3\n" | ||
254 | " teqeq %H1, %H3\n" | ||
255 | " strexdeq %0, %4, %H4, [%2]\n" | ||
256 | : "=&r" (res), "=&r" (oldval) | ||
257 | : "r" (ptr), "Ir" (__old), "r" (__new) | ||
258 | : "memory", "cc"); | ||
259 | } while (res); | ||
260 | |||
261 | return oldval; | ||
262 | } | ||
263 | |||
264 | static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, | ||
265 | unsigned long long old, | ||
266 | unsigned long long new) | ||
267 | { | ||
268 | unsigned long long ret; | ||
269 | |||
270 | smp_mb(); | ||
271 | ret = __cmpxchg64(ptr, old, new); | ||
272 | smp_mb(); | ||
273 | |||
274 | return ret; | ||
275 | } | ||
276 | |||
277 | #define cmpxchg64(ptr,o,n) \ | ||
278 | ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ | ||
279 | (unsigned long long)(o), \ | ||
280 | (unsigned long long)(n))) | ||
281 | |||
282 | #define cmpxchg64_local(ptr,o,n) \ | ||
283 | ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ | ||
284 | (unsigned long long)(o), \ | ||
285 | (unsigned long long)(n))) | ||
286 | |||
287 | #else /* min ARCH = ARMv6 */ | ||
288 | |||
289 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | ||
290 | |||
291 | #endif | ||
292 | 245 | ||
293 | #endif /* __LINUX_ARM_ARCH__ >= 6 */ | 246 | #endif /* __LINUX_ARM_ARCH__ >= 6 */ |
294 | 247 | ||
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h index f73c908b7fa0..6ca945f534ab 100644 --- a/arch/arm/include/asm/mach/time.h +++ b/arch/arm/include/asm/mach/time.h | |||
@@ -42,4 +42,9 @@ struct sys_timer { | |||
42 | 42 | ||
43 | extern void timer_tick(void); | 43 | extern void timer_tick(void); |
44 | 44 | ||
45 | struct timespec; | ||
46 | typedef void (*clock_access_fn)(struct timespec *); | ||
47 | extern int register_persistent_clock(clock_access_fn read_boot, | ||
48 | clock_access_fn read_persistent); | ||
49 | |||
45 | #endif | 50 | #endif |
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 759af70f9a0a..b24903549d1c 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h | |||
@@ -69,8 +69,6 @@ | |||
69 | */ | 69 | */ |
70 | #define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */ | 70 | #define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */ |
71 | #define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ | 71 | #define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ |
72 | #define L_PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ | ||
73 | #define L_PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ | ||
74 | #define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */ | 72 | #define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */ |
75 | #define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */ | 73 | #define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */ |
76 | #define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ | 74 | #define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ |
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 451808ba1211..355ece523f41 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
@@ -249,6 +249,11 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | |||
249 | return regs->ARM_sp; | 249 | return regs->ARM_sp; |
250 | } | 250 | } |
251 | 251 | ||
252 | static inline unsigned long user_stack_pointer(struct pt_regs *regs) | ||
253 | { | ||
254 | return regs->ARM_sp; | ||
255 | } | ||
256 | |||
252 | #endif /* __KERNEL__ */ | 257 | #endif /* __KERNEL__ */ |
253 | 258 | ||
254 | #endif /* __ASSEMBLY__ */ | 259 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h new file mode 100644 index 000000000000..c334a23ddf75 --- /dev/null +++ b/arch/arm/include/asm/syscall.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Access to user system call parameters and results | ||
3 | * | ||
4 | * See asm-generic/syscall.h for descriptions of what we must do here. | ||
5 | */ | ||
6 | |||
7 | #ifndef _ASM_ARM_SYSCALL_H | ||
8 | #define _ASM_ARM_SYSCALL_H | ||
9 | |||
10 | #include <linux/err.h> | ||
11 | |||
12 | extern const unsigned long sys_call_table[]; | ||
13 | |||
14 | static inline int syscall_get_nr(struct task_struct *task, | ||
15 | struct pt_regs *regs) | ||
16 | { | ||
17 | return task_thread_info(task)->syscall; | ||
18 | } | ||
19 | |||
20 | static inline void syscall_rollback(struct task_struct *task, | ||
21 | struct pt_regs *regs) | ||
22 | { | ||
23 | regs->ARM_r0 = regs->ARM_ORIG_r0; | ||
24 | } | ||
25 | |||
26 | static inline long syscall_get_error(struct task_struct *task, | ||
27 | struct pt_regs *regs) | ||
28 | { | ||
29 | unsigned long error = regs->ARM_r0; | ||
30 | return IS_ERR_VALUE(error) ? error : 0; | ||
31 | } | ||
32 | |||
33 | static inline long syscall_get_return_value(struct task_struct *task, | ||
34 | struct pt_regs *regs) | ||
35 | { | ||
36 | return regs->ARM_r0; | ||
37 | } | ||
38 | |||
39 | static inline void syscall_set_return_value(struct task_struct *task, | ||
40 | struct pt_regs *regs, | ||
41 | int error, long val) | ||
42 | { | ||
43 | regs->ARM_r0 = (long) error ? error : val; | ||
44 | } | ||
45 | |||
46 | #define SYSCALL_MAX_ARGS 7 | ||
47 | |||
48 | static inline void syscall_get_arguments(struct task_struct *task, | ||
49 | struct pt_regs *regs, | ||
50 | unsigned int i, unsigned int n, | ||
51 | unsigned long *args) | ||
52 | { | ||
53 | if (i + n > SYSCALL_MAX_ARGS) { | ||
54 | unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i; | ||
55 | unsigned int n_bad = n + i - SYSCALL_MAX_ARGS; | ||
56 | pr_warning("%s called with max args %d, handling only %d\n", | ||
57 | __func__, i + n, SYSCALL_MAX_ARGS); | ||
58 | memset(args_bad, 0, n_bad * sizeof(args[0])); | ||
59 | n = SYSCALL_MAX_ARGS - i; | ||
60 | } | ||
61 | |||
62 | if (i == 0) { | ||
63 | args[0] = regs->ARM_ORIG_r0; | ||
64 | args++; | ||
65 | i++; | ||
66 | n--; | ||
67 | } | ||
68 | |||
69 | memcpy(args, ®s->ARM_r0 + i, n * sizeof(args[0])); | ||
70 | } | ||
71 | |||
72 | static inline void syscall_set_arguments(struct task_struct *task, | ||
73 | struct pt_regs *regs, | ||
74 | unsigned int i, unsigned int n, | ||
75 | const unsigned long *args) | ||
76 | { | ||
77 | if (i + n > SYSCALL_MAX_ARGS) { | ||
78 | pr_warning("%s called with max args %d, handling only %d\n", | ||
79 | __func__, i + n, SYSCALL_MAX_ARGS); | ||
80 | n = SYSCALL_MAX_ARGS - i; | ||
81 | } | ||
82 | |||
83 | if (i == 0) { | ||
84 | regs->ARM_ORIG_r0 = args[0]; | ||
85 | args++; | ||
86 | i++; | ||
87 | n--; | ||
88 | } | ||
89 | |||
90 | memcpy(®s->ARM_r0 + i, args, n * sizeof(args[0])); | ||
91 | } | ||
92 | |||
93 | #endif /* _ASM_ARM_SYSCALL_H */ | ||