Index: amd64/include/pcb.h =================================================================== --- amd64/include/pcb.h (revision 195227) +++ amd64/include/pcb.h (working copy) @@ -56,6 +56,7 @@ register_t pcb_fsbase; register_t pcb_gsbase; u_long pcb_flags; +#define PCB_SEGLOADED 0x01 /* Segment registers are loaded and valid. */ #define PCB_DBREGS 0x02 /* process using debug registers */ #define PCB_FPUINITDONE 0x08 /* fpu state is initialized */ #define PCB_GS32BIT 0x20 /* linux gs switch */ Index: amd64/amd64/vm_machdep.c =================================================================== --- amd64/amd64/vm_machdep.c (revision 195227) +++ amd64/amd64/vm_machdep.c (working copy) @@ -171,6 +171,7 @@ pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *); pcb2->pcb_rbx = (register_t)td2; /* fork_trampoline argument */ pcb2->pcb_rip = (register_t)fork_trampoline; + pcb2->pcb_flags &= ~PCB_SEGLOADED; /*- * pcb2->pcb_dr*: cloned above. * pcb2->pcb_savefpu: cloned above. @@ -335,7 +336,7 @@ * values here. */ bcopy(td0->td_pcb, pcb2, sizeof(*pcb2)); - pcb2->pcb_flags &= ~PCB_FPUINITDONE; + pcb2->pcb_flags &= ~(PCB_FPUINITDONE | PCB_SEGLOADED); /* * Create a new fresh stack for the new thread. @@ -428,6 +429,7 @@ td->td_frame->tf_fs = _ufssel; td->td_frame->tf_gs = _ugssel; td->td_frame->tf_flags = TF_HASSEGS; + td->td_pcb->pcb_flags &= ~PCB_SEGLOADED; /* * Pass the address of the mailbox for this kse to the uts @@ -450,6 +452,8 @@ } #endif td->td_pcb->pcb_fsbase = (register_t)tls_base; + td->td_pcb->pcb_flags &= ~PCB_SEGLOADED; + return (0); } Index: amd64/amd64/exception.S =================================================================== --- amd64/amd64/exception.S (revision 195227) +++ amd64/amd64/exception.S (working copy) @@ -635,6 +635,9 @@ movq PCPU(CURTHREAD),%r8 movq TD_PCB(%r8),%r8 + testl $PCB_SEGLOADED,PCB_FLAGS(%r8) + je ld_regs + /* * Do not reload segment registers for kernel. * Since we do not reload segments registers with sane @@ -650,6 +653,7 @@ do_segs: /* Restore %fs and fsbase */ + andl $PCB_SEGLOADED,PCB_FLAGS(%r8) movw TF_FS(%rsp),%ax .globl ld_fs ld_fs: movw %ax,%fs Index: amd64/amd64/genassym.c =================================================================== --- amd64/amd64/genassym.c (revision 195227) +++ amd64/amd64/genassym.c (working copy) @@ -64,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -142,6 +141,7 @@ ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6)); ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); ASSYM(PCB_TSSP, offsetof(struct pcb, pcb_tssp)); +ASSYM(PCB_SEGLOADED, PCB_SEGLOADED); ASSYM(PCB_DBREGS, PCB_DBREGS); ASSYM(PCB_32BIT, PCB_32BIT); ASSYM(PCB_GS32BIT, PCB_GS32BIT); Index: amd64/amd64/cpu_switch.S =================================================================== --- amd64/amd64/cpu_switch.S (revision 195227) +++ amd64/amd64/cpu_switch.S (working copy) @@ -97,6 +97,7 @@ ENTRY(cpu_switch) /* Switch to new thread. First, save context. */ movq TD_PCB(%rdi),%r8 + andl $~PCB_SEGLOADED,PCB_FLAGS(%r8) movq (%rsp),%rax /* Hardware registers */ movq %r15,PCB_R15(%r8) Index: amd64/amd64/sys_machdep.c =================================================================== --- amd64/amd64/sys_machdep.c (revision 195227) +++ amd64/amd64/sys_machdep.c (working copy) @@ -164,6 +164,8 @@ uint64_t a64base; struct i386_ioperm_args iargs; + pcb->pcb_flags &= ~PCB_SEGLOADED; + if (uap->op == I386_GET_LDT || uap->op == I386_SET_LDT) return (sysarch_ldt(td, uap, UIO_USERSPACE)); /* Index: amd64/amd64/machdep.c =================================================================== --- amd64/amd64/machdep.c (revision 195227) +++ amd64/amd64/machdep.c (working copy) @@ -372,6 +372,7 @@ sigexit(td, SIGILL); } + td->td_pcb->pcb_flags &= ~PCB_SEGLOADED; regs->tf_rsp = (long)sfp; regs->tf_rip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); regs->tf_rflags &= ~(PSL_T | PSL_D); @@ -850,7 +851,7 @@ pcb->pcb_fsbase = 0; pcb->pcb_gsbase = 0; - pcb->pcb_flags &= ~(PCB_32BIT | PCB_GS32BIT); + pcb->pcb_flags &= ~(PCB_SEGLOADED | PCB_32BIT | PCB_GS32BIT); pcb->pcb_initial_fpucw = __INITIAL_FPUCW__; bzero((char *)regs, sizeof(struct trapframe)); @@ -2006,6 +2007,7 @@ td->td_pcb->pcb_gsbase = mcp->mc_gsbase; } td->td_pcb->pcb_flags |= PCB_FULLCTX; + td->td_pcb->pcb_flags &= ~PCB_SEGLOADED; return (0); } Index: amd64/amd64/trap.c =================================================================== --- amd64/amd64/trap.c (revision 195227) +++ amd64/amd64/trap.c (working copy) @@ -512,6 +512,7 @@ if (td->td_intr_nesting_level != 0) break; + td->td_pcb->pcb_flags &= ~PCB_SEGLOADED; /* * Invalid segment selectors and out of bounds * %rip's and %rsp's can be set up in user mode. Index: amd64/ia32/ia32_reg.c =================================================================== --- amd64/ia32/ia32_reg.c (revision 195227) +++ amd64/ia32/ia32_reg.c (working copy) @@ -138,6 +138,7 @@ tp->tf_rflags = regs->r_eflags; tp->tf_rsp = regs->r_esp; tp->tf_ss = regs->r_ss; + pcb->pcb_flags &= ~PCB_SEGLOADED; return (0); }