putuser.S 1.8 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>
L
Linus Torvalds 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31


/*
 * __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.
 */

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

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

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

58
ENTRY(__put_user_4)
L
Linus Torvalds 已提交
59
	ENTER
G
Glauber Costa 已提交
60 61 62
	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
	sub $3,%_ASM_BX
	cmp %_ASM_BX,%_ASM_CX
L
Linus Torvalds 已提交
63
	jae bad_put_user
G
Glauber Costa 已提交
64
3:	movl %eax,(%_ASM_CX)
65
	xor %eax,%eax
L
Linus Torvalds 已提交
66
	EXIT
67
ENDPROC(__put_user_4)
L
Linus Torvalds 已提交
68

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

bad_put_user:
84
	CFI_STARTPROC
85
	movl $-EFAULT,%eax
L
Linus Torvalds 已提交
86
	EXIT
87
END(bad_put_user)
L
Linus Torvalds 已提交
88

89 90 91 92
	_ASM_EXTABLE(1b,bad_put_user)
	_ASM_EXTABLE(2b,bad_put_user)
	_ASM_EXTABLE(3b,bad_put_user)
	_ASM_EXTABLE(4b,bad_put_user)
93
#ifdef CONFIG_X86_32
94
	_ASM_EXTABLE(5b,bad_put_user)
95
#endif