Deleted Added
full compact
linux_emul.c (191269) linux_emul.c (215664)
1/*-
2 * Copyright (c) 2006 Roman Divacky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006 Roman Divacky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_emul.c 191269 2009-04-19 13:48:42Z dchagin $");
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_emul.c 215664 2010-11-22 09:06:59Z netchild $");
31
32#include "opt_compat.h"
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/imgact.h>
37#include <sys/kernel.h>
38#include <sys/lock.h>

--- 111 unchanged lines hidden (view full) ---

150
151 return (0);
152}
153
154void
155linux_proc_exit(void *arg __unused, struct proc *p)
156{
157 struct linux_emuldata *em;
31
32#include "opt_compat.h"
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/imgact.h>
37#include <sys/kernel.h>
38#include <sys/lock.h>

--- 111 unchanged lines hidden (view full) ---

150
151 return (0);
152}
153
154void
155linux_proc_exit(void *arg __unused, struct proc *p)
156{
157 struct linux_emuldata *em;
158 int error;
158 int error, shared_flags, shared_xstat;
159 struct thread *td = FIRST_THREAD_IN_PROC(p);
160 int *child_clear_tid;
161 struct proc *q, *nq;
162
163 if (__predict_true(p->p_sysent != &elf_linux_sysvec))
164 return;
165
166 release_futexes(p);

--- 15 unchanged lines hidden (view full) ---

182 PROC_UNLOCK(p);
183 sx_xunlock(&proctree_lock);
184 } else {
185 child_clear_tid = em->child_clear_tid;
186 EMUL_UNLOCK(&emul_lock);
187 }
188
189 EMUL_SHARED_WLOCK(&emul_shared_lock);
159 struct thread *td = FIRST_THREAD_IN_PROC(p);
160 int *child_clear_tid;
161 struct proc *q, *nq;
162
163 if (__predict_true(p->p_sysent != &elf_linux_sysvec))
164 return;
165
166 release_futexes(p);

--- 15 unchanged lines hidden (view full) ---

182 PROC_UNLOCK(p);
183 sx_xunlock(&proctree_lock);
184 } else {
185 child_clear_tid = em->child_clear_tid;
186 EMUL_UNLOCK(&emul_lock);
187 }
188
189 EMUL_SHARED_WLOCK(&emul_shared_lock);
190 shared_flags = em->shared->flags;
191 shared_xstat = em->shared->xstat;
190 LIST_REMOVE(em, threads);
191
192 em->shared->refs--;
193 if (em->shared->refs == 0) {
194 EMUL_SHARED_WUNLOCK(&emul_shared_lock);
195 free(em->shared, M_LINUX);
196 } else
197 EMUL_SHARED_WUNLOCK(&emul_shared_lock);
198
192 LIST_REMOVE(em, threads);
193
194 em->shared->refs--;
195 if (em->shared->refs == 0) {
196 EMUL_SHARED_WUNLOCK(&emul_shared_lock);
197 free(em->shared, M_LINUX);
198 } else
199 EMUL_SHARED_WUNLOCK(&emul_shared_lock);
200
201 if ((shared_flags & EMUL_SHARED_HASXSTAT) != 0) {
202 PROC_LOCK(p);
203 p->p_xstat = shared_xstat;
204 PROC_UNLOCK(p);
205 }
206
199 if (child_clear_tid != NULL) {
200 struct linux_sys_futex_args cup;
201 int null = 0;
202
203 error = copyout(&null, child_clear_tid, sizeof(null));
204 if (error) {
205 free(em, M_LINUX);
206 return;

--- 45 unchanged lines hidden (view full) ---

252 * process.
253 */
254void
255linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
256{
257 if (__predict_false(imgp->sysent == &elf_linux_sysvec
258 && p->p_sysent != &elf_linux_sysvec))
259 linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
207 if (child_clear_tid != NULL) {
208 struct linux_sys_futex_args cup;
209 int null = 0;
210
211 error = copyout(&null, child_clear_tid, sizeof(null));
212 if (error) {
213 free(em, M_LINUX);
214 return;

--- 45 unchanged lines hidden (view full) ---

260 * process.
261 */
262void
263linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
264{
265 if (__predict_false(imgp->sysent == &elf_linux_sysvec
266 && p->p_sysent != &elf_linux_sysvec))
267 linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
268 if (__predict_false(p->p_sysent == &elf_linux_sysvec))
269 /* Kill threads regardless of imgp->sysent value */
270 linux_kill_threads(FIRST_THREAD_IN_PROC(p), SIGKILL);
260 if (__predict_false(imgp->sysent != &elf_linux_sysvec
261 && p->p_sysent == &elf_linux_sysvec)) {
262 struct linux_emuldata *em;
263
264 /*
265 * XXX:There's a race because here we assign p->p_emuldata NULL
266 * but the process is still counted as linux one for a short
267 * time so some other process might reference it and try to

--- 61 unchanged lines hidden (view full) ---

329 KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
330
331 em->child_clear_tid = args->tidptr;
332 td->td_retval[0] = td->td_proc->p_pid;
333
334 EMUL_UNLOCK(&emul_lock);
335 return 0;
336}
271 if (__predict_false(imgp->sysent != &elf_linux_sysvec
272 && p->p_sysent == &elf_linux_sysvec)) {
273 struct linux_emuldata *em;
274
275 /*
276 * XXX:There's a race because here we assign p->p_emuldata NULL
277 * but the process is still counted as linux one for a short
278 * time so some other process might reference it and try to

--- 61 unchanged lines hidden (view full) ---

340 KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
341
342 em->child_clear_tid = args->tidptr;
343 td->td_retval[0] = td->td_proc->p_pid;
344
345 EMUL_UNLOCK(&emul_lock);
346 return 0;
347}
348
349void
350linux_kill_threads(struct thread *td, int sig)
351{
352 struct linux_emuldata *em, *td_em, *tmp_em;
353 struct proc *sp;
354
355 td_em = em_find(td->td_proc, EMUL_DONTLOCK);
356
357 KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n"));
358
359 EMUL_SHARED_RLOCK(&emul_shared_lock);
360 LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) {
361 if (em->pid == td_em->pid)
362 continue;
363
364 sp = pfind(em->pid);
365 if ((sp->p_flag & P_WEXIT) == 0)
366 psignal(sp, sig);
367 PROC_UNLOCK(sp);
368#ifdef DEBUG
369 printf(LMSG("linux_kill_threads: kill PID %d\n"), em->pid);
370#endif
371 }
372 EMUL_SHARED_RUNLOCK(&emul_shared_lock);
373}