]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Nov 2018 10:14:28 +0000 (11:14 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Nov 2018 10:14:28 +0000 (11:14 +0100)
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

queue-3.18/cw1200-don-t-leak-memory-if-krealloc-failes.patch [new file with mode: 0644]
queue-3.18/scsi-qla2xxx-do-not-queue-commands-when-unloading.patch [new file with mode: 0644]
queue-3.18/scsi-ufs-fix-bugs-related-to-null-pointer-access-and-array-size.patch [new file with mode: 0644]
queue-3.18/scsi-ufs-fix-race-between-clock-gating-and-devfreq-scaling-work.patch [new file with mode: 0644]
queue-3.18/scsi-ufshcd-fix-race-between-clk-scaling-and-ungate-work.patch [new file with mode: 0644]
queue-3.18/series

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 (file)
index 0000000..933b5fc
--- /dev/null
@@ -0,0 +1,53 @@
+From 9afdd6128c39f42398041bb2e017d8df0dcebcd1 Mon Sep 17 00:00:00 2001
+From: Johannes Thumshirn <jthumshirn@suse.de>
+Date: Fri, 30 Sep 2016 14:39:17 +0200
+Subject: cw1200: Don't leak memory if krealloc failes
+
+From: Johannes Thumshirn <jthumshirn@suse.de>
+
+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 <jthumshirn@suse.de>
+Cc: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1db7ce6
--- /dev/null
@@ -0,0 +1,48 @@
+From 04dfaa53a0b6e66b328a5bc549e3af8f8b6eac02 Mon Sep 17 00:00:00 2001
+From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Date: Mon, 7 Nov 2016 17:53:30 -0200
+Subject: scsi: qla2xxx: do not queue commands when unloading
+
+From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+
+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 <mauricfo@linux.vnet.ibm.com>
+Acked-by: Himanshu Madhani <himanshu.madhani@cavium.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..16cab35
--- /dev/null
@@ -0,0 +1,101 @@
+From e3ce73d69aff44421d7899b235fec5ac2c306ff4 Mon Sep 17 00:00:00 2001
+From: Yaniv Gardi <ygardi@codeaurora.org>
+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 <ygardi@codeaurora.org>
+
+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 <ygardi@codeaurora.org>
+Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..57b2222
--- /dev/null
@@ -0,0 +1,138 @@
+From 30fc33f1ef475480dc5bea4fe1bda84b003b992c Mon Sep 17 00:00:00 2001
+From: Subhash Jadavani <subhashj@codeaurora.org>
+Date: Thu, 27 Oct 2016 17:25:47 -0700
+Subject: scsi: ufs: fix race between clock gating and devfreq scaling work
+
+From: Subhash Jadavani <subhashj@codeaurora.org>
+
+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 <stummala@codeaurora.org>
+Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..92daffb
--- /dev/null
@@ -0,0 +1,70 @@
+From f2a785ac23125fa0774327d39e837e45cf28fe92 Mon Sep 17 00:00:00 2001
+From: Venkat Gopalakrishnan <venkatg@codeaurora.org>
+Date: Mon, 17 Oct 2016 17:10:53 -0700
+Subject: scsi: ufshcd: Fix race between clk scaling and ungate work
+
+From: Venkat Gopalakrishnan <venkatg@codeaurora.org>
+
+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 <venkatg@codeaurora.org>
+Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)) {
index 39bc5fc196db6b9fd21712278fcad19b98be6806..9254f74a535cbc099ad5fc8988f21ac24a8646d3 100644 (file)
@@ -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