* [PATCH for-3.18.y 1/5] cw1200: Don't leak memory if krealloc failes
2018-11-28 14:47 [PATCH for-3.18.y 0/5] Stable candidates for linux-3.18.y Amit Pundir
@ 2018-11-28 14:47 ` Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 2/5] scsi: ufs: fix bugs related to null pointer access and array size Amit Pundir
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Amit Pundir @ 2018-11-28 14:47 UTC (permalink / raw)
To: Greg KH; +Cc: Stable, Johannes Thumshirn, Johannes Berg, Kalle Valo
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>
[AmitP: Refactored to fix driver file path in linux-3.18.y]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
---
drivers/net/wireless/cw1200/wsm.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index 9e0ca3048657..a5ac992670e8 100644
--- 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_buf *buf, size_t extra_size)
{
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;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH for-3.18.y 2/5] scsi: ufs: fix bugs related to null pointer access and array size
2018-11-28 14:47 [PATCH for-3.18.y 0/5] Stable candidates for linux-3.18.y Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 1/5] cw1200: Don't leak memory if krealloc failes Amit Pundir
@ 2018-11-28 14:47 ` Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 3/5] scsi: ufshcd: Fix race between clk scaling and ungate work Amit Pundir
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Amit Pundir @ 2018-11-28 14:47 UTC (permalink / raw)
To: Greg KH; +Cc: Stable, Yaniv Gardi, Subhash Jadavani, Martin K . Petersen
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>
[AmitP: Rebased for linux-3.18.y]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
---
drivers/scsi/ufs/ufs.h | 3 ++-
drivers/scsi/ufs/ufshcd.c | 25 +++++++++++++++++++------
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 42c459a9d3fe..ce5234555cc9 100644
--- 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];
};
/**
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 39a4e61bf8d2..3ff98821bec5 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -796,10 +796,14 @@ static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
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);
--
2.7.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH for-3.18.y 3/5] scsi: ufshcd: Fix race between clk scaling and ungate work
2018-11-28 14:47 [PATCH for-3.18.y 0/5] Stable candidates for linux-3.18.y Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 1/5] cw1200: Don't leak memory if krealloc failes Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 2/5] scsi: ufs: fix bugs related to null pointer access and array size Amit Pundir
@ 2018-11-28 14:47 ` Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 4/5] scsi: ufs: fix race between clock gating and devfreq scaling work Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 5/5] scsi: qla2xxx: do not queue commands when unloading Amit Pundir
4 siblings, 0 replies; 6+ messages in thread
From: Amit Pundir @ 2018-11-28 14:47 UTC (permalink / raw)
To: Greg KH
Cc: Stable, Venkat Gopalakrishnan, Subhash Jadavani, Martin K . Petersen
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>
---
drivers/scsi/ufs/ufshcd.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 3ff98821bec5..7b48fb84a900 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -570,6 +570,21 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
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)) {
--
2.7.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH for-3.18.y 4/5] scsi: ufs: fix race between clock gating and devfreq scaling work
2018-11-28 14:47 [PATCH for-3.18.y 0/5] Stable candidates for linux-3.18.y Amit Pundir
` (2 preceding siblings ...)
2018-11-28 14:47 ` [PATCH for-3.18.y 3/5] scsi: ufshcd: Fix race between clk scaling and ungate work Amit Pundir
@ 2018-11-28 14:47 ` Amit Pundir
2018-11-28 14:47 ` [PATCH for-3.18.y 5/5] scsi: qla2xxx: do not queue commands when unloading Amit Pundir
4 siblings, 0 replies; 6+ messages in thread
From: Amit Pundir @ 2018-11-28 14:47 UTC (permalink / raw)
To: Greg KH; +Cc: Stable, Subhash Jadavani, Martin K . Petersen
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>
---
drivers/scsi/ufs/ufshcd.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 7b48fb84a900..e8f3033d991b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5406,15 +5406,47 @@ static int ufshcd_devfreq_target(struct device *dev,
{
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;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH for-3.18.y 5/5] scsi: qla2xxx: do not queue commands when unloading
2018-11-28 14:47 [PATCH for-3.18.y 0/5] Stable candidates for linux-3.18.y Amit Pundir
` (3 preceding siblings ...)
2018-11-28 14:47 ` [PATCH for-3.18.y 4/5] scsi: ufs: fix race between clock gating and devfreq scaling work Amit Pundir
@ 2018-11-28 14:47 ` Amit Pundir
4 siblings, 0 replies; 6+ messages in thread
From: Amit Pundir @ 2018-11-28 14:47 UTC (permalink / raw)
To: Greg KH; +Cc: Stable, Mauricio Faria de Oliveira, Martin K . Petersen
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>
---
drivers/scsi/qla2xxx/qla_os.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7bc28c8d2832..4bd4f185102e 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -687,6 +687,11 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
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,
--
2.7.4
^ permalink raw reply related [flat|nested] 6+ messages in thread