Commit | Line | Data |
---|---|---|
76580237 AV |
1 | /* |
2 | * include/asm-xtensa/uaccess.h | |
3 | * | |
4 | * User space memory access functions | |
5 | * | |
6 | * These routines provide basic accessing functions to the user memory | |
7 | * space for the kernel. This header file provides functions such as: | |
8 | * | |
9 | * This file is subject to the terms and conditions of the GNU General Public | |
10 | * License. See the file "COPYING" in the main directory of this archive | |
11 | * for more details. | |
12 | * | |
13 | * Copyright (C) 2001 - 2005 Tensilica Inc. | |
14 | */ | |
15 | ||
16 | #ifndef _XTENSA_ASM_UACCESS_H | |
17 | #define _XTENSA_ASM_UACCESS_H | |
18 | ||
19 | #include <linux/errno.h> | |
20 | #include <asm/types.h> | |
21 | ||
76580237 AV |
22 | #include <asm/current.h> |
23 | #include <asm/asm-offsets.h> | |
24 | #include <asm/processor.h> | |
25 | ||
26 | /* | |
27 | * These assembly macros mirror the C macros in asm/uaccess.h. They | |
28 | * should always have identical functionality. See | |
29 | * arch/xtensa/kernel/sys.S for usage. | |
30 | */ | |
31 | ||
32 | #define KERNEL_DS 0 | |
33 | #define USER_DS 1 | |
34 | ||
76580237 AV |
35 | /* |
36 | * get_fs reads current->thread.current_ds into a register. | |
37 | * On Entry: | |
38 | * <ad> anything | |
39 | * <sp> stack | |
40 | * On Exit: | |
41 | * <ad> contains current->thread.current_ds | |
42 | */ | |
43 | .macro get_fs ad, sp | |
44 | GET_CURRENT(\ad,\sp) | |
45 | #if THREAD_CURRENT_DS > 1020 | |
46 | addi \ad, \ad, TASK_THREAD | |
47 | l32i \ad, \ad, THREAD_CURRENT_DS - TASK_THREAD | |
48 | #else | |
49 | l32i \ad, \ad, THREAD_CURRENT_DS | |
50 | #endif | |
51 | .endm | |
52 | ||
53 | /* | |
54 | * set_fs sets current->thread.current_ds to some value. | |
55 | * On Entry: | |
56 | * <at> anything (temp register) | |
57 | * <av> value to write | |
58 | * <sp> stack | |
59 | * On Exit: | |
60 | * <at> destroyed (actually, current) | |
61 | * <av> preserved, value to write | |
62 | */ | |
63 | .macro set_fs at, av, sp | |
64 | GET_CURRENT(\at,\sp) | |
65 | s32i \av, \at, THREAD_CURRENT_DS | |
66 | .endm | |
67 | ||
68 | /* | |
69 | * kernel_ok determines whether we should bypass addr/size checking. | |
70 | * See the equivalent C-macro version below for clarity. | |
71 | * On success, kernel_ok branches to a label indicated by parameter | |
72 | * <success>. This implies that the macro falls through to the next | |
73 | * insruction on an error. | |
74 | * | |
75 | * Note that while this macro can be used independently, we designed | |
76 | * in for optimal use in the access_ok macro below (i.e., we fall | |
77 | * through on error). | |
78 | * | |
79 | * On Entry: | |
80 | * <at> anything (temp register) | |
81 | * <success> label to branch to on success; implies | |
82 | * fall-through macro on error | |
83 | * <sp> stack pointer | |
84 | * On Exit: | |
85 | * <at> destroyed (actually, current->thread.current_ds) | |
86 | */ | |
87 | ||
88 | #if ((KERNEL_DS != 0) || (USER_DS == 0)) | |
89 | # error Assembly macro kernel_ok fails | |
90 | #endif | |
91 | .macro kernel_ok at, sp, success | |
92 | get_fs \at, \sp | |
93 | beqz \at, \success | |
94 | .endm | |
95 | ||
96 | /* | |
97 | * user_ok determines whether the access to user-space memory is allowed. | |
98 | * See the equivalent C-macro version below for clarity. | |
99 | * | |
100 | * On error, user_ok branches to a label indicated by parameter | |
101 | * <error>. This implies that the macro falls through to the next | |
102 | * instruction on success. | |
103 | * | |
104 | * Note that while this macro can be used independently, we designed | |
105 | * in for optimal use in the access_ok macro below (i.e., we fall | |
106 | * through on success). | |
107 | * | |
108 | * On Entry: | |
109 | * <aa> register containing memory address | |
110 | * <as> register containing memory size | |
111 | * <at> temp register | |
112 | * <error> label to branch to on error; implies fall-through | |
113 | * macro on success | |
114 | * On Exit: | |
115 | * <aa> preserved | |
116 | * <as> preserved | |
117 | * <at> destroyed (actually, (TASK_SIZE + 1 - size)) | |
118 | */ | |
119 | .macro user_ok aa, as, at, error | |
120 | movi \at, __XTENSA_UL_CONST(TASK_SIZE) | |
121 | bgeu \as, \at, \error | |
122 | sub \at, \at, \as | |
123 | bgeu \aa, \at, \error | |
124 | .endm | |
125 | ||
126 | /* | |
127 | * access_ok determines whether a memory access is allowed. See the | |
128 | * equivalent C-macro version below for clarity. | |
129 | * | |
130 | * On error, access_ok branches to a label indicated by parameter | |
131 | * <error>. This implies that the macro falls through to the next | |
132 | * instruction on success. | |
133 | * | |
134 | * Note that we assume success is the common case, and we optimize the | |
135 | * branch fall-through case on success. | |
136 | * | |
137 | * On Entry: | |
138 | * <aa> register containing memory address | |
139 | * <as> register containing memory size | |
140 | * <at> temp register | |
141 | * <sp> | |
142 | * <error> label to branch to on error; implies fall-through | |
143 | * macro on success | |
144 | * On Exit: | |
145 | * <aa> preserved | |
146 | * <as> preserved | |
147 | * <at> destroyed | |
148 | */ | |
149 | .macro access_ok aa, as, at, sp, error | |
150 | kernel_ok \at, \sp, .Laccess_ok_\@ | |
151 | user_ok \aa, \as, \at, \error | |
152 | .Laccess_ok_\@: | |
153 | .endm | |
154 | ||
155 | #endif /* _XTENSA_ASM_UACCESS_H */ |