]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/pci: Convert to use flag output macros
authorHeiko Carstens <hca@linux.ibm.com>
Thu, 7 Nov 2024 15:11:48 +0000 (16:11 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Wed, 13 Nov 2024 13:31:33 +0000 (14:31 +0100)
Use flag output macros in inline asm to allow for better code generation if
the compiler has support for the flag output constraint.

Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Tested-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/pci/pci_clp.c
arch/s390/pci/pci_insn.c
arch/s390/pci/pci_mmio.c

index 08987ac8dd35f47684915561513abaf5b4d2b04e..14bf7e8d06b7a75dc8820e47d46a5f6e260045c6 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/asm-extable.h>
 #include <asm/pci_debug.h>
 #include <asm/pci_clp.h>
+#include <asm/asm.h>
 #include <asm/clp.h>
 #include <uapi/asm/clp.h>
 
@@ -52,18 +53,20 @@ static inline void zpci_err_clp(unsigned int rsp, int rc)
 static inline int clp_get_ilp(unsigned long *ilp)
 {
        unsigned long mask;
-       int cc = 3;
+       int cc, exception;
 
+       exception = 1;
        asm volatile (
                "       .insn   rrf,0xb9a00000,%[mask],%[cmd],8,0\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [mask] "=d" (mask) : [cmd] "a" (1)
-               : "cc");
+               : CC_OUT(cc, cc), [mask] "=d" (mask), [exc] "+d" (exception)
+               : [cmd] "a" (1)
+               : CC_CLOBBER);
        *ilp = mask;
-       return cc;
+       return exception ? 3 : CC_TRANSFORM(cc);
 }
 
 /*
@@ -72,19 +75,20 @@ static inline int clp_get_ilp(unsigned long *ilp)
 static __always_inline int clp_req(void *data, unsigned int lps)
 {
        struct { u8 _[CLP_BLK_SIZE]; } *req = data;
+       int cc, exception;
        u64 ignored;
-       int cc = 3;
 
+       exception = 1;
        asm volatile (
                "       .insn   rrf,0xb9a00000,%[ign],%[req],0,%[lps]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [ign] "=d" (ignored), "+m" (*req)
+               : CC_OUT(cc, cc), [ign] "=d" (ignored), "+m" (*req), [exc] "+d" (exception)
                : [req] "a" (req), [lps] "i" (lps)
-               : "cc");
-       return cc;
+               : CC_CLOBBER);
+       return exception ? 3 : CC_TRANSFORM(cc);
 }
 
 static void *clp_alloc_block(gfp_t gfp_mask)
index 56480be4824478626cb1947ba154980bc41c38c5..f5a75ea7629afff04d85aa00b8bfa4d847a65f6c 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/pci_debug.h>
 #include <asm/pci_io.h>
 #include <asm/processor.h>
+#include <asm/asm.h>
 
 #define ZPCI_INSN_BUSY_DELAY   1       /* 1 microsecond */
 
@@ -57,16 +58,16 @@ static inline void zpci_err_insn_addr(int lvl, u8 insn, u8 cc, u8 status,
 /* Modify PCI Function Controls */
 static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status)
 {
-       u8 cc;
+       int cc;
 
        asm volatile (
                "       .insn   rxy,0xe300000000d0,%[req],%[fib]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib)
-               : : "cc");
+               CC_IPM(cc)
+               : CC_OUT(cc, cc), [req] "+d" (req), [fib] "+Q" (*fib)
+               :
+               : CC_CLOBBER);
        *status = req >> 24 & 0xff;
-       return cc;
+       return CC_TRANSFORM(cc);
 }
 
 u8 zpci_mod_fc(u64 req, struct zpci_fib *fib, u8 *status)
@@ -98,17 +99,16 @@ EXPORT_SYMBOL_GPL(zpci_mod_fc);
 static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status)
 {
        union register_pair addr_range = {.even = addr, .odd = range};
-       u8 cc;
+       int cc;
 
        asm volatile (
                "       .insn   rre,0xb9d30000,%[fn],%[addr_range]\n"
-               "       ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               : [cc] "=d" (cc), [fn] "+d" (fn)
+               CC_IPM(cc)
+               : CC_OUT(cc, cc), [fn] "+d" (fn)
                : [addr_range] "d" (addr_range.pair)
-               : "cc");
+               : CC_CLOBBER);
        *status = fn >> 24 & 0xff;
