diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cmpxchg.c | 72 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 64 |
3 files changed, 73 insertions, 65 deletions
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index ee76eaad3001..25b4c063fbf6 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-y := intel_cacheinfo.o addon_cpuid_features.o | 5 | obj-y := intel_cacheinfo.o addon_cpuid_features.o |
6 | obj-y += proc.o feature_names.o | 6 | obj-y += proc.o feature_names.o |
7 | 7 | ||
8 | obj-$(CONFIG_X86_32) += common.o bugs.o | 8 | obj-$(CONFIG_X86_32) += common.o bugs.o cmpxchg.o |
9 | obj-$(CONFIG_X86_64) += common_64.o bugs_64.o | 9 | obj-$(CONFIG_X86_64) += common_64.o bugs_64.o |
10 | obj-$(CONFIG_X86_32) += amd.o | 10 | obj-$(CONFIG_X86_32) += amd.o |
11 | obj-$(CONFIG_X86_64) += amd_64.o | 11 | obj-$(CONFIG_X86_64) += amd_64.o |
diff --git a/arch/x86/kernel/cpu/cmpxchg.c b/arch/x86/kernel/cpu/cmpxchg.c new file mode 100644 index 000000000000..2056ccf572cc --- /dev/null +++ b/arch/x86/kernel/cpu/cmpxchg.c | |||
@@ -0,0 +1,72 @@ | |||
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 | ||
55 | |||
56 | #ifndef CONFIG_X86_CMPXCHG64 | ||
57 | unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new) | ||
58 | { | ||
59 | u64 prev; | ||
60 | unsigned long flags; | ||
61 | |||
62 | /* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */ | ||
63 | local_irq_save(flags); | ||
64 | prev = *(u64 *)ptr; | ||
65 | if (prev == old) | ||
66 | *(u64 *)ptr = new; | ||
67 | local_irq_restore(flags); | ||
68 | return prev; | ||
69 | } | ||
70 | EXPORT_SYMBOL(cmpxchg_486_u64); | ||
71 | #endif | ||
72 | |||
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 5c8959b8a42e..77618c717d76 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -307,69 +307,5 @@ static struct cpu_dev intel_cpu_dev __cpuinitdata = { | |||
307 | 307 | ||
308 | cpu_vendor_dev_register(X86_VENDOR_INTEL, &intel_cpu_dev); | 308 | cpu_vendor_dev_register(X86_VENDOR_INTEL, &intel_cpu_dev); |
309 | 309 | ||
310 | #ifndef CONFIG_X86_CMPXCHG | ||
311 | unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new) | ||
312 | { | ||
313 | u8 prev; | ||
314 | unsigned long flags; | ||
315 | |||
316 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
317 | local_irq_save(flags); | ||
318 | prev = *(u8 *)ptr; | ||
319 | if (prev == old) | ||
320 | *(u8 *)ptr = new; | ||
321 | local_irq_restore(flags); | ||
322 | return prev; | ||
323 | } | ||
324 | EXPORT_SYMBOL(cmpxchg_386_u8); | ||
325 | |||
326 | unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new) | ||
327 | { | ||
328 | u16 prev; | ||
329 | unsigned long flags; | ||
330 | |||
331 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
332 | local_irq_save(flags); | ||
333 | prev = *(u16 *)ptr; | ||
334 | if (prev == old) | ||
335 | *(u16 *)ptr = new; | ||
336 | local_irq_restore(flags); | ||
337 | return prev; | ||
338 | } | ||
339 | EXPORT_SYMBOL(cmpxchg_386_u16); | ||
340 | |||
341 | unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new) | ||
342 | { | ||
343 | u32 prev; | ||
344 | unsigned long flags; | ||
345 | |||
346 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
347 | local_irq_save(flags); | ||
348 | prev = *(u32 *)ptr; | ||
349 | if (prev == old) | ||
350 | *(u32 *)ptr = new; | ||
351 | local_irq_restore(flags); | ||
352 | return prev; | ||
353 | } | ||
354 | EXPORT_SYMBOL(cmpxchg_386_u32); | ||
355 | #endif | ||
356 | |||
357 | #ifndef CONFIG_X86_CMPXCHG64 | ||
358 | unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new) | ||
359 | { | ||
360 | u64 prev; | ||
361 | unsigned long flags; | ||
362 | |||
363 | /* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */ | ||
364 | local_irq_save(flags); | ||
365 | prev = *(u64 *)ptr; | ||
366 | if (prev == old) | ||
367 | *(u64 *)ptr = new; | ||
368 | local_irq_restore(flags); | ||
369 | return prev; | ||
370 | } | ||
371 | EXPORT_SYMBOL(cmpxchg_486_u64); | ||
372 | #endif | ||
373 | |||
374 | /* arch_initcall(intel_cpu_init); */ | 310 | /* arch_initcall(intel_cpu_init); */ |
375 | 311 | ||