putuser.S 1.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 * __put_user functions.
 *
 * (C) Copyright 2005 Linus Torvalds
5 6
 * (C) Copyright 2005 Andi Kleen
 * (C) Copyright 2008 Glauber Costa
L
Linus Torvalds 已提交
7 8 9 10 11 12
 *
 * These functions have a non-standard call interface
 * to make them more efficient, especially as they
 * return an error value in addition to the "real"
 * return value.
 */
13 14
#include <linux/linkage.h>
#include <asm/dwarf2.h>
L
Linus Torvalds 已提交
15
#include <asm/thread_info.h>
16
#include <asm/errno.h>
G
Glauber Costa 已提交
17
#include <asm/asm.h>
18
#include <asm/smap.h>
L
Linus Torvalds 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31 32


/*
 * __put_user_X
 *
 * Inputs:	%eax[:%edx] contains the data
 *		%ecx contains the address
 *
 * Outputs:	%eax is error code (0 or -EFAULT)
 *
 * These functions should not modify any other registers,
 * as they get called from within inline assembly.
 */

33
#define ENTER	CFI_STARTPROC ; \
G
Glauber Costa 已提交
34
		GET_THREAD_INFO(%_ASM_BX)
35 36
#define EXIT	ASM_CLAC ;	\
		ret ;		\
37
		CFI_ENDPROC
L
Linus Torvalds 已提交
38 39

.text
40
ENTRY(__put_user_1)
L
Linus Torvalds 已提交
41
	ENTER
G
Glauber Costa 已提交
42
	cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
L
Linus Torvalds 已提交
43
	jae bad_put_user
44
	ASM_STAC
G
Glauber Costa 已提交
45
1:	movb %al,(%_ASM_CX)
46
	xor %eax,%eax
L
Linus Torvalds 已提交
47
	EXIT
48
ENDPROC(__put_user_1)
L
Linus Torvalds 已提交
49

50
ENTRY(__put_user_2)
L
Linus Torvalds 已提交
51
	ENTER
G
Glauber Costa 已提交
52 53 54
	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
	sub $1,%_ASM_BX
	cmp %_ASM_BX,%_ASM_CX
L
Linus Torvalds 已提交
55
	jae bad_put_user
56
	ASM_STAC
G
Glauber Costa 已提交
57
2:	movw %ax,(%_ASM_CX)
58
	xor %eax,%eax
L
Linus Torvalds 已提交
59
	EXIT
60
ENDPROC(__put_user_2)
L
Linus Torvalds 已提交
61

62
ENTRY(__put_user_4)
L
Linus Torvalds 已提交
63
	ENTER
G
Glauber Costa 已提交
64 65 66
	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
	sub $3,%_ASM_BX
	cmp %_ASM_BX,%_ASM_CX
L
Linus Torvalds 已提交
67
	jae bad_put_user
68
	ASM_STAC
G
Glauber Costa 已提交
69
3:	movl %eax,(%_ASM_CX)
70
	xor %eax,%eax
L
Linus Torvalds 已提交
71
	EXIT
72
ENDPROC(__put_user_4)
L
Linus Torvalds 已提交
73

74
ENTRY(__put_user_8)
L
Linus Torvalds 已提交
75
	ENTER
G
Glauber Costa 已提交
76 77 78
	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
	sub $7,%_ASM_BX
	cmp %_ASM_BX,%_ASM_CX
L
Linus Torvalds 已提交
79
	jae bad_put_user
80
	ASM_STAC
81 82
4:	mov %_ASM_AX,(%_ASM_CX)
#ifdef CONFIG_X86_32
G
Glauber Costa 已提交
83
5:	movl %edx,4(%_ASM_CX)
84
#endif
85
	xor %eax,%eax
L
Linus Torvalds 已提交
86
	EXIT
87
ENDPROC(__put_user_8)
L
Linus Torvalds 已提交
88 89

bad_put_user:
90
	CFI_STARTPROC
91
	movl $-EFAULT,%eax
L
Linus Torvalds 已提交
92
	EXIT
93
END(bad_put_user)
L
Linus Torvalds 已提交
94

95 96 97 98
	_ASM_EXTABLE(1b,bad_put_user)
	_ASM_EXTABLE(2b,bad_put_user)
	_ASM_EXTABLE(3b,bad_put_user)
	_ASM_EXTABLE(4b,bad_put_user)
99
#ifdef CONFIG_X86_32
100
	_ASM_EXTABLE(5b,bad_put_user)
101
#endif