Peter,

Attached is the fix wrt your previous email.  Again, can be found in
www.watson.org/~arr/fbsd-patches/

Cheers,
Andrew
--- include/pcb.h.orig  Wed Sep 19 02:07:48 2001
+++ include/pcb.h       Wed Sep 19 02:08:37 2001
@@ -61,7 +61,6 @@
        int     pcb_dr6;
        int     pcb_dr7;
 
-       struct  pcb_ldt *pcb_ldt;       /* per process (user) LDT */
        union   savefpu pcb_save;
        u_char  pcb_flags;
 #define        FP_SOFTFP       0x01    /* process using software fltng pnt emulator 
*/
--- include/pcb_ext.h.orig      Wed Sep 19 02:07:54 2001
+++ include/pcb_ext.h   Wed Sep 19 02:10:37 2001
@@ -43,20 +43,9 @@
        struct  vm86_kernel ext_vm86;   /* vm86 area */
 };
 
-struct pcb_ldt {
-       caddr_t ldt_base;
-       int     ldt_len;
-       int     ldt_refcnt;
-       u_long  ldt_active;
-       struct  segment_descriptor ldt_sd;
-};
-
 #ifdef _KERNEL
 
 int i386_extend_pcb __P((struct thread *));
-void set_user_ldt __P((struct pcb *));
-struct pcb_ldt *user_ldt_alloc __P((struct pcb *, int));
-void user_ldt_free __P((struct pcb *));
 
 #endif
 
--- include/proc.h.orig Wed Sep 19 02:07:59 2001
+++ include/proc.h      Wed Sep 19 03:28:55 2001
@@ -38,6 +38,15 @@
 #define        _MACHINE_PROC_H_
 
 #include <machine/globals.h>
+#include <machine/segments.h>
+
+struct proc_ldt {
+        caddr_t ldt_base;
+        int     ldt_len;
+        int     ldt_refcnt;
+        u_long  ldt_active;
+        struct  segment_descriptor ldt_sd;
+};
 
 /*
  * Machine-dependent part of the proc structure for i386.
@@ -46,6 +55,15 @@
 };
 
 struct mdproc {
+       struct proc_ldt *md_ldt;        /* per-process ldt */
 };
+
+#ifdef _KERNEL
+
+void   set_user_ldt __P((struct mdproc *));
+struct         proc_ldt *user_ldt_alloc __P((struct mdproc *, int));
+void   user_ldt_free __P((struct thread *));
+
+#endif /* _KERNEL */
 
 #endif /* !_MACHINE_PROC_H_ */
--- i386/genassym.c.orig        Wed Sep 19 02:16:34 2001
+++ i386/genassym.c     Wed Sep 19 13:03:45 2001
@@ -63,6 +63,7 @@
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 #include <sys/user.h>
+#include <sys/proc.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <nfs/nfsproto.h>
@@ -76,6 +77,7 @@
 #include <machine/sigframe.h>
 #include <machine/globaldata.h>
 #include <machine/vm86.h>
+#include <machine/proc.h>
 
 ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
 ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
@@ -92,6 +94,9 @@
 ASSYM(TD_PROC, offsetof(struct thread, td_proc));
 ASSYM(TD_INTR_NESTING_LEVEL, offsetof(struct thread, td_intr_nesting_level));
 
+ASSYM(P_MD, offsetof(struct proc, p_md));
+ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt));
+
 ASSYM(KE_FLAGS, offsetof(struct kse, ke_flags));
 
 ASSYM(KEF_ASTPENDING, KEF_ASTPENDING);
@@ -126,7 +131,6 @@
 ASSYM(PCB_EIP, offsetof(struct pcb, pcb_eip));
 ASSYM(TSS_ESP0, offsetof(struct i386tss, tss_esp0));
 
-ASSYM(PCB_USERLDT, offsetof(struct pcb, pcb_ldt));
 ASSYM(PCB_GS, offsetof(struct pcb, pcb_gs));
 ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0));
 ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1));
