~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_CN/arch/arm/kernel_user_helpers.txt

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 Chinese translated version of Documentation/arch/arm/kernel_user_helpers.rst
  2 
  3 If you have any comment or update to the content, please contact the
  4 original document maintainer directly.  However, if you have a problem
  5 communicating in English you can also ask the Chinese maintainer for
  6 help.  Contact the Chinese maintainer if this translation is outdated
  7 or if there is a problem with the translation.
  8 
  9 Maintainer: Nicolas Pitre <nicolas.pitre@linaro.org>
 10                 Dave Martin <dave.martin@linaro.org>
 11 Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
 12 ---------------------------------------------------------------------
 13 Documentation/arch/arm/kernel_user_helpers.rst 的中文翻译
 14 
 15 如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
 16 交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
 17 译存在问题,请联系中文版维护者。
 18 英文版维护者: Nicolas Pitre <nicolas.pitre@linaro.org>
 19                 Dave Martin <dave.martin@linaro.org>
 20 中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
 21 中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
 22 中文版校译者: 宋冬生 Dongsheng Song <dongshneg.song@gmail.com>
 23                 傅炜 Fu Wei <tekkamanninja@gmail.com>
 24 
 25 
 26 以下为正文
 27 ---------------------------------------------------------------------
 28 内核提供的用户空间辅助代码
 29 =========================
 30 
 31 在内核内存空间的固定地址处,有一个由内核提供并可从用户空间访问的代码
 32 段。它用于向用户空间提供因在许多 ARM CPU 中未实现的特性和/或指令而需
 33 内核提供帮助的某些操作。这些代码直接在用户模式下执行的想法是为了获得
 34 最佳效率,但那些与内核计数器联系过于紧密的部分,则被留给了用户库实现。
 35 事实上,此代码甚至可能因不同的 CPU 而异,这取决于其可用的指令集或它
 36 是否为 SMP 系统。换句话说,内核保留在不作出警告的情况下根据需要更改
 37 这些代码的权利。只有本文档描述的入口及其结果是保证稳定的。
 38 
 39 这与完全成熟的 VDSO 实现不同(但两者并不冲突),尽管如此,VDSO 可阻止
 40 某些通过常量高效跳转到那些代码段的汇编技巧。且由于那些代码段在返回用户
 41 代码前仅使用少量的代码周期,则一个 VDSO 间接远程调用将会在这些简单的
 42 操作上增加一个可测量的开销。
 43 
 44 在对那些拥有原生支持的新型处理器进行代码优化时,仅在已为其他操作使用
 45 了类似的新增指令,而导致二进制结果已与早期 ARM 处理器不兼容的情况下,
 46 用户空间才应绕过这些辅助代码,并在内联函数中实现这些操作(无论是通过
 47 编译器在代码中直接放置,还是作为库函数调用实现的一部分)。也就是说,
 48 如果你编译的代码不会为了其他目的使用新指令,则不要仅为了避免使用这些
 49 内核辅助代码,导致二进制程序无法在早期处理器上运行。
 50 
 51 新的辅助代码可能随着时间的推移而增加,所以新内核中的某些辅助代码在旧
 52 内核中可能不存在。因此,程序必须在对任何辅助代码调用假设是安全之前,
 53 检测 __kuser_helper_version 的值(见下文)。理想情况下,这种检测应该
 54 只在进程启动时执行一次;如果内核版本不支持所需辅助代码,则该进程可尽早
 55 中止执行。
 56 
 57 kuser_helper_version
 58 --------------------
 59 
 60 位置: 0xffff0ffc
 61 
 62 参考声明:
 63 
 64   extern int32_t __kuser_helper_version;
 65 
 66 定义:
 67 
 68   这个区域包含了当前运行内核实现的辅助代码版本号。用户空间可以通过读
 69   取此版本号以确定特定的辅助代码是否存在。
 70 
 71 使用范例:
 72 
 73 #define __kuser_helper_version (*(int32_t *)0xffff0ffc)
 74 
 75 void check_kuser_version(void)
 76 {
 77         if (__kuser_helper_version < 2) {
 78                 fprintf(stderr, "can't do atomic operations, kernel too old\n");
 79                 abort();
 80         }
 81 }
 82 
 83 注意:
 84 
 85   用户空间可以假设这个域的值不会在任何单个进程的生存期内改变。也就
 86   是说,这个域可以仅在库的初始化阶段或进程启动阶段读取一次。
 87 
 88 kuser_get_tls
 89 -------------
 90 
 91 位置: 0xffff0fe0
 92 
 93 参考原型:
 94 
 95   void * __kuser_get_tls(void);
 96 
 97 输入:
 98 
 99   lr = 返回地址
