linux_emul.c (165688) | linux_emul.c (165867) |
---|---|
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 165688 2006-12-31 12:42:55Z netchild $"); | 30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_emul.c 165867 2007-01-07 19:00:38Z 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/lock.h> 38#include <sys/malloc.h> --- 19 unchanged lines hidden (view full) --- 58struct sx emul_lock; 59 60/* this returns locked reference to the emuldata entry (if found) */ 61struct linux_emuldata * 62em_find(struct proc *p, int locked) 63{ 64 struct linux_emuldata *em; 65 | 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/lock.h> 38#include <sys/malloc.h> --- 19 unchanged lines hidden (view full) --- 58struct sx emul_lock; 59 60/* this returns locked reference to the emuldata entry (if found) */ 61struct linux_emuldata * 62em_find(struct proc *p, int locked) 63{ 64 struct linux_emuldata *em; 65 |
66 if (locked == EMUL_UNLOCKED) | 66 if (locked == EMUL_DOLOCK) |
67 EMUL_LOCK(&emul_lock); 68 69 em = p->p_emuldata; 70 | 67 EMUL_LOCK(&emul_lock); 68 69 em = p->p_emuldata; 70 |
71 if (em == NULL && locked == EMUL_UNLOCKED) | 71 if (em == NULL && locked == EMUL_DOLOCK) |
72 EMUL_UNLOCK(&emul_lock); 73 74 return (em); 75} 76 77int 78linux_proc_init(struct thread *td, pid_t child, int flags) 79{ --- 19 unchanged lines hidden (view full) --- 99 } 100 p = pfind(child); 101 KASSERT(p != NULL, ("process not found in proc_init\n")); 102 p->p_emuldata = em; 103 PROC_UNLOCK(p); 104 EMUL_LOCK(&emul_lock); 105 } else { 106 /* lookup the old one */ | 72 EMUL_UNLOCK(&emul_lock); 73 74 return (em); 75} 76 77int 78linux_proc_init(struct thread *td, pid_t child, int flags) 79{ --- 19 unchanged lines hidden (view full) --- 99 } 100 p = pfind(child); 101 KASSERT(p != NULL, ("process not found in proc_init\n")); 102 p->p_emuldata = em; 103 PROC_UNLOCK(p); 104 EMUL_LOCK(&emul_lock); 105 } else { 106 /* lookup the old one */ |
107 em = em_find(td->td_proc, EMUL_UNLOCKED); | 107 em = em_find(td->td_proc, EMUL_DOLOCK); |
108 KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 109 } 110 111 em->child_clear_tid = NULL; 112 em->child_set_tid = NULL; 113 114 /* 115 * allocate the shared struct only in clone()/fork cases in the case 116 * of clone() td = calling proc and child = pid of the newly created 117 * proc 118 */ 119 if (child != 0) { 120 if (flags & CLONE_THREAD) { 121 /* lookup the parent */ | 108 KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n")); 109 } 110 111 em->child_clear_tid = NULL; 112 em->child_set_tid = NULL; 113 114 /* 115 * allocate the shared struct only in clone()/fork cases in the case 116 * of clone() td = calling proc and child = pid of the newly created 117 * proc 118 */ 119 if (child != 0) { 120 if (flags & CLONE_THREAD) { 121 /* lookup the parent */ |
122 p_em = em_find(td->td_proc, EMUL_LOCKED); | 122 p_em = em_find(td->td_proc, EMUL_DONTLOCK); |
123 KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n")); 124 em->shared = p_em->shared; 125 em->shared->refs++; 126 } else { 127 /* 128 * handled earlier to avoid malloc(M_WAITOK) with 129 * rwlock held 130 */ --- 23 unchanged lines hidden (view full) --- 154 struct thread *td = FIRST_THREAD_IN_PROC(p); 155 int *child_clear_tid; 156 struct proc *q, *nq; 157 158 if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 159 return; 160 161 /* find the emuldata */ | 123 KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n")); 124 em->shared = p_em->shared; 125 em->shared->refs++; 126 } else { 127 /* 128 * handled earlier to avoid malloc(M_WAITOK) with 129 * rwlock held 130 */ --- 23 unchanged lines hidden (view full) --- 154 struct thread *td = FIRST_THREAD_IN_PROC(p); 155 int *child_clear_tid; 156 struct proc *q, *nq; 157 158 if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 159 return; 160 161 /* find the emuldata */ |
162 em = em_find(p, EMUL_UNLOCKED); | 162 em = em_find(p, EMUL_DOLOCK); |
163 164 KASSERT(em != NULL, ("proc_exit: emuldata not found.\n")); 165 166 child_clear_tid = em->child_clear_tid; 167 168 EMUL_UNLOCK(&emul_lock); 169 170 EMUL_SHARED_WLOCK(&emul_shared_lock); --- 41 unchanged lines hidden (view full) --- 212 sx_xlock(&proctree_lock); 213 q = LIST_FIRST(&p->p_children); 214 for (; q != NULL; q = nq) { 215 nq = LIST_NEXT(q, p_sibling); 216 if (q->p_flag & P_WEXIT) 217 continue; 218 if (__predict_false(q->p_sysent != &elf_linux_sysvec)) 219 continue; | 163 164 KASSERT(em != NULL, ("proc_exit: emuldata not found.\n")); 165 166 child_clear_tid = em->child_clear_tid; 167 168 EMUL_UNLOCK(&emul_lock); 169 170 EMUL_SHARED_WLOCK(&emul_shared_lock); --- 41 unchanged lines hidden (view full) --- 212 sx_xlock(&proctree_lock); 213 q = LIST_FIRST(&p->p_children); 214 for (; q != NULL; q = nq) { 215 nq = LIST_NEXT(q, p_sibling); 216 if (q->p_flag & P_WEXIT) 217 continue; 218 if (__predict_false(q->p_sysent != &elf_linux_sysvec)) 219 continue; |
220 em = em_find(q, EMUL_UNLOCKED); | 220 em = em_find(q, EMUL_DOLOCK); |
221 KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); 222 if (em->pdeath_signal != 0) { 223 PROC_LOCK(q); 224 psignal(q, em->pdeath_signal); 225 PROC_UNLOCK(q); 226 } 227 EMUL_UNLOCK(&emul_lock); 228 } --- 10 unchanged lines hidden (view full) --- 239{ 240 if (__predict_false(imgp->sysent == &elf_linux_sysvec 241 && p->p_sysent != &elf_linux_sysvec)) 242 linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); 243 if (__predict_false(imgp->sysent != &elf_linux_sysvec 244 && p->p_sysent == &elf_linux_sysvec)) { 245 struct linux_emuldata *em; 246 | 221 KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); 222 if (em->pdeath_signal != 0) { 223 PROC_LOCK(q); 224 psignal(q, em->pdeath_signal); 225 PROC_UNLOCK(q); 226 } 227 EMUL_UNLOCK(&emul_lock); 228 } --- 10 unchanged lines hidden (view full) --- 239{ 240 if (__predict_false(imgp->sysent == &elf_linux_sysvec 241 && p->p_sysent != &elf_linux_sysvec)) 242 linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0); 243 if (__predict_false(imgp->sysent != &elf_linux_sysvec 244 && p->p_sysent == &elf_linux_sysvec)) { 245 struct linux_emuldata *em; 246 |
247 em = em_find(p, EMUL_UNLOCKED); | 247 em = em_find(p, EMUL_DOLOCK); |
248 249 KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); 250 251 EMUL_UNLOCK(&emul_lock); 252 253 EMUL_SHARED_WLOCK(&emul_shared_lock); 254 LIST_REMOVE(em, threads); 255 --- 19 unchanged lines hidden (view full) --- 275 int error = 0; 276 int *child_set_tid; 277 278 if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 279 return; 280 281retry: 282 /* find the emuldata */ | 248 249 KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); 250 251 EMUL_UNLOCK(&emul_lock); 252 253 EMUL_SHARED_WLOCK(&emul_shared_lock); 254 LIST_REMOVE(em, threads); 255 --- 19 unchanged lines hidden (view full) --- 275 int error = 0; 276 int *child_set_tid; 277 278 if (__predict_true(p->p_sysent != &elf_linux_sysvec)) 279 return; 280 281retry: 282 /* find the emuldata */ |
283 em = em_find(p, EMUL_UNLOCKED); | 283 em = em_find(p, EMUL_DOLOCK); |
284 285 if (em == NULL) { 286 /* 287 * We might have been called before proc_init for this 288 * process so tsleep and be woken up by it. We use 289 * p->p_emuldata for this 290 */ 291 --- 18 unchanged lines hidden (view full) --- 310 struct linux_emuldata *em; 311 312#ifdef DEBUG 313 if (ldebug(set_tid_address)) 314 printf(ARGS(set_tid_address, "%p"), args->tidptr); 315#endif 316 317 /* find the emuldata */ | 284 285 if (em == NULL) { 286 /* 287 * We might have been called before proc_init for this 288 * process so tsleep and be woken up by it. We use 289 * p->p_emuldata for this 290 */ 291 --- 18 unchanged lines hidden (view full) --- 310 struct linux_emuldata *em; 311 312#ifdef DEBUG 313 if (ldebug(set_tid_address)) 314 printf(ARGS(set_tid_address, "%p"), args->tidptr); 315#endif 316 317 /* find the emuldata */ |
318 em = em_find(td->td_proc, EMUL_UNLOCKED); | 318 em = em_find(td->td_proc, EMUL_DOLOCK); |
319 320 KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); 321 322 em->child_clear_tid = args->tidptr; 323 td->td_retval[0] = td->td_proc->p_pid; 324 325 EMUL_UNLOCK(&emul_lock); 326 return 0; 327} | 319 320 KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); 321 322 em->child_clear_tid = args->tidptr; 323 td->td_retval[0] = td->td_proc->p_pid; 324 325 EMUL_UNLOCK(&emul_lock); 326 return 0; 327} |