3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
27 /* All Rights Reserved */
28
29 /* Copyright (c) 1987, 1988 Microsoft Corporation */
30 /* All Rights Reserved */
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <sys/systm.h>
36 #include <sys/signal.h>
37 #include <sys/errno.h>
38 #include <sys/fault.h>
39 #include <sys/syscall.h>
40 #include <sys/cpuvar.h>
41 #include <sys/sysi86.h>
42 #include <sys/psw.h>
43 #include <sys/cred.h>
44 #include <sys/policy.h>
45 #include <sys/thread.h>
46 #include <sys/debug.h>
47 #include <sys/ontrap.h>
48 #include <sys/privregs.h>
49 #include <sys/x86_archext.h>
50 #include <sys/vmem.h>
51 #include <sys/kmem.h>
52 #include <sys/mman.h>
53 #include <sys/archsystm.h>
54 #include <vm/hat.h>
55 #include <vm/as.h>
56 #include <vm/seg.h>
57 #include <vm/seg_kmem.h>
58 #include <vm/faultcode.h>
59 #include <sys/fp.h>
60 #include <sys/cmn_err.h>
61 #include <sys/segments.h>
62 #include <sys/clock.h>
63 #if defined(__xpv)
64 #include <sys/hypervisor.h>
65 #include <sys/note.h>
66 #endif
67
68 static void ldt_alloc(proc_t *, uint_t);
69 static void ldt_free(proc_t *);
70 static void ldt_dup(proc_t *, proc_t *);
71 static void ldt_grow(proc_t *, uint_t);
72
73 /*
74 * sysi86 System Call
75 */
76
77 /* ARGSUSED */
78 int
79 sysi86(short cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
80 {
81 struct ssd ssd;
82 int error = 0;
329 sgd->sgd_type = ssd->acc1;
330 sgd->sgd_dpl = ssd->acc1 >> 5;
331 sgd->sgd_p = ssd->acc1 >> 7;
332 ASSERT(sgd->sgd_type == SDT_SYSCGT);
333 ASSERT(sgd->sgd_dpl == SEL_UPL);
334 sgd->sgd_stkcpy = 0;
335 }
336
337 #endif /* __i386 */
338
339 /*
340 * Load LDT register with the current process's LDT.
341 */
342 static void
343 ldt_load(void)
344 {
345 #if defined(__xpv)
346 xen_set_ldt(get_ssd_base(&curproc->p_ldt_desc),
347 curproc->p_ldtlimit + 1);
348 #else
349 *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = curproc->p_ldt_desc;
350 wr_ldtr(ULDT_SEL);
351 #endif
352 }
353
354 /*
355 * Store a NULL selector in the LDTR. All subsequent illegal references to
356 * the LDT will result in a #gp.
357 */
358 void
359 ldt_unload(void)
360 {
361 #if defined(__xpv)
362 xen_set_ldt(NULL, 0);
363 #else
364 *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = null_sdesc;
365 wr_ldtr(0);
366 #endif
367 }
368
369 /*ARGSUSED*/
370 static void
371 ldt_savectx(proc_t *p)
372 {
373 ASSERT(p->p_ldt != NULL);
374 ASSERT(p == curproc);
375
376 #if defined(__amd64)
377 /*
378 * The 64-bit kernel must be sure to clear any stale ldt
379 * selectors when context switching away from a process that
380 * has a private ldt. Consider the following example:
381 *
382 * Wine creats a ldt descriptor and points a segment register
383 * to it.
384 *
385 * We then context switch away from wine lwp to kernel
697
698 /*
699 * Allocate new LDT for process just large enough to contain seli.
700 * Note we allocate and grow LDT in PAGESIZE chunks. We do this
701 * to simplify the implementation and because on the hypervisor it's
702 * required, since the LDT must live on pages that have PROT_WRITE
703 * removed and which are given to the hypervisor.
704 */
705 static void
706 ldt_alloc(proc_t *pp, uint_t seli)
707 {
708 user_desc_t *ldt;
709 size_t ldtsz;
710 uint_t nsels;
711
712 ASSERT(MUTEX_HELD(&pp->p_ldtlock));
713 ASSERT(pp->p_ldt == NULL);
714 ASSERT(pp->p_ldtlimit == 0);
715
716 /*
717 * Allocate new LDT just large enough to contain seli.
718 */
719 ldtsz = P2ROUNDUP((seli + 1) * sizeof (user_desc_t), PAGESIZE);
720 nsels = ldtsz / sizeof (user_desc_t);
721 ASSERT(nsels >= MINNLDT && nsels <= MAXNLDT);
722
723 ldt = kmem_zalloc(ldtsz, KM_SLEEP);
724 ASSERT(IS_P2ALIGNED(ldt, PAGESIZE));
725
726 #if defined(__xpv)
727 if (xen_ldt_setprot(ldt, ldtsz, PROT_READ))
728 panic("ldt_alloc:xen_ldt_setprot(PROT_READ) failed");
729 #endif
730
731 pp->p_ldt = ldt;
732 pp->p_ldtlimit = nsels - 1;
733 set_syssegd(&pp->p_ldt_desc, ldt, ldtsz - 1, SDT_SYSLDT, SEL_KPL);
734
735 if (pp == curproc) {
736 kpreempt_disable();
737 ldt_load();
815 if (xen_ldt_setprot(cp->p_ldt, ldtsz, PROT_READ))
816 panic("ldt_dup:xen_ldt_setprot(PROT_READ) failed");
817 #endif
818 mutex_exit(&cp->p_ldtlock);
819 mutex_exit(&pp->p_ldtlock);
820
821 }
822
823 static void
824 ldt_grow(proc_t *pp, uint_t seli)
825 {
826 user_desc_t *oldt, *nldt;
827 uint_t nsels;
828 size_t oldtsz, nldtsz;
829
830 ASSERT(MUTEX_HELD(&pp->p_ldtlock));
831 ASSERT(pp->p_ldt != NULL);
832 ASSERT(pp->p_ldtlimit != 0);
833
834 /*
835 * Allocate larger LDT just large enough to contain seli.
836 */
837 nldtsz = P2ROUNDUP((seli + 1) * sizeof (user_desc_t), PAGESIZE);
838 nsels = nldtsz / sizeof (user_desc_t);
839 ASSERT(nsels >= MINNLDT && nsels <= MAXNLDT);
840 ASSERT(nsels > pp->p_ldtlimit);
841
842 oldt = pp->p_ldt;
843 oldtsz = (pp->p_ldtlimit + 1) * sizeof (user_desc_t);
844
845 nldt = kmem_zalloc(nldtsz, KM_SLEEP);
846 ASSERT(IS_P2ALIGNED(nldt, PAGESIZE));
847
848 bcopy(oldt, nldt, oldtsz);
849
850 /*
851 * unload old ldt.
852 */
853 kpreempt_disable();
854 ldt_unload();
855 kpreempt_enable();
|
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Joyent, Inc.
24 */
25
26 /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
28 /* All Rights Reserved */
29
30 /* Copyright (c) 1987, 1988 Microsoft Corporation */
31 /* All Rights Reserved */
32
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>
65 #if defined(__xpv)
66 #include <sys/hypervisor.h>
67 #include <sys/note.h>
68 #endif
69
70 static void ldt_alloc(proc_t *, uint_t);
71 static void ldt_free(proc_t *);
72 static void ldt_dup(proc_t *, proc_t *);
73 static void ldt_grow(proc_t *, uint_t);
74
75 /*
76 * sysi86 System Call
77 */
78
79 /* ARGSUSED */
80 int
81 sysi86(short cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
82 {
83 struct ssd ssd;
84 int error = 0;
331 sgd->sgd_type = ssd->acc1;
332 sgd->sgd_dpl = ssd->acc1 >> 5;
333 sgd->sgd_p = ssd->acc1 >> 7;
334 ASSERT(sgd->sgd_type == SDT_SYSCGT);
335 ASSERT(sgd->sgd_dpl == SEL_UPL);
336 sgd->sgd_stkcpy = 0;
337 }
338
339 #endif /* __i386 */
340
341 /*
342 * Load LDT register with the current process's LDT.
343 */
344 static void
345 ldt_load(void)
346 {
347 #if defined(__xpv)
348 xen_set_ldt(get_ssd_base(&curproc->p_ldt_desc),
349 curproc->p_ldtlimit + 1);
350 #else
351 size_t len;
352 system_desc_t desc;
353
354 /*
355 * Before we can use the LDT on this CPU, we must install the LDT in the
356 * user mapping table.
357 */
358 len = (curproc->p_ldtlimit + 1) * sizeof (user_desc_t);
359 bcopy(curproc->p_ldt, CPU->cpu_m.mcpu_ldt, len);
360 CPU->cpu_m.mcpu_ldt_len = len;
361 set_syssegd(&desc, CPU->cpu_m.mcpu_ldt, len - 1, SDT_SYSLDT, SEL_KPL);
362 *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = desc;
363
364 wr_ldtr(ULDT_SEL);
365 #endif
366 }
367
368 /*
369 * Store a NULL selector in the LDTR. All subsequent illegal references to
370 * the LDT will result in a #gp.
371 */
372 void
373 ldt_unload(void)
374 {
375 #if defined(__xpv)
376 xen_set_ldt(NULL, 0);
377 #else
378 *((system_desc_t *)&CPU->cpu_gdt[GDT_LDT]) = null_sdesc;
379 wr_ldtr(0);
380
381 bzero(CPU->cpu_m.mcpu_ldt, CPU->cpu_m.mcpu_ldt_len);
382 CPU->cpu_m.mcpu_ldt_len = 0;
383 #endif
384 }
385
386 /*ARGSUSED*/
387 static void
388 ldt_savectx(proc_t *p)
389 {
390 ASSERT(p->p_ldt != NULL);
391 ASSERT(p == curproc);
392
393 #if defined(__amd64)
394 /*
395 * The 64-bit kernel must be sure to clear any stale ldt
396 * selectors when context switching away from a process that
397 * has a private ldt. Consider the following example:
398 *
399 * Wine creats a ldt descriptor and points a segment register
400 * to it.
401 *
402 * We then context switch away from wine lwp to kernel
714
715 /*
716 * Allocate new LDT for process just large enough to contain seli.
717 * Note we allocate and grow LDT in PAGESIZE chunks. We do this
718 * to simplify the implementation and because on the hypervisor it's
719 * required, since the LDT must live on pages that have PROT_WRITE
720 * removed and which are given to the hypervisor.
721 */
722 static void
723 ldt_alloc(proc_t *pp, uint_t seli)
724 {
725 user_desc_t *ldt;
726 size_t ldtsz;
727 uint_t nsels;
728
729 ASSERT(MUTEX_HELD(&pp->p_ldtlock));
730 ASSERT(pp->p_ldt == NULL);
731 ASSERT(pp->p_ldtlimit == 0);
732
733 /*
734 * Allocate new LDT just large enough to contain seli. The LDT must
735 * always be allocated in units of pages for KPTI.
736 */
737 ldtsz = P2ROUNDUP((seli + 1) * sizeof (user_desc_t), PAGESIZE);
738 nsels = ldtsz / sizeof (user_desc_t);
739 ASSERT(nsels >= MINNLDT && nsels <= MAXNLDT);
740
741 ldt = kmem_zalloc(ldtsz, KM_SLEEP);
742 ASSERT(IS_P2ALIGNED(ldt, PAGESIZE));
743
744 #if defined(__xpv)
745 if (xen_ldt_setprot(ldt, ldtsz, PROT_READ))
746 panic("ldt_alloc:xen_ldt_setprot(PROT_READ) failed");
747 #endif
748
749 pp->p_ldt = ldt;
750 pp->p_ldtlimit = nsels - 1;
751 set_syssegd(&pp->p_ldt_desc, ldt, ldtsz - 1, SDT_SYSLDT, SEL_KPL);
752
753 if (pp == curproc) {
754 kpreempt_disable();
755 ldt_load();
833 if (xen_ldt_setprot(cp->p_ldt, ldtsz, PROT_READ))
834 panic("ldt_dup:xen_ldt_setprot(PROT_READ) failed");
835 #endif
836 mutex_exit(&cp->p_ldtlock);
837 mutex_exit(&pp->p_ldtlock);
838
839 }
840
841 static void
842 ldt_grow(proc_t *pp, uint_t seli)
843 {
844 user_desc_t *oldt, *nldt;
845 uint_t nsels;
846 size_t oldtsz, nldtsz;
847
848 ASSERT(MUTEX_HELD(&pp->p_ldtlock));
849 ASSERT(pp->p_ldt != NULL);
850 ASSERT(pp->p_ldtlimit != 0);
851
852 /*
853 * Allocate larger LDT just large enough to contain seli. The LDT must
854 * always be allocated in units of pages for KPTI.
855 */
856 nldtsz = P2ROUNDUP((seli + 1) * sizeof (user_desc_t), PAGESIZE);
857 nsels = nldtsz / sizeof (user_desc_t);
858 ASSERT(nsels >= MINNLDT && nsels <= MAXNLDT);
859 ASSERT(nsels > pp->p_ldtlimit);
860
861 oldt = pp->p_ldt;
862 oldtsz = (pp->p_ldtlimit + 1) * sizeof (user_desc_t);
863
864 nldt = kmem_zalloc(nldtsz, KM_SLEEP);
865 ASSERT(IS_P2ALIGNED(nldt, PAGESIZE));
866
867 bcopy(oldt, nldt, oldtsz);
868
869 /*
870 * unload old ldt.
871 */
872 kpreempt_disable();
873 ldt_unload();
874 kpreempt_enable();
|