提交 ce0c12b6 编写于 作者: H Heiko Carstens 提交者: Martin Schwidefsky

s390/dasd: fix diag 0x250 inline assembly

git commit 1ec2772e ("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: 1ec2772e ("s390/diag: add a statistic for diagnose calls")
Cc: <stable@vger.kernel.org> # 4.4+
Reported-and-tested-by: NStefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 f691b77b
...@@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ ...@@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
* and function code cmd. * and function code cmd.
* In case of an exception return 3. Otherwise return result of bitwise OR of * In case of an exception return 3. Otherwise return result of bitwise OR of
* resulting condition code and DIAG return code. */ * 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; register unsigned long reg2 asm ("2") = (unsigned long) iob;
typedef union { typedef union {
...@@ -77,7 +77,6 @@ static inline int dia250(void *iob, int cmd) ...@@ -77,7 +77,6 @@ static inline int dia250(void *iob, int cmd)
int rc; int rc;
rc = 3; rc = 3;
diag_stat_inc(DIAG_STAT_X250);
asm volatile( asm volatile(
" diag 2,%2,0x250\n" " diag 2,%2,0x250\n"
"0: ipm %0\n" "0: ipm %0\n"
...@@ -91,6 +90,12 @@ static inline int dia250(void *iob, int cmd) ...@@ -91,6 +90,12 @@ static inline int dia250(void *iob, int cmd)
return rc; 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 /* 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 * 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 * number of blocks on the device minus the specified offset. Return non-zero
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册