Merge commit 'b6031810da58df96413bf76e068638fcab1f228a'
[unleashed.git] / arch / x86 / kernel / os / sysi86.c
blob536117fc82725300daa1898677a957788e3c8e6d
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Joyent, Inc.
26 /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
28 /* All Rights Reserved */
30 /* Copyright (c) 1987, 1988 Microsoft Corporation */
31 /* All Rights Reserved */
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/sysmacros.h>
36 #include <sys/systm.h>
37 #include <sys/signal.h>
38 #include <sys/errno.h>
39 #include <sys/fault.h>
40 #include <sys/syscall.h>
41 #include <sys/cpuvar.h>
42 #include <sys/sysi86.h>
43 #include <sys/psw.h>
44 #include <sys/cred.h>
45 #include <sys/policy.h>
46 #include <sys/thread.h>
47 #include <sys/debug.h>
48 #include <sys/ontrap.h>
49 #include <sys/privregs.h>
50 #include <sys/x86_archext.h>
51 #include <sys/vmem.h>
52 #include <sys/kmem.h>
53 #include <sys/mman.h>
54 #include <sys/archsystm.h>
55 #include <vm/hat.h>
56 #include <vm/as.h>
57 #include <vm/seg.h>
58 #include <vm/seg_kmem.h>
59 #include <vm/faultcode.h>
60 #include <sys/fp.h>
61 #include <sys/cmn_err.h>
62 #include <sys/segments.h>
63 #include <sys/clock.h>
64 #include <vm/hat_i86.h>
66 static void ldt_alloc(proc_t *, uint_t);
67 static void ldt_free(proc_t *);
68 static void ldt_dup(proc_t *, proc_t *);
69 static void ldt_grow(proc_t *, uint_t);
72 * sysi86 System Call
75 /* ARGSUSED */
76 int
77 sysi86(short cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
79 struct ssd ssd;
80 int error = 0;
81 int c;
82 proc_t *pp = curproc;
84 switch (cmd) {
87 * The SI86V86 subsystem call of the SYSI86 system call
88 * supports only one subcode -- V86SC_IOPL.
90 case SI86V86:
91 if (arg1 == V86SC_IOPL) {
92 struct regs *rp = lwptoregs(ttolwp(curthread));
93 greg_t oldpl = rp->r_ps & PS_IOPL;
94 greg_t newpl = arg2 & PS_IOPL;
97 * Must be privileged to run this system call
98 * if giving more io privilege.
100 if (newpl > oldpl && (error =
101 secpolicy_sys_config(CRED(), B_FALSE)) != 0)
102 return (set_errno(error));
103 rp->r_ps ^= oldpl ^ newpl;
104 } else
105 error = EINVAL;
106 break;
109 * Set a segment descriptor
111 case SI86DSCR:
113 * There are considerable problems here manipulating
114 * resources shared by many running lwps. Get everyone
115 * into a safe state before changing the LDT.
117 if (curthread != pp->p_agenttp && !holdlwps(SHOLDFORK1)) {
118 error = EINTR;
119 break;
122 if (get_udatamodel() == DATAMODEL_LP64) {
123 error = EINVAL;
124 break;
127 if (copyin((caddr_t)arg1, &ssd, sizeof (ssd)) < 0) {
128 error = EFAULT;
129 break;
132 error = setdscr(&ssd);
134 mutex_enter(&pp->p_lock);
135 if (curthread != pp->p_agenttp)
136 continuelwps(pp);
137 mutex_exit(&pp->p_lock);
138 break;
140 case SI86FPHW:
141 c = fp_kind & 0xff;
142 if (suword32((void *)arg1, c) == -1)
143 error = EFAULT;
144 break;
146 case SI86FPSTART:
148 * arg1 is the address of _fp_hw
149 * arg2 is the desired x87 FCW value
150 * arg3 is the desired SSE MXCSR value
151 * a return value of one means SSE hardware, else none.
153 c = fp_kind & 0xff;
154 if (suword32((void *)arg1, c) == -1) {
155 error = EFAULT;
156 break;
158 fpsetcw((uint16_t)arg2, (uint32_t)arg3);
159 return ((fp_kind & __FP_SSE) ? 1 : 0);
161 /* real time clock management commands */
163 case WTODC:
164 if ((error = secpolicy_settime(CRED())) == 0) {
165 timestruc_t ts;
166 mutex_enter(&tod_lock);
167 gethrestime(&ts);
168 tod_set(ts);
169 mutex_exit(&tod_lock);
171 break;
173 /* Give some timezone playing room */
174 #define ONEWEEK (7 * 24 * 60 * 60)
176 case SGMTL:
178 * Called from 32 bit land, negative values
179 * are not sign extended, so we do that here
180 * by casting it to an int and back. We also
181 * clamp the value to within reason and detect
182 * when a 64 bit call overflows an int.
184 if ((error = secpolicy_settime(CRED())) == 0) {
185 int newlag = (int)arg1;
187 #ifdef _SYSCALL32_IMPL
188 if (get_udatamodel() == DATAMODEL_NATIVE &&
189 (long)newlag != (long)arg1) {
190 error = EOVERFLOW;
191 } else
192 #endif
193 if (newlag >= -ONEWEEK && newlag <= ONEWEEK)
194 sgmtl(newlag);
195 else
196 error = EOVERFLOW;
198 break;
200 case GGMTL:
201 if (get_udatamodel() == DATAMODEL_NATIVE) {
202 if (sulword((void *)arg1, ggmtl()) == -1)
203 error = EFAULT;
204 #ifdef _SYSCALL32_IMPL
205 } else {
206 time_t gmtl;
208 if ((gmtl = ggmtl()) > INT32_MAX) {
210 * Since gmt_lag can at most be
211 * +/- 12 hours, something is
212 * *seriously* messed up here.
214 error = EOVERFLOW;
215 } else if (suword32((void *)arg1, (int32_t)gmtl) == -1)
216 error = EFAULT;
217 #endif
219 break;
221 case RTCSYNC:
222 if ((error = secpolicy_settime(CRED())) == 0)
223 rtcsync();
224 break;
226 /* END OF real time clock management commands */
228 default:
229 error = EINVAL;
230 break;
232 return (error == 0 ? 0 : set_errno(error));
235 void
236 usd_to_ssd(user_desc_t *usd, struct ssd *ssd, selector_t sel)
238 ssd->bo = USEGD_GETBASE(usd);
239 ssd->ls = USEGD_GETLIMIT(usd);
240 ssd->sel = sel;
243 * set type, dpl and present bits.
245 ssd->acc1 = usd->usd_type;
246 ssd->acc1 |= usd->usd_dpl << 5;
247 ssd->acc1 |= usd->usd_p << (5 + 2);
250 * set avl, DB and granularity bits.
252 ssd->acc2 = usd->usd_avl;
254 #if defined(__amd64)
255 ssd->acc2 |= usd->usd_long << 1;
256 #else
257 ssd->acc2 |= usd->usd_reserved << 1;
258 #endif
260 ssd->acc2 |= usd->usd_def32 << (1 + 1);
261 ssd->acc2 |= usd->usd_gran << (1 + 1 + 1);
264 static void
265 ssd_to_usd(struct ssd *ssd, user_desc_t *usd)
268 ASSERT(bcmp(usd, &null_udesc, sizeof (*usd)) == 0);
270 USEGD_SETBASE(usd, ssd->bo);
271 USEGD_SETLIMIT(usd, ssd->ls);
274 * Set type, dpl and present bits.
276 * Force the "accessed" bit to on so that we don't run afoul of
277 * KPTI.
279 usd->usd_type = ssd->acc1 | SDT_A;
280 usd->usd_dpl = ssd->acc1 >> 5;
281 usd->usd_p = ssd->acc1 >> (5 + 2);
283 ASSERT(usd->usd_type >= SDT_MEMRO);
284 ASSERT(usd->usd_dpl == SEL_UPL);
287 * 64-bit code selectors are never allowed in the LDT.
288 * Reserved bit is always 0 on 32-bit systems.
290 #if defined(__amd64)
291 usd->usd_long = 0;
292 #else
293 usd->usd_reserved = 0;
294 #endif
297 * set avl, DB and granularity bits.
299 usd->usd_avl = ssd->acc2;
300 usd->usd_def32 = ssd->acc2 >> (1 + 1);
301 usd->usd_gran = ssd->acc2 >> (1 + 1 + 1);
305 #if defined(__i386)
307 static void
308 ssd_to_sgd(struct ssd *ssd, gate_desc_t *sgd)
311 ASSERT(bcmp(sgd, &null_sdesc, sizeof (*sgd)) == 0);
313 sgd->sgd_looffset = ssd->bo;
314 sgd->sgd_hioffset = ssd->bo >> 16;
316 sgd->sgd_selector = ssd->ls;
319 * set type, dpl and present bits.
321 sgd->sgd_type = ssd->acc1;
322 sgd->sgd_dpl = ssd->acc1 >> 5;
323 sgd->sgd_p = ssd->acc1 >> 7;
324 ASSERT(sgd->sgd_type == SDT_SYSCGT);
325 ASSERT(sgd->sgd_dpl == SEL_UPL);
326 sgd->sgd_stkcpy = 0;
329 #endif /* __i386 */
332 * Load LDT register with the current process's LDT.
334 static void
335 ldt_load(void)
337 size_t len;
338 system_desc_t desc;
341 * Before we can use the LDT on this CPU, we must install the LDT in the
342 * user mapping table.
344 len = (curproc->p_ldtlimit + 1) * sizeof (user_desc_t);
345 bcopy(curproc->p_ldt, CPU->cpu_m.mcpu_ldt, len);
346 CPU->cpu_m.mcpu_ldt_len = len;
347 set_syssegd(&desc, CPU->cpu_m.mcpu_ldt, len - 1, SDT_SYSLDT, SEL_KPL);
348 *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = desc;
350 wr_ldtr(ULDT_SEL);
354 * Store a NULL selector in the LDTR. All subsequent illegal references to
355 * the LDT will result in a #gp.
357 void
358 ldt_unload(void)
360 *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = null_sdesc;
361 wr_ldtr(0);
363 bzero(CPU->cpu_m.mcpu_ldt, CPU->cpu_m.mcpu_ldt_len);
364 CPU->cpu_m.mcpu_ldt_len = 0;
367 /*ARGSUSED*/
368 static void
369 ldt_savectx(proc_t *p)
371 ASSERT(p->p_ldt != NULL);
372 ASSERT(p == curproc);
374 #if defined(__amd64)
376 * The 64-bit kernel must be sure to clear any stale ldt
377 * selectors when context switching away from a process that
378 * has a private ldt. Consider the following example:
380 * Wine creats a ldt descriptor and points a segment register
381 * to it.
383 * We then context switch away from wine lwp to kernel
384 * thread and hit breakpoint in kernel with kmdb
386 * When we continue and resume from kmdb we will #gp
387 * fault since kmdb will have saved the stale ldt selector
388 * from wine and will try to restore it but we are no longer in
389 * the context of the wine process and do not have our
390 * ldtr register pointing to the private ldt.
392 reset_sregs();
393 #endif
395 ldt_unload();
396 cpu_fast_syscall_enable();
399 static void
400 ldt_restorectx(proc_t *p)
402 ASSERT(p->p_ldt != NULL);
403 ASSERT(p == curproc);
405 ldt_load();
406 cpu_fast_syscall_disable();
410 * At exec time, we need to clear up our LDT context and re-enable fast syscalls
411 * for the new process image.
413 * The same is true for the other case, where we have:
415 * proc_exit()
416 * ->exitpctx()->ldt_savectx()
417 * ->freepctx()->ldt_freectx()
419 * Because pre-emption is not prevented between the two callbacks, we could have
420 * come off CPU, and brought back LDT context when coming back on CPU via
421 * ldt_restorectx().
423 /* ARGSUSED */
424 static void
425 ldt_freectx(proc_t *p, int isexec)
427 ASSERT(p->p_ldt != NULL);
428 ASSERT(p == curproc);
430 kpreempt_disable();
431 ldt_free(p);
432 cpu_fast_syscall_enable();
433 kpreempt_enable();
437 * Install ctx op that ensures syscall/sysenter are disabled.
438 * See comments below.
440 * When a thread with a private LDT forks, the new process
441 * must have the LDT context ops installed.
443 /* ARGSUSED */
444 static void
445 ldt_installctx(proc_t *p, proc_t *cp)
447 proc_t *targ = p;
448 kthread_t *t;
451 * If this is a fork, operate on the child process.
453 if (cp != NULL) {
454 targ = cp;
455 ldt_dup(p, cp);
459 * The process context ops expect the target process as their argument.
461 ASSERT(removepctx(targ, targ, ldt_savectx, ldt_restorectx,
462 ldt_installctx, ldt_savectx, ldt_freectx) == 0);
464 installpctx(targ, targ, ldt_savectx, ldt_restorectx,
465 ldt_installctx, ldt_savectx, ldt_freectx);
468 * We've just disabled fast system call and return instructions; take
469 * the slow path out to make sure we don't try to use one to return
470 * back to user. We must set t_post_sys for every thread in the
471 * process to make sure none of them escape out via fast return.
474 mutex_enter(&targ->p_lock);
475 t = targ->p_tlist;
476 do {
477 t->t_post_sys = 1;
478 } while ((t = t->t_forw) != targ->p_tlist);
479 mutex_exit(&targ->p_lock);
483 setdscr(struct ssd *ssd)
485 ushort_t seli; /* selector index */
486 user_desc_t *ldp; /* descriptor pointer */
487 user_desc_t ndesc; /* new descriptor */
488 proc_t *pp = curproc;
489 int rc = 0;
492 * LDT segments: executable and data at DPL 3 only.
494 if (!SELISLDT(ssd->sel) || !SELISUPL(ssd->sel))
495 return (EINVAL);
498 * check the selector index.
500 seli = SELTOIDX(ssd->sel);
501 if (seli >= MAXNLDT || seli < LDT_UDBASE)
502 return (EINVAL);
504 ndesc = null_udesc;
505 mutex_enter(&pp->p_ldtlock);
508 * If this is the first time for this process then setup a
509 * private LDT for it.
511 if (pp->p_ldt == NULL) {
512 ldt_alloc(pp, seli);
515 * Now that this process has a private LDT, the use of
516 * the syscall/sysret and sysenter/sysexit instructions
517 * is forbidden for this processes because they destroy
518 * the contents of %cs and %ss segment registers.
520 * Explicity disable them here and add a context handler
521 * to the process. Note that disabling
522 * them here means we can't use sysret or sysexit on
523 * the way out of this system call - so we force this
524 * thread to take the slow path (which doesn't make use
525 * of sysenter or sysexit) back out.
527 kpreempt_disable();
528 ldt_installctx(pp, NULL);
529 cpu_fast_syscall_disable();
530 ASSERT(curthread->t_post_sys != 0);
531 kpreempt_enable();
533 } else if (seli > pp->p_ldtlimit) {
534 ASSERT(pp->p_pctx != NULL);
537 * Increase size of ldt to include seli.
539 ldt_grow(pp, seli);
542 ASSERT(seli <= pp->p_ldtlimit);
543 ldp = &pp->p_ldt[seli];
546 * On the 64-bit kernel, this is where things get more subtle.
547 * Recall that in the 64-bit kernel, when we enter the kernel we
548 * deliberately -don't- reload the segment selectors we came in on
549 * for %ds, %es, %fs or %gs. Messing with selectors is expensive,
550 * and the underlying descriptors are essentially ignored by the
551 * hardware in long mode - except for the base that we override with
552 * the gsbase MSRs.
554 * However, there's one unfortunate issue with this rosy picture --
555 * a descriptor that's not marked as 'present' will still generate
556 * an #np when loading a segment register.
558 * Consider this case. An lwp creates a harmless LDT entry, points
559 * one of it's segment registers at it, then tells the kernel (here)
560 * to delete it. In the 32-bit kernel, the #np will happen on the
561 * way back to userland where we reload the segment registers, and be
562 * handled in kern_gpfault(). In the 64-bit kernel, the same thing
563 * will happen in the normal case too. However, if we're trying to
564 * use a debugger that wants to save and restore the segment registers,
565 * and the debugger things that we have valid segment registers, we
566 * have the problem that the debugger will try and restore the
567 * segment register that points at the now 'not present' descriptor
568 * and will take a #np right there.
570 * We should obviously fix the debugger to be paranoid about
571 * -not- restoring segment registers that point to bad descriptors;
572 * however we can prevent the problem here if we check to see if any
573 * of the segment registers are still pointing at the thing we're
574 * destroying; if they are, return an error instead. (That also seems
575 * a lot better failure mode than SIGKILL and a core file
576 * from kern_gpfault() too.)
578 if (SI86SSD_PRES(ssd) == 0) {
579 kthread_t *t;
580 int bad = 0;
583 * Look carefully at the segment registers of every lwp
584 * in the process (they're all stopped by our caller).
585 * If we're about to invalidate a descriptor that's still
586 * being referenced by *any* of them, return an error,
587 * rather than having them #gp on their way out of the kernel.
589 ASSERT(pp->p_lwprcnt == 1);
591 mutex_enter(&pp->p_lock);
592 t = pp->p_tlist;
593 do {
594 klwp_t *lwp = ttolwp(t);
595 struct regs *rp = lwp->lwp_regs;
596 #if defined(__amd64)
597 pcb_t *pcb = &lwp->lwp_pcb;
598 #endif
600 if (ssd->sel == rp->r_cs || ssd->sel == rp->r_ss) {
601 bad = 1;
602 break;
605 #if defined(__amd64)
606 if (pcb->pcb_rupdate == 1) {
607 if (ssd->sel == pcb->pcb_ds ||
608 ssd->sel == pcb->pcb_es ||
609 ssd->sel == pcb->pcb_fs ||
610 ssd->sel == pcb->pcb_gs) {
611 bad = 1;
612 break;
614 } else
615 #endif
617 if (ssd->sel == rp->r_ds ||
618 ssd->sel == rp->r_es ||
619 ssd->sel == rp->r_fs ||
620 ssd->sel == rp->r_gs) {
621 bad = 1;
622 break;
626 } while ((t = t->t_forw) != pp->p_tlist);
627 mutex_exit(&pp->p_lock);
629 if (bad) {
630 mutex_exit(&pp->p_ldtlock);
631 return (EBUSY);
636 * If acc1 is zero, clear the descriptor (including the 'present' bit).
637 * Make sure we update the CPU-private copy of the LDT.
639 if (ssd->acc1 == 0) {
640 rc = ldt_update_segd(ldp, &null_udesc);
641 kpreempt_disable();
642 ldt_load();
643 kpreempt_enable();
644 mutex_exit(&pp->p_ldtlock);
645 return (rc);
649 * Check segment type, allow segment not present and
650 * only user DPL (3).
652 if (SI86SSD_DPL(ssd) != SEL_UPL) {
653 mutex_exit(&pp->p_ldtlock);
654 return (EINVAL);
658 * Do not allow 32-bit applications to create 64-bit mode code
659 * segments.
661 if (SI86SSD_ISUSEG(ssd) && ((SI86SSD_TYPE(ssd) >> 3) & 1) == 1 &&
662 SI86SSD_ISLONG(ssd)) {
663 mutex_exit(&pp->p_ldtlock);
664 return (EINVAL);
668 * Set up a code or data user segment descriptor, making sure to update
669 * the CPU-private copy of the LDT.
671 if (SI86SSD_ISUSEG(ssd)) {
672 ssd_to_usd(ssd, &ndesc);
673 rc = ldt_update_segd(ldp, &ndesc);
674 kpreempt_disable();
675 ldt_load();
676 kpreempt_enable();
677 mutex_exit(&pp->p_ldtlock);
678 return (rc);
681 mutex_exit(&pp->p_ldtlock);
682 return (EINVAL);
686 * Allocate new LDT for process just large enough to contain seli. Note we
687 * allocate and grow LDT in PAGESIZE chunks. We do this to simplify the
688 * implementation and because on the hypervisor it's required, since the LDT
689 * must live on pages that have PROT_WRITE removed and which are given to the
690 * hypervisor.
692 * Note that we don't actually load the LDT into the current CPU here: it's done
693 * later by our caller.
695 static void
696 ldt_alloc(proc_t *pp, uint_t seli)
698 user_desc_t *ldt;
699 size_t ldtsz;
700 uint_t nsels;
702 ASSERT(MUTEX_HELD(&pp->p_ldtlock));
703 ASSERT(pp->p_ldt == NULL);
704 ASSERT(pp->p_ldtlimit == 0);
707 * Allocate new LDT just large enough to contain seli. The LDT must
708 * always be allocated in units of pages for KPTI.
710 ldtsz = P2ROUNDUP((seli + 1) * sizeof (user_desc_t), PAGESIZE);
711 nsels = ldtsz / sizeof (user_desc_t);
712 ASSERT(nsels >= MINNLDT && nsels <= MAXNLDT);
714 ldt = kmem_zalloc(ldtsz, KM_SLEEP);
715 ASSERT(IS_P2ALIGNED(ldt, PAGESIZE));
718 pp->p_ldt = ldt;
719 pp->p_ldtlimit = nsels - 1;
722 static void
723 ldt_free(proc_t *pp)
725 user_desc_t *ldt;
726 size_t ldtsz;
728 ASSERT(pp->p_ldt != NULL);
730 mutex_enter(&pp->p_ldtlock);
731 ldt = pp->p_ldt;
732 ldtsz = (pp->p_ldtlimit + 1) * sizeof (user_desc_t);
734 ASSERT(IS_P2ALIGNED(ldtsz, PAGESIZE));
736 pp->p_ldt = NULL;
737 pp->p_ldtlimit = 0;
738 mutex_exit(&pp->p_ldtlock);
740 if (pp == curproc) {
741 kpreempt_disable();
742 ldt_unload();
743 kpreempt_enable();
747 kmem_free(ldt, ldtsz);
751 * On fork copy new ldt for child.
753 static void
754 ldt_dup(proc_t *pp, proc_t *cp)
756 size_t ldtsz;
758 ASSERT(pp->p_ldt != NULL);
759 ASSERT(cp != curproc);
762 * I assume the parent's ldt can't increase since we're in a fork.
764 mutex_enter(&pp->p_ldtlock);
765 mutex_enter(&cp->p_ldtlock);
767 ldtsz = (pp->p_ldtlimit + 1) * sizeof (user_desc_t);
769 ldt_alloc(cp, pp->p_ldtlimit);
772 bcopy(pp->p_ldt, cp->p_ldt, ldtsz);
774 mutex_exit(&cp->p_ldtlock);
775 mutex_exit(&pp->p_ldtlock);
780 * Note that we don't actually load the LDT into the current CPU here: it's done
781 * later by our caller - unless we take an error. This works out because
782 * ldt_load() does a copy of ->p_ldt instead of directly loading it into the GDT
783 * (and therefore can't be using the freed old LDT), and by definition if the
784 * new entry didn't pass validation, then the proc shouldn't be referencing an
785 * entry in the extended region.
787 static void
788 ldt_grow(proc_t *pp, uint_t seli)
790 user_desc_t *oldt, *nldt;
791 uint_t nsels;
792 size_t oldtsz, nldtsz;
794 ASSERT(MUTEX_HELD(&pp->p_ldtlock));
795 ASSERT(pp->p_ldt != NULL);
796 ASSERT(pp->p_ldtlimit != 0);
799 * Allocate larger LDT just large enough to contain seli. The LDT must
800 * always be allocated in units of pages for KPTI.
802 nldtsz = P2ROUNDUP((seli + 1) * sizeof (user_desc_t), PAGESIZE);
803 nsels = nldtsz / sizeof (user_desc_t);
804 ASSERT(nsels >= MINNLDT && nsels <= MAXNLDT);
805 ASSERT(nsels > pp->p_ldtlimit);
807 oldt = pp->p_ldt;
808 oldtsz = (pp->p_ldtlimit + 1) * sizeof (user_desc_t);
810 nldt = kmem_zalloc(nldtsz, KM_SLEEP);
811 ASSERT(IS_P2ALIGNED(nldt, PAGESIZE));
813 bcopy(oldt, nldt, oldtsz);
816 * unload old ldt.
818 kpreempt_disable();
819 ldt_unload();
820 kpreempt_enable();
823 pp->p_ldt = nldt;
824 pp->p_ldtlimit = nsels - 1;
826 kmem_free(oldt, oldtsz);