s390/cmpxchg: use register pair instead of register asm
Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
2bd67038f8
commit
79ee201e26
@ -169,32 +169,36 @@ static __always_inline unsigned long __cmpxchg(unsigned long address,
|
||||
|
||||
#define system_has_cmpxchg_double() 1
|
||||
|
||||
#define __cmpxchg_double(p1, p2, o1, o2, n1, n2) \
|
||||
({ \
|
||||
register __typeof__(*(p1)) __old1 asm("2") = (o1); \
|
||||
register __typeof__(*(p2)) __old2 asm("3") = (o2); \
|
||||
register __typeof__(*(p1)) __new1 asm("4") = (n1); \
|
||||
register __typeof__(*(p2)) __new2 asm("5") = (n2); \
|
||||
int cc; \
|
||||
asm volatile( \
|
||||
" cdsg %[old],%[new],%[ptr]\n" \
|
||||
" ipm %[cc]\n" \
|
||||
" srl %[cc],28" \
|
||||
: [cc] "=d" (cc), [old] "+d" (__old1), "+d" (__old2) \
|
||||
: [new] "d" (__new1), "d" (__new2), \
|
||||
[ptr] "Q" (*(p1)), "Q" (*(p2)) \
|
||||
: "memory", "cc"); \
|
||||
!cc; \
|
||||
})
|
||||
static __always_inline int __cmpxchg_double(unsigned long p1, unsigned long p2,
|
||||
unsigned long o1, unsigned long o2,
|
||||
unsigned long n1, unsigned long n2)
|
||||
{
|
||||
union register_pair old = { .even = o1, .odd = o2, };
|
||||
union register_pair new = { .even = n1, .odd = n2, };
|
||||
int cc;
|
||||
|
||||
asm volatile(
|
||||
" cdsg %[old],%[new],%[ptr]\n"
|
||||
" ipm %[cc]\n"
|
||||
" srl %[cc],28\n"
|
||||
: [cc] "=&d" (cc), [old] "+&d" (old.pair)
|
||||
: [new] "d" (new.pair),
|
||||
[ptr] "QS" (*(unsigned long *)p1), "Q" (*(unsigned long *)p2)
|
||||
: "memory", "cc");
|
||||
return !cc;
|
||||
}
|
||||
|
||||
#define arch_cmpxchg_double(p1, p2, o1, o2, n1, n2) \
|
||||
({ \
|
||||
__typeof__(p1) __p1 = (p1); \
|
||||
__typeof__(p2) __p2 = (p2); \
|
||||
typeof(p1) __p1 = (p1); \
|
||||
typeof(p2) __p2 = (p2); \
|
||||
\
|
||||
BUILD_BUG_ON(sizeof(*(p1)) != sizeof(long)); \
|
||||
BUILD_BUG_ON(sizeof(*(p2)) != sizeof(long)); \
|
||||
VM_BUG_ON((unsigned long)((__p1) + 1) != (unsigned long)(__p2));\
|
||||
__cmpxchg_double(__p1, __p2, o1, o2, n1, n2); \
|
||||
__cmpxchg_double((unsigned long)__p1, (unsigned long)__p2, \
|
||||
(unsigned long)(o1), (unsigned long)(o2), \
|
||||
(unsigned long)(n1), (unsigned long)(n2)); \
|
||||
})
|
||||
|
||||
#endif /* __ASM_CMPXCHG_H */
|
||||
|
@ -164,19 +164,20 @@
|
||||
#define this_cpu_xchg_4(pcp, nval) arch_this_cpu_xchg(pcp, nval)
|
||||
#define this_cpu_xchg_8(pcp, nval) arch_this_cpu_xchg(pcp, nval)
|
||||
|
||||
#define arch_this_cpu_cmpxchg_double(pcp1, pcp2, o1, o2, n1, n2) \
|
||||
({ \
|
||||
typeof(pcp1) o1__ = (o1), n1__ = (n1); \
|
||||
typeof(pcp2) o2__ = (o2), n2__ = (n2); \
|
||||
typeof(pcp1) *p1__; \
|
||||
typeof(pcp2) *p2__; \
|
||||
int ret__; \
|
||||
preempt_disable_notrace(); \
|
||||
p1__ = raw_cpu_ptr(&(pcp1)); \
|
||||
p2__ = raw_cpu_ptr(&(pcp2)); \
|
||||
ret__ = __cmpxchg_double(p1__, p2__, o1__, o2__, n1__, n2__); \
|
||||
preempt_enable_notrace(); \
|
||||
ret__; \
|
||||
#define arch_this_cpu_cmpxchg_double(pcp1, pcp2, o1, o2, n1, n2) \
|
||||
({ \
|
||||
typeof(pcp1) *p1__; \
|
||||
typeof(pcp2) *p2__; \
|
||||
int ret__; \
|
||||
\
|
||||
preempt_disable_notrace(); \
|
||||
p1__ = raw_cpu_ptr(&(pcp1)); \
|
||||
p2__ = raw_cpu_ptr(&(pcp2)); \
|
||||
ret__ = __cmpxchg_double((unsigned long)p1__, (unsigned long)p2__, \
|
||||
(unsigned long)(o1), (unsigned long)(o2), \
|
||||
(unsigned long)(n1), (unsigned long)(n2)); \
|
||||
preempt_enable_notrace(); \
|
||||
ret__; \
|
||||
})
|
||||
|
||||
#define this_cpu_cmpxchg_double_8 arch_this_cpu_cmpxchg_double
|
||||
|
Loading…
Reference in New Issue
Block a user