s390/cpcmd: use register pair instead of register asm
authorHeiko Carstens <hca@linux.ibm.com>
Wed, 9 Jun 2021 20:59:13 +0000 (22:59 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Fri, 18 Jun 2021 14:41:22 +0000 (16:41 +0200)
Remove register asm usage from diag8_noresponse() since it wasn't
needed at all. There is no requirement for even/odd register pairs for
diag 0x8.

For diag_response() use register pairs to fulfill the rx+1 and ry+1
requirements as required if a response buffer is specified. Also
change the inline asm to return the condition code of the diagnose
instruction and do the conditional handling of response length
calculation in C.

Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/kernel/cpcmd.c

index 2da0273..54efc27 100644 (file)
@@ -26,33 +26,35 @@ static char cpcmd_buf[241];
 
 static int diag8_noresponse(int cmdlen)
 {
-       register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
-       register unsigned long reg3 asm ("3") = cmdlen;
-
        asm volatile(
-               "       diag    %1,%0,0x8\n"
-               : "+d" (reg3) : "d" (reg2) : "cc");
-       return reg3;
+               "       diag    %[rx],%[ry],0x8\n"
+               : [ry] "+&d" (cmdlen)
+               : [rx] "d" ((addr_t) cpcmd_buf)
+               : "cc");
+       return cmdlen;
 }
 
 static int diag8_response(int cmdlen, char *response, int *rlen)
 {
-       unsigned long _cmdlen = cmdlen | 0x40000000L;
-       unsigned long _rlen = *rlen;
-       register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf;
-       register unsigned long reg3 asm ("3") = (addr_t) response;
-       register unsigned long reg4 asm ("4") = _cmdlen;
-       register unsigned long reg5 asm ("5") = _rlen;
+       union register_pair rx, ry;
+       int cc;
 
+       rx.even = (addr_t) cpcmd_buf;
+       rx.odd  = (addr_t) response;
+       ry.even = cmdlen | 0x40000000L;
+       ry.odd  = *rlen;
        asm volatile(
-               "       diag    %2,%0,0x8\n"
-               "       brc     8,1f\n"
-               "       agr     %1,%4\n"
-               "1:\n"
-               : "+d" (reg4), "+d" (reg5)
-               : "d" (reg2), "d" (reg3), "d" (*rlen) : "cc");
-       *rlen = reg5;
-       return reg4;
+               "       diag    %[rx],%[ry],0x8\n"
+               "       ipm     %[cc]\n"
+               "       srl     %[cc],28\n"
+               : [cc] "=&d" (cc), [ry] "+&d" (ry.pair)
+               : [rx] "d" (rx.pair)
+               : "cc");
+       if (cc)
+               *rlen += ry.odd;
+       else
+               *rlen = ry.odd;
+       return ry.even;
 }
 
 /*