aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2014-01-27 07:26:10 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2014-02-21 02:50:11 -0500
commit2253e8d79237c69086ded391e6767afe16972527 (patch)
tree573f238758d5e67041caacf2bfb60db4cc39a491 /drivers/s390
parent960dfc4eb23a28495276b02604d7458e0e1a1ed8 (diff)
s390/cio: fix driver callback initialization for ccw consoles
ccw consoles are in use before they can be properly registered with the driver core. For devices which are in use by a device driver we rely on the ccw_device's pointer to the driver callbacks to be valid. For ccw consoles this pointer is NULL until they are registered later during boot and we dereferenced this pointer. This worked by chance on 64 bit builds (cdev->drv was NULL but the optional callback cdev->drv->path_event was also NULL by coincidence) and was unnoticed until we received reports about boot failures on 31 bit systems. Fix it by initializing the driver pointer for ccw consoles. Cc: <stable@vger.kernel.org> # 3.10+ Reported-by: Mike Frysinger <vapier@gentoo.org> Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/con3270.c6
-rw-r--r--drivers/s390/char/raw3270.c10
-rw-r--r--drivers/s390/char/raw3270.h2
-rw-r--r--drivers/s390/cio/device.c3
5 files changed, 14 insertions, 9 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index eb5d22795c47..bb86494e2b7b 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -922,7 +922,7 @@ static int __init con3215_init(void)
922 raw3215_freelist = req; 922 raw3215_freelist = req;
923 } 923 }
924 924
925 cdev = ccw_device_probe_console(); 925 cdev = ccw_device_probe_console(&raw3215_ccw_driver);
926 if (IS_ERR(cdev)) 926 if (IS_ERR(cdev))
927 return -ENODEV; 927 return -ENODEV;
928 928
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 699fd3e363df..bb6b0df50b33 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -576,7 +576,6 @@ static struct console con3270 = {
576static int __init 576static int __init
577con3270_init(void) 577con3270_init(void)
578{ 578{
579 struct ccw_device *cdev;
580 struct raw3270 *rp; 579 struct raw3270 *rp;
581 void *cbuf; 580 void *cbuf;
582 int i; 581 int i;
@@ -591,10 +590,7 @@ con3270_init(void)
591 cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); 590 cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
592 } 591 }
593 592
594 cdev = ccw_device_probe_console(); 593 rp = raw3270_setup_console();
595 if (IS_ERR(cdev))
596 return -ENODEV;
597 rp = raw3270_setup_console(cdev);
598 if (IS_ERR(rp)) 594 if (IS_ERR(rp))
599 return PTR_ERR(rp); 595 return PTR_ERR(rp);
600 596
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 2cdec21e8924..de2c0483949f 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -776,16 +776,24 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
776} 776}
777 777
778#ifdef CONFIG_TN3270_CONSOLE 778#ifdef CONFIG_TN3270_CONSOLE
779/* Tentative definition - see below for actual definition. */
780static struct ccw_driver raw3270_ccw_driver;
781
779/* 782/*
780 * Setup 3270 device configured as console. 783 * Setup 3270 device configured as console.
781 */ 784 */
782struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) 785struct raw3270 __init *raw3270_setup_console(void)
783{ 786{
787 struct ccw_device *cdev;
784 unsigned long flags; 788 unsigned long flags;
785 struct raw3270 *rp; 789 struct raw3270 *rp;
786 char *ascebc; 790 char *ascebc;
787 int rc; 791 int rc;
788 792
793 cdev = ccw_device_probe_console(&raw3270_ccw_driver);
794 if (IS_ERR(cdev))
795 return ERR_CAST(cdev);
796
789 rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); 797 rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
790 ascebc = kzalloc(256, GFP_KERNEL); 798 ascebc = kzalloc(256, GFP_KERNEL);
791 rc = raw3270_setup_device(cdev, rp, ascebc); 799 rc = raw3270_setup_device(cdev, rp, ascebc);
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index 7b73ff8c1bd7..359276a88396 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -190,7 +190,7 @@ raw3270_put_view(struct raw3270_view *view)
190 wake_up(&raw3270_wait_queue); 190 wake_up(&raw3270_wait_queue);
191} 191}
192 192
193struct raw3270 *raw3270_setup_console(struct ccw_device *cdev); 193struct raw3270 *raw3270_setup_console(void);
194void raw3270_wait_cons_dev(struct raw3270 *); 194void raw3270_wait_cons_dev(struct raw3270 *);
195 195
196/* Notifier for device addition/removal */ 196/* Notifier for device addition/removal */
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index e9d783563cbb..4283dd3cdd49 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1609,7 +1609,7 @@ out_unlock:
1609 return rc; 1609 return rc;
1610} 1610}
1611 1611
1612struct ccw_device *ccw_device_probe_console(void) 1612struct ccw_device *ccw_device_probe_console(struct ccw_driver *drv)
1613{ 1613{
1614 struct io_subchannel_private *io_priv; 1614 struct io_subchannel_private *io_priv;
1615 struct ccw_device *cdev; 1615 struct ccw_device *cdev;
@@ -1631,6 +1631,7 @@ struct ccw_device *ccw_device_probe_console(void)
1631 kfree(io_priv); 1631 kfree(io_priv);
1632 return cdev; 1632 return cdev;
1633 } 1633 }
1634 cdev->drv = drv;
1634 set_io_private(sch, io_priv); 1635 set_io_private(sch, io_priv);
1635 ret = ccw_device_console_enable(cdev, sch); 1636 ret = ccw_device_console_enable(cdev, sch);
1636 if (ret) { 1637 if (ret) {