Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[S390] xchg/cmpxchg: move to own header file

Move xchg() and cmpxchg() functions to own header file like some
other architectures have done.
With this we make sure that system.h now really looks like a place
where everything is gathered that doesn't fit anywhere else.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Heiko Carstens and committed by
Martin Schwidefsky
a2c9dbe8 3c190c51

+206 -195
+205
arch/s390/include/asm/cmpxchg.h
··· 1 + /* 2 + * Copyright IBM Corp. 1999, 2011 3 + * 4 + * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, 5 + */ 6 + 7 + #ifndef __ASM_CMPXCHG_H 8 + #define __ASM_CMPXCHG_H 9 + 10 + #include <linux/types.h> 11 + 12 + extern void __xchg_called_with_bad_pointer(void); 13 + 14 + static inline unsigned long __xchg(unsigned long x, void *ptr, int size) 15 + { 16 + unsigned long addr, old; 17 + int shift; 18 + 19 + switch (size) { 20 + case 1: 21 + addr = (unsigned long) ptr; 22 + shift = (3 ^ (addr & 3)) << 3; 23 + addr ^= addr & 3; 24 + asm volatile( 25 + " l %0,%4\n" 26 + "0: lr 0,%0\n" 27 + " nr 0,%3\n" 28 + " or 0,%2\n" 29 + " cs %0,0,%4\n" 30 + " jl 0b\n" 31 + : "=&d" (old), "=Q" (*(int *) addr) 32 + : "d" (x << shift), "d" (~(255 << shift)), 33 + "Q" (*(int *) addr) : "memory", "cc", "0"); 34 + return old >> shift; 35 + case 2: 36 + addr = (unsigned long) ptr; 37 + shift = (2 ^ (addr & 2)) << 3; 38 + addr ^= addr & 2; 39 + asm volatile( 40 + " l %0,%4\n" 41 + "0: lr 0,%0\n" 42 + " nr 0,%3\n" 43 + " or 0,%2\n" 44 + " cs %0,0,%4\n" 45 + " jl 0b\n" 46 + : "=&d" (old), "=Q" (*(int *) addr) 47 + : "d" (x << shift), "d" (~(65535 << shift)), 48 + "Q" (*(int *) addr) : "memory", "cc", "0"); 49 + return old >> shift; 50 + case 4: 51 + asm volatile( 52 + " l %0,%3\n" 53 + "0: cs %0,%2,%3\n" 54 + " jl 0b\n" 55 + : "=&d" (old), "=Q" (*(int *) ptr) 56 + : "d" (x), "Q" (*(int *) ptr) 57 + : "memory", "cc"); 58 + return old; 59 + #ifdef CONFIG_64BIT 60 + case 8: 61 + asm volatile( 62 + " lg %0,%3\n" 63 + "0: csg %0,%2,%3\n" 64 + " jl 0b\n" 65 + : "=&d" (old), "=m" (*(long *) ptr) 66 + : "d" (x), "Q" (*(long *) ptr) 67 + : "memory", "cc"); 68 + return old; 69 + #endif /* CONFIG_64BIT */ 70 + } 71 + __xchg_called_with_bad_pointer(); 72 + return x; 73 + } 74 + 75 + #define xchg(ptr, x) \ 76 + ({ \ 77 + __typeof__(*(ptr)) __ret; \ 78 + __ret = (__typeof__(*(ptr))) \ 79 + __xchg((unsigned long)(x), (void *)(ptr), sizeof(*(ptr)));\ 80 + __ret; \ 81 + }) 82 + 83 + /* 84 + * Atomic compare and exchange. Compare OLD with MEM, if identical, 85 + * store NEW in MEM. Return the initial value in MEM. Success is 86 + * indicated by comparing RETURN with OLD. 87 + */ 88 + 89 + #define __HAVE_ARCH_CMPXCHG 90 + 91 + extern void __cmpxchg_called_with_bad_pointer(void); 92 + 93 + static inline unsigned long __cmpxchg(void *ptr, unsigned long old, 94 + unsigned long new, int size) 95 + { 96 + unsigned long addr, prev, tmp; 97 + int shift; 98 + 99 + switch (size) { 100 + case 1: 101 + addr = (unsigned long) ptr; 102 + shift = (3 ^ (addr & 3)) << 3; 103 + addr ^= addr & 3; 104 + asm volatile( 105 + " l %0,%2\n" 106 + "0: nr %0,%5\n" 107 + " lr %1,%0\n" 108 + " or %0,%3\n" 109 + " or %1,%4\n" 110 + " cs %0,%1,%2\n" 111 + " jnl 1f\n" 112 + " xr %1,%0\n" 113 + " nr %1,%5\n" 114 + " jnz 0b\n" 115 + "1:" 116 + : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) 117 + : "d" (old << shift), "d" (new << shift), 118 + "d" (~(255 << shift)), "Q" (*(int *) ptr) 119 + : "memory", "cc"); 120 + return prev >> shift; 121 + case 2: 122 + addr = (unsigned long) ptr; 123 + shift = (2 ^ (addr & 2)) << 3; 124 + addr ^= addr & 2; 125 + asm volatile( 126 + " l %0,%2\n" 127 + "0: nr %0,%5\n" 128 + " lr %1,%0\n" 129 + " or %0,%3\n" 130 + " or %1,%4\n" 131 + " cs %0,%1,%2\n" 132 + " jnl 1f\n" 133 + " xr %1,%0\n" 134 + " nr %1,%5\n" 135 + " jnz 0b\n" 136 + "1:" 137 + : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) 138 + : "d" (old << shift), "d" (new << shift), 139 + "d" (~(65535 << shift)), "Q" (*(int *) ptr) 140 + : "memory", "cc"); 141 + return prev >> shift; 142 + case 4: 143 + asm volatile( 144 + " cs %0,%3,%1\n" 145 + : "=&d" (prev), "=Q" (*(int *) ptr) 146 + : "0" (old), "d" (new), "Q" (*(int *) ptr) 147 + : "memory", "cc"); 148 + return prev; 149 + #ifdef CONFIG_64BIT 150 + case 8: 151 + asm volatile( 152 + " csg %0,%3,%1\n" 153 + : "=&d" (prev), "=Q" (*(long *) ptr) 154 + : "0" (old), "d" (new), "Q" (*(long *) ptr) 155 + : "memory", "cc"); 156 + return prev; 157 + #endif /* CONFIG_64BIT */ 158 + } 159 + __cmpxchg_called_with_bad_pointer(); 160 + return old; 161 + } 162 + 163 + #define cmpxchg(ptr, o, n) \ 164 + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ 165 + (unsigned long)(n), sizeof(*(ptr)))) 166 + 167 + #include <asm-generic/cmpxchg-local.h> 168 + 169 + static inline unsigned long __cmpxchg_local(void *ptr, 170 + unsigned long old, 171 + unsigned long new, int size) 172 + { 173 + switch (size) { 174 + case 1: 175 + case 2: 176 + case 4: 177 + #ifdef CONFIG_64BIT 178 + case 8: 179 + #endif 180 + return __cmpxchg(ptr, old, new, size); 181 + default: 182 + return __cmpxchg_local_generic(ptr, old, new, size); 183 + } 184 + 185 + return old; 186 + } 187 + 188 + /* 189 + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make 190 + * them available. 191 + */ 192 + #define cmpxchg_local(ptr, o, n) \ 193 + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ 194 + (unsigned long)(n), sizeof(*(ptr)))) 195 + #ifdef CONFIG_64BIT 196 + #define cmpxchg64_local(ptr, o, n) \ 197 + ({ \ 198 + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ 199 + cmpxchg_local((ptr), (o), (n)); \ 200 + }) 201 + #else 202 + #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) 203 + #endif 204 + 205 + #endif /* __ASM_CMPXCHG_H */
+1 -195
arch/s390/include/asm/system.h
··· 14 14 #include <asm/setup.h> 15 15 #include <asm/processor.h> 16 16 #include <asm/lowcore.h> 17 + #include <asm/cmpxchg.h> 17 18 18 19 #ifdef __KERNEL__ 19 20 ··· 121 120 122 121 #define nop() asm volatile("nop") 123 122 124 - #define xchg(ptr,x) \ 125 - ({ \ 126 - __typeof__(*(ptr)) __ret; \ 127 - __ret = (__typeof__(*(ptr))) \ 128 - __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \ 129 - __ret; \ 130 - }) 131 - 132 - extern void __xchg_called_with_bad_pointer(void); 133 - 134 - static inline unsigned long __xchg(unsigned long x, void * ptr, int size) 135 - { 136 - unsigned long addr, old; 137 - int shift; 138 - 139 - switch (size) { 140 - case 1: 141 - addr = (unsigned long) ptr; 142 - shift = (3 ^ (addr & 3)) << 3; 143 - addr ^= addr & 3; 144 - asm volatile( 145 - " l %0,%4\n" 146 - "0: lr 0,%0\n" 147 - " nr 0,%3\n" 148 - " or 0,%2\n" 149 - " cs %0,0,%4\n" 150 - " jl 0b\n" 151 - : "=&d" (old), "=Q" (*(int *) addr) 152 - : "d" (x << shift), "d" (~(255 << shift)), 153 - "Q" (*(int *) addr) : "memory", "cc", "0"); 154 - return old >> shift; 155 - case 2: 156 - addr = (unsigned long) ptr; 157 - shift = (2 ^ (addr & 2)) << 3; 158 - addr ^= addr & 2; 159 - asm volatile( 160 - " l %0,%4\n" 161 - "0: lr 0,%0\n" 162 - " nr 0,%3\n" 163 - " or 0,%2\n" 164 - " cs %0,0,%4\n" 165 - " jl 0b\n" 166 - : "=&d" (old), "=Q" (*(int *) addr) 167 - : "d" (x << shift), "d" (~(65535 << shift)), 168 - "Q" (*(int *) addr) : "memory", "cc", "0"); 169 - return old >> shift; 170 - case 4: 171 - asm volatile( 172 - " l %0,%3\n" 173 - "0: cs %0,%2,%3\n" 174 - " jl 0b\n" 175 - : "=&d" (old), "=Q" (*(int *) ptr) 176 - : "d" (x), "Q" (*(int *) ptr) 177 - : "memory", "cc"); 178 - return old; 179 - #ifdef __s390x__ 180 - case 8: 181 - asm volatile( 182 - " lg %0,%3\n" 183 - "0: csg %0,%2,%3\n" 184 - " jl 0b\n" 185 - : "=&d" (old), "=m" (*(long *) ptr) 186 - : "d" (x), "Q" (*(long *) ptr) 187 - : "memory", "cc"); 188 - return old; 189 - #endif /* __s390x__ */ 190 - } 191 - __xchg_called_with_bad_pointer(); 192 - return x; 193 - } 194 - 195 - /* 196 - * Atomic compare and exchange. Compare OLD with MEM, if identical, 197 - * store NEW in MEM. Return the initial value in MEM. Success is 198 - * indicated by comparing RETURN with OLD. 199 - */ 200 - 201 - #define __HAVE_ARCH_CMPXCHG 1 202 - 203 - #define cmpxchg(ptr, o, n) \ 204 - ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ 205 - (unsigned long)(n), sizeof(*(ptr)))) 206 - 207 - extern void __cmpxchg_called_with_bad_pointer(void); 208 - 209 - static inline unsigned long 210 - __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) 211 - { 212 - unsigned long addr, prev, tmp; 213 - int shift; 214 - 215 - switch (size) { 216 - case 1: 217 - addr = (unsigned long) ptr; 218 - shift = (3 ^ (addr & 3)) << 3; 219 - addr ^= addr & 3; 220 - asm volatile( 221 - " l %0,%2\n" 222 - "0: nr %0,%5\n" 223 - " lr %1,%0\n" 224 - " or %0,%3\n" 225 - " or %1,%4\n" 226 - " cs %0,%1,%2\n" 227 - " jnl 1f\n" 228 - " xr %1,%0\n" 229 - " nr %1,%5\n" 230 - " jnz 0b\n" 231 - "1:" 232 - : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) 233 - : "d" (old << shift), "d" (new << shift), 234 - "d" (~(255 << shift)), "Q" (*(int *) ptr) 235 - : "memory", "cc"); 236 - return prev >> shift; 237 - case 2: 238 - addr = (unsigned long) ptr; 239 - shift = (2 ^ (addr & 2)) << 3; 240 - addr ^= addr & 2; 241 - asm volatile( 242 - " l %0,%2\n" 243 - "0: nr %0,%5\n" 244 - " lr %1,%0\n" 245 - " or %0,%3\n" 246 - " or %1,%4\n" 247 - " cs %0,%1,%2\n" 248 - " jnl 1f\n" 249 - " xr %1,%0\n" 250 - " nr %1,%5\n" 251 - " jnz 0b\n" 252 - "1:" 253 - : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) 254 - : "d" (old << shift), "d" (new << shift), 255 - "d" (~(65535 << shift)), "Q" (*(int *) ptr) 256 - : "memory", "cc"); 257 - return prev >> shift; 258 - case 4: 259 - asm volatile( 260 - " cs %0,%3,%1\n" 261 - : "=&d" (prev), "=Q" (*(int *) ptr) 262 - : "0" (old), "d" (new), "Q" (*(int *) ptr) 263 - : "memory", "cc"); 264 - return prev; 265 - #ifdef __s390x__ 266 - case 8: 267 - asm volatile( 268 - " csg %0,%3,%1\n" 269 - : "=&d" (prev), "=Q" (*(long *) ptr) 270 - : "0" (old), "d" (new), "Q" (*(long *) ptr) 271 - : "memory", "cc"); 272 - return prev; 273 - #endif /* __s390x__ */ 274 - } 275 - __cmpxchg_called_with_bad_pointer(); 276 - return old; 277 - } 278 - 279 123 /* 280 124 * Force strict CPU ordering. 281 125 * And yes, this is required on UP too when we're talking ··· 198 352 __dummy &= ~(1UL << (bit)); \ 199 353 __ctl_load(__dummy, cr, cr); \ 200 354 }) 201 - 202 - #include <linux/irqflags.h> 203 - 204 - #include <asm-generic/cmpxchg-local.h> 205 - 206 - static inline unsigned long __cmpxchg_local(volatile void *ptr, 207 - unsigned long old, 208 - unsigned long new, int size) 209 - { 210 - switch (size) { 211 - case 1: 212 - case 2: 213 - case 4: 214 - #ifdef __s390x__ 215 - case 8: 216 - #endif 217 - return __cmpxchg(ptr, old, new, size); 218 - default: 219 - return __cmpxchg_local_generic(ptr, old, new, size); 220 - } 221 - 222 - return old; 223 - } 224 - 225 - /* 226 - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make 227 - * them available. 228 - */ 229 - #define cmpxchg_local(ptr, o, n) \ 230 - ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ 231 - (unsigned long)(n), sizeof(*(ptr)))) 232 - #ifdef __s390x__ 233 - #define cmpxchg64_local(ptr, o, n) \ 234 - ({ \ 235 - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ 236 - cmpxchg_local((ptr), (o), (n)); \ 237 - }) 238 - #else 239 - #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) 240 - #endif 241 355 242 356 /* 243 357 * Use to set psw mask except for the first byte which