Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: src/trusted/service_runtime/arch/x86_64/nacl_tls_64.c

Issue 12218089: Remove nacl_user[] array lookup from syscall code path on x86-64 and MIPS (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #if NACL_OSX 7 #if NACL_OSX
8 # include <pthread.h> 8 # include <pthread.h>
9 #endif 9 #endif
10 10
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 uint32_t NaClTlsGetTlsValue2(struct NaClAppThread *natp) { 136 uint32_t NaClTlsGetTlsValue2(struct NaClAppThread *natp) {
137 return natp->user.tls_value2; 137 return natp->user.tls_value2;
138 } 138 }
139 139
140 uint32_t NaClGetThreadIdx(struct NaClAppThread *natp) { 140 uint32_t NaClGetThreadIdx(struct NaClAppThread *natp) {
141 return natp->user.tls_idx; 141 return natp->user.tls_idx;
142 } 142 }
143 143
144 #if NACL_OSX 144 #if NACL_OSX
145 145
146 pthread_key_t nacl_thread_info_key; 146 static pthread_key_t nacl_thread_info_key;
147 uint32_t nacl_thread_index_tls_offset; 147 uint32_t nacl_current_thread_tls_offset;
148 148
149 int NaClTlsInit(void) { 149 int NaClTlsInit(void) {
150 int errnum; 150 int errnum;
151 151
152 /* 152 /*
153 * Unlike Linux and Windows, Mac OS X does not provide TLS variables 153 * Unlike Linux and Windows, Mac OS X does not provide TLS variables
154 * that can be accessed via a TLS register without a function call, 154 * that can be accessed via a TLS register without a function call,
155 * which we need in order to restore the thread's trusted stack in 155 * which we need in order to restore the thread's trusted stack in
156 * nacl_syscall_64.S. 156 * nacl_syscall_64.S.
157 * 157 *
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 return 0; 190 return 0;
191 } 191 }
192 192
193 errnum = pthread_key_create(&nacl_thread_info_key, (void (*)(void *)) 0); 193 errnum = pthread_key_create(&nacl_thread_info_key, (void (*)(void *)) 0);
194 if (0 != errnum) { 194 if (0 != errnum) {
195 NaClLog(LOG_WARNING, 195 NaClLog(LOG_WARNING,
196 "NaClTlsInit: pthread_key_create failed for thread info key, %d\n", 196 "NaClTlsInit: pthread_key_create failed for thread info key, %d\n",
197 errnum); 197 errnum);
198 return 0; 198 return 0;
199 } 199 }
200 nacl_thread_index_tls_offset = pthread_tsd_offset + 8 * nacl_thread_info_key; 200 nacl_current_thread_tls_offset =
201 pthread_tsd_offset + 8 * nacl_thread_info_key;
201 202
202 return 1; 203 return 1;
203 } 204 }
204 205
205 void NaClTlsFini(void) { 206 void NaClTlsFini(void) {
206 int errnum = pthread_key_delete(nacl_thread_info_key); 207 int errnum = pthread_key_delete(nacl_thread_info_key);
207 if (0 != errnum) { 208 if (0 != errnum) {
208 NaClLog(LOG_FATAL, 209 NaClLog(LOG_FATAL,
209 "NaClTlsInit: pthread_key_delete failed for thread info key, %d\n", 210 "NaClTlsInit: pthread_key_delete failed for thread info key, %d\n",
210 errnum); 211 errnum);
211 } 212 }
212 NaClThreadIdxFini(); 213 NaClThreadIdxFini();
213 return; 214 return;
214 } 215 }
215 216
216 void NaClTlsSetIdx(uint32_t tls_idx) { 217 void NaClTlsSetCurrentThread(struct NaClAppThread *natp) {
217 uint32_t tls_idx_check; 218 struct NaClThreadContext *ntcp_check;
218 219
219 #if 1 /* PARANOIA */ 220 #if 1 /* PARANOIA */
220 if (NULL != pthread_getspecific(nacl_thread_info_key)) { 221 if (NULL != pthread_getspecific(nacl_thread_info_key)) {
221 NaClLog(LOG_WARNING, 222 NaClLog(LOG_WARNING,
222 "NaClSetThreadInfo invoked twice for the same thread\n"); 223 "NaClSetThreadInfo invoked twice for the same thread\n");
223 } 224 }
224 #endif 225 #endif
225 pthread_setspecific(nacl_thread_info_key, (void *) (uintptr_t) tls_idx); 226 if (pthread_setspecific(nacl_thread_info_key, &natp->user) != 0) {
227 NaClLog(LOG_FATAL, "NaClTlsSetCurrentThread: "
228 "pthread_setspecific() failed\n");
229 }
226 230
227 /* 231 /*
228 * Sanity check: Make sure that reading back the value using our 232 * Sanity check: Make sure that reading back the value using our
229 * knowledge of Mac OS X's TLS internals gives us the correct value. 233 * knowledge of Mac OS X's TLS internals gives us the correct value.
230 * This checks that we inferred _PTHREAD_TSD_OFFSET correctly earlier. 234 * This checks that we inferred _PTHREAD_TSD_OFFSET correctly earlier.
231 */ 235 */
232 __asm__("movl %%gs:(%1), %0" 236 __asm__("movq %%gs:(%1), %0"
233 : "=r"(tls_idx_check) 237 : "=r"(ntcp_check)
234 : "r"(nacl_thread_index_tls_offset)); 238 : "r"(nacl_current_thread_tls_offset));
235 if (tls_idx_check != tls_idx) { 239 if (ntcp_check != &natp->user) {
236 NaClLog(LOG_FATAL, "NaClTlsSetIdx: Sanity check failed: " 240 NaClLog(LOG_FATAL, "NaClTlsSetCurrentThread: Sanity check failed: "
237 "TLS offset must be wrong\n"); 241 "TLS offset must be wrong\n");
238 } 242 }
239 } 243 }
240 244
241 /* 245 /*
242 * May be called from asm (or have compiler-generated code copied into 246 * May be called from asm (or have compiler-generated code copied into
243 * asm)! We assume that register state is amenable to the use of 247 * asm)! We assume that register state is amenable to the use of
244 * pthread_getspecific. For both x86-32 and x86-64 OSX, this compiles 248 * pthread_getspecific. For both x86-32 and x86-64 OSX, this compiles
245 * to just a memory load using the %gs or %fs segment prefixes, and 249 * to just a memory load using the %gs or %fs segment prefixes, and
246 * for x86-64 we do not change %fs. (However, we are unlikely to use 250 * for x86-64 we do not change %fs. (However, we are unlikely to use
247 * this for x86-32 on OSX, since that's handled by NaCl "Classic" 251 * this for x86-32 on OSX, since that's handled by NaCl "Classic"
248 * where %gs gets swapped, and we use %gs >> 3 in the asm code.) 252 * where %gs gets swapped, and we use %gs >> 3 in the asm code.)
249 */ 253 */
250 uint32_t NaClTlsGetIdx(void) { 254 struct NaClAppThread *NaClTlsGetCurrentThread(void) {
251 return (intptr_t) pthread_getspecific(nacl_thread_info_key); 255 struct NaClThreadContext *ntcp = pthread_getspecific(nacl_thread_info_key);
256 return NaClAppThreadFromThreadContext(ntcp);
252 } 257 }
253 258
254 #elif NACL_LINUX || NACL_WINDOWS 259 #elif NACL_LINUX || NACL_WINDOWS
255 260
256 THREAD uint32_t nacl_thread_index; 261 /* May be NULL if the current thread does not host a NaClAppThread. */
257 /* encoded index; 0 is used to indicate error */ 262 THREAD struct NaClThreadContext *nacl_current_thread;
258 263
259 int NaClTlsInit(void) { 264 int NaClTlsInit(void) {
260
261 NaClThreadStartupCheck(); 265 NaClThreadStartupCheck();
262 266
263 if (!NaClThreadIdxInit()) { 267 if (!NaClThreadIdxInit()) {
264 return 0; 268 return 0;
265 } 269 }
266 return 1; 270 return 1;
267 } 271 }
268 272
269 void NaClTlsFini(void) { 273 void NaClTlsFini(void) {
270 NaClThreadIdxFini(); 274 NaClThreadIdxFini();
271 } 275 }
272 276
273 /* 277 /*
274 * On x86-64, we must avoid using segment registers since Windows 278 * On x86-64, we must avoid using segment registers since Windows
275 * Vista 64, Windows 7 64, etc do not permit user code to create LDT 279 * Vista 64, Windows 7 64, etc do not permit user code to create LDT
276 * entries. The sandboxing scheme reserves %r15 for the base of the 280 * entries. The sandboxing scheme reserves %r15 for the base of the
277 * NaCl app's 4G address space, but does not reserve any additional 281 * NaCl app's 4G address space, but does not reserve any additional
278 * registers for thread identity. This reduces additional register 282 * registers for thread identity. This reduces additional register
279 * pressure, but implies that we have to figure out the thread 283 * pressure, but implies that we have to figure out the thread
280 * identity in some other way -- we use TLS (or TSD, see below) to do 284 * identity in some other way -- we use TLS (or TSD, see below) to do
281 * so, and on context switch we must access the TLS variable in order 285 * so, and on context switch we must access the TLS variable in order
282 * to determine where to save the user register context. 286 * to determine where to save the user register context.
283 */ 287 */
284 void NaClTlsSetIdx(uint32_t tls_idx) { 288 void NaClTlsSetCurrentThread(struct NaClAppThread *natp) {
285 nacl_thread_index = tls_idx; 289 nacl_current_thread = &natp->user;
286 } 290 }
287 291
288 uint32_t NaClTlsGetIdx(void) { 292 struct NaClAppThread *NaClTlsGetCurrentThread(void) {
289 return nacl_thread_index; 293 return NaClAppThreadFromThreadContext(nacl_current_thread);
290 } 294 }
291 295
292 #else 296 #else
293 # error "Woe to the service runtime. What OS is it being compiled for?!?" 297 # error "Woe to the service runtime. What OS is it being compiled for?!?"
294 #endif 298 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698