--- i386/machdep.c.orig Wed Sep 19 02:16:39 2001
+++ i386/machdep.c      Wed Sep 19 04:57:31 2001
@@ -103,6 +103,7 @@
 #include <machine/md_var.h>
 #include <machine/pc/bios.h>
 #include <machine/pcb_ext.h>           /* pcb.h included via sys/user.h */
+#include <machine/proc.h>
 #include <machine/globals.h>
 #ifdef PERFMON
 #include <machine/perfmon.h>
@@ -880,8 +881,8 @@
        struct trapframe *regs = td->td_frame;
        struct pcb *pcb = td->td_pcb;
 
-       if (pcb->pcb_ldt)
-               user_ldt_free(pcb);
+       if (td->td_proc->p_md.md_ldt)
+               user_ldt_free(td);
   
        bzero((char *)regs, sizeof(struct trapframe));
        regs->tf_eip = entry;
--- i386/swtch.s.orig   Wed Sep 19 02:16:14 2001
+++ i386/swtch.s        Thu Sep 20 03:51:55 2001
@@ -246,7 +246,8 @@
        /* XXX FIXME: we should be restoring the local APIC TPR */
 #endif /* SMP */
 
-       cmpl    $0, PCB_USERLDT(%edx)   /* if there is one */
+       movl    TD_PROC(%ecx), %eax     /* load struct proc from CURTHREAD */
+       cmpl    $0, P_MD+MD_LDT(%eax)   /* see if md_ldt == 0 */
        jnz     1f                      /* then use it */
        movl    _default_ldt,%eax       /* We will use the default */
        cmpl    PCPU(CURRENTLDT),%eax   /* check to see if already loaded */
@@ -255,9 +256,11 @@
        movl    %eax,PCPU(CURRENTLDT)   /* store what we have */
        jmp     2f
 
-1:     pushl   %edx                    /* call a non-trusting routine */
-       call    set_user_ldt            /* to check and load the ldt */
-       popl    %edx
+1:     pushl   %edx                    /* save edx */
+       pushl   P_MD+MD_LDT(%eax)       /* passing p_md -> set_user_ldt */
+       call    set_user_ldt            /* check and load the ldt */
+       popl    %eax                    /* get p_md off stack */
+       popl    %edx                    /* restore edx */
 2:
 
        /* This must be done after loading the user LDT. */
--- i386/sys_machdep.c.orig     Wed Sep 19 02:16:22 2001
+++ i386/sys_machdep.c  Wed Sep 19 04:34:30 2001
@@ -54,6 +54,7 @@
 
 #include <machine/cpu.h>
 #include <machine/pcb_ext.h>   /* pcb.h included by sys/user.h */
+#include <machine/proc.h>
 #include <machine/sysarch.h>
 
 #include <vm/vm_kern.h>                /* for kernel_map */
@@ -70,7 +71,7 @@
 static int i386_get_ioperm     __P((struct thread *, char *));
 static int i386_set_ioperm     __P((struct thread *, char *));
 #ifdef SMP
-static void set_user_ldt_rv    __P((struct pcb *));
+static void set_user_ldt_rv    __P((struct thread *));
 #endif
 
 #ifndef _SYS_SYSPROTO_H_
@@ -257,15 +258,15 @@
  * curproc but before sched_lock's owner is updated in mi_switch().
  */   
 void
