diff options
| -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 | ||
