--- //depot/vendor/freebsd/src/sys/i386/i386/machdep.c 2004/07/19 02:50:39 +++ //depot/projects/smpng/sys/i386/i386/machdep.c 2004/07/28 18:25:59 @@ -1103,8 +1103,11 @@ pcb->pcb_gs = _udatasel; load_gs(_udatasel); + mtx_lock_spin(&sched_lock); if (td->td_proc->p_md.md_ldt) user_ldt_free(td); + else + mtx_unlock_spin(&sched_lock); bzero((char *)regs, sizeof(struct trapframe)); regs->tf_eip = entry; --- //depot/vendor/freebsd/src/sys/i386/i386/sys_machdep.c 2004/04/07 20:52:05 +++ //depot/projects/smpng/sys/i386/i386/sys_machdep.c 2004/04/16 18:42:25 @@ -292,7 +292,7 @@ #endif /* - * Must be called with either sched_lock free or held but not recursed. + * Must be called with sched_lock held but not recursed. * If it does not return NULL, it will return with it owned. */ struct proc_ldt * @@ -300,9 +300,8 @@ { struct proc_ldt *pldt, *new_ldt; - if (mtx_owned(&sched_lock)) - mtx_unlock_spin(&sched_lock); - mtx_assert(&sched_lock, MA_NOTOWNED); + mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); + mtx_unlock_spin(&sched_lock); MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt), M_SUBPROC, M_WAITOK); @@ -333,7 +332,7 @@ } /* - * Must be called either with sched_lock free or held but not recursed. + * Must be called with sched_lock held but not recursed. * If md_ldt is not NULL, it will return with sched_lock released. */ void @@ -345,8 +344,6 @@ if (pldt == NULL) return; - if (!mtx_owned(&sched_lock)) - mtx_lock_spin(&sched_lock); mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); if (td == PCPU_GET(curthread)) { lldt(_default_ldt); @@ -416,7 +413,7 @@ int error = 0, i; int largest_ld; struct mdproc *mdp = &td->td_proc->p_md; - struct proc_ldt *pldt = 0; + struct proc_ldt *pldt; struct i386_ldt_args ua, *uap = &ua; union descriptor *descs, *dp; int descs_size; @@ -630,16 +627,19 @@ if (len > MAX_LD) return (ENOMEM); - if (len < NLDT+1) - len = NLDT+1; + if (len < NLDT + 1) + len = NLDT + 1; + + /* allocate user ldt */ + mtx_lock_spin(&sched_lock); pldt = mdp->md_ldt; - /* allocate user ldt */ if (!pldt || len > pldt->ldt_len) { - struct proc_ldt *new_ldt = user_ldt_alloc(mdp, len); + struct proc_ldt *new_ldt; + + new_ldt = user_ldt_alloc(mdp, len); if (new_ldt == NULL) return (ENOMEM); pldt = mdp->md_ldt; - /* sched_lock was held by user_ldt_alloc */ if (pldt) { if (new_ldt->ldt_len > pldt->ldt_len) { old_ldt_base = pldt->ldt_base; @@ -676,6 +676,7 @@ set_user_ldt(mdp); mtx_unlock_spin(&sched_lock); #endif - } + } else + mtx_unlock_spin(&sched_lock); return (0); } --- //depot/vendor/freebsd/src/sys/i386/i386/vm_machdep.c 2004/07/20 01:40:31 +++ //depot/projects/smpng/sys/i386/i386/vm_machdep.c 2004/07/28 18:25:59 @@ -152,7 +152,10 @@ if ((flags & RFMEM) == 0) { /* unshare user LDT */ struct mdproc *mdp1 = &p1->p_md; - struct proc_ldt *pldt = mdp1->md_ldt; + struct proc_ldt *pldt; + + mtx_lock_spin(&sched_lock); + pldt = mdp1->md_ldt; if (pldt && pldt->ldt_refcnt > 1) { pldt = user_ldt_alloc(mdp1, pldt->ldt_len); if (pldt == NULL) @@ -160,7 +163,8 @@ mdp1->md_ldt = pldt; set_user_ldt(mdp1); user_ldt_free(td1); - } + } else + mtx_unlock_spin(&sched_lock); } return; } @@ -233,7 +237,7 @@ /* Copy the LDT, if necessary. */ mtx_lock_spin(&sched_lock); - if (mdp2->md_ldt != 0) { + if (mdp2->md_ldt != NULL) { if (flags & RFMEM) { mdp2->md_ldt->ldt_refcnt++; } else { @@ -285,11 +289,14 @@ /* Reset pc->pcb_gs and %gs before possibly invalidating it. */ mdp = &td->td_proc->p_md; + mtx_lock_spin(&sched_lock); if (mdp->md_ldt) { td->td_pcb->pcb_gs = _udatasel; load_gs(_udatasel); user_ldt_free(td); - } + } else + mtx_unlock_spin(&sched_lock); + if (pcb->pcb_flags & PCB_DBREGS) { /* disable all hardware breakpoints */ reset_dbregs();