Explicitly switch to the new TSS by updating the current CPU's TSS selector

and reloading it in i386_extend_pcb() rather than trying to force a context
switch to reload the TSS via the TDF_NEEDRESCHED flag.  Optimizations to
avoid calling cpu_switch() when the new thread was identical to the old
thread defeated the attempt to force a TSS reload.  Explicitly loading the
new TSS is what we really want to do anyway.

PR:		i386/84842
Reported by:	Alexander Best arundel at h3c dot de
MFC after:	1 week
Reviewed by:	bde (mostly)
This commit is contained in:
John Baldwin 2005-09-15 17:30:08 +00:00
parent b9fb13f573
commit f726a87319
2 changed files with 7 additions and 4 deletions

View File

@ -263,13 +263,15 @@ i386_extend_pcb(struct thread *td)
ssd.ssd_limit -= ((unsigned)&ext->ext_tss - (unsigned)ext);
ssdtosd(&ssd, &ext->ext_tssd);
KASSERT(td->td_proc == curthread->td_proc, ("giving TSS to !curproc"));
KASSERT(td == curthread, ("giving TSS to !curthread"));
KASSERT(td->td_pcb->pcb_ext == 0, ("already have a TSS!"));
/* Switch to the new TSS. */
mtx_lock_spin(&sched_lock);
td->td_pcb->pcb_ext = ext;
/* switch to the new TSS after syscall completes */
td->td_flags |= TDF_NEEDRESCHED;
private_tss |= PCPU_GET(cpumask);
*PCPU_GET(tss_gdt) = ext->ext_tssd;
ltr(GSEL(GPROC0_SEL, SEL_KPL));
mtx_unlock_spin(&sched_lock);
return 0;

View File

@ -44,6 +44,7 @@ struct pcb_ext {
};
#ifdef _KERNEL
extern int private_tss;
int i386_extend_pcb(struct thread *);