A recent review of the Sony Xperia Development kernel tree [0] resulted in the discovery of various patches which have been backported from Mainline in order to fix an array of issues. These patches should be applied to Stable such that everyone can benefit from them.
Note: The review is still on-going (~50%) - more to follow.
[0] https://github.com/sonyxperiadev/kernel
Arvind Yadav (1): rpmsg: glink: use put_device() if device_register fail
Austin Kim (1): mm/vmalloc.c: move 'area->pages' after if statement
Bjorn Andersson (1): rpmsg: glink: smem: Ensure ordering during tx
Chris Lew (1): soc: qcom: smem: Use le32_to_cpu for comparison
Dedy Lansky (2): wil6210: fix temperature debugfs wil6210: rate limit wil_rx_refill error
Geert Uytterhoeven (1): clk: Fix debugfs_create_*() usage
Gustavo A. R. Silva (1): android: binder: Use true and false for boolean values
Hamad Kadmany (2): wil6210: increase firmware ready timeout wil6210: abort properly in cfg suspend
Joe Moriarty (1): drm: NULL pointer dereference [null-pointer-deref] (CWE 476) problem
Lazar Alexei (1): wil6210: fix PCIe bus mastering in case of interface down
Lior David (2): wil6210: add block size checks during FW load wil6210: fix length check in __wmi_send
Mohit Aggarwal (1): rtc: pm8xxx: Fix issue in RTC write path
Prasad Sodagudi (1): arch_topology: Fix section miss match warning due to free_raw_capacity()
Rob Herring (1): of: fix missing kobject init for !SYSFS && OF_DYNAMIC config
Subash Abhinov Kasiviswanathan (1): net: qualcomm: rmnet: Fix casting issues
Subhash Jadavani (1): scsi: ufs: ufs-qcom: remove broken hci version quirk
Timur Tabi (1): Revert "gpio: set up initial state from .get_direction()"
Venkat Gopalakrishnan (1): scsi: ufs: make sure all interrupts are processed
Wei Yongjun (1): rpmsg: glink: Fix missing mutex_init() in qcom_glink_alloc_channel()
Will Deacon (1): arm64: traps: Don't print stack or raw PC/LR values in backtraces
Xu YiPing (1): arm64: perf: remove unsupported events for Cortex-A73
arch/arm64/kernel/perf_event.c | 6 -- arch/arm64/kernel/process.c | 8 +-- arch/arm64/kernel/traps.c | 65 +------------------ drivers/android/binder.c | 6 +- drivers/base/arch_topology.c | 2 +- drivers/clk/clk.c | 32 +++++---- drivers/gpio/gpiolib.c | 31 ++------- drivers/gpu/drm/drm_dp_mst_topology.c | 8 ++- .../net/ethernet/qualcomm/rmnet/rmnet_map.h | 6 +- drivers/net/wireless/ath/wil6210/cfg80211.c | 7 +- drivers/net/wireless/ath/wil6210/debugfs.c | 7 +- drivers/net/wireless/ath/wil6210/fw_inc.c | 58 +++++++++++------ drivers/net/wireless/ath/wil6210/interrupt.c | 22 ++++++- drivers/net/wireless/ath/wil6210/main.c | 2 +- drivers/net/wireless/ath/wil6210/pcie_bus.c | 24 ++++--- drivers/net/wireless/ath/wil6210/pm.c | 10 +-- drivers/net/wireless/ath/wil6210/txrx.c | 4 +- drivers/net/wireless/ath/wil6210/wil6210.h | 5 +- drivers/net/wireless/ath/wil6210/wmi.c | 13 +++- drivers/of/base.c | 3 - drivers/rpmsg/qcom_glink_native.c | 1 + drivers/rpmsg/qcom_glink_smem.c | 6 +- drivers/rtc/rtc-pm8xxx.c | 49 ++++++++++---- drivers/scsi/ufs/ufs-qcom.c | 2 +- drivers/scsi/ufs/ufshcd.c | 27 +++++--- drivers/soc/qcom/smem.c | 2 +- mm/vmalloc.c | 8 ++- 27 files changed, 212 insertions(+), 202 deletions(-)
From: Joe Moriarty joe.moriarty@oracle.com
[ Upstream commit 22a07038c0eaf4d1315a493ce66dcd255accba19 ]
The Parfait (version 2.1.0) static code analysis tool found the following NULL pointer derefernce problem.
- drivers/gpu/drm/drm_dp_mst_topology.c The call to drm_dp_calculate_rad() in function drm_dp_port_setup_pdt() could result in a NULL pointer being returned to port->mstb due to a failure to allocate memory for port->mstb.
Signed-off-by: Joe Moriarty joe.moriarty@oracle.com Reviewed-by: Steven Sistare steven.sistare@oracle.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20180212195144.98323-3-joe.mor... Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index f0d819fc16cd7..4a008fb8b1afc 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1043,10 +1043,12 @@ static bool drm_dp_port_setup_pdt(struct drm_dp_mst_port *port) lct = drm_dp_calculate_rad(port, rad);
port->mstb = drm_dp_add_mst_branch_device(lct, rad); - port->mstb->mgr = port->mgr; - port->mstb->port_parent = port; + if (port->mstb) { + port->mstb->mgr = port->mgr; + port->mstb->port_parent = port;
- send_link = true; + send_link = true; + } break; } return send_link;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 4c8326d5ebb0de3191e98980c80ab644026728d0 ]
When exposing data access through debugfs, the correct debugfs_create_*() functions must be used, matching the data types.
Remove all casts from data pointers passed to debugfs_create_*() functions, as such casts prevent the compiler from flagging bugs.
clk_core.rate and .accuracy are "unsigned long", hence casting their addresses to "u32 *" exposed the wrong halves on big-endian 64-bit systems. Fix this by using debugfs_create_ulong() instead.
Octal permissions are preferred, as they are easier to read than symbolic permissions. Hence replace "S_IRUGO" by "0444" throughout.
Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be [sboyd@codeaurora.org: Squash the octal change in too] Signed-off-by: Stephen Boyd sboyd@codeaurora.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/clk/clk.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8341a128dab1d..44b6f23cc851d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2172,18 +2172,16 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
core->dentry = d;
- d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry, - (u32 *)&core->rate); + d = debugfs_create_ulong("clk_rate", 0444, core->dentry, &core->rate); if (!d) goto err_out;
- d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry, - (u32 *)&core->accuracy); + d = debugfs_create_ulong("clk_accuracy", 0444, core->dentry, + &core->accuracy); if (!d) goto err_out;
- d = debugfs_create_u32("clk_phase", S_IRUGO, core->dentry, - (u32 *)&core->phase); + d = debugfs_create_u32("clk_phase", 0444, core->dentry, &core->phase); if (!d) goto err_out;
@@ -2192,23 +2190,23 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) if (!d) goto err_out;
- d = debugfs_create_u32("clk_prepare_count", S_IRUGO, core->dentry, - (u32 *)&core->prepare_count); + d = debugfs_create_u32("clk_prepare_count", 0444, core->dentry, + &core->prepare_count); if (!d) goto err_out;
- d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry, - (u32 *)&core->enable_count); + d = debugfs_create_u32("clk_enable_count", 0444, core->dentry, + &core->enable_count); if (!d) goto err_out;
- d = debugfs_create_u32("clk_notifier_count", S_IRUGO, core->dentry, - (u32 *)&core->notifier_count); + d = debugfs_create_u32("clk_notifier_count", 0444, core->dentry, + &core->notifier_count); if (!d) goto err_out;
if (core->num_parents > 1) { - d = debugfs_create_file("clk_possible_parents", S_IRUGO, + d = debugfs_create_file("clk_possible_parents", 0444, core->dentry, core, &possible_parents_fops); if (!d) goto err_out; @@ -2304,22 +2302,22 @@ static int __init clk_debug_init(void) if (!rootdir) return -ENOMEM;
- d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists, + d = debugfs_create_file("clk_summary", 0444, rootdir, &all_lists, &clk_summary_fops); if (!d) return -ENOMEM;
- d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists, + d = debugfs_create_file("clk_dump", 0444, rootdir, &all_lists, &clk_dump_fops); if (!d) return -ENOMEM;
- d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir, + d = debugfs_create_file("clk_orphan_summary", 0444, rootdir, &orphan_list, &clk_summary_fops); if (!d) return -ENOMEM;
- d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir, + d = debugfs_create_file("clk_orphan_dump", 0444, rootdir, &orphan_list, &clk_dump_fops); if (!d) return -ENOMEM;
From: Timur Tabi timur@codeaurora.org
[ Upstream commit 1ca2a92b2a99323f666f1b669b7484df4bda05e4 ]
This reverts commit 72d3200061776264941be1b5a9bb8e926b3b30a5.
We cannot blindly query the direction of all GPIOs when the pins are first registered. The get_direction callback normally triggers a read/write to hardware, but we shouldn't be touching the hardware for an individual GPIO until after it's been properly claimed.
Signed-off-by: Timur Tabi timur@codeaurora.org Reviewed-by: Stephen Boyd sboyd@codeaurora.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/gpio/gpiolib.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f0777a7a4305b..d5b42cc86d718 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1245,31 +1245,14 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) struct gpio_desc *desc = &gdev->descs[i];
desc->gdev = gdev; - /* - * REVISIT: most hardware initializes GPIOs as inputs - * (often with pullups enabled) so power usage is - * minimized. Linux code should set the gpio direction - * first thing; but until it does, and in case - * chip->get_direction is not set, we may expose the - * wrong direction in sysfs. - */ - - if (chip->get_direction) { - /* - * If we have .get_direction, set up the initial - * direction flag from the hardware. - */ - int dir = chip->get_direction(chip, i);
- if (!dir) - set_bit(FLAG_IS_OUT, &desc->flags); - } else if (!chip->direction_input) { - /* - * If the chip lacks the .direction_input callback - * we logically assume all lines are outputs. - */ - set_bit(FLAG_IS_OUT, &desc->flags); - } + /* REVISIT: most hardware initializes GPIOs as inputs (often + * with pullups enabled) so power usage is minimized. Linux + * code should set the gpio direction first thing; but until + * it does, and in case chip->get_direction is not set, we may + * expose the wrong direction in sysfs. + */ + desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; }
#ifdef CONFIG_PINCTRL
From: Xu YiPing xuyiping@hisilicon.com
[ Upstream commit f8ada189550984ee21f27be736042b74a7da1d68 ]
bus access read/write events are not supported in A73, based on the Cortex-A73 TRM r0p2, section 11.9 Events (pages 11-457 to 11-460).
Fixes: 5561b6c5e981 "arm64: perf: add support for Cortex-A73" Acked-by: Julien Thierry julien.thierry@arm.com Signed-off-by: Xu YiPing xuyiping@hisilicon.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Lee Jones lee.jones@linaro.org --- arch/arm64/kernel/perf_event.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 05fdae70e9f6e..53df84b2a07f4 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -262,12 +262,6 @@ static const unsigned armv8_a73_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD, [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, - - [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, - [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, - - [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, - [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, };
static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
From: Will Deacon will.deacon@arm.com
[ Upstream commit a25ffd3a6302a67814280274d8f1aa4ae2ea4b59 ]
Printing raw pointer values in backtraces has potential security implications and are of questionable value anyway.
This patch follows x86's lead and removes the "Exception stack:" dump from kernel backtraces, as well as converting PC/LR values to symbols such as "sysrq_handle_crash+0x20/0x30".
Tested-by: Laura Abbott labbott@redhat.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Lee Jones lee.jones@linaro.org --- arch/arm64/kernel/process.c | 8 ++--- arch/arm64/kernel/traps.c | 65 ++----------------------------------- 2 files changed, 6 insertions(+), 67 deletions(-)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index ee5ce03c9315d..2ff327651ebec 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -186,11 +186,9 @@ void __show_regs(struct pt_regs *regs) }
show_regs_print_info(KERN_DEFAULT); - print_symbol("PC is at %s\n", instruction_pointer(regs)); - print_symbol("LR is at %s\n", lr); - printk("pc : [<%016llx>] lr : [<%016llx>] pstate: %08llx\n", - regs->pc, lr, regs->pstate); - printk("sp : %016llx\n", sp); + print_symbol("pc : %s\n", regs->pc); + print_symbol("lr : %s\n", lr); + printk("sp : %016llx pstate : %08llx\n", sp, regs->pstate);
i = top_reg;
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 5ae9c86c30d1d..b30d23431fe11 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -59,55 +59,9 @@ static const char *handler[]= {
int show_unhandled_signals = 0;
-/* - * Dump out the contents of some kernel memory nicely... - */ -static void dump_mem(const char *lvl, const char *str, unsigned long bottom, - unsigned long top) -{ - unsigned long first; - mm_segment_t fs; - int i; - - /* - * We need to switch to kernel mode so that we can use __get_user - * to safely read from kernel space. - */ - fs = get_fs(); - set_fs(KERNEL_DS); - - printk("%s%s(0x%016lx to 0x%016lx)\n", lvl, str, bottom, top); - - for (first = bottom & ~31; first < top; first += 32) { - unsigned long p; - char str[sizeof(" 12345678") * 8 + 1]; - - memset(str, ' ', sizeof(str)); - str[sizeof(str) - 1] = '\0'; - - for (p = first, i = 0; i < (32 / 8) - && p < top; i++, p += 8) { - if (p >= bottom && p < top) { - unsigned long val; - - if (__get_user(val, (unsigned long *)p) == 0) - sprintf(str + i * 17, " %016lx", val); - else - sprintf(str + i * 17, " ????????????????"); - } - } - printk("%s%04lx:%s\n", lvl, first & 0xffff, str); - } - - set_fs(fs); -} - static void dump_backtrace_entry(unsigned long where) { - /* - * Note that 'where' can have a physical address, but it's not handled. - */ - print_ip_sym(where); + printk(" %pS\n", (void *)where); }
static void __dump_instr(const char *lvl, struct pt_regs *regs) @@ -177,10 +131,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) #endif
printk("Call trace:\n"); - while (1) { - unsigned long stack; - int ret; - + do { /* skip until specified stack frame */ if (!skip) { dump_backtrace_entry(frame.pc); @@ -195,17 +146,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) */ dump_backtrace_entry(regs->pc); } - ret = unwind_frame(tsk, &frame); - if (ret < 0) - break; - if (in_entry_text(frame.pc)) { - stack = frame.fp - offsetof(struct pt_regs, stackframe); - - if (on_accessible_stack(tsk, stack)) - dump_mem("", "Exception stack", stack, - stack + sizeof(struct pt_regs)); - } - } + } while (!unwind_frame(tsk, &frame));
put_task_stack(tsk); }
From: "Gustavo A. R. Silva" gustavo@embeddedor.com
[ Upstream commit 197410ad884eb18b31d48e9d8e64cb5a9e326f2f ]
Assign true or false to boolean variables instead of an integer value.
This issue was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Cc: Todd Kjos tkjos@android.com Cc: Martijn Coenen maco@android.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/android/binder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 05e75d18b4d93..afb690ed31ed9 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -249,7 +249,7 @@ static struct binder_transaction_log_entry *binder_transaction_log_add( unsigned int cur = atomic_inc_return(&log->cur);
if (cur >= ARRAY_SIZE(log->entry)) - log->full = 1; + log->full = true; e = &log->entry[cur % ARRAY_SIZE(log->entry)]; WRITE_ONCE(e->debug_id_done, 0); /* @@ -2598,7 +2598,7 @@ static bool binder_proc_transaction(struct binder_transaction *t, target_list = &node->async_todo; wakeup = false; } else { - node->has_async_transaction = 1; + node->has_async_transaction = true; } }
@@ -3453,7 +3453,7 @@ static int binder_thread_write(struct binder_proc *proc, w = binder_dequeue_work_head_ilocked( &buf_node->async_todo); if (!w) { - buf_node->has_async_transaction = 0; + buf_node->has_async_transaction = false; } else { binder_enqueue_work_ilocked( w, &proc->todo);
On Tue, Apr 21, 2020 at 01:39:59PM +0100, Lee Jones wrote:
From: "Gustavo A. R. Silva" gustavo@embeddedor.com
[ Upstream commit 197410ad884eb18b31d48e9d8e64cb5a9e326f2f ]
Assign true or false to boolean variables instead of an integer value.
This issue was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Cc: Todd Kjos tkjos@android.com Cc: Martijn Coenen maco@android.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Lee Jones lee.jones@linaro.org
drivers/android/binder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 05e75d18b4d93..afb690ed31ed9 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -249,7 +249,7 @@ static struct binder_transaction_log_entry *binder_transaction_log_add( unsigned int cur = atomic_inc_return(&log->cur); if (cur >= ARRAY_SIZE(log->entry))
log->full = 1;
log->full = true;
While nice and pretty, this does not actually fix a bug, so it's not needed for stable trees.
thanks,
greg k-h
From: Prasad Sodagudi psodagud@codeaurora.org
[ Upstream commit 82d8ba717ccb54dd803624db044f351b2a54d000 ]
Remove the __init annotation from free_raw_capacity() to avoid the following warning.
The function init_cpu_capacity_callback() references the function __init free_raw_capacity(). WARNING: vmlinux.o(.text+0x425cc0): Section mismatch in reference from the function init_cpu_capacity_callback() to the function .init.text:free_raw_capacity().
Signed-off-by: Prasad Sodagudi psodagud@codeaurora.org Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/base/arch_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 41be9ff7d70a9..3da53cc6cf2be 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -96,7 +96,7 @@ subsys_initcall(register_cpu_capacity_sysctl); static u32 capacity_scale; static u32 *raw_capacity;
-static int __init free_raw_capacity(void) +static int free_raw_capacity(void) { kfree(raw_capacity); raw_capacity = NULL;
From: Hamad Kadmany hkadmany@codeaurora.org
[ Upstream commit 6ccae584014ef7074359eb4151086beef66ecfa9 ]
Firmware ready event may take longer than current timeout in some scenarios, for example with multiple RFs connected where each requires an initial calibration.
Increase the timeout to support these scenarios.
Signed-off-by: Hamad Kadmany hkadmany@codeaurora.org Signed-off-by: Maya Erez merez@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index bac829aa950d5..a3dc42841526f 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -871,7 +871,7 @@ static void wil_bl_crash_info(struct wil6210_priv *wil, bool is_err)
static int wil_wait_for_fw_ready(struct wil6210_priv *wil) { - ulong to = msecs_to_jiffies(1000); + ulong to = msecs_to_jiffies(2000); ulong left = wait_for_completion_timeout(&wil->wmi_ready, to);
if (0 == left) {
From: Dedy Lansky dlansky@codeaurora.org
[ Upstream commit 6d9eb7ebae3d7e951bc0999235ae7028eb4cae4f ]
For negative temperatures, "temp" debugfs is showing wrong values. Use signed types so proper calculations is done for sub zero temperatures.
Signed-off-by: Dedy Lansky dlansky@codeaurora.org Signed-off-by: Maya Erez merez@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/debugfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 6db00c167d2e1..3a98f75c5d7e5 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1093,7 +1093,7 @@ static const struct file_operations fops_ssid = { };
/*---------temp------------*/ -static void print_temp(struct seq_file *s, const char *prefix, u32 t) +static void print_temp(struct seq_file *s, const char *prefix, s32 t) { switch (t) { case 0: @@ -1101,7 +1101,8 @@ static void print_temp(struct seq_file *s, const char *prefix, u32 t) seq_printf(s, "%s N/A\n", prefix); break; default: - seq_printf(s, "%s %d.%03d\n", prefix, t / 1000, t % 1000); + seq_printf(s, "%s %s%d.%03d\n", prefix, (t < 0 ? "-" : ""), + abs(t / 1000), abs(t % 1000)); break; } } @@ -1109,7 +1110,7 @@ static void print_temp(struct seq_file *s, const char *prefix, u32 t) static int wil_temp_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; - u32 t_m, t_r; + s32 t_m, t_r; int rc = wmi_get_temperature(wil, &t_m, &t_r);
if (rc) {
From: Venkat Gopalakrishnan venkatg@codeaurora.org
[ Upstream commit 7f6ba4f12e6cbfdefbb95cfd8fc67ece6c15d799 ]
As multiple requests are submitted to the ufs host controller in parallel there could be instances where the command completion interrupt arrives later for a request that is already processed earlier as the corresponding doorbell was cleared when handling the previous interrupt. Read the interrupt status in a loop after processing the received interrupt to catch such interrupts and handle it.
Signed-off-by: Venkat Gopalakrishnan venkatg@codeaurora.org Signed-off-by: Asutosh Das asutoshd@codeaurora.org Reviewed-by: Subhash Jadavani subhashj@codeaurora.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/scsi/ufs/ufshcd.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c350453246952..f4f2c4f22b5f5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5366,19 +5366,30 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) u32 intr_status, enabled_intr_status; irqreturn_t retval = IRQ_NONE; struct ufs_hba *hba = __hba; + int retries = hba->nutrs;
spin_lock(hba->host->host_lock); intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); - enabled_intr_status = - intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
- if (intr_status) - ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); + /* + * There could be max of hba->nutrs reqs in flight and in worst case + * if the reqs get finished 1 by 1 after the interrupt status is + * read, make sure we handle them by checking the interrupt status + * again in a loop until we process all of the reqs before returning. + */ + do { + enabled_intr_status = + intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + if (intr_status) + ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); + if (enabled_intr_status) { + ufshcd_sl_intr(hba, enabled_intr_status); + retval = IRQ_HANDLED; + } + + intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); + } while (intr_status && --retries);
- if (enabled_intr_status) { - ufshcd_sl_intr(hba, enabled_intr_status); - retval = IRQ_HANDLED; - } spin_unlock(hba->host->host_lock); return retval; }
From: Subhash Jadavani subhashj@codeaurora.org
[ Upstream commit 69a6fff068567469c0ef1156ae5ac8d3d71701f0 ]
UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION is only applicable for QCOM UFS host controller version 2.x.y and this has been fixed from version 3.x.y onwards, hence this change removes this quirk for version 3.x.y onwards.
[mkp: applied by hand]
Signed-off-by: Subhash Jadavani subhashj@codeaurora.org Signed-off-by: Asutosh Das asutoshd@codeaurora.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/scsi/ufs/ufs-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index c87d770b519a7..f2b8de195d8af 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1094,7 +1094,7 @@ static void ufs_qcom_advertise_quirks(struct ufs_hba *hba) hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC; }
- if (host->hw_ver.major >= 0x2) { + if (host->hw_ver.major == 0x2) { hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
if (!ufs_qcom_cap_qunipro(host))
From: Dedy Lansky dlansky@codeaurora.org
[ Upstream commit 3d6b72729cc2933906de8d2c602ae05e920b2122 ]
wil_err inside wil_rx_refill can flood the log buffer. Replace it with wil_err_ratelimited.
Signed-off-by: Dedy Lansky dlansky@codeaurora.org Signed-off-by: Maya Erez merez@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/txrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 16750056b8b52..b483c42660971 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -636,8 +636,8 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count) v->swtail = next_tail) { rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom); if (unlikely(rc)) { - wil_err(wil, "Error %d in wil_rx_refill[%d]\n", - rc, v->swtail); + wil_err_ratelimited(wil, "Error %d in rx refill[%d]\n", + rc, v->swtail); break; } }
From: Arvind Yadav arvind.yadav.cs@gmail.com
[ Upstream commit a9011726c4bb37e5d6a7279bf47fcc19cd9d3e1a ]
if device_register() returned an error! Always use put_device() to give up the reference initialized. And unregister device for other return error.
Signed-off-by: Arvind Yadav arvind.yadav.cs@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/rpmsg/qcom_glink_smem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 2b54e71886d9c..69a14041ef1fe 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -212,6 +212,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, ret = device_register(dev); if (ret) { pr_err("failed to register glink edge\n"); + put_device(dev); return ERR_PTR(ret); }
@@ -294,7 +295,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, return glink;
err_put_dev: - put_device(dev); + device_unregister(dev);
return ERR_PTR(ret); }
From: Mohit Aggarwal maggarwa@codeaurora.org
[ Upstream commit 83220bf38b77a830f8e62ab1a0d0408304f9b966 ]
In order to set time in rtc, need to disable rtc hw before writing into rtc registers.
Also fixes disabling of alarm while setting rtc time.
Signed-off-by: Mohit Aggarwal maggarwa@codeaurora.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/rtc/rtc-pm8xxx.c | 49 +++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 11 deletions(-)
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index a1b4b0ed1f196..3b619b7b2c530 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -74,16 +74,18 @@ struct pm8xxx_rtc { /* * Steps to write the RTC registers. * 1. Disable alarm if enabled. - * 2. Write 0x00 to LSB. - * 3. Write Byte[1], Byte[2], Byte[3] then Byte[0]. - * 4. Enable alarm if disabled in step 1. + * 2. Disable rtc if enabled. + * 3. Write 0x00 to LSB. + * 4. Write Byte[1], Byte[2], Byte[3] then Byte[0]. + * 5. Enable rtc if disabled in step 2. + * 6. Enable alarm if disabled in step 1. */ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) { int rc, i; unsigned long secs, irq_flags; - u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0; - unsigned int ctrl_reg; + u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, rtc_disabled = 0; + unsigned int ctrl_reg, rtc_ctrl_reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
@@ -92,23 +94,38 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_tm_to_time(tm, &secs);
+ dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); + for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { value[i] = secs & 0xFF; secs >>= 8; }
- dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); - spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
- rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg); + rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); if (rc) goto rtc_rw_fail;
if (ctrl_reg & regs->alarm_en) { alarm_enabled = 1; ctrl_reg &= ~regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); + if (rc) { + dev_err(dev, "Write to RTC Alarm control register failed\n"); + goto rtc_rw_fail; + } + } + + /* Disable RTC H/w before writing on RTC register */ + rc = regmap_read(rtc_dd->regmap, regs->ctrl, &rtc_ctrl_reg); + if (rc) + goto rtc_rw_fail; + + if (rtc_ctrl_reg & PM8xxx_RTC_ENABLE) { + rtc_disabled = 1; + rtc_ctrl_reg &= ~PM8xxx_RTC_ENABLE; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg); if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; @@ -137,11 +154,21 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) goto rtc_rw_fail; }
+ /* Enable RTC H/w after writing on RTC register */ + if (rtc_disabled) { + rtc_ctrl_reg |= PM8xxx_RTC_ENABLE; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg); + if (rc) { + dev_err(dev, "Write to RTC control register failed\n"); + goto rtc_rw_fail; + } + } + if (alarm_enabled) { ctrl_reg |= regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); if (rc) { - dev_err(dev, "Write to RTC control register failed\n"); + dev_err(dev, "Write to RTC Alarm control register failed\n"); goto rtc_rw_fail; } }
From: Subash Abhinov Kasiviswanathan subashab@codeaurora.org
[ Upstream commit 6e010dd9b16b1a320bbf8312359ac294d7e1d9a8 ]
Fix warnings which were reported when running with sparse (make C=1 CF=-D__CHECK_ENDIAN__)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c:81:15: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:271:37: warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [usertype] pkt_len got restricted __be16 [usertype] <noident> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:287:29: warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [usertype] pkt_len got restricted __be16 [usertype] <noident> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:310:22: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:319:13: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c:49:18: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c:50:18: warning: cast to restricted __be32 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c:74:21: warning: cast to restricted __be16
Signed-off-by: Subash Abhinov Kasiviswanathan subashab@codeaurora.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index ce2302c25b128..41fa881e4540e 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -23,8 +23,8 @@ struct rmnet_map_control_command { struct { u16 ip_family:2; u16 reserved:14; - u16 flow_control_seq_num; - u32 qos_id; + __be16 flow_control_seq_num; + __be32 qos_id; } flow_control; u8 data[0]; }; @@ -53,7 +53,7 @@ struct rmnet_map_header { u8 reserved_bit:1; u8 cd_bit:1; u8 mux_id; - u16 pkt_len; + __be16 pkt_len; } __aligned(1);
#define RMNET_MAP_GET_MUX_ID(Y) (((struct rmnet_map_header *) \
On Tue, Apr 21, 2020 at 01:40:08PM +0100, Lee Jones wrote:
From: Subash Abhinov Kasiviswanathan subashab@codeaurora.org
[ Upstream commit 6e010dd9b16b1a320bbf8312359ac294d7e1d9a8 ]
Fix warnings which were reported when running with sparse (make C=1 CF=-D__CHECK_ENDIAN__)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c:81:15: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:271:37: warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [usertype] pkt_len got restricted __be16 [usertype] <noident> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:287:29: warning: incorrect type in assignment (different base types) expected unsigned short [unsigned] [usertype] pkt_len got restricted __be16 [usertype] <noident> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:310:22: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:319:13: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c:49:18: warning: cast to restricted __be16 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c:50:18: warning: cast to restricted __be32 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c:74:21: warning: cast to restricted __be16
Signed-off-by: Subash Abhinov Kasiviswanathan subashab@codeaurora.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Lee Jones lee.jones@linaro.org
drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h index ce2302c25b128..41fa881e4540e 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h @@ -23,8 +23,8 @@ struct rmnet_map_control_command { struct { u16 ip_family:2; u16 reserved:14;
u16 flow_control_seq_num;
u32 qos_id;
__be16 flow_control_seq_num;
} flow_control; u8 data[0]; };__be32 qos_id;
@@ -53,7 +53,7 @@ struct rmnet_map_header { u8 reserved_bit:1; u8 cd_bit:1; u8 mux_id;
- u16 pkt_len;
- __be16 pkt_len;
Again, a nice patch, but doesn't actually fix a bug, so not needed for stable.
thanks,
greg k-h
From: Wei Yongjun weiyongjun1@huawei.com
[ Upstream commit fb416f69900773d5a6030c909114099f92d07ab9 ]
qcom_glink_alloc_channel() allocates the mutex but not initialize it. Use mutex_init() on it to initialize it correctly.
This is detected by Coccinelle semantic patch.
Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/rpmsg/qcom_glink_native.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 114481c9fba12..7802663efe332 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -221,6 +221,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink, /* Setup glink internal glink_channel data */ spin_lock_init(&channel->recv_lock); spin_lock_init(&channel->intent_lock); + mutex_init(&channel->intent_req_lock);
channel->glink = glink; channel->name = kstrdup(name, GFP_KERNEL);
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit 9d32497361ff89d2fc8306407de6f04b2bfb2836 ]
Ensure the ordering of the fifo write and the update of the write index, so that the index is not updated before the data has landed in the fifo.
Acked-By: Chris Lew clew@codeaurora.org Reported-by: Arun Kumar Neelakantam aneela@codeaurora.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/rpmsg/qcom_glink_smem.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 69a14041ef1fe..ed616b0bc563d 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -181,6 +181,9 @@ static void glink_smem_tx_write(struct qcom_glink_pipe *glink_pipe, if (head >= pipe->native.length) head -= pipe->native.length;
+ /* Ensure ordering of fifo and head update */ + wmb(); + *pipe->head = cpu_to_le32(head); }
From: Lazar Alexei qca_ailizaro@qca.qualcomm.com
[ Upstream commit 680c242dc25e036265793edc7d755cfc15afd231 ]
In case of interface down, radio is turned off but PCIe mastering is not cleared. This can cause unexpected PCIe access to the shutdown device. Fix this by clearing PCIe mastering also in case interface is down
Signed-off-by: Lazar Alexei qca_ailizaro@qca.qualcomm.com Signed-off-by: Maya Erez qca_merez@qca.qualcomm.com Signed-off-by: Kalle Valo kvalo@qca.qualcomm.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/pcie_bus.c | 24 +++++++++++++-------- drivers/net/wireless/ath/wil6210/pm.c | 10 ++------- drivers/net/wireless/ath/wil6210/wil6210.h | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 6a3ab4bf916dd..b2c3cf6db8814 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -393,6 +393,9 @@ static int wil6210_suspend(struct device *dev, bool is_runtime) int rc = 0; struct pci_dev *pdev = to_pci_dev(dev); struct wil6210_priv *wil = pci_get_drvdata(pdev); + struct net_device *ndev = wil_to_ndev(wil); + bool keep_radio_on = ndev->flags & IFF_UP && + wil->keep_radio_on_during_sleep;
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
@@ -400,14 +403,14 @@ static int wil6210_suspend(struct device *dev, bool is_runtime) if (rc) goto out;
- rc = wil_suspend(wil, is_runtime); + rc = wil_suspend(wil, is_runtime, keep_radio_on); if (!rc) { wil->suspend_stats.successful_suspends++;
- /* If platform device supports keep_radio_on_during_sleep - * it will control PCIe master + /* In case radio stays on, platform device will control + * PCIe master */ - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) /* disable bus mastering */ pci_clear_master(pdev); } @@ -420,20 +423,23 @@ static int wil6210_resume(struct device *dev, bool is_runtime) int rc = 0; struct pci_dev *pdev = to_pci_dev(dev); struct wil6210_priv *wil = pci_get_drvdata(pdev); + struct net_device *ndev = wil_to_ndev(wil); + bool keep_radio_on = ndev->flags & IFF_UP && + wil->keep_radio_on_during_sleep;
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
- /* If platform device supports keep_radio_on_during_sleep it will - * control PCIe master + /* In case radio stays on, platform device will control + * PCIe master */ - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) /* allow master */ pci_set_master(pdev); - rc = wil_resume(wil, is_runtime); + rc = wil_resume(wil, is_runtime, keep_radio_on); if (rc) { wil_err(wil, "device failed to resume (%d)\n", rc); wil->suspend_stats.failed_resumes++; - if (!wil->keep_radio_on_during_sleep) + if (!keep_radio_on) pci_clear_master(pdev); } else { wil->suspend_stats.successful_resumes++; diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c index 8f5d1b447aaa2..8378742ecd49d 100644 --- a/drivers/net/wireless/ath/wil6210/pm.c +++ b/drivers/net/wireless/ath/wil6210/pm.c @@ -279,12 +279,9 @@ static int wil_resume_radio_off(struct wil6210_priv *wil) return rc; }
-int wil_suspend(struct wil6210_priv *wil, bool is_runtime) +int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on) { int rc = 0; - struct net_device *ndev = wil_to_ndev(wil); - bool keep_radio_on = ndev->flags & IFF_UP && - wil->keep_radio_on_during_sleep;
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
@@ -307,12 +304,9 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime) return rc; }
-int wil_resume(struct wil6210_priv *wil, bool is_runtime) +int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on) { int rc = 0; - struct net_device *ndev = wil_to_ndev(wil); - bool keep_radio_on = ndev->flags & IFF_UP && - wil->keep_radio_on_during_sleep; unsigned long long suspend_time_usec = 0;
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 315ec8b596628..c5b6b783100aa 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1000,8 +1000,8 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name, bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name);
int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime); -int wil_suspend(struct wil6210_priv *wil, bool is_runtime); -int wil_resume(struct wil6210_priv *wil, bool is_runtime); +int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on); +int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on); bool wil_is_wmi_idle(struct wil6210_priv *wil); int wmi_resume(struct wil6210_priv *wil); int wmi_suspend(struct wil6210_priv *wil);
From: Lior David qca_liord@qca.qualcomm.com
[ Upstream commit 705d2fde94b23cd76efbeedde643ffa7c32fac7f ]
When loading FW from file add block size checks to ensure a corrupted FW file will not cause the driver to write outside the device memory.
Signed-off-by: Lior David qca_liord@qca.qualcomm.com Signed-off-by: Maya Erez qca_merez@qca.qualcomm.com Signed-off-by: Kalle Valo kvalo@qca.qualcomm.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/fw_inc.c | 58 ++++++++++++++-------- drivers/net/wireless/ath/wil6210/wil6210.h | 1 + drivers/net/wireless/ath/wil6210/wmi.c | 11 +++- 3 files changed, 49 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c index e01acac88825d..7d090150187c8 100644 --- a/drivers/net/wireless/ath/wil6210/fw_inc.c +++ b/drivers/net/wireless/ath/wil6210/fw_inc.c @@ -26,14 +26,17 @@ prefix_type, rowsize, \ groupsize, buf, len, ascii)
-#define FW_ADDR_CHECK(ioaddr, val, msg) do { \ - ioaddr = wmi_buffer(wil, val); \ - if (!ioaddr) { \ - wil_err_fw(wil, "bad " msg ": 0x%08x\n", \ - le32_to_cpu(val)); \ - return -EINVAL; \ - } \ - } while (0) +static bool wil_fw_addr_check(struct wil6210_priv *wil, + void __iomem **ioaddr, __le32 val, + u32 size, const char *msg) +{ + *ioaddr = wmi_buffer_block(wil, val, size); + if (!(*ioaddr)) { + wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val)); + return false; + } + return true; +}
/** * wil_fw_verify - verify firmware file validity @@ -165,7 +168,8 @@ static int fw_handle_data(struct wil6210_priv *wil, const void *data, return -EINVAL; }
- FW_ADDR_CHECK(dst, d->addr, "address"); + if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) + return -EINVAL; wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr), s); wil_memcpy_toio_32(dst, d->data, s); @@ -197,7 +201,8 @@ static int fw_handle_fill(struct wil6210_priv *wil, const void *data, return -EINVAL; }
- FW_ADDR_CHECK(dst, d->addr, "address"); + if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address")) + return -EINVAL;
v = le32_to_cpu(d->value); wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", @@ -253,7 +258,8 @@ static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data, u32 v = le32_to_cpu(block[i].value); u32 x, y;
- FW_ADDR_CHECK(dst, block[i].addr, "address"); + if (!wil_fw_addr_check(wil, &dst, block[i].addr, 0, "address")) + return -EINVAL;
x = readl(dst); y = (x & m) | (v & ~m); @@ -319,10 +325,15 @@ static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd);
- FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); - FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr"); - FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); - FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); + if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, + "gateway_addr_addr") || + !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0, + "gateway_value_addr") || + !wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, + "gateway_cmd_addr") || + !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, + "gateway_ctrl_address")) + return -EINVAL;
wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" " cmd 0x%08x ctl 0x%08x\n", @@ -378,12 +389,19 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data, wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", n, gw_cmd);
- FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); + if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0, + "gateway_addr_addr")) + return -EINVAL; for (k = 0; k < ARRAY_SIZE(block->value); k++) - FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k], - "gateway_value_addr"); - FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); - FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); + if (!wil_fw_addr_check(wil, &gwa_val[k], + d->gateway_value_addr[k], + 0, "gateway_value_addr")) + return -EINVAL; + if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0, + "gateway_cmd_addr") || + !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0, + "gateway_ctrl_address")) + return -EINVAL;
wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", le32_to_cpu(d->gateway_addr_addr), diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index c5b6b783100aa..0bfd51adcc81f 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -865,6 +865,7 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); void wil_set_ethtoolops(struct net_device *ndev);
+void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr, u32 size); void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 798516f42f2f9..6cfb820caa3ee 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -140,13 +140,15 @@ static u32 wmi_addr_remap(u32 x) /** * Check address validity for WMI buffer; remap if needed * @ptr - internal (linker) fw/ucode address + * @size - if non zero, validate the block does not + * exceed the device memory (bar) * * Valid buffer should be DWORD aligned * * return address for accessing buffer from the host; * if buffer is not valid, return NULL. */ -void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) +void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size) { u32 off; u32 ptr = le32_to_cpu(ptr_); @@ -161,10 +163,17 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) off = HOSTADDR(ptr); if (off > wil->bar_size - 4) return NULL; + if (size && ((off + size > wil->bar_size) || (off + size < off))) + return NULL;
return wil->csr + off; }
+void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_) +{ + return wmi_buffer_block(wil, ptr_, 0); +} + /** * Check address validity */
From: Lior David qca_liord@qca.qualcomm.com
[ Upstream commit 26a6d5274865532502c682ff378ac8ebe2886238 ]
The current length check: sizeof(cmd) + len > r->entry_size will allow very large values of len (> U16_MAX - sizeof(cmd)) and can cause a buffer overflow. Fix the check to cover this case. In addition, ensure the mailbox entry_size is not too small, since this can also bypass the above check.
Signed-off-by: Lior David qca_liord@qca.qualcomm.com Signed-off-by: Maya Erez qca_merez@qca.qualcomm.com Signed-off-by: Kalle Valo kvalo@qca.qualcomm.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/interrupt.c | 22 +++++++++++++++++++- drivers/net/wireless/ath/wil6210/wmi.c | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 59def4f3fcf3d..5cf341702dc11 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c @@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil) wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); }
+static bool wil_validate_mbox_regs(struct wil6210_priv *wil) +{ + size_t min_size = sizeof(struct wil6210_mbox_hdr) + + sizeof(struct wmi_cmd_hdr); + + if (wil->mbox_ctl.rx.entry_size < min_size) { + wil_err(wil, "rx mbox entry too small (%d)\n", + wil->mbox_ctl.rx.entry_size); + return false; + } + if (wil->mbox_ctl.tx.entry_size < min_size) { + wil_err(wil, "tx mbox entry too small (%d)\n", + wil->mbox_ctl.tx.entry_size); + return false; + } + + return true; +} + static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; @@ -393,7 +412,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (isr & ISR_MISC_FW_READY) { wil_dbg_irq(wil, "IRQ: FW ready\n"); wil_cache_mbox_regs(wil); - set_bit(wil_status_mbox_ready, wil->status); + if (wil_validate_mbox_regs(wil)) + set_bit(wil_status_mbox_ready, wil->status); /** * Actual FW ready indicated by the * WMI_FW_READY_EVENTID diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 6cfb820caa3ee..22bfa10ea8276 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -231,7 +231,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) uint retry; int rc = 0;
- if (sizeof(cmd) + len > r->entry_size) { + if (len > r->entry_size - sizeof(cmd)) { wil_err(wil, "WMI size too large: %d bytes, max is %d\n", (int)(sizeof(cmd) + len), r->entry_size); return -ERANGE;
From: Hamad Kadmany qca_hkadmany@qca.qualcomm.com
[ Upstream commit 144a12a6d83f3ca34ddefce5dee4d502afd2fc5b ]
On-going operations were not aborted properly and required locks were not taken.
Signed-off-by: Hamad Kadmany qca_hkadmany@qca.qualcomm.com Signed-off-by: Maya Erez qca_merez@qca.qualcomm.com Signed-off-by: Kalle Valo kvalo@qca.qualcomm.com Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/net/wireless/ath/wil6210/cfg80211.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index c374ed311520e..58784e77e215b 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -1735,9 +1735,12 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy,
wil_dbg_pm(wil, "suspending\n");
- wil_p2p_stop_discovery(wil); - + mutex_lock(&wil->mutex); + mutex_lock(&wil->p2p_wdev_mutex); + wil_p2p_stop_radio_operations(wil); wil_abort_scan(wil, true); + mutex_unlock(&wil->p2p_wdev_mutex); + mutex_unlock(&wil->mutex);
out: return rc;
From: Chris Lew clew@codeaurora.org
[ Upstream commit a216000f0140f415cec96129f777b5234c9d142f ]
Endianness can vary in the system, add le32_to_cpu when comparing partition sizes from smem.
Signed-off-by: Chris Lew clew@codeaurora.org Acked-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Andy Gross andy.gross@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/soc/qcom/smem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 18ec52f2078aa..89dd50fa404f7 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -646,7 +646,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, return -EINVAL; }
- if (header->size != entry->size) { + if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) { dev_err(smem->dev, "Partition %d has invalid size\n", i); return -EINVAL;
From: Rob Herring robh@kernel.org
[ Upstream commit bd82bbf38cbe27f2c65660da801900d71bcc5cc8 ]
The ref counting is broken for OF_DYNAMIC when sysfs is disabled because the kobject initialization is skipped. Only the properties add/remove/update should be skipped for !SYSFS config.
Tested-by: Nicolas Pitre nico@linaro.org Reviewed-by: Frank Rowand frowand.list@gmail.com Acked-by: Grant Likely grant.likely@secretlab.ca Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org --- drivers/of/base.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c index 41b254be02954..c0281be8e0611 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -169,9 +169,6 @@ int __of_attach_node_sysfs(struct device_node *np) struct property *pp; int rc;
- if (!IS_ENABLED(CONFIG_SYSFS)) - return 0; - if (!of_kset) return 0;
From: Austin Kim austindh.kim@gmail.com
[ Upstream commit 7ea362427c170061b8822dd41bafaa72b3bcb9ad ]
If !area->pages statement is true where memory allocation fails, area is freed.
In this case 'area->pages = pages' should not executed. So move 'area->pages = pages' after if statement.
[akpm@linux-foundation.org: give area->pages the same treatment] Link: http://lkml.kernel.org/r/20190830035716.GA190684@LGEARND20B15 Signed-off-by: Austin Kim austindh.kim@gmail.com Acked-by: Michal Hocko mhocko@suse.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Uladzislau Rezki (Sony) urezki@gmail.com Cc: Roman Gushchin guro@fb.com Cc: Roman Penyaev rpenyaev@suse.de Cc: Rick Edgecombe rick.p.edgecombe@intel.com Cc: Mike Rapoport rppt@linux.ibm.com Cc: Andrey Ryabinin aryabinin@virtuozzo.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Lee Jones lee.jones@linaro.org --- mm/vmalloc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index d00961ba0c42d..88091fd704f42 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1682,7 +1682,6 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, nr_pages = get_vm_area_size(area) >> PAGE_SHIFT; array_size = (nr_pages * sizeof(struct page *));
- area->nr_pages = nr_pages; /* Please note that the recursion is strictly bounded. */ if (array_size > PAGE_SIZE) { pages = __vmalloc_node(array_size, 1, nested_gfp|highmem_mask, @@ -1690,13 +1689,16 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, } else { pages = kmalloc_node(array_size, nested_gfp, node); } - area->pages = pages; - if (!area->pages) { + + if (!pages) { remove_vm_area(area->addr); kfree(area); return NULL; }
+ area->pages = pages; + area->nr_pages = nr_pages; + for (i = 0; i < area->nr_pages; i++) { struct page *page;
On Tue, Apr 21, 2020 at 01:39:53PM +0100, Lee Jones wrote:
A recent review of the Sony Xperia Development kernel tree [0] resulted in the discovery of various patches which have been backported from Mainline in order to fix an array of issues. These patches should be applied to Stable such that everyone can benefit from them.
Note: The review is still on-going (~50%) - more to follow.
Thanks for these, most queued up here, and in some older kernel trees as well.
greg k-h
linux-stable-mirror@lists.linaro.org