diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-09 09:00:48 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 09:00:48 -0400 |
commit | de989ef093623ab5259f885f30be699c431d4006 (patch) | |
tree | 8896b217f6f4ce6cd2d47b03b907ae0a8f4f4321 /arch/x86/lib | |
parent | a737abd11ac4eb9f4226fa8c9f1d9b5be12a96c1 (diff) | |
parent | 22cac1670786108ccd4caa0656c39fa4ba69fa7d (diff) |
Merge branch 'x86/unify-lib' into x86/core
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/lib/copy_user_64.S | 4 | ||||
-rw-r--r-- | arch/x86/lib/delay.c (renamed from arch/x86/lib/delay_32.c) | 17 | ||||
-rw-r--r-- | arch/x86/lib/delay_64.c | 85 | ||||
-rw-r--r-- | arch/x86/lib/getuser.S (renamed from arch/x86/lib/getuser_64.S) | 87 | ||||
-rw-r--r-- | arch/x86/lib/getuser_32.S | 78 | ||||
-rw-r--r-- | arch/x86/lib/putuser.S (renamed from arch/x86/lib/putuser_32.S) | 73 | ||||
-rw-r--r-- | arch/x86/lib/putuser_64.S | 106 |
8 files changed, 89 insertions, 365 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 76f60f52a885..83226e0a7ce4 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -4,8 +4,8 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_SMP) := msr-on-cpu.o | 5 | obj-$(CONFIG_SMP) := msr-on-cpu.o |
6 | 6 | ||
7 | lib-y := delay_$(BITS).o | 7 | lib-y := delay.o |
8 | lib-y += usercopy_$(BITS).o getuser_$(BITS).o putuser_$(BITS).o | 8 | lib-y += usercopy_$(BITS).o getuser.o putuser.o |
9 | lib-y += memcpy_$(BITS).o | 9 | lib-y += memcpy_$(BITS).o |
10 | 10 | ||
11 | ifeq ($(CONFIG_X86_32),y) | 11 | ifeq ($(CONFIG_X86_32),y) |
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index ee1c3f635157..7eaaf0123b4d 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S | |||
@@ -40,7 +40,7 @@ ENTRY(copy_to_user) | |||
40 | movq %rdi,%rcx | 40 | movq %rdi,%rcx |
41 | addq %rdx,%rcx | 41 | addq %rdx,%rcx |
42 | jc bad_to_user | 42 | jc bad_to_user |
43 | cmpq threadinfo_addr_limit(%rax),%rcx | 43 | cmpq TI_addr_limit(%rax),%rcx |
44 | jae bad_to_user | 44 | jae bad_to_user |
45 | xorl %eax,%eax /* clear zero flag */ | 45 | xorl %eax,%eax /* clear zero flag */ |
46 | ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string | 46 | ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string |
@@ -65,7 +65,7 @@ ENTRY(copy_from_user) | |||
65 | movq %rsi,%rcx | 65 | movq %rsi,%rcx |
66 | addq %rdx,%rcx | 66 | addq %rdx,%rcx |
67 | jc bad_from_user | 67 | jc bad_from_user |
68 | cmpq threadinfo_addr_limit(%rax),%rcx | 68 | cmpq TI_addr_limit(%rax),%rcx |
69 | jae bad_from_user | 69 | jae bad_from_user |
70 | movl $1,%ecx /* set zero flag */ | 70 | movl $1,%ecx /* set zero flag */ |
71 | ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string | 71 | ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string |
diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay.c index ef691316f8b6..f4568605d7d5 100644 --- a/arch/x86/lib/delay_32.c +++ b/arch/x86/lib/delay.c | |||
@@ -29,7 +29,7 @@ | |||
29 | /* simple loop based delay: */ | 29 | /* simple loop based delay: */ |
30 | static void delay_loop(unsigned long loops) | 30 | static void delay_loop(unsigned long loops) |
31 | { | 31 | { |
32 | __asm__ __volatile__( | 32 | asm volatile( |
33 | " test %0,%0 \n" | 33 | " test %0,%0 \n" |
34 | " jz 3f \n" | 34 | " jz 3f \n" |
35 | " jmp 1f \n" | 35 | " jmp 1f \n" |
@@ -38,9 +38,9 @@ static void delay_loop(unsigned long loops) | |||
38 | "1: jmp 2f \n" | 38 | "1: jmp 2f \n" |
39 | 39 | ||
40 | ".align 16 \n" | 40 | ".align 16 \n" |
41 | "2: decl %0 \n" | 41 | "2: dec %0 \n" |
42 | " jnz 2b \n" | 42 | " jnz 2b \n" |
43 | "3: decl %0 \n" | 43 | "3: dec %0 \n" |
44 | 44 | ||
45 | : /* we don't need output */ | 45 | : /* we don't need output */ |
46 | :"a" (loops) | 46 | :"a" (loops) |
@@ -98,7 +98,7 @@ void use_tsc_delay(void) | |||
98 | int __devinit read_current_timer(unsigned long *timer_val) | 98 | int __devinit read_current_timer(unsigned long *timer_val) |
99 | { | 99 | { |
100 | if (delay_fn == delay_tsc) { | 100 | if (delay_fn == delay_tsc) { |
101 | rdtscl(*timer_val); | 101 | rdtscll(*timer_val); |
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | return -1; | 104 | return -1; |
@@ -108,31 +108,30 @@ void __delay(unsigned long loops) | |||
108 | { | 108 | { |
109 | delay_fn(loops); | 109 | delay_fn(loops); |
110 | } | 110 | } |
111 | EXPORT_SYMBOL(__delay); | ||
111 | 112 | ||
112 | inline void __const_udelay(unsigned long xloops) | 113 | inline void __const_udelay(unsigned long xloops) |
113 | { | 114 | { |
114 | int d0; | 115 | int d0; |
115 | 116 | ||
116 | xloops *= 4; | 117 | xloops *= 4; |
117 | __asm__("mull %0" | 118 | asm("mull %%edx" |
118 | :"=d" (xloops), "=&a" (d0) | 119 | :"=d" (xloops), "=&a" (d0) |
119 | :"1" (xloops), "0" | 120 | :"1" (xloops), "0" |
120 | (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); | 121 | (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4))); |
121 | 122 | ||
122 | __delay(++xloops); | 123 | __delay(++xloops); |
123 | } | 124 | } |
125 | EXPORT_SYMBOL(__const_udelay); | ||
124 | 126 | ||
125 | void __udelay(unsigned long usecs) | 127 | void __udelay(unsigned long usecs) |
126 | { | 128 | { |
127 | __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ | 129 | __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ |
128 | } | 130 | } |
131 | EXPORT_SYMBOL(__udelay); | ||
129 | 132 | ||
130 | void __ndelay(unsigned long nsecs) | 133 | void __ndelay(unsigned long nsecs) |
131 | { | 134 | { |
132 | __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ | 135 | __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ |
133 | } | 136 | } |
134 | |||
135 | EXPORT_SYMBOL(__delay); | ||
136 | EXPORT_SYMBOL(__const_udelay); | ||
137 | EXPORT_SYMBOL(__udelay); | ||
138 | EXPORT_SYMBOL(__ndelay); | 137 | EXPORT_SYMBOL(__ndelay); |
diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c deleted file mode 100644 index 4c441be92641..000000000000 --- a/arch/x86/lib/delay_64.c +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | /* | ||
2 | * Precise Delay Loops for x86-64 | ||
3 | * | ||
4 | * Copyright (C) 1993 Linus Torvalds | ||
5 | * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||
6 | * | ||
7 | * The __delay function must _NOT_ be inlined as its execution time | ||
8 | * depends wildly on alignment on many x86 processors. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/timex.h> | ||
14 | #include <linux/preempt.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/init.h> | ||
17 | |||
18 | #include <asm/delay.h> | ||
19 | #include <asm/msr.h> | ||
20 | |||
21 | #ifdef CONFIG_SMP | ||
22 | #include <asm/smp.h> | ||
23 | #endif | ||
24 | |||
25 | int __devinit read_current_timer(unsigned long *timer_value) | ||
26 | { | ||
27 | rdtscll(*timer_value); | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | void __delay(unsigned long loops) | ||
32 | { | ||
33 | unsigned bclock, now; | ||
34 | int cpu; | ||
35 | |||
36 | preempt_disable(); | ||
37 | cpu = smp_processor_id(); | ||
38 | rdtscl(bclock); | ||
39 | for (;;) { | ||
40 | rdtscl(now); | ||
41 | if ((now - bclock) >= loops) | ||
42 | break; | ||
43 | |||
44 | /* Allow RT tasks to run */ | ||
45 | preempt_enable(); | ||
46 | rep_nop(); | ||
47 | preempt_disable(); | ||
48 | |||
49 | /* | ||
50 | * It is possible that we moved to another CPU, and | ||
51 | * since TSC's are per-cpu we need to calculate | ||
52 | * that. The delay must guarantee that we wait "at | ||
53 | * least" the amount of time. Being moved to another | ||
54 | * CPU could make the wait longer but we just need to | ||
55 | * make sure we waited long enough. Rebalance the | ||
56 | * counter for this CPU. | ||
57 | */ | ||
58 | if (unlikely(cpu != smp_processor_id())) { | ||
59 | loops -= (now - bclock); | ||
60 | cpu = smp_processor_id(); | ||
61 | rdtscl(bclock); | ||
62 | } | ||
63 | } | ||
64 | preempt_enable(); | ||
65 | } | ||
66 | EXPORT_SYMBOL(__delay); | ||
67 | |||
68 | inline void __const_udelay(unsigned long xloops) | ||
69 | { | ||
70 | __delay(((xloops * HZ * | ||
71 | cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1); | ||
72 | } | ||
73 | EXPORT_SYMBOL(__const_udelay); | ||
74 | |||
75 | void __udelay(unsigned long usecs) | ||
76 | { | ||
77 | __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ | ||
78 | } | ||
79 | EXPORT_SYMBOL(__udelay); | ||
80 | |||
81 | void __ndelay(unsigned long nsecs) | ||
82 | { | ||
83 | __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ | ||
84 | } | ||
85 | EXPORT_SYMBOL(__ndelay); | ||
diff --git a/arch/x86/lib/getuser_64.S b/arch/x86/lib/getuser.S index 5448876261f8..ad374003742f 100644 --- a/arch/x86/lib/getuser_64.S +++ b/arch/x86/lib/getuser.S | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * (C) Copyright 1998 Linus Torvalds | 4 | * (C) Copyright 1998 Linus Torvalds |
5 | * (C) Copyright 2005 Andi Kleen | 5 | * (C) Copyright 2005 Andi Kleen |
6 | * (C) Copyright 2008 Glauber Costa | ||
6 | * | 7 | * |
7 | * These functions have a non-standard call interface | 8 | * These functions have a non-standard call interface |
8 | * to make them more efficient, especially as they | 9 | * to make them more efficient, especially as they |
@@ -13,14 +14,13 @@ | |||
13 | /* | 14 | /* |
14 | * __get_user_X | 15 | * __get_user_X |
15 | * | 16 | * |
16 | * Inputs: %rcx contains the address. | 17 | * Inputs: %[r|e]ax contains the address. |
17 | * The register is modified, but all changes are undone | 18 | * The register is modified, but all changes are undone |
18 | * before returning because the C code doesn't know about it. | 19 | * before returning because the C code doesn't know about it. |
19 | * | 20 | * |
20 | * Outputs: %rax is error code (0 or -EFAULT) | 21 | * Outputs: %[r|e]ax is error code (0 or -EFAULT) |
21 | * %rdx contains zero-extended value | 22 | * %[r|e]dx contains zero-extended value |
22 | * | 23 | * |
23 | * %r8 is destroyed. | ||
24 | * | 24 | * |
25 | * These functions should not modify any other registers, | 25 | * These functions should not modify any other registers, |
26 | * as they get called from within inline assembly. | 26 | * as they get called from within inline assembly. |
@@ -32,78 +32,73 @@ | |||
32 | #include <asm/errno.h> | 32 | #include <asm/errno.h> |
33 | #include <asm/asm-offsets.h> | 33 | #include <asm/asm-offsets.h> |
34 | #include <asm/thread_info.h> | 34 | #include <asm/thread_info.h> |
35 | #include <asm/asm.h> | ||
35 | 36 | ||
36 | .text | 37 | .text |
37 | ENTRY(__get_user_1) | 38 | ENTRY(__get_user_1) |
38 | CFI_STARTPROC | 39 | CFI_STARTPROC |
39 | GET_THREAD_INFO(%r8) | 40 | GET_THREAD_INFO(%_ASM_DX) |
40 | cmpq threadinfo_addr_limit(%r8),%rcx | 41 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
41 | jae bad_get_user | 42 | jae bad_get_user |
42 | 1: movzb (%rcx),%edx | 43 | 1: movzb (%_ASM_AX),%edx |
43 | xorl %eax,%eax | 44 | xor %eax,%eax |
44 | ret | 45 | ret |
45 | CFI_ENDPROC | 46 | CFI_ENDPROC |
46 | ENDPROC(__get_user_1) | 47 | ENDPROC(__get_user_1) |
47 | 48 | ||
48 | ENTRY(__get_user_2) | 49 | ENTRY(__get_user_2) |
49 | CFI_STARTPROC | 50 | CFI_STARTPROC |
50 | GET_THREAD_INFO(%r8) | 51 | add $1,%_ASM_AX |
51 | addq $1,%rcx | 52 | jc bad_get_user |
52 | jc 20f | 53 | GET_THREAD_INFO(%_ASM_DX) |
53 | cmpq threadinfo_addr_limit(%r8),%rcx | 54 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
54 | jae 20f | 55 | jae bad_get_user |
55 | decq %rcx | 56 | 2: movzwl -1(%_ASM_AX),%edx |
56 | 2: movzwl (%rcx),%edx | 57 | xor %eax,%eax |
57 | xorl %eax,%eax | ||
58 | ret | 58 | ret |
59 | 20: decq %rcx | ||
60 | jmp bad_get_user | ||
61 | CFI_ENDPROC | 59 | CFI_ENDPROC |
62 | ENDPROC(__get_user_2) | 60 | ENDPROC(__get_user_2) |
63 | 61 | ||
64 | ENTRY(__get_user_4) | 62 | ENTRY(__get_user_4) |
65 | CFI_STARTPROC | 63 | CFI_STARTPROC |
66 | GET_THREAD_INFO(%r8) | 64 | add $3,%_ASM_AX |
67 | addq $3,%rcx | 65 | jc bad_get_user |
68 | jc 30f | 66 | GET_THREAD_INFO(%_ASM_DX) |
69 | cmpq threadinfo_addr_limit(%r8),%rcx | 67 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
70 | jae 30f | 68 | jae bad_get_user |
71 | subq $3,%rcx | 69 | 3: mov -3(%_ASM_AX),%edx |
72 | 3: movl (%rcx),%edx | 70 | xor %eax,%eax |
73 | xorl %eax,%eax | ||
74 | ret | 71 | ret |
75 | 30: subq $3,%rcx | ||
76 | jmp bad_get_user | ||
77 | CFI_ENDPROC | 72 | CFI_ENDPROC |
78 | ENDPROC(__get_user_4) | 73 | ENDPROC(__get_user_4) |
79 | 74 | ||
75 | #ifdef CONFIG_X86_64 | ||
80 | ENTRY(__get_user_8) | 76 | ENTRY(__get_user_8) |
81 | CFI_STARTPROC | 77 | CFI_STARTPROC |
82 | GET_THREAD_INFO(%r8) | 78 | add $7,%_ASM_AX |
83 | addq $7,%rcx | 79 | jc bad_get_user |
84 | jc 40f | 80 | GET_THREAD_INFO(%_ASM_DX) |
85 | cmpq threadinfo_addr_limit(%r8),%rcx | 81 | cmp TI_addr_limit(%_ASM_DX),%_ASM_AX |
86 | jae 40f | 82 | jae bad_get_user |
87 | subq $7,%rcx | 83 | 4: movq -7(%_ASM_AX),%_ASM_DX |
88 | 4: movq (%rcx),%rdx | 84 | xor %eax,%eax |
89 | xorl %eax,%eax | ||
90 | ret | 85 | ret |
91 | 40: subq $7,%rcx | ||
92 | jmp bad_get_user | ||
93 | CFI_ENDPROC | 86 | CFI_ENDPROC |
94 | ENDPROC(__get_user_8) | 87 | ENDPROC(__get_user_8) |
88 | #endif | ||
95 | 89 | ||
96 | bad_get_user: | 90 | bad_get_user: |
97 | CFI_STARTPROC | 91 | CFI_STARTPROC |
98 | xorl %edx,%edx | 92 | xor %edx,%edx |
99 | movq $(-EFAULT),%rax | 93 | mov $(-EFAULT),%_ASM_AX |
100 | ret | 94 | ret |
101 | CFI_ENDPROC | 95 | CFI_ENDPROC |
102 | END(bad_get_user) | 96 | END(bad_get_user) |
103 | 97 | ||
104 | .section __ex_table,"a" | 98 | .section __ex_table,"a" |
105 | .quad 1b,bad_get_user | 99 | _ASM_PTR 1b,bad_get_user |
106 | .quad 2b,bad_get_user | 100 | _ASM_PTR 2b,bad_get_user |
107 | .quad 3b,bad_get_user | 101 | _ASM_PTR 3b,bad_get_user |
108 | .quad 4b,bad_get_user | 102 | #ifdef CONFIG_X86_64 |
109 | .previous | 103 | _ASM_PTR 4b,bad_get_user |
104 | #endif | ||
diff --git a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S deleted file mode 100644 index 6d84b53f12a2..000000000000 --- a/arch/x86/lib/getuser_32.S +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* | ||
2 | * __get_user functions. | ||
3 | * | ||
4 | * (C) Copyright 1998 Linus Torvalds | ||
5 | * | ||
6 | * These functions have a non-standard call interface | ||
7 | * to make them more efficient, especially as they | ||
8 | * return an error value in addition to the "real" | ||
9 | * return value. | ||
10 | */ | ||
11 | #include <linux/linkage.h> | ||
12 | #include <asm/dwarf2.h> | ||
13 | #include <asm/thread_info.h> | ||
14 | |||
15 | |||
16 | /* | ||
17 | * __get_user_X | ||
18 | * | ||
19 | * Inputs: %eax contains the address | ||
20 | * | ||
21 | * Outputs: %eax is error code (0 or -EFAULT) | ||
22 | * %edx contains zero-extended value | ||
23 | * | ||
24 | * These functions should not modify any other registers, | ||
25 | * as they get called from within inline assembly. | ||
26 | */ | ||
27 | |||
28 | .text | ||
29 | ENTRY(__get_user_1) | ||
30 | CFI_STARTPROC | ||
31 | GET_THREAD_INFO(%edx) | ||
32 | cmpl TI_addr_limit(%edx),%eax | ||
33 | jae bad_get_user | ||
34 | 1: movzbl (%eax),%edx | ||
35 | xorl %eax,%eax | ||
36 | ret | ||
37 | CFI_ENDPROC | ||
38 | ENDPROC(__get_user_1) | ||
39 | |||
40 | ENTRY(__get_user_2) | ||
41 | CFI_STARTPROC | ||
42 | addl $1,%eax | ||
43 | jc bad_get_user | ||
44 | GET_THREAD_INFO(%edx) | ||
45 | cmpl TI_addr_limit(%edx),%eax | ||
46 | jae bad_get_user | ||
47 | 2: movzwl -1(%eax),%edx | ||
48 | xorl %eax,%eax | ||
49 | ret | ||
50 | CFI_ENDPROC | ||
51 | ENDPROC(__get_user_2) | ||
52 | |||
53 | ENTRY(__get_user_4) | ||
54 | CFI_STARTPROC | ||
55 | addl $3,%eax | ||
56 | jc bad_get_user | ||
57 | GET_THREAD_INFO(%edx) | ||
58 | cmpl TI_addr_limit(%edx),%eax | ||
59 | jae bad_get_user | ||
60 | 3: movl -3(%eax),%edx | ||
61 | xorl %eax,%eax | ||
62 | ret | ||
63 | CFI_ENDPROC | ||
64 | ENDPROC(__get_user_4) | ||
65 | |||
66 | bad_get_user: | ||
67 | CFI_STARTPROC | ||
68 | xorl %edx,%edx | ||
69 | movl $-14,%eax | ||
70 | ret | ||
71 | CFI_ENDPROC | ||
72 | END(bad_get_user) | ||
73 | |||
74 | .section __ex_table,"a" | ||
75 | .long 1b,bad_get_user | ||
76 | .long 2b,bad_get_user | ||
77 | .long 3b,bad_get_user | ||
78 | .previous | ||
diff --git a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser.S index f58fba109d18..36b0d15ae6e9 100644 --- a/arch/x86/lib/putuser_32.S +++ b/arch/x86/lib/putuser.S | |||
@@ -2,6 +2,8 @@ | |||
2 | * __put_user functions. | 2 | * __put_user functions. |
3 | * | 3 | * |
4 | * (C) Copyright 2005 Linus Torvalds | 4 | * (C) Copyright 2005 Linus Torvalds |
5 | * (C) Copyright 2005 Andi Kleen | ||
6 | * (C) Copyright 2008 Glauber Costa | ||
5 | * | 7 | * |
6 | * These functions have a non-standard call interface | 8 | * These functions have a non-standard call interface |
7 | * to make them more efficient, especially as they | 9 | * to make them more efficient, especially as they |
@@ -11,6 +13,8 @@ | |||
11 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
12 | #include <asm/dwarf2.h> | 14 | #include <asm/dwarf2.h> |
13 | #include <asm/thread_info.h> | 15 | #include <asm/thread_info.h> |
16 | #include <asm/errno.h> | ||
17 | #include <asm/asm.h> | ||
14 | 18 | ||
15 | 19 | ||
16 | /* | 20 | /* |
@@ -26,73 +30,68 @@ | |||
26 | */ | 30 | */ |
27 | 31 | ||
28 | #define ENTER CFI_STARTPROC ; \ | 32 | #define ENTER CFI_STARTPROC ; \ |
29 | pushl %ebx ; \ | 33 | GET_THREAD_INFO(%_ASM_BX) |
30 | CFI_ADJUST_CFA_OFFSET 4 ; \ | 34 | #define EXIT ret ; \ |
31 | CFI_REL_OFFSET ebx, 0 ; \ | ||
32 | GET_THREAD_INFO(%ebx) | ||
33 | #define EXIT popl %ebx ; \ | ||
34 | CFI_ADJUST_CFA_OFFSET -4 ; \ | ||
35 | CFI_RESTORE ebx ; \ | ||
36 | ret ; \ | ||
37 | CFI_ENDPROC | 35 | CFI_ENDPROC |
38 | 36 | ||
39 | .text | 37 | .text |
40 | ENTRY(__put_user_1) | 38 | ENTRY(__put_user_1) |
41 | ENTER | 39 | ENTER |
42 | cmpl TI_addr_limit(%ebx),%ecx | 40 | cmp TI_addr_limit(%_ASM_BX),%_ASM_CX |
43 | jae bad_put_user | 41 | jae bad_put_user |
44 | 1: movb %al,(%ecx) | 42 | 1: movb %al,(%_ASM_CX) |
45 | xorl %eax,%eax | 43 | xor %eax,%eax |
46 | EXIT | 44 | EXIT |
47 | ENDPROC(__put_user_1) | 45 | ENDPROC(__put_user_1) |
48 | 46 | ||
49 | ENTRY(__put_user_2) | 47 | ENTRY(__put_user_2) |
50 | ENTER | 48 | ENTER |
51 | movl TI_addr_limit(%ebx),%ebx | 49 | mov TI_addr_limit(%_ASM_BX),%_ASM_BX |
52 | subl $1,%ebx | 50 | sub $1,%_ASM_BX |
53 | cmpl %ebx,%ecx | 51 | cmp %_ASM_BX,%_ASM_CX |
54 | jae bad_put_user | 52 | jae bad_put_user |
55 | 2: movw %ax,(%ecx) | 53 | 2: movw %ax,(%_ASM_CX) |
56 | xorl %eax,%eax | 54 | xor %eax,%eax |
57 | EXIT | 55 | EXIT |
58 | ENDPROC(__put_user_2) | 56 | ENDPROC(__put_user_2) |
59 | 57 | ||
60 | ENTRY(__put_user_4) | 58 | ENTRY(__put_user_4) |
61 | ENTER | 59 | ENTER |
62 | movl TI_addr_limit(%ebx),%ebx | 60 | mov TI_addr_limit(%_ASM_BX),%_ASM_BX |
63 | subl $3,%ebx | 61 | sub $3,%_ASM_BX |
64 | cmpl %ebx,%ecx | 62 | cmp %_ASM_BX,%_ASM_CX |
65 | jae bad_put_user | 63 | jae bad_put_user |
66 | 3: movl %eax,(%ecx) | 64 | 3: movl %eax,(%_ASM_CX) |
67 | xorl %eax,%eax | 65 | xor %eax,%eax |
68 | EXIT | 66 | EXIT |
69 | ENDPROC(__put_user_4) | 67 | ENDPROC(__put_user_4) |
70 | 68 | ||
71 | ENTRY(__put_user_8) | 69 | ENTRY(__put_user_8) |
72 | ENTER | 70 | ENTER |
73 | movl TI_addr_limit(%ebx),%ebx | 71 | mov TI_addr_limit(%_ASM_BX),%_ASM_BX |
74 | subl $7,%ebx | 72 | sub $7,%_ASM_BX |
75 | cmpl %ebx,%ecx | 73 | cmp %_ASM_BX,%_ASM_CX |
76 | jae bad_put_user | 74 | jae bad_put_user |
77 | 4: movl %eax,(%ecx) | 75 | 4: mov %_ASM_AX,(%_ASM_CX) |
78 | 5: movl %edx,4(%ecx) | 76 | #ifdef CONFIG_X86_32 |
79 | xorl %eax,%eax | 77 | 5: movl %edx,4(%_ASM_CX) |
78 | #endif | ||
79 | xor %eax,%eax | ||
80 | EXIT | 80 | EXIT |
81 | ENDPROC(__put_user_8) | 81 | ENDPROC(__put_user_8) |
82 | 82 | ||
83 | bad_put_user: | 83 | bad_put_user: |
84 | CFI_STARTPROC simple | 84 | CFI_STARTPROC |
85 | CFI_DEF_CFA esp, 2*4 | 85 | movl $-EFAULT,%eax |
86 | CFI_OFFSET eip, -1*4 | ||
87 | CFI_OFFSET ebx, -2*4 | ||
88 | movl $-14,%eax | ||
89 | EXIT | 86 | EXIT |
90 | END(bad_put_user) | 87 | END(bad_put_user) |
91 | 88 | ||
92 | .section __ex_table,"a" | 89 | .section __ex_table,"a" |
93 | .long 1b,bad_put_user | 90 | _ASM_PTR 1b,bad_put_user |
94 | .long 2b,bad_put_user | 91 | _ASM_PTR 2b,bad_put_user |
95 | .long 3b,bad_put_user | 92 | _ASM_PTR 3b,bad_put_user |
96 | .long 4b,bad_put_user | 93 | _ASM_PTR 4b,bad_put_user |
97 | .long 5b,bad_put_user | 94 | #ifdef CONFIG_X86_32 |
95 | _ASM_PTR 5b,bad_put_user | ||
96 | #endif | ||
98 | .previous | 97 | .previous |
diff --git a/arch/x86/lib/putuser_64.S b/arch/x86/lib/putuser_64.S deleted file mode 100644 index 4989f5a8fa9b..000000000000 --- a/arch/x86/lib/putuser_64.S +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | /* | ||
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/dwarf2.h> | ||
29 | #include <asm/page.h> | ||
30 | #include <asm/errno.h> | ||
31 | #include <asm/asm-offsets.h> | ||
32 | #include <asm/thread_info.h> | ||
33 | |||
34 | .text | ||
35 | ENTRY(__put_user_1) | ||
36 | CFI_STARTPROC | ||
37 | GET_THREAD_INFO(%r8) | ||
38 | cmpq threadinfo_addr_limit(%r8),%rcx | ||
39 | jae bad_put_user | ||
40 | 1: movb %dl,(%rcx) | ||
41 | xorl %eax,%eax | ||
42 | ret | ||
43 | CFI_ENDPROC | ||
44 | ENDPROC(__put_user_1) | ||
45 | |||
46 | ENTRY(__put_user_2) | ||
47 | CFI_STARTPROC | ||
48 | GET_THREAD_INFO(%r8) | ||
49 | addq $1,%rcx | ||
50 | jc 20f | ||
51 | cmpq threadinfo_addr_limit(%r8),%rcx | ||
52 | jae 20f | ||
53 | decq %rcx | ||
54 | 2: movw %dx,(%rcx) | ||
55 | xorl %eax,%eax | ||
56 | ret | ||
57 | 20: decq %rcx | ||
58 | jmp bad_put_user | ||
59 | CFI_ENDPROC | ||
60 | ENDPROC(__put_user_2) | ||
61 | |||
62 | ENTRY(__put_user_4) | ||
63 | CFI_STARTPROC | ||
64 | GET_THREAD_INFO(%r8) | ||
65 | addq $3,%rcx | ||
66 | jc 30f | ||
67 | cmpq threadinfo_addr_limit(%r8),%rcx | ||
68 | jae 30f | ||
69 | subq $3,%rcx | ||
70 | 3: movl %edx,(%rcx) | ||
71 | xorl %eax,%eax | ||
72 | ret | ||
73 | 30: subq $3,%rcx | ||
74 | jmp bad_put_user | ||
75 | CFI_ENDPROC | ||
76 | ENDPROC(__put_user_4) | ||
77 | |||
78 | ENTRY(__put_user_8) | ||
79 | CFI_STARTPROC | ||
80 | GET_THREAD_INFO(%r8) | ||
81 | addq $7,%rcx | ||
82 | jc 40f | ||
83 | cmpq threadinfo_addr_limit(%r8),%rcx | ||
84 | jae 40f | ||
85 | subq $7,%rcx | ||
86 | 4: movq %rdx,(%rcx) | ||
87 | xorl %eax,%eax | ||
88 | ret | ||
89 | 40: subq $7,%rcx | ||
90 | jmp bad_put_user | ||
91 | CFI_ENDPROC | ||
92 | ENDPROC(__put_user_8) | ||
93 | |||
94 | bad_put_user: | ||
95 | CFI_STARTPROC | ||
96 | movq $(-EFAULT),%rax | ||
97 | ret | ||
98 | CFI_ENDPROC | ||
99 | END(bad_put_user) | ||
100 | |||
101 | .section __ex_table,"a" | ||
102 | .quad 1b,bad_put_user | ||
103 | .quad 2b,bad_put_user | ||
104 | .quad 3b,bad_put_user | ||
105 | .quad 4b,bad_put_user | ||
106 | .previous | ||