]> git.baikalelectronics.ru Git - kernel.git/commitdiff
s390/cmpxchg: use register pair instead of register asm
authorHeiko Carstens <hca@linux.ibm.com>
Thu, 17 Jun 2021 19:18:14 +0000 (21:18 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 28 Jun 2021 09:18:28 +0000 (11:18 +0200)
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/cmpxchg.h
arch/s390/include/asm/percpu.h

index 1960a7295ae5e501fad119c07ef3e368f4ea1de6..84c3f0d576c5b1272bc3785fe3ec44fcfb24715a 100644 (file)
@@ -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 */
index 918f0ba4f4d20f9934929639dcd4190b0b0f5a1e..cb5fc06904354a2e1cb523e826f02c1d171f7f55 100644 (file)
 #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