xref: /openbmc/linux/arch/x86/lib/getuser.S (revision 05bcf503)
1/*
2 * __get_user functions.
3 *
4 * (C) Copyright 1998 Linus Torvalds
5 * (C) Copyright 2005 Andi Kleen
6 * (C) Copyright 2008 Glauber Costa
7 *
8 * These functions have a non-standard call interface
9 * to make them more efficient, especially as they
10 * return an error value in addition to the "real"
11 * return value.
12 */
13
14/*
15 * __get_user_X
16 *
17 * Inputs:	%[r|e]ax contains the address.
18 *		The register is modified, but all changes are undone
19 *		before returning because the C code doesn't know about it.
20 *
21 * Outputs:	%[r|e]ax is error code (0 or -EFAULT)
22 *		%[r|e]dx contains zero-extended value
23 *
24 *
25 * These functions should not modify any other registers,
26 * as they get called from within inline assembly.
27 */
28
29#include <linux/linkage.h>
30#include <asm/dwarf2.h>
31#include <asm/page_types.h>
32#include <asm/errno.h>
33#include <asm/asm-offsets.h>
34#include <asm/thread_info.h>
35#include <asm/asm.h>
36#include <asm/smap.h>
37
38	.text
39ENTRY(__get_user_1)
40	CFI_STARTPROC
41	GET_THREAD_INFO(%_ASM_DX)
42	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
43	jae bad_get_user
44	ASM_STAC
451:	movzb (%_ASM_AX),%edx
46	xor %eax,%eax
47	ASM_CLAC
48	ret
49	CFI_ENDPROC
50ENDPROC(__get_user_1)
51
52ENTRY(__get_user_2)
53	CFI_STARTPROC
54	add $1,%_ASM_AX
55	jc bad_get_user
56	GET_THREAD_INFO(%_ASM_DX)
57	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
58	jae bad_get_user
59	ASM_STAC
602:	movzwl -1(%_ASM_AX),%edx
61	xor %eax,%eax
62	ASM_CLAC
63	ret
64	CFI_ENDPROC
65ENDPROC(__get_user_2)
66
67ENTRY(__get_user_4)
68	CFI_STARTPROC
69	add $3,%_ASM_AX
70	jc bad_get_user
71	GET_THREAD_INFO(%_ASM_DX)
72	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
73	jae bad_get_user
74	ASM_STAC
753:	mov -3(%_ASM_AX),%edx
76	xor %eax,%eax
77	ASM_CLAC
78	ret
79	CFI_ENDPROC
80ENDPROC(__get_user_4)
81
82#ifdef CONFIG_X86_64
83ENTRY(__get_user_8)
84	CFI_STARTPROC
85	add $7,%_ASM_AX
86	jc bad_get_user
87	GET_THREAD_INFO(%_ASM_DX)
88	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
89	jae	bad_get_user
90	ASM_STAC
914:	movq -7(%_ASM_AX),%_ASM_DX
92	xor %eax,%eax
93	ASM_CLAC
94	ret
95	CFI_ENDPROC
96ENDPROC(__get_user_8)
97#endif
98
99bad_get_user:
100	CFI_STARTPROC
101	xor %edx,%edx
102	mov $(-EFAULT),%_ASM_AX
103	ASM_CLAC
104	ret
105	CFI_ENDPROC
106END(bad_get_user)
107
108	_ASM_EXTABLE(1b,bad_get_user)
109	_ASM_EXTABLE(2b,bad_get_user)
110	_ASM_EXTABLE(3b,bad_get_user)
111#ifdef CONFIG_X86_64
112	_ASM_EXTABLE(4b,bad_get_user)
113#endif
114