-       return cc;
+       return CC_TRANSFORM(cc);
 }
 
 int zpci_refresh_trans(u64 fn, u64 addr, u64 range)
@@ -156,20 +156,23 @@ EXPORT_SYMBOL_GPL(zpci_set_irq_ctrl);
 static inline int ____pcilg(u64 *data, u64 req, u64 offset, u8 *status)
 {
        union register_pair req_off = {.even = req, .odd = offset};
-       int cc = -ENXIO;
+       int cc, exception;
        u64 __data;
 
+       exception = 1;
        asm volatile (
                "       .insn   rre,0xb9d20000,%[data],%[req_off]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [data] "=d" (__data),
-                 [req_off] "+&d" (req_off.pair) :: "cc");
+               : CC_OUT(cc, cc), [data] "=d" (__data),
+                 [req_off] "+d" (req_off.pair), [exc] "+d" (exception)
+               :
+               : CC_CLOBBER);
        *status = req_off.even >> 24 & 0xff;
        *data = __data;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status)
@@ -222,20 +225,23 @@ static inline int zpci_load_fh(u64 *data, const volatile void __iomem *addr,
 static inline int __pcilg_mio(u64 *data, u64 ioaddr, u64 len, u8 *status)
 {
        union register_pair ioaddr_len = {.even = ioaddr, .odd = len};
-       int cc = -ENXIO;
+       int cc, exception;
        u64 __data;
 
+       exception = 1;
        asm volatile (
                "       .insn   rre,0xb9d60000,%[data],%[ioaddr_len]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [data] "=d" (__data),
-                 [ioaddr_len] "+&d" (ioaddr_len.pair) :: "cc");
+               : CC_OUT(cc, cc), [data] "=d" (__data),
+                 [ioaddr_len] "+d" (ioaddr_len.pair), [exc] "+d" (exception)
+               :
+               : CC_CLOBBER);
        *status = ioaddr_len.odd >> 24 & 0xff;
        *data = __data;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 int zpci_load(u64 *data, const volatile void __iomem *addr, unsigned long len)
@@ -258,19 +264,20 @@ EXPORT_SYMBOL_GPL(zpci_load);
 static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status)
 {
        union register_pair req_off = {.even = req, .odd = offset};
-       int cc = -ENXIO;
+       int cc, exception;
 
+       exception = 1;
        asm volatile (
                "       .insn   rre,0xb9d00000,%[data],%[req_off]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [req_off] "+&d" (req_off.pair)
+               : CC_OUT(cc, cc), [req_off] "+d" (req_off.pair), [exc] "+d" (exception)
                : [data] "d" (data)
-               : "cc");
+               : CC_CLOBBER);
        *status = req_off.even >> 24 & 0xff;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 int __zpci_store(u64 data, u64 req, u64 offset)
@@ -311,19 +318,20 @@ static inline int zpci_store_fh(const volatile void __iomem *addr, u64 data,
 static inline int __pcistg_mio(u64 data, u64 ioaddr, u64 len, u8 *status)
 {
        union register_pair ioaddr_len = {.even = ioaddr, .odd = len};
-       int cc = -ENXIO;
+       int cc, exception;
 
+       exception = 1;
        asm volatile (
                "       .insn   rre,0xb9d40000,%[data],%[ioaddr_len]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [ioaddr_len] "+&d" (ioaddr_len.pair)
+               : CC_OUT(cc, cc), [ioaddr_len] "+d" (ioaddr_len.pair), [exc] "+d" (exception)
                : [data] "d" (data)
-               : "cc", "memory");
+               : CC_CLOBBER_LIST("memory"));
        *status = ioaddr_len.odd >> 24 & 0xff;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 int zpci_store(const volatile void __iomem *addr, u64 data, unsigned long len)
@@ -345,19 +353,20 @@ EXPORT_SYMBOL_GPL(zpci_store);
 /* PCI Store Block */
 static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status)
 {
-       int cc = -ENXIO;
+       int cc, exception;
 
+       exception = 1;
        asm volatile (
                "       .insn   rsy,0xeb00000000d0,%[req],%[offset],%[data]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [req] "+d" (req)
+               : CC_OUT(cc, cc), [req] "+d" (req), [exc] "+d" (exception)
                : [offset] "d" (offset), [data] "Q" (*data)
-               : "cc");
+               : CC_CLOBBER);
        *status = req >> 24 & 0xff;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 int __zpci_store_block(const u64 *data, u64 req, u64 offset)
