Apply by doing:
       cd /usr/src
       patch -p0 < 003_i386pmap.patch

And then rebuild your kernel.

Index: sys/arch/i386/i386/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/cpu.c,v
retrieving revision 1.15
retrieving revision 1.15.2.1
diff -u -p -r1.15 -r1.15.2.1
--- sys/arch/i386/i386/cpu.c    18 Jul 2005 02:43:25 -0000      1.15
+++ sys/arch/i386/i386/cpu.c    13 Jan 2006 01:56:54 -0000      1.15.2.1
@@ -255,6 +255,8 @@ cpu_attach(parent, self, aux)
       pcb->pcb_pmap = pmap_kernel();
       pcb->pcb_cr3 = vtophys(pcb->pcb_pmap->pm_pdir);
       /* pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdir - KERNBASE; XXX ??? */
+
+       cpu_default_ldt(ci);    /* Use the `global' ldt until one alloc'd */
#endif

       /* further PCB init done later. */
@@ -295,6 +297,7 @@ cpu_attach(parent, self, aux)
                */
               printf("apid %d (application processor)\n", caa->cpu_number);
               gdt_alloc_cpu(ci);
+               cpu_alloc_ldt(ci);
               ci->ci_flags |= CPUF_PRESENT | CPUF_AP;
               identifycpu(ci);
               ci->ci_next = cpu_info_list->ci_next;
@@ -455,6 +458,7 @@ cpu_hatch(void *v)
       lapic_initclocks();
       lapic_set_lvt();
       gdt_init_cpu(ci);
+       cpu_init_ldt(ci);
       npxinit(ci);

       lldt(GSEL(GLDT_SEL, SEL_KPL));
