getuser_64.S 1.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * __get_user functions.
 *
 * (C) Copyright 1998 Linus Torvalds
 * (C) Copyright 2005 Andi Kleen
 *
 * 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.
 */

/*
 * __get_user_X
 *
G
Glauber Costa 已提交
16
 * Inputs:	%rax contains the address.
L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24 25 26 27 28
 *		The register is modified, but all changes are undone
 *		before returning because the C code doesn't know about it.
 *
 * Outputs:	%rax is error code (0 or -EFAULT)
 *		%rdx contains zero-extended value
 * 
 *
 * These functions should not modify any other registers,
 * as they get called from within inline assembly.
 */

#include <linux/linkage.h>
29
#include <asm/dwarf2.h>
L
Linus Torvalds 已提交
30 31
#include <asm/page.h>
#include <asm/errno.h>
32
#include <asm/asm-offsets.h>
L
Linus Torvalds 已提交
33
#include <asm/thread_info.h>
G
Glauber Costa 已提交
34
#include <asm/asm.h>
L
Linus Torvalds 已提交
35 36

	.text
37 38
ENTRY(__get_user_1)
	CFI_STARTPROC
G
Glauber Costa 已提交
39 40
	GET_THREAD_INFO(%_ASM_DX)
	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
L
Linus Torvalds 已提交
41
	jae bad_get_user
G
Glauber Costa 已提交
42
1:	movzb (%_ASM_AX),%edx
43
	xor %eax,%eax
L
Linus Torvalds 已提交
44
	ret
45 46
	CFI_ENDPROC
ENDPROC(__get_user_1)
L
Linus Torvalds 已提交
47

48 49
ENTRY(__get_user_2)
	CFI_STARTPROC
G
Glauber Costa 已提交
50
	add $1,%_ASM_AX
51
	jc bad_get_user
G
Glauber Costa 已提交
52 53
	GET_THREAD_INFO(%_ASM_DX)
	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
54
	jae bad_get_user
G
Glauber Costa 已提交
55
2:	movzwl -1(%_ASM_AX),%edx
56
	xor %eax,%eax
L
Linus Torvalds 已提交
57
	ret
58 59
	CFI_ENDPROC
ENDPROC(__get_user_2)
L
Linus Torvalds 已提交
60

61 62
ENTRY(__get_user_4)
	CFI_STARTPROC
G
Glauber Costa 已提交
63
	add $3,%_ASM_AX
64
	jc bad_get_user
G
Glauber Costa 已提交
65 66
	GET_THREAD_INFO(%_ASM_DX)
	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
67
	jae bad_get_user
G
Glauber Costa 已提交
68
3:	mov -3(%_ASM_AX),%edx
69
	xor %eax,%eax
L
Linus Torvalds 已提交
70
	ret
71 72
	CFI_ENDPROC
ENDPROC(__get_user_4)
L
Linus Torvalds 已提交
73

74 75
ENTRY(__get_user_8)
	CFI_STARTPROC
G
Glauber Costa 已提交
76
	add $7,%_ASM_AX
77
	jc bad_get_user
G
Glauber Costa 已提交
78 79
	GET_THREAD_INFO(%_ASM_DX)
	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
80
	jae	bad_get_user
G
Glauber Costa 已提交
81
4:	movq -7(%_ASM_AX),%_ASM_DX
82
	xor %eax,%eax
L
Linus Torvalds 已提交
83
	ret
84 85
	CFI_ENDPROC
ENDPROC(__get_user_8)
L
Linus Torvalds 已提交
86 87

bad_get_user:
88
	CFI_STARTPROC
89
	xor %edx,%edx
G
Glauber Costa 已提交
90
	mov $(-EFAULT),%_ASM_AX
L
Linus Torvalds 已提交
91
	ret
92 93
	CFI_ENDPROC
END(bad_get_user)
L
Linus Torvalds 已提交
94 95 96 97 98 99 100

.section __ex_table,"a"
	.quad 1b,bad_get_user
	.quad 2b,bad_get_user
	.quad 3b,bad_get_user
	.quad 4b,bad_get_user
.previous