Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / lib / copy_user.S
1 /* Copyright 2002 Andi Kleen, SuSE Labs.
2  * Subject to the GNU Public License v2.
3  * 
4  * Functions to copy from and to user space.            
5  */              
6
7 #include <lwk/linkage.h>
8 #include <arch/dwarf2.h>
9
10 #include <arch/current.h>
11 #include <arch/asm-offsets.h>
12
13 /* Standard copy_to_user with segment limit checking */         
14 ENTRY(copy_to_user)
15         CFI_STARTPROC
16         GET_CURRENT(%rax)
17         movq %rdi,%rcx
18         addq %rdx,%rcx
19         jc  bad_to_user
20         cmpq tsk_arch_addr_limit(%rax),%rcx
21         jae bad_to_user
22         xorl %eax,%eax  /* clear zero flag */
23         jmp copy_user_generic_string
24         CFI_ENDPROC
25
26 ENTRY(copy_user_generic)
27         CFI_STARTPROC
28         movl $1,%ecx    /* set zero flag */
29         jmp copy_user_generic_string
30         CFI_ENDPROC
31
32 ENTRY(__copy_from_user_inatomic)
33         CFI_STARTPROC
34         xorl %ecx,%ecx  /* clear zero flag */
35         jmp copy_user_generic_string
36         CFI_ENDPROC
37
38 /* Standard copy_from_user with segment limit checking */       
39 ENTRY(copy_from_user)
40         CFI_STARTPROC
41         GET_CURRENT(%rax)
42         movq %rsi,%rcx
43         addq %rdx,%rcx
44         jc  bad_from_user
45         cmpq tsk_arch_addr_limit(%rax),%rcx
46         jae  bad_from_user
47         movl $1,%ecx    /* set zero flag */
48         jmp copy_user_generic_string
49         CFI_ENDPROC
50 ENDPROC(copy_from_user)
51         
52         .section .fixup,"ax"
53         /* must zero dest */
54 bad_from_user:
55         CFI_STARTPROC
56         movl %edx,%ecx
57         xorl %eax,%eax
58         rep
59         stosb
60 bad_to_user:
61         movl    %edx,%eax
62         ret
63         CFI_ENDPROC
64 END(bad_from_user)
65         .previous
66         
67                 
68  /* rdi destination
69   * rsi source
70   * rdx count
71   * ecx zero flag
72   *
73   * Output:
74   * eax uncopied bytes or 0 if successfull.
75   *
76   * Only 4GB of copy is supported. This shouldn't be a problem
77   * because the kernel normally only writes from/to page sized chunks
78   * even if user space passed a longer buffer.
79   * And more would be dangerous because both Intel and AMD have
80   * errata with rep movsq > 4GB. If someone feels the need to fix
81   * this please consider this.
82   */
83 ENTRY(copy_user_generic_string)
84         CFI_STARTPROC
85         movl %ecx,%r8d          /* save zero flag */
86         movl %edx,%ecx
87         shrl $3,%ecx
88         andl $7,%edx    
89         jz   10f
90 1:      rep 
91         movsq 
92         movl %edx,%ecx
93 2:      rep
94         movsb
95 9:      movl %ecx,%eax
96         ret
97
98         /* multiple of 8 byte */
99 10:     rep
100         movsq
101         xor %eax,%eax
102         ret
103
104         /* exception handling */
105 3:      lea (%rdx,%rcx,8),%rax  /* exception on quad loop */
106         jmp 6f
107 5:      movl %ecx,%eax          /* exception on byte loop */
108         /* eax: left over bytes */
109 6:      testl %r8d,%r8d         /* zero flag set? */
110         jz 7f
111         movl %eax,%ecx          /* initialize x86 loop counter */
112         push %rax
113         xorl %eax,%eax
114 8:      rep
115         stosb                   /* zero the rest */
116 11:     pop %rax
117 7:      ret
118         CFI_ENDPROC
119 END(copy_user_generic_c)
120
121         .section __ex_table,"a"
122         .quad 1b,3b
123         .quad 2b,5b
124         .quad 8b,11b
125         .quad 10b,3b
126         .previous