Exemple #1
0
int
sys_penguin_arch_prctl(struct penguin_arch_prctl_args *args)
{
	kprintf("sys_arch_prctl, %x\n", args->code);
	int error = 0;
	struct tls_info info;

	switch(args->code)
	{
	case ARCH_SET_GS:
		info.base = (void*)args->addr;
		info.size = -1;
		curthread->td_tls.info[1] = info;
		set_user_TLS();
		break;
	case ARCH_GET_GS:
		panic("TODO");
		break;
	case ARCH_SET_FS:
		info.base = (void*)args->addr;
		info.size = -1;
		curthread->td_tls.info[0] = info;
		set_user_TLS();
		break;
	case ARCH_GET_FS:
	panic("TODO");
		break;
	default: error = -1;
	}

	kprintf("sys_arch_prctl returns error %d\n", error);
	args->sysmsg_result64 = error;
	return 0;
}
Exemple #2
0
/*
 * set a TLS descriptor.  For x86_64 descriptor 0 identifies %fs and
 * descriptor 1 identifies %gs, and 0 is returned in sysmsg_result.
 * 
 * Returns the value userland needs to load into %gs representing the 
 * TLS descriptor or -1 on error.
 *
 * (int which, struct tls_info *info, size_t infosize)
 *
 * MPSAFE
 */
int
sys_set_tls_area(struct set_tls_area_args *uap)
{
	struct tls_info info;
	int error;
	int i;

	/*
	 * Sanity checks
	 *
	 * which 0 == %fs, which 1 == %gs
	 */
	i = uap->which;
	if (i < 0 || i > 1)
		return (ERANGE);
	if (uap->infosize < 0)
		return (EINVAL);

	/*
	 * Maintain forwards compatibility with future extensions.
	 */
	if (uap->infosize != sizeof(info)) {
		bzero(&info, sizeof(info));
		error = copyin(uap->info, &info, 
				min(sizeof(info), uap->infosize));
	} else {
		error = copyin(uap->info, &info, sizeof(info));
	}
	if (error)
		return (error);
	if (info.size < -1)
		return (EINVAL);

	/*
	 * For x86_64 we can only adjust FSBASE and GSBASE
	 */
	curthread->td_tls.info[i] = info;
	set_user_TLS();
	uap->sysmsg_result = 0;	/* segment descriptor $0 */
	return(0);
}