Index: sys/arch/i386/i386/freebsd_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/freebsd_machdep.c,v
retrieving revision 1.17
retrieving revision 1.17.10.1
diff -u -p -r1.17 -r1.17.10.1
--- sys/arch/i386/i386/freebsd_machdep.c        2 Jun 2003 23:27:47 -0000       1.17
+++ sys/arch/i386/i386/freebsd_machdep.c        13 Jan 2006 01:56:54 -0000      1.17.10.1
@@ -81,7 +81,6 @@ freebsd_sendsig(catcher, sig, mask, code
       union sigval val;
{
       register struct proc *p = curproc;
-       struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
       register struct trapframe *tf;
       struct freebsd_sigframe *fp, frame;
       struct sigacts *psp = p->p_sigacts;
@@ -157,8 +156,7 @@ freebsd_sendsig(catcher, sig, mask, code
       tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_eip = p->p_sigcode;
-       tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
-           GSEL(GUCODE1_SEL, SEL_UPL) : GSEL(GUCODE_SEL, SEL_UPL);
+       tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
       tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
       tf->tf_esp = (int)fp;
       tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
Index: sys/arch/i386/i386/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/genassym.cf,v
retrieving revision 1.21
retrieving revision 1.21.2.1
diff -u -p -r1.21 -r1.21.2.1
--- sys/arch/i386/i386/genassym.cf      18 Jul 2005 14:55:49 -0000      1.21
+++ sys/arch/i386/i386/genassym.cf      13 Jan 2006 01:56:54 -0000      1.21.2.1
@@ -110,6 +110,7 @@ member      pcb_cr3
member pcb_ebp
member pcb_esp
member pcb_cr0
+member pcb_ldt
member pcb_ldt_sel
member pcb_onfault
member pcb_fpcpu
Index: sys/arch/i386/i386/linux_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/linux_machdep.c,v
retrieving revision 1.30
retrieving revision 1.30.6.1
diff -u -p -r1.30 -r1.30.6.1
--- sys/arch/i386/i386/linux_machdep.c  2 Jul 2004 16:29:55 -0000       1.30
+++ sys/arch/i386/i386/linux_machdep.c  13 Jan 2006 01:56:54 -0000      1.30.6.1
@@ -112,7 +112,6 @@ linux_sendsig(catcher, sig, mask, code,
       union sigval val;
{
       struct proc *p = curproc;
-       struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
       struct trapframe *tf;
       struct linux_sigframe *fp, frame;
       struct sigacts *psp = p->p_sigacts;
@@ -185,8 +184,7 @@ linux_sendsig(catcher, sig, mask, code,
       tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_eip = p->p_sigcode;
-       tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
-           GSEL(GUCODE1_SEL, SEL_UPL) : GSEL(GUCODE_SEL, SEL_UPL);
+       tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
       tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
       tf->tf_esp = (int)fp;
       tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.324
retrieving revision 1.324.2.1
diff -u -p -r1.324 -r1.324.2.1
--- sys/arch/i386/i386/machdep.c        20 Aug 2005 00:27:08 -0000      1.324
+++ sys/arch/i386/i386/machdep.c        13 Jan 2006 01:56:54 -0000      1.324.2.1
@@ -483,6 +483,7 @@ i386_proc0_tss_ldt_init()
       pcb->pcb_iomap_pad = 0xff;

       pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
+       pcb->pcb_ldt = ldt;
       pcb->pcb_cr0 = rcr0();
       pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
       pcb->pcb_tss.tss_esp0 = (int)proc0.p_addr + USPACE - 16;
@@ -507,6 +508,7 @@ i386_init_pcb_tss_ldt(struct cpu_info *c
       pcb->pcb_iomap_pad = 0xff;

       pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
+       pcb->pcb_ldt = ci->ci_ldt;
       pcb->pcb_cr0 = rcr0();
       ci->ci_idle_tss_sel = tss_alloc(pcb);
}
@@ -2057,7 +2059,6 @@ sendsig(catcher, sig, mask, code, type,
       extern char sigcode, sigcode_xmm;
#endif
       struct proc *p = curproc;
-       struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
       struct trapframe *tf = p->p_md.md_regs;
       struct sigframe *fp, frame;
       struct sigacts *psp = p->p_sigacts;
@@ -2153,8 +2154,7 @@ sendsig(catcher, sig, mask, code, type,
       tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_eip = p->p_sigcode;
-       tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
-           GSEL(GUCODE1_SEL, SEL_UPL) : GSEL(GUCODE_SEL, SEL_UPL);
+       tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
#ifdef I686_CPU
       if (i386_use_fxsave)
               tf->tf_eip += &sigcode_xmm - &sigcode;
@@ -2556,6 +2556,30 @@ setregs(p, pack, stack, retval)
       pmap_ldt_cleanup(p);
#endif

+       /*
+        * Reset the code segment limit to I386_MAX_EXE_ADDR in the pmap;
+        * this gets copied into the GDT and LDT for {G,L}UCODE_SEL by
+        * pmap_activate().
+        */
+       setsegment(&pmap->pm_codeseg, 0, atop(I386_MAX_EXE_ADDR) - 1,
+           SDT_MEMERA, SEL_UPL, 1, 1);
+
+       /*
+        * And update the GDT and LDT since we return to the user process
+        * by leaving the syscall (we don't do another pmap_activate()).
+        */
+#ifdef MULTIPROCESSOR
+       curcpu()->ci_gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd =
+           pmap->pm_codeseg;
+#else
+       gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd = pmap->pm_codeseg;
+#endif
+
+       /*
+        * And reset the hiexec marker in the pmap.
+        */
+       pmap->pm_hiexec = 0;
+
       p->p_md.md_flags &= ~MDP_USEDFPU;
       if (i386_use_fxsave) {
               pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __OpenBSD_NPXCW__;
@@ -2570,8 +2594,7 @@ setregs(p, pack, stack, retval)
       tf->tf_ebp = 0;
       tf->tf_ebx = (int)PS_STRINGS;
       tf->tf_eip = pack->ep_entry;
-       tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
-           LSEL(LUCODE1_SEL, SEL_UPL) : LSEL(LUCODE_SEL, SEL_UPL);
+       tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
       tf->tf_eflags = PSL_USERSET;
       tf->tf_esp = stack;
       tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
@@ -2704,6 +2727,32 @@ cpu_init_idt()
       setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
       lidt(&region);
}
+
+void
+cpu_default_ldt(struct cpu_info *ci)
+{
+       ci->ci_ldt = ldt;
+       ci->ci_ldt_len = sizeof(ldt);
+}
+
+void
+cpu_alloc_ldt(struct cpu_info *ci)
+{
+       union descriptor *cpu_ldt;
+       size_t len = sizeof(ldt);
+
+       cpu_ldt = (union descriptor *)uvm_km_alloc(kernel_map, len);
+       bcopy(ldt, cpu_ldt, len);
+       ci->ci_ldt = cpu_ldt;
+       ci->ci_ldt_len = len;
+}
+
+void
+cpu_init_ldt(struct cpu_info *ci)
+{
+       setsegment(&ci->ci_gdt[GLDT_SEL].sd, ci->ci_ldt, ci->ci_ldt_len - 1,
+           SDT_SYSLDT, SEL_KPL, 0, 0);
+}
#endif /* MULTIPROCESSOR */

void
@@ -2740,8 +2789,6 @@ init386(paddr_t first_avail)
       setsegment(&gdt[GDATA_SEL].sd, 0, 0xfffff, SDT_MEMRWA, SEL_KPL, 1, 1);
       setsegment(&gdt[GLDT_SEL].sd, ldt, sizeof(ldt) - 1, SDT_SYSLDT,
           SEL_KPL, 0, 0);
-       setsegment(&gdt[GUCODE1_SEL].sd, 0, i386_btop(VM_MAXUSER_ADDRESS) - 1,
-           SDT_MEMERA, SEL_UPL, 1, 1);
       setsegment(&gdt[GUCODE_SEL].sd, 0, i386_btop(I386_MAX_EXE_ADDR) - 1,
           SDT_MEMERA, SEL_UPL, 1, 1);
       setsegment(&gdt[GUDATA_SEL].sd, 0, i386_btop(VM_MAXUSER_ADDRESS) - 1,
@@ -2752,7 +2799,6 @@ init386(paddr_t first_avail)
       /* make ldt gates and memory segments */
       setgate(&ldt[LSYS5CALLS_SEL].gd, &IDTVEC(osyscall), 1, SDT_SYS386CGT,
           SEL_UPL, GCODE_SEL);
-       ldt[LUCODE1_SEL] = gdt[GUCODE1_SEL];
       ldt[LUCODE_SEL] = gdt[GUCODE_SEL];
       ldt[LUDATA_SEL] = gdt[GUDATA_SEL];
       ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL];
Index: sys/arch/i386/i386/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.82
retrieving revision 1.82.2.1
diff -u -p -r1.82 -r1.82.2.1
--- sys/arch/i386/i386/pmap.c   12 Jul 2005 21:12:03 -0000      1.82
+++ sys/arch/i386/i386/pmap.c   13 Jan 2006 01:56:55 -0000      1.82.2.1
@@ -465,6 +465,8 @@ void                        pmap_release(pmap_t);

void                   pmap_zero_phys(paddr_t);

+void   setcslimit(struct pmap *, struct trapframe *, struct pcb *, vaddr_t);
+
/*
 * p m a p   i n l i n e   h e l p e r   f u n c t i o n s
 */
@@ -710,13 +712,14 @@ pmap_exec_account(struct pmap *pm, vaddr
               struct trapframe *tf = curproc->p_md.md_regs;
               struct pcb *pcb = &curproc->p_addr->u_pcb;

-               pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
               pm->pm_hiexec = I386_MAX_EXE_ADDR;
+               setcslimit(pm, tf, pcb, I386_MAX_EXE_ADDR);
       }
}

/*
 * Fixup the code segment to cover all potential executable mappings.
+ * Called by kernel SEGV trap handler.
 * returns 0 if no changes to the code segment were made.
 */
int
@@ -733,24 +736,62 @@ pmap_exec_fixup(struct vm_map *map, stru
                * We need to make it point to the last page, not past it.
                */
               if (ent->protection & VM_PROT_EXECUTE)
-                       va = trunc_page(ent->end) - PAGE_SIZE;
+                       va = trunc_page(ent->end - 1);
       }
       vm_map_unlock(map);

-       if (va == pm->pm_hiexec)
+       if (va <= pm->pm_hiexec) {
               return (0);
+       }

       pm->pm_hiexec = va;

-       if (pm->pm_hiexec > (vaddr_t)I386_MAX_EXE_ADDR) {
-               pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE1_SEL, SEL_UPL);
-       } else {
-               pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
-       }
-
+       /*
+        * We have a new 'highest executable' va, so we need to update
+        * the value for the code segment limit, which is stored in the
+        * PCB.
+        */
+       setcslimit(pm, tf, pcb, va);
+
       return (1);
}

+void
+setcslimit(struct pmap *pm, struct trapframe *tf, struct pcb *pcb,
+    vaddr_t limit)
+{
+       /*
+        * Called when we have a new 'highest executable' va, so we need
+        * to update the value for the code segment limit, which is stored
+        * in the PCB.
+        *
+        * There are no caching issues to be concerned with: the
+        * processor reads the whole descriptor from the GDT when the
+        * appropriate selector is loaded into a segment register, and
+        * this only happens on the return to userland.
+        *
+        * This also works in the MP case, since whichever CPU gets to
+        * run the process will pick up the right descriptor value from
+        * the PCB.
+        */
+       limit = min(limit, VM_MAXUSER_ADDRESS - 1);
+
+       setsegment(&pm->pm_codeseg, 0, atop(limit),
+           SDT_MEMERA, SEL_UPL, 1, 1);
+
+       /* And update the GDT and LDT since we may be called by the
+        * trap handler (cpu_switch won't get a chance).
+        */
+#ifdef MULTIPROCESSOR
+       curcpu()->ci_gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd =
+           pm->pm_codeseg;
+#else
+       gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd = pm->pm_codeseg;
+#endif
+
+       pcb->pcb_cs = tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
+}
+
/*
 * p m a p   k e n t e r   f u n c t i o n s
 *
@@ -1946,6 +1987,9 @@ pmap_pinit(pmap)
       pmap->pm_hiexec = 0;
       pmap->pm_flags = 0;

+       setsegment(&pmap->pm_codeseg, 0, atop(I386_MAX_EXE_ADDR) - 1,
+           SDT_MEMERA, SEL_UPL, 1, 1);
+
       /* allocate PDP */
       pmap->pm_pdir = (pd_entry_t *) uvm_km_alloc(kernel_map, NBPG);
       if (pmap->pm_pdir == NULL)
@@ -2171,11 +2215,32 @@ pmap_activate(p)
{
       struct pcb *pcb = &p->p_addr->u_pcb;
       struct pmap *pmap = p->p_vmspace->vm_map.pmap;
+#ifdef MULTIPROCESSOR
+       struct cpu_info *self = curcpu();
+#endif

       pcb->pcb_pmap = pmap;
+       /* Get the LDT that this process will actually use */
+#ifdef MULTIPROCESSOR
+       pcb->pcb_ldt = pmap->pm_ldt == NULL ? self->ci_ldt : pmap->pm_ldt;
+#else
+       pcb->pcb_ldt = pmap->pm_ldt == NULL ? ldt : pmap->pm_ldt;
+#endif
       pcb->pcb_ldt_sel = pmap->pm_ldt_sel;
       pcb->pcb_cr3 = pmap->pm_pdirpa;
       if (p == curproc) {
+               /*
+                * Set the correct descriptor value (i.e. with the
+                * correct code segment X limit) in the GDT and the LDT.
+                */
+#ifdef MULTIPROCESSOR
+               self->ci_gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd =
+                   pmap->pm_codeseg;
+#else
+               gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd =
+                   pmap->pm_codeseg;
+#endif
+
               lcr3(pcb->pcb_cr3);
               lldt(pcb->pcb_ldt_sel);

Index: sys/arch/i386/i386/svr4_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/svr4_machdep.c,v
retrieving revision 1.21
retrieving revision 1.21.6.1
diff -u -p -r1.21 -r1.21.6.1
--- sys/arch/i386/i386/svr4_machdep.c   2 Jul 2004 16:29:55 -0000       1.21
+++ sys/arch/i386/i386/svr4_machdep.c   13 Jan 2006 01:56:55 -0000      1.21.6.1
@@ -322,7 +322,6 @@ svr4_sendsig(catcher, sig, mask, code, t
       union sigval val;
{
       register struct proc *p = curproc;
-       struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
       register struct trapframe *tf;
       struct svr4_sigframe *fp, frame;
       struct sigacts *psp = p->p_sigacts;
@@ -380,8 +379,7 @@ svr4_sendsig(catcher, sig, mask, code, t
       tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
       tf->tf_eip = p->p_sigcode;
-       tf->tf_cs = pmap->pm_hiexec > I386_MAX_EXE_ADDR ?
-           GSEL(GUCODE1_SEL, SEL_UPL) : GSEL(GUCODE_SEL, SEL_UPL);
+       tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
       tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
       tf->tf_esp = (int)fp;
       tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
Index: sys/arch/i386/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.68
retrieving revision 1.68.2.1
diff -u -p -r1.68 -r1.68.2.1
--- sys/arch/i386/include/cpu.h 27 May 2005 10:41:11 -0000      1.68
+++ sys/arch/i386/include/cpu.h 13 Jan 2006 01:56:55 -0000      1.68.2.1
@@ -132,6 +132,8 @@ struct cpu_info {
       int             ci_astpending;

       union descriptor *ci_gdt;
+       union descriptor *ci_ldt;       /* per-cpu default LDT */
+       int             ci_ldt_len;     /* in bytes */

       volatile int ci_ddb_paused;     /* paused due to other proc in ddb */
#define CI_DDB_RUNNING         0
Index: sys/arch/i386/include/pmap.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/pmap.h,v
retrieving revision 1.37
retrieving revision 1.37.4.1
diff -u -p -r1.37 -r1.37.4.1
--- sys/arch/i386/include/pmap.h        14 Dec 2004 16:57:22 -0000      1.37
+++ sys/arch/i386/include/pmap.h        13 Jan 2006 01:56:55 -0000      1.37.4.1
@@ -275,6 +275,7 @@ struct pmap {
       vaddr_t pm_hiexec;              /* highest executable mapping */
       int pm_flags;                   /* see below */

+       struct  segment_descriptor pm_codeseg;  /* cs descriptor for process */
       union descriptor *pm_ldt;       /* user-set LDT */
       int pm_ldt_len;                 /* number of LDT entries */
       int pm_ldt_sel;                 /* LDT selector */
Index: sys/arch/i386/include/segments.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/segments.h,v
retrieving revision 1.13
retrieving revision 1.13.6.1
diff -u -p -r1.13 -r1.13.6.1
--- sys/arch/i386/include/segments.h    13 Jun 2004 21:49:16 -0000      1.13
+++ sys/arch/i386/include/segments.h    13 Jan 2006 01:56:55 -0000      1.13.6.1
@@ -134,6 +134,9 @@ void setsegment(struct segment_descripto
    int, int);
void unsetgate(struct gate_descriptor *);
void cpu_init_idt(void);
+void cpu_default_ldt(struct cpu_info *);
+void cpu_alloc_ldt(struct cpu_info *);
+void cpu_init_ldt(struct cpu_info *);

int idt_vec_alloc(int, int);
void idt_vec_set(int, void (*)(void));