From 0a9d947fbe3e89e44758e1b8bf0098e98b3ccd78 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 9 Jun 2021 22:59:13 +0200 Subject: [PATCH] s390/cpcmd: use register pair instead of register asm 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 Signed-off-by: Vasily Gorbik --- arch/s390/kernel/cpcmd.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 2da0273..54efc27 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -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; } /* -- 2.7.4