diff options
author | rab <none@none> | 2006-01-06 10:19:31 -0800 |
---|---|---|
committer | rab <none@none> | 2006-01-06 10:19:31 -0800 |
commit | 0baeff3d96eae184e775c1064f1836090446a7bf (patch) | |
tree | 223a82fa3266e75588aace66980f22165d83fcff /usr/src | |
parent | d045b9872121ef87817d5d01968d80cc01574bc8 (diff) | |
download | illumos-gate-0baeff3d96eae184e775c1064f1836090446a7bf.tar.gz |
6219276 need per-process equivalent of device context
6244042 x86 kernels do not need default LDTs
6308413 sysi86(SI86DSCR) rejects the first valid custom descriptor #6 with errno
6308413 contributed by Juergen Keil <jk@tools.de>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/Makefile.files | 3 | ||||
-rw-r--r-- | usr/src/uts/common/disp/thread.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/os/exec.c | 35 | ||||
-rw-r--r-- | usr/src/uts/common/os/exit.c | 32 | ||||
-rw-r--r-- | usr/src/uts/common/os/fork.c | 13 | ||||
-rw-r--r-- | usr/src/uts/common/os/lwp.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/os/proc.c | 155 | ||||
-rw-r--r-- | usr/src/uts/common/sys/proc.h | 26 | ||||
-rw-r--r-- | usr/src/uts/i86pc/ml/mpcore.s | 10 | ||||
-rw-r--r-- | usr/src/uts/i86pc/ml/offsets.in | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/mlsetup.c | 17 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/trap.c | 39 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/machcpuvar.h | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/ml/swtch.s | 107 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/archdep.c | 8 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/desctbls.c | 89 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/syscall.c | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/sysi86.c | 191 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/segments.h | 11 |
19 files changed, 433 insertions, 346 deletions
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index b51fd395d9..d614acf224 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -20,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -212,6 +212,7 @@ GENUNIX_OBJS += \ priocntl.o \ priv.o \ priv_const.o \ + proc.o \ procset.o \ processor_bind.o \ processor_info.o \ diff --git a/usr/src/uts/common/disp/thread.c b/usr/src/uts/common/disp/thread.c index 6cc6b08098..d9dfeb4993 100644 --- a/usr/src/uts/common/disp/thread.c +++ b/usr/src/uts/common/disp/thread.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -582,6 +582,8 @@ thread_exit() if (t->t_ctx != NULL) exitctx(t); + if (t->t_procp->p_pctx != NULL) + exitpctx(t->t_procp); t->t_state = TS_ZOMB; /* set zombie thread */ @@ -685,6 +687,8 @@ thread_free(kthread_t *t) lwp_freeregs(t->t_lwp, 0); if (t->t_ctx) freectx(t, 0); + if (t->t_procp->p_pctx) + freepctx(t->t_procp, 0); t->t_stk = NULL; if (t->t_lwp) lwp_stk_fini(t->t_lwp); @@ -872,7 +876,7 @@ reapq_add(kthread_t *t) } /* - * Install a device context for the current thread + * Install thread context ops for the current thread. */ void installctx( @@ -900,8 +904,8 @@ installctx( } /* - * Remove a device context from the current thread - * (Or allow the agent thread to remove device context from another + * Remove thread context ops from the current thread. + * (Or allow the agent thread to remove thread context ops from another * thread in the same, stopped, process) */ int @@ -1006,7 +1010,7 @@ exitctx(kthread_t *t) /* * freectx is called from thread_free() and exec() to get - * rid of old device context. + * rid of old thread context ops. */ void freectx(kthread_t *t, int isexec) diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c index 004efdd5ed..e7a44db1d8 100644 --- a/usr/src/uts/common/os/exec.c +++ b/usr/src/uts/common/os/exec.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -87,11 +87,6 @@ uint_t auxv_hwcap = 0; /* auxv AT_SUN_HWCAP value; determined on the fly */ uint_t auxv_hwcap32 = 0; /* 32-bit version of auxv_hwcap */ #endif -#if defined(__i386) || defined(__amd64) -extern void ldt_free(proc_t *p); -extern void ldt_load(void); -#endif - int exec_lpg_disable = 0; #define PSUIDFLAGS (SNOCD|SUGID) @@ -257,10 +252,12 @@ exec_common(const char *fname, const char **argp, const char **envp) lwp_freeregs(lwp, 1); /* - * Free device context + * Free thread and process context ops. */ if (curthread->t_ctx) freectx(curthread, 1); + if (p->p_pctx) + freepctx(p, 1); /* * Remember file name for accounting; clear any cached DTrace predicate. @@ -343,30 +340,6 @@ exec_common(const char *fname, const char **argp, const char **envp) ASSERT(curthread->t_schedctl == NULL); -#if defined(__i386) || defined(__amd64) - /* If the process uses a private LDT then change it to default */ - if (p->p_ldt) - ldt_free(p); -#endif /* __i386 || __amd64 */ - -#if defined(__amd64) - /* - * Make sure the process has the correct LDT descriptor for its data - * model. - */ - if (p->p_model == DATAMODEL_LP64) - p->p_ldt_desc = ldt0_default64_desc; - else - p->p_ldt_desc = ldt0_default_desc; - - /* - * Ensure the change of LDT is propagated into the LDTR. - */ - kpreempt_disable(); - ldt_load(); - kpreempt_enable(); -#endif /* __amd64 */ - #if defined(__sparc) if (p->p_utraps != NULL) utrap_free(p); diff --git a/usr/src/uts/common/os/exit.c b/usr/src/uts/common/os/exit.c index 83a6978064..7fcba5d9ec 100644 --- a/usr/src/uts/common/os/exit.c +++ b/usr/src/uts/common/os/exit.c @@ -21,7 +21,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -75,10 +75,6 @@ #include <sys/sdt.h> #include <sys/corectl.h> -#if defined(__x86) -extern void ldt_free(proc_t *pp); -#endif - /* * convert code/data pair into old style wait status */ @@ -538,14 +534,6 @@ proc_exit(int why, int what) } else mutex_exit(&pidlock); -#if defined(__x86) - /* - * If the process was using a private LDT then free it. - */ - if (p->p_ldt) - ldt_free(p); -#endif - #if defined(__sparc) if (p->p_utraps != NULL) utrap_free(p); @@ -769,6 +757,24 @@ proc_exit(int why, int what) p->p_tidhash_sz = 0; /* + * If the process has context ops installed, call the exit routine + * on behalf of this last remaining thread. Normally exitpctx() is + * called during thread_exit() or lwp_exit(), but because this is the + * last thread in the process, we must call it here. By the time + * thread_exit() is called (below), the association with the relevant + * process has been lost. + * + * We also free the context here. + */ + if (p->p_pctx) { + kpreempt_disable(); + exitpctx(p); + kpreempt_enable(); + + freepctx(p, 0); + } + + /* * curthread's proc pointer is changed to point at p0 because * curthread's original proc pointer can be freed as soon as * the child sends a SIGCLD to its parent. diff --git a/usr/src/uts/common/os/fork.c b/usr/src/uts/common/os/fork.c index 8c8a4e984a..4171c0b122 100644 --- a/usr/src/uts/common/os/fork.c +++ b/usr/src/uts/common/os/fork.c @@ -21,7 +21,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -407,12 +407,11 @@ cfork(int isvfork, int isfork1) corectl_path_hold(cp->p_corefile = p->p_corefile); corectl_content_hold(cp->p_content = p->p_content); -#if defined(__x86) /* - * Get the right ldt descr for the child. + * Duplicate process context ops, if any. */ - (void) ldt_dup(p, cp); -#endif + if (p->p_pctx) + forkpctx(p, cp); #ifdef __sparc utrap_dup(p, cp); @@ -796,10 +795,6 @@ newproc(void (*pc)(), caddr_t arg, id_t cid, int pri, struct contract **ct) p->p_as = &kas; -#if defined(__x86) - (void) ldt_dup(&p0, p); /* Get the default ldt descr */ -#endif - if ((lwp = lwp_create(pc, arg, 0, p, TS_STOPPED, pri, &curthread->t_hold, cid, 1)) == NULL) { task_t *tk; diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c index df3f6767e8..dbccf77b9e 100644 --- a/usr/src/uts/common/os/lwp.c +++ b/usr/src/uts/common/os/lwp.c @@ -21,7 +21,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -785,6 +785,12 @@ lwp_exit(void) * death-row by resume(). Avoid preemption after resetting t->t_procp. */ t->t_preempt++; + + if (t->t_ctx != NULL) + exitctx(t); + if (p->p_pctx != NULL) + exitpctx(p); + t->t_procp = &p0; /* @@ -817,9 +823,6 @@ lwp_exit(void) lwp_pcb_exit(); - if (t->t_ctx != NULL) - exitctx(t); - t->t_state = TS_ZOMB; swtch_from_zombie(); /* never returns */ @@ -1617,12 +1620,7 @@ forklwp(klwp_t *lwp, proc_t *cp, id_t lwpid) lwp_forkregs(lwp, clwp); /* - * fork device context, if any. - * - * Someday we could do the work to support the possibility of - * forkctx() or lwp_createctx() failing. Currently, this would - * only be needed on x86 for the occasional process using a - * private LDT. + * Fork thread context ops, if any. */ if (t->t_ctx) forkctx(t, ct); diff --git a/usr/src/uts/common/os/proc.c b/usr/src/uts/common/os/proc.c new file mode 100644 index 0000000000..83563f34a9 --- /dev/null +++ b/usr/src/uts/common/os/proc.c @@ -0,0 +1,155 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/proc.h> + +/* + * Install process context ops for the current process. + */ +void +installpctx( + proc_t *p, + void *arg, + void (*save)(void *), + void (*restore)(void *), + void (*fork)(void *, void *), + void (*exit)(void *), + void (*free)(void *, int)) +{ + struct pctxop *pctx; + + pctx = kmem_alloc(sizeof (struct pctxop), KM_SLEEP); + pctx->save_op = save; + pctx->restore_op = restore; + pctx->fork_op = fork; + pctx->exit_op = exit; + pctx->free_op = free; + pctx->arg = arg; + pctx->next = p->p_pctx; + p->p_pctx = pctx; +} + +/* + * Remove a process context ops from the current process. + */ +int +removepctx( + proc_t *p, + void *arg, + void (*save)(void *), + void (*restore)(void *), + void (*fork)(void *, void *), + void (*exit)(void *), + void (*free)(void *, int)) +{ + struct pctxop *pctx, *prev_pctx; + + prev_pctx = NULL; + for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) { + if (pctx->save_op == save && pctx->restore_op == restore && + pctx->fork_op == fork && + pctx->exit_op == exit && pctx->free_op == free && + pctx->arg == arg) { + if (prev_pctx) + prev_pctx->next = pctx->next; + else + p->p_pctx = pctx->next; + if (pctx->free_op != NULL) + (pctx->free_op)(pctx->arg, 0); + kmem_free(pctx, sizeof (struct pctxop)); + return (1); + } + prev_pctx = pctx; + } + return (0); +} + +void +savepctx(proc_t *p) +{ + struct pctxop *pctx; + + ASSERT(p == curthread->t_procp); + for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next) + if (pctx->save_op != NULL) + (pctx->save_op)(pctx->arg); +} + +void +restorepctx(proc_t *p) +{ + struct pctxop *pctx; + + ASSERT(p == curthread->t_procp); + for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next) + if (pctx->restore_op != NULL) + (pctx->restore_op)(pctx->arg); +} + +void +forkpctx(proc_t *p, proc_t *cp) +{ + struct pctxop *pctx; + + for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) + if (pctx->fork_op != NULL) + (pctx->fork_op)(p, cp); +} + +/* + * exitpctx is called during thread/lwp exit to perform any actions + * needed when an LWP in the process leaves the processor for the last + * time. This routine is not intended to deal with freeing memory; freepctx() + * is used for that purpose during proc_exit(). This routine is provided to + * allow for clean-up that can't wait until thread_free(). + */ +void +exitpctx(proc_t *p) +{ + struct pctxop *pctx; + + for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) + if (pctx->exit_op != NULL) + (pctx->exit_op)(p); +} + +/* + * freepctx is called from proc_exit() to get rid of the actual context ops. + */ +void +freepctx(proc_t *p, int isexec) +{ + struct pctxop *pctx; + + while ((pctx = p->p_pctx) != NULL) { + p->p_pctx = pctx->next; + if (pctx->free_op != NULL) + (pctx->free_op)(pctx->arg, isexec); + kmem_free(pctx, sizeof (struct pctxop)); + } +} diff --git a/usr/src/uts/common/sys/proc.h b/usr/src/uts/common/sys/proc.h index 1049c645e4..eb1463d88d 100644 --- a/usr/src/uts/common/sys/proc.h +++ b/usr/src/uts/common/sys/proc.h @@ -21,7 +21,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -86,6 +86,16 @@ typedef struct lwpent { struct vnode *le_trace; /* pointer to /proc lwp vnode */ } lwpent_t; +typedef struct pctxop { + void (*save_op)(void *); /* function to invoke to save ctx */ + void (*restore_op)(void *); /* function to invoke to restore ctx */ + void (*fork_op)(void *, void *); /* invoke to fork context */ + void (*exit_op)(void *); /* invoked during process exit */ + void (*free_op)(void *, int); /* function which frees the context */ + void *arg; /* argument to above functions */ + struct pctxop *next; /* next pcontext ops */ +} pctxop_t; + /* * Elements of the lwp directory, p->p_lwpdir[]. * @@ -270,6 +280,9 @@ typedef struct proc { * C2 Security (C2_AUDIT) */ struct p_audit_data *p_audit_data; /* per process audit structure */ + + pctxop_t *p_pctx; + #if defined(__x86) /* * LDT support. @@ -551,7 +564,7 @@ extern void upcount_inc(uid_t, zoneid_t); extern void upcount_dec(uid_t, zoneid_t); extern int upcount_get(uid_t, zoneid_t); #if defined(__x86) -extern int ldt_dup(proc_t *, proc_t *); +extern void ldt_dup(proc_t *, proc_t *); extern selector_t setup_thrptr(proc_t *, uintptr_t); #endif @@ -644,6 +657,15 @@ extern void forkctx(kthread_t *, kthread_t *); extern void lwp_createctx(kthread_t *, kthread_t *); extern void exitctx(kthread_t *); extern void freectx(kthread_t *, int); +extern void installpctx(proc_t *, void *, void (*)(), void (*)(), + void (*)(), void (*)(), void (*)()); +extern int removepctx(proc_t *, void *, void (*)(), void (*)(), + void (*)(), void (*)(), void (*)()); +extern void savepctx(proc_t *); +extern void restorepctx(proc_t *); +extern void forkpctx(proc_t *, proc_t *); +extern void exitpctx(proc_t *); +extern void freepctx(proc_t *, int); extern kthread_t *thread_unpin(void); extern void thread_create_intr(struct cpu *); extern void thread_init(void); diff --git a/usr/src/uts/i86pc/ml/mpcore.s b/usr/src/uts/i86pc/ml/mpcore.s index cf64091917..1c1b84df15 100644 --- a/usr/src/uts/i86pc/ml/mpcore.s +++ b/usr/src/uts/i86pc/ml/mpcore.s @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -252,7 +252,7 @@ kernel_cs_code: movw $KTSS_SEL, %ax /* setup kernel TSS */ ltr %ax - movw $ULDT_SEL, %ax /* setup ldt */ + xorw %ax, %ax /* clear LDTR */ lldt %ax /* @@ -500,7 +500,7 @@ kernel_cs_code: movw $KTSS_SEL, %ax /* setup kernel TSS */ ltr %ax - movw $ULDT_SEL, %ax /* setup ldt */ + xorw %ax, %ax /* clear LDTR */ lldt %ax /* @@ -636,7 +636,7 @@ kernel_cs_code: movl TSS_ESP0(%esi),%esp movw $KTSS_SEL,%ax ltr %ax - movw $ULDT_SEL, %ax /* setup ldt */ + xorw %ax, %ax /* clear LDTR */ lldt %ax movl %cr0,%edx andl $-1![CR0_TS|CR0_EM],%edx /* clear emulate math chip bit */ @@ -719,7 +719,7 @@ kernel_cs_code: mov TSS_ESP0(%esi), %esp mov $(KTSS_SEL), %ax ltr %ax - mov $ULDT_SEL, %ax /* load user ldt */ + xorw %ax, %ax /* clear LDTR */ lldt %ax mov %cr0, %edx and $~(CR0_TS|CR0_EM), %edx /* clear emulate math chip bit */ diff --git a/usr/src/uts/i86pc/ml/offsets.in b/usr/src/uts/i86pc/ml/offsets.in index 4a1959a822..13ec19da05 100644 --- a/usr/src/uts/i86pc/ml/offsets.in +++ b/usr/src/uts/i86pc/ml/offsets.in @@ -1,5 +1,5 @@ \ -\ Copyright 2005 Sun Microsystems, Inc. All rights reserved. +\ Copyright 2006 Sun Microsystems, Inc. All rights reserved. \ Use is subject to license terms. \ \ CDDL HEADER START @@ -75,6 +75,7 @@ proc PROCSIZE p_ldt p_ldt_desc p_model + p_pctx p_agenttp _kthread THREAD_SIZE diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c index 5118e61495..02326001f2 100644 --- a/usr/src/uts/i86pc/os/mlsetup.c +++ b/usr/src/uts/i86pc/os/mlsetup.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -296,23 +296,12 @@ mlsetup(struct regs *rp) CPU->cpu_pri = 12; /* initial PIL for the boot CPU */ - CPU->cpu_ldt = ldt0_default; /* default LDT */ CPU->cpu_gdt = gdt0; /* - * This must be done _after_ init_tables(), called above, has set up - * ldt0_default_desc. + * The kernel doesn't use LDTs unless a process explicitly requests one. */ -#if defined(__amd64) - /* - * ldt0_default64 contains all invalid entries. We use that as p0's LDT - * because p0 should never have any reason to use the LDT. This will - * catch things early if such a scenario should ever occur. - */ - p0.p_ldt_desc = ldt0_default64_desc; -#else - p0.p_ldt_desc = ldt0_default_desc; -#endif /* __amd64 */ + p0.p_ldt_desc = zero_sdesc; /* * Kernel IDT. diff --git a/usr/src/uts/i86pc/os/trap.c b/usr/src/uts/i86pc/os/trap.c index 7016be0cb2..2287b59493 100644 --- a/usr/src/uts/i86pc/os/trap.c +++ b/usr/src/uts/i86pc/os/trap.c @@ -21,7 +21,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -993,14 +993,39 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid) if (kern_gpfault(rp)) (void) die(type, rp, addr, cpuid); goto cleanup; + /*FALLTHROUGH*/ +/* + * ONLY 32-bit PROCESSES can USE a PRIVATE LDT! 64-bit apps should have + * no legacy need for them, so we put a stop to it here. + * + * So: not-present fault is ONLY valid for 32-bit processes with a private LDT + * trying to do a system call. Emulate it. + * + * #gp fault is ONLY valid for 32-bit processes also, which DO NOT have private + * LDT, and are trying to do a system call. Emulate it. + */ case T_SEGFLT + USER: /* segment not present fault */ + case T_GPFLT + USER: /* general protection violation */ #ifdef _SYSCALL32_IMPL + if (p->p_model != DATAMODEL_NATIVE) { +#endif /* _SYSCALL32_IMPL */ if (instr_is_syscall((caddr_t)rp->r_pc)) { + if (type == T_SEGFLT + USER) + ASSERT(p->p_ldt != NULL); + + if ((p->p_ldt == NULL && type == T_GPFLT + USER) || + type == T_SEGFLT + USER) { + + /* + * The user attempted a system call via the obsolete + * call gate mechanism. Because the process doesn't have + * an LDT (i.e. the ldtr contains 0), a #gp results. + * Emulate the syscall here, just as we do above for a + * #np trap. + */ + /* - * System calls via the call gate come in through - * not-present traps. - * * Since this is a not-present trap, rp->r_pc points to * the trapping lcall instruction. We need to bump it * to the next insn so the app can continue on. @@ -1017,11 +1042,11 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid) dosyscall(); goto out; + } + } +#ifdef _SYSCALL32_IMPL } #endif /* _SYSCALL32_IMPL */ - /*FALLTHROUGH*/ - - case T_GPFLT + USER: /* general protection violation */ /* * If the current process is using a private LDT and the * trapping instruction is sysenter, the sysenter instruction diff --git a/usr/src/uts/i86pc/sys/machcpuvar.h b/usr/src/uts/i86pc/sys/machcpuvar.h index 50241f2303..9e355d4b49 100644 --- a/usr/src/uts/i86pc/sys/machcpuvar.h +++ b/usr/src/uts/i86pc/sys/machcpuvar.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -76,10 +76,8 @@ struct machcpu { /* i86 hardware table addresses that cannot be shared */ user_desc_t *mcpu_gdt; /* GDT */ gate_desc_t *mcpu_idt; /* IDT */ - struct tss *mcpu_tss; /* TSS */ - user_desc_t *mcpu_ldt; /* LDT XXX - needed? */ struct cpu_tables *mcpu_cp_tables; /* pointer to space acquired */ /* while starting up */ /* auxillary processors */ diff --git a/usr/src/uts/intel/ia32/ml/swtch.s b/usr/src/uts/intel/ia32/ml/swtch.s index 888d8a45ee..48103f954f 100644 --- a/usr/src/uts/intel/ia32/ml/swtch.s +++ b/usr/src/uts/intel/ia32/ml/swtch.s @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -216,22 +216,18 @@ resume(kthread_t *t) call savectx /* call ctx ops */ .nosavectx: - /* - * Setup LDT register - */ - movq T_PROCP(%r12), %rax /* load new thread proc */ + /* + * Call savepctx if process has installed context ops. + */ + movq T_PROCP(%r13), %r14 /* %r14 = proc */ + cmpq $0, P_PCTX(%r14) /* should current thread savectx? */ + je .nosavepctx /* skip call when zero */ - /* make sure GDT contains the right LDT desc */ - movq %gs:CPU_GDT, %r11 + movq %r14, %rdi /* arg = proc pointer */ + call savepctx /* call ctx ops */ +.nosavepctx: - movq P_LDT_DESC(%rax), %r10 - movq _CONST(P_LDT_DESC+8)(%rax), %rax - movq %r10, ULDT_SEL(%r11) - movq %rax, _CONST(ULDT_SEL+8)(%r11) - movl $ULDT_SEL, %edx - lldt %dx - - /* + /* * Temporarily switch to the idle thread's stack */ movq CPU_IDLE_THREAD(%r15), %rax /* idle thread pointer */ @@ -329,10 +325,19 @@ resume(kthread_t *t) jz .norestorectx /* skip call when zero */ movq %r12, %rdi /* arg = thread pointer */ call restorectx /* call ctx ops */ - .norestorectx: /* + * Call restorepctx if context ops have been installed for the proc. + */ + movq T_PROCP(%r12), %rcx + cmpq $0, P_PCTX(%rcx) + jz .norestorepctx + movq %rcx, %rdi + call restorepctx +.norestorepctx: + + /* * If we are resuming an interrupt thread, store a timestamp * in the thread structure. */ @@ -425,35 +430,28 @@ resume_return: addl $4, %esp /* restore stack pointer */ .nosavectx: - movl T_LWP(%esi), %ecx - pushl %ecx /* save fp address for later check */ - - /* - * Setup LDT register - */ - movl T_PROCP(%edi), %eax /* load new proc */ - - /* make sure GDT contains the right LDT desc */ - movl %gs:CPU_GDT, %ecx - - movl P_LDT_DESC(%eax), %edx - movl _CONST(P_LDT_DESC+4)(%eax), %eax - movl %edx, ULDT_SEL(%ecx) - movl %eax, _CONST(ULDT_SEL+4)(%ecx) - movl $ULDT_SEL, %edx - lldt %dx + /* + * Call savepctx if process has installed context ops. + */ + movl T_PROCP(%esi), %eax /* %eax = proc */ + cmpl $0, P_PCTX(%eax) /* should current thread savectx? */ + je .nosavepctx /* skip call when zero */ + pushl %eax /* arg = proc pointer */ + call savepctx /* call ctx ops */ + addl $4, %esp +.nosavepctx: /* * Temporarily switch to the idle thread's stack */ movl CPU_IDLE_THREAD(%ebx), %eax /* idle thread pointer */ - popl %ecx /* restore pointer to fp structure. */ /* * Set the idle thread as the current thread */ movl T_SP(%eax), %esp /* It is safe to set esp */ movl %eax, CPU_THREAD(%ebx) + movl T_LWP(%esi), %ecx /* load pointer to pcb_fpu */ movl %ecx, %ebx /* save pcb_fpu pointer in %ebx */ /* switch in the hat context for the new thread */ @@ -532,6 +530,17 @@ resume_return: .norestorectx: /* + * Call restorepctx if context ops have been installed for the proc. + */ + movl T_PROCP(%edi), %eax + cmpl $0, P_PCTX(%eax) + je .norestorepctx + pushl %eax /* arg = proc pointer */ + call restorepctx + addl $4, %esp /* restore stack pointer */ +.norestorepctx: + + /* * If we are resuming an interrupt thread, store a timestamp * in the thread structure. */ @@ -633,21 +642,6 @@ resume_from_zombie(kthread_t *t) movq %gs:CPU_THREAD, %r13 /* %r13 = curthread */ - /* - * Setup LDT register - */ - movq T_PROCP(%r12), %rax /* load new thread proc */ - - /* make sure GDT contains the right LDT desc */ - movq %gs:CPU_GDT, %r11 - - movq P_LDT_DESC(%rax), %r10 - movq _CONST(P_LDT_DESC+8)(%rax), %rax - movq %r10, ULDT_SEL(%r11) - movq %rax, _CONST(ULDT_SEL+8)(%r11) - movl $ULDT_SEL, %edx - lldt %dx - /* clean up the fp unit. It might be left enabled */ movq %cr0, %rax testq $CR0_TS, %rax @@ -723,21 +717,6 @@ resume_from_zombie_return: movl %gs:CPU_THREAD, %esi /* %esi = curthread */ - /* - * Setup LDT register - */ - movl T_PROCP(%edi), %ecx /* load new proc */ - - /* make sure GDT contains the right LDT desc */ - movl %gs:CPU_GDT, %eax - - movl P_LDT_DESC(%ecx), %edx - movl _CONST(P_LDT_DESC+4)(%ecx), %ecx - movl %edx, ULDT_SEL(%eax) - movl %ecx, _CONST(ULDT_SEL+4)(%eax) - movl $ULDT_SEL, %edx - lldt %dx - /* clean up the fp unit. It might be left enabled */ movl %cr0, %eax testl $CR0_TS, %eax diff --git a/usr/src/uts/intel/ia32/os/archdep.c b/usr/src/uts/intel/ia32/os/archdep.c index 943c713966..5a94720495 100644 --- a/usr/src/uts/intel/ia32/os/archdep.c +++ b/usr/src/uts/intel/ia32/os/archdep.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -633,7 +633,11 @@ fix_segreg(greg_t sr, model_t datamodel) } /* - * Force it into the LDT in ring 3 for 32-bit processes. + * Force it into the LDT in ring 3 for 32-bit processes, which by + * default do not have an LDT, so that any attempt to use an invalid + * selector will reference the (non-existant) LDT, and cause a #gp fault + * for the process. + * * 64-bit processes get the null gdt selector since they * are not allowed to have a private LDT. */ diff --git a/usr/src/uts/intel/ia32/os/desctbls.c b/usr/src/uts/intel/ia32/os/desctbls.c index 59b8d001de..4ce5312548 100644 --- a/usr/src/uts/intel/ia32/os/desctbls.c +++ b/usr/src/uts/intel/ia32/os/desctbls.c @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +56,7 @@ #include <sys/cmn_err.h> #include <sys/reboot.h> #include <sys/kdi.h> +#include <sys/systm.h> extern void syscall_int(void); @@ -66,16 +67,6 @@ extern void syscall_int(void); user_desc_t gdt0[NGDT]; /* global descriptor table */ desctbr_t gdt0_default_r; -#pragma align 16(ldt0_default) -user_desc_t ldt0_default[MINNLDT]; /* default local descriptor table */ -system_desc_t ldt0_default_desc; /* seg descriptor for ldt0_default */ - -#if defined(__amd64) -#pragma align 16(ltd0_default64) -user_desc_t ldt0_default64[MINNLDT]; /* default LDT for 64-bit apps */ -system_desc_t ldt0_default64_desc; /* seg descriptor for ldt0_default64 */ -#endif /* __amd64 */ - #pragma align 16(idt0) gate_desc_t idt0[NIDT]; /* interrupt descriptor table */ desctbr_t idt0_default_r; /* describes idt0 in IDTR format */ @@ -89,6 +80,7 @@ struct tss dftss0; /* #DF double-fault exception */ #endif /* __i386 */ user_desc_t zero_udesc; /* base zero user desc native procs */ +system_desc_t zero_sdesc; #if defined(__amd64) user_desc_t zero_u32desc; /* 32-bit compatibility procs */ @@ -347,18 +339,9 @@ init_gdt(void) SDP_PAGES, SDP_OP32); /* - * LDT descriptor for 64-bit processes - */ - set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default64, - sizeof (ldt0_default64) - 1, SDT_SYSLDT, SEL_KPL); - ldt0_default64_desc = *((system_desc_t *)&gdt0[GDT_LDT]); - - /* - * LDT descriptor for 32-bit processes + * The 64-bit kernel has no default LDT. By default, the LDT descriptor + * in the GDT is 0. */ - set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default, - sizeof (ldt0_default) - 1, SDT_SYSLDT, SEL_KPL); - ldt0_default_desc = *((system_desc_t *)&gdt0[GDT_LDT]); /* * Kernel TSS @@ -446,14 +429,6 @@ init_gdt(void) SDP_OP32); /* - * LDT for current process - */ - set_syssegd((system_desc_t *)&gdt0[GDT_LDT], ldt0_default, - sizeof (ldt0_default) - 1, SDT_SYSLDT, SEL_KPL); - - ldt0_default_desc = *((system_desc_t *)&gdt0[GDT_LDT]); - - /* * TSS for T_DBLFLT (double fault) handler */ set_syssegd((system_desc_t *)&gdt0[GDT_DBFLT], &dftss0, @@ -769,62 +744,18 @@ init_idt(void) #endif /* __i386 */ -#if defined(__amd64) - -static void -init_ldt(void) -{ - /* - * System calls using call gates from libc.a and libc.so.1 - * must cause a #NP fault and be processed in trap(). - * Therefore clear the "present" bit in the gate descriptor. - */ - - /* - * call gate for libc.a (obsolete) - */ - set_gatesegd((gate_desc_t *)&ldt0_default[LDT_SYSCALL], - (void (*)(void))&sys_lcall32, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); - ((gate_desc_t *)&ldt0_default[LDT_SYSCALL])->sgd_p = 0; - - /* - * i386 call gate for system calls from libc. - */ - set_gatesegd((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL], - (void (*)(void))&sys_lcall32, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); - ((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL])->sgd_p = 0; - - wr_ldtr(ULDT_SEL); -} - -#elif defined(__i386) - /* - * Note that the call gates for system calls ask the hardware to copy exactly - * one parameter onto the kernel stack for us; the parameter itself is not used. - * The real reason this is done is to make room for a snapshot of EFLAGS. See - * comment above sys_call() for details. + * The kernel does not deal with LDTs unless a user explicitly creates + * one. Under normal circumstances, the LDTR contains 0. Any process attempting + * to reference the LDT will therefore cause a #gp. System calls made via the + * obsolete lcall mechanism are emulated by the #gp fault handler. */ static void init_ldt(void) { - /* - * call gate for libc.a (obsolete) - */ - set_gatesegd((gate_desc_t *)&ldt0_default[LDT_SYSCALL], - (void (*)(void))&sys_call, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); - - /* - * i386 call gate for system calls from libc. - */ - set_gatesegd((gate_desc_t *)&ldt0_default[LDT_ALTSYSCALL], - (void (*)(void))&sys_call, KCS_SEL, 1, SDT_SYSCGT, SEL_UPL); - - wr_ldtr(ULDT_SEL); + wr_ldtr(0); } -#endif /* __i386 */ - #if defined(__amd64) static void diff --git a/usr/src/uts/intel/ia32/os/syscall.c b/usr/src/uts/intel/ia32/os/syscall.c index b53c04ff92..8176ddb908 100644 --- a/usr/src/uts/intel/ia32/os/syscall.c +++ b/usr/src/uts/intel/ia32/os/syscall.c @@ -21,7 +21,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -834,7 +834,6 @@ nosys() return (set_errno(ENOSYS)); } -#ifdef _SYSCALL32_IMPL /* * Execute a 32-bit system call on behalf of the current thread. */ @@ -868,7 +867,6 @@ dosyscall(void) syscall_exit(curthread, (int)ret & 0xffffffffu, (int)(ret >> 32)); syscall_mstate(LMS_SYSTEM, LMS_TRAP); } -#endif /* _SYSCALL32_IMPL */ /* * Get the arguments to the current system call. See comment atop diff --git a/usr/src/uts/intel/ia32/os/sysi86.c b/usr/src/uts/intel/ia32/os/sysi86.c index 24f3dec349..08b48234f7 100644 --- a/usr/src/uts/intel/ia32/os/sysi86.c +++ b/usr/src/uts/intel/ia32/os/sysi86.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -64,8 +64,9 @@ #include <sys/cmn_err.h> static int setdscr(caddr_t ap); -static void *setup_ldt(proc_t *pp); +static void setup_ldt(proc_t *pp); static void *ldt_map(proc_t *pp, uint_t seli); +static void ldt_free(proc_t *pp); extern void rtcsync(void); extern long ggmtl(void); @@ -305,12 +306,36 @@ ssd_to_sgd(struct ssd *ssd, gate_desc_t *sgd) #endif } -static void ldt_installctx(kthread_t *, kthread_t *); +/* + * Load LDT register with the current process's LDT. + */ +void +ldt_load(void) +{ + /* + */ + *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = curproc->p_ldt_desc; + wr_ldtr(ULDT_SEL); +} + +/* + * Store a NULL selector in the LDTR. All subsequent illegal references to + * the LDT will result in a #gp. + */ +void +ldt_unload(void) +{ + CPU->cpu_gdt[GDT_LDT] = zero_udesc; + wr_ldtr(0); +} /*ARGSUSED*/ static void -ldt_savectx(kthread_t *t) +ldt_savectx(proc_t *p) { + ASSERT(p->p_ldt != NULL); + ASSERT(p == curproc); + #if defined(__amd64) /* * The 64-bit kernel must be sure to clear any stale ldt @@ -332,57 +357,87 @@ ldt_savectx(kthread_t *t) clr_ldt_sregs(); #endif + ldt_unload(); cpu_fast_syscall_enable(NULL); } +static void +ldt_restorectx(proc_t *p) +{ + ASSERT(p->p_ldt != NULL); + ASSERT(p == curproc); + + ldt_load(); + cpu_fast_syscall_disable(NULL); +} + /* - * When a thread with a private LDT execs, fast syscalls must be enabled for the - * new process image. + * When a process with a private LDT execs, fast syscalls must be enabled for + * the new process image. */ /* ARGSUSED */ static void -ldt_freectx(kthread_t *t, int isexec) +ldt_freectx(proc_t *p, int isexec) { + ASSERT(p->p_ldt); + if (isexec) { kpreempt_disable(); cpu_fast_syscall_enable(NULL); kpreempt_enable(); } + + /* + * ldt_free() will free the memory used by the private LDT, reset the + * process's descriptor, and re-program the LDTR. + */ + ldt_free(p); } /* * Install ctx op that ensures syscall/sysenter are disabled. * See comments below. * - * When a thread with a private LDT creates a new LWP or forks, the new LWP + * When a thread with a private LDT forks, the new process * must have the LDT context ops installed. */ /* ARGSUSED */ static void -ldt_installctx(kthread_t *t, kthread_t *ct) +ldt_installctx(proc_t *p, proc_t *cp) { - kthread_t *targ = t; + proc_t *targ = p; + kthread_t *t; /* - * If this is a fork or an lwp_create, operate on the child thread. + * If this is a fork, operate on the child process. */ - if (ct != NULL) - targ = ct; + if (cp != NULL) { + targ = cp; + ldt_dup(p, cp); + } - ASSERT(removectx(targ, NULL, ldt_savectx, cpu_fast_syscall_disable, - ldt_installctx, ldt_installctx, cpu_fast_syscall_enable, - ldt_freectx) == 0); + /* + * The process context ops expect the target process as their argument. + */ + ASSERT(removepctx(targ, targ, ldt_savectx, ldt_restorectx, + ldt_installctx, ldt_savectx, ldt_freectx) == 0); - installctx(targ, NULL, ldt_savectx, cpu_fast_syscall_disable, - ldt_installctx, ldt_installctx, cpu_fast_syscall_enable, - ldt_freectx); + installpctx(targ, targ, ldt_savectx, ldt_restorectx, + ldt_installctx, ldt_savectx, ldt_freectx); /* * We've just disabled fast system call and return instructions; take * the slow path out to make sure we don't try to use one to return - * back to user. + * back to user. We must set t_post_sys for every thread in the + * process to make sure none of them escape out via fast return. */ - targ->t_post_sys = 1; + + mutex_enter(&targ->p_lock); + t = targ->p_tlist; + do { + t->t_post_sys = 1; + } while ((t = t->t_forw) != targ->p_tlist); + mutex_exit(&targ->p_lock); } static int @@ -392,7 +447,6 @@ setdscr(caddr_t ap) ushort_t seli; /* selector index */ user_desc_t *dscrp; /* descriptor pointer */ proc_t *pp = ttoproc(curthread); - kthread_t *t; if (get_udatamodel() == DATAMODEL_LP64) return (EINVAL); @@ -410,7 +464,7 @@ setdscr(caddr_t ap) * check the selector index. */ seli = SELTOIDX(ssd.sel); - if (seli >= MAXNLDT || seli <= LDT_UDBASE) + if (seli >= MAXNLDT || seli < LDT_UDBASE) return (EINVAL); mutex_enter(&pp->p_ldtlock); @@ -420,10 +474,8 @@ setdscr(caddr_t ap) * private LDT for it. */ if (pp->p_ldt == NULL) { - if (setup_ldt(pp) == NULL) { - mutex_exit(&pp->p_ldtlock); - return (ENOMEM); - } + kpreempt_disable(); + setup_ldt(pp); /* * Now that this process has a private LDT, the use of @@ -431,26 +483,21 @@ setdscr(caddr_t ap) * is forbidden for this processes because they destroy * the contents of %cs and %ss segment registers. * - * Explicity disable them here and add context handlers - * to all lwps in the process. Note that disabling + * Explicity disable them here and add a context handler + * to the process. Note that disabling * them here means we can't use sysret or sysexit on * the way out of this system call - so we force this * thread to take the slow path (which doesn't make use * of sysenter or sysexit) back out. */ - mutex_enter(&pp->p_lock); - t = pp->p_tlist; - do { - ldt_installctx(t, NULL); - } while ((t = t->t_forw) != pp->p_tlist); - mutex_exit(&pp->p_lock); + ldt_installctx(pp, NULL); - kpreempt_disable(); cpu_fast_syscall_disable(NULL); - kpreempt_enable(); + ASSERT(curthread->t_post_sys != 0); wr_ldtr(ULDT_SEL); + kpreempt_enable(); } if (ldt_map(pp, seli) == NULL) { @@ -604,9 +651,9 @@ setdscr(caddr_t ap) /* * Allocate a private LDT for this process and initialize it with the - * default entries. Returns 0 for errors, pointer to LDT for success. + * default entries. */ -static void * +void setup_ldt(proc_t *pp) { user_desc_t *ldtp; /* descriptor pointer */ @@ -620,17 +667,10 @@ setup_ldt(proc_t *pp) /* * Allocate the minimum number of physical pages for LDT. */ - if (segkmem_xalloc(NULL, ldtp, MINNLDT * sizeof (user_desc_t), - VM_SLEEP, 0, segkmem_page_create, NULL) == NULL) { - vmem_free(heap_arena, ldtp, ptob(npages)); - return (0); - } - bzero(ldtp, ptob(btopr(MINNLDT * sizeof (user_desc_t)))); + (void) segkmem_xalloc(NULL, ldtp, MINNLDT * sizeof (user_desc_t), + VM_SLEEP, 0, segkmem_page_create, NULL); - /* - * Copy the default LDT entries into the new table. - */ - bcopy(ldt0_default, ldtp, MINNLDT * sizeof (user_desc_t)); + bzero(ldtp, ptob(btopr(MINNLDT * sizeof (user_desc_t)))); kpreempt_disable(); @@ -645,22 +685,6 @@ setup_ldt(proc_t *pp) *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = pp->p_ldt_desc; kpreempt_enable(); - - return (ldtp); -} - -/* - * Load LDT register with the current process's LDT. - */ -void -ldt_load(void) -{ - proc_t *p = curthread->t_procp; - - ASSERT(curthread->t_preempt != 0); - - *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = p->p_ldt_desc; - wr_ldtr(ULDT_SEL); } /* @@ -691,11 +715,8 @@ ldt_map(proc_t *pp, uint_t seli) if (!on_trap(&otd, OT_DATA_ACCESS)) (void) *(volatile int *)page; /* peek at the page */ else { /* Allocate a physical page */ - if (segkmem_xalloc(NULL, page, PAGESIZE, VM_SLEEP, 0, - segkmem_page_create, NULL) == NULL) { - no_trap(); - return (NULL); - } + (void) segkmem_xalloc(NULL, page, PAGESIZE, VM_SLEEP, 0, + segkmem_page_create, NULL); bzero(page, PAGESIZE); } no_trap(); @@ -719,7 +740,7 @@ ldt_map(proc_t *pp, uint_t seli) /* * Free up the kernel memory used for LDT of this process. */ -void +static void ldt_free(proc_t *pp) { on_trap_data_t otd; @@ -747,9 +768,11 @@ ldt_free(proc_t *pp) ptob(btopr(MAXNLDT * sizeof (user_desc_t)))); kpreempt_disable(); pp->p_ldt = NULL; - pp->p_ldt_desc = ldt0_default_desc; + pp->p_ldt_desc = zero_sdesc; + pp->p_ldtlimit = 0; + if (pp == curproc) - ldt_load(); + ldt_unload(); kpreempt_enable(); mutex_exit(&pp->p_ldtlock); } @@ -757,7 +780,7 @@ ldt_free(proc_t *pp) /* * On fork copy new ldt for child. */ -int +void ldt_dup(proc_t *pp, proc_t *cp) { on_trap_data_t otd; @@ -765,14 +788,9 @@ ldt_dup(proc_t *pp, proc_t *cp) volatile caddr_t addr, caddr; int minsize; - if (pp->p_ldt == NULL) { - cp->p_ldt_desc = ldt0_default_desc; - return (0); - } + ASSERT(pp->p_ldt); - if (setup_ldt(cp) == NULL) { - return (ENOMEM); - } + setup_ldt(cp); mutex_enter(&pp->p_ldtlock); cp->p_ldtlimit = pp->p_ldtlimit; @@ -789,19 +807,12 @@ ldt_dup(proc_t *pp, proc_t *cp) (void) *(volatile int *)addr; /* peek at the address */ /* allocate a page if necessary */ if (caddr >= ((caddr_t)cp->p_ldt + minsize)) { - if (segkmem_xalloc(NULL, caddr, PAGESIZE, - VM_SLEEP, 0, segkmem_page_create, NULL) == - NULL) { - no_trap(); - ldt_free(cp); - mutex_exit(&pp->p_ldtlock); - return (ENOMEM); - } + (void) segkmem_xalloc(NULL, caddr, PAGESIZE, + VM_SLEEP, 0, segkmem_page_create, NULL); } bcopy(addr, caddr, PAGESIZE); } } no_trap(); mutex_exit(&pp->p_ldtlock); - return (0); } diff --git a/usr/src/uts/intel/sys/segments.h b/usr/src/uts/intel/sys/segments.h index 0578a6f7fd..3045d533a2 100644 --- a/usr/src/uts/intel/sys/segments.h +++ b/usr/src/uts/intel/sys/segments.h @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -528,13 +528,10 @@ extern gate_desc_t idt0[NIDT]; extern desctbr_t idt0_default_reg; #pragma align 16(gdt0) extern user_desc_t gdt0[NGDT]; -#pragma align 16(ldt0_default) -extern user_desc_t ldt0_default[MINNLDT]; -extern system_desc_t ldt0_default_desc; -#pragma align 16(ldt0_default64) -extern user_desc_t ldt0_default64[MINNLDT]; -extern system_desc_t ldt0_default64_desc; + extern user_desc_t zero_udesc; +extern system_desc_t zero_sdesc; + #if defined(__amd64) extern user_desc_t zero_u32desc; #endif |