100 
101 输出:
102 
103   r0 = TLS 值
104 
105 被篡改的寄存器:
106 
107108 
109 定义:
110 
111   获取之前通过 __ARM_NR_set_tls 系统调用设置的 TLS 值。
112 
113 使用范例:
114 
115 typedef void * (__kuser_get_tls_t)(void);
116 #define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
117 
118 void foo()
119 {
120         void *tls = __kuser_get_tls();
121         printf("TLS = %p\n", tls);
122 }
123 
124 注意:
125 
126   - 仅在 __kuser_helper_version >= 1 时,此辅助代码存在
127     (从内核版本 2.6.12 开始)。
128 
129 kuser_cmpxchg
130 -------------
131 
132 位置: 0xffff0fc0
133 
134 参考原型:
135 
136   int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
137 
138 输入:
139 
140   r0 = oldval
141   r1 = newval
142   r2 = ptr
143   lr = 返回地址
144 
145 输出:
146 
147   r0 = 成功代码 (零或非零)
148   C flag = 如果 r0 == 0 则置 1,如果 r0 != 0 则清零。
149 
150 被篡改的寄存器:
151 
152   r3, ip, flags
153 
154 定义:
155 
156   仅在 *ptr 为 oldval 时原子保存 newval 于 *ptr 中。
157   如果 *ptr 被改变,则返回值为零,否则为非零值。
158   如果 *ptr 被改变,则 C flag 也会被置 1,以实现调用代码中的汇编
159   优化。
160 
161 使用范例:
162 
163 typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
164 #define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
165 
166 int atomic_add(volatile int *ptr, int val)
167 {
168         int old, new;
169 
170         do {
171                 old = *ptr;
172                 new = old + val;
173         } while(__kuser_cmpxchg(old, new, ptr));
174 
175         return new;
176 }
177 
178 注意:
179 
180   - 这个例程已根据需要包含了内存屏障。
181 
182   - 仅在 __kuser_helper_version >= 2 时,此辅助代码存在
183     (从内核版本 2.6.12 开始)。
184 
185 kuser_memory_barrier
186 --------------------
187 
188 位置: 0xffff0fa0
189 
190 参考原型:
191 
192   void __kuser_memory_barrier(void);
193 
194 输入:
195 
196   lr = 返回地址
197 
198 输出:
199 
200201 
202 被篡改的寄存器:
203 
204205 
206 定义:
207 
208   应用于任何需要内存屏障以防止手动数据修改带来的一致性问题,以及
209   __kuser_cmpxchg 中。
210 
211 使用范例:
212 
213 typedef void (__kuser_dmb_t)(void);
214 #define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
215 
216 注意:
217 
218   - 仅在 __kuser_helper_version >= 3 时,此辅助代码存在
219     (从内核版本 2.6.15 开始)。
220 
221 kuser_cmpxchg64
222 ---------------
223 
224 位置: 0xffff0f60
225 
226 参考原型:
227 
228   int __kuser_cmpxchg64(const int64_t *oldval,
229                         const int64_t *newval,
230                         volatile int64_t *ptr);
231 
232 输入:
233 
234   r0 = 指向 oldval
235   r1 = 指向 newval
236   r2 = 指向目标值
237   lr = 返回地址
238 
239 输出:
240 
241   r0 = 成功代码 (零或非零)
242   C flag = 如果 r0 == 0 则置 1,如果 r0 != 0 则清零。
243 
244 被篡改的寄存器:
245 
246   r3, lr, flags
247 
248 定义:
249 
250   仅在 *ptr 等于 *oldval 指向的 64 位值时,原子保存 *newval
251   指向的 64 位值于 *ptr 中。如果 *ptr 被改变,则返回值为零,
252   否则为非零值。
253 
254   如果 *ptr 被改变,则 C flag 也会被置 1,以实现调用代码中的汇编
255   优化。
256 
257 使用范例:
258 
259 typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
260                                   const int64_t *newval,
261                                   volatile int64_t *ptr);
262 #define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
263 
264 int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
265 {
266         int64_t old, new;
267 
268         do {
269                 old = *ptr;
270                 new = old + val;
271         } while(__kuser_cmpxchg64(&old, &new, ptr));
272 
273         return new;
274 }
275 
276 注意:
277 
278   - 这个例程已根据需要包含了内存屏障。
279 
280   - 由于这个过程的代码长度(此辅助代码跨越 2 个常规的 kuser “槽”),
281     因此 0xffff0f80 不被作为有效的入口点。
282 
283   - 仅在 __kuser_helper_version >= 5 时,此辅助代码存在
284     (从内核版本 3.1 开始)。

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php