]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - include/asm-x86/cmpxchg_64.h
Add a new sysfs_streq() string comparison function
[mirror_ubuntu-bionic-kernel.git] / include / asm-x86 / cmpxchg_64.h
CommitLineData
a436ed9c
JD
1#ifndef __ASM_CMPXCHG_H
2#define __ASM_CMPXCHG_H
3
4#include <asm/alternative.h> /* Provides LOCK_PREFIX */
5
e52da357
JP
6#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), \
7 (ptr), sizeof(*(ptr))))
a436ed9c
JD
8
9#define __xg(x) ((volatile long *)(x))
10
11static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
12{
13 *ptr = val;
14}
15
16#define _set_64bit set_64bit
17
18/*
19 * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
20 * Note 2: xchg has side effect, so that attribute volatile is necessary,
21 * but generally the primitive is invalid, *ptr is output argument. --ANK
22 */
e52da357
JP
23static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
24 int size)
a436ed9c
JD
25{
26 switch (size) {
e52da357
JP
27 case 1:
28 asm volatile("xchgb %b0,%1"
29 : "=q" (x)
30 : "m" (*__xg(ptr)), "0" (x)
31 : "memory");
32 break;
33 case 2:
34 asm volatile("xchgw %w0,%1"
35 : "=r" (x)
36 : "m" (*__xg(ptr)), "0" (x)
37 : "memory");
38 break;
39 case 4:
40 asm volatile("xchgl %k0,%1"
41 : "=r" (x)
42 : "m" (*__xg(ptr)), "0" (x)
43 : "memory");
44 break;
45 case 8:
46 asm volatile("xchgq %0,%1"
47 : "=r" (x)
48 : "m" (*__xg(ptr)), "0" (x)
49 : "memory");
50 break;
a436ed9c
JD
51 }
52 return x;
53}
54
55/*
56 * Atomic compare and exchange. Compare OLD with MEM, if identical,
57 * store NEW in MEM. Return the initial value in MEM. Success is
58 * indicated by comparing RETURN with OLD.
59 */
60
61#define __HAVE_ARCH_CMPXCHG 1
62
63static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
64 unsigned long new, int size)
65{
66 unsigned long prev;
67 switch (size) {
68 case 1:
e52da357
JP
69 asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
70 : "=a"(prev)
71 : "q"(new), "m"(*__xg(ptr)), "0"(old)
72 : "memory");
a436ed9c
JD
73 return prev;
74 case 2:
e52da357
JP
75 asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
76 : "=a"(prev)
77 : "r"(new), "m"(*__xg(ptr)), "0"(old)
78 : "memory");
a436ed9c
JD
79 return prev;
80 case 4:
e52da357
JP
81 asm volatile(LOCK_PREFIX "cmpxchgl %k1,%2"
82 : "=a"(prev)
83 : "r"(new), "m"(*__xg(ptr)), "0"(old)
84 : "memory");
a436ed9c
JD
85 return prev;
86 case 8:
e52da357
JP
87 asm volatile(LOCK_PREFIX "cmpxchgq %1,%2"
88 : "=a"(prev)
89 : "r"(new), "m"(*__xg(ptr)), "0"(old)
90 : "memory");
a436ed9c
JD
91 return prev;
92 }
93 return old;
94}
95
96static inline unsigned long __cmpxchg_local(volatile void *ptr,
e52da357
JP
97 unsigned long old,
98 unsigned long new, int size)
a436ed9c
JD
99{
100 unsigned long prev;
101 switch (size) {
102 case 1:
e52da357
JP
103 asm volatile("cmpxchgb %b1,%2"
104 : "=a"(prev)
105 : "q"(new), "m"(*__xg(ptr)), "0"(old)
106 : "memory");
a436ed9c
JD
107 return prev;
108 case 2:
e52da357
JP
109 asm volatile("cmpxchgw %w1,%2"
110 : "=a"(prev)
111 : "r"(new), "m"(*__xg(ptr)), "0"(old)
112 : "memory");
a436ed9c
JD
113 return prev;
114 case 4:
e52da357
JP
115 asm volatile("cmpxchgl %k1,%2"
116 : "=a"(prev)
117 : "r"(new), "m"(*__xg(ptr)), "0"(old)
118 : "memory");
a436ed9c
JD
119 return prev;
120 case 8:
e52da357
JP
121 asm volatile("cmpxchgq %1,%2"
122 : "=a"(prev)
123 : "r"(new), "m"(*__xg(ptr)), "0"(old)
124 : "memory");
a436ed9c
JD
125 return prev;
126 }
127 return old;
128}
129
32f49eab
MD
130#define cmpxchg(ptr, o, n) \
131 ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
e52da357 132 (unsigned long)(n), sizeof(*(ptr))))
32f49eab 133#define cmpxchg64(ptr, o, n) \
e52da357 134({ \
32f49eab
MD
135 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
136 cmpxchg((ptr), (o), (n)); \
e52da357 137})
32f49eab
MD
138#define cmpxchg_local(ptr, o, n) \
139 ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
e52da357
JP
140 (unsigned long)(n), \
141 sizeof(*(ptr))))
32f49eab 142#define cmpxchg64_local(ptr, o, n) \
e52da357 143({ \
32f49eab
MD
144 BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
145 cmpxchg_local((ptr), (o), (n)); \
e52da357 146})
a436ed9c
JD
147
148#endif