From: Greg Kroah-Hartman Date: Thu, 29 Nov 2018 10:14:28 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v4.19.6~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=da97ac1ae976b9d2a3613cc163a8c231446e2086;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: cw1200-don-t-leak-memory-if-krealloc-failes.patch scsi-qla2xxx-do-not-queue-commands-when-unloading.patch scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch --- diff --git a/queue-3.18/cw1200-don-t-leak-memory-if-krealloc-failes.patch b/queue-3.18/cw1200-don-t-leak-memory-if-krealloc-failes.patch new file mode 100644 index 00000000000..933b5fc8825 --- /dev/null +++ b/queue-3.18/cw1200-don-t-leak-memory-if-krealloc-failes.patch @@ -0,0 +1,53 @@ +From 9afdd6128c39f42398041bb2e017d8df0dcebcd1 Mon Sep 17 00:00:00 2001 +From: Johannes Thumshirn +Date: Fri, 30 Sep 2016 14:39:17 +0200 +Subject: cw1200: Don't leak memory if krealloc failes + +From: Johannes Thumshirn + +commit 9afdd6128c39f42398041bb2e017d8df0dcebcd1 upstream. + +The call to krealloc() in wsm_buf_reserve() directly assigns the newly +returned memory to buf->begin. This is all fine except when krealloc() +failes we loose the ability to free the old memory pointed to by +buf->begin. If we just create a temporary variable to assign memory to +and assign the memory to it we can mitigate the memory leak. + +Signed-off-by: Johannes Thumshirn +Cc: Johannes Berg +Signed-off-by: Kalle Valo +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/cw1200/wsm.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/cw1200/wsm.c ++++ b/drivers/net/wireless/cw1200/wsm.c +@@ -1807,16 +1807,18 @@ static int wsm_buf_reserve(struct wsm_bu + { + size_t pos = buf->data - buf->begin; + size_t size = pos + extra_size; ++ u8 *tmp; + + size = round_up(size, FWLOAD_BLOCK_SIZE); + +- buf->begin = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA); +- if (buf->begin) { +- buf->data = &buf->begin[pos]; +- buf->end = &buf->begin[size]; +- return 0; +- } else { +- buf->end = buf->data = buf->begin; ++ tmp = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA); ++ if (!tmp) { ++ wsm_buf_deinit(buf); + return -ENOMEM; + } ++ ++ buf->begin = tmp; ++ buf->data = &buf->begin[pos]; ++ buf->end = &buf->begin[size]; ++ return 0; + } diff --git a/queue-3.18/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch b/queue-3.18/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch new file mode 100644 index 00000000000..1db7ce63dba --- /dev/null +++ b/queue-3.18/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch @@ -0,0 +1,48 @@ +From 04dfaa53a0b6e66b328a5bc549e3af8f8b6eac02 Mon Sep 17 00:00:00 2001 +From: Mauricio Faria de Oliveira +Date: Mon, 7 Nov 2016 17:53:30 -0200 +Subject: scsi: qla2xxx: do not queue commands when unloading + +From: Mauricio Faria de Oliveira + +commit 04dfaa53a0b6e66b328a5bc549e3af8f8b6eac02 upstream. + +When the driver is unloading, in qla2x00_remove_one(), there is a single +call/point in time to abort ongoing commands, qla2x00_abort_all_cmds(), +which is still several steps away from the call to scsi_remove_host(). + +If more commands continue to arrive and be processed during that +interval, when the driver is tearing down and releasing its structures, +it might potentially hit an oops due to invalid memory access: + + Unable to handle kernel paging request for data at address 0x00000138 + <...> + NIP [d000000004700a40] qla2xxx_queuecommand+0x80/0x3f0 [qla2xxx] + LR [d000000004700a10] qla2xxx_queuecommand+0x50/0x3f0 [qla2xxx] + +So, fail commands in qla2xxx_queuecommand() if the UNLOADING bit is set. + +Signed-off-by: Mauricio Faria de Oliveira +Acked-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_os.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -687,6 +687,11 @@ qla2xxx_queuecommand(struct Scsi_Host *h + srb_t *sp; + int rval; + ++ if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) { ++ cmd->result = DID_NO_CONNECT << 16; ++ goto qc24_fail_command; ++ } ++ + if (ha->flags.eeh_busy) { + if (ha->flags.pci_channel_io_perm_failure) { + ql_dbg(ql_dbg_aer, vha, 0x9010, diff --git a/queue-3.18/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch b/queue-3.18/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch new file mode 100644 index 00000000000..16cab3565ff --- /dev/null +++ b/queue-3.18/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch @@ -0,0 +1,101 @@ +From e3ce73d69aff44421d7899b235fec5ac2c306ff4 Mon Sep 17 00:00:00 2001 +From: Yaniv Gardi +Date: Mon, 17 Oct 2016 17:09:24 -0700 +Subject: scsi: ufs: fix bugs related to null pointer access and array size + +From: Yaniv Gardi + +commit e3ce73d69aff44421d7899b235fec5ac2c306ff4 upstream. + +In this change there are a few fixes of possible NULL pointer access and +possible access to index that exceeds array boundaries. + +Signed-off-by: Yaniv Gardi +Signed-off-by: Subhash Jadavani +Signed-off-by: Martin K. Petersen +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ufs/ufs.h | 3 ++- + drivers/scsi/ufs/ufshcd.c | 25 +++++++++++++++++++------ + 2 files changed, 21 insertions(+), 7 deletions(-) + +--- a/drivers/scsi/ufs/ufs.h ++++ b/drivers/scsi/ufs/ufs.h +@@ -45,6 +45,7 @@ + #define QUERY_DESC_MIN_SIZE 2 + #define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ + (sizeof(struct utp_upiu_header))) ++#define RESPONSE_UPIU_SENSE_DATA_LENGTH 18 + + #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ + cpu_to_be32((byte3 << 24) | (byte2 << 16) |\ +@@ -383,7 +384,7 @@ struct utp_cmd_rsp { + __be32 residual_transfer_count; + __be32 reserved[4]; + __be16 sense_data_len; +- u8 sense_data[18]; ++ u8 sense_data[RESPONSE_UPIU_SENSE_DATA_LENGTH]; + }; + + /** +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -796,10 +796,14 @@ static inline void ufshcd_copy_sense_dat + int len; + if (lrbp->sense_buffer && + ufshcd_get_rsp_upiu_data_seg_len(lrbp->ucd_rsp_ptr)) { ++ int len_to_copy; ++ + len = be16_to_cpu(lrbp->ucd_rsp_ptr->sr.sense_data_len); ++ len_to_copy = min_t(int, RESPONSE_UPIU_SENSE_DATA_LENGTH, len); ++ + memcpy(lrbp->sense_buffer, + lrbp->ucd_rsp_ptr->sr.sense_data, +- min_t(int, len, SCSI_SENSE_BUFFERSIZE)); ++ min_t(int, len_to_copy, SCSI_SENSE_BUFFERSIZE)); + } + } + +@@ -5161,7 +5165,10 @@ EXPORT_SYMBOL(ufshcd_system_suspend); + + int ufshcd_system_resume(struct ufs_hba *hba) + { +- if (!hba || !hba->is_powered || pm_runtime_suspended(hba->dev)) ++ if (!hba) ++ return -EINVAL; ++ ++ if (!hba->is_powered || pm_runtime_suspended(hba->dev)) + /* + * Let the runtime resume take care of resuming + * if runtime suspended. +@@ -5182,7 +5189,10 @@ EXPORT_SYMBOL(ufshcd_system_resume); + */ + int ufshcd_runtime_suspend(struct ufs_hba *hba) + { +- if (!hba || !hba->is_powered) ++ if (!hba) ++ return -EINVAL; ++ ++ if (!hba->is_powered) + return 0; + + return ufshcd_suspend(hba, UFS_RUNTIME_PM); +@@ -5212,10 +5222,13 @@ EXPORT_SYMBOL(ufshcd_runtime_suspend); + */ + int ufshcd_runtime_resume(struct ufs_hba *hba) + { +- if (!hba || !hba->is_powered) ++ if (!hba) ++ return -EINVAL; ++ ++ if (!hba->is_powered) + return 0; +- else +- return ufshcd_resume(hba, UFS_RUNTIME_PM); ++ ++ return ufshcd_resume(hba, UFS_RUNTIME_PM); + } + EXPORT_SYMBOL(ufshcd_runtime_resume); + diff --git a/queue-3.18/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch b/queue-3.18/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch new file mode 100644 index 00000000000..57b2222bbd1 --- /dev/null +++ b/queue-3.18/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch @@ -0,0 +1,138 @@ +From 30fc33f1ef475480dc5bea4fe1bda84b003b992c Mon Sep 17 00:00:00 2001 +From: Subhash Jadavani +Date: Thu, 27 Oct 2016 17:25:47 -0700 +Subject: scsi: ufs: fix race between clock gating and devfreq scaling work + +From: Subhash Jadavani + +commit 30fc33f1ef475480dc5bea4fe1bda84b003b992c upstream. + +UFS devfreq clock scaling work may require clocks to be ON if it need to +execute some UFS commands hence it may request for clock hold before +issuing the command. But if UFS clock gating work is already running in +parallel, ungate work would end up waiting for the clock gating work to +finish and as clock gating work would also wait for the clock scaling +work to finish, we would enter in deadlock state. Here is the call trace +during this deadlock state: + +Workqueue: devfreq_wq devfreq_monitor + __switch_to + __schedule + schedule + schedule_timeout + wait_for_common + wait_for_completion + flush_work + ufshcd_hold + ufshcd_send_uic_cmd + ufshcd_dme_get_attr + ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div + ufs_qcom_clk_scale_notify + ufshcd_scale_clks + ufshcd_devfreq_target + update_devfreq + devfreq_monitor + process_one_work + worker_thread + kthread + ret_from_fork + +Workqueue: events ufshcd_gate_work + __switch_to + __schedule + schedule + schedule_preempt_disabled + __mutex_lock_slowpath + mutex_lock + devfreq_monitor_suspend + devfreq_simple_ondemand_handler + devfreq_suspend_device + ufshcd_gate_work + process_one_work + worker_thread + kthread + ret_from_fork + +Workqueue: events ufshcd_ungate_work + __switch_to + __schedule + schedule + schedule_timeout + wait_for_common + wait_for_completion + flush_work + __cancel_work_timer + cancel_delayed_work_sync + ufshcd_ungate_work + process_one_work + worker_thread + kthread + ret_from_fork + +This change fixes this deadlock by doing this in devfreq work (devfreq_wq): +Try cancelling clock gating work. If we are able to cancel gating work +or it wasn't scheduled, hold the clock reference count until scaling is +in progress. If gate work is already running in parallel, let's skip +the frequecy scaling at this time and it will be retried once next scaling +window expires. + +Reviewed-by: Sahitya Tummala +Signed-off-by: Subhash Jadavani +Signed-off-by: Martin K. Petersen +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ufs/ufshcd.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -5406,15 +5406,47 @@ static int ufshcd_devfreq_target(struct + { + int err = 0; + struct ufs_hba *hba = dev_get_drvdata(dev); ++ bool release_clk_hold = false; ++ unsigned long irq_flags; + + if (!ufshcd_is_clkscaling_enabled(hba)) + return -EINVAL; + ++ spin_lock_irqsave(hba->host->host_lock, irq_flags); ++ if (ufshcd_eh_in_progress(hba)) { ++ spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ++ return 0; ++ } ++ ++ if (ufshcd_is_clkgating_allowed(hba) && ++ (hba->clk_gating.state != CLKS_ON)) { ++ if (cancel_delayed_work(&hba->clk_gating.gate_work)) { ++ /* hold the vote until the scaling work is completed */ ++ hba->clk_gating.active_reqs++; ++ release_clk_hold = true; ++ hba->clk_gating.state = CLKS_ON; ++ } else { ++ /* ++ * Clock gating work seems to be running in parallel ++ * hence skip scaling work to avoid deadlock between ++ * current scaling work and gating work. ++ */ ++ spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ++ return 0; ++ } ++ } ++ spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ++ + if (*freq == UINT_MAX) + err = ufshcd_scale_clks(hba, true); + else if (*freq == 0) + err = ufshcd_scale_clks(hba, false); + ++ spin_lock_irqsave(hba->host->host_lock, irq_flags); ++ if (release_clk_hold) ++ __ufshcd_release(hba); ++ spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ++ + return err; + } + diff --git a/queue-3.18/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch b/queue-3.18/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch new file mode 100644 index 00000000000..92daffb5a5b --- /dev/null +++ b/queue-3.18/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch @@ -0,0 +1,70 @@ +From f2a785ac23125fa0774327d39e837e45cf28fe92 Mon Sep 17 00:00:00 2001 +From: Venkat Gopalakrishnan +Date: Mon, 17 Oct 2016 17:10:53 -0700 +Subject: scsi: ufshcd: Fix race between clk scaling and ungate work + +From: Venkat Gopalakrishnan + +commit f2a785ac23125fa0774327d39e837e45cf28fe92 upstream. + +The ungate work turns on the clock before it exits hibern8, if the link +was put in hibern8 during clock gating work. There occurs a race +condition when clock scaling work calls ufshcd_hold() to make sure low +power states cannot be entered, but that returns by checking only +whether the clocks are on. This causes the clock scaling work to issue +UIC commands when the link is in hibern8 causing failures. Make sure we +exit hibern8 state before returning from ufshcd_hold(). + +Callstacks for race condition: + + ufshcd_scale_gear + ufshcd_devfreq_scale + ufshcd_devfreq_target + update_devfreq + devfreq_monitor + process_one_work + worker_thread + kthread + ret_from_fork + + ufshcd_uic_hibern8_exit + ufshcd_ungate_work + process_one_work + worker_thread + kthread + ret_from_fork + +Signed-off-by: Venkat Gopalakrishnan +Signed-off-by: Subhash Jadavani +Signed-off-by: Martin K. Petersen +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ufs/ufshcd.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -570,6 +570,21 @@ int ufshcd_hold(struct ufs_hba *hba, boo + start: + switch (hba->clk_gating.state) { + case CLKS_ON: ++ /* ++ * Wait for the ungate work to complete if in progress. ++ * Though the clocks may be in ON state, the link could ++ * still be in hibner8 state if hibern8 is allowed ++ * during clock gating. ++ * Make sure we exit hibern8 state also in addition to ++ * clocks being ON. ++ */ ++ if (ufshcd_can_hibern8_during_gating(hba) && ++ ufshcd_is_link_hibern8(hba)) { ++ spin_unlock_irqrestore(hba->host->host_lock, flags); ++ flush_work(&hba->clk_gating.ungate_work); ++ spin_lock_irqsave(hba->host->host_lock, flags); ++ goto start; ++ } + break; + case REQ_CLKS_OFF: + if (cancel_delayed_work(&hba->clk_gating.gate_work)) { diff --git a/queue-3.18/series b/queue-3.18/series index 39bc5fc196d..9254f74a535 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -72,3 +72,8 @@ input-xpad-avoid-using-__set_bit-for-capabilities.patch input-xpad-add-gpd-win-2-controller-usb-ids.patch input-xpad-fix-gpd-win-2-controller-name.patch input-xpad-add-support-for-xbox1-pdp-camo-series-gam.patch +cw1200-don-t-leak-memory-if-krealloc-failes.patch +scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch +scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch +scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch +scsi-qla2xxx-do-not-queue-commands-when-unloading.patch