uaccess.h 5.05 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 *  linux/include/asm-arm/proc-armv/uaccess.h
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <asm/arch/memory.h>
#include <asm/proc/domain.h>

/*
 * Note that this is actually 0x1,0000,0000
 */
#define KERNEL_DS	0x00000000
15
#define USER_DS		TASK_SIZE
Linus Torvalds's avatar
Linus Torvalds committed
16

Linus Torvalds's avatar
Linus Torvalds committed
17
static inline void set_fs (mm_segment_t fs)
Linus Torvalds's avatar
Linus Torvalds committed
18
{
19
	current_thread_info()->addr_limit = fs;
Linus Torvalds's avatar
Linus Torvalds committed
20 21 22 23 24 25
	modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
}

/* We use 33-bit arithmetic here... */
#define __range_ok(addr,size) ({ \
	unsigned long flag, sum; \
Linus Torvalds's avatar
Linus Torvalds committed
26
	__asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
Linus Torvalds's avatar
Linus Torvalds committed
27
		: "=&r" (flag), "=&r" (sum) \
28
		: "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
Linus Torvalds's avatar
Linus Torvalds committed
29 30 31 32 33
		: "cc"); \
	flag; })

#define __addr_ok(addr) ({ \
	unsigned long flag; \
Linus Torvalds's avatar
Linus Torvalds committed
34
	__asm__("cmp %2, %0; movlo %0, #0" \
Linus Torvalds's avatar
Linus Torvalds committed
35
		: "=&r" (flag) \
36
		: "0" (current_thread_info()->addr_limit), "r" (addr) \
Linus Torvalds's avatar
Linus Torvalds committed
37 38 39
		: "cc"); \
	(flag == 0); })

40
#define __put_user_asm_byte(x,__pu_addr,err)			\
Linus Torvalds's avatar
Linus Torvalds committed
41 42 43 44 45 46 47 48 49 50 51 52
	__asm__ __volatile__(					\
	"1:	strbt	%1,[%2],#0\n"				\
	"2:\n"							\
	"	.section .fixup,\"ax\"\n"			\
	"	.align	2\n"					\
	"3:	mov	%0, %3\n"				\
	"	b	2b\n"					\
	"	.previous\n"					\
	"	.section __ex_table,\"a\"\n"			\
	"	.align	3\n"					\
	"	.long	1b, 3b\n"				\
	"	.previous"					\
53 54
	: "+r" (err)						\
	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
55
	: "cc")
Linus Torvalds's avatar
Linus Torvalds committed
56

Linus Torvalds's avatar
Linus Torvalds committed
57
#ifndef __ARMEB__
58
#define __put_user_asm_half(x,__pu_addr,err)			\
Linus Torvalds's avatar
Linus Torvalds committed
59 60
({								\
	unsigned long __temp = (unsigned long)(x);		\
61 62
	__put_user_asm_byte(__temp, __pu_addr, err);		\
	__put_user_asm_byte(__temp >> 8, __pu_addr + 1, err);	\
Linus Torvalds's avatar
Linus Torvalds committed
63
})
Linus Torvalds's avatar
Linus Torvalds committed
64
#else
65
#define __put_user_asm_half(x,__pu_addr,err)			\
Linus Torvalds's avatar
Linus Torvalds committed
66 67
({								\
	unsigned long __temp = (unsigned long)(x);		\
68 69
	__put_user_asm_byte(__temp >> 8, __pu_addr, err);	\
	__put_user_asm_byte(__temp, __pu_addr + 1, err);	\
Linus Torvalds's avatar
Linus Torvalds committed
70 71
})
#endif
Linus Torvalds's avatar
Linus Torvalds committed
72

73
#define __put_user_asm_word(x,__pu_addr,err)			\
Linus Torvalds's avatar
Linus Torvalds committed
74 75 76 77 78 79 80 81 82 83 84 85
	__asm__ __volatile__(					\
	"1:	strt	%1,[%2],#0\n"				\
	"2:\n"							\
	"	.section .fixup,\"ax\"\n"			\
	"	.align	2\n"					\
	"3:	mov	%0, %3\n"				\
	"	b	2b\n"					\
	"	.previous\n"					\
	"	.section __ex_table,\"a\"\n"			\
	"	.align	3\n"					\
	"	.long	1b, 3b\n"				\
	"	.previous"					\
86 87 88
	: "+r" (err)						\
	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
	: "cc")
89

90 91 92 93 94 95 96 97
#ifndef __ARMEB__
#define	__reg_oper0	"%R2"
#define	__reg_oper1	"%Q2"
#else
#define	__reg_oper0	"%Q2"
#define	__reg_oper1	"%R2"
#endif

