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