From 0f36e06c93ae8ca8c5c1e848d91a1c0661915918 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 Nov 2018 11:14:06 +0100 Subject: [PATCH] 4.4-stable patches added patches: cw1200-don-t-leak-memory-if-krealloc-failes.patch mwifiex-fix-null-pointer-dereference-in-skb_dequeue.patch mwifiex-fix-p2p-device-doesn-t-find-in-scan-problem.patch netfilter-nf_tables-fix-oops-when-inserting-an-element-into-a-verdict-map.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 scsi-ufshcd-release-resources-if-probe-fails.patch --- ...don-t-leak-memory-if-krealloc-failes.patch | 53 +++++++ ...l-pointer-dereference-in-skb_dequeue.patch | 72 +++++++++ ...-device-doesn-t-find-in-scan-problem.patch | 42 ++++++ ...erting-an-element-into-a-verdict-map.patch | 63 ++++++++ ...do-not-queue-commands-when-unloading.patch | 48 ++++++ ...o-null-pointer-access-and-array-size.patch | 101 +++++++++++++ ...lock-gating-and-devfreq-scaling-work.patch | 138 ++++++++++++++++++ ...-between-clk-scaling-and-ungate-work.patch | 70 +++++++++ ...hcd-release-resources-if-probe-fails.patch | 85 +++++++++++ queue-4.4/series | 9 ++ 10 files changed, 681 insertions(+) create mode 100644 queue-4.4/cw1200-don-t-leak-memory-if-krealloc-failes.patch create mode 100644 queue-4.4/mwifiex-fix-null-pointer-dereference-in-skb_dequeue.patch create mode 100644 queue-4.4/mwifiex-fix-p2p-device-doesn-t-find-in-scan-problem.patch create mode 100644 queue-4.4/netfilter-nf_tables-fix-oops-when-inserting-an-element-into-a-verdict-map.patch create mode 100644 queue-4.4/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch create mode 100644 queue-4.4/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch create mode 100644 queue-4.4/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch create mode 100644 queue-4.4/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch create mode 100644 queue-4.4/scsi-ufshcd-release-resources-if-probe-fails.patch diff --git a/queue-4.4/cw1200-don-t-leak-memory-if-krealloc-failes.patch b/queue-4.4/cw1200-don-t-leak-memory-if-krealloc-failes.patch new file mode 100644 index 00000000000..dc8cc2c0c66 --- /dev/null +++ b/queue-4.4/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 +@@ -1805,16 +1805,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-4.4/mwifiex-fix-null-pointer-dereference-in-skb_dequeue.patch b/queue-4.4/mwifiex-fix-null-pointer-dereference-in-skb_dequeue.patch new file mode 100644 index 00000000000..fb1f237626e --- /dev/null +++ b/queue-4.4/mwifiex-fix-null-pointer-dereference-in-skb_dequeue.patch @@ -0,0 +1,72 @@ +From c44c040300d7afd79294710313a4989683e2afb1 Mon Sep 17 00:00:00 2001 +From: Amitkumar Karwar +Date: Wed, 28 Sep 2016 18:18:23 +0530 +Subject: mwifiex: Fix NULL pointer dereference in skb_dequeue() + +From: Amitkumar Karwar + +commit c44c040300d7afd79294710313a4989683e2afb1 upstream. + +At couple of places in cleanup path, we are just going through the +skb queue and freeing them without unlinking. This leads to a crash +when other thread tries to do skb_dequeue() and use already freed node. + +The problem is freed by unlinking skb before freeing it. + +Signed-off-by: Amitkumar Karwar +Signed-off-by: Kalle Valo +[AmitP: Refactored to fix driver file path in linux-4.4.y] +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mwifiex/cfg80211.c | 4 +++- + drivers/net/wireless/mwifiex/wmm.c | 12 +++++++++--- + 2 files changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/mwifiex/cfg80211.c +@@ -2839,8 +2839,10 @@ int mwifiex_del_virtual_intf(struct wiph + + mwifiex_stop_net_dev_queue(priv->netdev, adapter); + +- skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) ++ skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) { ++ skb_unlink(skb, &priv->bypass_txq); + mwifiex_write_data_complete(priv->adapter, skb, 0, -1); ++ } + + if (netif_carrier_ok(priv->netdev)) + netif_carrier_off(priv->netdev); +--- a/drivers/net/wireless/mwifiex/wmm.c ++++ b/drivers/net/wireless/mwifiex/wmm.c +@@ -501,8 +501,10 @@ mwifiex_wmm_del_pkts_in_ralist_node(stru + struct mwifiex_adapter *adapter = priv->adapter; + struct sk_buff *skb, *tmp; + +- skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) ++ skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) { ++ skb_unlink(skb, &ra_list->skb_head); + mwifiex_write_data_complete(adapter, skb, 0, -1); ++ } + } + + /* +@@ -598,11 +600,15 @@ mwifiex_clean_txrx(struct mwifiex_privat + priv->adapter->if_ops.clean_pcie_ring(priv->adapter); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); + +- skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) ++ skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) { ++ skb_unlink(skb, &priv->tdls_txq); + mwifiex_write_data_complete(priv->adapter, skb, 0, -1); ++ } + +- skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) ++ skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) { ++ skb_unlink(skb, &priv->bypass_txq); + mwifiex_write_data_complete(priv->adapter, skb, 0, -1); ++ } + atomic_set(&priv->adapter->bypass_tx_pending, 0); + + idr_for_each(&priv->ack_status_frames, mwifiex_free_ack_frame, NULL); diff --git a/queue-4.4/mwifiex-fix-p2p-device-doesn-t-find-in-scan-problem.patch b/queue-4.4/mwifiex-fix-p2p-device-doesn-t-find-in-scan-problem.patch new file mode 100644 index 00000000000..085c49b3b2d --- /dev/null +++ b/queue-4.4/mwifiex-fix-p2p-device-doesn-t-find-in-scan-problem.patch @@ -0,0 +1,42 @@ +From 3d8bd85c2c9e47ed2c82348aa5b6029ed48376ae Mon Sep 17 00:00:00 2001 +From: Karthik D A +Date: Wed, 28 Sep 2016 18:18:28 +0530 +Subject: mwifiex: fix p2p device doesn't find in scan problem + +From: Karthik D A + +commit 3d8bd85c2c9e47ed2c82348aa5b6029ed48376ae upstream. + +Marvell p2p device disappears from the list of p2p peers on the other +p2p device after disconnection. + +It happens due to a bug in driver. When interface is changed from p2p +to station, certain variables(bss_type, bss_role etc.) aren't correctly +updated. This patch corrects them to fix the issue. + +Signed-off-by: Karthik D A +Signed-off-by: Amitkumar Karwar +Signed-off-by: Kalle Valo +[AmitP: Refactored to fix driver file path in linux-4.4.y] +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mwifiex/cfg80211.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wireless/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/mwifiex/cfg80211.c +@@ -1150,6 +1150,12 @@ mwifiex_cfg80211_change_virtual_intf(str + priv->adapter->curr_iface_comb.p2p_intf--; + priv->adapter->curr_iface_comb.sta_intf++; + dev->ieee80211_ptr->iftype = type; ++ if (mwifiex_deinit_priv_params(priv)) ++ return -1; ++ if (mwifiex_init_new_priv_params(priv, dev, type)) ++ return -1; ++ if (mwifiex_sta_init_cmd(priv, false, false)) ++ return -1; + break; + case NL80211_IFTYPE_ADHOC: + if (mwifiex_cfg80211_deinit_p2p(priv)) diff --git a/queue-4.4/netfilter-nf_tables-fix-oops-when-inserting-an-element-into-a-verdict-map.patch b/queue-4.4/netfilter-nf_tables-fix-oops-when-inserting-an-element-into-a-verdict-map.patch new file mode 100644 index 00000000000..abd50ae64be --- /dev/null +++ b/queue-4.4/netfilter-nf_tables-fix-oops-when-inserting-an-element-into-a-verdict-map.patch @@ -0,0 +1,63 @@ +From 58c78e104d937c1f560fb10ed9bb2dcde0db4fcf Mon Sep 17 00:00:00 2001 +From: Liping Zhang +Date: Sun, 6 Nov 2016 14:40:01 +0800 +Subject: netfilter: nf_tables: fix oops when inserting an element into a verdict map + +From: Liping Zhang + +commit 58c78e104d937c1f560fb10ed9bb2dcde0db4fcf upstream. + +Dalegaard says: + The following ruleset, when loaded with 'nft -f bad.txt' + ----snip---- + flush ruleset + table ip inlinenat { + map sourcemap { + type ipv4_addr : verdict; + } + + chain postrouting { + ip saddr vmap @sourcemap accept + } + } + add chain inlinenat test + add element inlinenat sourcemap { 100.123.10.2 : jump test } + ----snip---- + + results in a kernel oops: + BUG: unable to handle kernel paging request at 0000000000001344 + IP: [] nf_tables_check_loops+0x114/0x1f0 [nf_tables] + [...] + Call Trace: + [] ? nft_data_init+0x13e/0x1a0 [nf_tables] + [] nft_validate_register_store+0x60/0xb0 [nf_tables] + [] nft_add_set_elem+0x545/0x5e0 [nf_tables] + [] ? nft_table_lookup+0x30/0x60 [nf_tables] + [] ? nla_strcmp+0x40/0x50 + [] nf_tables_newsetelem+0x11e/0x210 [nf_tables] + [] ? nla_validate+0x60/0x80 + [] nfnetlink_rcv+0x354/0x5a7 [nfnetlink] + +Because we forget to fill the net pointer in bind_ctx, so dereferencing +it may cause kernel crash. + +Reported-by: Dalegaard +Signed-off-by: Liping Zhang +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_tables_api.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3452,6 +3452,7 @@ static int nft_add_set_elem(struct nft_c + dreg = nft_type_to_reg(set->dtype); + list_for_each_entry(binding, &set->bindings, list) { + struct nft_ctx bind_ctx = { ++ .net = ctx->net, + .afi = ctx->afi, + .table = ctx->table, + .chain = (struct nft_chain *)binding->chain, diff --git a/queue-4.4/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch b/queue-4.4/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch new file mode 100644 index 00000000000..86a587bc3b1 --- /dev/null +++ b/queue-4.4/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 +@@ -685,6 +685,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-4.4/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch b/queue-4.4/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch new file mode 100644 index 00000000000..b507faeb38b --- /dev/null +++ b/queue-4.4/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 +@@ -813,10 +813,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)); + } + } + +@@ -5251,7 +5255,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. +@@ -5272,7 +5279,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); +@@ -5302,10 +5312,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-4.4/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch b/queue-4.4/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch new file mode 100644 index 00000000000..2bdc1562b81 --- /dev/null +++ b/queue-4.4/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 +@@ -5511,15 +5511,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-4.4/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch b/queue-4.4/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch new file mode 100644 index 00000000000..61fa916443e --- /dev/null +++ b/queue-4.4/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 +@@ -585,6 +585,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-4.4/scsi-ufshcd-release-resources-if-probe-fails.patch b/queue-4.4/scsi-ufshcd-release-resources-if-probe-fails.patch new file mode 100644 index 00000000000..2ed03c2360d --- /dev/null +++ b/queue-4.4/scsi-ufshcd-release-resources-if-probe-fails.patch @@ -0,0 +1,85 @@ +From afa3dfd42d205b106787476647735aa1de1a5d02 Mon Sep 17 00:00:00 2001 +From: Subhash Jadavani +Date: Thu, 27 Oct 2016 17:25:58 -0700 +Subject: scsi: ufshcd: release resources if probe fails + +From: Subhash Jadavani + +commit afa3dfd42d205b106787476647735aa1de1a5d02 upstream. + +If ufshcd pltfrm/pci driver's probe fails for some reason then ensure +that scsi host is released to avoid memory leak but managed memory +allocations (via devm_* calls) need not to be freed explicitly on probe +failure as memory allocated with these functions is automatically freed +on driver detach. + +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-pci.c | 2 ++ + drivers/scsi/ufs/ufshcd-pltfrm.c | 5 +---- + drivers/scsi/ufs/ufshcd.c | 3 --- + 3 files changed, 3 insertions(+), 7 deletions(-) + +--- a/drivers/scsi/ufs/ufshcd-pci.c ++++ b/drivers/scsi/ufs/ufshcd-pci.c +@@ -104,6 +104,7 @@ static void ufshcd_pci_remove(struct pci + pm_runtime_forbid(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); + ufshcd_remove(hba); ++ ufshcd_dealloc_host(hba); + } + + /** +@@ -147,6 +148,7 @@ ufshcd_pci_probe(struct pci_dev *pdev, c + err = ufshcd_init(hba, mmio_base, pdev->irq); + if (err) { + dev_err(&pdev->dev, "Initialization failed\n"); ++ ufshcd_dealloc_host(hba); + return err; + } + +--- a/drivers/scsi/ufs/ufshcd-pltfrm.c ++++ b/drivers/scsi/ufs/ufshcd-pltfrm.c +@@ -161,7 +161,7 @@ static int ufshcd_populate_vreg(struct d + if (ret) { + dev_err(dev, "%s: unable to find %s err %d\n", + __func__, prop_name, ret); +- goto out_free; ++ goto out; + } + + vreg->min_uA = 0; +@@ -183,9 +183,6 @@ static int ufshcd_populate_vreg(struct d + + goto out; + +-out_free: +- devm_kfree(dev, vreg); +- vreg = NULL; + out: + if (!ret) + *out_vreg = vreg; +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -5385,8 +5385,6 @@ void ufshcd_remove(struct ufs_hba *hba) + ufshcd_disable_intr(hba, hba->intr_mask); + ufshcd_hba_stop(hba); + +- scsi_host_put(hba->host); +- + ufshcd_exit_clk_gating(hba); + if (ufshcd_is_clkscaling_enabled(hba)) + devfreq_remove_device(hba->devfreq); +@@ -5733,7 +5731,6 @@ exit_gating: + ufshcd_exit_clk_gating(hba); + out_disable: + hba->is_irq_enabled = false; +- scsi_host_put(host); + ufshcd_hba_exit(hba); + out_error: + return err; diff --git a/queue-4.4/series b/queue-4.4/series index b463d500f34..e4df7488988 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -66,3 +66,12 @@ 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 +mwifiex-fix-null-pointer-dereference-in-skb_dequeue.patch +mwifiex-fix-p2p-device-doesn-t-find-in-scan-problem.patch +netfilter-nf_tables-fix-oops-when-inserting-an-element-into-a-verdict-map.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-ufshcd-release-resources-if-probe-fails.patch +scsi-qla2xxx-do-not-queue-commands-when-unloading.patch -- 2.47.3