int
linux_sys_get_thread_area(struct proc *p, void *v, register_t *retval)
{
    struct linux_sys_get_thread_area_args *uap = v;
    struct l_segment_descriptor info;
    int error;
    int idx;

    error = copyin(SCARG(uap, desc), &info, sizeof(info));
    if (error)
        return error;

    idx = info.entry_number;
    if (idx != GUGS_SEL)
        return (EINVAL);

    info.base_addr = i386_get_threadbase(p, TSEG_GS);
    info.limit = atop(VM_MAXUSER_ADDRESS) - 1;
    info.seg_32bit = 1;
    info.contents = 0;
    info.read_exec_only = 0;	/* SDT_MEMRWA */
    info.limit_in_pages = 1;
    info.seg_not_present = 0;
    info.useable = 1;

    return (copyout(&info, SCARG(uap, desc), sizeof(SCARG(uap, desc))));
}
示例#2
0
int
sys_sysarch(struct proc *p, void *v, register_t *retval)
{
    struct sys_sysarch_args /* {
		syscallarg(int) op;
		syscallarg(void *) parms;
	} */ *uap = v;
    int error = 0;

    switch(SCARG(uap, op)) {
#ifdef	USER_LDT
    case I386_GET_LDT:
        error = i386_get_ldt(p, SCARG(uap, parms), retval);
        break;

    case I386_SET_LDT:
        error = i386_set_ldt(p, SCARG(uap, parms), retval);
        break;
#endif

    case I386_IOPL:
        error = i386_iopl(p, SCARG(uap, parms), retval);
        break;

    case I386_GET_IOPERM:
        error = i386_get_ioperm(p, SCARG(uap, parms), retval);
        break;

    case I386_SET_IOPERM:
        error = i386_set_ioperm(p, SCARG(uap, parms), retval);
        break;

#ifdef VM86
    case I386_VM86:
        error = i386_vm86(p, SCARG(uap, parms), retval);
        break;
#endif

    case I386_GET_FSBASE:
    {
        uint32_t base = i386_get_threadbase(p, TSEG_FS);

        error = copyout(&base, SCARG(uap, parms), sizeof(base));
        break;
    }

    case I386_SET_FSBASE:
    {
        uint32_t base;

        if ((error = copyin(SCARG(uap, parms), &base, sizeof(base))))
            break;
        error = i386_set_threadbase(p, base, TSEG_FS);
        break;
    }

    case I386_GET_GSBASE:
    {
        uint32_t base = i386_get_threadbase(p, TSEG_GS);

        error = copyout(&base, SCARG(uap, parms), sizeof(base));
        break;
    }

    case I386_SET_GSBASE:
    {
        uint32_t base;

        if ((error = copyin(SCARG(uap, parms), &base, sizeof(base))))
            break;
        error = i386_set_threadbase(p, base, TSEG_GS);
        break;
    }

    default:
        error = EINVAL;
        break;
    }
    return (error);
}