blob: 7f5593974e2d0b101c35091b267792943fbe9451 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * __put_user functions.
3 *
4 * (C) Copyright 1998 Linus Torvalds
5 * (C) Copyright 2005 Andi Kleen
6 *
7 * These functions have a non-standard call interface
8 * to make them more efficient, especially as they
9 * return an error value in addition to the "real"
10 * return value.
11 */
12
13/*
14 * __put_user_X
15 *
16 * Inputs: %rcx contains the address
17 * %rdx contains new value
18 *
19 * Outputs: %rax is error code (0 or -EFAULT)
20 *
21 * %r8 is destroyed.
22 *
23 * These functions should not modify any other registers,
24 * as they get called from within inline assembly.
25 */
26
27#include <linux/linkage.h>
28#include <asm/page.h>
29#include <asm/errno.h>
Sam Ravnborge2d5df92005-09-09 21:28:48 +020030#include <asm/asm-offsets.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <asm/thread_info.h>
32
33 .text
34 .p2align 4
35.globl __put_user_1
36__put_user_1:
37 GET_THREAD_INFO(%r8)
38 cmpq threadinfo_addr_limit(%r8),%rcx
39 jae bad_put_user
401: movb %dl,(%rcx)
41 xorl %eax,%eax
42 ret
43
44 .p2align 4
45.globl __put_user_2
46__put_user_2:
47 GET_THREAD_INFO(%r8)
48 addq $1,%rcx
Alexander Nyberg3a6fd752005-04-21 07:59:51 -070049 jc 20f
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 cmpq threadinfo_addr_limit(%r8),%rcx
Alexander Nyberg3a6fd752005-04-21 07:59:51 -070051 jae 20f
Alexander Nybergefab7732005-04-22 10:22:07 -070052 decq %rcx
532: movw %dx,(%rcx)
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 xorl %eax,%eax
55 ret
Alexander Nyberg3a6fd752005-04-21 07:59:51 -07005620: decq %rcx
57 jmp bad_put_user
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59 .p2align 4
60.globl __put_user_4
61__put_user_4:
62 GET_THREAD_INFO(%r8)
63 addq $3,%rcx
Alexander Nyberg3a6fd752005-04-21 07:59:51 -070064 jc 30f
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 cmpq threadinfo_addr_limit(%r8),%rcx
Alexander Nyberg3a6fd752005-04-21 07:59:51 -070066 jae 30f
Alexander Nybergefab7732005-04-22 10:22:07 -070067 subq $3,%rcx
683: movl %edx,(%rcx)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069 xorl %eax,%eax
70 ret
Alexander Nyberg3a6fd752005-04-21 07:59:51 -07007130: subq $3,%rcx
72 jmp bad_put_user
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74 .p2align 4
75.globl __put_user_8
76__put_user_8:
77 GET_THREAD_INFO(%r8)
78 addq $7,%rcx
Alexander Nyberg3a6fd752005-04-21 07:59:51 -070079 jc 40f
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 cmpq threadinfo_addr_limit(%r8),%rcx
Alexander Nyberg3a6fd752005-04-21 07:59:51 -070081 jae 40f
Alexander Nybergefab7732005-04-22 10:22:07 -070082 subq $7,%rcx
834: movq %rdx,(%rcx)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 xorl %eax,%eax
85 ret
Alexander Nyberg3a6fd752005-04-21 07:59:51 -07008640: subq $7,%rcx
87 jmp bad_put_user
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89bad_put_user:
90 movq $(-EFAULT),%rax
91 ret
92
93.section __ex_table,"a"
94 .quad 1b,bad_put_user
95 .quad 2b,bad_put_user
96 .quad 3b,bad_put_user
97 .quad 4b,bad_put_user
98.previous