diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2016-03-01 12:58:06 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-03-02 06:43:48 -0600 |
commit | ce0c12b633846a47e103842149a5bac2e5d261ec (patch) | |
tree | b8e305b904aff2c4e798ae9ec0372506df27051e /drivers | |
parent | f691b77b1fc491dae601631c8531a0a13e915466 (diff) | |
download | linux-ce0c12b633846a47e103842149a5bac2e5d261ec.tar.gz linux-ce0c12b633846a47e103842149a5bac2e5d261ec.tar.bz2 linux-ce0c12b633846a47e103842149a5bac2e5d261ec.zip |
s390/dasd: fix diag 0x250 inline assembly
git commit 1ec2772e0c3c ("s390/diag: add a statistic for diagnose
calls") added function calls to gather diagnose statistics.
In case of the dasd diag driver the function call was added between a
register asm statement which initialized register r2 and the inline
assembly itself. The function call clobbers the contents of register
r2 and therefore the diag 0x250 call behaves in a more or less random
way.
Fix this by extracting the function call into a separate function like
we do everywhere else.
Fixes: 1ec2772e0c3c ("s390/diag: add a statistic for diagnose calls")
Cc: <stable@vger.kernel.org> # 4.4+
Reported-and-tested-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index cb61f300f8b5..277b5c8c825c 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ * and function code cmd. * In case of an exception return 3. Otherwise return result of bitwise OR of * resulting condition code and DIAG return code. */ -static inline int dia250(void *iob, int cmd) +static inline int __dia250(void *iob, int cmd) { register unsigned long reg2 asm ("2") = (unsigned long) iob; typedef union { @@ -77,7 +77,6 @@ static inline int dia250(void *iob, int cmd) int rc; rc = 3; - diag_stat_inc(DIAG_STAT_X250); asm volatile( " diag 2,%2,0x250\n" "0: ipm %0\n" @@ -91,6 +90,12 @@ static inline int dia250(void *iob, int cmd) return rc; } +static inline int dia250(void *iob, int cmd) +{ + diag_stat_inc(DIAG_STAT_X250); + return __dia250(iob, cmd); +} + /* Initialize block I/O to DIAG device using the specified blocksize and * block offset. On success, return zero and set end_block to contain the * number of blocks on the device minus the specified offset. Return non-zero |