@@ -398,19 +407,20 @@ static inline int zpci_write_block_fh(volatile void __iomem *dst,
 
 static inline int __pcistb_mio(const u64 *data, u64 ioaddr, u64 len, u8 *status)
 {
-       int cc = -ENXIO;
+       int cc, exception;
 
+       exception = 1;
        asm volatile (
                "       .insn   rsy,0xeb00000000d4,%[len],%[ioaddr],%[data]\n"
-               "0:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
+               "0:     lhi     %[exc],0\n"
                "1:\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 1b)
-               : [cc] "+d" (cc), [len] "+d" (len)
+               : CC_OUT(cc, cc), [len] "+d" (len), [exc] "+d" (exception)
                : [ioaddr] "d" (ioaddr), [data] "Q" (*data)
-               : "cc");
+               : CC_CLOBBER);
        *status = len >> 24 & 0xff;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 int zpci_write_block(volatile void __iomem *dst,
index de5c0b389a3ec8ee70fe6eb5eeab47e513027f05..46f99dc164ade4ca10f170cd66bdb648f92aa904 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/asm-extable.h>
 #include <asm/pci_io.h>
 #include <asm/pci_debug.h>
+#include <asm/asm.h>
 
 static inline void zpci_err_mmio(u8 cc, u8 status, u64 offset)
 {
@@ -30,20 +31,21 @@ static inline int __pcistb_mio_inuser(
                void __iomem *ioaddr, const void __user *src,
                u64 len, u8 *status)
 {
-       int cc = -ENXIO;
+       int cc, exception;
 
+       exception = 1;
        asm volatile (
-               "       sacf 256\n"
-               "0:     .insn   rsy,0xeb00000000d4,%[len],%[ioaddr],%[src]\n"
-               "1:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               "2:     sacf 768\n"
+               "       sacf    256\n"
+               "0:     .insn   rsy,0xeb00000000d4,%[len],%[ioaddr],%[src]\n"
+               "1:     lhi     %[exc],0\n"
+               "2:     sacf    768\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
-               : [cc] "+d" (cc), [len] "+d" (len)
+               : CC_OUT(cc, cc), [len] "+d" (len), [exc] "+d" (exception)
                : [ioaddr] "a" (ioaddr), [src] "Q" (*((u8 __force *)src))
-               : "cc", "memory");
+               : CC_CLOBBER_LIST("memory"));
        *status = len >> 24 & 0xff;
-       return cc;
+       return exception ? -ENXIO : CC_TRANSFORM(cc);
 }
 
 static inline int __pcistg_mio_inuser(
@@ -51,7 +53,7 @@ static inline int __pcistg_mio_inuser(
                u64 ulen, u8 *status)
 {
        union register_pair ioaddr_len = {.even = (u64 __force)ioaddr, .odd = ulen};
-       int cc = -ENXIO;
+       int cc, exception;
        u64 val = 0;
        u64 cnt = ulen;
        u8 tmp;
@@ -61,25 +63,27 @@ static inline int __pcistg_mio_inuser(
         * a register, then store it to PCI at @ioaddr while in secondary
         * address space. pcistg then uses the user mappings.
         */
+       exception = 1;
        asm volatile (
-               "       sacf    256\n"
-               "0:     llgc    %[tmp],0(%[src])\n"
+               "       sacf    256\n"
+               "0:     llgc    %[tmp],0(%[src])\n"
                "4:     sllg    %[val],%[val],8\n"
-               "       aghi    %[src],1\n"
-               "       ogr     %[val],%[tmp]\n"
-               "       brctg   %[cnt],0b\n"
-               "1:     .insn   rre,0xb9d40000,%[val],%[ioaddr_len]\n"
-               "2:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               "3:     sacf    768\n"
+               "       aghi    %[src],1\n"
+               "       ogr     %[val],%[tmp]\n"
+               "       brctg   %[cnt],0b\n"
+               "1:     .insn   rre,0xb9d40000,%[val],%[ioaddr_len]\n"
+               "2:     lhi     %[exc],0\n"
+               "3:     sacf    768\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 3b) EX_TABLE(4b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
+               : [src] "+a" (src), [cnt] "+d" (cnt),
+                 [val] "+d" (val), [tmp] "=d" (tmp), [exc] "+d" (exception),
+                 CC_OUT(cc, cc), [ioaddr_len] "+&d" (ioaddr_len.pair)
                :
-               [src] "+a" (src), [cnt] "+d" (cnt),
-               [val] "+d" (val), [tmp] "=d" (tmp),
-               [cc] "+d" (cc), [ioaddr_len] "+&d" (ioaddr_len.pair)
-               :: "cc", "memory");
+               : CC_CLOBBER_LIST("memory"));
        *status = ioaddr_len.odd >> 24 & 0xff;
 
+       cc = exception ? -ENXIO : CC_TRANSFORM(cc);
        /* did we read everything from user memory? */
        if (!cc && cnt != 0)
                cc = -EFAULT;
@@ -198,7 +202,7 @@ static inline int __pcilg_mio_inuser(
        union register_pair ioaddr_len = {.even = (u64 __force)ioaddr, .odd = ulen};
        u64 cnt = ulen;
        int shift = ulen * 8;
-       int cc = -ENXIO;
+       int cc, exception;
        u64 val, tmp;
 
        /*
@@ -206,27 +210,33 @@ static inline int __pcilg_mio_inuser(
         * user space) into a register using pcilg then store these bytes at
         * user address @dst
         */
+       exception = 1;
        asm volatile (
-               "       sacf    256\n"
-               "0:     .insn   rre,0xb9d60000,%[val],%[ioaddr_len]\n"
-               "1:     ipm     %[cc]\n"
-               "       srl     %[cc],28\n"
-               "       ltr     %[cc],%[cc]\n"
-               "       jne     4f\n"
-               "2:     ahi     %[shift],-8\n"
-               "       srlg    %[tmp],%[val],0(%[shift])\n"
-               "3:     stc     %[tmp],0(%[dst])\n"
+               "       sacf    256\n"
+               "0:     .insn   rre,0xb9d60000,%[val],%[ioaddr_len]\n"
+               "1:     lhi     %[exc],0\n"
+               "       jne     4f\n"
+               "2:     ahi     %[shift],-8\n"
+               "       srlg    %[tmp],%[val],0(%[shift])\n"
+               "3:     stc     %[tmp],0(%[dst])\n"
                "5:     aghi    %[dst],1\n"
-               "       brctg   %[cnt],2b\n"
-               "4:     sacf    768\n"
+               "       brctg   %[cnt],2b\n"
+               /*
+                * Use xr to clear exc and set condition code to zero
+                * to ensure flag output is correct for this branch.
+                */
+               "       xr      %[exc],%[exc]\n"
+               "4:     sacf    768\n"
+               CC_IPM(cc)
                EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) EX_TABLE(5b, 4b)
+               : [ioaddr_len] "+&d" (ioaddr_len.pair), [exc] "+d" (exception),
+                 CC_OUT(cc, cc), [val] "=d" (val),
+                 [dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp),
+                 [shift] "+d" (shift)
                :
-               [ioaddr_len] "+&d" (ioaddr_len.pair),
-               [cc] "+d" (cc), [val] "=d" (val),
-               [dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp),
-               [shift] "+d" (shift)
-               :: "cc", "memory");
+               : CC_CLOBBER_LIST("memory"));
 
+       cc = exception ? -ENXIO : CC_TRANSFORM(cc);
        /* did we write everything to the user space buffer? */
        if (!cc && cnt != 0)
                cc = -EFAULT;