1/*
2 * __get_user functions.
3 *
4 * (C) Copyright 1998 Linus Torvalds
5 *
6 * These functions have a non-standard call interface
7 * to make them more efficient, especially as they
8 * return an error value in addition to the "real"
9 * return value.
10 */
11
12/*
13 * __get_user_X
14 *
15 * Inputs:	%rax contains the address
16 *
17 * Outputs:	%rax is error code (0 or -EFAULT)
18 *		%rdx contains zero-extended value
19 *
20 * %rbx is destroyed.
21 *
22 * These functions should not modify any other registers,
23 * as they get called from within inline assembly.
24 */
25
26#include <linux/linkage.h>
27#include <asm/page.h>
28#include <asm/errno.h>
29#include <asm/current.h>
30#include <asm/offset.h>
31#include <asm/calling.h>
32
33	.text
34	.p2align
35.globl __get_user_1
36__get_user_1:
37	GET_CURRENT(%rbx)
38	cmpq tsk_addr_limit(%rbx),%rax
39	jae bad_get_user
401:	movzb (%rax),%edx
41	xorq %rax,%rax
42	ret
43
44	.p2align
45.globl __get_user_2
46__get_user_2:
47	GET_CURRENT(%rbx)
48	addq $1,%rax
49	jc bad_get_user
50	cmpq tsk_addr_limit(%rbx),%rax
51	jae	 bad_get_user
522:	movzwl -1(%rax),%edx
53	xorq %rax,%rax
54	ret
55
56	.p2align
57.globl __get_user_4
58__get_user_4:
59	GET_CURRENT(%rbx)
60	addq $3,%rax
61	jc bad_get_user
62	cmpq tsk_addr_limit(%rbx),%rax
63	jae bad_get_user
643:	movl -3(%rax),%edx
65	xorq %rax,%rax
66	ret
67
68	.p2align
69.globl __get_user_8
70__get_user_8:
71	GET_CURRENT(%rbx)
72	addq $7,%rax
73	jc bad_get_user
74	cmpq tsk_addr_limit(%rbx),%rax
75	jae	bad_get_user
764:	movq -7(%rax),%rdx
77	xorq %rax,%rax
78	ret
79
80ENTRY(bad_get_user)
81bad_get_user:
82	xorq %rdx,%rdx
83	movq $(-EFAULT),%rax
84	ret
85
86.section __ex_table,"a"
87	.quad 1b,bad_get_user
88	.quad 2b,bad_get_user
89	.quad 3b,bad_get_user
90	.quad 4b,bad_get_user
91.previous
92