Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Oct 2001 14:43:23 -0400 (EDT)
From:      "Andrew R. Reiter" <arr@watson.org>
To:        freebsd-current@freebsd.org
Subject:   Call for testers: LDT -> MD Proc
Message-ID:  <Pine.NEB.3.96L.1011018143606.53752A-200000@fledge.watson.org>

index | next in thread | raw e-mail

[-- Attachment #1 --]
Hi,

The attached patch is to sys/i386/* code.  It's basically 50%, albeit the
easy 50%, of the Junior Kernel Hacker task from jhb last month.  I
finished it and tested awhile ago (~1 month) but my current box died.  My
current box is still dead, so I've yet to test it any further, but Peter
Wemm and jhb both looked at it and said it looked "ok" and to get people
to test it.

The attached patch is for current from 9/19/01 -- Yes, Im sorry, this
sucks.  I have a 4.3 release CD here so Im going to have to use that to
rebuild a box back to current (FTP installs with 4.4 floppies have really
sucked).  If you're willing to test and don't mind this patch, thanks.  If
you are willing to test and want a newer patch, let me know and I'll get
you one tonight or tomorrow.

Btw, the patch is also located at
http://www.watson.org/~arr/fbsd-patches/ldt-2-mdproc.diff

Cheers,
Andrew

*-------------.................................................
| Andrew R. Reiter 
| arr@fledge.watson.org
| "It requires a very unusual mind
|   to undertake the analysis of the obvious" -- A.N. Whitehead

[-- Attachment #2 --]
--- 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
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1011018143606.53752A-200000>