167 if (ucp->uc_flags & UC_SIGMASK) {
168 /*
169 * We don't need to acquire p->p_lock here;
170 * we are manipulating thread-private data.
171 */
172 schedctl_finish_sigblock(t);
173 sigutok(&ucp->uc_sigmask, &t->t_hold);
174 if (sigcheck(ttoproc(t), t))
175 t->t_sig_check = 1;
176 }
177 }
178
179
180 int
181 getsetcontext(int flag, void *arg)
182 {
183 ucontext_t uc;
184 ucontext_t *ucp;
185 klwp_t *lwp = ttolwp(curthread);
186 stack_t dummy_stk;
187
188 /*
189 * In future releases, when the ucontext structure grows,
190 * getcontext should be modified to only return the fields
191 * specified in the uc_flags. That way, the structure can grow
192 * and still be binary compatible will all .o's which will only
193 * have old fields defined in uc_flags
194 */
195
196 switch (flag) {
197 default:
198 return (set_errno(EINVAL));
199
200 case GETCONTEXT:
201 schedctl_finish_sigblock(curthread);
202 savecontext(&uc, &curthread->t_hold);
203 if (uc.uc_flags & UC_SIGMASK)
204 SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask);
205 if (copyout(&uc, arg, sizeof (uc)))
206 return (set_errno(EFAULT));
211 if (ucp == NULL)
212 exit(CLD_EXITED, 0);
213 /*
214 * Don't copyin filler or floating state unless we need it.
215 * The ucontext_t struct and fields are specified in the ABI.
216 */
217 if (copyin(ucp, &uc, sizeof (ucontext_t) -
218 sizeof (uc.uc_filler) -
219 sizeof (uc.uc_mcontext.fpregs))) {
220 return (set_errno(EFAULT));
221 }
222 if (uc.uc_flags & UC_SIGMASK)
223 SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
224
225 if ((uc.uc_flags & UC_FPU) &&
226 copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs,
227 sizeof (uc.uc_mcontext.fpregs))) {
228 return (set_errno(EFAULT));
229 }
230
231 restorecontext(&uc);
232
233 if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))
234 (void) copyout(&uc.uc_stack, (stack_t *)lwp->lwp_ustack,
235 sizeof (uc.uc_stack));
236 return (0);
237
238 case GETUSTACK:
239 if (copyout(&lwp->lwp_ustack, arg, sizeof (caddr_t)))
240 return (set_errno(EFAULT));
241 return (0);
242
243 case SETUSTACK:
244 if (copyin(arg, &dummy_stk, sizeof (dummy_stk)))
245 return (set_errno(EFAULT));
246 lwp->lwp_ustack = (uintptr_t)arg;
247 return (0);
248 }
249 }
250
251 #ifdef _SYSCALL32_IMPL
252
253 /*
254 * Save user context for 32-bit processes.
255 */
|
167 if (ucp->uc_flags & UC_SIGMASK) {
168 /*
169 * We don't need to acquire p->p_lock here;
170 * we are manipulating thread-private data.
171 */
172 schedctl_finish_sigblock(t);
173 sigutok(&ucp->uc_sigmask, &t->t_hold);
174 if (sigcheck(ttoproc(t), t))
175 t->t_sig_check = 1;
176 }
177 }
178
179
180 int
181 getsetcontext(int flag, void *arg)
182 {
183 ucontext_t uc;
184 ucontext_t *ucp;
185 klwp_t *lwp = ttolwp(curthread);
186 stack_t dummy_stk;
187 caddr_t xregs = NULL;
188 int xregs_size = 0;
189
190 /*
191 * In future releases, when the ucontext structure grows,
192 * getcontext should be modified to only return the fields
193 * specified in the uc_flags. That way, the structure can grow
194 * and still be binary compatible will all .o's which will only
195 * have old fields defined in uc_flags
196 */
197
198 switch (flag) {
199 default:
200 return (set_errno(EINVAL));
201
202 case GETCONTEXT:
203 schedctl_finish_sigblock(curthread);
204 savecontext(&uc, &curthread->t_hold);
205 if (uc.uc_flags & UC_SIGMASK)
206 SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask);
207 if (copyout(&uc, arg, sizeof (uc)))
208 return (set_errno(EFAULT));
213 if (ucp == NULL)
214 exit(CLD_EXITED, 0);
215 /*
216 * Don't copyin filler or floating state unless we need it.
217 * The ucontext_t struct and fields are specified in the ABI.
218 */
219 if (copyin(ucp, &uc, sizeof (ucontext_t) -
220 sizeof (uc.uc_filler) -
221 sizeof (uc.uc_mcontext.fpregs))) {
222 return (set_errno(EFAULT));
223 }
224 if (uc.uc_flags & UC_SIGMASK)
225 SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
226
227 if ((uc.uc_flags & UC_FPU) &&
228 copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs,
229 sizeof (uc.uc_mcontext.fpregs))) {
230 return (set_errno(EFAULT));
231 }
232
233 /*
234 * Get extra register state.
235 */
236 xregs_clrptr(lwp, &uc);
237
238 restorecontext(&uc);
239
240 if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))
241 (void) copyout(&uc.uc_stack, (stack_t *)lwp->lwp_ustack,
242 sizeof (uc.uc_stack));
243
244 /*
245 * Free extra register state.
246 */
247 if (xregs_size)
248 kmem_free(xregs, xregs_size);
249
250 return (0);
251
252 case GETUSTACK:
253 if (copyout(&lwp->lwp_ustack, arg, sizeof (caddr_t)))
254 return (set_errno(EFAULT));
255 return (0);
256
257 case SETUSTACK:
258 if (copyin(arg, &dummy_stk, sizeof (dummy_stk)))
259 return (set_errno(EFAULT));
260 lwp->lwp_ustack = (uintptr_t)arg;
261 return (0);
262 }
263 }
264
265 #ifdef _SYSCALL32_IMPL
266
267 /*
268 * Save user context for 32-bit processes.
269 */
|