diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2014-01-27 07:26:10 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-02-21 02:50:11 -0500 |
commit | 2253e8d79237c69086ded391e6767afe16972527 (patch) | |
tree | 573f238758d5e67041caacf2bfb60db4cc39a491 /drivers/s390/cio/device.c | |
parent | 960dfc4eb23a28495276b02604d7458e0e1a1ed8 (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/cio/device.c')
-rw-r--r-- | drivers/s390/cio/device.c | 3 |
1 files changed, 2 insertions, 1 deletions
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 | ||
1612 | struct ccw_device *ccw_device_probe_console(void) | 1612 | struct 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) { |