From 6c29588578edc9ae2c9fae27ff96f443cf39c0f3 Mon Sep 17 00:00:00 2001 From: Dong Jia Shi Date: Mon, 8 Aug 2016 04:27:15 +0200 Subject: s390: cio: remove redundant cio_cancel declaration cio_cancel was declared twice. Remove one of them. Signed-off-by: Dong Jia Shi Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cio.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 93de0b46b489..f0e57aefb5f2 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -127,7 +127,6 @@ extern int cio_resume (struct subchannel *); extern int cio_halt (struct subchannel *); extern int cio_start (struct subchannel *, struct ccw1 *, __u8); extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8); -extern int cio_cancel (struct subchannel *); extern int cio_set_options (struct subchannel *, int); extern int cio_update_schib(struct subchannel *sch); extern int cio_commit_config(struct subchannel *sch); -- cgit v1.2.3-59-g8ed1b From 2ccb5bf0e2f190c825c69087aa40c89db89ca1ad Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 20 Aug 2016 19:25:34 +0200 Subject: s390/tape: Use memdup_user() rather than duplicating its implementation Reuse existing functionality from memdup_user() instead of keeping duplicate source code. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape_3590.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index d3d1936057b4..e352047ed9f7 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -312,15 +312,10 @@ static int tape_3592_ioctl_kekl_set(struct tape_device *device, return -ENOSYS; if (!crypt_enabled(device)) return -EUNATCH; - ext_kekls = kmalloc(sizeof(*ext_kekls), GFP_KERNEL); - if (!ext_kekls) - return -ENOMEM; - if (copy_from_user(ext_kekls, (char __user *)arg, sizeof(*ext_kekls))) { - rc = -EFAULT; - goto out; - } + ext_kekls = memdup_user((char __user *)arg, sizeof(*ext_kekls)); + if (IS_ERR(ext_kekls)) + return PTR_ERR(ext_kekls); rc = tape_3592_kekl_set(device, ext_kekls); -out: kfree(ext_kekls); return rc; } -- cgit v1.2.3-59-g8ed1b From e68f1d4ca99e08652066f40d7778b6007f0149d9 Mon Sep 17 00:00:00 2001 From: Bhaktipriya Shridhar Date: Wed, 31 Aug 2016 01:57:20 +0530 Subject: s390: Remove deprecated create_singlethread_workqueue The workqueue "appldata_wq" has been replaced with an ordered dedicated workqueue. WQ_MEM_RECLAIM has not been set since the workqueue is not being used on a memory reclaim path. The adapter->work_queue queues multiple work items viz &adapter->scan_work, &port->rport_work, &adapter->ns_up_work, &adapter->stat_work, adapter->work_queue, &adapter->events.work, &port->gid_pn_work, &port->test_link_work. Hence, an ordered dedicated workqueue has been used. WQ_MEM_RECLAIM has been set to ensure forward progress under memory pressure. Signed-off-by: Bhaktipriya Shridhar Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/appldata/appldata_base.c | 2 +- drivers/s390/scsi/zfcp_aux.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 15c94246b600..f587c4811faf 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -542,7 +542,7 @@ static int __init appldata_init(void) rc = PTR_ERR(appldata_pdev); goto out_driver; } - appldata_wq = create_singlethread_workqueue("appldata"); + appldata_wq = alloc_ordered_workqueue("appldata", 0); if (!appldata_wq) { rc = -ENOMEM; goto out_device; diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index c00ac4650dce..bcc8f3dfd4c4 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -310,7 +310,7 @@ static int zfcp_setup_adapter_work_queue(struct zfcp_adapter *adapter) snprintf(name, sizeof(name), "zfcp_q_%s", dev_name(&adapter->ccw_device->dev)); - adapter->work_queue = create_singlethread_workqueue(name); + adapter->work_queue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); if (adapter->work_queue) return 0; -- cgit v1.2.3-59-g8ed1b From eed5c4b117d1f77553d517072584c4ac779af0ba Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 31 Aug 2016 13:31:10 +0200 Subject: s390/dasd: add missing KOBJ_CHANGE event for unformatted devices The DASD device driver throws change events for the DASD blockdevice after the online processing is done so that udev rules can take actions after it. The change event was missing for unformatted devices. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index fb1b56a71475..5245d7e37a46 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -336,6 +336,7 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) { int rc; struct dasd_block *block; + struct gendisk *disk; rc = 0; block = device->block; @@ -346,6 +347,9 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) if (rc) { if (rc != -EAGAIN) { device->state = DASD_STATE_UNFMT; + disk = device->block->gdp; + kobject_uevent(&disk_to_dev(disk)->kobj, + KOBJ_CHANGE); goto out; } return rc; -- cgit v1.2.3-59-g8ed1b From f622b517563b0d3be6c41e932124e0b717149ad8 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 19 Aug 2016 19:57:49 +0200 Subject: s390/vmur: fix irq pointer dereference in int handler "irq" in vmur's int handler can be an error pointer. Don't dereference this pointer in that case. Reported-by: Dan Carpenter Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmur.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 6c30e93ab8fa..ff18f373af9a 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -306,10 +306,11 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, { struct urdev *urd; - TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", - intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, - irb->scsw.cmd.count); - + if (!IS_ERR(irb)) { + TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", + intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, + irb->scsw.cmd.count); + } if (!intparm) { TRACE("ur_int_handler: unsolicited interrupt\n"); return; -- cgit v1.2.3-59-g8ed1b From a9f6273ff9c80dd2c226f7a2d5c16272e5092d3e Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Tue, 20 Sep 2016 10:29:22 +0200 Subject: s390/dasd: fix hanging offline processing Internal I/O is processed by the _sleep_on_function which might wait for a device to get operational. During offline processing this will never happen and therefore the refcount of the device will not drop to zero and the offline processing blocks as well. Fix by letting requests fail in the _sleep_on function during offline processing. No further handling of the requests is necessary since this is internal I/O and the device is thrown away afterwards. Reviewed-by: Peter Oberparleiter Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 5245d7e37a46..706ae0ac94c9 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2277,6 +2277,15 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) cqr->intrc = -ENOLINK; continue; } + /* + * Don't try to start requests if device is in + * offline processing, it might wait forever + */ + if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { + cqr->status = DASD_CQR_FAILED; + cqr->intrc = -ENODEV; + continue; + } /* * Don't try to start requests if device is stopped * except path verification requests -- cgit v1.2.3-59-g8ed1b From c020d722b110a44c613ef71e657e6dd4116e09d9 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Tue, 20 Sep 2016 10:42:38 +0200 Subject: s390/dasd: fix panic during offline processing A DASD device consists of the device itself and a discipline with a corresponding private structure. These fields are set up during online processing right after the device is created and before it is processed by the state machine and made available for I/O. During offline processing the discipline pointer and the private data gets freed within the state machine and without protection of the existing reference count. This might lead to a kernel panic because a function might have taken a device reference and accesses the discipline pointer and/or private data of the device while this is already freed. Fix by freeing the discipline pointer and the private data after ensuring that there is no reference to the device left. Reviewed-by: Peter Oberparleiter Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 26 ++++++++++++++++---------- drivers/s390/block/dasd_devmap.c | 1 + drivers/s390/block/dasd_int.h | 1 + 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 706ae0ac94c9..1de089019268 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -212,16 +212,6 @@ static int dasd_state_known_to_new(struct dasd_device *device) { /* Disable extended error reporting for this device. */ dasd_eer_disable(device); - /* Forget the discipline information. */ - if (device->discipline) { - if (device->discipline->uncheck_device) - device->discipline->uncheck_device(device); - module_put(device->discipline->owner); - } - device->discipline = NULL; - if (device->base_discipline) - module_put(device->base_discipline->owner); - device->base_discipline = NULL; device->state = DASD_STATE_NEW; if (device->block) @@ -3377,6 +3367,22 @@ int dasd_generic_probe(struct ccw_device *cdev, } EXPORT_SYMBOL_GPL(dasd_generic_probe); +void dasd_generic_free_discipline(struct dasd_device *device) +{ + /* Forget the discipline information. */ + if (device->discipline) { + if (device->discipline->uncheck_device) + device->discipline->uncheck_device(device); + module_put(device->discipline->owner); + device->discipline = NULL; + } + if (device->base_discipline) { + module_put(device->base_discipline->owner); + device->base_discipline = NULL; + } +} +EXPORT_SYMBOL_GPL(dasd_generic_free_discipline); + /* * This will one day be called from a global not_oper handler. * It is also used by driver_unregister during module unload. diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 3cdbce45e464..15a1a70cace9 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -617,6 +617,7 @@ dasd_delete_device(struct dasd_device *device) /* Wait for reference counter to drop to zero. */ wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); + dasd_generic_free_discipline(device); /* Disconnect dasd_device structure from ccw_device structure. */ cdev = device->cdev; device->cdev = NULL; diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index ac7027e6d52b..87ff6cef872f 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -725,6 +725,7 @@ void dasd_block_clear_timer(struct dasd_block *); int dasd_cancel_req(struct dasd_ccw_req *); int dasd_flush_device_queue(struct dasd_device *); int dasd_generic_probe (struct ccw_device *, struct dasd_discipline *); +void dasd_generic_free_discipline(struct dasd_device *); void dasd_generic_remove (struct ccw_device *cdev); int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); int dasd_generic_set_offline (struct ccw_device *cdev); -- cgit v1.2.3-59-g8ed1b From f50af850f407df7b548802461bc248c7683c6dd3 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 22 Sep 2016 10:49:40 +0200 Subject: s390/dasd: make query host access interruptible If the DASD device gets blocked for any reason, e.g. because it is reserved somewhere, the host_access_count sysfs entry or the host_access_list debugfs entry may sleep forever. Make it interruptible so that userspace can use ^C to abort the operation. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_eckd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 98bbec44bcd0..831935af7389 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -5201,7 +5201,7 @@ static int dasd_eckd_query_host_access(struct dasd_device *device, cqr->buildclk = get_tod_clock(); cqr->status = DASD_CQR_FILLED; - rc = dasd_sleep_on(cqr); + rc = dasd_sleep_on_interruptible(cqr); if (rc == 0) { *data = *host_access; } else { -- cgit v1.2.3-59-g8ed1b From 871f8bf0c477ef20ac1457bb241416d7d8749732 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 27 Sep 2016 12:13:18 -0700 Subject: s390/dasd: add missing \n to end of dev_err messages Trival fix, dev_err messages are missing a \n, so add it. Signed-off-by: Colin Ian King Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_erp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index e1e88486b2b4..d138d0116734 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c @@ -169,12 +169,12 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb) device = cqr->startdev; if (cqr->intrc == -ETIMEDOUT) { dev_err(&device->cdev->dev, - "A timeout error occurred for cqr %p", cqr); + "A timeout error occurred for cqr %p\n", cqr); return; } if (cqr->intrc == -ENOLINK) { dev_err(&device->cdev->dev, - "A transport error occurred for cqr %p", cqr); + "A transport error occurred for cqr %p\n", cqr); return; } /* dump sense data */ -- cgit v1.2.3-59-g8ed1b From d53c51f26145657aa7c55fa396f93677e613548d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 28 Sep 2016 13:36:19 +0200 Subject: s390/cio: fix accidental interrupt enabling during resume Since commit 9f3d6d7 chsc_get_channel_measurement_chars is called with interrupts disabled during resume from hibernate. Since this function used spin_unlock_irq, interrupts have been enabled accidentally. Fix this by using the irqsave variant. Since we can't guarantee the IRQ-enablement state for all (future/ external) callers, change the locking in related functions to prevent similar bugs in the future. Fixes: 9f3d6d7 ("s390/cio: update measurement characteristics") Signed-off-by: Sebastian Ott Reviewed-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 940e725bde1e..11674698b36d 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -95,12 +95,13 @@ struct chsc_ssd_area { int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) { struct chsc_ssd_area *ssd_area; + unsigned long flags; int ccode; int ret; int i; int mask; - spin_lock_irq(&chsc_page_lock); + spin_lock_irqsave(&chsc_page_lock, flags); memset(chsc_page, 0, PAGE_SIZE); ssd_area = chsc_page; ssd_area->request.length = 0x0010; @@ -144,7 +145,7 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) ssd->fla[i] = ssd_area->fla[i]; } out: - spin_unlock_irq(&chsc_page_lock); + spin_unlock_irqrestore(&chsc_page_lock, flags); return ret; } @@ -832,9 +833,10 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) u32 fmt : 4; u32 : 16; } __attribute__ ((packed)) *secm_area; + unsigned long flags; int ret, ccode; - spin_lock_irq(&chsc_page_lock); + spin_lock_irqsave(&chsc_page_lock, flags); memset(chsc_page, 0, PAGE_SIZE); secm_area = chsc_page; secm_area->request.length = 0x0050; @@ -864,7 +866,7 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n", secm_area->response.code); out: - spin_unlock_irq(&chsc_page_lock); + spin_unlock_irqrestore(&chsc_page_lock, flags); return ret; } @@ -992,6 +994,7 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, int chsc_get_channel_measurement_chars(struct channel_path *chp) { + unsigned long flags; int ccode, ret; struct { @@ -1021,7 +1024,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm) return -EINVAL; - spin_lock_irq(&chsc_page_lock); + spin_lock_irqsave(&chsc_page_lock, flags); memset(chsc_page, 0, PAGE_SIZE); scmc_area = chsc_page; scmc_area->request.length = 0x0010; @@ -1053,7 +1056,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) chsc_initialize_cmg_chars(chp, scmc_area->cmcv, (struct cmg_chars *) &scmc_area->data); out: - spin_unlock_irq(&chsc_page_lock); + spin_unlock_irqrestore(&chsc_page_lock, flags); return ret; } @@ -1134,6 +1137,7 @@ struct css_chsc_char css_chsc_characteristics; int __init chsc_determine_css_characteristics(void) { + unsigned long flags; int result; struct { struct chsc_header request; @@ -1146,7 +1150,7 @@ chsc_determine_css_characteristics(void) u32 chsc_char[508]; } __attribute__ ((packed)) *scsc_area; - spin_lock_irq(&chsc_page_lock); + spin_lock_irqsave(&chsc_page_lock, flags); memset(chsc_page, 0, PAGE_SIZE); scsc_area = chsc_page; scsc_area->request.length = 0x0010; @@ -1168,7 +1172,7 @@ chsc_determine_css_characteristics(void) CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n", scsc_area->response.code); exit: - spin_unlock_irq(&chsc_page_lock); + spin_unlock_irqrestore(&chsc_page_lock, flags); return result; } -- cgit v1.2.3-59-g8ed1b From c14f2aac7aa147861793eed9f41f91dd530f0be1 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Thu, 11 Aug 2016 21:34:54 +0200 Subject: s390/con3270: fix use of uninitialised data con3270 contains an optimisation that reduces the amount of data to be transmitted to the 3270 terminal by putting a Repeat to Address (RA) order into the data stream. The RA order itself takes up space, so con3270 only uses it if there's enough space left in the line buffer. Otherwise it just pads out the line manually. For lines too long to include the RA order, one byte was left uninitialised. This was caused by an off-by-one bug in the loop that pads out the line. Since the buffer is allocated from a common pool, the single byte left uninitialised contained some previous buffer content. Usually this was just a space or some character (which can result in clutter but is otherwise harmless). Sometimes, however, it was a Repeat to Address order, messing up the entire screen layout and causing the display to send the entire buffer content on every keystroke. Fixes: f51320a5 ("[PATCH] s390: new 3270 driver.") (tglx/history.git) Reported-by: Liu Jing Tested-by: Jing Liu Tested-by: Yang Chen Signed-off-by: Sascha Silbe Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3270.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 6b1577c73fe7..0c161dbec73d 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -464,7 +464,7 @@ con3270_cline_end(struct con3270 *cp) s->string[s->len - 4] = TO_RA; s->string[s->len - 1] = 0; } else { - while (--size > cp->cline->len) + while (--size >= cp->cline->len) s->string[size] = cp->view.ascebc[' ']; } /* Replace cline with allocated line s and reset cline. */ -- cgit v1.2.3-59-g8ed1b From 6cd997db911f28f2510b771691270c52b63ed2e6 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Tue, 20 Sep 2016 19:09:07 +0200 Subject: s390/con3270: fix insufficient space padding con3270 contains an optimisation that reduces the amount of data to be transmitted to the 3270 terminal by putting a Repeat to Address (RA) order into the data stream. The RA order itself takes up space, so con3270 only uses it if there's enough space left in the line buffer. Otherwise it just pads out the line manually. For lines that were _just_ short enough that the RA order still fit in the line buffer, the line was instead padded with an insufficient amount of spaces. This was caused by examining the size of the allocated line buffer rather than the length of the string to be displayed. For con3270_cline_end(), we just compare against the line length. For con3270_update_string() however that isn't available anymore, so we check whether the Repeat to Address order is present. Fixes: f51320a5 ("[PATCH] s390: new 3270 driver.") (tglx/history.git) Tested-by: Jing Liu Tested-by: Yang Chen Signed-off-by: Sascha Silbe Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3270.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 0c161dbec73d..285b4006f44b 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -124,7 +124,12 @@ con3270_create_status(struct con3270 *cp) static void con3270_update_string(struct con3270 *cp, struct string *s, int nr) { - if (s->len >= cp->view.cols - 5) + if (s->len < 4) { + /* This indicates a bug, but printing a warning would + * cause a deadlock. */ + return; + } + if (s->string[s->len - 4] != TO_RA) return; raw3270_buffer_address(cp->view.dev, s->string + s->len - 3, cp->view.cols * (nr + 1)); @@ -460,7 +465,7 @@ con3270_cline_end(struct con3270 *cp) cp->cline->len + 4 : cp->view.cols; s = con3270_alloc_string(cp, size); memcpy(s->string, cp->cline->string, cp->cline->len); - if (s->len < cp->view.cols - 5) { + if (cp->cline->len < cp->view.cols - 5) { s->string[s->len - 4] = TO_RA; s->string[s->len - 1] = 0; } else { -- cgit v1.2.3-59-g8ed1b