summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/ia32/syscall/lwp_private.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/ia32/syscall/lwp_private.c')
-rw-r--r--usr/src/uts/intel/ia32/syscall/lwp_private.c222
1 files changed, 0 insertions, 222 deletions
diff --git a/usr/src/uts/intel/ia32/syscall/lwp_private.c b/usr/src/uts/intel/ia32/syscall/lwp_private.c
deleted file mode 100644
index 50331a2899..0000000000
--- a/usr/src/uts/intel/ia32/syscall/lwp_private.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- * Copyright (c) 2018, Joyent, Inc.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/disp.h>
-#include <sys/sysmacros.h>
-#include <sys/cpuvar.h>
-#include <sys/systm.h>
-#include <sys/thread.h>
-#include <sys/lwp.h>
-#include <sys/segments.h>
-#include <sys/privregs.h>
-#include <sys/cmn_err.h>
-
-int
-lwp_setprivate(klwp_t *lwp, int which, uintptr_t base)
-{
- pcb_t *pcb = &lwp->lwp_pcb;
- struct regs *rp = lwptoregs(lwp);
- kthread_t *t = lwptot(lwp);
- int thisthread = t == curthread;
- int rval;
-
- if (thisthread)
- kpreempt_disable();
-
-
- /*
- * 32-bit compatibility processes point to the per-cpu GDT segment
- * descriptors that are virtualized to the lwp. That allows 32-bit
- * programs to mess with %fs and %gs; in particular it allows
- * things like this:
- *
- * movw %gs, %ax
- * ...
- * movw %ax, %gs
- *
- * to work, which is needed by emulators for legacy application
- * environments ..
- *
- * 64-bit processes may also point to a per-cpu GDT segment descriptor
- * virtualized to the lwp. However the descriptor base is forced
- * to zero (because we can't express the full 64-bit address range
- * in a long mode descriptor), so don't reload segment registers
- * in a 64-bit program! 64-bit processes must have selector values
- * of zero for %fs and %gs to use the 64-bit fs_base and gs_base
- * respectively.
- */
- if (!PCB_NEED_UPDATE_SEGS(pcb)) {
- pcb->pcb_ds = rp->r_ds;
- pcb->pcb_es = rp->r_es;
- pcb->pcb_fs = rp->r_fs;
- pcb->pcb_gs = rp->r_gs;
- PCB_SET_UPDATE_SEGS(pcb);
- t->t_post_sys = 1;
- }
- ASSERT(t->t_post_sys);
-
- switch (which) {
- case _LWP_FSBASE:
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- set_usegd(&pcb->pcb_fsdesc, SDP_LONG, 0, 0,
- SDT_MEMRWA, SEL_UPL, SDP_BYTES, SDP_OP32);
- rval = pcb->pcb_fs = 0; /* null gdt descriptor */
- } else {
- set_usegd(&pcb->pcb_fsdesc, SDP_SHORT, (void *)base, -1,
- SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32);
- rval = pcb->pcb_fs = LWPFS_SEL;
- }
- if (thisthread)
- gdt_update_usegd(GDT_LWPFS, &pcb->pcb_fsdesc);
-
- pcb->pcb_fsbase = base;
- break;
- case _LWP_GSBASE:
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- set_usegd(&pcb->pcb_gsdesc, SDP_LONG, 0, 0,
- SDT_MEMRWA, SEL_UPL, SDP_BYTES, SDP_OP32);
- rval = pcb->pcb_gs = 0; /* null gdt descriptor */
- } else {
- set_usegd(&pcb->pcb_gsdesc, SDP_SHORT, (void *)base, -1,
- SDT_MEMRWA, SEL_UPL, SDP_PAGES, SDP_OP32);
- rval = pcb->pcb_gs = LWPGS_SEL;
- }
- if (thisthread)
- gdt_update_usegd(GDT_LWPGS, &pcb->pcb_gsdesc);
-
- pcb->pcb_gsbase = base;
- break;
- default:
- rval = -1;
- break;
- }
-
- if (thisthread)
- kpreempt_enable();
- return (rval);
-}
-
-static int
-lwp_getprivate(klwp_t *lwp, int which, uintptr_t base)
-{
- pcb_t *pcb = &lwp->lwp_pcb;
- struct regs *rp = lwptoregs(lwp);
- uintptr_t sbase;
- int error = 0;
-
- ASSERT(lwptot(lwp) == curthread);
-
- kpreempt_disable();
- switch (which) {
- case _LWP_FSBASE:
- if ((sbase = pcb->pcb_fsbase) != 0) {
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- if (PCB_NEED_UPDATE_SEGS(pcb)) {
- if (pcb->pcb_fs == 0)
- break;
- } else {
- if (rp->r_fs == 0)
- break;
- }
- } else {
- if (PCB_NEED_UPDATE_SEGS(pcb)) {
- if (pcb->pcb_fs == LWPFS_SEL)
- break;
- } else {
- if (rp->r_fs == LWPFS_SEL)
- break;
- }
- }
- }
- error = EINVAL;
- break;
- case _LWP_GSBASE:
- if ((sbase = pcb->pcb_gsbase) != 0) {
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- if (PCB_NEED_UPDATE_SEGS(pcb)) {
- if (pcb->pcb_gs == 0)
- break;
- } else {
- if (rp->r_gs == 0)
- break;
- }
- } else {
- if (PCB_NEED_UPDATE_SEGS(pcb)) {
- if (pcb->pcb_gs == LWPGS_SEL)
- break;
- } else {
- if (rp->r_gs == LWPGS_SEL)
- break;
- }
- }
- }
- error = EINVAL;
- break;
-
-
- default:
- error = ENOTSUP;
- break;
- }
- kpreempt_enable();
-
- if (error != 0)
- return (error);
-
- if (lwp_getdatamodel(lwp) == DATAMODEL_NATIVE) {
- if (sulword((void *)base, sbase) == -1)
- error = EFAULT;
-#if defined(_SYSCALL32_IMPL)
- } else {
- if (suword32((void *)base, (uint32_t)sbase) == -1)
- error = EFAULT;
-#endif
- }
- return (error);
-}
-
-/*
- * libc-private syscall for managing per-lwp %gs and %fs segment base values.
- */
-int
-syslwp_private(int cmd, int which, uintptr_t base)
-{
- klwp_t *lwp = ttolwp(curthread);
- int res, error;
-
- switch (cmd) {
- case _LWP_SETPRIVATE:
- res = lwp_setprivate(lwp, which, base);
- return (res < 0 ? set_errno(ENOTSUP) : res);
- case _LWP_GETPRIVATE:
- error = lwp_getprivate(lwp, which, base);
- return (error != 0 ? set_errno(error) : error);
- default:
- return (set_errno(ENOTSUP));
- }
-}