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