-set_user_ldt(struct pcb *pcb)
+set_user_ldt(struct mdproc *mdp)
 {
-       struct pcb_ldt *pcb_ldt;
+       struct proc_ldt *pldt;
 
-       pcb_ldt = pcb->pcb_ldt;
+       pldt = mdp->md_ldt;
 #ifdef SMP
-       gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
+       gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
 #else
-       gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
+       gdt[GUSERLDT_SEL].sd = pldt->ldt_sd;
 #endif
        lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
        PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
@@ -273,14 +274,14 @@
 
 #ifdef SMP
 static void
-set_user_ldt_rv(struct pcb *pcb)
+set_user_ldt_rv(struct thread *td)
 {
 
-       if (pcb != PCPU_GET(curpcb))
+       if (td != PCPU_GET(curthread))
                return;
 
        mtx_lock_spin(&sched_lock);
-       set_user_ldt(pcb);
+       set_user_ldt(&td->td_proc->p_md);
        mtx_unlock_spin(&sched_lock);
 }
 #endif
@@ -289,15 +290,15 @@
  * Must be called with either sched_lock free or held but not recursed.
  * If it does not return NULL, it will return with it owned.
  */
-struct pcb_ldt *
-user_ldt_alloc(struct pcb *pcb, int len)
+struct proc_ldt *
+user_ldt_alloc(struct mdproc *mdp, int len)
 {
-       struct pcb_ldt *pcb_ldt, *new_ldt;
+       struct proc_ldt *pldt, *new_ldt;
 
        if (mtx_owned(&sched_lock))
                mtx_unlock_spin(&sched_lock);
        mtx_assert(&sched_lock, MA_NOTOWNED);
-       MALLOC(new_ldt, struct pcb_ldt *, sizeof(struct pcb_ldt),
+       MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt),
                M_SUBPROC, M_WAITOK);
 
        new_ldt->ldt_len = len = NEW_MAX_LD(len);
@@ -315,11 +316,11 @@
        gdt_segs[GUSERLDT_SEL].ssd_limit = len * sizeof(union descriptor) - 1;
        ssdtosd(&gdt_segs[GUSERLDT_SEL], &new_ldt->ldt_sd);
 
-       if ((pcb_ldt = pcb->pcb_ldt)) {
-               if (len > pcb_ldt->ldt_len)
-                       len = pcb_ldt->ldt_len;
-               bcopy(pcb_ldt->ldt_base, new_ldt->ldt_base,
-                       len * sizeof(union descriptor));
+       if ((pldt = mdp->md_ldt)) {
+               if (len > pldt->ldt_len)
+                       len = pldt->ldt_len;
+               bcopy(pldt->ldt_base, new_ldt->ldt_base,
+                   len * sizeof(union descriptor));
        } else {
                bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
        }
@@ -328,30 +329,31 @@
 
 /*
  * Must be called either with sched_lock free or held but not recursed.
- * If pcb->pcb_ldt is not NULL, it will return with sched_lock released.
+ * If md_ldt is not NULL, it will return with sched_lock released.
  */
 void
-user_ldt_free(struct pcb *pcb)
+user_ldt_free(struct thread *td)
 {
-       struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+       struct mdproc *mdp = &td->td_proc->p_md;
+       struct proc_ldt *pldt = mdp->md_ldt;
 
-       if (pcb_ldt == NULL)
+       if (pldt == NULL)
                return;
 
        if (!mtx_owned(&sched_lock))
                mtx_lock_spin(&sched_lock);
        mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED);
-       if (pcb == PCPU_GET(curpcb)) {
+       if (td == PCPU_GET(curthread)) {
                lldt(_default_ldt);
                PCPU_SET(currentldt, _default_ldt);
        }
 
-       pcb->pcb_ldt = NULL;
-       if (--pcb_ldt->ldt_refcnt == 0) {
+       mdp->md_ldt = NULL;
+       if (--pldt->ldt_refcnt == 0) {
                mtx_unlock_spin(&sched_lock);
-               kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
-                       pcb_ldt->ldt_len * sizeof(union descriptor));
-               FREE(pcb_ldt, M_SUBPROC);
+               kmem_free(kernel_map, (vm_offset_t)pldt->ldt_base,
+                       pldt->ldt_len * sizeof(union descriptor));
+               FREE(pldt, M_SUBPROC);
        } else
                mtx_unlock_spin(&sched_lock);
 }
@@ -362,8 +364,7 @@
        char *args;
 {
        int error = 0;
-       struct pcb *pcb = td->td_pcb;
-       struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+       struct proc_ldt *pldt = td->td_proc->p_md.md_ldt;
        int nldt, num;
        union descriptor *lp;
        struct i386_ldt_args ua, *uap = &ua;
@@ -380,10 +381,10 @@
        if ((uap->start < 0) || (uap->num <= 0))
                return(EINVAL);
 
-       if (pcb_ldt) {
-               nldt = pcb_ldt->ldt_len;
+       if (pldt) {
+               nldt = pldt->ldt_len;
                num = min(uap->num, nldt);
-               lp = &((union descriptor *)(pcb_ldt->ldt_base))[uap->start];
+               lp = &((union descriptor *)(pldt->ldt_base))[uap->start];
        } else {
                nldt = sizeof(ldt)/sizeof(ldt[0]);
                num = min(uap->num, nldt);
@@ -406,8 +407,9 @@
 {
        int error = 0, i, n;
        int largest_ld;
+       struct mdproc *mdp = &td->td_proc->p_md;
        struct pcb *pcb = td->td_pcb;
-       struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+       struct proc_ldt *pldt = mdp->md_ldt;
        struct i386_ldt_args ua, *uap = &ua;
        caddr_t old_ldt_base;
        int old_ldt_len;
@@ -432,16 +434,16 @@
                return(EINVAL);
 
        /* allocate user ldt */
-       if (!pcb_ldt || largest_ld >= pcb_ldt->ldt_len) {
-               struct pcb_ldt *new_ldt = user_ldt_alloc(pcb, largest_ld);
+       if (!pldt || largest_ld >= pldt->ldt_len) {
+               struct proc_ldt *new_ldt = user_ldt_alloc(mdp, largest_ld);
                if (new_ldt == NULL)
                        return ENOMEM;
-               if (pcb_ldt) {
-                       old_ldt_base = pcb_ldt->ldt_base;
-                       old_ldt_len = pcb_ldt->ldt_len;
-                       pcb_ldt->ldt_sd = new_ldt->ldt_sd;
-                       pcb_ldt->ldt_base = new_ldt->ldt_base;
-                       pcb_ldt->ldt_len = new_ldt->ldt_len;
+               if (pldt) {
+                       old_ldt_base = pldt->ldt_base;
+                       old_ldt_len = pldt->ldt_len;
+                       pldt->ldt_sd = new_ldt->ldt_sd;
+                       pldt->ldt_base = new_ldt->ldt_base;
+                       pldt->ldt_len = new_ldt->ldt_len;
                        mtx_unlock_spin(&sched_lock);
                        kmem_free(kernel_map, (vm_offset_t)old_ldt_base,
                                old_ldt_len * sizeof(union descriptor));
@@ -450,16 +452,17 @@
                        mtx_lock_spin(&sched_lock);
 #endif
                } else {
-                       pcb->pcb_ldt = pcb_ldt = new_ldt;
+                       mdp->md_ldt = pldt = new_ldt;
 #ifdef SMP
                        mtx_unlock_spin(&sched_lock);
 #endif
                }
 #ifdef SMP
                /* signal other cpus to reload ldt */
-               smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, pcb);
+               smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, 
+                   NULL, td);
 #else
-               set_user_ldt(pcb);
+               set_user_ldt(mdp);
                mtx_unlock_spin(&sched_lock);
 #endif
        }
@@ -533,7 +536,7 @@
        /* Fill in range */
        savecrit = critical_enter();
        error = copyin(uap->descs, 
-           &((union descriptor *)(pcb_ldt->ldt_base))[uap->start],
+           &((union descriptor *)(pldt->ldt_base))[uap->start],
            uap->num * sizeof(union descriptor));
        if (!error)
                td->td_retval[0] = uap->start;
--- i386/vm_machdep.c.orig      Wed Sep 19 02:16:28 2001
+++ i386/vm_machdep.c   Wed Sep 19 03:39:14 2001
@@ -125,6 +125,7 @@
        register struct proc *p1;
        struct thread *td2;
        struct pcb *pcb2;
+       struct mdproc *mdp2;
 #ifdef DEV_NPX
        int savecrit;
 #endif
@@ -134,15 +135,15 @@
        if ((flags & RFPROC) == 0) {
                if ((flags & RFMEM) == 0) {
                        /* unshare user LDT */
-                       struct pcb *pcb1 = td1->td_pcb;
-                       struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
-                       if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
-                               pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
-                               if (pcb_ldt == NULL)
+                       struct mdproc *mdp1 = &td1->td_proc->p_md;
+                       struct proc_ldt *pldt = mdp1->md_ldt;
+                       if (pldt && pldt->ldt_refcnt > 1) {
+                               pldt = user_ldt_alloc(mdp1, pldt->ldt_len);
+                               if (pldt == NULL)
                                        panic("could not copy LDT");
-                               pcb1->pcb_ldt = pcb_ldt;
-                               set_user_ldt(pcb1);
-                               user_ldt_free(pcb1);
+                               mdp1->md_ldt = pldt;
+                               set_user_ldt(mdp1);
+                               user_ldt_free(td1);
                        }
                }
                return;
@@ -162,9 +163,13 @@
        pcb2 = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
        td2->td_pcb = pcb2;
 
-       /* Copy p1's pcb. */
+       /* Copy p1's pcb */
        bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
 
+       /* Point mdproc and then copy over td1's contents */
+       mdp2 = &td2->td_proc->p_md;
+       bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
+
        /*
         * Create a new fresh stack for the new process.
         * Copy the trap frame for the return to user mode as if from a
@@ -190,7 +195,6 @@
        pcb2->pcb_eip = (int)fork_trampoline;
        /*-
         * pcb2->pcb_dr*:       cloned above.
-        * pcb2->pcb_ldt:       duplicated below, if necessary.
         * pcb2->pcb_savefpu:   cloned above.
         * pcb2->pcb_flags:     cloned above.
         * pcb2->pcb_onfault:   cloned above (always NULL here?).
@@ -205,13 +209,13 @@
 
         /* Copy the LDT, if necessary. */
        mtx_lock_spin(&sched_lock);
-        if (pcb2->pcb_ldt != 0) {
+        if (mdp2->md_ldt != 0) {
                if (flags & RFMEM) {
-                       pcb2->pcb_ldt->ldt_refcnt++;
+                       mdp2->md_ldt->ldt_refcnt++;
                } else {
-                       pcb2->pcb_ldt = user_ldt_alloc(pcb2,
-                               pcb2->pcb_ldt->ldt_len);
-                       if (pcb2->pcb_ldt == NULL)
+                       mdp2->md_ldt = user_ldt_alloc(mdp2,
+                           mdp2->md_ldt->ldt_len);
+                       if (mdp2->md_ldt == NULL)
                                panic("could not copy LDT");
                }
         }
@@ -253,7 +257,7 @@
        register struct thread *td;
 {
        struct pcb *pcb = td->td_pcb; 
-
+       struct mdproc *mdp = &td->td_proc->p_md;
 #ifdef DEV_NPX
        npxexit(td);
 #endif
@@ -266,8 +270,8 @@
                    ctob(IOPAGES + 1));
                pcb->pcb_ext = 0;
        }
-       if (pcb->pcb_ldt)
-               user_ldt_free(pcb);
+       if (mdp->md_ldt)
+               user_ldt_free(td);
         if (pcb->pcb_flags & PCB_DBREGS) {
                 /*
                  * disable all hardware breakpoints

Reply via email to