1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * System call trap handler.
28 */
29 #include <sys/asm_linkage.h>
30 #include <sys/machpcb.h>
31 #include <sys/machthread.h>
32 #include <sys/syscall.h>
33 #include <sys/trap.h>
34 #include <sys/machtrap.h>
35 #include <sys/pcb.h>
36 #include <sys/machparam.h>
37
38 #if !defined(lint) && !defined(__lint)
39 #include "assym.h"
40 #endif
41
42 #ifdef TRAPTRACE
43 #include <sys/traptrace.h>
44 #endif /* TRAPTRACE */
45
46 #if defined(lint) || defined(__lint)
47
48 /*ARGSUSED*/
49 void
50 syscall_trap(struct regs *rp) /* for tags only; not called from C */
51 {}
52
53 #else /* lint */
54
55 #if (1 << SYSENT_SHIFT) != SYSENT_SIZE
56 #error "SYSENT_SHIFT does not correspond to size of sysent structure"
57 #endif
58
59 /*
60 * Native System call trap handler.
61 *
62 * We branch here from sys_trap when a 64-bit system call occurs.
63 *
64 * Entry:
65 * %o0 = regs
66 *
67 * Usage:
68 * %l0 = saved return address
69 * %l1 = saved regs
70 * %l2 = lwp
71 */
72 ENTRY_NP(syscall_trap)
73 ldn [THREAD_REG + T_CPU], %g1 ! get cpu pointer
74 mov %o7, %l0 ! save return addr
75 !
76 ! If the trapping thread has the address mask bit set, then it's
77 ! a 32-bit process, and has no business calling 64-bit syscalls.
78 !
79 ldx [%o0 + TSTATE_OFF], %l1 ! saved %tstate.am is that
80 andcc %l1, TSTATE_AM, %l1 ! of the trapping proc
81 bne,pn %xcc, _syscall_ill !
82 mov %o0, %l1 ! save reg pointer
83 mov %i0, %o0 ! copy 1st arg
84 mov %i1, %o1 ! copy 2nd arg
85 ldx [%g1 + CPU_STATS_SYS_SYSCALL], %g2
86 inc %g2 ! cpu_stats.sys.syscall++
87 stx %g2, [%g1 + CPU_STATS_SYS_SYSCALL]
88
89 !
90 ! Set new state for LWP
91 !
92 ldn [THREAD_REG + T_LWP], %l2
93 mov LWP_SYS, %g3
94 mov %i2, %o2 ! copy 3rd arg
95 stb %g3, [%l2 + LWP_STATE]
96 mov %i3, %o3 ! copy 4th arg
97 ldx [%l2 + LWP_RU_SYSC], %g2 ! pesky statistics
98 mov %i4, %o4 ! copy 5th arg
99 addx %g2, 1, %g2
100 stx %g2, [%l2 + LWP_RU_SYSC]
101 mov %i5, %o5 ! copy 6th arg
102 ! args for direct syscalls now set up
103
104 #ifdef TRAPTRACE
105 !
106 ! make trap trace entry - helps in debugging
107 !
108 rdpr %pstate, %l3
109 andn %l3, PSTATE_IE | PSTATE_AM, %g3
110 wrpr %g0, %g3, %pstate ! disable interrupt
111 TRACE_PTR(%g3, %g2) ! get trace pointer
112 GET_TRACE_TICK(%g1, %g2)
113 stxa %g1, [%g3 + TRAP_ENT_TICK]%asi
114 ldx [%l1 + G1_OFF], %g1 ! get syscall code
115 TRACE_SAVE_TL_VAL(%g3, %g1)
116 TRACE_SAVE_GL_VAL(%g3, %g0)
117 set TT_SC_ENTR, %g2
118 stha %g2, [%g3 + TRAP_ENT_TT]%asi
119 stxa %g7, [%g3 + TRAP_ENT_TSTATE]%asi ! save thread in tstate space
120 stna %sp, [%g3 + TRAP_ENT_SP]%asi
121 stna %o0, [%g3 + TRAP_ENT_F1]%asi
122 stna %o1, [%g3 + TRAP_ENT_F2]%asi
123 stna %o2, [%g3 + TRAP_ENT_F3]%asi
124 stna %o3, [%g3 + TRAP_ENT_F4]%asi
125 stna %o4, [%g3 + TRAP_ENT_TPC]%asi
126 stna %o5, [%g3 + TRAP_ENT_TR]%asi
127 TRACE_NEXT(%g3, %g2, %g1) ! set new trace pointer
128 wrpr %g0, %l3, %pstate ! enable interrupt
129 #endif /* TRAPTRACE */
130
131 !
132 ! Test for pre-system-call handling
133 !
134 ldub [THREAD_REG + T_PRE_SYS], %g3 ! pre-syscall proc?
135 #ifdef SYSCALLTRACE
136 sethi %hi(syscalltrace), %g4
137 ld [%g4 + %lo(syscalltrace)], %g4
138 orcc %g3, %g4, %g0 ! pre_syscall OR syscalltrace?
139 #else
140 tst %g3 ! is pre_syscall flag set?
141 #endif /* SYSCALLTRACE */
142
143 bnz,pn %icc, _syscall_pre
144 nop
145
146 ! Fast path invocation of new_mstate
147
148 mov LMS_USER, %o0
149 call syscall_mstate
150 mov LMS_SYSTEM, %o1
151
152 ldx [%l1 + O0_OFF], %o0 ! restore %o0
153 ldx [%l1 + O1_OFF], %o1 ! restore %o1
154 ldx [%l1 + O2_OFF], %o2
155 ldx [%l1 + O3_OFF], %o3
156 ldx [%l1 + O4_OFF], %o4
157 ldx [%l1 + O5_OFF], %o5
158
159 ! lwp_arg now set up
160 3:
161 !
162 ! Call the handler. The %o's and lwp_arg have been set up.
163 !
164 ldx [%l1 + G1_OFF], %g1 ! get code
165 set sysent, %g3 ! load address of vector table
166 cmp %g1, NSYSCALL ! check range
167 sth %g1, [THREAD_REG + T_SYSNUM] ! save syscall code
168 bgeu,pn %ncc, _syscall_ill
169 sll %g1, SYSENT_SHIFT, %g4 ! delay - get index
170 add %g3, %g4, %l4
171 ldn [%l4 + SY_CALLC], %g3 ! load system call handler
172
173 call %g3 ! call system call handler
174 nop
175 !
176 ! If handler returns two ints, then we need to split the 64-bit
177 ! return value in %o0 into %o0 and %o1
178 !
179 lduh [%l4 + SY_FLAGS], %l4 ! load sy_flags
180 andcc %l4, SE_32RVAL2, %g0 ! check for 2 x 32-bit
181 bz,pt %xcc, 5f
182 nop
183 srl %o0, 0, %o1 ! lower 32-bits into %o1
184 srlx %o0, 32, %o0 ! upper 32-bits into %o0
185 5:
186
187 #ifdef TRAPTRACE
188 !
189 ! make trap trace entry for return - helps in debugging
190 !
191 rdpr %pstate, %g5
192 andn %g5, PSTATE_IE | PSTATE_AM, %g4
193 wrpr %g0, %g4, %pstate ! disable interrupt
194 TRACE_PTR(%g4, %g2) ! get trace pointer
195 GET_TRACE_TICK(%g2, %g3)
196 stxa %g2, [%g4 + TRAP_ENT_TICK]%asi
197 lduh [THREAD_REG + T_SYSNUM], %g2
198 TRACE_SAVE_TL_VAL(%g4, %g2)
199 TRACE_SAVE_GL_VAL(%g4, %g0)
200 mov TT_SC_RET, %g2 ! system call return code
201 stha %g2, [%g4 + TRAP_ENT_TT]%asi
202 ldn [%l1 + nPC_OFF], %g2 ! get saved npc (new pc)
203 stna %g2, [%g4 + TRAP_ENT_TPC]%asi
204 ldx [%l1 + TSTATE_OFF], %g2 ! get saved tstate
205 stxa %g2, [%g4 + TRAP_ENT_TSTATE]%asi
206 stna %sp, [%g4 + TRAP_ENT_SP]%asi
207 stna THREAD_REG, [%g4 + TRAP_ENT_TR]%asi
208 stna %o0, [%g4 + TRAP_ENT_F1]%asi
209 stna %o1, [%g4 + TRAP_ENT_F2]%asi
210 stna %g0, [%g4 + TRAP_ENT_F3]%asi
211 stna %g0, [%g4 + TRAP_ENT_F4]%asi
212 TRACE_NEXT(%g4, %g2, %g3) ! set new trace pointer
213 wrpr %g0, %g5, %pstate ! enable interrupt
214 #endif /* TRAPTRACE */
215 !
216 ! Check for post-syscall processing.
217 ! This tests all members of the union containing t_astflag, t_post_sys,
218 ! and t_sig_check with one test.
219 !
220 ld [THREAD_REG + T_POST_SYS_AST], %g1
221 #ifdef SYSCALLTRACE
222 sethi %hi(syscalltrace), %g4
223 ld [%g4 + %lo(syscalltrace)], %g4
224 orcc %g4, %g1, %g0 ! OR in syscalltrace
225 #else
226 tst %g1 ! need post-processing?
227 #endif /* SYSCALLTRACE */
228 bnz,pn %icc, _syscall_post ! yes - post_syscall or AST set
229 mov LWP_USER, %g1
230 stb %g1, [%l2 + LWP_STATE] ! set lwp_state
231 stx %o0, [%l1 + O0_OFF] ! set rp->r_o0
232 stx %o1, [%l1 + O1_OFF] ! set rp->r_o1
233 clrh [THREAD_REG + T_SYSNUM] ! clear syscall code
234 ldx [%l1 + TSTATE_OFF], %g1 ! get saved tstate
235 ldn [%l1 + nPC_OFF], %g2 ! get saved npc (new pc)
236 mov CCR_IC, %g3
237 sllx %g3, TSTATE_CCR_SHIFT, %g3
238 add %g2, 4, %g4 ! calc new npc
239 andn %g1, %g3, %g1 ! clear carry bit for no error
240 stn %g2, [%l1 + PC_OFF]
241 stn %g4, [%l1 + nPC_OFF]
242 stx %g1, [%l1 + TSTATE_OFF]
243
244 ! Switch mstate back on the way out
245
246 mov LMS_SYSTEM, %o0
247 call syscall_mstate
248 mov LMS_USER, %o1
249 jmp %l0 + 8
250 nop
251
252 _syscall_pre:
253 ldx [%l1 + G1_OFF], %g1
254 call pre_syscall ! abort = pre_syscall(arg0)
255 sth %g1, [THREAD_REG + T_SYSNUM]
256
257 brnz,pn %o0, _syscall_post ! did it abort?
258 nop
259 ldx [%l1 + O0_OFF], %o0 ! reload args
260 ldx [%l1 + O1_OFF], %o1
261 ldx [%l1 + O2_OFF], %o2
262 ldx [%l1 + O3_OFF], %o3
263 ldx [%l1 + O4_OFF], %o4
264 ba,pt %xcc, 3b
265 ldx [%l1 + O5_OFF], %o5
266
267 !
268 ! Floating-point trap was pending at start of system call.
269 ! Here with:
270 ! %l3 = mpcb_flags
271 !
272 _syscall_fp:
273 andn %l3, FP_TRAPPED, %l3
274 st %l3, [%sp + STACK_BIAS + MPCB_FLAGS] ! clear FP_TRAPPED
275 jmp %l0 + 8 ! return to user_rtt
276 clrh [THREAD_REG + T_SYSNUM] ! clear syscall code
277
278 !
279 ! illegal system call - syscall number out of range
280 !
281 _syscall_ill:
282 call nosys
283 nop
284 !
285 ! Post-syscall with special processing needed.
286 !
287 _syscall_post:
288 call post_syscall ! post_syscall(rvals)
289 nop
290 jmp %l0 + 8 ! return to user_rtt
291 nop
292 SET_SIZE(syscall_trap)
293 #endif /* lint */
294
295 #if defined(lint) || defined(__lint)
296
297 void
298 syscall_trap32(void) /* for tags only - trap handler - not called from C */
299 {}
300
301 #else /* lint */
302
303 /*
304 * System call trap handler for ILP32 processes.
305 *
306 * We branch here from sys_trap when a system call occurs.
307 *
308 * Entry:
309 * %o0 = regs
310 *
311 * Usage:
312 * %l0 = saved return address
313 * %l1 = saved regs
314 * %l2 = lwp
315 */
316 ENTRY_NP(syscall_trap32)
317 ldx [THREAD_REG + T_CPU], %g1 ! get cpu pointer
318 mov %o7, %l0 ! save return addr
319
320 !
321 ! If the trapping thread has the address mask bit clear, then it's
322 ! a 64-bit process, and has no business calling 32-bit syscalls.
323 !
324 ldx [%o0 + TSTATE_OFF], %l1 ! saved %tstate.am is that
325 andcc %l1, TSTATE_AM, %l1 ! of the trapping proc
326 be,pn %xcc, _syscall_ill32 !
327 mov %o0, %l1 ! save reg pointer
328 srl %i0, 0, %o0 ! copy 1st arg, clear high bits
329 srl %i1, 0, %o1 ! copy 2nd arg, clear high bits
330 ldx [%g1 + CPU_STATS_SYS_SYSCALL], %g2
331 inc %g2 ! cpu_stats.sys.syscall++
332 stx %g2, [%g1 + CPU_STATS_SYS_SYSCALL]
333
334 !
335 ! Set new state for LWP
336 !
337 ldx [THREAD_REG + T_LWP], %l2
338 mov LWP_SYS, %g3
339 srl %i2, 0, %o2 ! copy 3rd arg, clear high bits
340 stb %g3, [%l2 + LWP_STATE]
341 srl %i3, 0, %o3 ! copy 4th arg, clear high bits
342 ldx [%l2 + LWP_RU_SYSC], %g2 ! pesky statistics
343 srl %i4, 0, %o4 ! copy 5th arg, clear high bits
344 addx %g2, 1, %g2
345 stx %g2, [%l2 + LWP_RU_SYSC]
346 srl %i5, 0, %o5 ! copy 6th arg, clear high bits
347 ! args for direct syscalls now set up
348
349 #ifdef TRAPTRACE
350 !
351 ! make trap trace entry - helps in debugging
352 !
353 rdpr %pstate, %l3
354 andn %l3, PSTATE_IE | PSTATE_AM, %g3
355 wrpr %g0, %g3, %pstate ! disable interrupt
356 TRACE_PTR(%g3, %g2) ! get trace pointer
357 GET_TRACE_TICK(%g1, %g2)
358 stxa %g1, [%g3 + TRAP_ENT_TICK]%asi
359 ldx [%l1 + G1_OFF], %g1 ! get syscall code
360 TRACE_SAVE_TL_VAL(%g3, %g1)
361 TRACE_SAVE_GL_VAL(%g3, %g0)
362 set TT_SC_ENTR, %g2
363 stha %g2, [%g3 + TRAP_ENT_TT]%asi
364 stxa %g7, [%g3 + TRAP_ENT_TSTATE]%asi ! save thread in tstate space
365 stna %sp, [%g3 + TRAP_ENT_SP]%asi
366 stna %o0, [%g3 + TRAP_ENT_F1]%asi
367 stna %o1, [%g3 + TRAP_ENT_F2]%asi
368 stna %o2, [%g3 + TRAP_ENT_F3]%asi
369 stna %o3, [%g3 + TRAP_ENT_F4]%asi
370 stna %o4, [%g3 + TRAP_ENT_TPC]%asi
371 stna %o5, [%g3 + TRAP_ENT_TR]%asi
372 TRACE_NEXT(%g3, %g2, %g1) ! set new trace pointer
373 wrpr %g0, %l3, %pstate ! enable interrupt
374 #endif /* TRAPTRACE */
375
376 !
377 ! Test for pre-system-call handling
378 !
379 ldub [THREAD_REG + T_PRE_SYS], %g3 ! pre-syscall proc?
380 #ifdef SYSCALLTRACE
381 sethi %hi(syscalltrace), %g4
382 ld [%g4 + %lo(syscalltrace)], %g4
383 orcc %g3, %g4, %g0 ! pre_syscall OR syscalltrace?
384 #else
385 tst %g3 ! is pre_syscall flag set?
386 #endif /* SYSCALLTRACE */
387 bnz,pn %icc, _syscall_pre32 ! yes - pre_syscall needed
388 nop
389
390 ! Fast path invocation of new_mstate
391 mov LMS_USER, %o0
392 call syscall_mstate
393 mov LMS_SYSTEM, %o1
394
395 lduw [%l1 + O0_OFF + 4], %o0 ! reload 32-bit args
396 lduw [%l1 + O1_OFF + 4], %o1
397 lduw [%l1 + O2_OFF + 4], %o2
398 lduw [%l1 + O3_OFF + 4], %o3
399 lduw [%l1 + O4_OFF + 4], %o4
400 lduw [%l1 + O5_OFF + 4], %o5
401
402 ! lwp_arg now set up
403 3:
404 !
405 ! Call the handler. The %o's have been set up.
406 !
407 lduw [%l1 + G1_OFF + 4], %g1 ! get 32-bit code
408 set sysent32, %g3 ! load address of vector table
409 cmp %g1, NSYSCALL ! check range
410 sth %g1, [THREAD_REG + T_SYSNUM] ! save syscall code
411 bgeu,pn %ncc, _syscall_ill32
412 sll %g1, SYSENT_SHIFT, %g4 ! delay - get index
413 add %g3, %g4, %g5 ! g5 = addr of sysentry
414 ldx [%g5 + SY_CALLC], %g3 ! load system call handler
415
416 brnz,a,pt %g1, 4f ! check for indir()
417 mov %g5, %l4 ! save addr of sysentry
418 !
419 ! Yuck. If %g1 is zero, that means we're doing a syscall() via the
420 ! indirect system call. That means we have to check the
421 ! flags of the targetted system call, not the indirect system call
422 ! itself. See return value handling code below.
423 !
424 set sysent32, %l4 ! load address of vector table
425 cmp %o0, NSYSCALL ! check range
426 bgeu,pn %ncc, 4f ! out of range, let C handle it
427 sll %o0, SYSENT_SHIFT, %g4 ! delay - get index
428 add %g4, %l4, %l4 ! compute & save addr of sysent
429 4:
430 call %g3 ! call system call handler
431 nop
432
433 !
434 ! If handler returns long long then we need to split the 64 bit
435 ! return value in %o0 into %o0 and %o1 for ILP32 clients.
436 !
437 lduh [%l4 + SY_FLAGS], %g4 ! load sy_flags
438 andcc %g4, SE_64RVAL | SE_32RVAL2, %g0 ! check for 64-bit return
439 bz,a,pt %xcc, 5f
440 srl %o0, 0, %o0 ! 32-bit only
441 srl %o0, 0, %o1 ! lower 32 bits into %o1
442 srlx %o0, 32, %o0 ! upper 32 bits into %o0
443 5:
444
445 #ifdef TRAPTRACE
446 !
447 ! make trap trace entry for return - helps in debugging
448 !
449 rdpr %pstate, %g5
450 andn %g5, PSTATE_IE | PSTATE_AM, %g4
451 wrpr %g0, %g4, %pstate ! disable interrupt
452 TRACE_PTR(%g4, %g2) ! get trace pointer
453 GET_TRACE_TICK(%g2, %g3)
454 stxa %g2, [%g4 + TRAP_ENT_TICK]%asi
455 lduh [THREAD_REG + T_SYSNUM], %g2
456 TRACE_SAVE_TL_VAL(%g4, %g2)
457 TRACE_SAVE_GL_VAL(%g4, %g0)
458 mov TT_SC_RET, %g2 ! system call return code
459 stha %g2, [%g4 + TRAP_ENT_TT]%asi
460 ldx [%l1 + nPC_OFF], %g2 ! get saved npc (new pc)
461 stna %g2, [%g4 + TRAP_ENT_TPC]%asi
462 ldx [%l1 + TSTATE_OFF], %g2 ! get saved tstate
463 stxa %g2, [%g4 + TRAP_ENT_TSTATE]%asi
464 stna %sp, [%g4 + TRAP_ENT_SP]%asi
465 stna THREAD_REG, [%g4 + TRAP_ENT_TR]%asi
466 stna %o0, [%g4 + TRAP_ENT_F1]%asi
467 stna %o1, [%g4 + TRAP_ENT_F2]%asi
468 stna %g0, [%g4 + TRAP_ENT_F3]%asi
469 stna %g0, [%g4 + TRAP_ENT_F4]%asi
470 TRACE_NEXT(%g4, %g2, %g3) ! set new trace pointer
471 wrpr %g0, %g5, %pstate ! enable interrupt
472 #endif /* TRAPTRACE */
473 !
474 ! Check for post-syscall processing.
475 ! This tests all members of the union containing t_astflag, t_post_sys,
476 ! and t_sig_check with one test.
477 !
478 ld [THREAD_REG + T_POST_SYS_AST], %g1
479 #ifdef SYSCALLTRACE
480 sethi %hi(syscalltrace), %g4
481 ld [%g4 + %lo(syscalltrace)], %g4
482 orcc %g4, %g1, %g0 ! OR in syscalltrace
483 #else
484 tst %g1 ! need post-processing?
485 #endif /* SYSCALLTRACE */
486 bnz,pn %icc, _syscall_post32 ! yes - post_syscall or AST set
487 mov LWP_USER, %g1
488 stb %g1, [%l2 + LWP_STATE] ! set lwp_state
489 stx %o0, [%l1 + O0_OFF] ! set rp->r_o0
490 stx %o1, [%l1 + O1_OFF] ! set rp->r_o1
491 clrh [THREAD_REG + T_SYSNUM] ! clear syscall code
492 ldx [%l1 + TSTATE_OFF], %g1 ! get saved tstate
493 ldx [%l1 + nPC_OFF], %g2 ! get saved npc (new pc)
494 mov CCR_IC, %g3
495 sllx %g3, TSTATE_CCR_SHIFT, %g3
496 add %g2, 4, %g4 ! calc new npc
497 andn %g1, %g3, %g1 ! clear carry bit for no error
498 stx %g2, [%l1 + PC_OFF]
499 stx %g4, [%l1 + nPC_OFF]
500 stx %g1, [%l1 + TSTATE_OFF]
501
502 ! fast path outbound microstate accounting call
503 mov LMS_SYSTEM, %o0
504 call syscall_mstate
505 mov LMS_USER, %o1
506
507 jmp %l0 + 8
508 nop
509
510
511 _syscall_pre32:
512 ldx [%l1 + G1_OFF], %g1
513 call pre_syscall ! abort = pre_syscall(arg0)
514 sth %g1, [THREAD_REG + T_SYSNUM]
515
516 brnz,pn %o0, _syscall_post32 ! did it abort?
517 nop
518 lduw [%l1 + O0_OFF + 4], %o0 ! reload 32-bit args
519 lduw [%l1 + O1_OFF + 4], %o1
520 lduw [%l1 + O2_OFF + 4], %o2
521 lduw [%l1 + O3_OFF + 4], %o3
522 lduw [%l1 + O4_OFF + 4], %o4
523 ba,pt %xcc, 3b
524 lduw [%l1 + O5_OFF + 4], %o5
525
526 !
527 ! Floating-point trap was pending at start of system call.
528 ! Here with:
529 ! %l3 = mpcb_flags
530 !
531 _syscall_fp32:
532 andn %l3, FP_TRAPPED, %l3
533 st %l3, [%sp + STACK_BIAS + MPCB_FLAGS] ! clear FP_TRAPPED
534 jmp %l0 + 8 ! return to user_rtt
535 clrh [THREAD_REG + T_SYSNUM] ! clear syscall code
536
537 !
538 ! illegal system call - syscall number out of range
539 !
540 _syscall_ill32:
541 call nosys
542 nop
543 !
544 ! Post-syscall with special processing needed.
545 !
546 _syscall_post32:
547 call post_syscall ! post_syscall(rvals)
548 nop
549 jmp %l0 + 8 ! return to user_rtt
550 nop
551 SET_SIZE(syscall_trap32)
552
553 #endif /* lint */
554
555
556 /*
557 * lwp_rtt - start execution in newly created LWP.
558 * Here with t_post_sys set by lwp_create, and lwp_eosys == JUSTRETURN,
559 * so that post_syscall() will run and the registers will
560 * simply be restored.
561 * This must go out through sys_rtt instead of syscall_rtt.
562 */
563 #if defined(lint) || defined(__lint)
564
565 void
566 lwp_rtt_initial(void)
567 {}
568
569 void
570 lwp_rtt(void)
571 {}
572
573 #else /* lint */
574 ENTRY_NP(lwp_rtt_initial)
575 ldn [THREAD_REG + T_STACK], %l7
576 call __dtrace_probe___proc_start
577 sub %l7, STACK_BIAS, %sp
578 ba,a,pt %xcc, 0f
579
580 ENTRY_NP(lwp_rtt)
581 ldn [THREAD_REG + T_STACK], %l7
582 sub %l7, STACK_BIAS, %sp
583 0:
584 call __dtrace_probe___proc_lwp__start
585 nop
586 call dtrace_systrace_rtt
587 add %sp, REGOFF + STACK_BIAS, %l7
588 ldx [%l7 + O0_OFF], %o0
589 call post_syscall
590 ldx [%l7 + O1_OFF], %o1
591 ba,a,pt %xcc, user_rtt
592 SET_SIZE(lwp_rtt)
593 SET_SIZE(lwp_rtt_initial)
594
595 #endif /* lint */