MFp4 (114193 (i386 part), 114194, 114195, 114200):
- Dont "return" in linux_clone() after we forked the new process in a case of problems. - Move the copyout of p2->p_pid outside the emul_lock coverage in linux_clone(). - Cache the em->pdeath_signal in a local variable and move the copyout out of the emul_lock coverage. - Move the free() out of the emul_shared_lock coverage in a preparation to switch emul_lock to non-sleepable lock (mutex). Submitted by: rdivacky
This commit is contained in:
parent
e8b8b834b4
commit
1a26db0a3a
sys
@ -186,9 +186,11 @@ linux_proc_exit(void *arg __unused, struct proc *p)
|
||||
LIST_REMOVE(em, threads);
|
||||
|
||||
em->shared->refs--;
|
||||
if (em->shared->refs == 0)
|
||||
if (em->shared->refs == 0) {
|
||||
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
|
||||
free(em->shared, M_LINUX);
|
||||
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
|
||||
} else
|
||||
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
|
||||
|
||||
if (child_clear_tid != NULL) {
|
||||
struct linux_sys_futex_args cup;
|
||||
@ -273,9 +275,11 @@ linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
em->shared->refs--;
|
||||
if (em->shared->refs == 0)
|
||||
if (em->shared->refs == 0) {
|
||||
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
|
||||
free(em->shared, M_LINUX);
|
||||
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
|
||||
} else
|
||||
EMUL_SHARED_WUNLOCK(&emul_shared_lock);
|
||||
|
||||
free(em, M_LINUX);
|
||||
}
|
||||
|
@ -1642,6 +1642,7 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args)
|
||||
struct proc *p = td->td_proc;
|
||||
char comm[LINUX_MAX_COMM_LEN];
|
||||
struct linux_emuldata *em;
|
||||
int pdeath_signal;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(prctl))
|
||||
@ -1661,10 +1662,11 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args)
|
||||
case LINUX_PR_GET_PDEATHSIG:
|
||||
em = em_find(p, EMUL_DOLOCK);
|
||||
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
|
||||
error = copyout(&em->pdeath_signal,
|
||||
(void *)(register_t)args->arg2,
|
||||
sizeof(em->pdeath_signal));
|
||||
pdeath_signal = em->pdeath_signal;
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
error = copyout(&pdeath_signal,
|
||||
(void *)(register_t)args->arg2,
|
||||
sizeof(pdeath_signal));
|
||||
break;
|
||||
case LINUX_PR_SET_NAME:
|
||||
/*
|
||||
|
@ -435,6 +435,10 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
if ((args->flags & 0xffffff00) == THREADING_FLAGS)
|
||||
ff |= RFTHREAD;
|
||||
|
||||
if (args->flags & CLONE_PARENT_SETTID)
|
||||
if (args->parent_tidptr == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
error = fork1(td, ff, 0, &p2);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -453,17 +457,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
em = em_find(p2, EMUL_DOLOCK);
|
||||
KASSERT(em != NULL, ("clone: emuldata not found.\n"));
|
||||
/* and adjust it */
|
||||
if (args->flags & CLONE_PARENT_SETTID) {
|
||||
if (args->parent_tidptr == NULL) {
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
return (EINVAL);
|
||||
}
|
||||
error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid));
|
||||
if (error) {
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
if (args->flags & CLONE_THREAD) {
|
||||
/* XXX: linux mangles pgrp and pptr somehow
|
||||
@ -489,6 +482,12 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
|
||||
EMUL_UNLOCK(&emul_lock);
|
||||
|
||||
if (args->flags & CLONE_PARENT_SETTID) {
|
||||
error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid));
|
||||
if (error)
|
||||
printf(LMSG("copyout failed!"));
|
||||
}
|
||||
|
||||
PROC_LOCK(p2);
|
||||
p2->p_sigparent = exit_signal;
|
||||
PROC_UNLOCK(p2);
|
||||
@ -507,34 +506,37 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
struct segment_descriptor sd;
|
||||
|
||||
error = copyin((void *)td->td_frame->tf_esi, &info, sizeof(struct l_user_desc));
|
||||
if (error)
|
||||
return (error);
|
||||
if (error) {
|
||||
printf(LMSG("copyin failed!"));
|
||||
} else {
|
||||
|
||||
idx = info.entry_number;
|
||||
idx = info.entry_number;
|
||||
|
||||
/*
|
||||
* looks like we're getting the idx we returned
|
||||
* in the set_thread_area() syscall
|
||||
*/
|
||||
if (idx != 6 && idx != 3)
|
||||
return (EINVAL);
|
||||
/*
|
||||
* looks like we're getting the idx we returned
|
||||
* in the set_thread_area() syscall
|
||||
*/
|
||||
if (idx != 6 && idx != 3) {
|
||||
printf(LMSG("resetting idx!"));
|
||||
idx = 3;
|
||||
}
|
||||
|
||||
/* this doesnt happen in practice */
|
||||
if (idx == 6) {
|
||||
/* we might copy out the entry_number as 3 */
|
||||
info.entry_number = 3;
|
||||
error = copyout(&info, (void *) td->td_frame->tf_esi, sizeof(struct l_user_desc));
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
/* this doesnt happen in practice */
|
||||
if (idx == 6) {
|
||||
/* we might copy out the entry_number as 3 */
|
||||
info.entry_number = 3;
|
||||
error = copyout(&info, (void *) td->td_frame->tf_esi, sizeof(struct l_user_desc));
|
||||
if (error)
|
||||
printf(LMSG("copyout failed!"));
|
||||
}
|
||||
|
||||
a[0] = LDT_entry_a(&info);
|
||||
a[1] = LDT_entry_b(&info);
|
||||
a[0] = LDT_entry_a(&info);
|
||||
a[1] = LDT_entry_b(&info);
|
||||
|
||||
memcpy(&sd, &a, sizeof(a));
|
||||
memcpy(&sd, &a, sizeof(a));
|
||||
#ifdef DEBUG
|
||||
if (ldebug(clone))
|
||||
printf("Segment created in clone with CLONE_SETTLS: lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, type: %i, dpl: %i, p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase,
|
||||
if (ldebug(clone))
|
||||
printf("Segment created in clone with CLONE_SETTLS: lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, type: %i, dpl: %i, p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase,
|
||||
sd.sd_hibase,
|
||||
sd.sd_lolimit,
|
||||
sd.sd_hilimit,
|
||||
@ -546,9 +548,10 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
|
||||
sd.sd_gran);
|
||||
#endif
|
||||
|
||||
/* set %gs */
|
||||
td2->td_pcb->pcb_gsd = sd;
|
||||
td2->td_pcb->pcb_gs = GSEL(GUGS_SEL, SEL_UPL);
|
||||
/* set %gs */
|
||||
td2->td_pcb->pcb_gsd = sd;
|
||||
td2->td_pcb->pcb_gs = GSEL(GUGS_SEL, SEL_UPL);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
Loading…
x
Reference in New Issue
Block a user