18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * include/asm-xtensa/uaccess.h
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * User space memory access functions
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * These routines provide basic accessing functions to the user memory
78c2ecf20Sopenharmony_ci * space for the kernel. This header file provides functions such as:
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
108c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
118c2ecf20Sopenharmony_ci * for more details.
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * Copyright (C) 2001 - 2005 Tensilica Inc.
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#ifndef _XTENSA_ASM_UACCESS_H
178c2ecf20Sopenharmony_ci#define _XTENSA_ASM_UACCESS_H
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#include <linux/errno.h>
208c2ecf20Sopenharmony_ci#include <asm/types.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include <asm/current.h>
238c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h>
248c2ecf20Sopenharmony_ci#include <asm/processor.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/*
278c2ecf20Sopenharmony_ci * These assembly macros mirror the C macros in asm/uaccess.h.  They
288c2ecf20Sopenharmony_ci * should always have identical functionality.  See
298c2ecf20Sopenharmony_ci * arch/xtensa/kernel/sys.S for usage.
308c2ecf20Sopenharmony_ci */
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#define KERNEL_DS	0
338c2ecf20Sopenharmony_ci#define USER_DS		1
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/*
368c2ecf20Sopenharmony_ci * get_fs reads current->thread.current_ds into a register.
378c2ecf20Sopenharmony_ci * On Entry:
388c2ecf20Sopenharmony_ci * 	<ad>	anything
398c2ecf20Sopenharmony_ci * 	<sp>	stack
408c2ecf20Sopenharmony_ci * On Exit:
418c2ecf20Sopenharmony_ci * 	<ad>	contains current->thread.current_ds
428c2ecf20Sopenharmony_ci */
438c2ecf20Sopenharmony_ci	.macro	get_fs	ad, sp
448c2ecf20Sopenharmony_ci	GET_CURRENT(\ad,\sp)
458c2ecf20Sopenharmony_ci#if THREAD_CURRENT_DS > 1020
468c2ecf20Sopenharmony_ci	addi	\ad, \ad, TASK_THREAD
478c2ecf20Sopenharmony_ci	l32i	\ad, \ad, THREAD_CURRENT_DS - TASK_THREAD
488c2ecf20Sopenharmony_ci#else
498c2ecf20Sopenharmony_ci	l32i	\ad, \ad, THREAD_CURRENT_DS
508c2ecf20Sopenharmony_ci#endif
518c2ecf20Sopenharmony_ci	.endm
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/*
548c2ecf20Sopenharmony_ci * set_fs sets current->thread.current_ds to some value.
558c2ecf20Sopenharmony_ci * On Entry:
568c2ecf20Sopenharmony_ci *	<at>	anything (temp register)
578c2ecf20Sopenharmony_ci *	<av>	value to write
588c2ecf20Sopenharmony_ci *	<sp>	stack
598c2ecf20Sopenharmony_ci * On Exit:
608c2ecf20Sopenharmony_ci *	<at>	destroyed (actually, current)
618c2ecf20Sopenharmony_ci *	<av>	preserved, value to write
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_ci	.macro	set_fs	at, av, sp
648c2ecf20Sopenharmony_ci	GET_CURRENT(\at,\sp)
658c2ecf20Sopenharmony_ci	s32i	\av, \at, THREAD_CURRENT_DS
668c2ecf20Sopenharmony_ci	.endm
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci/*
698c2ecf20Sopenharmony_ci * kernel_ok determines whether we should bypass addr/size checking.
708c2ecf20Sopenharmony_ci * See the equivalent C-macro version below for clarity.
718c2ecf20Sopenharmony_ci * On success, kernel_ok branches to a label indicated by parameter
728c2ecf20Sopenharmony_ci * <success>.  This implies that the macro falls through to the next
738c2ecf20Sopenharmony_ci * insruction on an error.
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci * Note that while this macro can be used independently, we designed
768c2ecf20Sopenharmony_ci * in for optimal use in the access_ok macro below (i.e., we fall
778c2ecf20Sopenharmony_ci * through on error).
788c2ecf20Sopenharmony_ci *
798c2ecf20Sopenharmony_ci * On Entry:
808c2ecf20Sopenharmony_ci * 	<at>		anything (temp register)
818c2ecf20Sopenharmony_ci * 	<success>	label to branch to on success; implies
828c2ecf20Sopenharmony_ci * 			fall-through macro on error
838c2ecf20Sopenharmony_ci * 	<sp>		stack pointer
848c2ecf20Sopenharmony_ci * On Exit:
858c2ecf20Sopenharmony_ci * 	<at>		destroyed (actually, current->thread.current_ds)
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#if ((KERNEL_DS != 0) || (USER_DS == 0))
898c2ecf20Sopenharmony_ci# error Assembly macro kernel_ok fails
908c2ecf20Sopenharmony_ci#endif
918c2ecf20Sopenharmony_ci	.macro	kernel_ok  at, sp, success
928c2ecf20Sopenharmony_ci	get_fs	\at, \sp
938c2ecf20Sopenharmony_ci	beqz	\at, \success
948c2ecf20Sopenharmony_ci	.endm
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/*
978c2ecf20Sopenharmony_ci * user_ok determines whether the access to user-space memory is allowed.
988c2ecf20Sopenharmony_ci * See the equivalent C-macro version below for clarity.
998c2ecf20Sopenharmony_ci *
1008c2ecf20Sopenharmony_ci * On error, user_ok branches to a label indicated by parameter
1018c2ecf20Sopenharmony_ci * <error>.  This implies that the macro falls through to the next
1028c2ecf20Sopenharmony_ci * instruction on success.
1038c2ecf20Sopenharmony_ci *
1048c2ecf20Sopenharmony_ci * Note that while this macro can be used independently, we designed
1058c2ecf20Sopenharmony_ci * in for optimal use in the access_ok macro below (i.e., we fall
1068c2ecf20Sopenharmony_ci * through on success).
1078c2ecf20Sopenharmony_ci *
1088c2ecf20Sopenharmony_ci * On Entry:
1098c2ecf20Sopenharmony_ci * 	<aa>	register containing memory address
1108c2ecf20Sopenharmony_ci * 	<as>	register containing memory size
1118c2ecf20Sopenharmony_ci * 	<at>	temp register
1128c2ecf20Sopenharmony_ci * 	<error>	label to branch to on error; implies fall-through
1138c2ecf20Sopenharmony_ci * 		macro on success
1148c2ecf20Sopenharmony_ci * On Exit:
1158c2ecf20Sopenharmony_ci * 	<aa>	preserved
1168c2ecf20Sopenharmony_ci * 	<as>	preserved
1178c2ecf20Sopenharmony_ci * 	<at>	destroyed (actually, (TASK_SIZE + 1 - size))
1188c2ecf20Sopenharmony_ci */
1198c2ecf20Sopenharmony_ci	.macro	user_ok	aa, as, at, error
1208c2ecf20Sopenharmony_ci	movi	\at, __XTENSA_UL_CONST(TASK_SIZE)
1218c2ecf20Sopenharmony_ci	bgeu	\as, \at, \error
1228c2ecf20Sopenharmony_ci	sub	\at, \at, \as
1238c2ecf20Sopenharmony_ci	bgeu	\aa, \at, \error
1248c2ecf20Sopenharmony_ci	.endm
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci/*
1278c2ecf20Sopenharmony_ci * access_ok determines whether a memory access is allowed.  See the
1288c2ecf20Sopenharmony_ci * equivalent C-macro version below for clarity.
1298c2ecf20Sopenharmony_ci *
1308c2ecf20Sopenharmony_ci * On error, access_ok branches to a label indicated by parameter
1318c2ecf20Sopenharmony_ci * <error>.  This implies that the macro falls through to the next
1328c2ecf20Sopenharmony_ci * instruction on success.
1338c2ecf20Sopenharmony_ci *
1348c2ecf20Sopenharmony_ci * Note that we assume success is the common case, and we optimize the
1358c2ecf20Sopenharmony_ci * branch fall-through case on success.
1368c2ecf20Sopenharmony_ci *
1378c2ecf20Sopenharmony_ci * On Entry:
1388c2ecf20Sopenharmony_ci * 	<aa>	register containing memory address
1398c2ecf20Sopenharmony_ci * 	<as>	register containing memory size
1408c2ecf20Sopenharmony_ci * 	<at>	temp register
1418c2ecf20Sopenharmony_ci * 	<sp>
1428c2ecf20Sopenharmony_ci * 	<error>	label to branch to on error; implies fall-through
1438c2ecf20Sopenharmony_ci * 		macro on success
1448c2ecf20Sopenharmony_ci * On Exit:
1458c2ecf20Sopenharmony_ci * 	<aa>	preserved
1468c2ecf20Sopenharmony_ci * 	<as>	preserved
1478c2ecf20Sopenharmony_ci * 	<at>	destroyed
1488c2ecf20Sopenharmony_ci */
1498c2ecf20Sopenharmony_ci	.macro	access_ok  aa, as, at, sp, error
1508c2ecf20Sopenharmony_ci	kernel_ok  \at, \sp, .Laccess_ok_\@
1518c2ecf20Sopenharmony_ci	user_ok    \aa, \as, \at, \error
1528c2ecf20Sopenharmony_ci.Laccess_ok_\@:
1538c2ecf20Sopenharmony_ci	.endm
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci#endif	/* _XTENSA_ASM_UACCESS_H */
156