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.
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.
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]
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
26 * This is an assembly file that gets #include-ed into the brand-specific
27 * assembly files (e.g. sn1_brand_asm.s) for Solaris-derived brands.
28 * We can't make these into functions since in the trap context there's
29 * no easy place to save the extra parameters that would be required, so
30 * each brand module needs its own copy of this code. We #include this and
31 * use brand-specific #defines to replace the XXX_brand_... definitions.
35 #include <sys/asm_linkage.h>
36 #include <sys/privregs.h>
37 #include <sys/segments.h>
39 #include "brand_asm.h"
43 #ifdef _ASM /* The remainder of this file is only for assembly files */
48 * syscall handler for 32-bit user processes:
49 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
50 * To 'return' to our user-space handler, we just need to place its address
51 * into %rcx. The original return address is passed back in SYSCALL_REG.
53 ENTRY
(XXX_brand_syscall32_callback
)
54 CALLBACK_PROLOGUE
(XXX_emulation_table
, SPD_HANDLER
, SYSCALL_REG
,
56 CALC_TABLE_ADDR
(SCR_REG
, SPD_HANDLER
);
57 mov
%rcx
, SYSCALL_REG;
/* save orig return addr in syscall_reg */
58 mov SCR_REG
, %rcx;
/* place new return addr in %rcx */
59 mov
%gs
:CPU_RTMP_R15
, SCR_REG;
/* restore scratch register */
60 mov V_SSP
(SP_REG
), SP_REG
/* restore user stack pointer */
61 jmp nopop_sys_syscall32_swapgs_sysretl
64 SET_SIZE
(XXX_brand_syscall32_callback
)
67 * syscall handler for 64-bit user processes:
68 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
69 * To 'return' to our user-space handler, we just need to place its address
70 * into %rcx. The original return address is passed back in SYSCALL_REG.
72 ENTRY
(XXX_brand_syscall_callback
)
73 CALLBACK_PROLOGUE
(XXX_emulation_table
, SPD_HANDLER
, SYSCALL_REG
,
75 CALC_TABLE_ADDR
(SCR_REG
, SPD_HANDLER
);
76 mov
%rcx
, SYSCALL_REG;
/* save orig return addr in syscall_reg */
77 mov SCR_REG
, %rcx;
/* place new return addr in %rcx */
78 mov
%gs
:CPU_RTMP_R15
, SCR_REG;
/* restore scratch register */
79 mov V_SSP
(SP_REG
), SP_REG
/* restore user stack pointer */
80 jmp nopop_sys_syscall_swapgs_sysretq
83 SET_SIZE
(XXX_brand_syscall_callback
)
86 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
87 * To 'return' to our user-space handler, we just need to place its address
88 * into %rdx. The original return address is passed back in SYSCALL_REG.
90 ENTRY
(XXX_brand_sysenter_callback
)
91 CALLBACK_PROLOGUE
(XXX_emulation_table
, SPD_HANDLER
, SYSCALL_REG
,
93 CALC_TABLE_ADDR
(SCR_REG
, SPD_HANDLER
);
94 mov
%rdx
, SYSCALL_REG;
/* save orig return addr in syscall_reg */
95 mov SCR_REG
, %rdx;
/* place new return addr in %rdx */
96 mov
%gs
:CPU_RTMP_R15
, SCR_REG;
/* restore scratch register */
97 mov V_SSP
(SP_REG
), SP_REG
/* restore user stack pointer */
98 jmp sys_sysenter_swapgs_sysexit
101 SET_SIZE
(XXX_brand_sysenter_callback
)
104 * To 'return' to our user-space handler we need to update the user's %eip
105 * pointer in the saved interrupt state on the stack. The interrupt state was
106 * pushed onto our stack automatically when the interrupt occured; see the
107 * comments above. The original return address is passed back in SYSCALL_REG.
108 * See "64-BIT INTERPOSITION STACK" and "64-BIT INT STACK" in brand_asm.h.
110 ENTRY
(XXX_brand_int91_callback
)
111 CALLBACK_PROLOGUE
(XXX_emulation_table
, SPD_HANDLER
, SYSCALL_REG
,
113 CALC_TABLE_ADDR
(SCR_REG
, SPD_HANDLER
);
/* new ret addr is in scratch */
114 mov SCR_REG
, SYSCALL_REG;
/* place new ret addr in syscallreg */
115 mov
%gs
:CPU_RTMP_R15
, SCR_REG;
/* restore scratch register */
116 mov V_SSP
(SP_REG
), SP_REG;
/* restore intr stack pointer */
118 xchg
(SP_REG
), SYSCALL_REG
/* swap new and orig. return addrs */
119 jmp sys_sysint_swapgs_iret
122 SET_SIZE
(XXX_brand_int91_callback
)
127 * To 'return' to our user-space handler, we need to replace the iret target
128 * address. The original return address is passed back in %eax.
129 * See "32-BIT INTERPOSITION STACK" and "32-BIT INT STACK" in brand_asm.h.
131 ENTRY
(XXX_brand_syscall_callback
)
132 CALLBACK_PROLOGUE
(XXX_emulation_table
, SPD_HANDLER
, SYSCALL_REG
,
134 CALC_TABLE_ADDR
(SCR_REG
, SPD_HANDLER
);
/* new ret addr is in scratch */
135 mov SCR_REG
, SYSCALL_REG;
/* place new ret addr in syscallreg */
136 GET_V
(SP_REG
, 0, V_U_EBX
, SCR_REG
);
/* restore scratch register */
137 add $V_END
, SP_REG;
/* restore intr stack pointer */
139 xchg
(SP_REG
), SYSCALL_REG
/* swap new and orig. return addrs */
140 jmp nopop_sys_rtt_syscall
143 SET_SIZE
(XXX_brand_syscall_callback
)
146 * To 'return' to our user-space handler, we just need to place its address
147 * into %edx. The original return address is passed back in SYSCALL_REG.
148 * See "32-BIT INTERPOSITION STACK" in brand_asm.h.
150 ENTRY
(XXX_brand_sysenter_callback
)
151 CALLBACK_PROLOGUE
(XXX_emulation_table
, SPD_HANDLER
, SYSCALL_REG
,
153 mov
%edx
, SCR_REG;
/* save orig return addr in scr reg */
154 CALC_TABLE_ADDR
(%edx
, SPD_HANDLER
);
/* new return addr is in %edx */
155 mov SCR_REG
, SYSCALL_REG;
/* save orig return addr in %eax */
156 GET_V
(SP_REG
, 0, V_U_EBX
, SCR_REG
) /* restore scratch register */
160 SET_SIZE
(XXX_brand_sysenter_callback
)
162 #endif /* !__amd64 */