Print this page
OS-3149 lx brand always sends SIGCHLD to parent processes, regardless of how clone was invoked
OS-2887 lxbrand add WALL, WCLONE, WNOTHREAD support to waitid
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/intel/brand/common/brand_asm.h
+++ new/usr/src/uts/intel/brand/common/brand_asm.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #ifndef _COMMON_BRAND_ASM_H
26 26 #define _COMMON_BRAND_ASM_H
27 27
28 28 #ifdef __cplusplus
29 29 extern "C" {
30 30 #endif
31 31
32 32 #ifndef lint
33 33
34 34 #include <sys/asm_linkage.h>
35 35 #include <sys/privregs.h>
36 36 #include <sys/segments.h>
37 37 #include "assym.h"
38 38
39 39 #endif /* lint */
40 40
41 41 #ifdef _ASM /* The remainder of this file is only for assembly files */
42 42
43 43 #if defined(__amd64)
44 44 /*
45 45 * Common to all 64-bit callbacks:
46 46 *
47 47 * We're running on the kernel's %gs.
48 48 *
49 49 * We return directly to userland, bypassing the _update_sregs logic, so
50 50 * the routine must NOT do anything that could cause a context switch.
51 51 *
52 52 * %rax - syscall number
53 53 *
54 54 * When called, all general registers, except for %r15, are as they were when
55 55 * the user process made the system call. %r15 is available to the callback as
56 56 * a scratch register. If the callback returns to the kernel path, %r15 does
57 57 * not have to be restored to the user value. If the callback returns to the
58 58 * userlevel emulation code, the callback should restore %r15 if the emulation
59 59 * depends on the original userlevel value.
60 60 *
61 61 * 64-BIT INTERPOSITION STACK
62 62 * On entry to the callback the stack looks like this:
63 63 * --------------------------------------
64 64 * 32 | callback pointer |
65 65 * 24 | saved stack pointer |
66 66 * | 16 | lwp pointer |
67 67 * v 8 | user return address |
68 68 * 0 | BRAND_CALLBACK()'s return addr |
69 69 * --------------------------------------
70 70 */
71 71
72 72 #define V_COUNT 5
73 73 #define V_END (CLONGSIZE * 5)
74 74 #define V_SSP (CLONGSIZE * 3)
75 75 #define V_LWP (CLONGSIZE * 2)
76 76 #define V_URET_ADDR (CLONGSIZE * 1)
77 77 #define V_CB_ADDR (CLONGSIZE * 0)
78 78
79 79 #define SP_REG %rsp
80 80 #define SCR_REG %r15
81 81 #define SCR_REGB %r15b
82 82 #define SYSCALL_REG %rax
83 83
84 84 /*
85 85 * 64-BIT INT STACK
86 86 * For int callbacks (e.g. int91) the saved stack pointer (V_SSP) points at
87 87 * the state saved when we took the interrupt:
88 88 * --------------------------------------
89 89 * | 32 | user's %ss |
90 90 * | 24 | user's %esp |
91 91 * | 16 | EFLAGS register |
92 92 * v 8 | user's %cs |
93 93 * 0 | user's %eip (user return address) |
94 94 * --------------------------------------
95 95 */
96 96 #define V_U_EIP (CLONGSIZE * 0)
97 97
98 98 #else /* !__amd64 */
99 99 /*
100 100 * 32-BIT INTERPOSITION STACK
101 101 * When our syscall interposition callback entry point gets invoked the
102 102 * stack looks like this:
103 103 * --------------------------------------
104 104 * | 16 | 'scratch space' |
105 105 * | 12 | user's %ebx |
106 106 * | 8 | user's %gs selector |
107 107 * v 4 | lwp pointer |
108 108 * 0 | callback wrapper return addr |
109 109 * --------------------------------------
110 110 */
111 111
112 112 #define V_COUNT 5
113 113 #define V_END (CLONGSIZE * 5)
114 114 #define V_U_EBX (CLONGSIZE * 3)
115 115 #define V_LWP (CLONGSIZE * 1)
116 116 #define V_CB_ADDR (CLONGSIZE * 0)
117 117
118 118 #define SP_REG %esp
119 119 #define SCR_REG %ebx
120 120 #define SCR_REGB %bl
121 121 #define SYSCALL_REG %eax
122 122
123 123 /*
124 124 * 32-BIT INT STACK
125 125 * For the lcall handler for 32-bit OS (i.e. xxx_brand_syscall_callback)
126 126 * above the stack contents common to all callbacks is the int/lcall-specific
127 127 * state:
128 128 * --------------------------------------
129 129 * | 36 | user's %ss |
130 130 * | 32 | user's %esp |
131 131 * | 28 | EFLAGS register |
132 132 * v 24 | user's %cs |
133 133 * 20 | user's %eip (user return address) |
134 134 * --------------------------------------
135 135 */
136 136 #define V_U_EIP (V_END + (CLONGSIZE * 0))
137 137
138 138 #endif /* !__amd64 */
139 139
140 140 /*
141 141 * The following macros allow us to access to variables/parameters passed
142 142 * in on the stack. They take the following variables:
143 143 * sp - a register with the current stack pointer value
144 144 * pcnt - the number of words currently pushed onto the stack
145 145 * var - the variable to lookup
146 146 * reg - a register to read the variable into, or
147 147 * a register to write to the variable
148 148 */
149 149 #define V_OFFSET(pcnt, var) \
150 150 (var + (pcnt * CLONGSIZE))
151 151
152 152 #define GET_V(sp, pcnt, var, reg) \
153 153 mov V_OFFSET(pcnt, var)(sp), reg
|
↓ open down ↓ |
153 lines elided |
↑ open up ↑ |
154 154
155 155 #define SET_V(sp, pcnt, var, reg) \
156 156 mov reg, V_OFFSET(pcnt, var)(sp)
157 157
158 158 #define GET_PROCP(sp, pcnt, reg) \
159 159 GET_V(sp, pcnt, V_LWP, reg); /* get lwp pointer */ \
160 160 mov LWP_PROCP(reg), reg /* get proc pointer */
161 161
162 162 #define GET_P_BRAND_DATA(sp, pcnt, reg) \
163 163 GET_PROCP(sp, pcnt, reg); \
164 - mov P_BRAND_DATA(reg), reg /* get p_brand_data */
164 + mov __P_BRAND_DATA(reg), reg /* get p_brand_data */
165 165
166 166 /*
167 167 * Each of the following macros returns to the standard syscall codepath if
168 168 * it detects that this process is not able, or intended, to emulate this
169 169 * system call. They all assume that the routine provides a 'bail-out'
170 170 * label of '9'.
171 171 */
172 172
173 173 /*
174 174 * See if this process has a user-space handler registered for it. For the
175 175 * brand, the per-process brand data holds the address of the handler.
176 176 * As shown in the stack diagrams above, the callback code leaves the lwp
177 177 * pointer at well-defined offsets, so check if proc_data_t->X_handler is
178 178 * non-NULL. For each brand, the handler parameter refers to the brand's
179 179 * user-space handler variable name.
180 180 */
181 181 #define CHECK_FOR_HANDLER(scr, handler) \
182 182 GET_P_BRAND_DATA(SP_REG, 0, scr); /* get p_brand_data */ \
183 183 cmp $0, scr; \
184 184 je 9f; \
185 185 cmp $0, handler(scr); /* check handler */ \
186 186 je 9f
187 187
188 188 /*
189 189 * If the system call number is >= 1024, then it is coming from the
190 190 * emulation support library. As such we should handle it natively instead
191 191 * of sending it back to the emulation library.
192 192 */
193 193 #define CHECK_FOR_NATIVE(reg) \
194 194 cmp $1024, reg; \
195 195 jl 1f; \
196 196 sub $1024, reg; \
197 197 jmp 9f; \
198 198 1:
199 199
200 200 /*
201 201 * Check to see if we want to interpose on this system call. If not, we
202 202 * jump back into the normal syscall path and pretend nothing happened.
203 203 * This macro is usable for brands which have the same number of syscalls
204 204 * as the base OS.
205 205 */
206 206 #define CHECK_FOR_INTERPOSITION(emul_table, call, scr, scr_low) \
207 207 cmp $NSYSCALL, call; /* is 0 <= syscall <= MAX? */ \
208 208 ja 9f; /* no, take normal ret path */ \
209 209 lea emul_table, scr; \
210 210 /*CSTYLED*/ \
211 211 mov (scr), scr; \
212 212 add call, scr; \
213 213 /*CSTYLED*/ \
214 214 movb (scr), scr_low; \
215 215 cmpb $0, scr_low; \
216 216 je 9f /* no, take normal ret path */
217 217
218 218 #define CALLBACK_PROLOGUE(emul_table, handler, call, scr, scr_low) \
219 219 CHECK_FOR_HANDLER(scr, handler); \
220 220 CHECK_FOR_NATIVE(call); \
221 221 CHECK_FOR_INTERPOSITION(emul_table, call, scr, scr_low)
222 222
223 223 /*
224 224 * Rather than returning to the instruction after the syscall, we need to
225 225 * transfer control into the brand library's handler table at
226 226 * table_addr + (16 * syscall_num), thus encoding the system call number in the
227 227 * instruction pointer. The CALC_TABLE_ADDR macro performs that calculation.
228 228 *
229 229 * This macro assumes the syscall number is in SYSCALL_REG and it clobbers
230 230 * that register. It leaves the calculated handler table return address in
231 231 * the scratch reg.
232 232 */
233 233 #define CALC_TABLE_ADDR(scr, handler) \
234 234 GET_P_BRAND_DATA(SP_REG, 0, scr); /* get p_brand_data ptr */ \
235 235 mov handler(scr), scr; /* get p_brand_data->XX_handler */ \
236 236 shl $4, SYSCALL_REG; /* syscall_num * 16 */ \
237 237 add SYSCALL_REG, scr /* leave return addr in scr reg. */
238 238
239 239 #endif /* _ASM */
240 240
241 241 #ifdef __cplusplus
242 242 }
243 243 #endif
244 244
245 245 #endif /* _COMMON_BRAND_ASM_H */
|
↓ open down ↓ |
71 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX