Messages in this thread Patch in this message | | | From | Paweł Sikora <> | Subject | [PATCH] cmpxchg(8b) fixes. | Date | Sat, 7 Aug 2004 20:31:44 +0200 |
| |
Could someone look at this and fix/apply?
-- /* Copyright (C) 2003, SCO, Inc. This is valuable Intellectual Property. */
#define say(x) lie(x) --- linux-2.6.8-rc3/arch/i386/Kconfig.orig 2004-08-07 07:52:57.000000000 +0200 +++ linux-2.6.8-rc3/arch/i386/Kconfig 2004-08-07 10:37:33.204220304 +0200 @@ -342,6 +342,11 @@ depends on !M386 default y +config X86_CMPXCHG8B + bool + depends on !M386 && !M486 + default y + config X86_XADD bool depends on !M386 --- linux-2.6.8-rc3/arch/x86_64/Kconfig.orig 2004-08-07 14:22:20.000000000 +0200 +++ linux-2.6.8-rc3/arch/x86_64/Kconfig 2004-08-07 14:42:35.503414192 +0200 @@ -45,6 +45,10 @@ bool default y +config X86_CMPXCHG8B + bool + default y + config EARLY_PRINTK bool default y --- linux-2.6.8-rc3/drivers/acpi/Kconfig.orig 2004-08-03 23:28:51.000000000 +0200 +++ linux-2.6.8-rc3/drivers/acpi/Kconfig 2004-08-07 14:45:14.718209864 +0200 @@ -5,11 +5,11 @@ menu "ACPI (Advanced Configuration and Power Interface) Support" depends on !X86_VISWS depends on !IA64_HP_SIM - depends on IA64 || X86 + depends on IA64 || X86_CMPXCHG config ACPI bool "ACPI Support" - depends on IA64 || X86 + depends on IA64 || X86_CMPXCHG default y ---help--- --- linux-2.6.8-rc3/drivers/char/drm/Kconfig.orig 2004-08-03 23:28:30.000000000 +0200 +++ linux-2.6.8-rc3/drivers/char/drm/Kconfig 2004-08-07 12:49:55.413820920 +0200 @@ -6,6 +6,7 @@ # config DRM bool "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" + depends on !X86 || X86_CMPXCHG help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select --- linux-2.6.8-rc3/include/asm-i386/system.h.orig 2004-08-07 20:13:02.385439072 +0200 +++ linux-2.6.8-rc3/include/asm-i386/system.h 2004-08-07 20:19:48.638679192 +0200 @@ -5,7 +5,6 @@ #include <linux/kernel.h> #include <asm/segment.h> #include <asm/cpufeature.h> -#include <linux/bitops.h> /* for LOCK_PREFIX */ #ifdef __KERNEL__ @@ -149,8 +148,14 @@ #define __xg(x) ((struct __xchg_dummy *)(x)) +#ifdef CONFIG_X86_CMPXCHG8B +#define __HAVE_ARCH_CMPXCHG8B 1 + /* - * The semantics of XCHGCMP8B are a bit strange, this is why + * CMPXCHG8B isn't supported on Intel processors earlier + * than the Pentium processors. + * + * The semantics of CMPXCHG8B are a bit strange, this is why * there is a loop and the loading of %%eax and %%edx has to * be inside. This inlines well in most cases, the cached * cost is around ~38 cycles. (in the future we might want @@ -163,8 +168,9 @@ * of the instruction set reference 24319102.pdf. We need * the reader side to see the coherent 64bit value. */ -static inline void __set_64bit (unsigned long long * ptr, - unsigned int low, unsigned int high) +static __inline__ void __set_64bit(unsigned long long * ptr, + const unsigned int low, + const unsigned int high) { __asm__ __volatile__ ( "\n1:\t" @@ -179,29 +185,19 @@ : "ax","dx","memory"); } -static inline void __set_64bit_constant (unsigned long long *ptr, - unsigned long long value) -{ - __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL)); -} -#define ll_low(x) *(((unsigned int*)&(x))+0) -#define ll_high(x) *(((unsigned int*)&(x))+1) - -static inline void __set_64bit_var (unsigned long long *ptr, - unsigned long long value) -{ - __set_64bit(ptr,ll_low(value), ll_high(value)); -} +#define set_64bit(ptr, value) \ + (__builtin_constant_p(value) ? \ + __set_64bit(ptr, \ + (const unsigned int)(value), \ + (const unsigned int)(value >> 32ULL) \ + ) : \ + __set_64bit(ptr, \ + *(((const unsigned int *)&value) + 0), \ + *(((const unsigned int *)&value) + 1) \ + ) \ + ) -#define set_64bit(ptr,value) \ -(__builtin_constant_p(value) ? \ - __set_64bit_constant(ptr, value) : \ - __set_64bit_var(ptr, value) ) - -#define _set_64bit(ptr,value) \ -(__builtin_constant_p(value) ? \ - __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \ - __set_64bit(ptr, ll_low(value), ll_high(value)) ) +#endif /* * Note: no "lock" prefix even on SMP: xchg always implies lock anyway @@ -233,35 +229,38 @@ return x; } +#ifdef CONFIG_X86_CMPXCHG +#define __HAVE_ARCH_CMPXCHG 1 + /* * Atomic compare and exchange. Compare OLD with MEM, if identical, * store NEW in MEM. Return the initial value in MEM. Success is * indicated by comparing RETURN with OLD. + * + * CMPXCHG isn't supported on Intel processors earlier than + * the Intel486 processors. */ - -#ifdef CONFIG_X86_CMPXCHG -#define __HAVE_ARCH_CMPXCHG 1 -#endif - -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) +static __inline__ unsigned long __cmpxchg(volatile void *ptr, + const unsigned long old, + const unsigned long new, + const int size) { unsigned long prev; switch (size) { case 1: - __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" + __asm__ __volatile__(LOCK "cmpxchgb %b1,%2" : "=a"(prev) : "q"(new), "m"(*__xg(ptr)), "0"(old) : "memory"); return prev; case 2: - __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" + __asm__ __volatile__(LOCK "cmpxchgw %w1,%2" : "=a"(prev) : "q"(new), "m"(*__xg(ptr)), "0"(old) : "memory"); return prev; case 4: - __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" + __asm__ __volatile__(LOCK "cmpxchgl %1,%2" : "=a"(prev) : "q"(new), "m"(*__xg(ptr)), "0"(old) : "memory"); @@ -270,10 +269,14 @@ return old; } -#define cmpxchg(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ - (unsigned long)(n),sizeof(*(ptr)))) - +#define cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))) + +#endif + #ifdef __KERNEL__ struct alt_instr { __u8 *instr; /* original instruction */ | |