aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@de.ibm.com>2007-08-22 07:51:40 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2007-08-22 07:51:47 -0400
commit0a87c5cfc0bb0c1bdcc1cc9fd82e4a1711fac512 (patch)
treef204007f95e2807e63712593c3b42d3fb59be5fe /drivers/s390
parent37cd0a007f88f1d6269035bdb02b50f536cca8de (diff)
[S390] vmur: fix diag14 exceptions with addresses > 2GB.
There are several s390 diagnose calls, which must be executed below the 2GB memory boundary. In order to enforce this, those diagnoses must be compiled into the kernel. Currently diag 14 can be called within the vmur kernel module from addresses above 2GB. This leads to specification exceptions. This patch moves diag10, diag14 and diag210 into the new diag.c file. Signed-off-by: Michael Holzheu <holzheu@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd_diag.c1
-rw-r--r--drivers/s390/char/raw3270.c1
-rw-r--r--drivers/s390/char/vmur.c32
-rw-r--r--drivers/s390/cio/device_id.c48
4 files changed, 7 insertions, 75 deletions
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index eccac1c3b71b..d32c60dbdd82 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -24,6 +24,7 @@
24#include <asm/s390_ext.h> 24#include <asm/s390_ext.h>
25#include <asm/todclk.h> 25#include <asm/todclk.h>
26#include <asm/vtoc.h> 26#include <asm/vtoc.h>
27#include <asm/diag.h>
27 28
28#include "dasd_int.h" 29#include "dasd_int.h"
29#include "dasd_diag.h" 30#include "dasd_diag.h"
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 4f2f81b16cfa..2edd5fb6d3dc 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -21,6 +21,7 @@
21#include <asm/ccwdev.h> 21#include <asm/ccwdev.h>
22#include <asm/cio.h> 22#include <asm/cio.h>
23#include <asm/ebcdic.h> 23#include <asm/ebcdic.h>
24#include <asm/diag.h>
24 25
25#include "raw3270.h" 26#include "raw3270.h"
26 27
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 04b19bdc09da..2d96c958df64 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -14,6 +14,7 @@
14#include <asm/cio.h> 14#include <asm/cio.h>
15#include <asm/ccwdev.h> 15#include <asm/ccwdev.h>
16#include <asm/debug.h> 16#include <asm/debug.h>
17#include <asm/diag.h>
17 18
18#include "vmur.h" 19#include "vmur.h"
19 20
@@ -379,31 +380,6 @@ static ssize_t ur_write(struct file *file, const char __user *udata,
379 return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); 380 return do_write(urf->urd, udata, count, urf->dev_reclen, ppos);
380} 381}
381 382
382static int do_diag_14(unsigned long rx, unsigned long ry1,
383 unsigned long subcode)
384{
385 register unsigned long _ry1 asm("2") = ry1;
386 register unsigned long _ry2 asm("3") = subcode;
387 int rc = 0;
388
389 asm volatile(
390#ifdef CONFIG_64BIT
391 " sam31\n"
392 " diag %2,2,0x14\n"
393 " sam64\n"
394#else
395 " diag %2,2,0x14\n"
396#endif
397 " ipm %0\n"
398 " srl %0,28\n"
399 : "=d" (rc), "+d" (_ry2)
400 : "d" (rx), "d" (_ry1)
401 : "cc");
402
403 TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc);
404 return rc;
405}
406
407/* 383/*
408 * diagnose code 0x14 subcode 0x0028 - position spool file to designated 384 * diagnose code 0x14 subcode 0x0028 - position spool file to designated
409 * record 385 * record
@@ -415,7 +391,7 @@ static int diag_position_to_record(int devno, int record)
415{ 391{
416 int cc; 392 int cc;
417 393
418 cc = do_diag_14(record, devno, 0x28); 394 cc = diag14(record, devno, 0x28);
419 switch (cc) { 395 switch (cc) {
420 case 0: 396 case 0:
421 return 0; 397 return 0;
@@ -440,7 +416,7 @@ static int diag_read_file(int devno, char *buf)
440{ 416{
441 int cc; 417 int cc;
442 418
443 cc = do_diag_14((unsigned long) buf, devno, 0x00); 419 cc = diag14((unsigned long) buf, devno, 0x00);
444 switch (cc) { 420 switch (cc) {
445 case 0: 421 case 0:
446 return 0; 422 return 0;
@@ -533,7 +509,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid)
533{ 509{
534 int cc; 510 int cc;
535 511
536 cc = do_diag_14((unsigned long) buf, spid, 0xfff); 512 cc = diag14((unsigned long) buf, spid, 0xfff);
537 switch (cc) { 513 switch (cc) {
538 case 0: 514 case 0:
539 return 0; 515 return 0;
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 60b9347f7c92..f232832f2b22 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -17,6 +17,7 @@
17#include <asm/delay.h> 17#include <asm/delay.h>
18#include <asm/cio.h> 18#include <asm/cio.h>
19#include <asm/lowcore.h> 19#include <asm/lowcore.h>
20#include <asm/diag.h>
20 21
21#include "cio.h" 22#include "cio.h"
22#include "cio_debug.h" 23#include "cio_debug.h"
@@ -25,51 +26,6 @@
25#include "ioasm.h" 26#include "ioasm.h"
26 27
27/* 28/*
28 * diag210 is used under VM to get information about a virtual device
29 */
30int
31diag210(struct diag210 * addr)
32{
33 /*
34 * diag 210 needs its data below the 2GB border, so we
35 * use a static data area to be sure
36 */
37 static struct diag210 diag210_tmp;
38 static DEFINE_SPINLOCK(diag210_lock);
39 unsigned long flags;
40 int ccode;
41
42 spin_lock_irqsave(&diag210_lock, flags);
43 diag210_tmp = *addr;
44
45#ifdef CONFIG_64BIT
46 asm volatile(
47 " lhi %0,-1\n"
48 " sam31\n"
49 " diag %1,0,0x210\n"
50 "0: ipm %0\n"
51 " srl %0,28\n"
52 "1: sam64\n"
53 EX_TABLE(0b,1b)
54 : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
55#else
56 asm volatile(
57 " lhi %0,-1\n"
58 " diag %1,0,0x210\n"
59 "0: ipm %0\n"
60 " srl %0,28\n"
61 "1:\n"
62 EX_TABLE(0b,1b)
63 : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
64#endif
65
66 *addr = diag210_tmp;
67 spin_unlock_irqrestore(&diag210_lock, flags);
68
69 return ccode;
70}
71
72/*
73 * Input : 29 * Input :
74 * devno - device number 30 * devno - device number
75 * ps - pointer to sense ID data area 31 * ps - pointer to sense ID data area
@@ -349,5 +305,3 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
349 break; 305 break;
350 } 306 }
351} 307}
352
353EXPORT_SYMBOL(diag210);