From 814a3c0c2a8dfad97089f6bdc71b374f6076490e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 10 Feb 2016 15:02:44 -0800 Subject: [PATCH 1/8] mmc: omap_hsmmc: Fix PM regression with deferred probe for pm_runtime_reinit Commit 5de85b9d57ab ("PM / runtime: Re-init runtime PM states at probe error and driver unbind") introduced pm_runtime_reinit() that is used to reinitialize PM runtime after -EPROBE_DEFER. This allows shutting down the device after a failed probe. However, for drivers using pm_runtime_use_autosuspend() this can cause a state where suspend callback is never called after -EPROBE_DEFER. On the following device driver probe, hardware state is different from the PM runtime state causing omap_device to produce the following error: omap_device_enable() called from invalid state 1 And with omap_device and omap hardware being picky for PM, this will block any deeper idle states in hardware. The solution is to fix the drivers to follow the PM runtime documentation: 1. For sections of code that needs the device disabled, use pm_runtime_put_sync_suspend() if pm_runtime_set_autosuspend() has been set. 2. For driver exit code, use pm_runtime_dont_use_autosuspend() before pm_runtime_put_sync() if pm_runtime_use_autosuspend() has been set. Fixes: 5de85b9d57ab ("PM / runtime: Re-init runtime PM states at probe error and driver unbind") Cc: linux-mmc@vger.kernel.org Cc: Alan Stern Cc: Kevin Hilman Cc: Nishanth Menon Cc: Rafael J. Wysocki Cc: Ulf Hansson Cc: Tero Kristo Signed-off-by: Tony Lindgren Signed-off-by: Ulf Hansson --- drivers/mmc/host/omap_hsmmc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b6639ea0bf18..f6e4d9718035 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2232,6 +2232,7 @@ err_irq: dma_release_channel(host->tx_chan); if (host->rx_chan) dma_release_channel(host->rx_chan); + pm_runtime_dont_use_autosuspend(host->dev); pm_runtime_put_sync(host->dev); pm_runtime_disable(host->dev); if (host->dbclk) @@ -2253,6 +2254,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev) dma_release_channel(host->tx_chan); dma_release_channel(host->rx_chan); + pm_runtime_dont_use_autosuspend(host->dev); pm_runtime_put_sync(host->dev); pm_runtime_disable(host->dev); device_init_wakeup(&pdev->dev, false); From 4328daa2e79ed904a42ce00a9f38b9c36b44b21a Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Sun, 21 Feb 2016 19:09:22 -0500 Subject: [PATCH 2/8] dm: fix dm_rq_target_io leak on faults with .request_fn DM w/ blk-mq paths Using request-based DM mpath configured with the following stacking (.request_fn DM mpath ontop of scsi-mq paths): echo Y > /sys/module/scsi_mod/parameters/use_blk_mq echo N > /sys/module/dm_mod/parameters/use_blk_mq 'struct dm_rq_target_io' would leak if a request is requeued before a blk-mq clone is allocated (or fails to allocate). free_rq_tio() wasn't being called. kmemleak reported: unreferenced object 0xffff8800b90b98c0 (size 112): comm "kworker/7:1H", pid 5692, jiffies 4295056109 (age 78.589s) hex dump (first 32 bytes): 00 d0 5c 2c 03 88 ff ff 40 00 bf 01 00 c9 ff ff ..\,....@....... e0 d9 b1 34 00 88 ff ff 00 00 00 00 00 00 00 00 ...4............ backtrace: [] kmemleak_alloc+0x4e/0xb0 [] kmem_cache_alloc+0xc3/0x1e0 [] mempool_alloc_slab+0x15/0x20 [] mempool_alloc+0x6e/0x170 [] dm_old_prep_fn+0x3c/0x180 [dm_mod] [] blk_peek_request+0x168/0x290 [] dm_request_fn+0xb2/0x1b0 [dm_mod] [] __blk_run_queue+0x33/0x40 [] blk_delay_work+0x25/0x40 [] process_one_work+0x14f/0x3d0 [] worker_thread+0x125/0x4b0 [] kthread+0xd8/0xf0 [] ret_from_fork+0x3f/0x70 [] 0xffffffffffffffff crash> struct -o dm_rq_target_io struct dm_rq_target_io { ... } SIZE: 112 Fixes: e5863d9ad7 ("dm: allocate requests in target when stacking on blk-mq devices") Cc: stable@vger.kernel.org # 4.0+ Signed-off-by: Mike Snitzer --- drivers/md/dm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 5df40480228b..dd834927bc66 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1191,6 +1191,8 @@ static void dm_unprep_request(struct request *rq) if (clone) free_rq_clone(clone); + else if (!tio->md->queue->mq_ops) + free_rq_tio(tio); } /* From e1cd3911170eda37fd9501e81ee1c2eb63803fd0 Mon Sep 17 00:00:00 2001 From: jiangyiwen Date: Tue, 16 Feb 2016 20:14:13 +0800 Subject: [PATCH 3/8] SCSI: Free resources when we return BLKPREP_INVALID When called scsi_prep_fn return BLKPREP_INVALID, we should use the same code with BLKPREP_KILL in scsi_prep_return. Signed-off-by: Yiwen Jiang Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index fa6b2c4eb7a2..8c6e31874171 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1344,6 +1344,7 @@ scsi_prep_return(struct request_queue *q, struct request *req, int ret) switch (ret) { case BLKPREP_KILL: + case BLKPREP_INVALID: req->errors = DID_NO_CONNECT << 16; /* release the command and kill it */ if (req->special) { From 21b81716c6bff24cda52dc75588455f879ddbfe9 Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Thu, 25 Feb 2016 13:54:20 -0300 Subject: [PATCH 4/8] ipr: Fix regression when loading firmware Commit d63c7dd5bcb9 ("ipr: Fix out-of-bounds null overwrite") removed the end of line handling when storing the update_fw sysfs attribute. This changed the userpace API because it started refusing writes terminated by a line feed, which broke the update tools we already have. This patch re-adds that handling, so both a write terminated by a line feed or not can make it through with the update. Fixes: d63c7dd5bcb9 ("ipr: Fix out-of-bounds null overwrite") Signed-off-by: Gabriel Krisman Bertazi Cc: Insu Yun Acked-by: Brian King Signed-off-by: Martin K. Petersen --- drivers/scsi/ipr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 3b3e0998fa6e..d6a691e27d33 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4002,6 +4002,7 @@ static ssize_t ipr_store_update_fw(struct device *dev, struct ipr_sglist *sglist; char fname[100]; char *src; + char *endline; int result, dnld_size; if (!capable(CAP_SYS_ADMIN)) @@ -4009,6 +4010,10 @@ static ssize_t ipr_store_update_fw(struct device *dev, snprintf(fname, sizeof(fname), "%s", buf); + endline = strchr(fname, '\n'); + if (endline) + *endline = '\0'; + if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) { dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname); return -EIO; From 6540a65da90c09590897310e31993b1f6e28485a Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Sat, 5 Mar 2016 17:52:02 -0500 Subject: [PATCH 5/8] sd: Fix discard granularity when LBPRZ=1 Commit 397737223c59 ("sd: Make discard granularity match logical block size when LBPRZ=1") accidentally set the granularity to one byte instead of one logical block on devices that provide deterministic zeroes after UNMAP. Signed-off-by: Martin K. Petersen Reported-by: Mike Snitzer Reviewed-by: Ewan Milne Reviewed-by: Bart Van Assche Fixes: 397737223c59e89dca7305feb6528caef8fbef84 Cc: #v4.4+ --- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d749da765df1..5a5457ac9cdb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -648,7 +648,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) */ if (sdkp->lbprz) { q->limits.discard_alignment = 0; - q->limits.discard_granularity = 1; + q->limits.discard_granularity = logical_block_size; } else { q->limits.discard_alignment = sdkp->unmap_alignment * logical_block_size; From 84bd64993f916bcf86270c67686ecf4cea7b8933 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Fri, 4 Mar 2016 10:41:49 +0100 Subject: [PATCH 6/8] be2iscsi: set the boot_kset pointer to NULL in case of failure In beiscsi_setup_boot_info(), the boot_kset pointer should be set to NULL in case of failure otherwise an invalid pointer dereference may occur later. Cc: Signed-off-by: Maurizio Lombardi Reviewed-by: Johannes Thumshirn Reviewed-by: Jitendra Bhivare Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index cb9072a841be..069e5c50abd0 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4468,6 +4468,7 @@ put_shost: scsi_host_put(phba->shost); free_kset: iscsi_boot_destroy_kset(phba->boot_kset); + phba->boot_kset = NULL; return -ENOMEM; } From ff06c5ffbcb4ffa542fb80c897be977956fafecc Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 7 Mar 2016 11:59:44 +0100 Subject: [PATCH 7/8] scsi: storvsc: fix SRB_STATUS_ABORTED handling Commit 3209f9d780d1 ("scsi: storvsc: Fix a bug in the handling of SRB status flags") filtered SRB_STATUS_AUTOSENSE_VALID out effectively making the (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID) case a dead code. The logic from this branch (e.g. storvsc_device_scan() call) is still required, fix the check. Cc: #v4.4+ Fixes: 3209f9d780d1 ("scsi: storvsc: Fix a bug in the handling of SRB status flags") Signed-off-by: Vitaly Kuznetsov Acked-by: K. Y. Srinivasan Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 292c04eec9ad..3ddcabb790a8 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -914,8 +914,9 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, do_work = true; process_err_fn = storvsc_remove_lun; break; - case (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID): - if ((asc == 0x2a) && (ascq == 0x9)) { + case SRB_STATUS_ABORTED: + if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID && + (asc == 0x2a) && (ascq == 0x9)) { do_work = true; process_err_fn = storvsc_device_scan; /* From 5ecee0a3ee8d74b6950cb41e8989b0c2174568d4 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Thu, 3 Mar 2016 00:31:29 -0500 Subject: [PATCH 8/8] sg: fix dxferp in from_to case One of the strange things that the original sg driver did was let the user provide both a data-out buffer (it followed the sg_header+cdb) _and_ specify a reply length greater than zero. What happened was that the user data-out buffer was copied into some kernel buffers and then the mid level was told a read type operation would take place with the data from the device overwriting the same kernel buffers. The user would then read those kernel buffers back into the user space. From what I can tell, the above action was broken by commit fad7f01e61bf ("sg: set dxferp to NULL for READ with the older SG interface") in 2008 and syzkaller found that out recently. Make sure that a user space pointer is passed through when data follows the sg_header structure and command. Fix the abnormal case when a non-zero reply_len is also given. Fixes: fad7f01e61bf737fe8a3740d803f000db57ecac6 Cc: #v2.6.28+ Signed-off-by: Douglas Gilbert Reviewed-by: Ewan Milne Signed-off-by: Martin K. Petersen --- drivers/scsi/sg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 5e820674432c..ae7d9bdf409c 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -652,7 +652,8 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) else hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; hp->dxfer_len = mxsize; - if (hp->dxfer_direction == SG_DXFER_TO_DEV) + if ((hp->dxfer_direction == SG_DXFER_TO_DEV) || + (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV)) hp->dxferp = (char __user *)buf + cmd_size; else hp->dxferp = NULL;