diff options
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/clear_page_64.S | 2 | ||||
-rw-r--r-- | arch/x86/lib/cmpxchg.c | 54 | ||||
-rw-r--r-- | arch/x86/lib/copy_page_64.S | 2 | ||||
-rw-r--r-- | arch/x86/lib/copy_user_64.S | 2 | ||||
-rw-r--r-- | arch/x86/lib/memcpy_64.S | 2 | ||||
-rw-r--r-- | arch/x86/lib/memset_64.S | 2 |
7 files changed, 60 insertions, 5 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index f871e04b6965..e10cf070ede0 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -30,6 +30,7 @@ ifeq ($(CONFIG_X86_32),y) | |||
30 | lib-y += checksum_32.o | 30 | lib-y += checksum_32.o |
31 | lib-y += strstr_32.o | 31 | lib-y += strstr_32.o |
32 | lib-y += semaphore_32.o string_32.o | 32 | lib-y += semaphore_32.o string_32.o |
33 | lib-y += cmpxchg.o | ||
33 | ifneq ($(CONFIG_X86_CMPXCHG64),y) | 34 | ifneq ($(CONFIG_X86_CMPXCHG64),y) |
34 | lib-y += cmpxchg8b_emu.o atomic64_386_32.o | 35 | lib-y += cmpxchg8b_emu.o atomic64_386_32.o |
35 | endif | 36 | endif |
diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S index ebeafcce04a9..aa4326bfb24a 100644 --- a/arch/x86/lib/clear_page_64.S +++ b/arch/x86/lib/clear_page_64.S | |||
@@ -52,7 +52,7 @@ ENDPROC(clear_page) | |||
52 | .align 8 | 52 | .align 8 |
53 | .quad clear_page | 53 | .quad clear_page |
54 | .quad 1b | 54 | .quad 1b |
55 | .byte X86_FEATURE_REP_GOOD | 55 | .word X86_FEATURE_REP_GOOD |
56 | .byte .Lclear_page_end - clear_page | 56 | .byte .Lclear_page_end - clear_page |
57 | .byte 2b - 1b | 57 | .byte 2b - 1b |
58 | .previous | 58 | .previous |
diff --git a/arch/x86/lib/cmpxchg.c b/arch/x86/lib/cmpxchg.c new file mode 100644 index 000000000000..5d619f6df3ee --- /dev/null +++ b/arch/x86/lib/cmpxchg.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * cmpxchg*() fallbacks for CPU not supporting these instructions | ||
3 | */ | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/smp.h> | ||
7 | #include <linux/module.h> | ||
8 | |||
9 | #ifndef CONFIG_X86_CMPXCHG | ||
10 | unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new) | ||
11 | { | ||
12 | u8 prev; | ||
13 | unsigned long flags; | ||
14 | |||
15 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
16 | local_irq_save(flags); | ||
17 | prev = *(u8 *)ptr; | ||
18 | if (prev == old) | ||
19 | *(u8 *)ptr = new; | ||
20 | local_irq_restore(flags); | ||
21 | return prev; | ||
22 | } | ||
23 | EXPORT_SYMBOL(cmpxchg_386_u8); | ||
24 | |||
25 | unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new) | ||
26 | { | ||
27 | u16 prev; | ||
28 | unsigned long flags; | ||
29 | |||
30 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
31 | local_irq_save(flags); | ||
32 | prev = *(u16 *)ptr; | ||
33 | if (prev == old) | ||
34 | *(u16 *)ptr = new; | ||
35 | local_irq_restore(flags); | ||
36 | return prev; | ||
37 | } | ||
38 | EXPORT_SYMBOL(cmpxchg_386_u16); | ||
39 | |||
40 | unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new) | ||
41 | { | ||
42 | u32 prev; | ||
43 | unsigned long flags; | ||
44 | |||
45 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
46 | local_irq_save(flags); | ||
47 | prev = *(u32 *)ptr; | ||
48 | if (prev == old) | ||
49 | *(u32 *)ptr = new; | ||
50 | local_irq_restore(flags); | ||
51 | return prev; | ||
52 | } | ||
53 | EXPORT_SYMBOL(cmpxchg_386_u32); | ||
54 | #endif | ||
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S index 727a5d46d2fc..6fec2d1cebe1 100644 --- a/arch/x86/lib/copy_page_64.S +++ b/arch/x86/lib/copy_page_64.S | |||
@@ -113,7 +113,7 @@ ENDPROC(copy_page) | |||
113 | .align 8 | 113 | .align 8 |
114 | .quad copy_page | 114 | .quad copy_page |
115 | .quad 1b | 115 | .quad 1b |
116 | .byte X86_FEATURE_REP_GOOD | 116 | .word X86_FEATURE_REP_GOOD |
117 | .byte .Lcopy_page_end - copy_page | 117 | .byte .Lcopy_page_end - copy_page |
118 | .byte 2b - 1b | 118 | .byte 2b - 1b |
119 | .previous | 119 | .previous |
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 71100c98e337..a460158b5ac5 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S | |||
@@ -29,7 +29,7 @@ | |||
29 | .align 8 | 29 | .align 8 |
30 | .quad 0b | 30 | .quad 0b |
31 | .quad 2b | 31 | .quad 2b |
32 | .byte \feature /* when feature is set */ | 32 | .word \feature /* when feature is set */ |
33 | .byte 5 | 33 | .byte 5 |
34 | .byte 5 | 34 | .byte 5 |
35 | .previous | 35 | .previous |
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index f82e884928af..bcbcd1e0f7d5 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S | |||
@@ -131,7 +131,7 @@ ENDPROC(__memcpy) | |||
131 | .align 8 | 131 | .align 8 |
132 | .quad memcpy | 132 | .quad memcpy |
133 | .quad .Lmemcpy_c | 133 | .quad .Lmemcpy_c |
134 | .byte X86_FEATURE_REP_GOOD | 134 | .word X86_FEATURE_REP_GOOD |
135 | 135 | ||
136 | /* | 136 | /* |
137 | * Replace only beginning, memcpy is used to apply alternatives, | 137 | * Replace only beginning, memcpy is used to apply alternatives, |
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index e88d3b81644a..09d344269652 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S | |||
@@ -121,7 +121,7 @@ ENDPROC(__memset) | |||
121 | .align 8 | 121 | .align 8 |
122 | .quad memset | 122 | .quad memset |
123 | .quad .Lmemset_c | 123 | .quad .Lmemset_c |
124 | .byte X86_FEATURE_REP_GOOD | 124 | .word X86_FEATURE_REP_GOOD |
125 | .byte .Lfinal - memset | 125 | .byte .Lfinal - memset |
126 | .byte .Lmemset_e - .Lmemset_c | 126 | .byte .Lmemset_e - .Lmemset_c |
127 | .previous | 127 | .previous |