98 99
#define __put_user_asm_dword(x,__pu_addr,err)			\
	__asm__ __volatile__(					\
100 101
	"1:	strt	" __reg_oper1 ", [%1], #4\n"		\
	"2:	strt	" __reg_oper0 ", [%1], #0\n"		\
102 103 104
	"3:\n"							\
	"	.section .fixup,\"ax\"\n"			\
	"	.align	2\n"					\
105
	"4:	mov	%0, %3\n"				\
106 107 108 109 110 111 112
	"	b	3b\n"					\
	"	.previous\n"					\
	"	.section __ex_table,\"a\"\n"			\
	"	.align	3\n"					\
	"	.long	1b, 4b\n"				\
	"	.long	2b, 4b\n"				\
	"	.previous"					\
113 114 115
	: "+r" (err), "+r" (__pu_addr)				\
	: "r" (x), "i" (-EFAULT)				\
	: "cc")
Linus Torvalds's avatar
Linus Torvalds committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

#define __get_user_asm_byte(x,addr,err)				\
	__asm__ __volatile__(					\
	"1:	ldrbt	%1,[%2],#0\n"				\
	"2:\n"							\
	"	.section .fixup,\"ax\"\n"			\
	"	.align	2\n"					\
	"3:	mov	%0, %3\n"				\
	"	mov	%1, #0\n"				\
	"	b	2b\n"					\
	"	.previous\n"					\
	"	.section __ex_table,\"a\"\n"			\
	"	.align	3\n"					\
	"	.long	1b, 3b\n"				\
	"	.previous"					\
131 132 133
	: "+r" (err), "=&r" (x)					\
	: "r" (addr), "i" (-EFAULT)				\
	: "cc")
Linus Torvalds's avatar
Linus Torvalds committed
134

Linus Torvalds's avatar
Linus Torvalds committed
135
#ifndef __ARMEB__
136
#define __get_user_asm_half(x,__gu_addr,err)			\
Linus Torvalds's avatar
Linus Torvalds committed
137
({								\
138 139 140
	unsigned long __b1, __b2;				\
	__get_user_asm_byte(__b1, __gu_addr, err);		\
	__get_user_asm_byte(__b2, __gu_addr + 1, err);		\
Linus Torvalds's avatar
Linus Torvalds committed
141
	(x) = __b1 | (__b2 << 8);				\
Linus Torvalds's avatar
Linus Torvalds committed
142
})
Linus Torvalds's avatar
Linus Torvalds committed
143
#else
144
#define __get_user_asm_half(x,__gu_addr,err)			\
Linus Torvalds's avatar
Linus Torvalds committed
145 146
({								\
	unsigned long __b1, __b2;				\
147 148
	__get_user_asm_byte(__b1, __gu_addr, err);		\
	__get_user_asm_byte(__b2, __gu_addr + 1, err);		\
Linus Torvalds's avatar
Linus Torvalds committed
149 150 151
	(x) = (__b1 << 8) | __b2;				\
})
#endif
Linus Torvalds's avatar
Linus Torvalds committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

#define __get_user_asm_word(x,addr,err)				\
	__asm__ __volatile__(					\
	"1:	ldrt	%1,[%2],#0\n"				\
	"2:\n"							\
	"	.section .fixup,\"ax\"\n"			\
	"	.align	2\n"					\
	"3:	mov	%0, %3\n"				\
	"	mov	%1, #0\n"				\
	"	b	2b\n"					\
	"	.previous\n"					\
	"	.section __ex_table,\"a\"\n"			\
	"	.align	3\n"					\
	"	.long	1b, 3b\n"				\
	"	.previous"					\
167 168 169
	: "+r" (err), "=&r" (x)					\
	: "r" (addr), "i" (-EFAULT)				\
	: "cc")
Linus Torvalds's avatar
Linus Torvalds committed
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n);
#define __do_copy_from_user(to,from,n)				\
	(n) = __arch_copy_from_user(to,from,n)

extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n);
#define __do_copy_to_user(to,from,n)				\
	(n) = __arch_copy_to_user(to,from,n)

extern unsigned long __arch_clear_user(void *addr, unsigned long n);
#define __do_clear_user(addr,sz)				\
	(sz) = __arch_clear_user(addr,sz)

extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count);
#define __do_strncpy_from_user(dst,src,count,res)		\
	(res) = __arch_strncpy_from_user(dst,src,count)

extern unsigned long __arch_strnlen_user(const char *s, long n);
#define __do_strnlen_user(s,n,res)					\
	(res) = __arch_strnlen_user(s,n)