From a5e42516a61ead33e5b98c6508547e1cbef0f8ac Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 30 Jun 2021 17:35:18 +0200 Subject: [PATCH 001/150] locking/mutex: Fix HANDOFF condition [ Upstream commit 048661a1f963e9517630f080687d48af79ed784c ] Yanfei reported that setting HANDOFF should not depend on recomputing @first, only on @first state. Which would then give: if (ww_ctx || !first) first = __mutex_waiter_is_first(lock, &waiter); if (first) __mutex_set_flag(lock, MUTEX_FLAG_HANDOFF); But because 'ww_ctx || !first' is basically 'always' and the test for first is relatively cheap, omit that first branch entirely. Reported-by: Yanfei Xu Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Waiman Long Reviewed-by: Yanfei Xu Link: https://lore.kernel.org/r/20210630154114.896786297@infradead.org Signed-off-by: Sasha Levin --- kernel/locking/mutex.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index c0c7784f074b..b02fff28221f 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -938,7 +938,6 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) { struct mutex_waiter waiter; - bool first = false; struct ww_mutex *ww; int ret; @@ -1017,6 +1016,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, set_current_state(state); for (;;) { + bool first; + /* * Once we hold wait_lock, we're serialized against * mutex_unlock() handing the lock off to us, do a trylock @@ -1045,15 +1046,9 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, spin_unlock(&lock->wait_lock); schedule_preempt_disabled(); - /* - * ww_mutex needs to always recheck its position since its waiter - * list is not FIFO ordered. - */ - if (ww_ctx || !first) { - first = __mutex_waiter_is_first(lock, &waiter); - if (first) - __mutex_set_flag(lock, MUTEX_FLAG_HANDOFF); - } + first = __mutex_waiter_is_first(lock, &waiter); + if (first) + __mutex_set_flag(lock, MUTEX_FLAG_HANDOFF); set_current_state(state); /* From 344a38789ab26f795a1de23593b22548df56e87e Mon Sep 17 00:00:00 2001 From: Jeongtae Park Date: Thu, 1 Jul 2021 23:26:30 +0900 Subject: [PATCH 002/150] regmap: fix the offset of register error log [ Upstream commit 1852f5ed358147095297a09cc3c6f160208a676d ] This patch fixes the offset of register error log by using regmap_get_offset(). Signed-off-by: Jeongtae Park Link: https://lore.kernel.org/r/20210701142630.44936-1-jeongtae.park@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e0893f1b1452..43c0452a8ba9 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1505,7 +1505,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, if (ret) { dev_err(map->dev, "Error in caching of register: %x ret: %d\n", - reg + i, ret); + reg + regmap_get_offset(map, i), ret); return ret; } } From 53a6ef40c6bcf13971e48fc6a340d26b971b96d8 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 1 Jul 2021 14:56:37 -0400 Subject: [PATCH 003/150] crypto: mxs-dcp - Check for DMA mapping errors [ Upstream commit df6313d707e575a679ada3313358289af24454c0 ] After calling dma_map_single(), we must also call dma_mapping_error(). This fixes the following warning when compiling with CONFIG_DMA_API_DEBUG: [ 311.241478] WARNING: CPU: 0 PID: 428 at kernel/dma/debug.c:1027 check_unmap+0x79c/0x96c [ 311.249547] DMA-API: mxs-dcp 2280000.crypto: device driver failed to check map error[device address=0x00000000860cb080] [size=32 bytes] [mapped as single] Signed-off-by: Sean Anderson Reviewed-by: Richard Weinberger Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/mxs-dcp.c | 45 +++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c index f8a48a84df2a..66fa524b6261 100644 --- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c @@ -168,15 +168,19 @@ static struct dcp *global_sdcp; static int mxs_dcp_start_dma(struct dcp_async_ctx *actx) { + int dma_err; struct dcp *sdcp = global_sdcp; const int chan = actx->chan; uint32_t stat; unsigned long ret; struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan]; - dma_addr_t desc_phys = dma_map_single(sdcp->dev, desc, sizeof(*desc), DMA_TO_DEVICE); + dma_err = dma_mapping_error(sdcp->dev, desc_phys); + if (dma_err) + return dma_err; + reinit_completion(&sdcp->completion[chan]); /* Clear status register. */ @@ -214,18 +218,29 @@ static int mxs_dcp_start_dma(struct dcp_async_ctx *actx) static int mxs_dcp_run_aes(struct dcp_async_ctx *actx, struct ablkcipher_request *req, int init) { + dma_addr_t key_phys, src_phys, dst_phys; struct dcp *sdcp = global_sdcp; struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan]; struct dcp_aes_req_ctx *rctx = ablkcipher_request_ctx(req); int ret; - dma_addr_t key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key, - 2 * AES_KEYSIZE_128, - DMA_TO_DEVICE); - dma_addr_t src_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_in_buf, - DCP_BUF_SZ, DMA_TO_DEVICE); - dma_addr_t dst_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_out_buf, - DCP_BUF_SZ, DMA_FROM_DEVICE); + key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key, + 2 * AES_KEYSIZE_128, DMA_TO_DEVICE); + ret = dma_mapping_error(sdcp->dev, key_phys); + if (ret) + return ret; + + src_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_in_buf, + DCP_BUF_SZ, DMA_TO_DEVICE); + ret = dma_mapping_error(sdcp->dev, src_phys); + if (ret) + goto err_src; + + dst_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_out_buf, + DCP_BUF_SZ, DMA_FROM_DEVICE); + ret = dma_mapping_error(sdcp->dev, dst_phys); + if (ret) + goto err_dst; if (actx->fill % AES_BLOCK_SIZE) { dev_err(sdcp->dev, "Invalid block size!\n"); @@ -263,10 +278,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx, ret = mxs_dcp_start_dma(actx); aes_done_run: + dma_unmap_single(sdcp->dev, dst_phys, DCP_BUF_SZ, DMA_FROM_DEVICE); +err_dst: + dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE); +err_src: dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128, DMA_TO_DEVICE); - dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE); - dma_unmap_single(sdcp->dev, dst_phys, DCP_BUF_SZ, DMA_FROM_DEVICE); return ret; } @@ -565,6 +582,10 @@ static int mxs_dcp_run_sha(struct ahash_request *req) dma_addr_t buf_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_in_buf, DCP_BUF_SZ, DMA_TO_DEVICE); + ret = dma_mapping_error(sdcp->dev, buf_phys); + if (ret) + return ret; + /* Fill in the DMA descriptor. */ desc->control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE | MXS_DCP_CONTROL0_INTERRUPT | @@ -597,6 +618,10 @@ static int mxs_dcp_run_sha(struct ahash_request *req) if (rctx->fini) { digest_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_out_buf, DCP_SHA_PAY_SZ, DMA_FROM_DEVICE); + ret = dma_mapping_error(sdcp->dev, digest_phys); + if (ret) + goto done_run; + desc->control0 |= MXS_DCP_CONTROL0_HASH_TERM; desc->payload = digest_phys; } From bba2b82d1b4815687d7e86b80e77dd235cdf3f9a Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Tue, 27 Jul 2021 11:11:01 +0100 Subject: [PATCH 004/150] sched/deadline: Fix reset_on_fork reporting of DL tasks [ Upstream commit f95091536f78971b269ec321b057b8d630b0ad8a ] It is possible for sched_getattr() to incorrectly report the state of the reset_on_fork flag when called on a deadline task. Indeed, if the flag was set on a deadline task using sched_setattr() with flags (SCHED_FLAG_RESET_ON_FORK | SCHED_FLAG_KEEP_PARAMS), then p->sched_reset_on_fork will be set, but __setscheduler() will bail out early, which means that the dl_se->flags will not get updated by __setscheduler_params()->__setparam_dl(). Consequently, if sched_getattr() is then called on the task, __getparam_dl() will override kattr.sched_flags with the now out-of-date copy in dl_se->flags and report the stale value to userspace. To fix this, make sure to only copy the flags that are relevant to sched_deadline to and from the dl_se->flags field. Signed-off-by: Quentin Perret Signed-off-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/20210727101103.2729607-2-qperret@google.com Signed-off-by: Sasha Levin --- kernel/sched/deadline.c | 7 ++++--- kernel/sched/sched.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 3cf776d5bce8..7ab0b80cb12d 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -2622,7 +2622,7 @@ void __setparam_dl(struct task_struct *p, const struct sched_attr *attr) dl_se->dl_runtime = attr->sched_runtime; dl_se->dl_deadline = attr->sched_deadline; dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline; - dl_se->flags = attr->sched_flags; + dl_se->flags = attr->sched_flags & SCHED_DL_FLAGS; dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime); dl_se->dl_density = to_ratio(dl_se->dl_deadline, dl_se->dl_runtime); } @@ -2635,7 +2635,8 @@ void __getparam_dl(struct task_struct *p, struct sched_attr *attr) attr->sched_runtime = dl_se->dl_runtime; attr->sched_deadline = dl_se->dl_deadline; attr->sched_period = dl_se->dl_period; - attr->sched_flags = dl_se->flags; + attr->sched_flags &= ~SCHED_DL_FLAGS; + attr->sched_flags |= dl_se->flags; } /* @@ -2710,7 +2711,7 @@ bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr) if (dl_se->dl_runtime != attr->sched_runtime || dl_se->dl_deadline != attr->sched_deadline || dl_se->dl_period != attr->sched_period || - dl_se->flags != attr->sched_flags) + dl_se->flags != (attr->sched_flags & SCHED_DL_FLAGS)) return true; return false; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 4e490e3db2f8..fe755c1a0af9 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -209,6 +209,8 @@ static inline int task_has_dl_policy(struct task_struct *p) */ #define SCHED_FLAG_SUGOV 0x10000000 +#define SCHED_DL_FLAGS (SCHED_FLAG_RECLAIM | SCHED_FLAG_DL_OVERRUN | SCHED_FLAG_SUGOV) + static inline bool dl_entity_is_special(struct sched_dl_entity *dl_se) { #ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL From ebf0f71ae3bdadcd1186167b236681822579e0d2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 1 Aug 2021 15:30:59 +0200 Subject: [PATCH 005/150] power: supply: axp288_fuel_gauge: Report register-address on readb / writeb errors [ Upstream commit caa534c3ba40c6e8352b42cbbbca9ba481814ac8 ] When fuel_gauge_reg_readb()/_writeb() fails, report which register we were trying to read / write when the error happened. Also reword the message a bit: - Drop the axp288 prefix, dev_err() already prints this - Switch from telegram / abbreviated style to a normal sentence, aligning the message with those from fuel_gauge_read_*bit_word() Signed-off-by: Hans de Goede Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/axp288_fuel_gauge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index f40fa0e63b6e..993e4a4a34b3 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c @@ -149,7 +149,7 @@ static int fuel_gauge_reg_readb(struct axp288_fg_info *info, int reg) } if (ret < 0) { - dev_err(&info->pdev->dev, "axp288 reg read err:%d\n", ret); + dev_err(&info->pdev->dev, "Error reading reg 0x%02x err: %d\n", reg, ret); return ret; } @@ -163,7 +163,7 @@ static int fuel_gauge_reg_writeb(struct axp288_fg_info *info, int reg, u8 val) ret = regmap_write(info->regmap, reg, (unsigned int)val); if (ret < 0) - dev_err(&info->pdev->dev, "axp288 reg write err:%d\n", ret); + dev_err(&info->pdev->dev, "Error writing reg 0x%02x err: %d\n", reg, ret); return ret; } From 40db13e3efcec79553e36cfa97a9cc7adf04c6b6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 27 Jul 2021 13:23:34 +0300 Subject: [PATCH 006/150] crypto: omap-sham - clear dma flags only after omap_sham_update_dma_stop() [ Upstream commit fe28140b3393b0ba1eb95cc109f974a7e58b26fd ] We should not clear FLAGS_DMA_ACTIVE before omap_sham_update_dma_stop() is done calling dma_unmap_sg(). We already clear FLAGS_DMA_ACTIVE at the end of omap_sham_update_dma_stop(). The early clearing of FLAGS_DMA_ACTIVE is not causing issues as we do not need to defer anything based on FLAGS_DMA_ACTIVE currently. So this can be applied as clean-up. Cc: Lokesh Vutla Cc: Tero Kristo Signed-off-by: Tony Lindgren Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/omap-sham.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index f80db1eb2994..f8a146554b1f 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -1734,7 +1734,7 @@ static void omap_sham_done_task(unsigned long data) if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) goto finish; } else if (test_bit(FLAGS_DMA_READY, &dd->flags)) { - if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) { + if (test_bit(FLAGS_DMA_ACTIVE, &dd->flags)) { omap_sham_update_dma_stop(dd); if (dd->err) { err = dd->err; From b7c560ae51c606d9ed7c9753f11719ff71b652f4 Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Wed, 4 Aug 2021 15:59:25 +0200 Subject: [PATCH 007/150] sched/deadline: Fix missing clock update in migrate_task_rq_dl() [ Upstream commit b4da13aa28d4fd0071247b7b41c579ee8a86c81a ] A missing clock update is causing the following warning: rq->clock_update_flags < RQCF_ACT_SKIP WARNING: CPU: 112 PID: 2041 at kernel/sched/sched.h:1453 sub_running_bw.isra.0+0x190/0x1a0 ... CPU: 112 PID: 2041 Comm: sugov:112 Tainted: G W 5.14.0-rc1 #1 Hardware name: WIWYNN Mt.Jade Server System B81.030Z1.0007/Mt.Jade Motherboard, BIOS 1.6.20210526 (SCP: 1.06.20210526) 2021/05/26 ... Call trace: sub_running_bw.isra.0+0x190/0x1a0 migrate_task_rq_dl+0xf8/0x1e0 set_task_cpu+0xa8/0x1f0 try_to_wake_up+0x150/0x3d4 wake_up_q+0x64/0xc0 __up_write+0xd0/0x1c0 up_write+0x4c/0x2b0 cppc_set_perf+0x120/0x2d0 cppc_cpufreq_set_target+0xe0/0x1a4 [cppc_cpufreq] __cpufreq_driver_target+0x74/0x140 sugov_work+0x64/0x80 kthread_worker_fn+0xe0/0x230 kthread+0x138/0x140 ret_from_fork+0x10/0x18 The task causing this is the `cppc_fie` DL task introduced by commit 1eb5dde674f5 ("cpufreq: CPPC: Add support for frequency invariance"). With CONFIG_ACPI_CPPC_CPUFREQ_FIE=y and schedutil cpufreq governor on slow-switching system (like on this Ampere Altra WIWYNN Mt. Jade Arm Server): DL task `curr=sugov:112` lets `p=cppc_fie` migrate and since the latter is in `non_contending` state, migrate_task_rq_dl() calls sub_running_bw()->__sub_running_bw()->cpufreq_update_util()-> rq_clock()->assert_clock_updated() on p. Fix this by updating the clock for a non_contending task in migrate_task_rq_dl() before calling sub_running_bw(). Reported-by: Bruno Goncalves Signed-off-by: Dietmar Eggemann Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Daniel Bristot de Oliveira Acked-by: Juri Lelli Link: https://lore.kernel.org/r/20210804135925.3734605-1-dietmar.eggemann@arm.com Signed-off-by: Sasha Levin --- kernel/sched/deadline.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 7ab0b80cb12d..2bda9fdba31c 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1654,6 +1654,7 @@ static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused */ raw_spin_lock(&rq->lock); if (p->dl.dl_non_contending) { + update_rq_clock(rq); sub_running_bw(&p->dl, &rq->dl); p->dl.dl_non_contending = 0; /* From 28996dbb8a74e0ffc8715f3fd463efafa0947db1 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Sat, 22 May 2021 00:56:23 +0900 Subject: [PATCH 008/150] rcu/tree: Handle VM stoppage in stall detection [ Upstream commit ccfc9dd6914feaa9a81f10f9cce56eb0f7712264 ] The soft watchdog timer function checks if a virtual machine was suspended and hence what looks like a lockup in fact is a false positive. This is what kvm_check_and_clear_guest_paused() does: it tests guest PVCLOCK_GUEST_STOPPED (which is set by the host) and if it's set then we need to touch all watchdogs and bail out. Watchdog timer function runs from IRQ, so PVCLOCK_GUEST_STOPPED check works fine. There is, however, one more watchdog that runs from IRQ, so watchdog timer fn races with it, and that watchdog is not aware of PVCLOCK_GUEST_STOPPED - RCU stall detector. apic_timer_interrupt() smp_apic_timer_interrupt() hrtimer_interrupt() __hrtimer_run_queues() tick_sched_timer() tick_sched_handle() update_process_times() rcu_sched_clock_irq() This triggers RCU stalls on our devices during VM resume. If tick_sched_handle()->rcu_sched_clock_irq() runs on a VCPU before watchdog_timer_fn()->kvm_check_and_clear_guest_paused() then there is nothing on this VCPU that touches watchdogs and RCU reads stale gp stall timestamp and new jiffies value, which makes it think that RCU has stalled. Make RCU stall watchdog aware of PVCLOCK_GUEST_STOPPED and don't report RCU stalls when we resume the VM. Signed-off-by: Sergey Senozhatsky Signed-off-by: Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/tree_stall.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h index c0b8c458d8a6..b8c9744ad595 100644 --- a/kernel/rcu/tree_stall.h +++ b/kernel/rcu/tree_stall.h @@ -7,6 +7,8 @@ * Author: Paul E. McKenney */ +#include + ////////////////////////////////////////////////////////////////////////////// // // Controlling CPU stall warnings, including delay calculation. @@ -525,6 +527,14 @@ static void check_cpu_stall(struct rcu_data *rdp) (READ_ONCE(rnp->qsmask) & rdp->grpmask) && cmpxchg(&rcu_state.jiffies_stall, js, jn) == js) { + /* + * If a virtual machine is stopped by the host it can look to + * the watchdog like an RCU stall. Check to see if the host + * stopped the vm. + */ + if (kvm_check_and_clear_guest_paused()) + return; + /* We haven't checked in, so go dump stack. */ print_cpu_stall(); if (rcu_cpu_stall_ftrace_dump) @@ -534,6 +544,14 @@ static void check_cpu_stall(struct rcu_data *rdp) ULONG_CMP_GE(j, js + RCU_STALL_RAT_DELAY) && cmpxchg(&rcu_state.jiffies_stall, js, jn) == js) { + /* + * If a virtual machine is stopped by the host it can look to + * the watchdog like an RCU stall. Check to see if the host + * stopped the vm. + */ + if (kvm_check_and_clear_guest_paused()) + return; + /* They had a few time units to dump stack, so complain. */ print_other_cpu_stall(gs2); if (rcu_cpu_stall_ftrace_dump) From c322a963d522e9a4273e18c9d7bd6fd40a25160f Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 26 Jul 2021 14:55:10 +0200 Subject: [PATCH 009/150] posix-cpu-timers: Force next expiration recalc after itimer reset [ Upstream commit 406dd42bd1ba0c01babf9cde169bb319e52f6147 ] When an itimer deactivates a previously armed expiration, it simply doesn't do anything. As a result the process wide cputime counter keeps running and the tick dependency stays set until it reaches the old ghost expiration value. This can be reproduced with the following snippet: void trigger_process_counter(void) { struct itimerval n = {}; n.it_value.tv_sec = 100; setitimer(ITIMER_VIRTUAL, &n, NULL); n.it_value.tv_sec = 0; setitimer(ITIMER_VIRTUAL, &n, NULL); } Fix this with resetting the relevant base expiration. This is similar to disarming a timer. Signed-off-by: Frederic Weisbecker Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/20210726125513.271824-4-frederic@kernel.org Signed-off-by: Sasha Levin --- kernel/time/posix-cpu-timers.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index eacb0ca30193..30e061b210b7 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -1201,8 +1201,6 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clkid, } } - if (!*newval) - return; *newval += now; } From a8457878307fa3683bd836cf3249de41efc3fabf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 13 Jul 2021 15:39:46 +0200 Subject: [PATCH 010/150] hrtimer: Avoid double reprogramming in __hrtimer_start_range_ns() [ Upstream commit 627ef5ae2df8eeccb20d5af0e4cfa4df9e61ed28 ] If __hrtimer_start_range_ns() is invoked with an already armed hrtimer then the timer has to be canceled first and then added back. If the timer is the first expiring timer then on removal the clockevent device is reprogrammed to the next expiring timer to avoid that the pending expiry fires needlessly. If the new expiry time ends up to be the first expiry again then the clock event device has to reprogrammed again. Avoid this by checking whether the timer is the first to expire and in that case, keep the timer on the current CPU and delay the reprogramming up to the point where the timer has been enqueued again. Reported-by: Lorenzo Colitti Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210713135157.873137732@linutronix.de Signed-off-by: Sasha Levin --- kernel/time/hrtimer.c | 60 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 1f3e3a17f67e..39beb9aaa24b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -1031,12 +1031,13 @@ static void __remove_hrtimer(struct hrtimer *timer, * remove hrtimer, called with base lock held */ static inline int -remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart) +remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, + bool restart, bool keep_local) { u8 state = timer->state; if (state & HRTIMER_STATE_ENQUEUED) { - int reprogram; + bool reprogram; /* * Remove the timer and force reprogramming when high @@ -1049,8 +1050,16 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool rest debug_deactivate(timer); reprogram = base->cpu_base == this_cpu_ptr(&hrtimer_bases); + /* + * If the timer is not restarted then reprogramming is + * required if the timer is local. If it is local and about + * to be restarted, avoid programming it twice (on removal + * and a moment later when it's requeued). + */ if (!restart) state = HRTIMER_STATE_INACTIVE; + else + reprogram &= !keep_local; __remove_hrtimer(timer, base, state, reprogram); return 1; @@ -1104,9 +1113,31 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, struct hrtimer_clock_base *base) { struct hrtimer_clock_base *new_base; + bool force_local, first; - /* Remove an active timer from the queue: */ - remove_hrtimer(timer, base, true); + /* + * If the timer is on the local cpu base and is the first expiring + * timer then this might end up reprogramming the hardware twice + * (on removal and on enqueue). To avoid that by prevent the + * reprogram on removal, keep the timer local to the current CPU + * and enforce reprogramming after it is queued no matter whether + * it is the new first expiring timer again or not. + */ + force_local = base->cpu_base == this_cpu_ptr(&hrtimer_bases); + force_local &= base->cpu_base->next_timer == timer; + + /* + * Remove an active timer from the queue. In case it is not queued + * on the current CPU, make sure that remove_hrtimer() updates the + * remote data correctly. + * + * If it's on the current CPU and the first expiring timer, then + * skip reprogramming, keep the timer local and enforce + * reprogramming later if it was the first expiring timer. This + * avoids programming the underlying clock event twice (once at + * removal and once after enqueue). + */ + remove_hrtimer(timer, base, true, force_local); if (mode & HRTIMER_MODE_REL) tim = ktime_add_safe(tim, base->get_time()); @@ -1116,9 +1147,24 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, hrtimer_set_expires_range_ns(timer, tim, delta_ns); /* Switch the timer base, if necessary: */ - new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); + if (!force_local) { + new_base = switch_hrtimer_base(timer, base, + mode & HRTIMER_MODE_PINNED); + } else { + new_base = base; + } - return enqueue_hrtimer(timer, new_base, mode); + first = enqueue_hrtimer(timer, new_base, mode); + if (!force_local) + return first; + + /* + * Timer was forced to stay on the current CPU to avoid + * reprogramming on removal and enqueue. Force reprogram the + * hardware by evaluating the new first expiring timer. + */ + hrtimer_force_reprogram(new_base->cpu_base, 1); + return 0; } /** @@ -1184,7 +1230,7 @@ int hrtimer_try_to_cancel(struct hrtimer *timer) base = lock_hrtimer_base(timer, &flags); if (!hrtimer_callback_running(timer)) - ret = remove_hrtimer(timer, base, false); + ret = remove_hrtimer(timer, base, false, false); unlock_hrtimer_base(timer, &flags); From cc608af36e0007402ac326c84db8826fc9ebd08e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 13 Jul 2021 15:39:48 +0200 Subject: [PATCH 011/150] hrtimer: Ensure timerfd notification for HIGHRES=n [ Upstream commit 8c3b5e6ec0fee18bc2ce38d1dfe913413205f908 ] If high resolution timers are disabled the timerfd notification about a clock was set event is not happening for all cases which use clock_was_set_delayed() because that's a NOP for HIGHRES=n, which is wrong. Make clock_was_set_delayed() unconditially available to fix that. Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210713135158.196661266@linutronix.de Signed-off-by: Sasha Levin --- include/linux/hrtimer.h | 5 ----- kernel/time/hrtimer.c | 32 ++++++++++++++++---------------- kernel/time/tick-internal.h | 3 +++ 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 1f98b52118f0..48be92aded5e 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -317,16 +317,12 @@ struct clock_event_device; extern void hrtimer_interrupt(struct clock_event_device *dev); -extern void clock_was_set_delayed(void); - extern unsigned int hrtimer_resolution; #else #define hrtimer_resolution (unsigned int)LOW_RES_NSEC -static inline void clock_was_set_delayed(void) { } - #endif static inline ktime_t @@ -350,7 +346,6 @@ hrtimer_expires_remaining_adjusted(const struct hrtimer *timer) timer->base->get_time()); } -extern void clock_was_set(void); #ifdef CONFIG_TIMERFD extern void timerfd_clock_was_set(void); #else diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 39beb9aaa24b..e1e8d5dab0c5 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -759,22 +759,6 @@ static void hrtimer_switch_to_hres(void) retrigger_next_event(NULL); } -static void clock_was_set_work(struct work_struct *work) -{ - clock_was_set(); -} - -static DECLARE_WORK(hrtimer_work, clock_was_set_work); - -/* - * Called from timekeeping and resume code to reprogram the hrtimer - * interrupt device on all cpus. - */ -void clock_was_set_delayed(void) -{ - schedule_work(&hrtimer_work); -} - #else static inline int hrtimer_is_hres_enabled(void) { return 0; } @@ -892,6 +876,22 @@ void clock_was_set(void) timerfd_clock_was_set(); } +static void clock_was_set_work(struct work_struct *work) +{ + clock_was_set(); +} + +static DECLARE_WORK(hrtimer_work, clock_was_set_work); + +/* + * Called from timekeeping and resume code to reprogram the hrtimer + * interrupt device on all cpus and to notify timerfd. + */ +void clock_was_set_delayed(void) +{ + schedule_work(&hrtimer_work); +} + /* * During resume we might have to reprogram the high resolution timer * interrupt on all online CPUs. However, all other CPUs will be diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 7b2496136729..5294f5b1f955 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -165,3 +165,6 @@ DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases); extern u64 get_next_timer_interrupt(unsigned long basej, u64 basem); void timer_clear_idle(void); + +void clock_was_set(void); +void clock_was_set_delayed(void); From 86987cf0fbd279c7917e7c60af6d2ce2760d341c Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 3 May 2021 11:39:03 +0200 Subject: [PATCH 012/150] udf: Check LVID earlier [ Upstream commit 781d2a9a2fc7d0be53a072794dc03ef6de770f3d ] We were checking validity of LVID entries only when getting implementation use information from LVID in udf_sb_lvidiu(). However if the LVID is suitably corrupted, it can cause problems also to code such as udf_count_free() which doesn't use udf_sb_lvidiu(). So check validity of LVID already when loading it from the disk and just disable LVID altogether when it is not valid. Reported-by: syzbot+7fbfe5fed73ebb675748@syzkaller.appspotmail.com Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/super.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 8bb001c7927f..a1efcf0593cb 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -108,16 +108,10 @@ struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb) return NULL; lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data; partnum = le32_to_cpu(lvid->numOfPartitions); - if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) - - offsetof(struct logicalVolIntegrityDesc, impUse)) / - (2 * sizeof(uint32_t)) < partnum) { - udf_err(sb, "Logical volume integrity descriptor corrupted " - "(numOfPartitions = %u)!\n", partnum); - return NULL; - } /* The offset is to skip freeSpaceTable and sizeTable arrays */ offset = partnum * 2 * sizeof(uint32_t); - return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); + return (struct logicalVolIntegrityDescImpUse *) + (((uint8_t *)(lvid + 1)) + offset); } /* UDF filesystem type */ @@ -1548,6 +1542,7 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDesc *lvid; int indirections = 0; + u32 parts, impuselen; while (++indirections <= UDF_MAX_LVID_NESTING) { final_bh = NULL; @@ -1574,15 +1569,27 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data; if (lvid->nextIntegrityExt.extLength == 0) - return; + goto check; loc = leea_to_cpu(lvid->nextIntegrityExt); } udf_warn(sb, "Too many LVID indirections (max %u), ignoring.\n", UDF_MAX_LVID_NESTING); +out_err: brelse(sbi->s_lvid_bh); sbi->s_lvid_bh = NULL; + return; +check: + parts = le32_to_cpu(lvid->numOfPartitions); + impuselen = le32_to_cpu(lvid->lengthOfImpUse); + if (parts >= sb->s_blocksize || impuselen >= sb->s_blocksize || + sizeof(struct logicalVolIntegrityDesc) + impuselen + + 2 * parts * sizeof(u32) > sb->s_blocksize) { + udf_warn(sb, "Corrupted LVID (parts=%u, impuselen=%u), " + "ignoring.\n", parts, impuselen); + goto out_err; + } } /* From 0f5cd92e5eb53c08309285b9d923fa7602bc613d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 8 Aug 2021 18:24:36 +0200 Subject: [PATCH 013/150] udf: Fix iocharset=utf8 mount option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b645333443712d2613e4e863f81090d5dc509657 ] Currently iocharset=utf8 mount option is broken. To use UTF-8 as iocharset, it is required to use utf8 mount option. Fix iocharset=utf8 mount option to use be equivalent to the utf8 mount option. If UTF-8 as iocharset is used then s_nls_map is set to NULL. So simplify code around, remove UDF_FLAG_NLS_MAP and UDF_FLAG_UTF8 flags as to distinguish between UTF-8 and non-UTF-8 it is needed just to check if s_nls_map set to NULL or not. Link: https://lore.kernel.org/r/20210808162453.1653-4-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/super.c | 50 ++++++++++++++++++------------------------------ fs/udf/udf_sb.h | 2 -- fs/udf/unicode.c | 4 ++-- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index a1efcf0593cb..5663bae95700 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -343,10 +343,10 @@ static int udf_show_options(struct seq_file *seq, struct dentry *root) seq_printf(seq, ",lastblock=%u", sbi->s_last_block); if (sbi->s_anchor != 0) seq_printf(seq, ",anchor=%u", sbi->s_anchor); - if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) - seq_puts(seq, ",utf8"); - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map) + if (sbi->s_nls_map) seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset); + else + seq_puts(seq, ",iocharset=utf8"); return 0; } @@ -551,19 +551,24 @@ static int udf_parse_options(char *options, struct udf_options *uopt, /* Ignored (never implemented properly) */ break; case Opt_utf8: - uopt->flags |= (1 << UDF_FLAG_UTF8); + if (!remount) { + unload_nls(uopt->nls_map); + uopt->nls_map = NULL; + } break; case Opt_iocharset: if (!remount) { - if (uopt->nls_map) - unload_nls(uopt->nls_map); - /* - * load_nls() failure is handled later in - * udf_fill_super() after all options are - * parsed. - */ + unload_nls(uopt->nls_map); + uopt->nls_map = NULL; + } + /* When nls_map is not loaded then UTF-8 is used */ + if (!remount && strcmp(args[0].from, "utf8") != 0) { uopt->nls_map = load_nls(args[0].from); - uopt->flags |= (1 << UDF_FLAG_NLS_MAP); + if (!uopt->nls_map) { + pr_err("iocharset %s not found\n", + args[0].from); + return 0; + } } break; case Opt_uforget: @@ -2152,21 +2157,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) if (!udf_parse_options((char *)options, &uopt, false)) goto parse_options_failure; - if (uopt.flags & (1 << UDF_FLAG_UTF8) && - uopt.flags & (1 << UDF_FLAG_NLS_MAP)) { - udf_err(sb, "utf8 cannot be combined with iocharset\n"); - goto parse_options_failure; - } - if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) { - uopt.nls_map = load_nls_default(); - if (!uopt.nls_map) - uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP); - else - udf_debug("Using default NLS map\n"); - } - if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP))) - uopt.flags |= (1 << UDF_FLAG_UTF8); - fileset.logicalBlockNum = 0xFFFFFFFF; fileset.partitionReferenceNum = 0xFFFF; @@ -2321,8 +2311,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) error_out: iput(sbi->s_vat_inode); parse_options_failure: - if (uopt.nls_map) - unload_nls(uopt.nls_map); + unload_nls(uopt.nls_map); if (lvid_open) udf_close_lvid(sb); brelse(sbi->s_lvid_bh); @@ -2372,8 +2361,7 @@ static void udf_put_super(struct super_block *sb) sbi = UDF_SB(sb); iput(sbi->s_vat_inode); - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) - unload_nls(sbi->s_nls_map); + unload_nls(sbi->s_nls_map); if (!sb_rdonly(sb)) udf_close_lvid(sb); brelse(sbi->s_lvid_bh); diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 3d83be54c474..8eace7a633d3 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -20,8 +20,6 @@ #define UDF_FLAG_UNDELETE 6 #define UDF_FLAG_UNHIDE 7 #define UDF_FLAG_VARCONV 8 -#define UDF_FLAG_NLS_MAP 9 -#define UDF_FLAG_UTF8 10 #define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ #define UDF_FLAG_GID_FORGET 12 #define UDF_FLAG_UID_SET 13 diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 5fcfa96463eb..622569007b53 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -177,7 +177,7 @@ static int udf_name_from_CS0(struct super_block *sb, return 0; } - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) + if (UDF_SB(sb)->s_nls_map) conv_f = UDF_SB(sb)->s_nls_map->uni2char; else conv_f = NULL; @@ -285,7 +285,7 @@ static int udf_name_to_CS0(struct super_block *sb, if (ocu_max_len <= 0) return 0; - if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) + if (UDF_SB(sb)->s_nls_map) conv_f = UDF_SB(sb)->s_nls_map->char2uni; else conv_f = NULL; From e55f20798f5305f32236431a53e23ab04efa6aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 8 Aug 2021 18:24:37 +0200 Subject: [PATCH 014/150] isofs: joliet: Fix iocharset=utf8 mount option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 28ce50f8d96ec9035f60c9348294ea26b94db944 ] Currently iocharset=utf8 mount option is broken. To use UTF-8 as iocharset, it is required to use utf8 mount option. Fix iocharset=utf8 mount option to use be equivalent to the utf8 mount option. If UTF-8 as iocharset is used then s_nls_iocharset is set to NULL. So simplify code around, remove s_utf8 field as to distinguish between UTF-8 and non-UTF-8 it is needed just to check if s_nls_iocharset is set to NULL or not. Link: https://lore.kernel.org/r/20210808162453.1653-5-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/isofs/inode.c | 29 ++++++++++++++--------------- fs/isofs/isofs.h | 1 - fs/isofs/joliet.c | 4 +--- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 62c0462dc89f..bf30f6ce8dd1 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -155,7 +155,6 @@ struct iso9660_options{ unsigned int overriderockperm:1; unsigned int uid_set:1; unsigned int gid_set:1; - unsigned int utf8:1; unsigned char map; unsigned char check; unsigned int blocksize; @@ -355,7 +354,6 @@ static int parse_options(char *options, struct iso9660_options *popt) popt->gid = GLOBAL_ROOT_GID; popt->uid = GLOBAL_ROOT_UID; popt->iocharset = NULL; - popt->utf8 = 0; popt->overriderockperm = 0; popt->session=-1; popt->sbsector=-1; @@ -388,10 +386,13 @@ static int parse_options(char *options, struct iso9660_options *popt) case Opt_cruft: popt->cruft = 1; break; - case Opt_utf8: - popt->utf8 = 1; - break; #ifdef CONFIG_JOLIET + case Opt_utf8: + kfree(popt->iocharset); + popt->iocharset = kstrdup("utf8", GFP_KERNEL); + if (!popt->iocharset) + return 0; + break; case Opt_iocharset: kfree(popt->iocharset); popt->iocharset = match_strdup(&args[0]); @@ -494,7 +495,6 @@ static int isofs_show_options(struct seq_file *m, struct dentry *root) if (sbi->s_nocompress) seq_puts(m, ",nocompress"); if (sbi->s_overriderockperm) seq_puts(m, ",overriderockperm"); if (sbi->s_showassoc) seq_puts(m, ",showassoc"); - if (sbi->s_utf8) seq_puts(m, ",utf8"); if (sbi->s_check) seq_printf(m, ",check=%c", sbi->s_check); if (sbi->s_mapping) seq_printf(m, ",map=%c", sbi->s_mapping); @@ -517,9 +517,10 @@ static int isofs_show_options(struct seq_file *m, struct dentry *root) seq_printf(m, ",fmode=%o", sbi->s_fmode); #ifdef CONFIG_JOLIET - if (sbi->s_nls_iocharset && - strcmp(sbi->s_nls_iocharset->charset, CONFIG_NLS_DEFAULT) != 0) + if (sbi->s_nls_iocharset) seq_printf(m, ",iocharset=%s", sbi->s_nls_iocharset->charset); + else + seq_puts(m, ",iocharset=utf8"); #endif return 0; } @@ -867,14 +868,13 @@ root_found: sbi->s_nls_iocharset = NULL; #ifdef CONFIG_JOLIET - if (joliet_level && opt.utf8 == 0) { + if (joliet_level) { char *p = opt.iocharset ? opt.iocharset : CONFIG_NLS_DEFAULT; - sbi->s_nls_iocharset = load_nls(p); - if (! sbi->s_nls_iocharset) { - /* Fail only if explicit charset specified */ - if (opt.iocharset) + if (strcmp(p, "utf8") != 0) { + sbi->s_nls_iocharset = opt.iocharset ? + load_nls(opt.iocharset) : load_nls_default(); + if (!sbi->s_nls_iocharset) goto out_freesbi; - sbi->s_nls_iocharset = load_nls_default(); } } #endif @@ -890,7 +890,6 @@ root_found: sbi->s_gid = opt.gid; sbi->s_uid_set = opt.uid_set; sbi->s_gid_set = opt.gid_set; - sbi->s_utf8 = opt.utf8; sbi->s_nocompress = opt.nocompress; sbi->s_overriderockperm = opt.overriderockperm; /* diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 055ec6c586f7..dcdc191ed183 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h @@ -44,7 +44,6 @@ struct isofs_sb_info { unsigned char s_session; unsigned int s_high_sierra:1; unsigned int s_rock:2; - unsigned int s_utf8:1; unsigned int s_cruft:1; /* Broken disks with high byte of length * containing junk */ unsigned int s_nocompress:1; diff --git a/fs/isofs/joliet.c b/fs/isofs/joliet.c index be8b6a9d0b92..c0f04a1e7f69 100644 --- a/fs/isofs/joliet.c +++ b/fs/isofs/joliet.c @@ -41,14 +41,12 @@ uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls) int get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, struct inode * inode) { - unsigned char utf8; struct nls_table *nls; unsigned char len = 0; - utf8 = ISOFS_SB(inode->i_sb)->s_utf8; nls = ISOFS_SB(inode->i_sb)->s_nls_iocharset; - if (utf8) { + if (!nls) { len = utf16s_to_utf8s((const wchar_t *) de->name, de->name_len[0] >> 1, UTF16_BIG_ENDIAN, outname, PAGE_SIZE); From 93cf19b4d9b33786e584aae57ab908b04fed29dc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 9 Aug 2021 08:40:26 +0200 Subject: [PATCH 015/150] bcache: add proper error unwinding in bcache_device_init [ Upstream commit 224b0683228c5f332f9cee615d85e75e9a347170 ] Except for the IDA none of the allocations in bcache_device_init is unwound on error, fix that. Signed-off-by: Christoph Hellwig Acked-by: Coly Li Link: https://lore.kernel.org/r/20210809064028.1198327-7-hch@lst.de Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/md/bcache/super.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index b0d569032dd4..efdf6ce0443e 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -839,20 +839,20 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, n = BITS_TO_LONGS(d->nr_stripes) * sizeof(unsigned long); d->full_dirty_stripes = kvzalloc(n, GFP_KERNEL); if (!d->full_dirty_stripes) - return -ENOMEM; + goto out_free_stripe_sectors_dirty; idx = ida_simple_get(&bcache_device_idx, 0, BCACHE_DEVICE_IDX_MAX, GFP_KERNEL); if (idx < 0) - return idx; + goto out_free_full_dirty_stripes; if (bioset_init(&d->bio_split, 4, offsetof(struct bbio, bio), BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER)) - goto err; + goto out_ida_remove; d->disk = alloc_disk(BCACHE_MINORS); if (!d->disk) - goto err; + goto out_bioset_exit; set_capacity(d->disk, sectors); snprintf(d->disk->disk_name, DISK_NAME_LEN, "bcache%i", idx); @@ -887,8 +887,14 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, return 0; -err: +out_bioset_exit: + bioset_exit(&d->bio_split); +out_ida_remove: ida_simple_remove(&bcache_device_idx, idx); +out_free_full_dirty_stripes: + kvfree(d->full_dirty_stripes); +out_free_stripe_sectors_dirty: + kvfree(d->stripe_sectors_dirty); return -ENOMEM; } From 3073ec7f064245437b0c780ca20c8fe9491e6f07 Mon Sep 17 00:00:00 2001 From: Ruozhu Li Date: Sat, 7 Aug 2021 11:50:23 +0800 Subject: [PATCH 016/150] nvme-tcp: don't update queue count when failing to set io queues [ Upstream commit 664227fde63844d69e9ec9e90a8a7801e6ff072d ] We update ctrl->queue_count and schedule another reconnect when io queue count is zero.But we will never try to create any io queue in next reco- nnection, because ctrl->queue_count already set to zero.We will end up having an admin-only session in Live state, which is exactly what we try to avoid in the original patch. Update ctrl->queue_count after queue_count zero checking to fix it. Signed-off-by: Ruozhu Li Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 718152adc625..f6427a10a990 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1649,13 +1649,13 @@ static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl) if (ret) return ret; - ctrl->queue_count = nr_io_queues + 1; - if (ctrl->queue_count < 2) { + if (nr_io_queues == 0) { dev_err(ctrl->device, "unable to set any I/O queues\n"); return -ENOMEM; } + ctrl->queue_count = nr_io_queues + 1; dev_info(ctrl->device, "creating %d I/O queues.\n", nr_io_queues); From 6cb5d6ae687df7690694ba3783915f89a6547de4 Mon Sep 17 00:00:00 2001 From: Ruozhu Li Date: Wed, 28 Jul 2021 17:41:20 +0800 Subject: [PATCH 017/150] nvme-rdma: don't update queue count when failing to set io queues [ Upstream commit 85032874f80ba17bf187de1d14d9603bf3f582b8 ] We update ctrl->queue_count and schedule another reconnect when io queue count is zero.But we will never try to create any io queue in next reco- nnection, because ctrl->queue_count already set to zero.We will end up having an admin-only session in Live state, which is exactly what we try to avoid in the original patch. Update ctrl->queue_count after queue_count zero checking to fix it. Signed-off-by: Ruozhu Li Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/rdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index b8c0f75bfb7b..dcc3d2393605 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -665,13 +665,13 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl *ctrl) if (ret) return ret; - ctrl->ctrl.queue_count = nr_io_queues + 1; - if (ctrl->ctrl.queue_count < 2) { + if (nr_io_queues == 0) { dev_err(ctrl->ctrl.device, "unable to set any I/O queues\n"); return -ENOMEM; } + ctrl->ctrl.queue_count = nr_io_queues + 1; dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n", nr_io_queues); From eb45ae88bf106108b5991a4b25b741e69187978e Mon Sep 17 00:00:00 2001 From: Amit Engel Date: Sun, 8 Aug 2021 09:20:14 +0300 Subject: [PATCH 018/150] nvmet: pass back cntlid on successful completion [ Upstream commit e804d5abe2d74cfe23f5f83be580d1cdc9307111 ] According to the NVMe specification, the response dword 0 value of the Connect command is based on status code: return cntlid for successful compeltion return IPO and IATTR for connect invalid parameters. Fix a missing error information for a zero sized queue, and return the cntlid also for I/O queue Connect commands. Signed-off-by: Amit Engel Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/fabrics-cmd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c index 4e9004fe5c6f..5e47395afc1d 100644 --- a/drivers/nvme/target/fabrics-cmd.c +++ b/drivers/nvme/target/fabrics-cmd.c @@ -116,6 +116,7 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req) if (!sqsize) { pr_warn("queue size zero!\n"); req->error_loc = offsetof(struct nvmf_connect_command, sqsize); + req->cqe->result.u32 = IPO_IATTR_CONNECT_SQE(sqsize); ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; goto err; } @@ -250,11 +251,11 @@ static void nvmet_execute_io_connect(struct nvmet_req *req) } status = nvmet_install_queue(ctrl, req); - if (status) { - /* pass back cntlid that had the issue of installing queue */ - req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid); + if (status) goto out_ctrl_put; - } + + /* pass back cntlid for successful completion */ + req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid); pr_debug("adding queue %d to ctrl %d.\n", qid, ctrl->cntlid); From 0423517520d306464688aca8fa445db29a0d5673 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Mon, 16 Aug 2021 18:50:14 +0200 Subject: [PATCH 019/150] power: supply: max17042_battery: fix typo in MAx17042_TOFF [ Upstream commit ed0d0a0506025f06061325cedae1bbebd081620a ] Signed-off-by: Sebastian Krzyszkowiak Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/max17042_battery.c | 2 +- include/linux/power/max17042_battery.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index fa862f0380c4..ab4740c3bf57 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -726,7 +726,7 @@ static inline void max17042_override_por_values(struct max17042_chip *chip) struct max17042_config_data *config = chip->pdata->config_data; max17042_override_por(map, MAX17042_TGAIN, config->tgain); - max17042_override_por(map, MAx17042_TOFF, config->toff); + max17042_override_por(map, MAX17042_TOFF, config->toff); max17042_override_por(map, MAX17042_CGAIN, config->cgain); max17042_override_por(map, MAX17042_COFF, config->coff); diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h index 4badd5322949..2f9ff5017f12 100644 --- a/include/linux/power/max17042_battery.h +++ b/include/linux/power/max17042_battery.h @@ -69,7 +69,7 @@ enum max17042_register { MAX17042_RelaxCFG = 0x2A, MAX17042_MiscCFG = 0x2B, MAX17042_TGAIN = 0x2C, - MAx17042_TOFF = 0x2D, + MAX17042_TOFF = 0x2D, MAX17042_CGAIN = 0x2E, MAX17042_COFF = 0x2F, From e55b627d6e1f13ee73ec3525f1e4ff0b48a85453 Mon Sep 17 00:00:00 2001 From: Vineeth Vijayan Date: Sun, 25 Apr 2021 10:52:38 +0200 Subject: [PATCH 020/150] s390/cio: add dev_busid sysfs entry for each subchannel [ Upstream commit d3683c055212bf910d4e318f7944910ce10dbee6 ] Introduce dev_busid, which exports the device-id associated with the io-subchannel (and message-subchannel). The dev_busid indicates that of the device which may be physically installed on the corrosponding subchannel. The dev_busid value "none" indicates that the subchannel is not valid, there is no I/O device currently associated with the subchannel. The dev_busid information would be helpful to write device-specific udev-rules associated with the subchannel. The dev_busid interface would be available even when the sch is not bound to any driver or if there is no operational device connected on it. Hence this attribute can be used to write udev-rules which are specific to the device associated with the subchannel. Signed-off-by: Vineeth Vijayan Reviewed-by: Peter Oberparleiter Signed-off-by: Vasily Gorbik Signed-off-by: Sasha Levin --- drivers/s390/cio/css.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 5734a78dbb8e..7950ac59b174 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -426,9 +426,26 @@ static ssize_t pimpampom_show(struct device *dev, } static DEVICE_ATTR_RO(pimpampom); +static ssize_t dev_busid_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct subchannel *sch = to_subchannel(dev); + struct pmcw *pmcw = &sch->schib.pmcw; + + if ((pmcw->st == SUBCHANNEL_TYPE_IO || + pmcw->st == SUBCHANNEL_TYPE_MSG) && pmcw->dnv) + return sysfs_emit(buf, "0.%x.%04x\n", sch->schid.ssid, + pmcw->dev); + else + return sysfs_emit(buf, "none\n"); +} +static DEVICE_ATTR_RO(dev_busid); + static struct attribute *io_subchannel_type_attrs[] = { &dev_attr_chpids.attr, &dev_attr_pimpampom.attr, + &dev_attr_dev_busid.attr, NULL, }; ATTRIBUTE_GROUPS(io_subchannel_type); From 1c189ccef0cfaf292a816f9abcc7a1b11fe094c6 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Mon, 16 Aug 2021 10:44:47 +0900 Subject: [PATCH 021/150] libata: fix ata_host_start() [ Upstream commit 355a8031dc174450ccad2a61c513ad7222d87a97 ] The loop on entry of ata_host_start() may not initialize host->ops to a non NULL value. The test on the host_stop field of host->ops must then be preceded by a check that host->ops is not NULL. Reported-by: kernel test robot Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke Link: https://lore.kernel.org/r/20210816014456.2191776-3-damien.lemoal@wdc.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f67b3fb33d57..7788af0ca109 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6394,7 +6394,7 @@ int ata_host_start(struct ata_host *host) have_stop = 1; } - if (host->ops->host_stop) + if (host->ops && host->ops->host_stop) have_stop = 1; if (have_stop) { From c2b3f81125a6b197796c78927ccfd8de757c49da Mon Sep 17 00:00:00 2001 From: Giovanni Cabiddu Date: Thu, 12 Aug 2021 21:21:13 +0100 Subject: [PATCH 022/150] crypto: qat - do not ignore errors from enable_vf2pf_comms() [ Upstream commit 5147f0906d50a9d26f2b8698cd06b5680e9867ff ] The function adf_dev_init() ignores the error code reported by enable_vf2pf_comms(). If the latter fails, e.g. the VF is not compatible with the pf, then the load of the VF driver progresses. This patch changes adf_dev_init() so that the error code from enable_vf2pf_comms() is returned to the caller. Signed-off-by: Giovanni Cabiddu Reviewed-by: Marco Chiappero Reviewed-by: Fiona Trahe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c index 26556c713049..7a7d43c47534 100644 --- a/drivers/crypto/qat/qat_common/adf_init.c +++ b/drivers/crypto/qat/qat_common/adf_init.c @@ -105,6 +105,7 @@ int adf_dev_init(struct adf_accel_dev *accel_dev) struct service_hndl *service; struct list_head *list_itr; struct adf_hw_device_data *hw_data = accel_dev->hw_device; + int ret; if (!hw_data) { dev_err(&GET_DEV(accel_dev), @@ -171,9 +172,9 @@ int adf_dev_init(struct adf_accel_dev *accel_dev) } hw_data->enable_error_correction(accel_dev); - hw_data->enable_vf2pf_comms(accel_dev); + ret = hw_data->enable_vf2pf_comms(accel_dev); - return 0; + return ret; } EXPORT_SYMBOL_GPL(adf_dev_init); From 4a988264556c809444e62a46d72c76aaffdb067e Mon Sep 17 00:00:00 2001 From: Giovanni Cabiddu Date: Thu, 12 Aug 2021 21:21:14 +0100 Subject: [PATCH 023/150] crypto: qat - handle both source of interrupt in VF ISR [ Upstream commit 0a73c762e1eee33a5e5dc0e3488f1b7cd17249b3 ] The top half of the VF drivers handled only a source at the time. If an interrupt for PF2VF and bundle occurred at the same time, the ISR scheduled only the bottom half for PF2VF. This patch fixes the VF top half so that if both sources of interrupt trigger at the same time, both bottom halves are scheduled. This patch is based on earlier work done by Conor McLoughlin. Signed-off-by: Giovanni Cabiddu Reviewed-by: Marco Chiappero Reviewed-by: Fiona Trahe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_vf_isr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/qat/qat_common/adf_vf_isr.c b/drivers/crypto/qat/qat_common/adf_vf_isr.c index df9a1f35b832..ef90902c8200 100644 --- a/drivers/crypto/qat/qat_common/adf_vf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_vf_isr.c @@ -203,6 +203,7 @@ static irqreturn_t adf_isr(int irq, void *privdata) struct adf_bar *pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; void __iomem *pmisc_bar_addr = pmisc->virt_addr; + bool handled = false; u32 v_int; /* Read VF INT source CSR to determine the source of VF interrupt */ @@ -215,7 +216,7 @@ static irqreturn_t adf_isr(int irq, void *privdata) /* Schedule tasklet to handle interrupt BH */ tasklet_hi_schedule(&accel_dev->vf.pf2vf_bh_tasklet); - return IRQ_HANDLED; + handled = true; } /* Check bundle interrupt */ @@ -227,10 +228,10 @@ static irqreturn_t adf_isr(int irq, void *privdata) WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, bank->bank_number, 0); tasklet_hi_schedule(&bank->resp_handler); - return IRQ_HANDLED; + handled = true; } - return IRQ_NONE; + return handled ? IRQ_HANDLED : IRQ_NONE; } static int adf_request_msi_irq(struct adf_accel_dev *accel_dev) From 843b4e713a80b7cfdceb79833fdcfeaf66870859 Mon Sep 17 00:00:00 2001 From: Marco Chiappero Date: Thu, 12 Aug 2021 21:21:19 +0100 Subject: [PATCH 024/150] crypto: qat - fix reuse of completion variable [ Upstream commit 3d655732b0199562267a05c7ff69ecdd11632939 ] Use reinit_completion() to set to a clean state a completion variable, used to coordinate the VF to PF request-response flow, before every new VF request. Signed-off-by: Marco Chiappero Co-developed-by: Giovanni Cabiddu Signed-off-by: Giovanni Cabiddu Reviewed-by: Fiona Trahe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c index b3875fdf6cd7..9dab2cc11fdf 100644 --- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c +++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c @@ -361,6 +361,8 @@ static int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev) msg |= ADF_PFVF_COMPATIBILITY_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT; BUILD_BUG_ON(ADF_PFVF_COMPATIBILITY_VERSION > 255); + reinit_completion(&accel_dev->vf.iov_msg_completion); + /* Send request from VF to PF */ ret = adf_iov_putmsg(accel_dev, msg, 0); if (ret) { From 7dfa7bb69e1322c81b52b8a4d405791a47f8ff38 Mon Sep 17 00:00:00 2001 From: Marco Chiappero Date: Thu, 12 Aug 2021 21:21:22 +0100 Subject: [PATCH 025/150] crypto: qat - fix naming for init/shutdown VF to PF notifications [ Upstream commit b90c1c4d3fa8cd90f4e8245b13564380fd0bfad1 ] At start and shutdown, VFs notify the PF about their state. These notifications are carried out through a message exchange using the PFVF protocol. Function names lead to believe they do perform init or shutdown logic. This is to fix the naming to better reflect their purpose. Signed-off-by: Marco Chiappero Co-developed-by: Giovanni Cabiddu Signed-off-by: Giovanni Cabiddu Reviewed-by: Fiona Trahe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c | 4 ++-- drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c | 4 ++-- drivers/crypto/qat/qat_common/adf_common_drv.h | 8 ++++---- drivers/crypto/qat/qat_common/adf_vf2pf_msg.c | 12 ++++++------ .../qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c index d2d0ae445fd8..7c7d49a8a403 100644 --- a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c +++ b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c @@ -123,10 +123,10 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data) hw_data->enable_error_correction = adf_vf_void_noop; hw_data->init_admin_comms = adf_vf_int_noop; hw_data->exit_admin_comms = adf_vf_void_noop; - hw_data->send_admin_init = adf_vf2pf_init; + hw_data->send_admin_init = adf_vf2pf_notify_init; hw_data->init_arb = adf_vf_int_noop; hw_data->exit_arb = adf_vf_void_noop; - hw_data->disable_iov = adf_vf2pf_shutdown; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_num_accels = get_num_accels; diff --git a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c index 38e4bc04f407..90e8a7564756 100644 --- a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c +++ b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c @@ -123,10 +123,10 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data) hw_data->enable_error_correction = adf_vf_void_noop; hw_data->init_admin_comms = adf_vf_int_noop; hw_data->exit_admin_comms = adf_vf_void_noop; - hw_data->send_admin_init = adf_vf2pf_init; + hw_data->send_admin_init = adf_vf2pf_notify_init; hw_data->init_arb = adf_vf_int_noop; hw_data->exit_arb = adf_vf_void_noop; - hw_data->disable_iov = adf_vf2pf_shutdown; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_num_accels = get_num_accels; diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h index d78f8d5c89c3..289dd7e48d4a 100644 --- a/drivers/crypto/qat/qat_common/adf_common_drv.h +++ b/drivers/crypto/qat/qat_common/adf_common_drv.h @@ -239,8 +239,8 @@ void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); -int adf_vf2pf_init(struct adf_accel_dev *accel_dev); -void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev); +int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev); +void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev); int adf_init_pf_wq(void); void adf_exit_pf_wq(void); int adf_init_vf_wq(void); @@ -263,12 +263,12 @@ static inline void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev) { } -static inline int adf_vf2pf_init(struct adf_accel_dev *accel_dev) +static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) { return 0; } -static inline void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) +static inline void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) { } diff --git a/drivers/crypto/qat/qat_common/adf_vf2pf_msg.c b/drivers/crypto/qat/qat_common/adf_vf2pf_msg.c index cd5f37dffe8a..1830194567e8 100644 --- a/drivers/crypto/qat/qat_common/adf_vf2pf_msg.c +++ b/drivers/crypto/qat/qat_common/adf_vf2pf_msg.c @@ -49,14 +49,14 @@ #include "adf_pf2vf_msg.h" /** - * adf_vf2pf_init() - send init msg to PF + * adf_vf2pf_notify_init() - send init msg to PF * @accel_dev: Pointer to acceleration VF device. * * Function sends an init messge from the VF to a PF * * Return: 0 on success, error code otherwise. */ -int adf_vf2pf_init(struct adf_accel_dev *accel_dev) +int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) { u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | (ADF_VF2PF_MSGTYPE_INIT << ADF_VF2PF_MSGTYPE_SHIFT)); @@ -69,17 +69,17 @@ int adf_vf2pf_init(struct adf_accel_dev *accel_dev) set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); return 0; } -EXPORT_SYMBOL_GPL(adf_vf2pf_init); +EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init); /** - * adf_vf2pf_shutdown() - send shutdown msg to PF + * adf_vf2pf_notify_shutdown() - send shutdown msg to PF * @accel_dev: Pointer to acceleration VF device. * * Function sends a shutdown messge from the VF to a PF * * Return: void */ -void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) +void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) { u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_VF2PF_MSGTYPE_SHIFT)); @@ -89,4 +89,4 @@ void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) dev_err(&GET_DEV(accel_dev), "Failed to send Shutdown event to PF\n"); } -EXPORT_SYMBOL_GPL(adf_vf2pf_shutdown); +EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown); diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c index a3b4dd8099a7..3a8361c83f0b 100644 --- a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c @@ -123,10 +123,10 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) hw_data->enable_error_correction = adf_vf_void_noop; hw_data->init_admin_comms = adf_vf_int_noop; hw_data->exit_admin_comms = adf_vf_void_noop; - hw_data->send_admin_init = adf_vf2pf_init; + hw_data->send_admin_init = adf_vf2pf_notify_init; hw_data->init_arb = adf_vf_int_noop; hw_data->exit_arb = adf_vf_void_noop; - hw_data->disable_iov = adf_vf2pf_shutdown; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_num_accels = get_num_accels; From a6273c8c2aca93782746af84f97fae20d481c3e6 Mon Sep 17 00:00:00 2001 From: Giovanni Cabiddu Date: Thu, 12 Aug 2021 21:21:28 +0100 Subject: [PATCH 026/150] crypto: qat - do not export adf_iov_putmsg() [ Upstream commit 645ae0af1840199086c33e4f841892ebee73f615 ] The function adf_iov_putmsg() is only used inside the intel_qat module therefore should not be exported. Remove EXPORT_SYMBOL for the function adf_iov_putmsg(). Signed-off-by: Giovanni Cabiddu Reviewed-by: Fiona Trahe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c index 9dab2cc11fdf..c64481160b71 100644 --- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c +++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c @@ -231,7 +231,6 @@ int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) return ret; } -EXPORT_SYMBOL_GPL(adf_iov_putmsg); void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) { From ae4240d1f4bf3e253bd3c429d54de9975595f7da Mon Sep 17 00:00:00 2001 From: Desmond Cheong Zhi Xi Date: Fri, 2 Jul 2021 17:18:31 +0800 Subject: [PATCH 027/150] fcntl: fix potential deadlock for &fasync_struct.fa_lock [ Upstream commit 2f488f698fda820f8e6fa0407630154eceb145d6 ] There is an existing lock hierarchy of &dev->event_lock --> &fasync_struct.fa_lock --> &f->f_owner.lock from the following call chain: input_inject_event(): spin_lock_irqsave(&dev->event_lock,...); input_handle_event(): input_pass_values(): input_to_handler(): evdev_events(): evdev_pass_values(): spin_lock(&client->buffer_lock); __pass_event(): kill_fasync(): kill_fasync_rcu(): read_lock(&fa->fa_lock); send_sigio(): read_lock_irqsave(&fown->lock,...); &dev->event_lock is HARDIRQ-safe, so interrupts have to be disabled while grabbing &fasync_struct.fa_lock, otherwise we invert the lock hierarchy. However, since kill_fasync which calls kill_fasync_rcu is an exported symbol, it may not necessarily be called with interrupts disabled. As kill_fasync_rcu may be called with interrupts disabled (for example, in the call chain above), we replace calls to read_lock/read_unlock on &fasync_struct.fa_lock in kill_fasync_rcu with read_lock_irqsave/read_unlock_irqrestore. Signed-off-by: Desmond Cheong Zhi Xi Signed-off-by: Jeff Layton Signed-off-by: Sasha Levin --- fs/fcntl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index 3dc90e5293e6..fa0fdd829613 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -993,13 +993,14 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) { while (fa) { struct fown_struct *fown; + unsigned long flags; if (fa->magic != FASYNC_MAGIC) { printk(KERN_ERR "kill_fasync: bad magic number in " "fasync_struct!\n"); return; } - read_lock(&fa->fa_lock); + read_lock_irqsave(&fa->fa_lock, flags); if (fa->fa_file) { fown = &fa->fa_file->f_owner; /* Don't send SIGURG to processes which have not set a @@ -1008,7 +1009,7 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) if (!(sig == SIGURG && fown->signum == 0)) send_sigio(fown, fa->fa_fd, band); } - read_unlock(&fa->fa_lock); + read_unlock_irqrestore(&fa->fa_lock, flags); fa = rcu_dereference(fa->fa_next); } } From 98296eb3deca34760f6c98478d7d2454b4005ff1 Mon Sep 17 00:00:00 2001 From: Stian Skjelstad Date: Sun, 22 Aug 2021 11:33:32 +0200 Subject: [PATCH 028/150] udf_get_extendedattr() had no boundary checks. [ Upstream commit 58bc6d1be2f3b0ceecb6027dfa17513ec6aa2abb ] When parsing the ExtendedAttr data, malicous or corrupt attribute length could cause kernel hangs and buffer overruns in some special cases. Link: https://lore.kernel.org/r/20210822093332.25234-1-stian.skjelstad@gmail.com Signed-off-by: Stian Skjelstad Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/misc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/udf/misc.c b/fs/udf/misc.c index 401e64cde1be..853bcff51043 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c @@ -173,13 +173,22 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type, else offset = le32_to_cpu(eahd->appAttrLocation); - while (offset < iinfo->i_lenEAttr) { + while (offset + sizeof(*gaf) < iinfo->i_lenEAttr) { + uint32_t attrLength; + gaf = (struct genericFormat *)&ea[offset]; + attrLength = le32_to_cpu(gaf->attrLength); + + /* Detect undersized elements and buffer overflows */ + if ((attrLength < sizeof(*gaf)) || + (attrLength > (iinfo->i_lenEAttr - offset))) + break; + if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype) return gaf; else - offset += le32_to_cpu(gaf->attrLength); + offset += attrLength; } } From 7a67a00ea8a7d4a9df6fa5585d90f5cc7877733e Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Fri, 6 Aug 2021 12:55:08 +0200 Subject: [PATCH 029/150] s390/kasan: fix large PMD pages address alignment check [ Upstream commit ddd63c85ef67ea9ea7282ad35eafb6568047126e ] It is currently possible to initialize a large PMD page when the address is not aligned on page boundary. Signed-off-by: Alexander Gordeev Reviewed-by: Vasily Gorbik Signed-off-by: Vasily Gorbik Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin --- arch/s390/mm/kasan_init.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c index 460f25572940..5182e0836ca7 100644 --- a/arch/s390/mm/kasan_init.c +++ b/arch/s390/mm/kasan_init.c @@ -101,6 +101,9 @@ static void __init kasan_early_vmemmap_populate(unsigned long address, pgt_prot = pgprot_val(PAGE_KERNEL_EXEC); sgt_prot = pgprot_val(SEGMENT_KERNEL_EXEC); + /* + * The first 1MB of 1:1 mapping is mapped with 4KB pages + */ while (address < end) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { @@ -146,30 +149,26 @@ static void __init kasan_early_vmemmap_populate(unsigned long address, pm_dir = pmd_offset(pu_dir, address); if (pmd_none(*pm_dir)) { - if (mode == POPULATE_ZERO_SHADOW && - IS_ALIGNED(address, PMD_SIZE) && + if (IS_ALIGNED(address, PMD_SIZE) && end - address >= PMD_SIZE) { - pmd_populate(&init_mm, pm_dir, - kasan_early_shadow_pte); - address = (address + PMD_SIZE) & PMD_MASK; - continue; - } - /* the first megabyte of 1:1 is mapped with 4k pages */ - if (has_edat && address && end - address >= PMD_SIZE && - mode != POPULATE_ZERO_SHADOW) { - void *page; + if (mode == POPULATE_ZERO_SHADOW) { + pmd_populate(&init_mm, pm_dir, kasan_early_shadow_pte); + address = (address + PMD_SIZE) & PMD_MASK; + continue; + } else if (has_edat && address) { + void *page; - if (mode == POPULATE_ONE2ONE) { - page = (void *)address; - } else { - page = kasan_early_alloc_segment(); - memset(page, 0, _SEGMENT_SIZE); + if (mode == POPULATE_ONE2ONE) { + page = (void *)address; + } else { + page = kasan_early_alloc_segment(); + memset(page, 0, _SEGMENT_SIZE); + } + pmd_val(*pm_dir) = __pa(page) | sgt_prot; + address = (address + PMD_SIZE) & PMD_MASK; + continue; } - pmd_val(*pm_dir) = __pa(page) | sgt_prot; - address = (address + PMD_SIZE) & PMD_MASK; - continue; } - pt_dir = kasan_early_pte_alloc(); pmd_populate(&init_mm, pm_dir, pt_dir); } else if (pmd_large(*pm_dir)) { From c68ba4a708fbd0efdc384cd29250bb292a45e559 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 13 Aug 2021 15:05:03 +0200 Subject: [PATCH 030/150] s390/debug: fix debug area life cycle [ Upstream commit 9372a82892c2caa6bccab9a4081166fa769699f8 ] Currently allocation and registration of s390dbf debug areas are tied together. As a result, a debug area cannot be unregistered and re-registered while any process has an associated debugfs file open. Fix this by splitting alloc/release from register/unregister. Signed-off-by: Peter Oberparleiter Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin --- arch/s390/kernel/debug.c | 102 +++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 7184d55d87aa..b1aadc3ad065 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -327,24 +327,6 @@ static debug_info_t *debug_info_create(const char *name, int pages_per_area, goto out; rc->mode = mode & ~S_IFMT; - - /* create root directory */ - rc->debugfs_root_entry = debugfs_create_dir(rc->name, - debug_debugfs_root_entry); - - /* append new element to linked list */ - if (!debug_area_first) { - /* first element in list */ - debug_area_first = rc; - rc->prev = NULL; - } else { - /* append element to end of list */ - debug_area_last->next = rc; - rc->prev = debug_area_last; - } - debug_area_last = rc; - rc->next = NULL; - refcount_set(&rc->ref_count, 1); out: return rc; @@ -404,27 +386,10 @@ static void debug_info_get(debug_info_t *db_info) */ static void debug_info_put(debug_info_t *db_info) { - int i; - if (!db_info) return; - if (refcount_dec_and_test(&db_info->ref_count)) { - for (i = 0; i < DEBUG_MAX_VIEWS; i++) { - if (!db_info->views[i]) - continue; - debugfs_remove(db_info->debugfs_entries[i]); - } - debugfs_remove(db_info->debugfs_root_entry); - if (db_info == debug_area_first) - debug_area_first = db_info->next; - if (db_info == debug_area_last) - debug_area_last = db_info->prev; - if (db_info->prev) - db_info->prev->next = db_info->next; - if (db_info->next) - db_info->next->prev = db_info->prev; + if (refcount_dec_and_test(&db_info->ref_count)) debug_info_free(db_info); - } } /* @@ -648,6 +613,31 @@ static int debug_close(struct inode *inode, struct file *file) return 0; /* success */ } +/* Create debugfs entries and add to internal list. */ +static void _debug_register(debug_info_t *id) +{ + /* create root directory */ + id->debugfs_root_entry = debugfs_create_dir(id->name, + debug_debugfs_root_entry); + + /* append new element to linked list */ + if (!debug_area_first) { + /* first element in list */ + debug_area_first = id; + id->prev = NULL; + } else { + /* append element to end of list */ + debug_area_last->next = id; + id->prev = debug_area_last; + } + debug_area_last = id; + id->next = NULL; + + debug_register_view(id, &debug_level_view); + debug_register_view(id, &debug_flush_view); + debug_register_view(id, &debug_pages_view); +} + /** * debug_register_mode() - creates and initializes debug area. * @@ -677,19 +667,16 @@ debug_info_t *debug_register_mode(const char *name, int pages_per_area, if ((uid != 0) || (gid != 0)) pr_warn("Root becomes the owner of all s390dbf files in sysfs\n"); BUG_ON(!initialized); - mutex_lock(&debug_mutex); /* create new debug_info */ rc = debug_info_create(name, pages_per_area, nr_areas, buf_size, mode); - if (!rc) - goto out; - debug_register_view(rc, &debug_level_view); - debug_register_view(rc, &debug_flush_view); - debug_register_view(rc, &debug_pages_view); -out: - if (!rc) + if (rc) { + mutex_lock(&debug_mutex); + _debug_register(rc); + mutex_unlock(&debug_mutex); + } else { pr_err("Registering debug feature %s failed\n", name); - mutex_unlock(&debug_mutex); + } return rc; } EXPORT_SYMBOL(debug_register_mode); @@ -718,6 +705,27 @@ debug_info_t *debug_register(const char *name, int pages_per_area, } EXPORT_SYMBOL(debug_register); +/* Remove debugfs entries and remove from internal list. */ +static void _debug_unregister(debug_info_t *id) +{ + int i; + + for (i = 0; i < DEBUG_MAX_VIEWS; i++) { + if (!id->views[i]) + continue; + debugfs_remove(id->debugfs_entries[i]); + } + debugfs_remove(id->debugfs_root_entry); + if (id == debug_area_first) + debug_area_first = id->next; + if (id == debug_area_last) + debug_area_last = id->prev; + if (id->prev) + id->prev->next = id->next; + if (id->next) + id->next->prev = id->prev; +} + /** * debug_unregister() - give back debug area. * @@ -731,8 +739,10 @@ void debug_unregister(debug_info_t *id) if (!id) return; mutex_lock(&debug_mutex); - debug_info_put(id); + _debug_unregister(id); mutex_unlock(&debug_mutex); + + debug_info_put(id); } EXPORT_SYMBOL(debug_unregister); From 67da2d9c9e9943be4258ee94906cf3be367df152 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Mon, 5 Jul 2021 23:47:27 +0300 Subject: [PATCH 031/150] m68k: emu: Fix invalid free in nfeth_cleanup() [ Upstream commit 761608f5cf70e8876c2f0e39ca54b516bdcb7c12 ] In the for loop all nfeth_dev array members should be freed, not only the first one. Freeing only the first array member can cause double-free bugs and memory leaks. Fixes: 9cd7b148312f ("m68k/atari: ARAnyM - Add support for network access") Signed-off-by: Pavel Skripkin Link: https://lore.kernel.org/r/20210705204727.10743-1-paskripkin@gmail.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/emu/nfeth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c index a4ebd2445eda..e5831cd293d0 100644 --- a/arch/m68k/emu/nfeth.c +++ b/arch/m68k/emu/nfeth.c @@ -254,8 +254,8 @@ static void __exit nfeth_cleanup(void) for (i = 0; i < MAX_UNIT; i++) { if (nfeth_dev[i]) { - unregister_netdev(nfeth_dev[0]); - free_netdev(nfeth_dev[0]); + unregister_netdev(nfeth_dev[i]); + free_netdev(nfeth_dev[i]); } } free_irq(nfEtherIRQ, nfeth_interrupt); From 449884aeb3587ac38fd142a5448f178de37e5421 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Thu, 5 Aug 2021 11:21:53 +0100 Subject: [PATCH 032/150] sched: Fix UCLAMP_FLAG_IDLE setting [ Upstream commit ca4984a7dd863f3e1c0df775ae3e744bff24c303 ] The UCLAMP_FLAG_IDLE flag is set on a runqueue when dequeueing the last uclamp active task (that is, when buckets.tasks reaches 0 for all buckets) to maintain the last uclamp.max and prevent blocked util from suddenly becoming visible. However, there is an asymmetry in how the flag is set and cleared which can lead to having the flag set whilst there are active tasks on the rq. Specifically, the flag is cleared in the uclamp_rq_inc() path, which is called at enqueue time, but set in uclamp_rq_dec_id() which is called both when dequeueing a task _and_ in the update_uclamp_active() path. As a result, when both uclamp_rq_{dec,ind}_id() are called from update_uclamp_active(), the flag ends up being set but not cleared, hence leaving the runqueue in a broken state. Fix this by clearing the flag in update_uclamp_active() as well. Fixes: e496187da710 ("sched/uclamp: Enforce last task's UCLAMP_MAX") Reported-by: Rick Yiu Signed-off-by: Quentin Perret Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Qais Yousef Tested-by: Dietmar Eggemann Link: https://lore.kernel.org/r/20210805102154.590709-2-qperret@google.com Signed-off-by: Sasha Levin --- kernel/sched/core.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 8294debf68c4..5dc43d37e6a2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1110,6 +1110,23 @@ static inline void uclamp_rq_dec(struct rq *rq, struct task_struct *p) uclamp_rq_dec_id(rq, p, clamp_id); } +static inline void uclamp_rq_reinc_id(struct rq *rq, struct task_struct *p, + enum uclamp_id clamp_id) +{ + if (!p->uclamp[clamp_id].active) + return; + + uclamp_rq_dec_id(rq, p, clamp_id); + uclamp_rq_inc_id(rq, p, clamp_id); + + /* + * Make sure to clear the idle flag if we've transiently reached 0 + * active tasks on rq. + */ + if (clamp_id == UCLAMP_MAX && (rq->uclamp_flags & UCLAMP_FLAG_IDLE)) + rq->uclamp_flags &= ~UCLAMP_FLAG_IDLE; +} + static inline void uclamp_update_active(struct task_struct *p) { @@ -1133,12 +1150,8 @@ uclamp_update_active(struct task_struct *p) * affecting a valid clamp bucket, the next time it's enqueued, * it will already see the updated clamp bucket value. */ - for_each_clamp_id(clamp_id) { - if (p->uclamp[clamp_id].active) { - uclamp_rq_dec_id(rq, p, clamp_id); - uclamp_rq_inc_id(rq, p, clamp_id); - } - } + for_each_clamp_id(clamp_id) + uclamp_rq_reinc_id(rq, p, clamp_id); task_rq_unlock(rq, p, &rf); } From b29593d0696d81fc6bbfd510f74391cb2cc6b8d5 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:17:26 +0300 Subject: [PATCH 033/150] spi: spi-fsl-dspi: Fix issue with uninitialized dma_slave_config [ Upstream commit 209ab223ad5b18e437289235e3bde12593b94ac4 ] Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For spi-fsl-dspi, this is probably not currently an issue but is still good to fix though. Fixes: 90ba37033cb9 ("spi: spi-fsl-dspi: Add DMA support for Vybrid") Cc: Sanchayan Maity Cc: Vladimir Oltean Cc: Peter Ujfalusi Cc: Vinod Koul Signed-off-by: Tony Lindgren Acked-by: Vladimir Oltean Link: https://lore.kernel.org/r/20210810081727.19491-1-tony@atomide.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-fsl-dspi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 40dccc580e86..3e0200618af3 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -423,6 +423,7 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) goto err_rx_dma_buf; } + memset(&cfg, 0, sizeof(cfg)); cfg.src_addr = phy_addr + SPI_POPR; cfg.dst_addr = phy_addr + SPI_PUSHR; cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; From 2d00b22c8b8136f5b86af6772be6d556fe227962 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:17:27 +0300 Subject: [PATCH 034/150] spi: spi-pic32: Fix issue with uninitialized dma_slave_config [ Upstream commit 976c1de1de147bb7f4e0d87482f375221c05aeaf ] Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For spi-pic32, this is probably not currently an issue but is still good to fix though. Fixes: 1bcb9f8ceb67 ("spi: spi-pic32: Add PIC32 SPI master driver") Cc: Purna Chandra Mandal Cc: Peter Ujfalusi Cc: Vinod Koul Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210810081727.19491-2-tony@atomide.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-pic32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c index 8272bde5d706..b5268b0d7b4c 100644 --- a/drivers/spi/spi-pic32.c +++ b/drivers/spi/spi-pic32.c @@ -361,6 +361,7 @@ static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width) struct dma_slave_config cfg; int ret; + memset(&cfg, 0, sizeof(cfg)); cfg.device_fc = true; cfg.src_addr = pic32s->dma_base + buf_offset; cfg.dst_addr = pic32s->dma_base + buf_offset; From 57c8e2ea47bcca90bda5c8b3da8182a25da985e3 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Wed, 11 Aug 2021 17:33:32 +0800 Subject: [PATCH 035/150] genirq/timings: Fix error return code in irq_timings_test_irqs() [ Upstream commit 290fdc4b7ef14e33d0e30058042b0e9bfd02b89b ] Return a negative error code from the error handling case instead of 0, as done elsewhere in this function. Fixes: f52da98d900e ("genirq/timings: Add selftest for irqs circular buffer") Reported-by: Hulk Robot Signed-off-by: Zhen Lei Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210811093333.2376-1-thunder.leizhen@huawei.com Signed-off-by: Sasha Levin --- kernel/irq/timings.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/irq/timings.c b/kernel/irq/timings.c index b5985da80acf..7ccc8edce46d 100644 --- a/kernel/irq/timings.c +++ b/kernel/irq/timings.c @@ -799,12 +799,14 @@ static int __init irq_timings_test_irqs(struct timings_intervals *ti) __irq_timings_store(irq, irqs, ti->intervals[i]); if (irqs->circ_timings[i & IRQ_TIMINGS_MASK] != index) { + ret = -EBADSLT; pr_err("Failed to store in the circular buffer\n"); goto out; } } if (irqs->count != ti->count) { + ret = -ERANGE; pr_err("Count differs\n"); goto out; } From 6b10d3d3a9ff260d734e0072a3b3792e4f1bbea5 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Thu, 5 Aug 2021 16:53:32 +0800 Subject: [PATCH 036/150] lib/mpi: use kcalloc in mpi_resize [ Upstream commit b6f756726e4dfe75be1883f6a0202dcecdc801ab ] We should set the additional space to 0 in mpi_resize(). So use kcalloc() instead of kmalloc_array(). In lib/mpi/ec.c: /**************** * Resize the array of A to NLIMBS. the additional space is cleared * (set to 0) [done by m_realloc()] */ int mpi_resize(MPI a, unsigned nlimbs) Like the comment of kernel's mpi_resize() said, the additional space need to be set to 0, but when a->d is not NULL, it does not set. The kernel's mpi lib is from libgcrypt, the mpi resize in libgcrypt is _gcry_mpi_resize() which set the additional space to 0. This bug may cause mpi api which use mpi_resize() get wrong result under the condition of using the additional space without initiation. If this condition is not met, the bug would not be triggered. Currently in kernel, rsa, sm2 and dh use mpi lib, and they works well, so the bug is not triggered in these cases. add_points_edwards() use the additional space directly, so it will get a wrong result. Fixes: cdec9cb5167a ("crypto: GnuPG based MPI lib - source files (part 1)") Signed-off-by: Hongbo Li Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- lib/mpi/mpiutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c index 20ed0f766787..00825028cc84 100644 --- a/lib/mpi/mpiutil.c +++ b/lib/mpi/mpiutil.c @@ -91,7 +91,7 @@ int mpi_resize(MPI a, unsigned nlimbs) return 0; /* no need to do it */ if (a->d) { - p = kmalloc_array(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL); + p = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL); if (!p) return -ENOMEM; memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t)); From c60a31db3990a144adc95df1feed9f7ebba6cd27 Mon Sep 17 00:00:00 2001 From: Phong Hoang Date: Thu, 22 Apr 2021 14:34:43 +0200 Subject: [PATCH 037/150] clocksource/drivers/sh_cmt: Fix wrong setting if don't request IRQ for clock source channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit be83c3b6e7b8ff22f72827a613bf6f3aa5afadbb ] If CMT instance has at least two channels, one channel will be used as a clock source and another one used as a clock event device. In that case, IRQ is not requested for clock source channel so sh_cmt_clock_event_program_verify() might work incorrectly. Besides, when a channel is only used for clock source, don't need to re-set the next match_value since it should be maximum timeout as it still is. On the other hand, due to no IRQ, total_cycles is not counted up when reaches compare match time (timer counter resets to zero), so sh_cmt_clocksource_read() returns unexpected value. Therefore, use 64-bit clocksoure's mask for 32-bit or 16-bit variants will also lead to wrong delta calculation. Hence, this mask should correspond to timer counter width, and above function just returns the raw value of timer counter register. Fixes: bfa76bb12f23 ("clocksource: sh_cmt: Request IRQ for clock event device only") Fixes: 37e7742c55ba ("clocksource/drivers/sh_cmt: Fix clocksource width for 32-bit machines") Signed-off-by: Phong Hoang Signed-off-by: Niklas Söderlund Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210422123443.73334-1-niklas.soderlund+renesas@ragnatech.se Signed-off-by: Sasha Levin --- drivers/clocksource/sh_cmt.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index ef773db080e9..a0570213170d 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -568,7 +568,8 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag) ch->flags |= flag; /* setup timeout if no clockevent */ - if ((flag == FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT))) + if (ch->cmt->num_channels == 1 && + flag == FLAG_CLOCKSOURCE && (!(ch->flags & FLAG_CLOCKEVENT))) __sh_cmt_set_next(ch, ch->max_match_value); out: raw_spin_unlock_irqrestore(&ch->lock, flags); @@ -604,20 +605,25 @@ static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs) static u64 sh_cmt_clocksource_read(struct clocksource *cs) { struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); - unsigned long flags; u32 has_wrapped; - u64 value; - u32 raw; - raw_spin_lock_irqsave(&ch->lock, flags); - value = ch->total_cycles; - raw = sh_cmt_get_counter(ch, &has_wrapped); + if (ch->cmt->num_channels == 1) { + unsigned long flags; + u64 value; + u32 raw; - if (unlikely(has_wrapped)) - raw += ch->match_value + 1; - raw_spin_unlock_irqrestore(&ch->lock, flags); + raw_spin_lock_irqsave(&ch->lock, flags); + value = ch->total_cycles; + raw = sh_cmt_get_counter(ch, &has_wrapped); - return value + raw; + if (unlikely(has_wrapped)) + raw += ch->match_value + 1; + raw_spin_unlock_irqrestore(&ch->lock, flags); + + return value + raw; + } + + return sh_cmt_get_counter(ch, &has_wrapped); } static int sh_cmt_clocksource_enable(struct clocksource *cs) @@ -680,7 +686,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch, cs->disable = sh_cmt_clocksource_disable; cs->suspend = sh_cmt_clocksource_suspend; cs->resume = sh_cmt_clocksource_resume; - cs->mask = CLOCKSOURCE_MASK(sizeof(u64) * 8); + cs->mask = CLOCKSOURCE_MASK(ch->cmt->info->width); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n", From b3fa499d72a0db612f12645265a36751955c0037 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Thu, 12 Aug 2021 12:15:01 +0300 Subject: [PATCH 038/150] block: nbd: add sanity check for first_minor [ Upstream commit b1a811633f7321cf1ae2bb76a66805b7720e44c9 ] Syzbot hit WARNING in internal_create_group(). The problem was in too big disk->first_minor. disk->first_minor is initialized by value, which comes from userspace and there wasn't any sanity checks about value correctness. It can cause duplicate creation of sysfs files/links, because disk->first_minor will be passed to MKDEV() which causes truncation to byte. Since maximum minor value is 0xff, let's check if first_minor is correct minor number. NOTE: the root case of the reported warning was in wrong error handling in register_disk(), but we can avoid passing knowingly wrong values to sysfs API, because sysfs error messages can confuse users. For example: user passed 1048576 as index, but sysfs complains about duplicate creation of /dev/block/43:0. It's not obvious how 1048576 becomes 0. Log and reproducer for above example can be found on syzkaller bug report page. Link: https://syzkaller.appspot.com/bug?id=03c2ae9146416edf811958d5fd7acfab75b143d1 Fixes: b0d9111a2d53 ("nbd: use an idr to keep track of nbd devices") Reported-by: syzbot+9937dc42271cd87d4b98@syzkaller.appspotmail.com Reviewed-by: Christoph Hellwig Signed-off-by: Pavel Skripkin Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/nbd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 25e81b1a59a5..bc3ab98855cf 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1744,7 +1744,17 @@ static int nbd_dev_add(int index) refcount_set(&nbd->refs, 1); INIT_LIST_HEAD(&nbd->list); disk->major = NBD_MAJOR; + + /* Too big first_minor can cause duplicate creation of + * sysfs files/links, since first_minor will be truncated to + * byte in __device_add_disk(). + */ disk->first_minor = index << part_shift; + if (disk->first_minor > 0xff) { + err = -EINVAL; + goto out_free_idr; + } + disk->fops = &nbd_fops; disk->private_data = nbd; sprintf(disk->disk_name, "nbd%d", index); From cc74533a47c9dd03ec38cddcad5361fce63987d6 Mon Sep 17 00:00:00 2001 From: Giovanni Cabiddu Date: Thu, 12 Aug 2021 21:21:10 +0100 Subject: [PATCH 039/150] crypto: qat - use proper type for vf_mask [ Upstream commit 462354d986b6a89c6449b85f17aaacf44e455216 ] Replace vf_mask type with unsigned long to avoid a stack-out-of-bound. This is to fix the following warning reported by KASAN the first time adf_msix_isr_ae() gets called. [ 692.091987] BUG: KASAN: stack-out-of-bounds in find_first_bit+0x28/0x50 [ 692.092017] Read of size 8 at addr ffff88afdf789e60 by task swapper/32/0 [ 692.092076] Call Trace: [ 692.092089] [ 692.092101] dump_stack+0x9c/0xcf [ 692.092132] print_address_description.constprop.0+0x18/0x130 [ 692.092164] ? find_first_bit+0x28/0x50 [ 692.092185] kasan_report.cold+0x7f/0x111 [ 692.092213] ? static_obj+0x10/0x80 [ 692.092234] ? find_first_bit+0x28/0x50 [ 692.092262] find_first_bit+0x28/0x50 [ 692.092288] adf_msix_isr_ae+0x16e/0x230 [intel_qat] Fixes: ed8ccaef52fa ("crypto: qat - Add support for SRIOV") Signed-off-by: Giovanni Cabiddu Reviewed-by: Marco Chiappero Reviewed-by: Fiona Trahe Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_isr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c index 4898ef41fd9f..7d319c5c071c 100644 --- a/drivers/crypto/qat/qat_common/adf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_isr.c @@ -59,6 +59,8 @@ #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" +#define ADF_MAX_NUM_VFS 32 + static int adf_enable_msix(struct adf_accel_dev *accel_dev) { struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; @@ -111,7 +113,7 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr) struct adf_bar *pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; void __iomem *pmisc_bar_addr = pmisc->virt_addr; - u32 vf_mask; + unsigned long vf_mask; /* Get the interrupt sources triggered by VFs */ vf_mask = ((ADF_CSR_RD(pmisc_bar_addr, ADF_ERRSOU5) & @@ -132,8 +134,7 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr) * unless the VF is malicious and is attempting to * flood the host OS with VF2PF interrupts. */ - for_each_set_bit(i, (const unsigned long *)&vf_mask, - (sizeof(vf_mask) * BITS_PER_BYTE)) { + for_each_set_bit(i, &vf_mask, ADF_MAX_NUM_VFS) { vf_info = accel_dev->pf.vf_info + i; if (!__ratelimit(&vf_info->vf2pf_ratelimit)) { From 013177ccc4c5d1a2437545655d912d2844bd64db Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 29 Jun 2021 17:34:20 -0400 Subject: [PATCH 040/150] certs: Trigger creation of RSA module signing key if it's not an RSA key [ Upstream commit ea35e0d5df6c92fa2e124bb1b91d09b2240715ba ] Address a kbuild issue where a developer created an ECDSA key for signing kernel modules and then builds an older version of the kernel, when bi- secting the kernel for example, that does not support ECDSA keys. If openssl is installed, trigger the creation of an RSA module signing key if it is not an RSA key. Fixes: cfc411e7fff3 ("Move certificate handling to its own directory") Cc: David Howells Cc: David Woodhouse Signed-off-by: Stefan Berger Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Sasha Levin --- certs/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/certs/Makefile b/certs/Makefile index f4b90bad8690..2baef6fba029 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -46,11 +46,19 @@ endif redirect_openssl = 2>&1 quiet_redirect_openssl = 2>&1 silent_redirect_openssl = 2>/dev/null +openssl_available = $(shell openssl help 2>/dev/null && echo yes) # We do it this way rather than having a boolean option for enabling an # external private key, because 'make randconfig' might enable such a # boolean option and we unfortunately can't make it depend on !RANDCONFIG. ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem") + +ifeq ($(openssl_available),yes) +X509TEXT=$(shell openssl x509 -in "certs/signing_key.pem" -text 2>/dev/null) + +$(if $(findstring rsaEncryption,$(X509TEXT)),,$(shell rm -f "certs/signing_key.pem")) +endif + $(obj)/signing_key.pem: $(obj)/x509.genkey @$(kecho) "###" @$(kecho) "### Now generating an X.509 key pair to be used for signing modules." From d255d6a6457f4f801db4202862ca23a6af7e3dfe Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 25 Aug 2021 11:37:03 +0800 Subject: [PATCH 041/150] regulator: vctrl: Use locked regulator_get_voltage in probe path [ Upstream commit 98e47570ba985f2310586c80409238200fa3170f ] In commit e9153311491d ("regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage"), all calls to get/set the voltage of the control regulator were switched to unlocked versions to avoid deadlocks. However, the call in the probe path is done without regulator locks held. In this case the locked version should be used. Switch back to the locked regulator_get_voltage() in the probe path to avoid any mishaps. Fixes: e9153311491d ("regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20210825033704.3307263-2-wenst@chromium.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/vctrl-regulator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c index cbadb1c99679..93d33201ffe0 100644 --- a/drivers/regulator/vctrl-regulator.c +++ b/drivers/regulator/vctrl-regulator.c @@ -490,7 +490,8 @@ static int vctrl_probe(struct platform_device *pdev) if (ret) return ret; - ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev); + /* Use locked consumer API when not in regulator framework */ + ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg); if (ctrl_uV < 0) { dev_err(&pdev->dev, "failed to get control voltage\n"); return ctrl_uV; From 1f70517eac57fbc0b4cedab0b7aab8f653d733c7 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 25 Aug 2021 11:37:04 +0800 Subject: [PATCH 042/150] regulator: vctrl: Avoid lockdep warning in enable/disable ops [ Upstream commit 21e39809fd7c4b8ff3662f23e0168e87594c8ca8 ] vctrl_enable() and vctrl_disable() call regulator_enable() and regulator_disable(), respectively. However, vctrl_* are regulator ops and should not be calling the locked regulator APIs. Doing so results in a lockdep warning. Instead of exporting more internal regulator ops, model the ctrl supply as an actual supply to vctrl-regulator. At probe time this driver still needs to use the consumer API to fetch its constraints, but otherwise lets the regulator core handle the upstream supply for it. The enable/disable/is_enabled ops are not removed, but now only track state internally. This preserves the original behavior with the ops being available, but one could argue that the original behavior was already incorrect: the internal state would not match the upstream supply if that supply had another consumer that enabled the supply, while vctrl-regulator was not enabled. The lockdep warning is as follows: WARNING: possible circular locking dependency detected 5.14.0-rc6 #2 Not tainted ------------------------------------------------------ swapper/0/1 is trying to acquire lock: ffffffc011306d00 (regulator_list_mutex){+.+.}-{3:3}, at: regulator_lock_dependent (arch/arm64/include/asm/current.h:19 include/linux/ww_mutex.h:111 drivers/regulator/core.c:329) but task is already holding lock: ffffff8004a77160 (regulator_ww_class_mutex){+.+.}-{3:3}, at: regulator_lock_recursive (drivers/regulator/core.c:156 drivers/regulator/core.c:263) which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (regulator_ww_class_mutex){+.+.}-{3:3}: __mutex_lock_common (include/asm-generic/atomic-instrumented.h:606 include/asm-generic/atomic-long.h:29 kernel/locking/mutex.c:103 kernel/locking/mutex.c:144 kernel/locking/mutex.c:963) ww_mutex_lock (kernel/locking/mutex.c:1199) regulator_lock_recursive (drivers/regulator/core.c:156 drivers/regulator/core.c:263) regulator_lock_dependent (drivers/regulator/core.c:343) regulator_enable (drivers/regulator/core.c:2808) set_machine_constraints (drivers/regulator/core.c:1536) regulator_register (drivers/regulator/core.c:5486) devm_regulator_register (drivers/regulator/devres.c:196) reg_fixed_voltage_probe (drivers/regulator/fixed.c:289) platform_probe (drivers/base/platform.c:1427) [...] -> #1 (regulator_ww_class_acquire){+.+.}-{0:0}: regulator_lock_dependent (include/linux/ww_mutex.h:129 drivers/regulator/core.c:329) regulator_enable (drivers/regulator/core.c:2808) set_machine_constraints (drivers/regulator/core.c:1536) regulator_register (drivers/regulator/core.c:5486) devm_regulator_register (drivers/regulator/devres.c:196) reg_fixed_voltage_probe (drivers/regulator/fixed.c:289) [...] -> #0 (regulator_list_mutex){+.+.}-{3:3}: __lock_acquire (kernel/locking/lockdep.c:3052 (discriminator 4) kernel/locking/lockdep.c:3174 (discriminator 4) kernel/locking/lockdep.c:3789 (discriminator 4) kernel/locking/lockdep.c:5015 (discriminator 4)) lock_acquire (arch/arm64/include/asm/percpu.h:39 kernel/locking/lockdep.c:438 kernel/locking/lockdep.c:5627) __mutex_lock_common (include/asm-generic/atomic-instrumented.h:606 include/asm-generic/atomic-long.h:29 kernel/locking/mutex.c:103 kernel/locking/mutex.c:144 kernel/locking/mutex.c:963) mutex_lock_nested (kernel/locking/mutex.c:1125) regulator_lock_dependent (arch/arm64/include/asm/current.h:19 include/linux/ww_mutex.h:111 drivers/regulator/core.c:329) regulator_enable (drivers/regulator/core.c:2808) vctrl_enable (drivers/regulator/vctrl-regulator.c:400) _regulator_do_enable (drivers/regulator/core.c:2617) _regulator_enable (drivers/regulator/core.c:2764) regulator_enable (drivers/regulator/core.c:308 drivers/regulator/core.c:2809) _set_opp (drivers/opp/core.c:819 drivers/opp/core.c:1072) dev_pm_opp_set_rate (drivers/opp/core.c:1164) set_target (drivers/cpufreq/cpufreq-dt.c:62) __cpufreq_driver_target (drivers/cpufreq/cpufreq.c:2216 drivers/cpufreq/cpufreq.c:2271) cpufreq_online (drivers/cpufreq/cpufreq.c:1488 (discriminator 2)) cpufreq_add_dev (drivers/cpufreq/cpufreq.c:1563) subsys_interface_register (drivers/base/bus.c:?) cpufreq_register_driver (drivers/cpufreq/cpufreq.c:2819) dt_cpufreq_probe (drivers/cpufreq/cpufreq-dt.c:344) [...] other info that might help us debug this: Chain exists of: regulator_list_mutex --> regulator_ww_class_acquire --> regulator_ww_class_mutex Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(regulator_ww_class_mutex); lock(regulator_ww_class_acquire); lock(regulator_ww_class_mutex); lock(regulator_list_mutex); *** DEADLOCK *** 6 locks held by swapper/0/1: #0: ffffff8002d32188 (&dev->mutex){....}-{3:3}, at: __device_driver_lock (drivers/base/dd.c:1030) #1: ffffffc0111a0520 (cpu_hotplug_lock){++++}-{0:0}, at: cpufreq_register_driver (drivers/cpufreq/cpufreq.c:2792 (discriminator 2)) #2: ffffff8002a8d918 (subsys mutex#9){+.+.}-{3:3}, at: subsys_interface_register (drivers/base/bus.c:1033) #3: ffffff800341bb90 (&policy->rwsem){+.+.}-{3:3}, at: cpufreq_online (include/linux/bitmap.h:285 include/linux/cpumask.h:405 drivers/cpufreq/cpufreq.c:1399) #4: ffffffc011f0b7b8 (regulator_ww_class_acquire){+.+.}-{0:0}, at: regulator_enable (drivers/regulator/core.c:2808) #5: ffffff8004a77160 (regulator_ww_class_mutex){+.+.}-{3:3}, at: regulator_lock_recursive (drivers/regulator/core.c:156 drivers/regulator/core.c:263) stack backtrace: CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc6 #2 7c8f8996d021ed0f65271e6aeebf7999de74a9fa Hardware name: Google Scarlet (DT) Call trace: dump_backtrace (arch/arm64/kernel/stacktrace.c:161) show_stack (arch/arm64/kernel/stacktrace.c:218) dump_stack_lvl (lib/dump_stack.c:106 (discriminator 2)) dump_stack (lib/dump_stack.c:113) print_circular_bug (kernel/locking/lockdep.c:?) check_noncircular (kernel/locking/lockdep.c:?) __lock_acquire (kernel/locking/lockdep.c:3052 (discriminator 4) kernel/locking/lockdep.c:3174 (discriminator 4) kernel/locking/lockdep.c:3789 (discriminator 4) kernel/locking/lockdep.c:5015 (discriminator 4)) lock_acquire (arch/arm64/include/asm/percpu.h:39 kernel/locking/lockdep.c:438 kernel/locking/lockdep.c:5627) __mutex_lock_common (include/asm-generic/atomic-instrumented.h:606 include/asm-generic/atomic-long.h:29 kernel/locking/mutex.c:103 kernel/locking/mutex.c:144 kernel/locking/mutex.c:963) mutex_lock_nested (kernel/locking/mutex.c:1125) regulator_lock_dependent (arch/arm64/include/asm/current.h:19 include/linux/ww_mutex.h:111 drivers/regulator/core.c:329) regulator_enable (drivers/regulator/core.c:2808) vctrl_enable (drivers/regulator/vctrl-regulator.c:400) _regulator_do_enable (drivers/regulator/core.c:2617) _regulator_enable (drivers/regulator/core.c:2764) regulator_enable (drivers/regulator/core.c:308 drivers/regulator/core.c:2809) _set_opp (drivers/opp/core.c:819 drivers/opp/core.c:1072) dev_pm_opp_set_rate (drivers/opp/core.c:1164) set_target (drivers/cpufreq/cpufreq-dt.c:62) __cpufreq_driver_target (drivers/cpufreq/cpufreq.c:2216 drivers/cpufreq/cpufreq.c:2271) cpufreq_online (drivers/cpufreq/cpufreq.c:1488 (discriminator 2)) cpufreq_add_dev (drivers/cpufreq/cpufreq.c:1563) subsys_interface_register (drivers/base/bus.c:?) cpufreq_register_driver (drivers/cpufreq/cpufreq.c:2819) dt_cpufreq_probe (drivers/cpufreq/cpufreq-dt.c:344) [...] Reported-by: Brian Norris Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking") Fixes: e9153311491d ("regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20210825033704.3307263-3-wenst@chromium.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/vctrl-regulator.c | 72 +++++++++++++++++------------ 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c index 93d33201ffe0..d2a37978fc3a 100644 --- a/drivers/regulator/vctrl-regulator.c +++ b/drivers/regulator/vctrl-regulator.c @@ -37,7 +37,6 @@ struct vctrl_voltage_table { struct vctrl_data { struct regulator_dev *rdev; struct regulator_desc desc; - struct regulator *ctrl_reg; bool enabled; unsigned int min_slew_down_rate; unsigned int ovp_threshold; @@ -82,7 +81,12 @@ static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV) static int vctrl_get_voltage(struct regulator_dev *rdev) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - int ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev); + int ctrl_uV; + + if (!rdev->supply) + return -EPROBE_DEFER; + + ctrl_uV = regulator_get_voltage_rdev(rdev->supply->rdev); return vctrl_calc_output_voltage(vctrl, ctrl_uV); } @@ -92,14 +96,19 @@ static int vctrl_set_voltage(struct regulator_dev *rdev, unsigned int *selector) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - struct regulator *ctrl_reg = vctrl->ctrl_reg; - int orig_ctrl_uV = regulator_get_voltage_rdev(ctrl_reg->rdev); - int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV); + int orig_ctrl_uV; + int uV; int ret; + if (!rdev->supply) + return -EPROBE_DEFER; + + orig_ctrl_uV = regulator_get_voltage_rdev(rdev->supply->rdev); + uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV); + if (req_min_uV >= uV || !vctrl->ovp_threshold) /* voltage rising or no OVP */ - return regulator_set_voltage_rdev(ctrl_reg->rdev, + return regulator_set_voltage_rdev(rdev->supply->rdev, vctrl_calc_ctrl_voltage(vctrl, req_min_uV), vctrl_calc_ctrl_voltage(vctrl, req_max_uV), PM_SUSPEND_ON); @@ -117,7 +126,7 @@ static int vctrl_set_voltage(struct regulator_dev *rdev, next_uV = max_t(int, req_min_uV, uV - max_drop_uV); next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV); - ret = regulator_set_voltage_rdev(ctrl_reg->rdev, + ret = regulator_set_voltage_rdev(rdev->supply->rdev, next_ctrl_uV, next_ctrl_uV, PM_SUSPEND_ON); @@ -134,7 +143,7 @@ static int vctrl_set_voltage(struct regulator_dev *rdev, err: /* Try to go back to original voltage */ - regulator_set_voltage_rdev(ctrl_reg->rdev, orig_ctrl_uV, orig_ctrl_uV, + regulator_set_voltage_rdev(rdev->supply->rdev, orig_ctrl_uV, orig_ctrl_uV, PM_SUSPEND_ON); return ret; @@ -151,16 +160,18 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - struct regulator *ctrl_reg = vctrl->ctrl_reg; unsigned int orig_sel = vctrl->sel; int ret; + if (!rdev->supply) + return -EPROBE_DEFER; + if (selector >= rdev->desc->n_voltages) return -EINVAL; if (selector >= vctrl->sel || !vctrl->ovp_threshold) { /* voltage rising or no OVP */ - ret = regulator_set_voltage_rdev(ctrl_reg->rdev, + ret = regulator_set_voltage_rdev(rdev->supply->rdev, vctrl->vtable[selector].ctrl, vctrl->vtable[selector].ctrl, PM_SUSPEND_ON); @@ -179,7 +190,7 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev, else next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel; - ret = regulator_set_voltage_rdev(ctrl_reg->rdev, + ret = regulator_set_voltage_rdev(rdev->supply->rdev, vctrl->vtable[next_sel].ctrl, vctrl->vtable[next_sel].ctrl, PM_SUSPEND_ON); @@ -202,7 +213,7 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev, err: if (vctrl->sel != orig_sel) { /* Try to go back to original voltage */ - if (!regulator_set_voltage_rdev(ctrl_reg->rdev, + if (!regulator_set_voltage_rdev(rdev->supply->rdev, vctrl->vtable[orig_sel].ctrl, vctrl->vtable[orig_sel].ctrl, PM_SUSPEND_ON)) @@ -234,10 +245,6 @@ static int vctrl_parse_dt(struct platform_device *pdev, u32 pval; u32 vrange_ctrl[2]; - vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl"); - if (IS_ERR(vctrl->ctrl_reg)) - return PTR_ERR(vctrl->ctrl_reg); - ret = of_property_read_u32(np, "ovp-threshold-percent", &pval); if (!ret) { vctrl->ovp_threshold = pval; @@ -315,11 +322,11 @@ static int vctrl_cmp_ctrl_uV(const void *a, const void *b) return at->ctrl - bt->ctrl; } -static int vctrl_init_vtable(struct platform_device *pdev) +static int vctrl_init_vtable(struct platform_device *pdev, + struct regulator *ctrl_reg) { struct vctrl_data *vctrl = platform_get_drvdata(pdev); struct regulator_desc *rdesc = &vctrl->desc; - struct regulator *ctrl_reg = vctrl->ctrl_reg; struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl; int n_voltages; int ctrl_uV; @@ -395,23 +402,19 @@ static int vctrl_init_vtable(struct platform_device *pdev) static int vctrl_enable(struct regulator_dev *rdev) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - int ret = regulator_enable(vctrl->ctrl_reg); - if (!ret) - vctrl->enabled = true; + vctrl->enabled = true; - return ret; + return 0; } static int vctrl_disable(struct regulator_dev *rdev) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - int ret = regulator_disable(vctrl->ctrl_reg); - if (!ret) - vctrl->enabled = false; + vctrl->enabled = false; - return ret; + return 0; } static int vctrl_is_enabled(struct regulator_dev *rdev) @@ -447,6 +450,7 @@ static int vctrl_probe(struct platform_device *pdev) struct regulator_desc *rdesc; struct regulator_config cfg = { }; struct vctrl_voltage_range *vrange_ctrl; + struct regulator *ctrl_reg; int ctrl_uV; int ret; @@ -461,15 +465,20 @@ static int vctrl_probe(struct platform_device *pdev) if (ret) return ret; + ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl"); + if (IS_ERR(ctrl_reg)) + return PTR_ERR(ctrl_reg); + vrange_ctrl = &vctrl->vrange.ctrl; rdesc = &vctrl->desc; rdesc->name = "vctrl"; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; + rdesc->supply_name = "ctrl"; - if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) || - (regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) { + if ((regulator_get_linear_step(ctrl_reg) == 1) || + (regulator_count_voltages(ctrl_reg) == -EINVAL)) { rdesc->continuous_voltage_range = true; rdesc->ops = &vctrl_ops_cont; } else { @@ -486,12 +495,12 @@ static int vctrl_probe(struct platform_device *pdev) cfg.init_data = init_data; if (!rdesc->continuous_voltage_range) { - ret = vctrl_init_vtable(pdev); + ret = vctrl_init_vtable(pdev, ctrl_reg); if (ret) return ret; /* Use locked consumer API when not in regulator framework */ - ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg); + ctrl_uV = regulator_get_voltage(ctrl_reg); if (ctrl_uV < 0) { dev_err(&pdev->dev, "failed to get control voltage\n"); return ctrl_uV; @@ -514,6 +523,9 @@ static int vctrl_probe(struct platform_device *pdev) } } + /* Drop ctrl-supply here in favor of regulator core managed supply */ + devm_regulator_put(ctrl_reg); + vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg); if (IS_ERR(vctrl->rdev)) { ret = PTR_ERR(vctrl->rdev); From 4206dbc9857bebd1b9beaa5b42ef2df2810ca883 Mon Sep 17 00:00:00 2001 From: Chunyan Zhang Date: Thu, 26 Aug 2021 17:15:46 +0800 Subject: [PATCH 043/150] spi: sprd: Fix the wrong WDG_LOAD_VAL [ Upstream commit 245ca2cc212bb2a078332ec99afbfbb202f44c2d ] Use 50ms as default timeout value and the time clock is 32768HZ. The original value of WDG_LOAD_VAL is not correct, so this patch fixes it. Fixes: ac1775012058 ("spi: sprd: Add the support of restarting the system") Signed-off-by: Chunyan Zhang Link: https://lore.kernel.org/r/20210826091549.2138125-2-zhang.lyra@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-sprd-adi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c index 09f983524d51..e804a3854c35 100644 --- a/drivers/spi/spi-sprd-adi.c +++ b/drivers/spi/spi-sprd-adi.c @@ -102,7 +102,7 @@ #define HWRST_STATUS_WATCHDOG 0xf0 /* Use default timeout 50 ms that converts to watchdog values */ -#define WDG_LOAD_VAL ((50 * 1000) / 32768) +#define WDG_LOAD_VAL ((50 * 32768) / 1000) #define WDG_LOAD_MASK GENMASK(15, 0) #define WDG_UNLOCK_KEY 0xe551 From 32d8a3684bbade1b3a4bc04533e6f3d6cbc4e6eb Mon Sep 17 00:00:00 2001 From: Quanyang Wang Date: Thu, 26 Aug 2021 08:59:30 +0800 Subject: [PATCH 044/150] spi: spi-zynq-qspi: use wait_for_completion_timeout to make zynq_qspi_exec_mem_op not interruptible [ Upstream commit 26cfc0dbe43aae60dc03af27077775244f26c167 ] The function wait_for_completion_interruptible_timeout will return -ERESTARTSYS immediately when receiving SIGKILL signal which is sent by "jffs2_gcd_mtd" during umounting jffs2. This will break the SPI memory operation because the data transmitting may begin before the command or address transmitting completes. Use wait_for_completion_timeout to prevent the process from being interruptible. Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller") Signed-off-by: Quanyang Wang Link: https://lore.kernel.org/r/20210826005930.20572-1-quanyang.wang@windriver.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-zynq-qspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c index 5cf6993ddce5..1ced6eb8b330 100644 --- a/drivers/spi/spi-zynq-qspi.c +++ b/drivers/spi/spi-zynq-qspi.c @@ -533,7 +533,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; } @@ -551,7 +551,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; } @@ -567,7 +567,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; @@ -591,7 +591,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; } From fc9cf222908746dc969fdccfa5a5af44e1a69ad9 Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Wed, 18 Aug 2021 10:57:00 -0700 Subject: [PATCH 045/150] EDAC/i10nm: Fix NVDIMM detection [ Upstream commit 2294a7299f5e51667b841f63c6d69474491753fb ] MCDDRCFG is a per-channel register and uses bit{0,1} to indicate the NVDIMM presence on DIMM slot{0,1}. Current i10nm_edac driver wrongly uses MCDDRCFG as per-DIMM register and fails to detect the NVDIMM. Fix it by reading MCDDRCFG as per-channel register and using its bit{0,1} to check whether the NVDIMM is populated on DIMM slot{0,1}. Fixes: d4dc89d069aa ("EDAC, i10nm: Add a driver for Intel 10nm server processors") Reported-by: Fan Du Tested-by: Wen Jin Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Link: https://lore.kernel.org/r/20210818175701.1611513-2-tony.luck@intel.com Signed-off-by: Sasha Levin --- drivers/edac/i10nm_base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index f72be5f94e6f..29576922df78 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -26,8 +26,8 @@ pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg)) #define I10NM_GET_DIMMMTR(m, i, j) \ readl((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4) -#define I10NM_GET_MCDDRTCFG(m, i, j) \ - readl((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4) +#define I10NM_GET_MCDDRTCFG(m, i) \ + readl((m)->mbase + 0x20970 + (i) * 0x4000) #define I10NM_GET_MCMTR(m, i) \ readl((m)->mbase + 0x20ef8 + (i) * 0x4000) @@ -156,11 +156,11 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci) continue; ndimms = 0; + mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i); for (j = 0; j < I10NM_NUM_DIMMS; j++) { dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0); mtr = I10NM_GET_DIMMMTR(imc, i, j); - mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i, j); edac_dbg(1, "dimmmtr 0x%x mcddrtcfg 0x%x (mc%d ch%d dimm%d)\n", mtr, mcddrtcfg, imc->mc, i, j); From 43282ca83ace5fb4a62b5a41cc147b8e2541b2b2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 8 Jun 2021 14:38:56 +0000 Subject: [PATCH 046/150] drm/panfrost: Fix missing clk_disable_unprepare() on error in panfrost_clk_init() [ Upstream commit f42498705965bd4b026953c1892c686d8b1138e4 ] Fix the missing clk_disable_unprepare() before return from panfrost_clk_init() in the error handling case. Fixes: b681af0bc1cc ("drm: panfrost: add optional bus_clock") Reported-by: Hulk Robot Signed-off-by: Wei Yongjun Reviewed-by: Steven Price Signed-off-by: Steven Price Link: https://patchwork.freedesktop.org/patch/msgid/20210608143856.4154766-1-weiyongjun1@huawei.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/panfrost/panfrost_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index 238fb6d54df4..413bf314a2bc 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -59,7 +59,8 @@ static int panfrost_clk_init(struct panfrost_device *pfdev) if (IS_ERR(pfdev->bus_clock)) { dev_err(pfdev->dev, "get bus_clock failed %ld\n", PTR_ERR(pfdev->bus_clock)); - return PTR_ERR(pfdev->bus_clock); + err = PTR_ERR(pfdev->bus_clock); + goto disable_clock; } if (pfdev->bus_clock) { From b928930530032a1a4acb9cf197d43b8468767983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Wed, 16 Jun 2021 07:13:55 +0200 Subject: [PATCH 047/150] media: TDA1997x: enable EDID support [ Upstream commit ea3e1c36e38810427485f06c2becc1f29e54521d ] Without this patch, the TDA19971 chip's EDID is inactive. EDID never worked with this driver, it was all tested with HDMI signal sources which don't need EDID support. Signed-off-by: Krzysztof Halasa Fixes: 9ac0038db9a7 ("media: i2c: Add TDA1997x HDMI receiver driver") Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/tda1997x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index e43d8327b810..1088161498df 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2233,6 +2233,7 @@ static int tda1997x_core_init(struct v4l2_subdev *sd) /* get initial HDMI status */ state->hdmi_status = io_read(sd, REG_HDMI_FLAGS); + io_write(sd, REG_EDID_ENABLE, EDID_ENABLE_A_EN | EDID_ENABLE_B_EN); return 0; } From 34106f5260158dea7c6044fdcdf1b64973d7a3f5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 8 Feb 2021 15:38:55 +0100 Subject: [PATCH 048/150] soc: rockchip: ROCKCHIP_GRF should not default to y, unconditionally [ Upstream commit 2a1c55d4762dd34a8b0f2e36fb01b7b16b60735b ] Merely enabling CONFIG_COMPILE_TEST should not enable additional code. To fix this, restrict the automatic enabling of ROCKCHIP_GRF to ARCH_ROCKCHIP, and ask the user in case of compile-testing. Fixes: 4c58063d4258f6be ("soc: rockchip: add driver handling grf setup") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210208143855.418374-1-geert+renesas@glider.be Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- drivers/soc/rockchip/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig index b71b73bf5fc5..785990720479 100644 --- a/drivers/soc/rockchip/Kconfig +++ b/drivers/soc/rockchip/Kconfig @@ -6,8 +6,8 @@ if ARCH_ROCKCHIP || COMPILE_TEST # config ROCKCHIP_GRF - bool - default y + bool "Rockchip General Register Files support" if COMPILE_TEST + default y if ARCH_ROCKCHIP help The General Register Files are a central component providing special additional settings registers for a lot of soc-components. From 9a193caf9d7977bbf58441da4e4a2af73f2e97a5 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 10 Jun 2021 21:54:31 +0200 Subject: [PATCH 049/150] media: cxd2880-spi: Fix an error handling path [ Upstream commit dcb0145821017e929a733e2271c85c6f82b9c9f8 ] If an error occurs after a successful 'regulator_enable()' call, 'regulator_disable()' must be called. Fix the error handling path of the probe accordingly. Fixes: cb496cd472af ("media: cxd2880-spi: Add optional vcc regulator") Signed-off-by: Christophe JAILLET Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/spi/cxd2880-spi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c index 4077217777f9..93194f03764d 100644 --- a/drivers/media/spi/cxd2880-spi.c +++ b/drivers/media/spi/cxd2880-spi.c @@ -524,13 +524,13 @@ cxd2880_spi_probe(struct spi_device *spi) if (IS_ERR(dvb_spi->vcc_supply)) { if (PTR_ERR(dvb_spi->vcc_supply) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; - goto fail_adapter; + goto fail_regulator; } dvb_spi->vcc_supply = NULL; } else { ret = regulator_enable(dvb_spi->vcc_supply); if (ret) - goto fail_adapter; + goto fail_regulator; } dvb_spi->spi = spi; @@ -618,6 +618,9 @@ fail_frontend: fail_attach: dvb_unregister_adapter(&dvb_spi->adapter); fail_adapter: + if (!dvb_spi->vcc_supply) + regulator_disable(dvb_spi->vcc_supply); +fail_regulator: kfree(dvb_spi); return ret; } From fa4802c54e69430304e61ddb13d69ebd4724f8c5 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 14 Jul 2021 21:43:17 +0900 Subject: [PATCH 050/150] bpf: Fix a typo of reuseport map in bpf.h. [ Upstream commit f170acda7ffaf0473d06e1e17c12cd9fd63904f5 ] Fix s/BPF_MAP_TYPE_REUSEPORT_ARRAY/BPF_MAP_TYPE_REUSEPORT_SOCKARRAY/ typo in bpf.h. Fixes: 2dbb9b9e6df6 ("bpf: Introduce BPF_PROG_TYPE_SK_REUSEPORT") Signed-off-by: Kuniyuki Iwashima Signed-off-by: Alexei Starovoitov Acked-by: Martin KaFai Lau Acked-by: John Fastabend Link: https://lore.kernel.org/bpf/20210714124317.67526-1-kuniyu@amazon.co.jp Signed-off-by: Sasha Levin --- include/uapi/linux/bpf.h | 2 +- tools/include/uapi/linux/bpf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 8649422e760c..63038eb23560 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2264,7 +2264,7 @@ union bpf_attr { * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags) * Description * Select a **SO_REUSEPORT** socket from a - * **BPF_MAP_TYPE_REUSEPORT_ARRAY** *map*. + * **BPF_MAP_TYPE_REUSEPORT_SOCKARRAY** *map*. * It checks the selected socket is matching the incoming * request in the socket buffer. * Return diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 8649422e760c..63038eb23560 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -2264,7 +2264,7 @@ union bpf_attr { * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags) * Description * Select a **SO_REUSEPORT** socket from a - * **BPF_MAP_TYPE_REUSEPORT_ARRAY** *map*. + * **BPF_MAP_TYPE_REUSEPORT_SOCKARRAY** *map*. * It checks the selected socket is matching the incoming * request in the socket buffer. * Return From 004778bf390a20e9483bf3c170434deddc6a20bf Mon Sep 17 00:00:00 2001 From: He Fengqing Date: Wed, 14 Jul 2021 10:18:15 +0000 Subject: [PATCH 051/150] bpf: Fix potential memleak and UAF in the verifier. [ Upstream commit 75f0fc7b48ad45a2e5736bcf8de26c8872fe8695 ] In bpf_patch_insn_data(), we first use the bpf_patch_insn_single() to insert new instructions, then use adjust_insn_aux_data() to adjust insn_aux_data. If the old env->prog have no enough room for new inserted instructions, we use bpf_prog_realloc to construct new_prog and free the old env->prog. There have two errors here. First, if adjust_insn_aux_data() return ENOMEM, we should free the new_prog. Second, if adjust_insn_aux_data() return ENOMEM, bpf_patch_insn_data() will return NULL, and env->prog has been freed in bpf_prog_realloc, but we will use it in bpf_check(). So in this patch, we make the adjust_insn_aux_data() never fails. In bpf_patch_insn_data(), we first pre-malloc memory for the new insn_aux_data, then call bpf_patch_insn_single() to insert new instructions, at last call adjust_insn_aux_data() to adjust insn_aux_data. Fixes: 8041902dae52 ("bpf: adjust insn_aux_data when patching insns") Signed-off-by: He Fengqing Signed-off-by: Alexei Starovoitov Acked-by: Song Liu Link: https://lore.kernel.org/bpf/20210714101815.164322-1-hefengqing@huawei.com Signed-off-by: Sasha Levin --- kernel/bpf/verifier.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 4deaf15b7618..80b219d27e37 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8401,10 +8401,11 @@ static void convert_pseudo_ld_imm64(struct bpf_verifier_env *env) * insni[off, off + cnt). Adjust corresponding insn_aux_data by copying * [0, off) and [off, end) to new locations, so the patched range stays zero */ -static int adjust_insn_aux_data(struct bpf_verifier_env *env, - struct bpf_prog *new_prog, u32 off, u32 cnt) +static void adjust_insn_aux_data(struct bpf_verifier_env *env, + struct bpf_insn_aux_data *new_data, + struct bpf_prog *new_prog, u32 off, u32 cnt) { - struct bpf_insn_aux_data *new_data, *old_data = env->insn_aux_data; + struct bpf_insn_aux_data *old_data = env->insn_aux_data; struct bpf_insn *insn = new_prog->insnsi; bool old_seen = old_data[off].seen; u32 prog_len; @@ -8417,12 +8418,9 @@ static int adjust_insn_aux_data(struct bpf_verifier_env *env, old_data[off].zext_dst = insn_has_def32(env, insn + off + cnt - 1); if (cnt == 1) - return 0; + return; prog_len = new_prog->len; - new_data = vzalloc(array_size(prog_len, - sizeof(struct bpf_insn_aux_data))); - if (!new_data) - return -ENOMEM; + memcpy(new_data, old_data, sizeof(struct bpf_insn_aux_data) * off); memcpy(new_data + off + cnt - 1, old_data + off, sizeof(struct bpf_insn_aux_data) * (prog_len - off - cnt + 1)); @@ -8433,7 +8431,6 @@ static int adjust_insn_aux_data(struct bpf_verifier_env *env, } env->insn_aux_data = new_data; vfree(old_data); - return 0; } static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len) @@ -8454,6 +8451,14 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of const struct bpf_insn *patch, u32 len) { struct bpf_prog *new_prog; + struct bpf_insn_aux_data *new_data = NULL; + + if (len > 1) { + new_data = vzalloc(array_size(env->prog->len + len - 1, + sizeof(struct bpf_insn_aux_data))); + if (!new_data) + return NULL; + } new_prog = bpf_patch_insn_single(env->prog, off, patch, len); if (IS_ERR(new_prog)) { @@ -8461,10 +8466,10 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of verbose(env, "insn %d cannot be patched due to 16-bit range\n", env->insn_aux_data[off].orig_idx); + vfree(new_data); return NULL; } - if (adjust_insn_aux_data(env, new_prog, off, len)) - return NULL; + adjust_insn_aux_data(env, new_data, new_prog, off, len); adjust_subprog_starts(env, off, len); return new_prog; } From 6c106c73208a9ac6a4e4e8a63f21c5447f13e817 Mon Sep 17 00:00:00 2001 From: Dylan Hung Date: Thu, 29 Oct 2020 14:27:23 +0800 Subject: [PATCH 052/150] ARM: dts: aspeed-g6: Fix HVI3C function-group in pinctrl dtsi [ Upstream commit 8c295b7f3d01359ff4336fcb6e406e6ed37957d6 ] The HVI3C shall be a group of I3C function, not an independent function. Correct the function name from "HVI3C" to "I3C". Signed-off-by: Dylan Hung Reviewed-by: Andrew Jeffery Fixes: f510f04c8c83 ("ARM: dts: aspeed: Add AST2600 pinmux nodes") Link: https://lore.kernel.org/r/20201029062723.20798-1-dylan_hung@aspeedtech.com Signed-off-by: Joel Stanley Signed-off-by: Sasha Levin --- arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi index 5b8bf58e89cb..996e006e06c2 100644 --- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi +++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi @@ -208,12 +208,12 @@ }; pinctrl_hvi3c3_default: hvi3c3_default { - function = "HVI3C3"; + function = "I3C3"; groups = "HVI3C3"; }; pinctrl_hvi3c4_default: hvi3c4_default { - function = "HVI3C4"; + function = "I3C4"; groups = "HVI3C4"; }; From 5b3987f583254a55c6242558df1629c9280188c5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 1 Jul 2021 12:15:50 +0200 Subject: [PATCH 053/150] arm64: dts: renesas: r8a77995: draak: Remove bogus adv7511w properties [ Upstream commit 4ec82a7bb3db8c6005e715c63224c32d458917a2 ] The "max-clock" and "min-vrefresh" properties fail to validate with commit cfe34bb7a770c5d8 ("dt-bindings: drm: bridge: adi,adv7511.txt: convert to yaml"). Drop them, as they are parts of an out-of-tree workaround that is not needed upstream. Fixes: bcf3003438ea4645 ("arm64: dts: renesas: r8a77995: draak: Enable HDMI display output") Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Reviewed-by: Ulrich Hecht Link: https://lore.kernel.org/r/975b6686bc423421b147d367fe7fb9a0db99c5af.1625134398.git.geert+renesas@glider.be Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index 67634cb01d6b..cbdd46ed3ca6 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -277,10 +277,6 @@ interrupt-parent = <&gpio1>; interrupts = <28 IRQ_TYPE_LEVEL_LOW>; - /* Depends on LVDS */ - max-clock = <135000000>; - min-vrefresh = <50>; - adi,input-depth = <8>; adi,input-colorspace = "rgb"; adi,input-clock = "1x"; From f81c89614ee890cbf30ccf67169ae60a6d3b923d Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 2 Jul 2021 17:54:15 -0700 Subject: [PATCH 054/150] soc: qcom: rpmhpd: Use corner in power_off [ Upstream commit d43b3a989bc8c06fd4bbb69a7500d180db2d68e8 ] rpmhpd_aggregate_corner() takes a corner as parameter, but in rpmhpd_power_off() the code requests the level of the first corner instead. In all (known) current cases the first corner has level 0, so this change should be a nop, but in case that there's a power domain with a non-zero lowest level this makes sure that rpmhpd_power_off() actually requests the lowest level - which is the closest to "power off" we can get. While touching the code, also skip the unnecessary zero-initialization of "ret". Fixes: 279b7e8a62cc ("soc: qcom: rpmhpd: Add RPMh power domain driver") Reviewed-by: Rajendra Nayak Reviewed-by: Stephen Boyd Reviewed-by: Sibi Sankar Tested-by: Sibi Sankar Link: https://lore.kernel.org/r/20210703005416.2668319-2-bjorn.andersson@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/soc/qcom/rpmhpd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index 51850cc68b70..aa24237a7840 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -235,12 +235,11 @@ static int rpmhpd_power_on(struct generic_pm_domain *domain) static int rpmhpd_power_off(struct generic_pm_domain *domain) { struct rpmhpd *pd = domain_to_rpmhpd(domain); - int ret = 0; + int ret; mutex_lock(&rpmhpd_lock); - ret = rpmhpd_aggregate_corner(pd, pd->level[0]); - + ret = rpmhpd_aggregate_corner(pd, 0); if (!ret) pd->enabled = false; From 88933f9c93a00c940f97bdbc9ad7bb425b8c69c8 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Fri, 25 Jun 2021 07:33:27 +0200 Subject: [PATCH 055/150] media: dvb-usb: fix uninit-value in dvb_usb_adapter_dvb_init [ Upstream commit c5453769f77ce19a5b03f1f49946fd3f8a374009 ] If dibusb_read_eeprom_byte fails, the mac address is not initialized. And nova_t_read_mac_address does not handle this failure, which leads to the uninit-value in dvb_usb_adapter_dvb_init. Fix this by handling the failure of dibusb_read_eeprom_byte. Reported-by: syzbot+e27b4fd589762b0b9329@syzkaller.appspotmail.com Fixes: 786baecfe78f ("[media] dvb-usb: move it to drivers/media/usb/dvb-usb") Signed-off-by: Dongliang Mu Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/dvb-usb/nova-t-usb2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c index e368935a5089..c16d4f162495 100644 --- a/drivers/media/usb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/usb/dvb-usb/nova-t-usb2.c @@ -130,7 +130,7 @@ ret: static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) { - int i; + int i, ret; u8 b; mac[0] = 0x00; @@ -139,7 +139,9 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) /* this is a complete guess, but works for my box */ for (i = 136; i < 139; i++) { - dibusb_read_eeprom_byte(d,i, &b); + ret = dibusb_read_eeprom_byte(d, i, &b); + if (ret) + return ret; mac[5 - (i - 136)] = b; } From fa8aaa769092b0836e579fa4a7ce90f315f317a0 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Fri, 25 Jun 2021 07:59:04 +0200 Subject: [PATCH 056/150] media: dvb-usb: fix uninit-value in vp702x_read_mac_addr [ Upstream commit 797c061ad715a9a1480eb73f44b6939fbe3209ed ] If vp702x_usb_in_op fails, the mac address is not initialized. And vp702x_read_mac_addr does not handle this failure, which leads to the uninit-value in dvb_usb_adapter_dvb_init. Fix this by handling the failure of vp702x_usb_in_op. Fixes: 786baecfe78f ("[media] dvb-usb: move it to drivers/media/usb/dvb-usb") Signed-off-by: Dongliang Mu Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/dvb-usb/vp702x.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c index 381b5c898a07..b7ee972455e5 100644 --- a/drivers/media/usb/dvb-usb/vp702x.c +++ b/drivers/media/usb/dvb-usb/vp702x.c @@ -291,16 +291,22 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) { u8 i, *buf; + int ret; struct vp702x_device_state *st = d->priv; mutex_lock(&st->buf_mutex); buf = st->buf; - for (i = 6; i < 12; i++) - vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1); + for (i = 6; i < 12; i++) { + ret = vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, + &buf[i - 6], 1); + if (ret < 0) + goto err; + } memcpy(mac, buf, 6); +err: mutex_unlock(&st->buf_mutex); - return 0; + return ret; } static int vp702x_frontend_attach(struct dvb_usb_adapter *adap) From 810149287981ce968e59770997a80e0ba7eb9198 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Mon, 21 Jun 2021 07:07:28 +0200 Subject: [PATCH 057/150] media: dvb-usb: Fix error handling in dvb_usb_i2c_init [ Upstream commit 131ae388b88e3daf4cb0721ed4b4cb8bfc201465 ] In dvb_usb_i2c_init, if i2c_add_adapter fails, it only prints an error message, and then continues to set DVB_USB_STATE_I2C. This affects the logic of dvb_usb_i2c_exit, which leads to that, the deletion of i2c_adap even if the i2c_add_adapter fails. Fix this by returning at the failure of i2c_add_adapter and then move dvb_usb_i2c_exit out of the error handling code of dvb_usb_i2c_init. Fixes: 13a79f14ab28 ("media: dvb-usb: Fix memory leak at error in dvb_usb_device_init()") Signed-off-by: Dongliang Mu Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/dvb-usb/dvb-usb-i2c.c | 9 +++++++-- drivers/media/usb/dvb-usb/dvb-usb-init.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/dvb-usb/dvb-usb-i2c.c b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c index 2e07106f4680..bc4b2abdde1a 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c @@ -17,7 +17,8 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) if (d->props.i2c_algo == NULL) { err("no i2c algorithm specified"); - return -EINVAL; + ret = -EINVAL; + goto err; } strscpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); @@ -27,11 +28,15 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) i2c_set_adapdata(&d->i2c_adap, d); - if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0) + ret = i2c_add_adapter(&d->i2c_adap); + if (ret < 0) { err("could not add i2c adapter"); + goto err; + } d->state |= DVB_USB_STATE_I2C; +err: return ret; } diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c index f57c4627624f..e7720ff11d3d 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -194,8 +194,8 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums) err_adapter_init: dvb_usb_adapter_exit(d); -err_i2c_init: dvb_usb_i2c_exit(d); +err_i2c_init: if (d->priv && d->props.priv_destroy) d->props.priv_destroy(d); err_priv_init: From 7163014d7d294c90535b9319942de78f80adac3e Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Sun, 20 Jun 2021 21:45:42 +0200 Subject: [PATCH 058/150] media: go7007: remove redundant initialization [ Upstream commit 6f5885a7750545973bf1a942d2f0f129aef0aa06 ] In go7007_alloc() kzalloc() is used for struct go7007 allocation. It means that there is no need in zeroing any members, because kzalloc will take care of it. Removing these reduntant initialization steps increases execution speed a lot: Before: + 86.802 us | go7007_alloc(); After: + 29.595 us | go7007_alloc(); Fixes: 866b8695d67e8 ("Staging: add the go7007 video driver") Signed-off-by: Pavel Skripkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/go7007/go7007-driver.c | 26 ------------------------ 1 file changed, 26 deletions(-) diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c index 153a0c3e3da6..b9302d77d6c8 100644 --- a/drivers/media/usb/go7007/go7007-driver.c +++ b/drivers/media/usb/go7007/go7007-driver.c @@ -691,49 +691,23 @@ struct go7007 *go7007_alloc(const struct go7007_board_info *board, struct device *dev) { struct go7007 *go; - int i; go = kzalloc(sizeof(struct go7007), GFP_KERNEL); if (go == NULL) return NULL; go->dev = dev; go->board_info = board; - go->board_id = 0; go->tuner_type = -1; - go->channel_number = 0; - go->name[0] = 0; mutex_init(&go->hw_lock); init_waitqueue_head(&go->frame_waitq); spin_lock_init(&go->spinlock); go->status = STATUS_INIT; - memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter)); - go->i2c_adapter_online = 0; - go->interrupt_available = 0; init_waitqueue_head(&go->interrupt_waitq); - go->input = 0; go7007_update_board(go); - go->encoder_h_halve = 0; - go->encoder_v_halve = 0; - go->encoder_subsample = 0; go->format = V4L2_PIX_FMT_MJPEG; go->bitrate = 1500000; go->fps_scale = 1; - go->pali = 0; go->aspect_ratio = GO7007_RATIO_1_1; - go->gop_size = 0; - go->ipb = 0; - go->closed_gop = 0; - go->repeat_seqhead = 0; - go->seq_header_enable = 0; - go->gop_header_enable = 0; - go->dvd_mode = 0; - go->interlace_coding = 0; - for (i = 0; i < 4; ++i) - go->modet[i].enable = 0; - for (i = 0; i < 1624; ++i) - go->modet_map[i] = 0; - go->audio_deliver = NULL; - go->audio_enabled = 0; return go; } From a96eb96ce4c1515c9ff9ee064c6c9e993e590858 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 19 Jul 2021 16:57:08 +0200 Subject: [PATCH 059/150] media: coda: fix frame_mem_ctrl for YUV420 and YVU420 formats [ Upstream commit 44693d74f5653f82cd7ca0fe730eed0f6b83306a ] The frame memory control register value is currently determined before userspace selects the final capture format and never corrected. Update ctx->frame_mem_ctrl in __coda_start_decoding() to fix decoding into YUV420 or YVU420 capture buffers. Reported-by: Andrej Picej Fixes: 497e6b8559a6 ("media: coda: add sequence initialization work") Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/coda/coda-bit.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 00c7bed3dd57..e6b68be09f8f 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -2023,17 +2023,25 @@ static int __coda_start_decoding(struct coda_ctx *ctx) u32 src_fourcc, dst_fourcc; int ret; - if (!ctx->initialized) { - ret = __coda_decoder_seq_init(ctx); - if (ret < 0) - return ret; - } - q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); src_fourcc = q_data_src->fourcc; dst_fourcc = q_data_dst->fourcc; + if (!ctx->initialized) { + ret = __coda_decoder_seq_init(ctx); + if (ret < 0) + return ret; + } else { + ctx->frame_mem_ctrl &= ~(CODA_FRAME_CHROMA_INTERLEAVE | (0x3 << 9) | + CODA9_FRAME_TILED2LINEAR); + if (dst_fourcc == V4L2_PIX_FMT_NV12 || dst_fourcc == V4L2_PIX_FMT_YUYV) + ctx->frame_mem_ctrl |= CODA_FRAME_CHROMA_INTERLEAVE; + if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP) + ctx->frame_mem_ctrl |= (0x3 << 9) | + ((ctx->use_vdoa) ? 0 : CODA9_FRAME_TILED2LINEAR); + } + coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc); From c4895cf45fd50a1e1fa4152f4cd9e584a806c667 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 25 Jun 2021 18:00:09 +0300 Subject: [PATCH 060/150] Bluetooth: sco: prevent information leak in sco_conn_defer_accept() [ Upstream commit 59da0b38bc2ea570ede23a3332ecb3e7574ce6b2 ] Smatch complains that some of these struct members are not initialized leading to a stack information disclosure: net/bluetooth/sco.c:778 sco_conn_defer_accept() warn: check that 'cp.retrans_effort' doesn't leak information This seems like a valid warning. I've added a default case to fix this issue. Fixes: 2f69a82acf6f ("Bluetooth: Use voice setting in deferred SCO connection request") Signed-off-by: Dan Carpenter Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- net/bluetooth/sco.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index b91d6b440fdf..335264706aae 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -761,6 +761,11 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) cp.max_latency = cpu_to_le16(0xffff); cp.retrans_effort = 0xff; break; + default: + /* use CVSD settings as fallback */ + cp.max_latency = cpu_to_le16(0xffff); + cp.retrans_effort = 0xff; + break; } hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, From bd1cd32caa67e1af9acbf8889863bf0c6b1dca87 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 12 Jul 2021 13:14:40 +0100 Subject: [PATCH 061/150] 6lowpan: iphc: Fix an off-by-one check of array index [ Upstream commit 9af417610b6142e826fd1ee8ba7ff3e9a2133a5a ] The bounds check of id is off-by-one and the comparison should be >= rather >. Currently the WARN_ON_ONCE check does not stop the out of range indexing of &ldev->ctx.table[id] so also add a return path if the bounds are out of range. Addresses-Coverity: ("Illegal address computation"). Fixes: 5609c185f24d ("6lowpan: iphc: add support for stateful compression") Signed-off-by: Colin Ian King Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- net/6lowpan/debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/6lowpan/debugfs.c b/net/6lowpan/debugfs.c index 1c140af06d52..600b9563bfc5 100644 --- a/net/6lowpan/debugfs.c +++ b/net/6lowpan/debugfs.c @@ -170,7 +170,8 @@ static void lowpan_dev_debugfs_ctx_init(struct net_device *dev, struct dentry *root; char buf[32]; - WARN_ON_ONCE(id > LOWPAN_IPHC_CTX_TABLE_SIZE); + if (WARN_ON_ONCE(id >= LOWPAN_IPHC_CTX_TABLE_SIZE)) + return; sprintf(buf, "%d", id); From 252fad3d023484d3f258ebb29979960c345b9e80 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Mon, 13 Jan 2020 22:39:22 +0100 Subject: [PATCH 062/150] netns: protect netns ID lookups with RCU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 2dce224f469f060b9998a5a869151ef83c08ce77 upstream. __peernet2id() can be protected by RCU as it only calls idr_for_each(), which is RCU-safe, and never modifies the nsid table. rtnl_net_dumpid() can also do lockless lookups. It does two nested idr_for_each() calls on nsid tables (one direct call and one indirect call because of rtnl_net_dumpid_one() calling __peernet2id()). The netnsid tables are never updated. Therefore it is safe to not take the nsid_lock and run within an RCU-critical section instead. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Signed-off-by: Håkon Bugge --- net/core/net_namespace.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index c303873496a3..9bf15512601b 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -211,9 +211,9 @@ static int net_eq_idr(int id, void *net, void *peer) return 0; } -/* Should be called with nsid_lock held. If a new id is assigned, the bool alloc - * is set to true, thus the caller knows that the new id must be notified via - * rtnl. +/* Must be called from RCU-critical section or with nsid_lock held. If + * a new id is assigned, the bool alloc is set to true, thus the + * caller knows that the new id must be notified via rtnl. */ static int __peernet2id_alloc(struct net *net, struct net *peer, bool *alloc) { @@ -237,7 +237,7 @@ static int __peernet2id_alloc(struct net *net, struct net *peer, bool *alloc) return NETNSA_NSID_NOT_ASSIGNED; } -/* should be called with nsid_lock held */ +/* Must be called from RCU-critical section or with nsid_lock held */ static int __peernet2id(struct net *net, struct net *peer) { bool no = false; @@ -281,9 +281,10 @@ int peernet2id(struct net *net, struct net *peer) { int id; - spin_lock_bh(&net->nsid_lock); + rcu_read_lock(); id = __peernet2id(net, peer); - spin_unlock_bh(&net->nsid_lock); + rcu_read_unlock(); + return id; } EXPORT_SYMBOL(peernet2id); @@ -962,6 +963,7 @@ struct rtnl_net_dump_cb { int s_idx; }; +/* Runs in RCU-critical section. */ static int rtnl_net_dumpid_one(int id, void *peer, void *data) { struct rtnl_net_dump_cb *net_cb = (struct rtnl_net_dump_cb *)data; @@ -1046,19 +1048,9 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb) goto end; } - spin_lock_bh(&net_cb.tgt_net->nsid_lock); - if (net_cb.fillargs.add_ref && - !net_eq(net_cb.ref_net, net_cb.tgt_net) && - !spin_trylock_bh(&net_cb.ref_net->nsid_lock)) { - spin_unlock_bh(&net_cb.tgt_net->nsid_lock); - err = -EAGAIN; - goto end; - } + rcu_read_lock(); idr_for_each(&net_cb.tgt_net->netns_ids, rtnl_net_dumpid_one, &net_cb); - if (net_cb.fillargs.add_ref && - !net_eq(net_cb.ref_net, net_cb.tgt_net)) - spin_unlock_bh(&net_cb.ref_net->nsid_lock); - spin_unlock_bh(&net_cb.tgt_net->nsid_lock); + rcu_read_unlock(); cb->args[0] = net_cb.idx; end: From 952136275367a77eb2281b9a84da40f7eb58f9fd Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Wed, 21 Jul 2021 01:22:15 +0800 Subject: [PATCH 063/150] drm/amdgpu/acp: Make PM domain really work [ Upstream commit aff890288de2d818e4f83ec40c9315e2d735df07 ] Devices created by mfd_add_hotplug_devices() don't really increase the index of its name, so get_mfd_cell_dev() cannot find any device, hence a NULL dev is passed to pm_genpd_add_device(): [ 56.974926] (NULL device *): amdgpu: device acp_audio_dma.0.auto added to pm domain [ 56.974933] (NULL device *): amdgpu: Failed to add dev to genpd [ 56.974941] [drm:amdgpu_device_ip_init [amdgpu]] *ERROR* hw_init of IP block failed -22 [ 56.975810] amdgpu 0000:00:01.0: amdgpu: amdgpu_device_ip_init failed [ 56.975839] amdgpu 0000:00:01.0: amdgpu: Fatal error during GPU init [ 56.977136] ------------[ cut here ]------------ [ 56.977143] kernel BUG at mm/slub.c:4206! [ 56.977158] invalid opcode: 0000 [#1] SMP NOPTI [ 56.977167] CPU: 1 PID: 1648 Comm: modprobe Not tainted 5.12.0-051200rc8-generic #202104182230 [ 56.977175] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./FM2A68M-HD+, BIOS P5.20 02/13/2019 [ 56.977180] RIP: 0010:kfree+0x3bf/0x410 [ 56.977195] Code: 89 e7 48 d3 e2 f7 da e8 5f 0d 02 00 80 e7 02 75 3e 44 89 ee 4c 89 e7 e8 ef 5f fd ff e9 fa fe ff ff 49 8b 44 24 08 a8 01 75 b7 <0f> 0b 4c 8b 4d b0 48 8b 4d a8 48 89 da 4c 89 e6 41 b8 01 00 00 00 [ 56.977202] RSP: 0018:ffffa48640ff79f0 EFLAGS: 00010246 [ 56.977210] RAX: 0000000000000000 RBX: ffff9286127d5608 RCX: 0000000000000000 [ 56.977215] RDX: 0000000000000000 RSI: ffffffffc099d0fb RDI: ffff9286127d5608 [ 56.977220] RBP: ffffa48640ff7a48 R08: 0000000000000001 R09: 0000000000000001 [ 56.977224] R10: 0000000000000000 R11: ffff9286087d8458 R12: fffff3ae0449f540 [ 56.977229] R13: 0000000000000000 R14: dead000000000122 R15: dead000000000100 [ 56.977234] FS: 00007f9de5929540(0000) GS:ffff928612e80000(0000) knlGS:0000000000000000 [ 56.977240] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 56.977245] CR2: 00007f697dd97160 CR3: 00000001110f0000 CR4: 00000000001506e0 [ 56.977251] Call Trace: [ 56.977261] amdgpu_dm_encoder_destroy+0x1b/0x30 [amdgpu] [ 56.978056] drm_mode_config_cleanup+0x4f/0x2e0 [drm] [ 56.978147] ? kfree+0x3dd/0x410 [ 56.978157] ? drm_managed_release+0xc8/0x100 [drm] [ 56.978232] drm_mode_config_init_release+0xe/0x10 [drm] [ 56.978311] drm_managed_release+0x9d/0x100 [drm] [ 56.978388] devm_drm_dev_init_release+0x4d/0x70 [drm] [ 56.978450] devm_action_release+0x15/0x20 [ 56.978459] release_nodes+0x77/0xc0 [ 56.978469] devres_release_all+0x3f/0x50 [ 56.978477] really_probe+0x245/0x460 [ 56.978485] driver_probe_device+0xe9/0x160 [ 56.978492] device_driver_attach+0xab/0xb0 [ 56.978499] __driver_attach+0x8f/0x150 [ 56.978506] ? device_driver_attach+0xb0/0xb0 [ 56.978513] bus_for_each_dev+0x7e/0xc0 [ 56.978521] driver_attach+0x1e/0x20 [ 56.978528] bus_add_driver+0x135/0x1f0 [ 56.978534] driver_register+0x91/0xf0 [ 56.978540] __pci_register_driver+0x54/0x60 [ 56.978549] amdgpu_init+0x77/0x1000 [amdgpu] [ 56.979246] ? 0xffffffffc0dbc000 [ 56.979254] do_one_initcall+0x48/0x1d0 [ 56.979265] ? kmem_cache_alloc_trace+0x120/0x230 [ 56.979274] ? do_init_module+0x28/0x280 [ 56.979282] do_init_module+0x62/0x280 [ 56.979288] load_module+0x71c/0x7a0 [ 56.979296] __do_sys_finit_module+0xc2/0x120 [ 56.979305] __x64_sys_finit_module+0x1a/0x20 [ 56.979311] do_syscall_64+0x38/0x90 [ 56.979319] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 56.979328] RIP: 0033:0x7f9de54f989d [ 56.979335] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c3 f5 0c 00 f7 d8 64 89 01 48 [ 56.979342] RSP: 002b:00007ffe3c395a28 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 56.979350] RAX: ffffffffffffffda RBX: 0000560df3ef4330 RCX: 00007f9de54f989d [ 56.979355] RDX: 0000000000000000 RSI: 0000560df3a07358 RDI: 000000000000000f [ 56.979360] RBP: 0000000000040000 R08: 0000000000000000 R09: 0000000000000000 [ 56.979365] R10: 000000000000000f R11: 0000000000000246 R12: 0000560df3a07358 [ 56.979369] R13: 0000000000000000 R14: 0000560df3ef4460 R15: 0000560df3ef4330 [ 56.979377] Modules linked in: amdgpu(+) iommu_v2 gpu_sched drm_ttm_helper ttm drm_kms_helper cec rc_core i2c_algo_bit fb_sys_fops syscopyarea sysfillrect sysimgblt nft_counter xt_tcpudp ipt_REJECT nf_reject_ipv4 xt_conntrack iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_mangle iptable_raw iptable_security ip_set nf_tables libcrc32c nfnetlink ip6_tables iptable_filter bpfilter input_leds binfmt_misc edac_mce_amd kvm_amd ccp kvm snd_hda_codec_realtek snd_hda_codec_generic crct10dif_pclmul snd_hda_codec_hdmi ledtrig_audio ghash_clmulni_intel aesni_intel snd_hda_intel snd_intel_dspcfg snd_seq_midi crypto_simd snd_intel_sdw_acpi cryptd snd_hda_codec snd_seq_midi_event snd_rawmidi snd_hda_core snd_hwdep snd_seq fam15h_power k10temp snd_pcm snd_seq_device snd_timer snd mac_hid soundcore sch_fq_codel nct6775 hwmon_vid drm ip_tables x_tables autofs4 dm_mirror dm_region_hash dm_log hid_generic usbhid hid uas usb_storage r8169 crc32_pclmul realtek ahci xhci_pci i2c_piix4 [ 56.979521] xhci_pci_renesas libahci video [ 56.979541] ---[ end trace cb8f6a346f18da7b ]--- Instead of finding MFD hotplugged device by its name, simply iterate over the child devices to avoid the issue. Squash in unused variable removal (Alex) BugLink: https://bugs.launchpad.net/bugs/1920674 Fixes: 25030321ba28 ("drm/amd: add pm domain for ACP IP sub blocks") Signed-off-by: Kai-Heng Feng Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 54 ++++++++++++------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index 82155ac3288a..64ee44c2fdd1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -163,17 +163,28 @@ static int acp_poweron(struct generic_pm_domain *genpd) return 0; } -static struct device *get_mfd_cell_dev(const char *device_name, int r) +static int acp_genpd_add_device(struct device *dev, void *data) { - char auto_dev_name[25]; - struct device *dev; + struct generic_pm_domain *gpd = data; + int ret; - snprintf(auto_dev_name, sizeof(auto_dev_name), - "%s.%d.auto", device_name, r); - dev = bus_find_device_by_name(&platform_bus_type, NULL, auto_dev_name); - dev_info(dev, "device %s added to pm domain\n", auto_dev_name); + ret = pm_genpd_add_device(gpd, dev); + if (ret) + dev_err(dev, "Failed to add dev to genpd %d\n", ret); - return dev; + return ret; +} + +static int acp_genpd_remove_device(struct device *dev, void *data) +{ + int ret; + + ret = pm_genpd_remove_device(dev); + if (ret) + dev_err(dev, "Failed to remove dev from genpd %d\n", ret); + + /* Continue to remove */ + return 0; } /** @@ -184,11 +195,10 @@ static struct device *get_mfd_cell_dev(const char *device_name, int r) */ static int acp_hw_init(void *handle) { - int r, i; + int r; uint64_t acp_base; u32 val = 0; u32 count = 0; - struct device *dev; struct i2s_platform_data *i2s_pdata = NULL; struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -344,15 +354,10 @@ static int acp_hw_init(void *handle) if (r) goto failure; - for (i = 0; i < ACP_DEVS ; i++) { - dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); - r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev); - if (r) { - dev_err(dev, "Failed to add dev to genpd\n"); - goto failure; - } - } - + r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd, + acp_genpd_add_device); + if (r) + goto failure; /* Assert Soft reset of ACP */ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); @@ -413,10 +418,8 @@ failure: */ static int acp_hw_fini(void *handle) { - int i, ret; u32 val = 0; u32 count = 0; - struct device *dev; struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* return early if no ACP */ @@ -461,13 +464,8 @@ static int acp_hw_fini(void *handle) udelay(100); } - for (i = 0; i < ACP_DEVS ; i++) { - dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); - ret = pm_genpd_remove_device(dev); - /* If removal fails, dont giveup and try rest */ - if (ret) - dev_err(dev, "remove dev from genpd failed\n"); - } + device_for_each_child(adev->acp.parent, NULL, + acp_genpd_remove_device); mfd_remove_devices(adev->acp.parent); kfree(adev->acp.acp_res); From 37ed461b52e97591fb83449640929a4b2ad4a0c9 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Thu, 1 Jul 2021 13:05:41 -0700 Subject: [PATCH 064/150] tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos [ Upstream commit 525e2f9fd0229eb10cb460a9e6d978257f24804e ] st->bucket stores the current bucket number. st->offset stores the offset within this bucket that is the sk to be seq_show(). Thus, st->offset only makes sense within the same st->bucket. These two variables are an optimization for the common no-lseek case. When resuming the seq_file iteration (i.e. seq_start()), tcp_seek_last_pos() tries to continue from the st->offset at bucket st->bucket. However, it is possible that the bucket pointed by st->bucket has changed and st->offset may end up skipping the whole st->bucket without finding a sk. In this case, tcp_seek_last_pos() currently continues to satisfy the offset condition in the next (and incorrect) bucket. Instead, regardless of the offset value, the first sk of the next bucket should be returned. Thus, "bucket == st->bucket" check is added to tcp_seek_last_pos(). The chance of hitting this is small and the issue is a decade old, so targeting for the next tree. Fixes: a8b690f98baf ("tcp: Fix slowness in read /proc/net/tcp") Signed-off-by: Martin KaFai Lau Signed-off-by: Andrii Nakryiko Reviewed-by: Eric Dumazet Acked-by: Kuniyuki Iwashima Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20210701200541.1033917-1-kafai@fb.com Signed-off-by: Sasha Levin --- net/ipv4/tcp_ipv4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 91788ff19a5d..2ce85e52aea7 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2304,6 +2304,7 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos) static void *tcp_seek_last_pos(struct seq_file *seq) { struct tcp_iter_state *st = seq->private; + int bucket = st->bucket; int offset = st->offset; int orig_num = st->num; void *rc = NULL; @@ -2314,7 +2315,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq) break; st->state = TCP_SEQ_STATE_LISTENING; rc = listening_get_next(seq, NULL); - while (offset-- && rc) + while (offset-- && rc && bucket == st->bucket) rc = listening_get_next(seq, rc); if (rc) break; @@ -2325,7 +2326,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq) if (st->bucket > tcp_hashinfo.ehash_mask) break; rc = established_get_first(seq); - while (offset-- && rc) + while (offset-- && rc && bucket == st->bucket) rc = established_get_next(seq, rc); } From f7058060c01bd3a48ded0300b0f6398e70e1017d Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 11 Jul 2021 23:40:23 +0200 Subject: [PATCH 065/150] ARM: dts: meson8: Use a higher default GPU clock frequency [ Upstream commit 44cf630bcb8c5ec78125805c9447dd5766792224 ] We are seeing "imprecise external abort (0x1406)" errors during boot (which then cause the whole board to hang) on Meson8 (but not Meson8m2). These are observed while trying to access the GPU's registers when the MALI clock is running at it's default setting of 24MHz. The 3.10 vendor kernel uses 318.75MHz as "default" GPU frequency. Using that makes the "imprecise external aborts" go away. Add the assigned-clocks and assigned-clock-rates properties to also bump the MALI clock to 318.75MHz before accessing any of it's registers. Fixes: 7d3f6b536e72c9 ("ARM: dts: meson8: add the Mali-450 MP6 GPU") Reported-by: Demetris Ierokipides Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20210711214023.2163565-1-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- arch/arm/boot/dts/meson8.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index 3efe9d41c2bb..d7c9dbee0f01 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -241,8 +241,13 @@ "pp2", "ppmmu2", "pp4", "ppmmu4", "pp5", "ppmmu5", "pp6", "ppmmu6"; resets = <&reset RESET_MALI>; + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; clock-names = "bus", "core"; + + assigned-clocks = <&clkc CLKID_MALI>; + assigned-clock-rates = <318750000>; + operating-points-v2 = <&gpu_opp_table>; }; }; From 4b0bbc412b510b0668f02f259941468a2e93662f Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Mon, 5 Jul 2021 11:23:53 +0000 Subject: [PATCH 066/150] ARM: dts: meson8b: odroidc1: Fix the pwm regulator supply properties [ Upstream commit 876228e9f935f19c7afc7ba394d17e2ec9143b65 ] After enabling CONFIG_REGULATOR_DEBUG=y we observe below debug logs. Changes help link VCCK and VDDEE pwm regulator to 5V regulator supply instead of dummy regulator. [ 7.117140] pwm-regulator regulator-vcck: Looking up pwm-supply from device tree [ 7.117153] pwm-regulator regulator-vcck: Looking up pwm-supply property in node /regulator-vcck failed [ 7.117184] VCCK: supplied by regulator-dummy [ 7.117194] regulator-dummy: could not add device link regulator.8: -ENOENT [ 7.117266] VCCK: 860 <--> 1140 mV at 986 mV, enabled [ 7.118498] VDDEE: will resolve supply early: pwm [ 7.118515] pwm-regulator regulator-vddee: Looking up pwm-supply from device tree [ 7.118526] pwm-regulator regulator-vddee: Looking up pwm-supply property in node /regulator-vddee failed [ 7.118553] VDDEE: supplied by regulator-dummy [ 7.118563] regulator-dummy: could not add device link regulator.9: -ENOENT Fixes: 524d96083b66 ("ARM: dts: meson8b: odroidc1: add the CPU voltage regulator") Fixes: 8bdf38be712d ("ARM: dts: meson8b: odroidc1: add the VDDEE regulator") Tested-by: Martin Blumenstingl Cc: Martin Blumenstingl Signed-off-by: Anand Moon Reviewed-by: Martin Blumenstingl [narmstrong: fixed typo in commit s/observer/observe/] Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20210705112358.3554-2-linux.amoon@gmail.com Signed-off-by: Sasha Levin --- arch/arm/boot/dts/meson8b-odroidc1.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts index 0f9c71137bed..c413af9a7af8 100644 --- a/arch/arm/boot/dts/meson8b-odroidc1.dts +++ b/arch/arm/boot/dts/meson8b-odroidc1.dts @@ -130,7 +130,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&p5v0>; + pwm-supply = <&p5v0>; pwms = <&pwm_cd 0 12218 0>; pwm-dutycycle-range = <91 0>; @@ -162,7 +162,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&p5v0>; + pwm-supply = <&p5v0>; pwms = <&pwm_cd 1 12218 0>; pwm-dutycycle-range = <91 0>; From e55d7cbe1fe2404bdf5c696bb2ec4db4eecebc09 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Mon, 5 Jul 2021 11:23:54 +0000 Subject: [PATCH 067/150] ARM: dts: meson8b: mxq: Fix the pwm regulator supply properties [ Upstream commit 632062e540becbbcb067523ec8bcadb1239d9578 ] After enabling CONFIG_REGULATOR_DEBUG=y we observer below debug logs. Changes help link VCCK and VDDEE pwm regulator to 5V regulator supply instead of dummy regulator. Add missing pwm-supply for regulator-vcck regulator node. [ 7.117140] pwm-regulator regulator-vcck: Looking up pwm-supply from device tree [ 7.117153] pwm-regulator regulator-vcck: Looking up pwm-supply property in node /regulator-vcck failed [ 7.117184] VCCK: supplied by regulator-dummy [ 7.117194] regulator-dummy: could not add device link regulator.8: -ENOENT [ 7.117266] VCCK: 860 <--> 1140 mV at 986 mV, enabled [ 7.118498] VDDEE: will resolve supply early: pwm [ 7.118515] pwm-regulator regulator-vddee: Looking up pwm-supply from device tree [ 7.118526] pwm-regulator regulator-vddee: Looking up pwm-supply property in node /regulator-vddee failed [ 7.118553] VDDEE: supplied by regulator-dummy [ 7.118563] regulator-dummy: could not add device link regulator.9: -ENOENT Fixes: dee51cd0d2e8 ("ARM: dts: meson8b: mxq: add the VDDEE regulator") Fixes: d94f60e3dfa0 ("ARM: dts: meson8b: mxq: improve support for the TRONFY MXQ S805") Cc: Martin Blumenstingl Signed-off-by: Anand Moon Reviewed-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20210705112358.3554-3-linux.amoon@gmail.com Signed-off-by: Sasha Levin --- arch/arm/boot/dts/meson8b-mxq.dts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/meson8b-mxq.dts b/arch/arm/boot/dts/meson8b-mxq.dts index 6e39ad52e42d..ab8fe55963f7 100644 --- a/arch/arm/boot/dts/meson8b-mxq.dts +++ b/arch/arm/boot/dts/meson8b-mxq.dts @@ -39,6 +39,8 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; + pwm-supply = <&vcc_5v>; + pwms = <&pwm_cd 0 1148 0>; pwm-dutycycle-range = <100 0>; @@ -84,7 +86,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&vcc_5v>; + pwm-supply = <&vcc_5v>; pwms = <&pwm_cd 1 1148 0>; pwm-dutycycle-range = <100 0>; From 87f817c560e63b4b857281e8e5dd8c6be2eb0f34 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Mon, 5 Jul 2021 11:23:55 +0000 Subject: [PATCH 068/150] ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties [ Upstream commit 72ccc373b064ae3ac0c5b5f2306069b60ca118df ] After enabling CONFIG_REGULATOR_DEBUG=y we observer below debug logs. Changes help link VCCK and VDDEE pwm regulator to 5V regulator supply instead of dummy regulator. [ 7.117140] pwm-regulator regulator-vcck: Looking up pwm-supply from device tree [ 7.117153] pwm-regulator regulator-vcck: Looking up pwm-supply property in node /regulator-vcck failed [ 7.117184] VCCK: supplied by regulator-dummy [ 7.117194] regulator-dummy: could not add device link regulator.8: -ENOENT [ 7.117266] VCCK: 860 <--> 1140 mV at 986 mV, enabled [ 7.118498] VDDEE: will resolve supply early: pwm [ 7.118515] pwm-regulator regulator-vddee: Looking up pwm-supply from device tree [ 7.118526] pwm-regulator regulator-vddee: Looking up pwm-supply property in node /regulator-vddee failed [ 7.118553] VDDEE: supplied by regulator-dummy [ 7.118563] regulator-dummy: could not add device link regulator.9: -ENOENT Fixes: 087a1d8b4e4c ("ARM: dts: meson8b: ec100: add the VDDEE regulator") Fixes: 3e7db1c1b7a3 ("ARM: dts: meson8b: ec100: improve the description of the regulators") Cc: Martin Blumenstingl Signed-off-by: Anand Moon Reviewed-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20210705112358.3554-4-linux.amoon@gmail.com Signed-off-by: Sasha Levin --- arch/arm/boot/dts/meson8b-ec100.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/meson8b-ec100.dts b/arch/arm/boot/dts/meson8b-ec100.dts index bed1dfef1985..32d1c322dbc6 100644 --- a/arch/arm/boot/dts/meson8b-ec100.dts +++ b/arch/arm/boot/dts/meson8b-ec100.dts @@ -148,7 +148,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&vcc_5v>; + pwm-supply = <&vcc_5v>; pwms = <&pwm_cd 0 1148 0>; pwm-dutycycle-range = <100 0>; @@ -232,7 +232,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&vcc_5v>; + pwm-supply = <&vcc_5v>; pwms = <&pwm_cd 1 1148 0>; pwm-dutycycle-range = <100 0>; From ffde0581995372cd0322388c99809e07f3c1592a Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Thu, 8 Apr 2021 17:20:04 +0300 Subject: [PATCH 069/150] net/mlx5e: Prohibit inner indir TIRs in IPoIB [ Upstream commit 9c43f3865c2a03be104f1c1d5e9129c2a2bdba88 ] TIR's rx_hash_field_selector_inner can be enabled only when tunneled_offload_en = 1. tunneled_offload_en is filled according to the tunneled_offload_en field in struct mlx5e_params, which is false in the IPoIB profile. On the other hand, the IPoIB profile passes inner_ttc = true to mlx5e_create_indirect_tirs, which potentially allows the latter function to attempt to create inner indirect TIRs without having tunneled_offload_en set. This commit prohibits this behavior by passing inner_ttc = false to mlx5e_create_indirect_tirs. The latter function won't attempt to create inner indirect TIRs. As inner indirect TIRs are not created in the IPoIB profile (this commit blocks it explicitly, and even before they would have failed to be created), the call to mlx5e_create_inner_ttc_table in mlx5i_create_flow_steering is a no-op and can be removed. Fixes: 46dc933cee82 ("net/mlx5e: Provide explicit directive if to create inner indirect tirs") Fixes: 458821c72bd0 ("net/mlx5e: IPoIB, Add inner TTC table to IPoIB flow steering") Signed-off-by: Maxim Mikityanskiy Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- .../net/ethernet/mellanox/mlx5/core/en/fs.h | 6 ------ .../net/ethernet/mellanox/mlx5/core/en_fs.c | 10 +++++----- .../ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 18 ++---------------- 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h index d48292ccda29..9239d767443f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h @@ -234,18 +234,12 @@ struct ttc_params { void mlx5e_set_ttc_basic_params(struct mlx5e_priv *priv, struct ttc_params *ttc_params); void mlx5e_set_ttc_ft_params(struct ttc_params *ttc_params); -void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params); int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, struct mlx5e_ttc_table *ttc); void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv, struct mlx5e_ttc_table *ttc); -int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, - struct mlx5e_ttc_table *ttc); -void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, - struct mlx5e_ttc_table *ttc); - void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft); void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c index c4ac7a9968d1..c3b9278486a1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c @@ -1123,7 +1123,7 @@ void mlx5e_set_ttc_basic_params(struct mlx5e_priv *priv, ttc_params->inner_ttc = &priv->fs.inner_ttc; } -void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params) +static void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params) { struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr; @@ -1142,8 +1142,8 @@ void mlx5e_set_ttc_ft_params(struct ttc_params *ttc_params) ft_attr->prio = MLX5E_NIC_PRIO; } -int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, - struct mlx5e_ttc_table *ttc) +static int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, + struct mlx5e_ttc_table *ttc) { struct mlx5e_flow_table *ft = &ttc->ft; int err; @@ -1173,8 +1173,8 @@ err: return err; } -void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, - struct mlx5e_ttc_table *ttc) +static void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, + struct mlx5e_ttc_table *ttc) { if (!mlx5e_tunnel_inner_ft_supported(priv->mdev)) return; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index 0fed2419623d..1f3d12faa2a5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c @@ -319,17 +319,6 @@ static int mlx5i_create_flow_steering(struct mlx5e_priv *priv) } mlx5e_set_ttc_basic_params(priv, &ttc_params); - mlx5e_set_inner_ttc_ft_params(&ttc_params); - for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) - ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn; - - err = mlx5e_create_inner_ttc_table(priv, &ttc_params, &priv->fs.inner_ttc); - if (err) { - netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n", - err); - goto err_destroy_arfs_tables; - } - mlx5e_set_ttc_ft_params(&ttc_params); for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn; @@ -338,13 +327,11 @@ static int mlx5i_create_flow_steering(struct mlx5e_priv *priv) if (err) { netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n", err); - goto err_destroy_inner_ttc_table; + goto err_destroy_arfs_tables; } return 0; -err_destroy_inner_ttc_table: - mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc); err_destroy_arfs_tables: mlx5e_arfs_destroy_tables(priv); @@ -354,7 +341,6 @@ err_destroy_arfs_tables: static void mlx5i_destroy_flow_steering(struct mlx5e_priv *priv) { mlx5e_destroy_ttc_table(priv, &priv->fs.ttc); - mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc); mlx5e_arfs_destroy_tables(priv); } @@ -379,7 +365,7 @@ static int mlx5i_init_rx(struct mlx5e_priv *priv) if (err) goto err_destroy_indirect_rqts; - err = mlx5e_create_indirect_tirs(priv, true); + err = mlx5e_create_indirect_tirs(priv, false); if (err) goto err_destroy_direct_rqts; From 9fdac650c41314ae02095bdebc5f7bc6ce8a4452 Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Tue, 20 Jul 2021 10:18:27 -0400 Subject: [PATCH 070/150] cgroup/cpuset: Fix a partition bug with hotplug [ Upstream commit 15d428e6fe77fffc3f4fff923336036f5496ef17 ] In cpuset_hotplug_workfn(), the detection of whether the cpu list has been changed is done by comparing the effective cpus of the top cpuset with the cpu_active_mask. However, in the rare case that just all the CPUs in the subparts_cpus are offlined, the detection fails and the partition states are not updated correctly. Fix it by forcing the cpus_updated flag to true in this particular case. Fixes: 4b842da276a8 ("cpuset: Make CPU hotplug work with partition") Signed-off-by: Waiman Long Signed-off-by: Tejun Heo Signed-off-by: Sasha Levin --- kernel/cgroup/cpuset.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index bab6a934862e..badfa8f15359 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -3166,6 +3166,13 @@ static void cpuset_hotplug_workfn(struct work_struct *work) cpus_updated = !cpumask_equal(top_cpuset.effective_cpus, &new_cpus); mems_updated = !nodes_equal(top_cpuset.effective_mems, new_mems); + /* + * In the rare case that hotplug removes all the cpus in subparts_cpus, + * we assumed that cpus are updated. + */ + if (!cpus_updated && top_cpuset.nr_subparts_cpus) + cpus_updated = true; + /* synchronize cpus_allowed to cpu_active_mask */ if (cpus_updated) { spin_lock_irq(&callback_lock); From fba783ddd945aa9f424b2409e73e12e046b529f2 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Tue, 27 Jul 2021 19:35:30 +0300 Subject: [PATCH 071/150] net: cipso: fix warnings in netlbl_cipsov4_add_std [ Upstream commit 8ca34a13f7f9b3fa2c464160ffe8cc1a72088204 ] Syzbot reported warning in netlbl_cipsov4_add(). The problem was in too big doi_def->map.std->lvl.local_size passed to kcalloc(). Since this value comes from userpace there is no need to warn if value is not correct. The same problem may occur with other kcalloc() calls in this function, so, I've added __GFP_NOWARN flag to all kcalloc() calls there. Reported-and-tested-by: syzbot+cdd51ee2e6b0b2e18c0d@syzkaller.appspotmail.com Fixes: 96cb8e3313c7 ("[NetLabel]: CIPSOv4 and Unlabeled packet integration") Acked-by: Paul Moore Signed-off-by: Pavel Skripkin Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/netlabel/netlabel_cipso_v4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 4cb43a2c07d1..8cd3daf0e3db 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -187,14 +187,14 @@ static int netlbl_cipsov4_add_std(struct genl_info *info, } doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size, sizeof(u32), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (doi_def->map.std->lvl.local == NULL) { ret_val = -ENOMEM; goto add_std_failure; } doi_def->map.std->lvl.cipso = kcalloc(doi_def->map.std->lvl.cipso_size, sizeof(u32), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (doi_def->map.std->lvl.cipso == NULL) { ret_val = -ENOMEM; goto add_std_failure; @@ -263,7 +263,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info, doi_def->map.std->cat.local = kcalloc( doi_def->map.std->cat.local_size, sizeof(u32), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (doi_def->map.std->cat.local == NULL) { ret_val = -ENOMEM; goto add_std_failure; @@ -271,7 +271,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info, doi_def->map.std->cat.cipso = kcalloc( doi_def->map.std->cat.cipso_size, sizeof(u32), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (doi_def->map.std->cat.cipso == NULL) { ret_val = -ENOMEM; goto add_std_failure; From e39c73563a381eefdc283ac797f40da4583b1d30 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sun, 30 May 2021 22:13:45 +0300 Subject: [PATCH 072/150] i2c: highlander: add IRQ check [ Upstream commit f16a3bb69aa6baabf8f0aca982c8cf21e2a4f6bc ] The driver is written as if platform_get_irq() returns 0 on errors (while actually it returns a negative error code), blithely passing these error codes to request_irq() (which takes *unsigned* IRQ #) -- which fails with -EINVAL. Add the necessary error check to the pre-existing *if* statement forcing the driver into the polling mode... Fixes: 4ad48e6ab18c ("i2c: Renesas Highlander FPGA SMBus support") Signed-off-by: Sergey Shtylyov Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-highlander.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index ff340d7ae2e5..6a880c262380 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -379,7 +379,7 @@ static int highlander_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dev); dev->irq = platform_get_irq(pdev, 0); - if (iic_force_poll) + if (dev->irq < 0 || iic_force_poll) dev->irq = 0; if (dev->irq) { From 0a01dc77662cfb3c15aea7cbf153c985b65cc6da Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sat, 29 May 2021 14:19:33 +0300 Subject: [PATCH 073/150] leds: lt3593: Put fwnode in any case during ->probe() [ Upstream commit 7e1baaaa2407a642ea19b58e214fab9a69cda1d7 ] device_get_next_child_node() bumps a reference counting of a returned variable. We have to balance it whenever we return to the caller. Fixes: 8cd7d6daba93 ("leds: lt3593: Add device tree probing glue") Cc: Daniel Mack Signed-off-by: Andy Shevchenko Signed-off-by: Pavel Machek Signed-off-by: Sasha Levin --- drivers/leds/leds-lt3593.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index c94995f0daa2..03ae33093ce6 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c @@ -103,10 +103,9 @@ static int lt3593_led_probe(struct platform_device *pdev) init_data.default_label = ":"; ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data); - if (ret < 0) { - fwnode_handle_put(child); + fwnode_handle_put(child); + if (ret < 0) return ret; - } led_data->cdev.dev->of_node = dev->of_node; platform_set_drvdata(pdev, led_data); From ebf570042b5f9614f53f02848d9c0e93485c71f8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 21 Feb 2021 12:52:08 +0100 Subject: [PATCH 074/150] leds: trigger: audio: Add an activate callback to ensure the initial brightness is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 64f67b5240db79eceb0bd57dae8e591fd3103ba0 ] Some 2-in-1s with a detachable (USB) keyboard(dock) have mute-LEDs in the speaker- and/or mic-mute keys on the keyboard. Examples of this are the Lenovo Thinkpad10 tablet (with its USB kbd-dock) and the HP x2 10 series. The detachable nature of these keyboards means that the keyboard and thus the mute LEDs may show up after the user (or userspace restoring old mixer settings) has muted the speaker and/or mic. Current LED-class devices with a default_trigger of "audio-mute" or "audio-micmute" initialize the brightness member of led_classdev with ledtrig_audio_get() before registering the LED. This makes the software state after attaching the keyboard match the actual audio mute state, e.g. cat /sys/class/leds/foo/brightness will show the right value. But before this commit nothing was actually calling the led_classdev's brightness_set[_blocking] callback so the value returned by ledtrig_audio_get() was never actually being sent to the hw, leading to the mute LEDs staying in their default power-on state, after attaching the keyboard, even if ledtrig_audio_get() returned a different state. This could be fixed by having the individual LED drivers call brightness_set[_blocking] themselves after registering the LED, but this really is something which should be done by a led-trigger activate callback. Add an activate callback for this, fixing the issue of the mute LEDs being out of sync after (re)attaching the keyboard. Cc: Takashi Iwai Fixes: faa2541f5b1a ("leds: trigger: Introduce audio mute LED trigger") Reviewed-by: Marek Behún Signed-off-by: Hans de Goede Signed-off-by: Pavel Machek Signed-off-by: Sasha Levin --- drivers/leds/trigger/ledtrig-audio.c | 37 ++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-audio.c b/drivers/leds/trigger/ledtrig-audio.c index f76621e88482..c6b437e6369b 100644 --- a/drivers/leds/trigger/ledtrig-audio.c +++ b/drivers/leds/trigger/ledtrig-audio.c @@ -6,10 +6,33 @@ #include #include #include +#include "../leds.h" -static struct led_trigger *ledtrig_audio[NUM_AUDIO_LEDS]; static enum led_brightness audio_state[NUM_AUDIO_LEDS]; +static int ledtrig_audio_mute_activate(struct led_classdev *led_cdev) +{ + led_set_brightness_nosleep(led_cdev, audio_state[LED_AUDIO_MUTE]); + return 0; +} + +static int ledtrig_audio_micmute_activate(struct led_classdev *led_cdev) +{ + led_set_brightness_nosleep(led_cdev, audio_state[LED_AUDIO_MICMUTE]); + return 0; +} + +static struct led_trigger ledtrig_audio[NUM_AUDIO_LEDS] = { + [LED_AUDIO_MUTE] = { + .name = "audio-mute", + .activate = ledtrig_audio_mute_activate, + }, + [LED_AUDIO_MICMUTE] = { + .name = "audio-micmute", + .activate = ledtrig_audio_micmute_activate, + }, +}; + enum led_brightness ledtrig_audio_get(enum led_audio type) { return audio_state[type]; @@ -19,24 +42,22 @@ EXPORT_SYMBOL_GPL(ledtrig_audio_get); void ledtrig_audio_set(enum led_audio type, enum led_brightness state) { audio_state[type] = state; - led_trigger_event(ledtrig_audio[type], state); + led_trigger_event(&ledtrig_audio[type], state); } EXPORT_SYMBOL_GPL(ledtrig_audio_set); static int __init ledtrig_audio_init(void) { - led_trigger_register_simple("audio-mute", - &ledtrig_audio[LED_AUDIO_MUTE]); - led_trigger_register_simple("audio-micmute", - &ledtrig_audio[LED_AUDIO_MICMUTE]); + led_trigger_register(&ledtrig_audio[LED_AUDIO_MUTE]); + led_trigger_register(&ledtrig_audio[LED_AUDIO_MICMUTE]); return 0; } module_init(ledtrig_audio_init); static void __exit ledtrig_audio_exit(void) { - led_trigger_unregister_simple(ledtrig_audio[LED_AUDIO_MUTE]); - led_trigger_unregister_simple(ledtrig_audio[LED_AUDIO_MICMUTE]); + led_trigger_unregister(&ledtrig_audio[LED_AUDIO_MUTE]); + led_trigger_unregister(&ledtrig_audio[LED_AUDIO_MICMUTE]); } module_exit(ledtrig_audio_exit); From d2ea2f0725cccaf0bc7294a30fc546bc48637cb4 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Wed, 7 Jul 2021 11:34:09 +0200 Subject: [PATCH 075/150] media: em28xx-input: fix refcount bug in em28xx_usb_disconnect [ Upstream commit 6fa54bc713c262e1cfbc5613377ef52280d7311f ] If em28xx_ir_init fails, it would decrease the refcount of dev. However, in the em28xx_ir_fini, when ir is NULL, it goes to ref_put and decrease the refcount of dev. This will lead to a refcount bug. Fix this bug by removing the kref_put in the error handling code of em28xx_ir_init. refcount_t: underflow; use-after-free. WARNING: CPU: 0 PID: 7 at lib/refcount.c:28 refcount_warn_saturate+0x18e/0x1a0 lib/refcount.c:28 Modules linked in: CPU: 0 PID: 7 Comm: kworker/0:1 Not tainted 5.13.0 #3 Workqueue: usb_hub_wq hub_event RIP: 0010:refcount_warn_saturate+0x18e/0x1a0 lib/refcount.c:28 Call Trace: kref_put.constprop.0+0x60/0x85 include/linux/kref.h:69 em28xx_usb_disconnect.cold+0xd7/0xdc drivers/media/usb/em28xx/em28xx-cards.c:4150 usb_unbind_interface+0xbf/0x3a0 drivers/usb/core/driver.c:458 __device_release_driver drivers/base/dd.c:1201 [inline] device_release_driver_internal+0x22a/0x230 drivers/base/dd.c:1232 bus_remove_device+0x108/0x160 drivers/base/bus.c:529 device_del+0x1fe/0x510 drivers/base/core.c:3540 usb_disable_device+0xd1/0x1d0 drivers/usb/core/message.c:1419 usb_disconnect+0x109/0x330 drivers/usb/core/hub.c:2221 hub_port_connect drivers/usb/core/hub.c:5151 [inline] hub_port_connect_change drivers/usb/core/hub.c:5440 [inline] port_event drivers/usb/core/hub.c:5586 [inline] hub_event+0xf81/0x1d40 drivers/usb/core/hub.c:5668 process_one_work+0x2c9/0x610 kernel/workqueue.c:2276 process_scheduled_works kernel/workqueue.c:2338 [inline] worker_thread+0x333/0x5b0 kernel/workqueue.c:2424 kthread+0x188/0x1d0 kernel/kthread.c:319 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 Reported-by: Dongliang Mu Fixes: ac5688637144 ("media: em28xx: Fix possible memory leak of em28xx struct") Signed-off-by: Dongliang Mu Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/em28xx/em28xx-input.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 59529cbf9cd0..0b6d77c3bec8 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -842,7 +842,6 @@ error: kfree(ir); ref_put: em28xx_shutdown_buttons(dev); - kref_put(&dev->ref, em28xx_free_device); return err; } From f865b316ccc6abed1191a3f940c9524b15e7c4ce Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 9 Jul 2021 14:30:25 +0200 Subject: [PATCH 076/150] media: venus: venc: Fix potential null pointer dereference on pointer fmt [ Upstream commit 09ea9719a423fc675d40dd05407165e161ea0c48 ] Currently the call to find_format can potentially return a NULL to fmt and the nullpointer is later dereferenced on the assignment of pixmp->num_planes = fmt->num_planes. Fix this by adding a NULL pointer check and returning NULL for the failure case. Addresses-Coverity: ("Dereference null return") Fixes: aaaa93eda64b ("[media] media: venus: venc: add video encoder files") Signed-off-by: Colin Ian King Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/qcom/venus/venc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 30028ceb548b..766ca497f856 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -308,6 +308,8 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) else return NULL; fmt = find_format(inst, pixmp->pixelformat, f->type); + if (!fmt) + return NULL; } pixmp->width = clamp(pixmp->width, frame_width_min(inst), From 9e570f3d477739ad9d75a260a01d180d7334bb13 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 29 Jul 2021 17:54:28 +0200 Subject: [PATCH 077/150] PCI: PM: Avoid forcing PCI_D0 for wakeup reasons inconsistently [ Upstream commit da9f2150684ea684a7ddd6d7f0e38b2bdf43dcd8 ] It is inconsistent to return PCI_D0 from pci_target_state() instead of the original target state if 'wakeup' is true and the device cannot signal PME from D0. This only happens when the device cannot signal PME from the original target state and any shallower power states (including D0) and that case is effectively equivalent to the one in which PME singaling is not supported at all. Since the original target state is returned in the latter case, make the function do that in the former one too. Link: https://lore.kernel.org/linux-pm/3149540.aeNJFYEL58@kreacher/ Fixes: 666ff6f83e1d ("PCI/PM: Avoid using device_may_wakeup() for runtime PM") Reported-by: Mika Westerberg Reported-by: Utkarsh H Patel Reported-by: Koba Ko Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg Signed-off-by: Sasha Levin --- drivers/pci/pci.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 3c3bc9f58498..9c4ac6face3b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2357,16 +2357,20 @@ static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup) if (dev->current_state == PCI_D3cold) target_state = PCI_D3cold; - if (wakeup) { + if (wakeup && dev->pme_support) { + pci_power_t state = target_state; + /* * Find the deepest state from which the device can generate * PME#. */ - if (dev->pme_support) { - while (target_state - && !(dev->pme_support & (1 << target_state))) - target_state--; - } + while (state && !(dev->pme_support & (1 << state))) + state--; + + if (state) + return state; + else if (dev->pme_support & 1) + return PCI_D0; } return target_state; From e7997fe3e9cafb48621a88567c649530643e1a05 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 29 Jul 2021 16:49:10 +0200 Subject: [PATCH 078/150] PCI: PM: Enable PME if it can be signaled from D3cold [ Upstream commit 0e00392a895c95c6d12d42158236c8862a2f43f2 ] PME signaling is only enabled by __pci_enable_wake() if the target device can signal PME from the given target power state (to avoid pointless reconfiguration of the device), but if the hierarchy above the device goes into D3cold, the device itself will end up in D3cold too, so if it can signal PME from D3cold, it should be enabled to do so in __pci_enable_wake(). [Note that if the device does not end up in D3cold and it cannot signal PME from the original target power state, it will not signal PME, so in that case the behavior does not change.] Link: https://lore.kernel.org/linux-pm/3149540.aeNJFYEL58@kreacher/ Fixes: 5bcc2fb4e815 ("PCI PM: Simplify PCI wake-up code") Reported-by: Mika Westerberg Reported-by: Utkarsh H Patel Reported-by: Koba Ko Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg Signed-off-by: Sasha Levin --- drivers/pci/pci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9c4ac6face3b..58c33b65d451 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2253,7 +2253,14 @@ static int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable if (enable) { int error; - if (pci_pme_capable(dev, state)) + /* + * Enable PME signaling if the device can signal PME from + * D3cold regardless of whether or not it can signal PME from + * the current target state, because that will allow it to + * signal PME when the hierarchy above it goes into D3cold and + * the device itself ends up in D3cold as a result of that. + */ + if (pci_pme_capable(dev, state) || pci_pme_capable(dev, PCI_D3cold)) pci_pme_active(dev, true); else ret = 1; From f44714b4eb2ad2d40f8fecefccd347960a68b112 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 12 Jul 2021 15:57:03 +0200 Subject: [PATCH 079/150] soc: qcom: smsm: Fix missed interrupts if state changes while masked [ Upstream commit e3d4571955050736bbf3eda0a9538a09d9fcfce8 ] The SMSM driver detects interrupt edges by tracking the last state it has seen (and has triggered the interrupt handler for). This works fine, but only if the interrupt does not change state while masked. For example, if an interrupt is unmasked while the state is HIGH, the stored last_value for that interrupt might still be LOW. Then, when the remote processor triggers smsm_intr() we assume that nothing has changed, even though the state might have changed from HIGH to LOW. Attempt to fix this by checking the current remote state before unmasking an IRQ. Use atomic operations to avoid the interrupt handler from interfering with the unmask function. This fixes modem crashes in some edge cases with the BAM-DMUX driver. Specifically, the BAM-DMUX interrupt handler is not called for the HIGH -> LOW smsm state transition if the BAM-DMUX driver is loaded (and therefore unmasks the interrupt) after the modem was already started: qcom-q6v5-mss 4080000.remoteproc: fatal error received: a2_task.c:3188: Assert FALSE failed: A2 DL PER deadlock timer expired waiting for Apps ACK Fixes: c97c4090ff72 ("soc: qcom: smsm: Add driver for Qualcomm SMSM") Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20210712135703.324748-2-stephan@gerhold.net Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/soc/qcom/smsm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index 70c3c90b997c..c428d0f78816 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -109,7 +109,7 @@ struct smsm_entry { DECLARE_BITMAP(irq_enabled, 32); DECLARE_BITMAP(irq_rising, 32); DECLARE_BITMAP(irq_falling, 32); - u32 last_value; + unsigned long last_value; u32 *remote_state; u32 *subscription; @@ -204,8 +204,7 @@ static irqreturn_t smsm_intr(int irq, void *data) u32 val; val = readl(entry->remote_state); - changed = val ^ entry->last_value; - entry->last_value = val; + changed = val ^ xchg(&entry->last_value, val); for_each_set_bit(i, entry->irq_enabled, 32) { if (!(changed & BIT(i))) @@ -266,6 +265,12 @@ static void smsm_unmask_irq(struct irq_data *irqd) struct qcom_smsm *smsm = entry->smsm; u32 val; + /* Make sure our last cached state is up-to-date */ + if (readl(entry->remote_state) & BIT(irq)) + set_bit(irq, &entry->last_value); + else + clear_bit(irq, &entry->last_value); + set_bit(irq, entry->irq_enabled); if (entry->subscription) { From c0faa638f016caca324c8d2bec84fcde658f5472 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 2 Aug 2021 18:24:44 +0200 Subject: [PATCH 080/150] debugfs: Return error during {full/open}_proxy_open() on rmmod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 112cedc8e600b668688eb809bf11817adec58ddc ] If a kernel module gets unloaded then it printed report about a leak before commit 275678e7a9be ("debugfs: Check module state before warning in {full/open}_proxy_open()"). An additional check was added in this commit to avoid this printing. But it was forgotten that the function must return an error in this case because it was not actually opened. As result, the systems started to crash or to hang when a module was unloaded while something was trying to open a file. Fixes: 275678e7a9be ("debugfs: Check module state before warning in {full/open}_proxy_open()") Cc: Taehee Yoo Reported-by: Mário Lopes Signed-off-by: Sven Eckelmann Link: https://lore.kernel.org/r/20210802162444.7848-1-sven@narfation.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- fs/debugfs/file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 943637298f65..a32c5c7dcfd8 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -178,8 +178,10 @@ static int open_proxy_open(struct inode *inode, struct file *filp) if (!fops_get(real_fops)) { #ifdef CONFIG_MODULES if (real_fops->owner && - real_fops->owner->state == MODULE_STATE_GOING) + real_fops->owner->state == MODULE_STATE_GOING) { + r = -ENXIO; goto out; + } #endif /* Huh? Module did not clean up after itself at exit? */ @@ -313,8 +315,10 @@ static int full_proxy_open(struct inode *inode, struct file *filp) if (!fops_get(real_fops)) { #ifdef CONFIG_MODULES if (real_fops->owner && - real_fops->owner->state == MODULE_STATE_GOING) + real_fops->owner->state == MODULE_STATE_GOING) { + r = -ENXIO; goto out; + } #endif /* Huh? Module did not cleanup after itself at exit? */ From 5537dc810b2abf95eea37d96dfe16419c7760ea4 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 4 Aug 2021 16:09:51 +0100 Subject: [PATCH 081/150] Bluetooth: increase BTNAMSIZ to 21 chars to fix potential buffer overflow [ Upstream commit 713baf3dae8f45dc8ada4ed2f5fdcbf94a5c274d ] An earlier commit replaced using batostr to using %pMR sprintf for the construction of session->name. Static analysis detected that this new method can use a total of 21 characters (including the trailing '\0') so we need to increase the BTNAMSIZ from 18 to 21 to fix potential buffer overflows. Addresses-Coverity: ("Out-of-bounds write") Fixes: fcb73338ed53 ("Bluetooth: Use %pMR in sprintf/seq_printf instead of batostr") Signed-off-by: Colin Ian King Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- net/bluetooth/cmtp/cmtp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index c32638dddbf9..f6b9dc4e408f 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h @@ -26,7 +26,7 @@ #include #include -#define BTNAMSIZ 18 +#define BTNAMSIZ 21 /* CMTP ioctl defines */ #define CMTPCONNADD _IOW('C', 200, int) From 156eaacba3d22cb145fbc1062b652b3f969aa40c Mon Sep 17 00:00:00 2001 From: Lukasz Luba Date: Tue, 3 Aug 2021 11:27:43 +0100 Subject: [PATCH 082/150] PM: EM: Increase energy calculation precision [ Upstream commit 7fcc17d0cb12938d2b3507973a6f93fc9ed2c7a1 ] The Energy Model (EM) provides useful information about device power in each performance state to other subsystems like: Energy Aware Scheduler (EAS). The energy calculation in EAS does arithmetic operation based on the EM em_cpu_energy(). Current implementation of that function uses em_perf_state::cost as a pre-computed cost coefficient equal to: cost = power * max_frequency / frequency. The 'power' is expressed in milli-Watts (or in abstract scale). There are corner cases when the EAS energy calculation for two Performance Domains (PDs) return the same value. The EAS compares these values to choose smaller one. It might happen that this values are equal due to rounding error. In such scenario, we need better resolution, e.g. 1000 times better. To provide this possibility increase the resolution in the em_perf_state::cost for 64-bit architectures. The cost of increasing resolution on 32-bit is pretty high (64-bit division) and is not justified since there are no new 32bit big.LITTLE EAS systems expected which would benefit from this higher resolution. This patch allows to avoid the rounding to milli-Watt errors, which might occur in EAS energy estimation for each PD. The rounding error is common for small tasks which have small utilization value. There are two places in the code where it makes a difference: 1. In the find_energy_efficient_cpu() where we are searching for best_delta. We might suffer there when two PDs return the same result, like in the example below. Scenario: Low utilized system e.g. ~200 sum_util for PD0 and ~220 for PD1. There are quite a few small tasks ~10-15 util. These tasks would suffer for the rounding error. These utilization values are typical when running games on Android. One of our partners has reported 5..10mA less battery drain when running with increased resolution. Some details: We have two PDs: PD0 (big) and PD1 (little) Let's compare w/o patch set ('old') and w/ patch set ('new') We are comparing energy w/ task and w/o task placed in the PDs a) 'old' w/o patch set, PD0 task_util = 13 cost = 480 sum_util_w/o_task = 215 sum_util_w_task = 228 scale_cpu = 1024 energy_w/o_task = 480 * 215 / 1024 = 100.78 => 100 energy_w_task = 480 * 228 / 1024 = 106.87 => 106 energy_diff = 106 - 100 = 6 (this is equal to 'old' PD1's energy_diff in 'c)') b) 'new' w/ patch set, PD0 task_util = 13 cost = 480 * 1000 = 480000 sum_util_w/o_task = 215 sum_util_w_task = 228 energy_w/o_task = 480000 * 215 / 1024 = 100781 energy_w_task = 480000 * 228 / 1024 = 106875 energy_diff = 106875 - 100781 = 6094 (this is not equal to 'new' PD1's energy_diff in 'd)') c) 'old' w/o patch set, PD1 task_util = 13 cost = 160 sum_util_w/o_task = 283 sum_util_w_task = 293 scale_cpu = 355 energy_w/o_task = 160 * 283 / 355 = 127.55 => 127 energy_w_task = 160 * 296 / 355 = 133.41 => 133 energy_diff = 133 - 127 = 6 (this is equal to 'old' PD0's energy_diff in 'a)') d) 'new' w/ patch set, PD1 task_util = 13 cost = 160 * 1000 = 160000 sum_util_w/o_task = 283 sum_util_w_task = 293 scale_cpu = 355 energy_w/o_task = 160000 * 283 / 355 = 127549 energy_w_task = 160000 * 296 / 355 = 133408 energy_diff = 133408 - 127549 = 5859 (this is not equal to 'new' PD0's energy_diff in 'b)') 2. Difference in the 6% energy margin filter at the end of find_energy_efficient_cpu(). With this patch the margin comparison also has better resolution, so it's possible to have better task placement thanks to that. Fixes: 27871f7a8a341ef ("PM: Introduce an Energy Model management framework") Reported-by: CCJ Yeh Reviewed-by: Dietmar Eggemann Signed-off-by: Lukasz Luba Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- include/linux/energy_model.h | 16 ++++++++++++++++ kernel/power/energy_model.c | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 73f8c3cb9588..9ee6ccc18424 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -42,6 +42,22 @@ struct em_perf_domain { #define EM_CPU_MAX_POWER 0xFFFF +/* + * Increase resolution of energy estimation calculations for 64-bit + * architectures. The extra resolution improves decision made by EAS for the + * task placement when two Performance Domains might provide similar energy + * estimation values (w/o better resolution the values could be equal). + * + * We increase resolution only if we have enough bits to allow this increased + * resolution (i.e. 64-bit). The costs for increasing resolution when 32-bit + * are pretty high and the returns do not justify the increased costs. + */ +#ifdef CONFIG_64BIT +#define em_scale_power(p) ((p) * 1000) +#else +#define em_scale_power(p) (p) +#endif + struct em_data_callback { /** * active_power() - Provide power at the next capacity state of a CPU diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 8dac32bd9089..7ef35eb985ba 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -149,7 +149,9 @@ static struct em_perf_domain *em_create_pd(cpumask_t *span, int nr_states, /* Compute the cost of each capacity_state. */ fmax = (u64) table[nr_states - 1].frequency; for (i = 0; i < nr_states; i++) { - table[i].cost = div64_u64(fmax * table[i].power, + unsigned long power_res = em_scale_power(table[i].power); + + table[i].cost = div64_u64(fmax * power_res, table[i].frequency); } From 1b6fcd10375a9e69c5d546b3edcbefec902615e4 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 5 Jul 2021 02:05:19 +0300 Subject: [PATCH 083/150] drm/msm/dpu: make dpu_hw_ctl_clear_all_blendstages clear necessary LMs [ Upstream commit a41cdb693595ae1904dd793fc15d6954f4295e27 ] dpu_hw_ctl_clear_all_blendstages() clears settings for the few first LMs instead of mixers actually used for the CTL. Change it to clear necessary data, using provided mixer ids. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20210704230519.4081467-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 179e8d52cadb..a08ca7a47400 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -281,10 +281,12 @@ static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx) int i; for (i = 0; i < ctx->mixer_count; i++) { - DPU_REG_WRITE(c, CTL_LAYER(LM_0 + i), 0); - DPU_REG_WRITE(c, CTL_LAYER_EXT(LM_0 + i), 0); - DPU_REG_WRITE(c, CTL_LAYER_EXT2(LM_0 + i), 0); - DPU_REG_WRITE(c, CTL_LAYER_EXT3(LM_0 + i), 0); + enum dpu_lm mixer_id = ctx->mixer_hw_caps[i].id; + + DPU_REG_WRITE(c, CTL_LAYER(mixer_id), 0); + DPU_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0); + DPU_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0); + DPU_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0); } } From a1194b805c900a0f5fdc077614bec5c471cddb3b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 5 Aug 2021 09:21:10 +0200 Subject: [PATCH 084/150] arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7 [ Upstream commit 01c72cad790cb6cd3ccbe4c1402b6cb6c6bbffd0 ] The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF (by ARM). Reported-by: Sam Protsenko Reported-by: Marc Zyngier Signed-off-by: Krzysztof Kozlowski Reviewed-by: Sam Protsenko Reviewed-by: Alim Akhtar Fixes: b9024cbc937d ("arm64: dts: Add initial device tree support for exynos7") Link: https://lore.kernel.org/r/20210805072110.4730-1-krzysztof.kozlowski@canonical.com Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/exynos/exynos7.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi index 25549d9552ae..84f92b44c323 100644 --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi @@ -113,7 +113,7 @@ #address-cells = <0>; interrupt-controller; reg = <0x11001000 0x1000>, - <0x11002000 0x1000>, + <0x11002000 0x2000>, <0x11004000 0x2000>, <0x11006000 0x2000>; }; From c2451d5439d08ff351a6d07d51ec35d354a3d2df Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Tue, 3 Aug 2021 21:06:11 +0900 Subject: [PATCH 085/150] counter: 104-quad-8: Return error when invalid mode during ceiling_write [ Upstream commit 728246e8f7269ecd35a2c6e6795323e6d8f48db7 ] The 104-QUAD-8 only has two count modes where a ceiling value makes sense: Range Limit and Modulo-N. Outside of these two modes, setting a ceiling value is an invalid operation -- so let's report it as such by returning -EINVAL. Fixes: fc069262261c ("counter: 104-quad-8: Add lock guards - generic interface") Acked-by: Syed Nayyar Waris Signed-off-by: William Breathitt Gray Link: https://lore.kernel.org/r/a2147f022829b66839a1db5530a7fada47856847.1627990337.git.vilhelm.gray@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/counter/104-quad-8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c index 5c23a9a56921..f261a57af1c0 100644 --- a/drivers/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -1230,12 +1230,13 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter, case 1: case 3: quad8_preset_register_set(priv, count->id, ceiling); - break; + mutex_unlock(&priv->lock); + return len; } mutex_unlock(&priv->lock); - return len; + return -EINVAL; } static ssize_t quad8_count_preset_enable_read(struct counter_device *counter, From 5ccb04c6e1fb7b97fa2e1785b67c3a1cb3527ef7 Mon Sep 17 00:00:00 2001 From: Desmond Cheong Zhi Xi Date: Tue, 10 Aug 2021 12:14:10 +0800 Subject: [PATCH 086/150] Bluetooth: fix repeated calls to sco_sock_kill [ Upstream commit e1dee2c1de2b4dd00eb44004a4bda6326ed07b59 ] In commit 4e1a720d0312 ("Bluetooth: avoid killing an already killed socket"), a check was added to sco_sock_kill to skip killing a socket if the SOCK_DEAD flag was set. This was done after a trace for a use-after-free bug showed that the same sock pointer was being killed twice. Unfortunately, this check prevents sco_sock_kill from running on any socket. sco_sock_kill kills a socket only if it's zapped and orphaned, however sock_orphan announces that the socket is dead before detaching it. i.e., orphaned sockets have the SOCK_DEAD flag set. To fix this, we remove the check for SOCK_DEAD, and avoid repeated calls to sco_sock_kill by removing incorrect calls in: 1. sco_sock_timeout. The socket should not be killed on timeout as further processing is expected to be done. For example, sco_sock_connect sets the timer then waits for the socket to be connected or for an error to be returned. 2. sco_conn_del. This function should clean up resources for the connection, but the socket itself should be cleaned up in sco_sock_release. 3. sco_sock_close. Calls to sco_sock_close in sco_sock_cleanup_listen and sco_sock_release are followed by sco_sock_kill. Hence the duplicated call should be removed. Fixes: 4e1a720d0312 ("Bluetooth: avoid killing an already killed socket") Signed-off-by: Desmond Cheong Zhi Xi Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/sco.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 335264706aae..1b7540cb8e5c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -84,7 +84,6 @@ static void sco_sock_timeout(struct timer_list *t) sk->sk_state_change(sk); bh_unlock_sock(sk); - sco_sock_kill(sk); sock_put(sk); } @@ -176,7 +175,6 @@ static void sco_conn_del(struct hci_conn *hcon, int err) sco_sock_clear_timer(sk); sco_chan_del(sk, err); bh_unlock_sock(sk); - sco_sock_kill(sk); sock_put(sk); } @@ -393,8 +391,7 @@ static void sco_sock_cleanup_listen(struct sock *parent) */ static void sco_sock_kill(struct sock *sk) { - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket || - sock_flag(sk, SOCK_DEAD)) + if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; BT_DBG("sk %p state %d", sk, sk->sk_state); @@ -446,7 +443,6 @@ static void sco_sock_close(struct sock *sk) lock_sock(sk); __sco_sock_close(sk); release_sock(sk); - sco_sock_kill(sk); } static void sco_sock_init(struct sock *sk, struct sock *parent) From 05e5b16b79dc97d64044d8c35fd3fd5e4bec27ed Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 6 Aug 2021 11:15:13 +0200 Subject: [PATCH 087/150] drm/msm/dsi: Fix some reference counted resource leaks [ Upstream commit 6977cc89c87506ff17e6c05f0e37f46752256e82 ] 'of_find_device_by_node()' takes a reference that must be released when not needed anymore. This is expected to be done in 'dsi_destroy()'. However, there are 2 issues in 'dsi_get_phy()'. First, if 'of_find_device_by_node()' succeeds but 'platform_get_drvdata()' returns NULL, 'msm_dsi->phy_dev' will still be NULL, and the reference won't be released in 'dsi_destroy()'. Secondly, as 'of_find_device_by_node()' already takes a reference, there is no need for an additional 'get_device()'. Move the assignment to 'msm_dsi->phy_dev' a few lines above and remove the unneeded 'get_device()' to solve both issues. Fixes: ec31abf6684e ("drm/msm/dsi: Separate PHY to another platform device") Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/f15bc57648a00e7c99f943903468a04639d50596.1628241097.git.christophe.jaillet@wanadoo.fr Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dsi/dsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 55ea4bc2ee9c..0d37ae5b310c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -26,8 +26,10 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi) } phy_pdev = of_find_device_by_node(phy_node); - if (phy_pdev) + if (phy_pdev) { msm_dsi->phy = platform_get_drvdata(phy_pdev); + msm_dsi->phy_dev = &phy_pdev->dev; + } of_node_put(phy_node); @@ -36,8 +38,6 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi) return -EPROBE_DEFER; } - msm_dsi->phy_dev = get_device(&phy_pdev->dev); - return 0; } From 9535f55d0cba9313222dac546b76088e1848472a Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 9 Aug 2021 23:27:28 +0300 Subject: [PATCH 088/150] usb: gadget: udc: at91: add IRQ check [ Upstream commit 50855c31573b02963f0aa2aacfd4ea41c31ae0e0 ] The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to devm_request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original error code. Stop calling devm_request_irq() with the invalid IRQ #s. Fixes: 8b2e76687b39 ("USB: AT91 UDC updates, mostly power management") Signed-off-by: Sergey Shtylyov Acked-by: Felipe Balbi Link: https://lore.kernel.org/r/6654a224-739a-1a80-12f0-76d920f87b6c@omp.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/at91_udc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 194ffb1ed462..d7714c94b119 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1878,7 +1878,9 @@ static int at91udc_probe(struct platform_device *pdev) clk_disable(udc->iclk); /* request UDC and maybe VBUS irqs */ - udc->udp_irq = platform_get_irq(pdev, 0); + udc->udp_irq = retval = platform_get_irq(pdev, 0); + if (retval < 0) + goto err_unprepare_iclk; retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0, driver_name, udc); if (retval) { From e1473ac28563b0afd5fdf849a6f82b24c48d1467 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 9 Aug 2021 23:50:18 +0300 Subject: [PATCH 089/150] usb: phy: fsl-usb: add IRQ check [ Upstream commit ecc2f30dbb25969908115c81ec23650ed982b004 ] The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original error code. Stop calling request_irq() with the invalid IRQ #s. Fixes: 0807c500a1a6 ("USB: add Freescale USB OTG Transceiver driver") Acked-by: Felipe Balbi Signed-off-by: Sergey Shtylyov Link: https://lore.kernel.org/r/b0a86089-8b8b-122e-fd6d-73e8c2304964@omp.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/phy/phy-fsl-usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index b451f4695f3f..446c7bf67873 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -873,6 +873,8 @@ int usb_otg_start(struct platform_device *pdev) /* request irq */ p_otg->irq = platform_get_irq(pdev, 0); + if (p_otg->irq < 0) + return p_otg->irq; status = request_irq(p_otg->irq, fsl_otg_isr, IRQF_SHARED, driver_name, p_otg); if (status) { From 30d9607bcd739c4e746060460ae80732e486856e Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 9 Aug 2021 23:53:16 +0300 Subject: [PATCH 090/150] usb: phy: twl6030: add IRQ checks [ Upstream commit 0881e22c06e66af0b64773c91c8868ead3d01aa1 ] The driver neglects to check the result of platform_get_irq()'s calls and blithely passes the negative error codes to request_threaded_irq() (which takes *unsigned* IRQ #), causing them both to fail with -EINVAL, overriding an original error code. Stop calling request_threaded_irq() with the invalid IRQ #s. Fixes: c33fad0c3748 ("usb: otg: Adding twl6030-usb transceiver driver for OMAP4430") Acked-by: Felipe Balbi Signed-off-by: Sergey Shtylyov Link: https://lore.kernel.org/r/9507f50b-50f1-6dc4-f57c-3ed4e53a1c25@omp.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/phy/phy-twl6030-usb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 9a7e655d5280..9337c30f0743 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -348,6 +348,11 @@ static int twl6030_usb_probe(struct platform_device *pdev) twl->irq2 = platform_get_irq(pdev, 1); twl->linkstat = MUSB_UNKNOWN; + if (twl->irq1 < 0) + return twl->irq1; + if (twl->irq2 < 0) + return twl->irq2; + twl->comparator.set_vbus = twl6030_set_vbus; twl->comparator.start_srp = twl6030_start_srp; From 93ec1fd04f0f792e96f52bf60d501677fa0ad2dd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Aug 2021 17:52:54 +0200 Subject: [PATCH 091/150] usb: gadget: udc: renesas_usb3: Fix soc_device_match() abuse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit cea45a3bd2dd4d9c35581328f571afd32b3c9f48 ] soc_device_match() is intended as a last resort, to handle e.g. quirks that cannot be handled by matching based on a compatible value. As the device nodes for the Renesas USB 3.0 Peripheral Controller on R-Car E3 and RZ/G2E do have SoC-specific compatible values, the latter can and should be used to match against these devices. This also fixes support for the USB 3.0 Peripheral Controller on the R-Car E3e (R8A779M6) SoC, which is a different grading of the R-Car E3 (R8A77990) SoC, using the same SoC-specific compatible value. Fixes: 30025efa8b5e75f5 ("usb: gadget: udc: renesas_usb3: add support for r8a77990") Fixes: 546970fdab1da5fe ("usb: gadget: udc: renesas_usb3: add support for r8a774c0") Reviewed-by: Niklas Söderlund Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/760981fb4cd110d7cbfc9dcffa365e7c8b25c6e5.1628696960.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/renesas_usb3.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 08a93cf68eff..b6653bc7acc2 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2692,10 +2692,15 @@ static const struct renesas_usb3_priv renesas_usb3_priv_r8a77990 = { static const struct of_device_id usb3_of_match[] = { { + .compatible = "renesas,r8a774c0-usb3-peri", + .data = &renesas_usb3_priv_r8a77990, + }, { .compatible = "renesas,r8a7795-usb3-peri", .data = &renesas_usb3_priv_gen3, - }, - { + }, { + .compatible = "renesas,r8a77990-usb3-peri", + .data = &renesas_usb3_priv_r8a77990, + }, { .compatible = "renesas,rcar-gen3-usb3-peri", .data = &renesas_usb3_priv_gen3, }, @@ -2704,18 +2709,10 @@ static const struct of_device_id usb3_of_match[] = { MODULE_DEVICE_TABLE(of, usb3_of_match); static const struct soc_device_attribute renesas_usb3_quirks_match[] = { - { - .soc_id = "r8a774c0", - .data = &renesas_usb3_priv_r8a77990, - }, { .soc_id = "r8a7795", .revision = "ES1.*", .data = &renesas_usb3_priv_r8a7795_es1, }, - { - .soc_id = "r8a77990", - .data = &renesas_usb3_priv_r8a77990, - }, { /* sentinel */ }, }; From abbcd61d091f69ec98013dc0ae9c992e152fc303 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 10 Aug 2021 12:53:15 +0800 Subject: [PATCH 092/150] Bluetooth: Move shutdown callback before flushing tx and rx queue [ Upstream commit 0ea53674d07fb6db2dd7a7ec2fdc85a12eb246c2 ] Commit 0ea9fd001a14 ("Bluetooth: Shutdown controller after workqueues are flushed or cancelled") introduced a regression that makes mtkbtsdio driver stops working: [ 36.593956] Bluetooth: hci0: Firmware already downloaded [ 46.814613] Bluetooth: hci0: Execution of wmt command timed out [ 46.814619] Bluetooth: hci0: Failed to send wmt func ctrl (-110) The shutdown callback depends on the result of hdev->rx_work, so we should call it before flushing rx_work: -> btmtksdio_shutdown() -> mtk_hci_wmt_sync() -> __hci_cmd_send() -> wait for BTMTKSDIO_TX_WAIT_VND_EVT gets cleared -> btmtksdio_recv_event() -> hci_recv_frame() -> queue_work(hdev->workqueue, &hdev->rx_work) -> clears BTMTKSDIO_TX_WAIT_VND_EVT So move the shutdown callback before flushing TX/RX queue to resolve the issue. Reported-and-tested-by: Mattijs Korpershoek Tested-by: Hsin-Yi Wang Cc: Guenter Roeck Fixes: 0ea9fd001a14 ("Bluetooth: Shutdown controller after workqueues are flushed or cancelled") Signed-off-by: Kai-Heng Feng Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- net/bluetooth/hci_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 83a07fca9000..4e4972800370 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1685,6 +1685,14 @@ int hci_dev_do_close(struct hci_dev *hdev) hci_request_cancel_all(hdev); hci_req_sync_lock(hdev); + if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && + !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && + test_bit(HCI_UP, &hdev->flags)) { + /* Execute vendor specific shutdown routine */ + if (hdev->shutdown) + hdev->shutdown(hdev); + } + if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { cancel_delayed_work_sync(&hdev->cmd_timer); hci_req_sync_unlock(hdev); From ecf18ac8ff7601b4670a24e640b041e0fbb0d254 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Fri, 13 Aug 2021 23:30:18 +0300 Subject: [PATCH 093/150] usb: host: ohci-tmio: add IRQ check [ Upstream commit 4ac5132e8a4300637a2da8f5d6bc7650db735b8a ] The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to usb_add_hcd() (which takes *unsigned* IRQ #), causing request_irq() that it calls to fail with -EINVAL, overriding an original error code. Stop calling usb_add_hcd() with the invalid IRQ #s. Fixes: 78c73414f4f6 ("USB: ohci: add support for tmio-ohci cell") Acked-by: Alan Stern Signed-off-by: Sergey Shtylyov Link: https://lore.kernel.org/r/402e1a45-a0a4-0e08-566a-7ca1331506b1@omp.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/ohci-tmio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index fb6f5e9ae5c6..fed43c6dd85c 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -202,6 +202,9 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) if (!cell) return -EINVAL; + if (irq < 0) + return irq; + hcd = usb_create_hcd(&ohci_tmio_hc_driver, &dev->dev, dev_name(&dev->dev)); if (!hcd) { ret = -ENOMEM; From 606668e24a0d7fd262e2326d76bb60b965fe713f Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Fri, 13 Aug 2021 23:32:38 +0300 Subject: [PATCH 094/150] usb: phy: tahvo: add IRQ check [ Upstream commit 0d45a1373e669880b8beaecc8765f44cb0241e47 ] The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_threaded_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original error code. Stop calling request_threaded_irq() with the invalid IRQ #s. Fixes: 9ba96ae5074c ("usb: omap1: Tahvo USB transceiver driver") Acked-by: Felipe Balbi Signed-off-by: Sergey Shtylyov Link: https://lore.kernel.org/r/8280d6a4-8e9a-7cfe-1aa9-db586dc9afdf@omp.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/phy/phy-tahvo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index baebb1f5a973..a3e043e3e4aa 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -393,7 +393,9 @@ static int tahvo_usb_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, tu); - tu->irq = platform_get_irq(pdev, 0); + tu->irq = ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, IRQF_ONESHOT, "tahvo-vbus", tu); From e1c02e2e6a7ad0d65dd7f5ecc23a33a02eb10a54 Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Mon, 16 Aug 2021 16:51:28 +0800 Subject: [PATCH 095/150] mac80211: Fix insufficient headroom issue for AMSDU [ Upstream commit f50d2ff8f016b79a2ff4acd5943a1eda40c545d4 ] ieee80211_amsdu_realloc_pad() fails to account for extra_tx_headroom, the original reserved headroom might be eaten. Add the necessary extra_tx_headroom. Fixes: 6e0456b54545 ("mac80211: add A-MSDU tx support") Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Link: https://lore.kernel.org/r/20210816085128.10931-2-pkshih@realtek.com [fix indentation] Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 538722522ffe..4dfac7a25e5a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3189,7 +3189,9 @@ static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata, if (info->control.flags & IEEE80211_TX_CTRL_AMSDU) return true; - if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr))) + if (!ieee80211_amsdu_realloc_pad(local, skb, + sizeof(*amsdu_hdr) + + local->hw.extra_tx_headroom)) return false; data = skb_push(skb, sizeof(*amsdu_hdr)); From 81e69d3fdd9e47287a0f3705c154263fe08fa2a7 Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Mon, 26 Jul 2021 09:33:28 -0400 Subject: [PATCH 096/150] lockd: Fix invalid lockowner cast after vfs_test_lock [ Upstream commit cd2d644ddba183ec7b451b7c20d5c7cc06fcf0d7 ] After calling vfs_test_lock() the pointer to a conflicting lock can be returned, and that lock is not guarunteed to be owned by nlm. In that case, we cannot cast it to struct nlm_lockowner. Instead return the pid of that conflicting lock. Fixes: 646d73e91b42 ("lockd: Show pid of lockd for remote locks") Signed-off-by: Benjamin Coddington Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/lockd/svclock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 61d3cc2283dc..498cb70c2c0d 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -634,7 +634,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, conflock->caller = "somehost"; /* FIXME */ conflock->len = strlen(conflock->caller); conflock->oh.len = 0; /* don't return OH info */ - conflock->svid = ((struct nlm_lockowner *)lock->fl.fl_owner)->pid; + conflock->svid = lock->fl.fl_pid; conflock->fl.fl_type = lock->fl.fl_type; conflock->fl.fl_start = lock->fl.fl_start; conflock->fl.fl_end = lock->fl.fl_end; From eb3c6a25012fa2b55f71c583cd143a747aaa3361 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 12 Aug 2021 16:41:43 -0400 Subject: [PATCH 097/150] nfsd4: Fix forced-expiry locking [ Upstream commit f7104cc1a9159cd0d3e8526cb638ae0301de4b61 ] This should use the network-namespace-wide client_lock, not the per-client cl_lock. You shouldn't see any bugs unless you're actually using the forced-expiry interface introduced by 89c905beccbb. Fixes: 89c905beccbb "nfsd: allow forced expiration of NFSv4 clients" Signed-off-by: J. Bruce Fields Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 8cb2f744dde6..3283cc2a4e42 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2572,9 +2572,9 @@ static void force_expire_client(struct nfs4_client *clp) struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); bool already_expired; - spin_lock(&clp->cl_lock); + spin_lock(&nn->client_lock); clp->cl_time = 0; - spin_unlock(&clp->cl_lock); + spin_unlock(&nn->client_lock); wait_event(expiry_wq, atomic_read(&clp->cl_rpc_users) == 0); spin_lock(&nn->client_lock); From 8f5e26053c464429540bf4ffc34c66052c45b699 Mon Sep 17 00:00:00 2001 From: Nadezda Lutovinova Date: Wed, 18 Aug 2021 17:12:47 +0300 Subject: [PATCH 098/150] usb: gadget: mv_u3d: request_irq() after initializing UDC [ Upstream commit 2af0c5ffadaf9d13eca28409d4238b4e672942d3 ] If IRQ occurs between calling request_irq() and mv_u3d_eps_init(), then null pointer dereference occurs since u3d->eps[] wasn't initialized yet but used in mv_u3d_nuke(). The patch puts registration of the interrupt handler after initializing of neccesery data. Found by Linux Driver Verification project (linuxtesting.org). Fixes: 90fccb529d24 ("usb: gadget: Gadget directory cleanup - group UDC drivers") Acked-by: Felipe Balbi Signed-off-by: Nadezda Lutovinova Link: https://lore.kernel.org/r/20210818141247.4794-1-lutovinova@ispras.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/mv_u3d_core.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 35e02a8d0091..bdba3f48c052 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -1922,14 +1922,6 @@ static int mv_u3d_probe(struct platform_device *dev) goto err_get_irq; } u3d->irq = r->start; - if (request_irq(u3d->irq, mv_u3d_irq, - IRQF_SHARED, driver_name, u3d)) { - u3d->irq = 0; - dev_err(&dev->dev, "Request irq %d for u3d failed\n", - u3d->irq); - retval = -ENODEV; - goto err_request_irq; - } /* initialize gadget structure */ u3d->gadget.ops = &mv_u3d_ops; /* usb_gadget_ops */ @@ -1942,6 +1934,15 @@ static int mv_u3d_probe(struct platform_device *dev) mv_u3d_eps_init(u3d); + if (request_irq(u3d->irq, mv_u3d_irq, + IRQF_SHARED, driver_name, u3d)) { + u3d->irq = 0; + dev_err(&dev->dev, "Request irq %d for u3d failed\n", + u3d->irq); + retval = -ENODEV; + goto err_request_irq; + } + /* external vbus detection */ if (u3d->vbus) { u3d->clock_gating = 1; @@ -1965,8 +1966,8 @@ static int mv_u3d_probe(struct platform_device *dev) err_unregister: free_irq(u3d->irq, u3d); -err_request_irq: err_get_irq: +err_request_irq: kfree(u3d->status_req); err_alloc_status_req: kfree(u3d->eps); From 70d71611eb839d1345e8ce75e67b78e55169e365 Mon Sep 17 00:00:00 2001 From: Xu Yu Date: Wed, 18 Aug 2021 12:47:52 -0700 Subject: [PATCH 099/150] mm/swap: consider max pages in iomap_swapfile_add_extent [ Upstream commit 36ca7943ac18aebf8aad4c50829eb2ea5ec847df ] When the max pages (last_page in the swap header + 1) is smaller than the total pages (inode size) of the swapfile, iomap_swapfile_activate overwrites sis->max with total pages. However, frontswap_map is a swap page state bitmap allocated using the initial sis->max page count read from the swap header. If swapfile activation increases sis->max, it's possible for the frontswap code to walk off the end of the bitmap, thereby corrupting kernel memory. [djwong: modify the description a bit; the original paragraph reads: "However, frontswap_map is allocated using max pages. When test and clear the sis offset, which is larger than max pages, of frontswap_map in __frontswap_invalidate_page(), neighbors of frontswap_map may be overwritten, i.e., slab is polluted." Note also that this bug resulted in a behavioral change: activating a swap file that was formatted and later extended results in all pages being activated, not the number of pages recorded in the swap header.] This fixes the issue by considering the limitation of max pages of swap info in iomap_swapfile_add_extent(). To reproduce the case, compile kernel with slub RED ZONE, then run test: $ sudo stress-ng -a 1 -x softlockup,resources -t 72h --metrics --times \ --verify -v -Y /root/tmpdir/stress-ng/stress-statistic-12.yaml \ --log-file /root/tmpdir/stress-ng/stress-logfile-12.txt \ --temp-path /root/tmpdir/stress-ng/ We'll get the error log as below: [ 1151.015141] ============================================================================= [ 1151.016489] BUG kmalloc-16 (Not tainted): Right Redzone overwritten [ 1151.017486] ----------------------------------------------------------------------------- [ 1151.017486] [ 1151.018997] Disabling lock debugging due to kernel taint [ 1151.019873] INFO: 0x0000000084e43932-0x0000000098d17cae @offset=7392. First byte 0x0 instead of 0xcc [ 1151.021303] INFO: Allocated in __do_sys_swapon+0xcf6/0x1170 age=43417 cpu=9 pid=3816 [ 1151.022538] __slab_alloc+0xe/0x20 [ 1151.023069] __kmalloc_node+0xfd/0x4b0 [ 1151.023704] __do_sys_swapon+0xcf6/0x1170 [ 1151.024346] do_syscall_64+0x33/0x40 [ 1151.024925] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 1151.025749] INFO: Freed in put_cred_rcu+0xa1/0xc0 age=43424 cpu=3 pid=2041 [ 1151.026889] kfree+0x276/0x2b0 [ 1151.027405] put_cred_rcu+0xa1/0xc0 [ 1151.027949] rcu_do_batch+0x17d/0x410 [ 1151.028566] rcu_core+0x14e/0x2b0 [ 1151.029084] __do_softirq+0x101/0x29e [ 1151.029645] asm_call_irq_on_stack+0x12/0x20 [ 1151.030381] do_softirq_own_stack+0x37/0x40 [ 1151.031037] do_softirq.part.15+0x2b/0x30 [ 1151.031710] __local_bh_enable_ip+0x4b/0x50 [ 1151.032412] copy_fpstate_to_sigframe+0x111/0x360 [ 1151.033197] __setup_rt_frame+0xce/0x480 [ 1151.033809] arch_do_signal+0x1a3/0x250 [ 1151.034463] exit_to_user_mode_prepare+0xcf/0x110 [ 1151.035242] syscall_exit_to_user_mode+0x27/0x190 [ 1151.035970] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 1151.036795] INFO: Slab 0x000000003b9de4dc objects=44 used=9 fp=0x00000000539e349e flags=0xfffffc0010201 [ 1151.038323] INFO: Object 0x000000004855ba01 @offset=7376 fp=0x0000000000000000 [ 1151.038323] [ 1151.039683] Redzone 000000008d0afd3d: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ [ 1151.041180] Object 000000004855ba01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 1151.042714] Redzone 0000000084e43932: 00 00 00 c0 cc cc cc cc ........ [ 1151.044120] Padding 000000000864c042: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ [ 1151.045615] CPU: 5 PID: 3816 Comm: stress-ng Tainted: G B 5.10.50+ #7 [ 1151.046846] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 [ 1151.048633] Call Trace: [ 1151.049072] dump_stack+0x57/0x6a [ 1151.049585] check_bytes_and_report+0xed/0x110 [ 1151.050320] check_object+0x1eb/0x290 [ 1151.050924] ? __x64_sys_swapoff+0x39a/0x540 [ 1151.051646] free_debug_processing+0x151/0x350 [ 1151.052333] __slab_free+0x21a/0x3a0 [ 1151.052938] ? _cond_resched+0x2d/0x40 [ 1151.053529] ? __vunmap+0x1de/0x220 [ 1151.054139] ? __x64_sys_swapoff+0x39a/0x540 [ 1151.054796] ? kfree+0x276/0x2b0 [ 1151.055307] kfree+0x276/0x2b0 [ 1151.055832] __x64_sys_swapoff+0x39a/0x540 [ 1151.056466] do_syscall_64+0x33/0x40 [ 1151.057084] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 1151.057866] RIP: 0033:0x150340b0ffb7 [ 1151.058481] Code: Unable to access opcode bytes at RIP 0x150340b0ff8d. [ 1151.059537] RSP: 002b:00007fff7f4ee238 EFLAGS: 00000246 ORIG_RAX: 00000000000000a8 [ 1151.060768] RAX: ffffffffffffffda RBX: 00007fff7f4ee66c RCX: 0000150340b0ffb7 [ 1151.061904] RDX: 000000000000000a RSI: 0000000000018094 RDI: 00007fff7f4ee860 [ 1151.063033] RBP: 00007fff7f4ef980 R08: 0000000000000000 R09: 0000150340a672bd [ 1151.064135] R10: 00007fff7f4edca0 R11: 0000000000000246 R12: 0000000000018094 [ 1151.065253] R13: 0000000000000005 R14: 000000000160d930 R15: 00007fff7f4ee66c [ 1151.066413] FIX kmalloc-16: Restoring 0x0000000084e43932-0x0000000098d17cae=0xcc [ 1151.066413] [ 1151.067890] FIX kmalloc-16: Object at 0x000000004855ba01 not freed Fixes: 67482129cdab ("iomap: add a swapfile activation function") Fixes: a45c0eccc564 ("iomap: move the swapfile code into a separate file") Signed-off-by: Gang Deng Signed-off-by: Xu Yu Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Sasha Levin --- fs/iomap/swapfile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/iomap/swapfile.c b/fs/iomap/swapfile.c index bd0cc3dcc980..2d18246f6726 100644 --- a/fs/iomap/swapfile.c +++ b/fs/iomap/swapfile.c @@ -30,11 +30,16 @@ static int iomap_swapfile_add_extent(struct iomap_swapfile_info *isi) { struct iomap *iomap = &isi->iomap; unsigned long nr_pages; + unsigned long max_pages; uint64_t first_ppage; uint64_t first_ppage_reported; uint64_t next_ppage; int error; + if (unlikely(isi->nr_pages >= isi->sis->max)) + return 0; + max_pages = isi->sis->max - isi->nr_pages; + /* * Round the start up and the end down so that the physical * extent aligns to a page boundary. @@ -47,6 +52,7 @@ static int iomap_swapfile_add_extent(struct iomap_swapfile_info *isi) if (first_ppage >= next_ppage) return 0; nr_pages = next_ppage - first_ppage; + nr_pages = min(nr_pages, max_pages); /* * Calculate how much swap space we're adding; the first page contains From 2da3272ae0ea12658e39fd2ddc5691474627f25f Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Thu, 19 Aug 2021 18:15:21 +0300 Subject: [PATCH 100/150] Bluetooth: add timeout sanity check to hci_inquiry [ Upstream commit f41a4b2b5eb7872109723dab8ae1603bdd9d9ec1 ] Syzbot hit "task hung" bug in hci_req_sync(). The problem was in unreasonable huge inquiry timeout passed from userspace. Fix it by adding sanity check for timeout value to hci_inquiry(). Since hci_inquiry() is the only user of hci_req_sync() with user controlled timeout value, it makes sense to check timeout value in hci_inquiry() and don't touch hci_req_sync(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-and-tested-by: syzbot+be2baed593ea56c6a84c@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- net/bluetooth/hci_core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 4e4972800370..bdd330527cfa 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1297,6 +1297,12 @@ int hci_inquiry(void __user *arg) goto done; } + /* Restrict maximum inquiry length to 60 seconds */ + if (ir.length > 60) { + err = -EINVAL; + goto done; + } + hci_dev_lock(hdev); if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { From da3e5f32049a30b90b70f1bf3635376611cc6e5d Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 12 Aug 2021 23:35:09 +0300 Subject: [PATCH 101/150] i2c: iop3xx: fix deferred probing [ Upstream commit a1299505162ad00def3573260c2c68b9c8e8d697 ] When adding the code to handle platform_get_irq*() errors in the commit 489447380a29 ("handle errors returned by platform_get_irq*()"), the actual error code was enforced to be -ENXIO in the driver for some strange reason. This didn't matter much until the deferred probing was introduced -- which requires an actual error code to be propagated upstream from the failure site. While fixing this, also stop overriding the errors from request_irq() to -EIO (done since the pre-git era). Fixes: 489447380a29 ("[PATCH] handle errors returned by platform_get_irq*()") Signed-off-by: Sergey Shtylyov Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-iop3xx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 2f8b8050a223..899624721c1e 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -467,16 +467,14 @@ iop3xx_i2c_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - ret = -ENXIO; + ret = irq; goto unmap; } ret = request_irq(irq, iop3xx_i2c_irq_handler, 0, pdev->name, adapter_data); - if (ret) { - ret = -EIO; + if (ret) goto unmap; - } memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); new_adapter->owner = THIS_MODULE; From 4be8deab6f0d0e42ab85f9dda7c32eb29d82d815 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sun, 4 Jul 2021 17:45:25 +0300 Subject: [PATCH 102/150] i2c: s3c2410: fix IRQ check [ Upstream commit d6840a5e370b7ea4fde16ce2caf431bcc87f9a75 ] Iff platform_get_irq() returns 0, the driver's probe() method will return 0 early (as if the method's call was successful). Let's consider IRQ0 valid for simplicity -- devm_request_irq() can always override that decision... Fixes: e0d1ec97853f ("i2c-s3c2410: Change IRQ to be plain integer.") Signed-off-by: Sergey Shtylyov Reviewed-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-s3c2410.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index d6322698b245..e6f927c6f8af 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -1141,7 +1141,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) */ if (!(i2c->quirks & QUIRK_POLL)) { i2c->irq = ret = platform_get_irq(pdev, 0); - if (ret <= 0) { + if (ret < 0) { dev_err(&pdev->dev, "cannot find IRQ\n"); clk_unprepare(i2c->clk); return ret; From d82fe3dd0b0f1d386261aba9ec1ed025368b403c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Aug 2021 13:37:46 +0300 Subject: [PATCH 103/150] rsi: fix error code in rsi_load_9116_firmware() [ Upstream commit d0f8430332a16c7baa80ce2886339182c5d85f37 ] This code returns success if the kmemdup() fails, but obviously it should return -ENOMEM instead. Fixes: e5a1ecc97e5f ("rsi: add firmware loading for 9116 device") Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210805103746.GA26417@kili Signed-off-by: Sasha Levin --- drivers/net/wireless/rsi/rsi_91x_hal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index 03791f3fe480..5e6c5d13319d 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -1038,8 +1038,10 @@ static int rsi_load_9116_firmware(struct rsi_hw *adapter) } ta_firmware = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); - if (!ta_firmware) + if (!ta_firmware) { + status = -ENOMEM; goto fail_release_fw; + } fw_p = ta_firmware; instructions_sz = fw_entry->size; rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", instructions_sz); From b58cf18e384d8af26f316ddb4b3ad9c08befa70d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 16 Aug 2021 21:39:47 +0300 Subject: [PATCH 104/150] rsi: fix an error code in rsi_probe() [ Upstream commit 9adcdf6758d7c4c9bdaf22d78eb9fcae260ed113 ] Return -ENODEV instead of success for unsupported devices. Fixes: 54fdb318c111 ("rsi: add new device model for 9116") Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210816183947.GA2119@kili Signed-off-by: Sasha Levin --- drivers/net/wireless/rsi/rsi_91x_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index a296f4e0d324..e8aa3d4bda88 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -806,6 +806,7 @@ static int rsi_probe(struct usb_interface *pfunction, } else { rsi_dbg(ERR_ZONE, "%s: Unsupported RSI device id 0x%x\n", __func__, id->idProduct); + status = -ENODEV; goto err1; } From 92397571c2434b271be10b9eba37a2b5f98f9471 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 18 Aug 2021 09:57:33 +0200 Subject: [PATCH 105/150] ASoC: Intel: Skylake: Leave data as is when invoking TLV IPCs [ Upstream commit 126b3422adc80f29d2129db7f61e0113a8a526c6 ] Advancing pointer initially fixed issue for some users but caused regression for others. Leave data as it to make it easier for end users to adjust their topology files if needed. Fixes: a8cd7066f042 ("ASoC: Intel: Skylake: Strip T and L from TLV IPCs") Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20210818075742.1515155-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/skylake/skl-topology.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 1940b17f27ef..104c73eb9769 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1463,12 +1463,6 @@ static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol, struct skl_dev *skl = get_skl_ctx(w->dapm->dev); if (ac->params) { - /* - * Widget data is expected to be stripped of T and L - */ - size -= 2 * sizeof(unsigned int); - data += 2; - if (size > ac->max) return -EINVAL; ac->size = size; From 57314d8414d1e489110c7e8827a637e88c1d3869 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 18 Aug 2021 09:57:35 +0200 Subject: [PATCH 106/150] ASoC: Intel: Skylake: Fix module resource and format selection [ Upstream commit e8b374b649afe756c2470e0e6668022e90bf8518 ] Module configuration may differ between its instances depending on resources required and input and output audio format. Available parameters to select from are stored in module resource and interface (format) lists. These come from topology, together with description of each of pipe's modules. Ignoring index value provided by topology and relying always on 0th entry leads to unexpected module behavior due to under/overbudged resources assigned or impropper format selection. Fix by taking entry at index specified by topology. Fixes: f6fa56e22559 ("ASoC: Intel: Skylake: Parse and update module config structure") Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20210818075742.1515155-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/skylake/skl-topology.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 104c73eb9769..254b796e635d 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -113,7 +113,7 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w, static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg) { - struct skl_module_iface *iface = &mcfg->module->formats[0]; + struct skl_module_iface *iface = &mcfg->module->formats[mcfg->fmt_idx]; dev_dbg(skl->dev, "Dumping config\n"); dev_dbg(skl->dev, "Input Format:\n"); @@ -195,8 +195,8 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg, struct skl_module_fmt *in_fmt, *out_fmt; /* Fixups will be applied to pin 0 only */ - in_fmt = &m_cfg->module->formats[0].inputs[0].fmt; - out_fmt = &m_cfg->module->formats[0].outputs[0].fmt; + in_fmt = &m_cfg->module->formats[m_cfg->fmt_idx].inputs[0].fmt; + out_fmt = &m_cfg->module->formats[m_cfg->fmt_idx].outputs[0].fmt; if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (is_fe) { @@ -239,9 +239,9 @@ static void skl_tplg_update_buffer_size(struct skl_dev *skl, /* Since fixups is applied to pin 0 only, ibs, obs needs * change for pin 0 only */ - res = &mcfg->module->resources[0]; - in_fmt = &mcfg->module->formats[0].inputs[0].fmt; - out_fmt = &mcfg->module->formats[0].outputs[0].fmt; + res = &mcfg->module->resources[mcfg->res_idx]; + in_fmt = &mcfg->module->formats[mcfg->fmt_idx].inputs[0].fmt; + out_fmt = &mcfg->module->formats[mcfg->fmt_idx].outputs[0].fmt; if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) multiplier = 5; @@ -1631,11 +1631,12 @@ int skl_tplg_update_pipe_params(struct device *dev, struct skl_module_cfg *mconfig, struct skl_pipe_params *params) { - struct skl_module_res *res = &mconfig->module->resources[0]; + struct skl_module_res *res; struct skl_dev *skl = get_skl_ctx(dev); struct skl_module_fmt *format = NULL; u8 cfg_idx = mconfig->pipe->cur_config_idx; + res = &mconfig->module->resources[mconfig->res_idx]; skl_tplg_fill_dma_id(mconfig, params); mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; @@ -1644,9 +1645,9 @@ int skl_tplg_update_pipe_params(struct device *dev, return 0; if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) - format = &mconfig->module->formats[0].inputs[0].fmt; + format = &mconfig->module->formats[mconfig->fmt_idx].inputs[0].fmt; else - format = &mconfig->module->formats[0].outputs[0].fmt; + format = &mconfig->module->formats[mconfig->fmt_idx].outputs[0].fmt; /* set the hw_params */ format->s_freq = params->s_freq; From 48b1f117e8d0a049135e178c11beb7c08fcd81c3 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:16:43 +0300 Subject: [PATCH 107/150] mmc: dw_mmc: Fix issue with uninitialized dma_slave_config [ Upstream commit c3ff0189d3bc9c03845fe37472c140f0fefd0c79 ] Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For dw_mmc, this is probably not currently an issue but is still good to fix though. Fixes: 3fc7eaef44db ("mmc: dw_mmc: Add external dma interface support") Cc: Shawn Lin Cc: Jaehoon Chung Cc: Peter Ujfalusi Cc: Vinod Koul Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210810081644.19353-2-tony@atomide.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/dw_mmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 6ace82028667..7b280cb36327 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -782,6 +782,7 @@ static int dw_mci_edmac_start_dma(struct dw_mci *host, int ret = 0; /* Set external dma config: burst size, burst width */ + memset(&cfg, 0, sizeof(cfg)); cfg.dst_addr = host->phy_regs + fifo_offset; cfg.src_addr = cfg.dst_addr; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; From fb8e695e9cfa47864c5df8f1c15c2a4b8cf753f2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:16:44 +0300 Subject: [PATCH 108/150] mmc: moxart: Fix issue with uninitialized dma_slave_config [ Upstream commit ee5165354d498e5bceb0b386e480ac84c5f8c28c ] Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For moxart, this is probably not currently an issue but is still good to fix though. Fixes: 1b66e94e6b99 ("mmc: moxart: Add MOXA ART SD/MMC driver") Cc: Jonas Jensen Cc: Vinod Koul Cc: Peter Ujfalusi Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210810081644.19353-3-tony@atomide.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/moxart-mmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index a0670e9cd012..5553a5643f40 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c @@ -631,6 +631,7 @@ static int moxart_probe(struct platform_device *pdev) host->dma_chan_tx, host->dma_chan_rx); host->have_dma = true; + memset(&cfg, 0, sizeof(cfg)); cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; From e37eeaf9506c543e43c2a503720ecd6ba1270747 Mon Sep 17 00:00:00 2001 From: Andrey Ignatov Date: Fri, 20 Aug 2021 09:39:35 -0700 Subject: [PATCH 109/150] bpf: Fix possible out of bound write in narrow load handling [ Upstream commit d7af7e497f0308bc97809cc48b58e8e0f13887e1 ] Fix a verifier bug found by smatch static checker in [0]. This problem has never been seen in prod to my best knowledge. Fixing it still seems to be a good idea since it's hard to say for sure whether it's possible or not to have a scenario where a combination of convert_ctx_access() and a narrow load would lead to an out of bound write. When narrow load is handled, one or two new instructions are added to insn_buf array, but before it was only checked that cnt >= ARRAY_SIZE(insn_buf) And it's safe to add a new instruction to insn_buf[cnt++] only once. The second try will lead to out of bound write. And this is what can happen if `shift` is set. Fix it by making sure that if the BPF_RSH instruction has to be added in addition to BPF_AND then there is enough space for two more instructions in insn_buf. The full report [0] is below: kernel/bpf/verifier.c:12304 convert_ctx_accesses() warn: offset 'cnt' incremented past end of array kernel/bpf/verifier.c:12311 convert_ctx_accesses() warn: offset 'cnt' incremented past end of array kernel/bpf/verifier.c 12282 12283 insn->off = off & ~(size_default - 1); 12284 insn->code = BPF_LDX | BPF_MEM | size_code; 12285 } 12286 12287 target_size = 0; 12288 cnt = convert_ctx_access(type, insn, insn_buf, env->prog, 12289 &target_size); 12290 if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf) || ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Bounds check. 12291 (ctx_field_size && !target_size)) { 12292 verbose(env, "bpf verifier is misconfigured\n"); 12293 return -EINVAL; 12294 } 12295 12296 if (is_narrower_load && size < target_size) { 12297 u8 shift = bpf_ctx_narrow_access_offset( 12298 off, size, size_default) * 8; 12299 if (ctx_field_size <= 4) { 12300 if (shift) 12301 insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, ^^^^^ increment beyond end of array 12302 insn->dst_reg, 12303 shift); --> 12304 insn_buf[cnt++] = BPF_ALU32_IMM(BPF_AND, insn->dst_reg, ^^^^^ out of bounds write 12305 (1 << size * 8) - 1); 12306 } else { 12307 if (shift) 12308 insn_buf[cnt++] = BPF_ALU64_IMM(BPF_RSH, 12309 insn->dst_reg, 12310 shift); 12311 insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg, ^^^^^^^^^^^^^^^ Same. 12312 (1ULL << size * 8) - 1); 12313 } 12314 } 12315 12316 new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); 12317 if (!new_prog) 12318 return -ENOMEM; 12319 12320 delta += cnt - 1; 12321 12322 /* keep walking new program and skip insns we just inserted */ 12323 env->prog = new_prog; 12324 insn = new_prog->insnsi + i + delta; 12325 } 12326 12327 return 0; 12328 } [0] https://lore.kernel.org/bpf/20210817050843.GA21456@kili/ v1->v2: - clarify that problem was only seen by static checker but not in prod; Fixes: 46f53a65d2de ("bpf: Allow narrow loads with offset > 0") Reported-by: Dan Carpenter Signed-off-by: Andrey Ignatov Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20210820163935.1902398-1-rdna@fb.com Signed-off-by: Sasha Levin --- kernel/bpf/verifier.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 80b219d27e37..c5ecb6147ea2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8957,6 +8957,10 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) if (is_narrower_load && size < target_size) { u8 shift = bpf_ctx_narrow_access_offset( off, size, size_default) * 8; + if (shift && cnt + 1 >= ARRAY_SIZE(insn_buf)) { + verbose(env, "bpf verifier narrow ctx load misconfigured\n"); + return -EINVAL; + } if (ctx_field_size <= 4) { if (shift) insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, From b444064a0e0ef64491b8739a9ae05a952b5f8974 Mon Sep 17 00:00:00 2001 From: Len Baker Date: Tue, 17 Aug 2021 12:27:09 +0200 Subject: [PATCH 110/150] CIFS: Fix a potencially linear read overflow [ Upstream commit f980d055a0f858d73d9467bb0b570721bbfcdfb8 ] strlcpy() reads the entire source buffer first. This read may exceed the destination size limit. This is both inefficient and can lead to linear read overflows if a source string is not NUL-terminated. Also, the strnlen() call does not avoid the read overflow in the strlcpy function when a not NUL-terminated string is passed. So, replace this block by a call to kstrndup() that avoids this type of overflow and does the same. Fixes: 066ce6899484d ("cifs: rename cifs_strlcpy_to_host and make it use new functions") Signed-off-by: Len Baker Reviewed-by: Paulo Alcantara (SUSE) Reviewed-by: Jeff Layton Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/cifs_unicode.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 9bd03a231032..171ad8b42107 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -358,14 +358,9 @@ cifs_strndup_from_utf16(const char *src, const int maxlen, if (!dst) return NULL; cifs_from_utf16(dst, (__le16 *) src, len, maxlen, codepage, - NO_MAP_UNI_RSVD); + NO_MAP_UNI_RSVD); } else { - len = strnlen(src, maxlen); - len++; - dst = kmalloc(len, GFP_KERNEL); - if (!dst) - return NULL; - strlcpy(dst, src, len); + dst = kstrndup(src, maxlen, GFP_KERNEL); } return dst; From a0a9ecca2dc4d97f122fcdb26f737d7d67c655b8 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sun, 4 Jul 2021 17:38:45 +0300 Subject: [PATCH 111/150] i2c: mt65xx: fix IRQ check [ Upstream commit 58fb7c643d346e2364404554f531cfa6a1a3917c ] Iff platform_get_irq() returns 0, the driver's probe() method will return 0 early (as if the method's call was successful). Let's consider IRQ0 valid for simplicity -- devm_request_irq() can always override that decision... Fixes: ce38815d39ea ("I2C: mediatek: Add driver for MediaTek I2C controller") Signed-off-by: Sergey Shtylyov Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-mt65xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index e1ef0122ef75..5587e7c549c4 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -932,7 +932,7 @@ static int mtk_i2c_probe(struct platform_device *pdev) return PTR_ERR(i2c->pdmabase); irq = platform_get_irq(pdev, 0); - if (irq <= 0) + if (irq < 0) return irq; init_completion(&i2c->msg_complete); From 06203abb72752d403edab644d0283f9a3c6497a9 Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Wed, 25 Aug 2021 20:09:02 +0300 Subject: [PATCH 112/150] usb: ehci-orion: Handle errors of clk_prepare_enable() in probe [ Upstream commit 4720f1bf4ee4a784d9ece05420ba33c9222a3004 ] ehci_orion_drv_probe() did not account for possible errors of clk_prepare_enable() that in particular could cause invocation of clk_disable_unprepare() on clocks that were not prepared/enabled yet, e.g. in remove or on handling errors of usb_add_hcd() in probe. Though, there were several patches fixing different issues with clocks in this driver, they did not solve this problem. Add handling of errors of clk_prepare_enable() in ehci_orion_drv_probe() to avoid calls of clk_disable_unprepare() without previous successful invocation of clk_prepare_enable(). Found by Linux Driver Verification project (linuxtesting.org). Fixes: 8c869edaee07 ("ARM: Orion: EHCI: Add support for enabling clocks") Co-developed-by: Kirill Shilimanov Reviewed-by: Andrew Lunn Acked-by: Alan Stern Signed-off-by: Evgeny Novikov Signed-off-by: Kirill Shilimanov Link: https://lore.kernel.org/r/20210825170902.11234-1-novikov@ispras.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/ehci-orion.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index a319b1df3011..3626758b3e2a 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -264,8 +264,11 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) * the clock does not exists. */ priv->clk = devm_clk_get(&pdev->dev, NULL); - if (!IS_ERR(priv->clk)) - clk_prepare_enable(priv->clk); + if (!IS_ERR(priv->clk)) { + err = clk_prepare_enable(priv->clk); + if (err) + goto err_put_hcd; + } priv->phy = devm_phy_optional_get(&pdev->dev, "usb"); if (IS_ERR(priv->phy)) { @@ -311,6 +314,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) err_dis_clk: if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); +err_put_hcd: usb_put_hcd(hcd); err: dev_err(&pdev->dev, "init %s fail, %d\n", From 0f1375fa693b5c64253e71b843ebd4847706b77c Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 18 Aug 2021 21:32:38 +0200 Subject: [PATCH 113/150] usb: bdc: Fix an error handling path in 'bdc_probe()' when no suitable DMA config is available [ Upstream commit d2f42e09393c774ab79088d8e3afcc62b3328fc9 ] If no suitable DMA configuration is available, a previous 'bdc_phy_init()' call must be undone by a corresponding 'bdc_phy_exit()' call. Branch to the existing error handling path instead of returning directly. Fixes: cc29d4f67757 ("usb: bdc: Add support for USB phy") Acked-by: Florian Fainelli Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/0c5910979f39225d5d8fe68c9ab1c147c68ddee1.1629314734.git.christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/bdc/bdc_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index 3d33499db50b..845aead48d85 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -565,7 +565,8 @@ static int bdc_probe(struct platform_device *pdev) if (ret) { dev_err(dev, "No suitable DMA config available, abort\n"); - return -ENOTSUPP; + ret = -ENOTSUPP; + goto phycleanup; } dev_dbg(dev, "Using 32-bit address\n"); } From 7bfa680f3b478e699ba96f9809384502d6f386e7 Mon Sep 17 00:00:00 2001 From: Andy Duan Date: Thu, 19 Aug 2021 10:10:33 +0800 Subject: [PATCH 114/150] tty: serial: fsl_lpuart: fix the wrong mapbase value [ Upstream commit d5c38948448abc2bb6b36dbf85a554bf4748885e ] Register offset needs to be applied on mapbase also. dma_tx/rx_request use the physical address of UARTDATA. Register offset is currently only applied to membase (the corresponding virtual addr) but not on mapbase. Fixes: 24b1e5f0e83c ("tty: serial: lpuart: add imx7ulp support") Reviewed-by: Leonard Crestez Signed-off-by: Adriana Reus Signed-off-by: Sherry Sun Signed-off-by: Andy Duan Link: https://lore.kernel.org/r/20210819021033.32606-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index b053345dfd1a..13e705b53217 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2414,7 +2414,7 @@ static int lpuart_probe(struct platform_device *pdev) return PTR_ERR(sport->port.membase); sport->port.membase += sdata->reg_off; - sport->port.mapbase = res->start; + sport->port.mapbase = res->start + sdata->reg_off; sport->port.dev = &pdev->dev; sport->port.type = PORT_LPUART; sport->devtype = sdata->devtype; From a6088f4ed3fc5a443dcaeb5ee2cfbb29ef22500f Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 16 Aug 2021 07:25:10 +0200 Subject: [PATCH 115/150] ASoC: wcd9335: Fix a double irq free in the remove function [ Upstream commit 7a6a723e98aa45f393e6add18f7309dfffa1b0e2 ] There is no point in calling 'free_irq()' explicitly for 'WCD9335_IRQ_SLIMBUS' in the remove function. The irqs are requested in 'wcd9335_setup_irqs()' using a resource managed function (i.e. 'devm_request_threaded_irq()'). 'wcd9335_setup_irqs()' requests all what is defined in the 'wcd9335_irqs' structure. This structure has only one entry for 'WCD9335_IRQ_SLIMBUS'. So 'devm_request...irq()' + explicit 'free_irq()' would lead to a double free. Remove the unneeded 'free_irq()' from the remove function. Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") Signed-off-by: Christophe JAILLET Message-Id: <0614d63bc00edd7e81dd367504128f3d84f72efa.1629091028.git.christophe.jaillet@wanadoo.fr> Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wcd9335.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 81906c25e4a8..a31a20dcd6b5 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -4869,7 +4869,6 @@ static void wcd9335_codec_remove(struct snd_soc_component *comp) struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); wcd_clsh_ctrl_free(wcd->clsh_ctrl); - free_irq(regmap_irq_get_virq(wcd->irq_data, WCD9335_IRQ_SLIMBUS), wcd); } static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp, From f3ec07f832bb6b48d4584ac8b26e1e30a685011c Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 16 Aug 2021 07:25:20 +0200 Subject: [PATCH 116/150] ASoC: wcd9335: Fix a memory leak in the error handling path of the probe function [ Upstream commit fc6fc81caa63900cef9ebb8b2e365c3ed5a9effb ] If 'wcd9335_setup_irqs()' fails, me must release the memory allocated in 'wcd_clsh_ctrl_alloc()', as already done in the remove function. Add an error handling path and the missing 'wcd_clsh_ctrl_free()' call. Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") Signed-off-by: Christophe JAILLET Message-Id: <6dc12372f09fabb70bf05941dbe6a1382dc93e43.1629091028.git.christophe.jaillet@wanadoo.fr> Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wcd9335.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index a31a20dcd6b5..5ec63217ad02 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -4844,6 +4844,7 @@ static void wcd9335_codec_init(struct snd_soc_component *component) static int wcd9335_codec_probe(struct snd_soc_component *component) { struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); + int ret; int i; snd_soc_component_init_regmap(component, wcd->regmap); @@ -4861,7 +4862,15 @@ static int wcd9335_codec_probe(struct snd_soc_component *component) for (i = 0; i < NUM_CODEC_DAIS; i++) INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list); - return wcd9335_setup_irqs(wcd); + ret = wcd9335_setup_irqs(wcd); + if (ret) + goto free_clsh_ctrl; + + return 0; + +free_clsh_ctrl: + wcd_clsh_ctrl_free(wcd->clsh_ctrl); + return ret; } static void wcd9335_codec_remove(struct snd_soc_component *comp) From d946e685d6b7aaa9f827c89c353a0661822eba4a Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 16 Aug 2021 07:25:28 +0200 Subject: [PATCH 117/150] ASoC: wcd9335: Disable irq on slave ports in the remove function [ Upstream commit d3efd26af2e044ff2b48d38bb871630282d77e60 ] The probe calls 'wcd9335_setup_irqs()' to enable interrupts on all slave ports. This must be undone in the remove function. Add a 'wcd9335_teardown_irqs()' function that undoes 'wcd9335_setup_irqs()' function, and call it from the remove function. Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") Signed-off-by: Christophe JAILLET Message-Id: <8f761244d79bd4c098af8a482be9121d3a486d1b.1629091028.git.christophe.jaillet@wanadoo.fr> Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wcd9335.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 5ec63217ad02..016aff97e2fb 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -4076,6 +4076,16 @@ static int wcd9335_setup_irqs(struct wcd9335_codec *wcd) return ret; } +static void wcd9335_teardown_irqs(struct wcd9335_codec *wcd) +{ + int i; + + /* disable interrupts on all slave ports */ + for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++) + regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i, + 0x00); +} + static void wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec *wcd, bool ccl_flag) { @@ -4878,6 +4888,7 @@ static void wcd9335_codec_remove(struct snd_soc_component *comp) struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); wcd_clsh_ctrl_free(wcd->clsh_ctrl); + wcd9335_teardown_irqs(wcd); } static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp, From 574e563649ecaf437002b0b793474f11f97af0cb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 13 Aug 2021 14:34:38 +0300 Subject: [PATCH 118/150] ath6kl: wmi: fix an error code in ath6kl_wmi_sync_point() [ Upstream commit fd6729ec534cffbbeb3917761e6d1fe6a412d3fe ] This error path is unlikely because of it checked for NULL and returned -ENOMEM earlier in the function. But it should return an error code here as well if we ever do hit it because of a race condition or something. Fixes: bdcd81707973 ("Add ath6kl cleaned up driver") Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210813113438.GB30697@kili Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath6kl/wmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index c610fe21c85c..31ffec3a5972 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2510,8 +2510,10 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) goto free_data_skb; for (index = 0; index < num_pri_streams; index++) { - if (WARN_ON(!data_sync_bufs[index].skb)) + if (WARN_ON(!data_sync_bufs[index].skb)) { + ret = -ENOMEM; goto free_data_skb; + } ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, data_sync_bufs[index]. From 5debec63a28fbdd654753c86c8ea42f1df34fc2c Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Tue, 27 Jul 2021 10:52:31 +0800 Subject: [PATCH 119/150] bcma: Fix memory leak for internally-handled cores [ Upstream commit b63aed3ff195130fef12e0af590f4838cf0201d8 ] kmemleak reported that dev_name() of internally-handled cores were leaked on driver unbinding. Let's use device_initialize() to take refcounts for them and put_device() to properly free the related stuff. While looking at it, there's another potential issue for those which should be *registered* into driver core. If device_register() failed, we put device once and freed bcma_device structures. In bcma_unregister_cores(), they're treated as unregistered and we hit both UAF and double-free. That smells not good and has also been fixed now. Fixes: ab54bc8460b5 ("bcma: fill core details for every device") Signed-off-by: Zenghui Yu Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210727025232.663-2-yuzenghui@huawei.com Signed-off-by: Sasha Levin --- drivers/bcma/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 6535614a7dc1..1df2b5801c3b 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -236,6 +236,7 @@ EXPORT_SYMBOL(bcma_core_irq); void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) { + device_initialize(&core->dev); core->dev.release = bcma_release_core_dev; core->dev.bus = &bcma_bus_type; dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); @@ -277,11 +278,10 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) { int err; - err = device_register(&core->dev); + err = device_add(&core->dev); if (err) { bcma_err(bus, "Could not register dev for core 0x%03X\n", core->id.id); - put_device(&core->dev); return; } core->dev_registered = true; @@ -372,7 +372,7 @@ void bcma_unregister_cores(struct bcma_bus *bus) /* Now noone uses internally-handled cores, we can free them */ list_for_each_entry_safe(core, tmp, &bus->cores, list) { list_del(&core->list); - kfree(core); + put_device(&core->dev); } } From aa167dcde4c78a7670c5c8992074d3cbec4e18e7 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Tue, 17 Aug 2021 08:35:22 +0200 Subject: [PATCH 120/150] brcmfmac: pcie: fix oops on failure to resume and reprobe [ Upstream commit d745ca4f2c4ae9f1bd8cf7d8ac6e22d739bffd19 ] When resuming from suspend, brcmf_pcie_pm_leave_D3 will first attempt a hot resume and then fall back to removing the PCI device and then reprobing. If this probe fails, the kernel will oops, because brcmf_err, which is called to report the failure will dereference the stale bus pointer. Open code and use the default bus-less brcmf_err to avoid this. Fixes: 8602e62441ab ("brcmfmac: pass bus to the __brcmf_err() in pcie.c") Signed-off-by: Ahmad Fatoum Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210817063521.22450-1-a.fatoum@pengutronix.de Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index bda042138e96..e6001f0a81a3 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -2073,7 +2073,7 @@ cleanup: err = brcmf_pcie_probe(pdev, NULL); if (err) - brcmf_err(bus, "probe after resume failed, err=%d\n", err); + __brcmf_err(NULL, __func__, "probe after resume failed, err=%d\n", err); return err; } From f73cbdd1b8e7ea32c66138426f826c8734b70c18 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 29 Aug 2021 15:16:14 -0700 Subject: [PATCH 121/150] ipv6: make exception cache less predictible [ Upstream commit a00df2caffed3883c341d5685f830434312e4a43 ] Even after commit 4785305c05b2 ("ipv6: use siphash in rt6_exception_hash()"), an attacker can still use brute force to learn some secrets from a victim linux host. One way to defeat these attacks is to make the max depth of the hash table bucket a random value. Before this patch, each bucket of the hash table used to store exceptions could contain 6 items under attack. After the patch, each bucket would contains a random number of items, between 6 and 10. The attacker can no longer infer secrets. This is slightly increasing memory size used by the hash table, we do not expect this to be a problem. Following patch is dealing with the same issue in IPv4. Fixes: 35732d01fe31 ("ipv6: introduce a hash table to store dst cache") Signed-off-by: Eric Dumazet Reported-by: Keyu Man Cc: Wei Wang Cc: Martin KaFai Lau Reviewed-by: David Ahern Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv6/route.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d6fc22f7d7a6..575bd0f1b008 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1667,6 +1667,7 @@ static int rt6_insert_exception(struct rt6_info *nrt, struct in6_addr *src_key = NULL; struct rt6_exception *rt6_ex; struct fib6_nh *nh = res->nh; + int max_depth; int err = 0; spin_lock_bh(&rt6_exception_lock); @@ -1721,7 +1722,9 @@ static int rt6_insert_exception(struct rt6_info *nrt, bucket->depth++; net->ipv6.rt6_stats->fib_rt_cache++; - if (bucket->depth > FIB6_MAX_DEPTH) + /* Randomize max depth to avoid some side channels attacks. */ + max_depth = FIB6_MAX_DEPTH + prandom_u32_max(FIB6_MAX_DEPTH); + while (bucket->depth > max_depth) rt6_exception_remove_oldest(bucket); out: From e46e23c289f62ccd8e2230d9ce652072d777ff30 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 29 Aug 2021 15:16:15 -0700 Subject: [PATCH 122/150] ipv4: make exception cache less predictible [ Upstream commit 67d6d681e15b578c1725bad8ad079e05d1c48a8e ] Even after commit 6457378fe796 ("ipv4: use siphash instead of Jenkins in fnhe_hashfun()"), an attacker can still use brute force to learn some secrets from a victim linux host. One way to defeat these attacks is to make the max depth of the hash table bucket a random value. Before this patch, each bucket of the hash table used to store exceptions could contain 6 items under attack. After the patch, each bucket would contains a random number of items, between 6 and 10. The attacker can no longer infer secrets. This is slightly increasing memory size used by the hash table, by 50% in average, we do not expect this to be a problem. This patch is more complex than the prior one (IPv6 equivalent), because IPv4 was reusing the oldest entry. Since we need to be able to evict more than one entry per update_or_create_fnhe() call, I had to replace fnhe_oldest() with fnhe_remove_oldest(). Also note that we will queue extra kfree_rcu() calls under stress, which hopefully wont be a too big issue. Fixes: 4895c771c7f0 ("ipv4: Add FIB nexthop exceptions.") Signed-off-by: Eric Dumazet Reported-by: Keyu Man Cc: Willy Tarreau Signed-off-by: David S. Miller Reviewed-by: David Ahern Tested-by: David Ahern Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/route.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0e976848d4bb..03f35764a40e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -610,18 +610,25 @@ static void fnhe_flush_routes(struct fib_nh_exception *fnhe) } } -static struct fib_nh_exception *fnhe_oldest(struct fnhe_hash_bucket *hash) +static void fnhe_remove_oldest(struct fnhe_hash_bucket *hash) { - struct fib_nh_exception *fnhe, *oldest; + struct fib_nh_exception __rcu **fnhe_p, **oldest_p; + struct fib_nh_exception *fnhe, *oldest = NULL; - oldest = rcu_dereference(hash->chain); - for (fnhe = rcu_dereference(oldest->fnhe_next); fnhe; - fnhe = rcu_dereference(fnhe->fnhe_next)) { - if (time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp)) + for (fnhe_p = &hash->chain; ; fnhe_p = &fnhe->fnhe_next) { + fnhe = rcu_dereference_protected(*fnhe_p, + lockdep_is_held(&fnhe_lock)); + if (!fnhe) + break; + if (!oldest || + time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp)) { oldest = fnhe; + oldest_p = fnhe_p; + } } fnhe_flush_routes(oldest); - return oldest; + *oldest_p = oldest->fnhe_next; + kfree_rcu(oldest, rcu); } static inline u32 fnhe_hashfun(__be32 daddr) @@ -700,16 +707,21 @@ static void update_or_create_fnhe(struct fib_nh_common *nhc, __be32 daddr, if (rt) fill_route_from_fnhe(rt, fnhe); } else { - if (depth > FNHE_RECLAIM_DEPTH) - fnhe = fnhe_oldest(hash); - else { - fnhe = kzalloc(sizeof(*fnhe), GFP_ATOMIC); - if (!fnhe) - goto out_unlock; + /* Randomize max depth to avoid some side channels attacks. */ + int max_depth = FNHE_RECLAIM_DEPTH + + prandom_u32_max(FNHE_RECLAIM_DEPTH); - fnhe->fnhe_next = hash->chain; - rcu_assign_pointer(hash->chain, fnhe); + while (depth > max_depth) { + fnhe_remove_oldest(hash); + depth--; } + + fnhe = kzalloc(sizeof(*fnhe), GFP_ATOMIC); + if (!fnhe) + goto out_unlock; + + fnhe->fnhe_next = hash->chain; + fnhe->fnhe_genid = genid; fnhe->fnhe_daddr = daddr; fnhe->fnhe_gw = gw; @@ -717,6 +729,8 @@ static void update_or_create_fnhe(struct fib_nh_common *nhc, __be32 daddr, fnhe->fnhe_mtu_locked = lock; fnhe->fnhe_expires = max(1UL, expires); + rcu_assign_pointer(hash->chain, fnhe); + /* Exception created; mark the cached routes for the nexthop * stale, so anyone caching it rechecks if this exception * applies to them. From 4648917e499c93e228e72bce36fa68a9244bac94 Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Sun, 29 Aug 2021 23:58:01 +0800 Subject: [PATCH 123/150] net: sched: Fix qdisc_rate_table refcount leak when get tcf_block failed [ Upstream commit c66070125837900163b81a03063ddd657a7e9bfb ] The reference counting issue happens in one exception handling path of cbq_change_class(). When failing to get tcf_block, the function forgets to decrease the refcount of "rtab" increased by qdisc_put_rtab(), causing a refcount leak. Fix this issue by jumping to "failure" label when get tcf_block failed. Fixes: 6529eaba33f0 ("net: sched: introduce tcf block infractructure") Signed-off-by: Xiyu Yang Reviewed-by: Cong Wang Link: https://lore.kernel.org/r/1630252681-71588-1-git-send-email-xiyuyang19@fudan.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_cbq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 39b427dc7512..e5972889cd81 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1614,7 +1614,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); if (err) { kfree(cl); - return err; + goto failure; } if (tca[TCA_RATE]) { From 8216d7157bcf50f492a63caef1293cf8dd937a79 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 28 Aug 2021 16:23:15 +0200 Subject: [PATCH 124/150] net: qualcomm: fix QCA7000 checksum handling [ Upstream commit 429205da6c834447a57279af128bdd56ccd5225e ] Based on tests the QCA7000 doesn't support checksum offloading. So assume ip_summed is CHECKSUM_NONE and let the kernel take care of the checksum handling. This fixes data transfer issues in noisy environments. Reported-by: Michael Heimpold Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000") Signed-off-by: Stefan Wahren Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/qualcomm/qca_spi.c | 2 +- drivers/net/ethernet/qualcomm/qca_uart.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index baac016f3ec0..15591ad5fe4e 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -434,7 +434,7 @@ qcaspi_receive(struct qcaspi *qca) skb_put(qca->rx_skb, retcode); qca->rx_skb->protocol = eth_type_trans( qca->rx_skb, qca->rx_skb->dev); - qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_checksum_none_assert(qca->rx_skb); netif_rx_ni(qca->rx_skb); qca->rx_skb = netdev_alloc_skb_ip_align(net_dev, net_dev->mtu + VLAN_ETH_HLEN); diff --git a/drivers/net/ethernet/qualcomm/qca_uart.c b/drivers/net/ethernet/qualcomm/qca_uart.c index 0981068504fa..ade70f5df496 100644 --- a/drivers/net/ethernet/qualcomm/qca_uart.c +++ b/drivers/net/ethernet/qualcomm/qca_uart.c @@ -107,7 +107,7 @@ qca_tty_receive(struct serdev_device *serdev, const unsigned char *data, skb_put(qca->rx_skb, retcode); qca->rx_skb->protocol = eth_type_trans( qca->rx_skb, qca->rx_skb->dev); - qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_checksum_none_assert(qca->rx_skb); netif_rx_ni(qca->rx_skb); qca->rx_skb = netdev_alloc_skb_ip_align(netdev, netdev->mtu + From b3fe6d19212660b14e8bdc327aee7b0e337b2fb8 Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Date: Mon, 30 Aug 2021 23:30:43 +0530 Subject: [PATCH 125/150] octeontx2-af: Fix loop in free and unmap counter [ Upstream commit 6537e96d743b89294b397b4865c6c061abae31b0 ] When the given counter does not belong to the entry then code ends up in infinite loop because the loop cursor, entry is not getting updated further. This patch fixes that by updating entry for every iteration. Fixes: a958dd59f9ce ("octeontx2-af: Map or unmap NPC MCAM entry and counter") Signed-off-by: Subbaraya Sundeep Signed-off-by: Sunil Goutham Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c index d82a519a0cd9..f9f246c82c97 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -2013,10 +2013,11 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu, index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); if (index >= mcam->bmap_entries) break; + entry = index + 1; + if (mcam->entry2cntr_map[index] != req->cntr) continue; - entry = index + 1; npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index, req->cntr); } From 1c9424a765afa20c023d42018d1f5c3d9158a9c3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 30 Aug 2021 19:02:10 -0700 Subject: [PATCH 126/150] ipv4: fix endianness issue in inet_rtm_getroute_build_skb() [ Upstream commit 92548b0ee220e000d81c27ac9a80e0ede895a881 ] The UDP length field should be in network order. This removes the following sparse error: net/ipv4/route.c:3173:27: warning: incorrect type in assignment (different base types) net/ipv4/route.c:3173:27: expected restricted __be16 [usertype] len net/ipv4/route.c:3173:27: got unsigned long Fixes: 404eb77ea766 ("ipv4: support sport, dport and ip_proto in RTM_GETROUTE") Signed-off-by: Eric Dumazet Cc: Roopa Prabhu Cc: David Ahern Reviewed-by: David Ahern Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 03f35764a40e..539492998864 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3004,7 +3004,7 @@ static struct sk_buff *inet_rtm_getroute_build_skb(__be32 src, __be32 dst, udph = skb_put_zero(skb, sizeof(struct udphdr)); udph->source = sport; udph->dest = dport; - udph->len = sizeof(struct udphdr); + udph->len = htons(sizeof(struct udphdr)); udph->check = 0; break; } From e80c3533c354ede56146ab0e4fbb8304d0c1209f Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Tue, 7 Sep 2021 16:16:58 +0300 Subject: [PATCH 127/150] bpf: Introduce BPF nospec instruction for mitigating Spectre v4 commit f5e81d1117501546b7be050c5fbafa6efd2c722c upstream. In case of JITs, each of the JIT backends compiles the BPF nospec instruction /either/ to a machine instruction which emits a speculation barrier /or/ to /no/ machine instruction in case the underlying architecture is not affected by Speculative Store Bypass or has different mitigations in place already. This covers both x86 and (implicitly) arm64: In case of x86, we use 'lfence' instruction for mitigation. In case of arm64, we rely on the firmware mitigation as controlled via the ssbd kernel parameter. Whenever the mitigation is enabled, it works for all of the kernel code with no need to provide any additional instructions here (hence only comment in arm64 JIT). Other archs can follow as needed. The BPF nospec instruction is specifically targeting Spectre v4 since i) we don't use a serialization barrier for the Spectre v1 case, and ii) mitigation instructions for v1 and v4 might be different on some archs. The BPF nospec is required for a future commit, where the BPF verifier does annotate intermediate BPF programs with speculation barriers. Co-developed-by: Piotr Krysiuk Co-developed-by: Benedict Schlueter Signed-off-by: Daniel Borkmann Signed-off-by: Piotr Krysiuk Signed-off-by: Benedict Schlueter Acked-by: Alexei Starovoitov Signed-off-by: Sasha Levin [OP: - adjusted context for 5.4 - apply riscv changes to /arch/riscv/net/bpf_jit_comp.c] Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- arch/arm/net/bpf_jit_32.c | 3 +++ arch/arm64/net/bpf_jit_comp.c | 13 +++++++++++++ arch/mips/net/ebpf_jit.c | 3 +++ arch/powerpc/net/bpf_jit_comp64.c | 6 ++++++ arch/riscv/net/bpf_jit_comp.c | 4 ++++ arch/s390/net/bpf_jit_comp.c | 5 +++++ arch/sparc/net/bpf_jit_comp_64.c | 3 +++ arch/x86/net/bpf_jit_comp.c | 7 +++++++ arch/x86/net/bpf_jit_comp32.c | 6 ++++++ include/linux/filter.h | 15 +++++++++++++++ kernel/bpf/core.c | 18 +++++++++++++++++- kernel/bpf/disasm.c | 16 +++++++++------- 12 files changed, 91 insertions(+), 8 deletions(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 7216653424fd..b51a8c7b0111 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1602,6 +1602,9 @@ exit: rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx); emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code)); break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 945e5f690ede..afc7d41347f7 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -701,6 +701,19 @@ emit_cond_jmp: } break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + /* + * Nothing required here. + * + * In case of arm64, we rely on the firmware mitigation of + * Speculative Store Bypass as controlled via the ssbd kernel + * parameter. Whenever the mitigation is enabled, it works + * for all of the kernel code with no need to provide any + * additional instructions. + */ + break; + /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c index 561154cbcc40..b31b91e57c34 100644 --- a/arch/mips/net/ebpf_jit.c +++ b/arch/mips/net/ebpf_jit.c @@ -1355,6 +1355,9 @@ jeq_common: } break; + case BPF_ST | BPF_NOSPEC: /* speculation barrier */ + break; + case BPF_ST | BPF_B | BPF_MEM: case BPF_ST | BPF_H | BPF_MEM: case BPF_ST | BPF_W | BPF_MEM: diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index be3517ef0574..20bfd753bcba 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -644,6 +644,12 @@ emit_clear: } break; + /* + * BPF_ST NOSPEC (speculation barrier) + */ + case BPF_ST | BPF_NOSPEC: + break; + /* * BPF_ST(X) */ diff --git a/arch/riscv/net/bpf_jit_comp.c b/arch/riscv/net/bpf_jit_comp.c index e2279fed8f56..0eefe6193253 100644 --- a/arch/riscv/net/bpf_jit_comp.c +++ b/arch/riscv/net/bpf_jit_comp.c @@ -1313,6 +1313,10 @@ out_be: emit(rv_ld(rd, 0, RV_REG_T1), ctx); break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; + /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_B: emit_imm(RV_REG_T1, imm, ctx); diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index e160f4650f8e..3e6612d8b921 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -913,6 +913,11 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, break; } break; + /* + * BPF_NOSPEC (speculation barrier) + */ + case BPF_ST | BPF_NOSPEC: + break; /* * BPF_ST(X) */ diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 3364e2a00989..fef734473c0f 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1287,6 +1287,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) return 1; break; } + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 6e884f17634f..55f62dca28aa 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -728,6 +728,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, } break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + if (boot_cpu_has(X86_FEATURE_XMM2)) + /* Emit 'lfence' */ + EMIT3(0x0F, 0xAE, 0xE8); + break; + /* ST: *(u8*)(dst_reg + off) = imm */ case BPF_ST | BPF_MEM | BPF_B: if (is_ereg(dst_reg)) diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index 0fcba32077c8..2914f900034e 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -1705,6 +1705,12 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, i++; break; } + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + if (boot_cpu_has(X86_FEATURE_XMM2)) + /* Emit 'lfence' */ + EMIT3(0x0F, 0xAE, 0xE8); + break; /* ST: *(u8*)(dst_reg + off) = imm */ case BPF_ST | BPF_MEM | BPF_H: case BPF_ST | BPF_MEM | BPF_B: diff --git a/include/linux/filter.h b/include/linux/filter.h index c53e2fe3c8f7..c4f89340f498 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -68,6 +68,11 @@ struct ctl_table_header; /* unused opcode to mark call to interpreter with arguments */ #define BPF_CALL_ARGS 0xe0 +/* unused opcode to mark speculation barrier for mitigating + * Speculative Store Bypass + */ +#define BPF_NOSPEC 0xc0 + /* As per nm, we expose JITed images as text (code) section for * kallsyms. That way, tools like perf can find it to match * addresses. @@ -368,6 +373,16 @@ static inline bool insn_is_zext(const struct bpf_insn *insn) .off = 0, \ .imm = 0 }) +/* Speculation barrier */ + +#define BPF_ST_NOSPEC() \ + ((struct bpf_insn) { \ + .code = BPF_ST | BPF_NOSPEC, \ + .dst_reg = 0, \ + .src_reg = 0, \ + .off = 0, \ + .imm = 0 }) + /* Internal classic blocks for direct assignment */ #define __BPF_STMT(CODE, K) \ diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 323913ba13b3..d9a3d995bd96 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -31,6 +31,7 @@ #include #include +#include #include /* Registers */ @@ -1310,6 +1311,7 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack) /* Non-UAPI available opcodes. */ [BPF_JMP | BPF_CALL_ARGS] = &&JMP_CALL_ARGS, [BPF_JMP | BPF_TAIL_CALL] = &&JMP_TAIL_CALL, + [BPF_ST | BPF_NOSPEC] = &&ST_NOSPEC, }; #undef BPF_INSN_3_LBL #undef BPF_INSN_2_LBL @@ -1550,7 +1552,21 @@ out: COND_JMP(s, JSGE, >=) COND_JMP(s, JSLE, <=) #undef COND_JMP - /* STX and ST and LDX*/ + /* ST, STX and LDX*/ + ST_NOSPEC: + /* Speculation barrier for mitigating Speculative Store Bypass. + * In case of arm64, we rely on the firmware mitigation as + * controlled via the ssbd kernel parameter. Whenever the + * mitigation is enabled, it works for all of the kernel code + * with no need to provide any additional instructions here. + * In case of x86, we use 'lfence' insn for mitigation. We + * reuse preexisting logic from Spectre v1 mitigation that + * happens to produce the required code on x86 for v4 as well. + */ +#ifdef CONFIG_X86 + barrier_nospec(); +#endif + CONT; #define LDST(SIZEOP, SIZE) \ STX_MEM_##SIZEOP: \ *(SIZE *)(unsigned long) (DST + insn->off) = SRC; \ diff --git a/kernel/bpf/disasm.c b/kernel/bpf/disasm.c index b44d8c447afd..ff1dd7d45b58 100644 --- a/kernel/bpf/disasm.c +++ b/kernel/bpf/disasm.c @@ -162,15 +162,17 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs, else verbose(cbs->private_data, "BUG_%02x\n", insn->code); } else if (class == BPF_ST) { - if (BPF_MODE(insn->code) != BPF_MEM) { + if (BPF_MODE(insn->code) == BPF_MEM) { + verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n", + insn->code, + bpf_ldst_string[BPF_SIZE(insn->code) >> 3], + insn->dst_reg, + insn->off, insn->imm); + } else if (BPF_MODE(insn->code) == 0xc0 /* BPF_NOSPEC, no UAPI */) { + verbose(cbs->private_data, "(%02x) nospec\n", insn->code); + } else { verbose(cbs->private_data, "BUG_st_%02x\n", insn->code); - return; } - verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n", - insn->code, - bpf_ldst_string[BPF_SIZE(insn->code) >> 3], - insn->dst_reg, - insn->off, insn->imm); } else if (class == BPF_LDX) { if (BPF_MODE(insn->code) != BPF_MEM) { verbose(cbs->private_data, "BUG_ldx_%02x\n", insn->code); From f5893af2704eb763eb982f01d573f5b19f06b623 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Tue, 7 Sep 2021 16:16:59 +0300 Subject: [PATCH 128/150] bpf: Fix leakage due to insufficient speculative store bypass mitigation commit 2039f26f3aca5b0e419b98f65dd36481337b86ee upstream. Spectre v4 gadgets make use of memory disambiguation, which is a set of techniques that execute memory access instructions, that is, loads and stores, out of program order; Intel's optimization manual, section 2.4.4.5: A load instruction micro-op may depend on a preceding store. Many microarchitectures block loads until all preceding store addresses are known. The memory disambiguator predicts which loads will not depend on any previous stores. When the disambiguator predicts that a load does not have such a dependency, the load takes its data from the L1 data cache. Eventually, the prediction is verified. If an actual conflict is detected, the load and all succeeding instructions are re-executed. af86ca4e3088 ("bpf: Prevent memory disambiguation attack") tried to mitigate this attack by sanitizing the memory locations through preemptive "fast" (low latency) stores of zero prior to the actual "slow" (high latency) store of a pointer value such that upon dependency misprediction the CPU then speculatively executes the load of the pointer value and retrieves the zero value instead of the attacker controlled scalar value previously stored at that location, meaning, subsequent access in the speculative domain is then redirected to the "zero page". The sanitized preemptive store of zero prior to the actual "slow" store is done through a simple ST instruction based on r10 (frame pointer) with relative offset to the stack location that the verifier has been tracking on the original used register for STX, which does not have to be r10. Thus, there are no memory dependencies for this store, since it's only using r10 and immediate constant of zero; hence af86ca4e3088 /assumed/ a low latency operation. However, a recent attack demonstrated that this mitigation is not sufficient since the preemptive store of zero could also be turned into a "slow" store and is thus bypassed as well: [...] // r2 = oob address (e.g. scalar) // r7 = pointer to map value 31: (7b) *(u64 *)(r10 -16) = r2 // r9 will remain "fast" register, r10 will become "slow" register below 32: (bf) r9 = r10 // JIT maps BPF reg to x86 reg: // r9 -> r15 (callee saved) // r10 -> rbp // train store forward prediction to break dependency link between both r9 // and r10 by evicting them from the predictor's LRU table. 33: (61) r0 = *(u32 *)(r7 +24576) 34: (63) *(u32 *)(r7 +29696) = r0 35: (61) r0 = *(u32 *)(r7 +24580) 36: (63) *(u32 *)(r7 +29700) = r0 37: (61) r0 = *(u32 *)(r7 +24584) 38: (63) *(u32 *)(r7 +29704) = r0 39: (61) r0 = *(u32 *)(r7 +24588) 40: (63) *(u32 *)(r7 +29708) = r0 [...] 543: (61) r0 = *(u32 *)(r7 +25596) 544: (63) *(u32 *)(r7 +30716) = r0 // prepare call to bpf_ringbuf_output() helper. the latter will cause rbp // to spill to stack memory while r13/r14/r15 (all callee saved regs) remain // in hardware registers. rbp becomes slow due to push/pop latency. below is // disasm of bpf_ringbuf_output() helper for better visual context: // // ffffffff8117ee20: 41 54 push r12 // ffffffff8117ee22: 55 push rbp // ffffffff8117ee23: 53 push rbx // ffffffff8117ee24: 48 f7 c1 fc ff ff ff test rcx,0xfffffffffffffffc // ffffffff8117ee2b: 0f 85 af 00 00 00 jne ffffffff8117eee0 <-- jump taken // [...] // ffffffff8117eee0: 49 c7 c4 ea ff ff ff mov r12,0xffffffffffffffea // ffffffff8117eee7: 5b pop rbx // ffffffff8117eee8: 5d pop rbp // ffffffff8117eee9: 4c 89 e0 mov rax,r12 // ffffffff8117eeec: 41 5c pop r12 // ffffffff8117eeee: c3 ret 545: (18) r1 = map[id:4] 547: (bf) r2 = r7 548: (b7) r3 = 0 549: (b7) r4 = 4 550: (85) call bpf_ringbuf_output#194288 // instruction 551 inserted by verifier \ 551: (7a) *(u64 *)(r10 -16) = 0 | /both/ are now slow stores here // storing map value pointer r7 at fp-16 | since value of r10 is "slow". 552: (7b) *(u64 *)(r10 -16) = r7 / // following "fast" read to the same memory location, but due to dependency // misprediction it will speculatively execute before insn 551/552 completes. 553: (79) r2 = *(u64 *)(r9 -16) // in speculative domain contains attacker controlled r2. in non-speculative // domain this contains r7, and thus accesses r7 +0 below. 554: (71) r3 = *(u8 *)(r2 +0) // leak r3 As can be seen, the current speculative store bypass mitigation which the verifier inserts at line 551 is insufficient since /both/, the write of the zero sanitation as well as the map value pointer are a high latency instruction due to prior memory access via push/pop of r10 (rbp) in contrast to the low latency read in line 553 as r9 (r15) which stays in hardware registers. Thus, architecturally, fp-16 is r7, however, microarchitecturally, fp-16 can still be r2. Initial thoughts to address this issue was to track spilled pointer loads from stack and enforce their load via LDX through r10 as well so that /both/ the preemptive store of zero /as well as/ the load use the /same/ register such that a dependency is created between the store and load. However, this option is not sufficient either since it can be bypassed as well under speculation. An updated attack with pointer spill/fills now _all_ based on r10 would look as follows: [...] // r2 = oob address (e.g. scalar) // r7 = pointer to map value [...] // longer store forward prediction training sequence than before. 2062: (61) r0 = *(u32 *)(r7 +25588) 2063: (63) *(u32 *)(r7 +30708) = r0 2064: (61) r0 = *(u32 *)(r7 +25592) 2065: (63) *(u32 *)(r7 +30712) = r0 2066: (61) r0 = *(u32 *)(r7 +25596) 2067: (63) *(u32 *)(r7 +30716) = r0 // store the speculative load address (scalar) this time after the store // forward prediction training. 2068: (7b) *(u64 *)(r10 -16) = r2 // preoccupy the CPU store port by running sequence of dummy stores. 2069: (63) *(u32 *)(r7 +29696) = r0 2070: (63) *(u32 *)(r7 +29700) = r0 2071: (63) *(u32 *)(r7 +29704) = r0 2072: (63) *(u32 *)(r7 +29708) = r0 2073: (63) *(u32 *)(r7 +29712) = r0 2074: (63) *(u32 *)(r7 +29716) = r0 2075: (63) *(u32 *)(r7 +29720) = r0 2076: (63) *(u32 *)(r7 +29724) = r0 2077: (63) *(u32 *)(r7 +29728) = r0 2078: (63) *(u32 *)(r7 +29732) = r0 2079: (63) *(u32 *)(r7 +29736) = r0 2080: (63) *(u32 *)(r7 +29740) = r0 2081: (63) *(u32 *)(r7 +29744) = r0 2082: (63) *(u32 *)(r7 +29748) = r0 2083: (63) *(u32 *)(r7 +29752) = r0 2084: (63) *(u32 *)(r7 +29756) = r0 2085: (63) *(u32 *)(r7 +29760) = r0 2086: (63) *(u32 *)(r7 +29764) = r0 2087: (63) *(u32 *)(r7 +29768) = r0 2088: (63) *(u32 *)(r7 +29772) = r0 2089: (63) *(u32 *)(r7 +29776) = r0 2090: (63) *(u32 *)(r7 +29780) = r0 2091: (63) *(u32 *)(r7 +29784) = r0 2092: (63) *(u32 *)(r7 +29788) = r0 2093: (63) *(u32 *)(r7 +29792) = r0 2094: (63) *(u32 *)(r7 +29796) = r0 2095: (63) *(u32 *)(r7 +29800) = r0 2096: (63) *(u32 *)(r7 +29804) = r0 2097: (63) *(u32 *)(r7 +29808) = r0 2098: (63) *(u32 *)(r7 +29812) = r0 // overwrite scalar with dummy pointer; same as before, also including the // sanitation store with 0 from the current mitigation by the verifier. 2099: (7a) *(u64 *)(r10 -16) = 0 | /both/ are now slow stores here 2100: (7b) *(u64 *)(r10 -16) = r7 | since store unit is still busy. // load from stack intended to bypass stores. 2101: (79) r2 = *(u64 *)(r10 -16) 2102: (71) r3 = *(u8 *)(r2 +0) // leak r3 [...] Looking at the CPU microarchitecture, the scheduler might issue loads (such as seen in line 2101) before stores (line 2099,2100) because the load execution units become available while the store execution unit is still busy with the sequence of dummy stores (line 2069-2098). And so the load may use the prior stored scalar from r2 at address r10 -16 for speculation. The updated attack may work less reliable on CPU microarchitectures where loads and stores share execution resources. This concludes that the sanitizing with zero stores from af86ca4e3088 ("bpf: Prevent memory disambiguation attack") is insufficient. Moreover, the detection of stack reuse from af86ca4e3088 where previously data (STACK_MISC) has been written to a given stack slot where a pointer value is now to be stored does not have sufficient coverage as precondition for the mitigation either; for several reasons outlined as follows: 1) Stack content from prior program runs could still be preserved and is therefore not "random", best example is to split a speculative store bypass attack between tail calls, program A would prepare and store the oob address at a given stack slot and then tail call into program B which does the "slow" store of a pointer to the stack with subsequent "fast" read. From program B PoV such stack slot type is STACK_INVALID, and therefore also must be subject to mitigation. 2) The STACK_SPILL must not be coupled to register_is_const(&stack->spilled_ptr) condition, for example, the previous content of that memory location could also be a pointer to map or map value. Without the fix, a speculative store bypass is not mitigated in such precondition and can then lead to a type confusion in the speculative domain leaking kernel memory near these pointer types. While brainstorming on various alternative mitigation possibilities, we also stumbled upon a retrospective from Chrome developers [0]: [...] For variant 4, we implemented a mitigation to zero the unused memory of the heap prior to allocation, which cost about 1% when done concurrently and 4% for scavenging. Variant 4 defeats everything we could think of. We explored more mitigations for variant 4 but the threat proved to be more pervasive and dangerous than we anticipated. For example, stack slots used by the register allocator in the optimizing compiler could be subject to type confusion, leading to pointer crafting. Mitigating type confusion for stack slots alone would have required a complete redesign of the backend of the optimizing compiler, perhaps man years of work, without a guarantee of completeness. [...] >From BPF side, the problem space is reduced, however, options are rather limited. One idea that has been explored was to xor-obfuscate pointer spills to the BPF stack: [...] // preoccupy the CPU store port by running sequence of dummy stores. [...] 2106: (63) *(u32 *)(r7 +29796) = r0 2107: (63) *(u32 *)(r7 +29800) = r0 2108: (63) *(u32 *)(r7 +29804) = r0 2109: (63) *(u32 *)(r7 +29808) = r0 2110: (63) *(u32 *)(r7 +29812) = r0 // overwrite scalar with dummy pointer; xored with random 'secret' value // of 943576462 before store ... 2111: (b4) w11 = 943576462 2112: (af) r11 ^= r7 2113: (7b) *(u64 *)(r10 -16) = r11 2114: (79) r11 = *(u64 *)(r10 -16) 2115: (b4) w2 = 943576462 2116: (af) r2 ^= r11 // ... and restored with the same 'secret' value with the help of AX reg. 2117: (71) r3 = *(u8 *)(r2 +0) [...] While the above would not prevent speculation, it would make data leakage infeasible by directing it to random locations. In order to be effective and prevent type confusion under speculation, such random secret would have to be regenerated for each store. The additional complexity involved for a tracking mechanism that prevents jumps such that restoring spilled pointers would not get corrupted is not worth the gain for unprivileged. Hence, the fix in here eventually opted for emitting a non-public BPF_ST | BPF_NOSPEC instruction which the x86 JIT translates into a lfence opcode. Inserting the latter in between the store and load instruction is one of the mitigations options [1]. The x86 instruction manual notes: [...] An LFENCE that follows an instruction that stores to memory might complete before the data being stored have become globally visible. [...] The latter meaning that the preceding store instruction finished execution and the store is at minimum guaranteed to be in the CPU's store queue, but it's not guaranteed to be in that CPU's L1 cache at that point (globally visible). The latter would only be guaranteed via sfence. So the load which is guaranteed to execute after the lfence for that local CPU would have to rely on store-to-load forwarding. [2], in section 2.3 on store buffers says: [...] For every store operation that is added to the ROB, an entry is allocated in the store buffer. This entry requires both the virtual and physical address of the target. Only if there is no free entry in the store buffer, the frontend stalls until there is an empty slot available in the store buffer again. Otherwise, the CPU can immediately continue adding subsequent instructions to the ROB and execute them out of order. On Intel CPUs, the store buffer has up to 56 entries. [...] One small upside on the fix is that it lifts constraints from af86ca4e3088 where the sanitize_stack_off relative to r10 must be the same when coming from different paths. The BPF_ST | BPF_NOSPEC gets emitted after a BPF_STX or BPF_ST instruction. This happens either when we store a pointer or data value to the BPF stack for the first time, or upon later pointer spills. The former needs to be enforced since otherwise stale stack data could be leaked under speculation as outlined earlier. For non-x86 JITs the BPF_ST | BPF_NOSPEC mapping is currently optimized away, but others could emit a speculation barrier as well if necessary. For real-world unprivileged programs e.g. generated by LLVM, pointer spill/fill is only generated upon register pressure and LLVM only tries to do that for pointers which are not used often. The program main impact will be the initial BPF_ST | BPF_NOSPEC sanitation for the STACK_INVALID case when the first write to a stack slot occurs e.g. upon map lookup. In future we might refine ways to mitigate the latter cost. [0] https://arxiv.org/pdf/1902.05178.pdf [1] https://msrc-blog.microsoft.com/2018/05/21/analysis-and-mitigation-of-speculative-store-bypass-cve-2018-3639/ [2] https://arxiv.org/pdf/1905.05725.pdf Fixes: af86ca4e3088 ("bpf: Prevent memory disambiguation attack") Fixes: f7cf25b2026d ("bpf: track spill/fill of constants") Co-developed-by: Piotr Krysiuk Co-developed-by: Benedict Schlueter Signed-off-by: Daniel Borkmann Signed-off-by: Piotr Krysiuk Signed-off-by: Benedict Schlueter Acked-by: Alexei Starovoitov Signed-off-by: Sasha Levin [OP: - apply check_stack_write_fixed_off() changes in check_stack_write() - replace env->bypass_spec_v4 -> env->allow_ptr_leaks] Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- include/linux/bpf_verifier.h | 2 +- kernel/bpf/verifier.c | 87 +++++++++++++----------------------- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 22f070085971..4292e8e42c12 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -301,8 +301,8 @@ struct bpf_insn_aux_data { }; }; int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ - int sanitize_stack_off; /* stack slot to be cleared */ bool seen; /* this insn was processed by the verifier */ + bool sanitize_stack_spill; /* subject to Spectre v4 sanitation */ bool zext_dst; /* this insn zero extends dst reg */ u8 alu_state; /* used in combination with alu_limit */ bool prune_point; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c5ecb6147ea2..28767cd43046 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1920,6 +1920,19 @@ static int check_stack_write(struct bpf_verifier_env *env, cur = env->cur_state->frame[env->cur_state->curframe]; if (value_regno >= 0) reg = &cur->regs[value_regno]; + if (!env->allow_ptr_leaks) { + bool sanitize = reg && is_spillable_regtype(reg->type); + + for (i = 0; i < size; i++) { + if (state->stack[spi].slot_type[i] == STACK_INVALID) { + sanitize = true; + break; + } + } + + if (sanitize) + env->insn_aux_data[insn_idx].sanitize_stack_spill = true; + } if (reg && size == BPF_REG_SIZE && register_is_const(reg) && !register_is_null(reg) && env->allow_ptr_leaks) { @@ -1942,47 +1955,10 @@ static int check_stack_write(struct bpf_verifier_env *env, verbose(env, "invalid size of register spill\n"); return -EACCES; } - if (state != cur && reg->type == PTR_TO_STACK) { verbose(env, "cannot spill pointers to stack into stack frame of the caller\n"); return -EINVAL; } - - if (!env->allow_ptr_leaks) { - bool sanitize = false; - - if (state->stack[spi].slot_type[0] == STACK_SPILL && - register_is_const(&state->stack[spi].spilled_ptr)) - sanitize = true; - for (i = 0; i < BPF_REG_SIZE; i++) - if (state->stack[spi].slot_type[i] == STACK_MISC) { - sanitize = true; - break; - } - if (sanitize) { - int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; - int soff = (-spi - 1) * BPF_REG_SIZE; - - /* detected reuse of integer stack slot with a pointer - * which means either llvm is reusing stack slot or - * an attacker is trying to exploit CVE-2018-3639 - * (speculative store bypass) - * Have to sanitize that slot with preemptive - * store of zero. - */ - if (*poff && *poff != soff) { - /* disallow programs where single insn stores - * into two different stack slots, since verifier - * cannot sanitize them - */ - verbose(env, - "insn %d cannot access two stack slots fp%d and fp%d", - insn_idx, *poff, soff); - return -EINVAL; - } - *poff = soff; - } - } save_register_state(state, spi, reg); } else { u8 type = STACK_MISC; @@ -8854,35 +8830,33 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) for (i = 0; i < insn_cnt; i++, insn++) { bpf_convert_ctx_access_t convert_ctx_access; + bool ctx_access; if (insn->code == (BPF_LDX | BPF_MEM | BPF_B) || insn->code == (BPF_LDX | BPF_MEM | BPF_H) || insn->code == (BPF_LDX | BPF_MEM | BPF_W) || - insn->code == (BPF_LDX | BPF_MEM | BPF_DW)) + insn->code == (BPF_LDX | BPF_MEM | BPF_DW)) { type = BPF_READ; - else if (insn->code == (BPF_STX | BPF_MEM | BPF_B) || - insn->code == (BPF_STX | BPF_MEM | BPF_H) || - insn->code == (BPF_STX | BPF_MEM | BPF_W) || - insn->code == (BPF_STX | BPF_MEM | BPF_DW)) + ctx_access = true; + } else if (insn->code == (BPF_STX | BPF_MEM | BPF_B) || + insn->code == (BPF_STX | BPF_MEM | BPF_H) || + insn->code == (BPF_STX | BPF_MEM | BPF_W) || + insn->code == (BPF_STX | BPF_MEM | BPF_DW) || + insn->code == (BPF_ST | BPF_MEM | BPF_B) || + insn->code == (BPF_ST | BPF_MEM | BPF_H) || + insn->code == (BPF_ST | BPF_MEM | BPF_W) || + insn->code == (BPF_ST | BPF_MEM | BPF_DW)) { type = BPF_WRITE; - else + ctx_access = BPF_CLASS(insn->code) == BPF_STX; + } else { continue; + } if (type == BPF_WRITE && - env->insn_aux_data[i + delta].sanitize_stack_off) { + env->insn_aux_data[i + delta].sanitize_stack_spill) { struct bpf_insn patch[] = { - /* Sanitize suspicious stack slot with zero. - * There are no memory dependencies for this store, - * since it's only using frame pointer and immediate - * constant of zero - */ - BPF_ST_MEM(BPF_DW, BPF_REG_FP, - env->insn_aux_data[i + delta].sanitize_stack_off, - 0), - /* the original STX instruction will immediately - * overwrite the same stack slot with appropriate value - */ *insn, + BPF_ST_NOSPEC(), }; cnt = ARRAY_SIZE(patch); @@ -8896,6 +8870,9 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) continue; } + if (!ctx_access) + continue; + switch (env->insn_aux_data[i + delta].ptr_type) { case PTR_TO_CTX: if (!ops->convert_ctx_access) From a0a4778feae1a435ef2d03006cc434db40cfa311 Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Tue, 7 Sep 2021 16:17:00 +0300 Subject: [PATCH 129/150] bpf: verifier: Allocate idmap scratch in verifier env commit c9e73e3d2b1eb1ea7ff068e05007eec3bd8ef1c9 upstream. func_states_equal makes a very short lived allocation for idmap, probably because it's too large to fit on the stack. However the function is called quite often, leading to a lot of alloc / free churn. Replace the temporary allocation with dedicated scratch space in struct bpf_verifier_env. Signed-off-by: Lorenz Bauer Signed-off-by: Alexei Starovoitov Acked-by: Edward Cree Link: https://lore.kernel.org/bpf/20210429134656.122225-4-lmb@cloudflare.com Signed-off-by: Greg Kroah-Hartman [OP: adjusted context for 5.4] Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- include/linux/bpf_verifier.h | 8 +++++++ kernel/bpf/verifier.c | 46 ++++++++++++------------------------ 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 4292e8e42c12..d5a7798a4cbf 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -194,6 +194,13 @@ struct bpf_idx_pair { u32 idx; }; +struct bpf_id_pair { + u32 old; + u32 cur; +}; + +/* Maximum number of register states that can exist at once */ +#define BPF_ID_MAP_SIZE (MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) #define MAX_CALL_FRAMES 8 struct bpf_verifier_state { /* call stack tracking */ @@ -370,6 +377,7 @@ struct bpf_verifier_env { const struct bpf_line_info *prev_linfo; struct bpf_verifier_log log; struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1]; + struct bpf_id_pair idmap_scratch[BPF_ID_MAP_SIZE]; struct { int *insn_state; int *insn_stack; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 28767cd43046..003c7169167d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6976,13 +6976,6 @@ static bool range_within(struct bpf_reg_state *old, old->smax_value >= cur->smax_value; } -/* Maximum number of register states that can exist at once */ -#define ID_MAP_SIZE (MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) -struct idpair { - u32 old; - u32 cur; -}; - /* If in the old state two registers had the same id, then they need to have * the same id in the new state as well. But that id could be different from * the old state, so we need to track the mapping from old to new ids. @@ -6993,11 +6986,11 @@ struct idpair { * So we look through our idmap to see if this old id has been seen before. If * so, we require the new id to match; otherwise, we add the id pair to the map. */ -static bool check_ids(u32 old_id, u32 cur_id, struct idpair *idmap) +static bool check_ids(u32 old_id, u32 cur_id, struct bpf_id_pair *idmap) { unsigned int i; - for (i = 0; i < ID_MAP_SIZE; i++) { + for (i = 0; i < BPF_ID_MAP_SIZE; i++) { if (!idmap[i].old) { /* Reached an empty slot; haven't seen this id before */ idmap[i].old = old_id; @@ -7110,7 +7103,7 @@ next: /* Returns true if (rold safe implies rcur safe) */ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, - struct idpair *idmap) + struct bpf_id_pair *idmap) { bool equal; @@ -7227,7 +7220,7 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, static bool stacksafe(struct bpf_func_state *old, struct bpf_func_state *cur, - struct idpair *idmap) + struct bpf_id_pair *idmap) { int i, spi; @@ -7324,32 +7317,23 @@ static bool refsafe(struct bpf_func_state *old, struct bpf_func_state *cur) * whereas register type in current state is meaningful, it means that * the current state will reach 'bpf_exit' instruction safely */ -static bool func_states_equal(struct bpf_func_state *old, +static bool func_states_equal(struct bpf_verifier_env *env, struct bpf_func_state *old, struct bpf_func_state *cur) { - struct idpair *idmap; - bool ret = false; int i; - idmap = kcalloc(ID_MAP_SIZE, sizeof(struct idpair), GFP_KERNEL); - /* If we failed to allocate the idmap, just say it's not safe */ - if (!idmap) + memset(env->idmap_scratch, 0, sizeof(env->idmap_scratch)); + for (i = 0; i < MAX_BPF_REG; i++) + if (!regsafe(&old->regs[i], &cur->regs[i], env->idmap_scratch)) + return false; + + if (!stacksafe(old, cur, env->idmap_scratch)) return false; - for (i = 0; i < MAX_BPF_REG; i++) { - if (!regsafe(&old->regs[i], &cur->regs[i], idmap)) - goto out_free; - } - - if (!stacksafe(old, cur, idmap)) - goto out_free; - if (!refsafe(old, cur)) - goto out_free; - ret = true; -out_free: - kfree(idmap); - return ret; + return false; + + return true; } static bool states_equal(struct bpf_verifier_env *env, @@ -7376,7 +7360,7 @@ static bool states_equal(struct bpf_verifier_env *env, for (i = 0; i <= old->curframe; i++) { if (old->frame[i]->callsite != cur->frame[i]->callsite) return false; - if (!func_states_equal(old->frame[i], cur->frame[i])) + if (!func_states_equal(env, old->frame[i], cur->frame[i])) return false; } return true; From ae968e270f2e3427f2f24d6ef463fcb0351e2f37 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Tue, 7 Sep 2021 16:17:01 +0300 Subject: [PATCH 130/150] bpf: Fix pointer arithmetic mask tightening under state pruning commit e042aa532c84d18ff13291d00620502ce7a38dda upstream. In 7fedb63a8307 ("bpf: Tighten speculative pointer arithmetic mask") we narrowed the offset mask for unprivileged pointer arithmetic in order to mitigate a corner case where in the speculative domain it is possible to advance, for example, the map value pointer by up to value_size-1 out-of- bounds in order to leak kernel memory via side-channel to user space. The verifier's state pruning for scalars leaves one corner case open where in the first verification path R_x holds an unknown scalar with an aux->alu_limit of e.g. 7, and in a second verification path that same register R_x, here denoted as R_x', holds an unknown scalar which has tighter bounds and would thus satisfy range_within(R_x, R_x') as well as tnum_in(R_x, R_x') for state pruning, yielding an aux->alu_limit of 3: Given the second path fits the register constraints for pruning, the final generated mask from aux->alu_limit will remain at 7. While technically not wrong for the non-speculative domain, it would however be possible to craft similar cases where the mask would be too wide as in 7fedb63a8307. One way to fix it is to detect the presence of unknown scalar map pointer arithmetic and force a deeper search on unknown scalars to ensure that we do not run into a masking mismatch. Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov Signed-off-by: Greg Kroah-Hartman [OP: adjusted context in include/linux/bpf_verifier.h for 5.4] Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- include/linux/bpf_verifier.h | 1 + kernel/bpf/verifier.c | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index d5a7798a4cbf..ee10a9f06b97 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -371,6 +371,7 @@ struct bpf_verifier_env { struct bpf_map *used_maps[MAX_USED_MAPS]; /* array of map's used by eBPF program */ u32 used_map_cnt; /* number of used maps */ u32 id_gen; /* used to generate unique reg IDs */ + bool explore_alu_limits; bool allow_ptr_leaks; bool seen_direct_write; struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 003c7169167d..60383b28549b 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4449,6 +4449,12 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, alu_state |= off_is_imm ? BPF_ALU_IMMEDIATE : 0; alu_state |= ptr_is_dst_reg ? BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST; + + /* Limit pruning on unknown scalars to enable deep search for + * potential masking differences from other program paths. + */ + if (!off_is_imm) + env->explore_alu_limits = true; } err = update_alu_sanitation_state(aux, alu_state, alu_limit); @@ -7102,8 +7108,8 @@ next: } /* Returns true if (rold safe implies rcur safe) */ -static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, - struct bpf_id_pair *idmap) +static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, + struct bpf_reg_state *rcur, struct bpf_id_pair *idmap) { bool equal; @@ -7129,6 +7135,8 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, return false; switch (rold->type) { case SCALAR_VALUE: + if (env->explore_alu_limits) + return false; if (rcur->type == SCALAR_VALUE) { if (!rold->precise && !rcur->precise) return true; @@ -7218,9 +7226,8 @@ static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur, return false; } -static bool stacksafe(struct bpf_func_state *old, - struct bpf_func_state *cur, - struct bpf_id_pair *idmap) +static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, + struct bpf_func_state *cur, struct bpf_id_pair *idmap) { int i, spi; @@ -7265,9 +7272,8 @@ static bool stacksafe(struct bpf_func_state *old, continue; if (old->stack[spi].slot_type[0] != STACK_SPILL) continue; - if (!regsafe(&old->stack[spi].spilled_ptr, - &cur->stack[spi].spilled_ptr, - idmap)) + if (!regsafe(env, &old->stack[spi].spilled_ptr, + &cur->stack[spi].spilled_ptr, idmap)) /* when explored and current stack slot are both storing * spilled registers, check that stored pointers types * are the same as well. @@ -7324,10 +7330,11 @@ static bool func_states_equal(struct bpf_verifier_env *env, struct bpf_func_stat memset(env->idmap_scratch, 0, sizeof(env->idmap_scratch)); for (i = 0; i < MAX_BPF_REG; i++) - if (!regsafe(&old->regs[i], &cur->regs[i], env->idmap_scratch)) + if (!regsafe(env, &old->regs[i], &cur->regs[i], + env->idmap_scratch)) return false; - if (!stacksafe(old, cur, env->idmap_scratch)) + if (!stacksafe(env, old, cur, env->idmap_scratch)) return false; if (!refsafe(old, cur)) From 7a25a0a94c8b49759582ac6141c06af4f3e8ae8f Mon Sep 17 00:00:00 2001 From: Lukas Hannen Date: Wed, 25 Aug 2021 10:12:43 +0000 Subject: [PATCH 131/150] time: Handle negative seconds correctly in timespec64_to_ns() commit 39ff83f2f6cc5cc1458dfcea9697f96338210beb upstream. timespec64_ns() prevents multiplication overflows by comparing the seconds value of the timespec to KTIME_SEC_MAX. If the value is greater or equal it returns KTIME_MAX. But that check casts the signed seconds value to unsigned which makes the comparision true for all negative values and therefore return wrongly KTIME_MAX. Negative second values are perfectly valid and required in some places, e.g. ptp_clock_adjtime(). Remove the cast and add a check for the negative boundary which is required to prevent undefined behaviour due to multiplication underflow. Fixes: cb47755725da ("time: Prevent undefined behaviour in timespec64_to_ns()")' Signed-off-by: Lukas Hannen Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/AM6PR01MB541637BD6F336B8FFB72AF80EEC69@AM6PR01MB5416.eurprd01.prod.exchangelabs.com Signed-off-by: Greg Kroah-Hartman --- include/linux/time64.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/linux/time64.h b/include/linux/time64.h index 5eab3f263518..f6059c505986 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -33,7 +33,9 @@ struct itimerspec64 { #define TIME64_MIN (-TIME64_MAX - 1) #define KTIME_MAX ((s64)~((u64)1 << 63)) +#define KTIME_MIN (-KTIME_MAX - 1) #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) +#define KTIME_SEC_MIN (KTIME_MIN / NSEC_PER_SEC) /* * Limits for settimeofday(): @@ -132,10 +134,13 @@ static inline bool timespec64_valid_settod(const struct timespec64 *ts) */ static inline s64 timespec64_to_ns(const struct timespec64 *ts) { - /* Prevent multiplication overflow */ - if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) + /* Prevent multiplication overflow / underflow */ + if (ts->tv_sec >= KTIME_SEC_MAX) return KTIME_MAX; + if (ts->tv_sec <= KTIME_SEC_MIN) + return KTIME_MIN; + return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; } From 03c3e977eeacbaa9929d5e15fe6908523909543c Mon Sep 17 00:00:00 2001 From: Nguyen Dinh Phi Date: Mon, 23 Aug 2021 08:06:41 +0800 Subject: [PATCH 132/150] tty: Fix data race between tiocsti() and flush_to_ldisc() commit bb2853a6a421a052268eee00fd5d3f6b3504b2b1 upstream. The ops->receive_buf() may be accessed concurrently from these two functions. If the driver flushes data to the line discipline receive_buf() method while tiocsti() is waiting for the ops->receive_buf() to finish its work, the data race will happen. For example: tty_ioctl |tty_ldisc_receive_buf ->tioctsi | ->tty_port_default_receive_buf | ->tty_ldisc_receive_buf ->hci_uart_tty_receive | ->hci_uart_tty_receive ->h4_recv | ->h4_recv In this case, the h4 receive buffer will be overwritten by the latecomer, and we will lost the data. Hence, change tioctsi() function to use the exclusive lock interface from tty_buffer to avoid the data race. Reported-by: syzbot+97388eb9d31b997fe1d0@syzkaller.appspotmail.com Reviewed-by: Jiri Slaby Signed-off-by: Nguyen Dinh Phi Link: https://lore.kernel.org/r/20210823000641.2082292-1-phind.uet@gmail.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index cee7514c3aaf..ddfe873b5fcc 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2176,8 +2176,6 @@ static int tty_fasync(int fd, struct file *filp, int on) * Locking: * Called functions take tty_ldiscs_lock * current->signal->tty check is safe without locks - * - * FIXME: may race normal receive processing */ static int tiocsti(struct tty_struct *tty, char __user *p) @@ -2193,8 +2191,10 @@ static int tiocsti(struct tty_struct *tty, char __user *p) ld = tty_ldisc_ref_wait(tty); if (!ld) return -EIO; + tty_buffer_lock_exclusive(tty->port); if (ld->ops->receive_buf) ld->ops->receive_buf(tty, &ch, &mbz, 1); + tty_buffer_unlock_exclusive(tty->port); tty_ldisc_deref(ld); return 0; } From 51f4575ca182071218cc709c13827d96c52a2d8f Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 17 Aug 2021 17:10:41 -0500 Subject: [PATCH 133/150] perf/x86/amd/ibs: Extend PERF_PMU_CAP_NO_EXCLUDE to IBS Op commit f11dd0d80555cdc8eaf5cfc9e19c9e198217f9f1 upstream. Commit: 2ff40250691e ("perf/core, arch/x86: Use PERF_PMU_CAP_NO_EXCLUDE for exclusion incapable PMUs") neglected to do so. Fixes: 2ff40250691e ("perf/core, arch/x86: Use PERF_PMU_CAP_NO_EXCLUDE for exclusion incapable PMUs") Signed-off-by: Kim Phillips Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210817221048.88063-2-kim.phillips@amd.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/amd/ibs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index ff07040287c4..b7baaa973317 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -562,6 +562,7 @@ static struct perf_ibs perf_ibs_op = { .start = perf_ibs_start, .stop = perf_ibs_stop, .read = perf_ibs_read, + .capabilities = PERF_PMU_CAP_NO_EXCLUDE, }, .msr = MSR_AMD64_IBSOPCTL, .config_mask = IBS_OP_CONFIG_MASK, From 0323ab5b254e05a5f84051afb61ad7e646d840f3 Mon Sep 17 00:00:00 2001 From: Babu Moger Date: Fri, 20 Aug 2021 16:52:42 -0500 Subject: [PATCH 134/150] x86/resctrl: Fix a maybe-uninitialized build warning treated as error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 527f721478bce3f49b513a733bacd19d6f34b08c upstream. The recent commit 064855a69003 ("x86/resctrl: Fix default monitoring groups reporting") caused a RHEL build failure with an uninitialized variable warning treated as an error because it removed the default case snippet. The RHEL Makefile uses '-Werror=maybe-uninitialized' to force possibly uninitialized variable warnings to be treated as errors. This is also reported by smatch via the 0day robot. The error from the RHEL build is: arch/x86/kernel/cpu/resctrl/monitor.c: In function ‘__mon_event_count’: arch/x86/kernel/cpu/resctrl/monitor.c:261:12: error: ‘m’ may be used uninitialized in this function [-Werror=maybe-uninitialized] m->chunks += chunks; ^~ The upstream Makefile does not build using '-Werror=maybe-uninitialized'. So, the problem is not seen there. Fix the problem by putting back the default case snippet. [ bp: note that there's nothing wrong with the code and other compilers do not trigger this warning - this is being done just so the RHEL compiler is happy. ] Fixes: 064855a69003 ("x86/resctrl: Fix default monitoring groups reporting") Reported-by: Terry Bowman Reported-by: kernel test robot Signed-off-by: Babu Moger Signed-off-by: Borislav Petkov Reviewed-by: Reinette Chatre Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/162949631908.23903.17090272726012848523.stgit@bmoger-ubuntu Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/resctrl/monitor.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index 21eb593e0313..008bcb15fe96 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -242,6 +242,12 @@ static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) case QOS_L3_MBM_LOCAL_EVENT_ID: m = &rr->d->mbm_local[rmid]; break; + default: + /* + * Code would never reach here because an invalid + * event id would fail the __rmid_read. + */ + return RMID_VAL_ERROR; } if (rr->first) { From 20fff3ef33b225cbb666600de014c43fad75f839 Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Fri, 27 Aug 2021 14:54:29 +0200 Subject: [PATCH 135/150] KVM: s390: index kvm->arch.idle_mask by vcpu_idx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a3e03bc1368c1bc16e19b001fc96dc7430573cc8 upstream. While in practice vcpu->vcpu_idx == vcpu->vcp_id is often true, it may not always be, and we must not rely on this. Reason is that KVM decides the vcpu_idx, userspace decides the vcpu_id, thus the two might not match. Currently kvm->arch.idle_mask is indexed by vcpu_id, which implies that code like for_each_set_bit(vcpu_id, kvm->arch.idle_mask, online_vcpus) { vcpu = kvm_get_vcpu(kvm, vcpu_id); do_stuff(vcpu); } is not legit. Reason is that kvm_get_vcpu expects an vcpu_idx, not an vcpu_id. The trouble is, we do actually use kvm->arch.idle_mask like this. To fix this problem we have two options. Either use kvm_get_vcpu_by_id(vcpu_id), which would loop to find the right vcpu_id, or switch to indexing via vcpu_idx. The latter is preferable for obvious reasons. Let us make switch from indexing kvm->arch.idle_mask by vcpu_id to indexing it by vcpu_idx. To keep gisa_int.kicked_mask indexed by the same index as idle_mask lets make the same change for it as well. Fixes: 1ee0bc559dc3 ("KVM: s390: get rid of local_int array") Signed-off-by: Halil Pasic Reviewed-by: Christian Bornträger Reviewed-by: Claudio Imbrenda Cc: # 3.15+ Link: https://lore.kernel.org/r/20210827125429.1912577-1-pasic@linux.ibm.com Signed-off-by: Christian Borntraeger Signed-off-by: Greg Kroah-Hartman --- arch/s390/include/asm/kvm_host.h | 1 + arch/s390/kvm/interrupt.c | 12 ++++++------ arch/s390/kvm/kvm-s390.c | 2 +- arch/s390/kvm/kvm-s390.h | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 0fe5600a037e..4d59d11e6813 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -873,6 +873,7 @@ struct kvm_arch{ atomic64_t cmma_dirty_pages; /* subset of available cpu features enabled by user space */ DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); + /* indexed by vcpu_idx */ DECLARE_BITMAP(idle_mask, KVM_MAX_VCPUS); struct kvm_s390_gisa_interrupt gisa_int; }; diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 62388a678b91..fa9483aa4f57 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -408,13 +408,13 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu) static void __set_cpu_idle(struct kvm_vcpu *vcpu) { kvm_s390_set_cpuflags(vcpu, CPUSTAT_WAIT); - set_bit(vcpu->vcpu_id, vcpu->kvm->arch.idle_mask); + set_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.idle_mask); } static void __unset_cpu_idle(struct kvm_vcpu *vcpu) { kvm_s390_clear_cpuflags(vcpu, CPUSTAT_WAIT); - clear_bit(vcpu->vcpu_id, vcpu->kvm->arch.idle_mask); + clear_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.idle_mask); } static void __reset_intercept_indicators(struct kvm_vcpu *vcpu) @@ -2984,18 +2984,18 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len) static void __airqs_kick_single_vcpu(struct kvm *kvm, u8 deliverable_mask) { - int vcpu_id, online_vcpus = atomic_read(&kvm->online_vcpus); + int vcpu_idx, online_vcpus = atomic_read(&kvm->online_vcpus); struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; struct kvm_vcpu *vcpu; - for_each_set_bit(vcpu_id, kvm->arch.idle_mask, online_vcpus) { - vcpu = kvm_get_vcpu(kvm, vcpu_id); + for_each_set_bit(vcpu_idx, kvm->arch.idle_mask, online_vcpus) { + vcpu = kvm_get_vcpu(kvm, vcpu_idx); if (psw_ioint_disabled(vcpu)) continue; deliverable_mask &= (u8)(vcpu->arch.sie_block->gcr[6] >> 24); if (deliverable_mask) { /* lately kicked but not yet running */ - if (test_and_set_bit(vcpu_id, gi->kicked_mask)) + if (test_and_set_bit(vcpu_idx, gi->kicked_mask)) return; kvm_s390_vcpu_wakeup(vcpu); return; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 20ba8537dbcc..9ed2fee61229 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -3726,7 +3726,7 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu) kvm_s390_patch_guest_per_regs(vcpu); } - clear_bit(vcpu->vcpu_id, vcpu->kvm->arch.gisa_int.kicked_mask); + clear_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.gisa_int.kicked_mask); vcpu->arch.sie_block->icptcode = 0; cpuflags = atomic_read(&vcpu->arch.sie_block->cpuflags); diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 6d9448dbd052..63d94a5253a8 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -67,7 +67,7 @@ static inline int is_vcpu_stopped(struct kvm_vcpu *vcpu) static inline int is_vcpu_idle(struct kvm_vcpu *vcpu) { - return test_bit(vcpu->vcpu_id, vcpu->kvm->arch.idle_mask); + return test_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.idle_mask); } static inline int kvm_is_ucontrol(struct kvm *kvm) From 1735cec1e83c5e1b93de47c07d74d706644394ad Mon Sep 17 00:00:00 2001 From: Zelin Deng Date: Wed, 28 Apr 2021 10:22:01 +0800 Subject: [PATCH 136/150] KVM: x86: Update vCPU's hv_clock before back to guest when tsc_offset is adjusted commit d9130a2dfdd4b21736c91b818f87dbc0ccd1e757 upstream. When MSR_IA32_TSC_ADJUST is written by guest due to TSC ADJUST feature especially there's a big tsc warp (like a new vCPU is hot-added into VM which has been up for a long time), tsc_offset is added by a large value then go back to guest. This causes system time jump as tsc_timestamp is not adjusted in the meantime and pvclock monotonic character. To fix this, just notify kvm to update vCPU's guest time before back to guest. Cc: stable@vger.kernel.org Signed-off-by: Zelin Deng Signed-off-by: Paolo Bonzini Message-Id: <1619576521-81399-2-git-send-email-zelin.deng@linux.alibaba.com> Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/x86.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 364e96e508d9..f1a0eebdcf64 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2764,6 +2764,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (!msr_info->host_initiated) { s64 adj = data - vcpu->arch.ia32_tsc_adjust_msr; adjust_tsc_offset_guest(vcpu, adj); + /* Before back to guest, tsc_timestamp must be adjusted + * as well, otherwise guest's percpu pvclock time could jump. + */ + kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); } vcpu->arch.ia32_tsc_adjust_msr = data; } From 06dad664d4eae136e8dfa9eea955b154213f3f2e Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 10 Aug 2021 07:45:26 -0700 Subject: [PATCH 137/150] KVM: nVMX: Unconditionally clear nested.pi_pending on nested VM-Enter commit f7782bb8d818d8f47c26b22079db10599922787a upstream. Clear nested.pi_pending on nested VM-Enter even if L2 will run without posted interrupts enabled. If nested.pi_pending is left set from a previous L2, vmx_complete_nested_posted_interrupt() will pick up the stale flag and exit to userspace with an "internal emulation error" due the new L2 not having a valid nested.pi_desc. Arguably, vmx_complete_nested_posted_interrupt() should first check for posted interrupts being enabled, but it's also completely reasonable that KVM wouldn't screw up a fundamental flag. Not to mention that the mere existence of nested.pi_pending is a long-standing bug as KVM shouldn't move the posted interrupt out of the IRR until it's actually processed, e.g. KVM effectively drops an interrupt when it performs a nested VM-Exit with a "pending" posted interrupt. Fixing the mess is a future problem. Prior to vmx_complete_nested_posted_interrupt() interpreting a null PI descriptor as an error, this was a benign bug as the null PI descriptor effectively served as a check on PI not being enabled. Even then, the new flow did not become problematic until KVM started checking the result of kvm_check_nested_events(). Fixes: 705699a13994 ("KVM: nVMX: Enable nested posted interrupt processing") Fixes: 966eefb89657 ("KVM: nVMX: Disable vmcs02 posted interrupts if vmcs12 PID isn't mappable") Fixes: 47d3530f86c0 ("KVM: x86: Exit to userspace when kvm_check_nested_events fails") Cc: stable@vger.kernel.org Cc: Jim Mattson Signed-off-by: Sean Christopherson Message-Id: <20210810144526.2662272-1-seanjc@google.com> Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/nested.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 023bd3e1aa0d..3041015b05f7 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2057,12 +2057,11 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) ~PIN_BASED_VMX_PREEMPTION_TIMER); /* Posted interrupts setting is only taken from vmcs12. */ - if (nested_cpu_has_posted_intr(vmcs12)) { + vmx->nested.pi_pending = false; + if (nested_cpu_has_posted_intr(vmcs12)) vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv; - vmx->nested.pi_pending = false; - } else { + else exec_control &= ~PIN_BASED_POSTED_INTR; - } pin_controls_set(vmx, exec_control); /* From 8a98ced6e1c812e28340080739505bffe0a0cf4c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 17 Aug 2021 21:05:16 +0200 Subject: [PATCH 138/150] fuse: truncate pagecache on atomic_o_trunc commit 76224355db7570cbe6b6f75c8929a1558828dd55 upstream. fuse_finish_open() will be called with FUSE_NOWRITE in case of atomic O_TRUNC. This can deadlock with fuse_wait_on_page_writeback() in fuse_launder_page() triggered by invalidate_inode_pages2(). Fix by replacing invalidate_inode_pages2() in fuse_finish_open() with a truncate_pagecache() call. This makes sense regardless of FOPEN_KEEP_CACHE or fc->writeback cache, so do it unconditionally. Reported-by: Xie Yongji Reported-and-tested-by: syzbot+bea44a5189836d956894@syzkaller.appspotmail.com Fixes: e4648309b85a ("fuse: truncate pending writes on O_TRUNC") Cc: Signed-off-by: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- fs/fuse/file.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 0883e5b24c90..682d668c28e9 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -193,12 +193,11 @@ void fuse_finish_open(struct inode *inode, struct file *file) struct fuse_file *ff = file->private_data; struct fuse_conn *fc = get_fuse_conn(inode); - if (!(ff->open_flags & FOPEN_KEEP_CACHE)) - invalidate_inode_pages2(inode->i_mapping); if (ff->open_flags & FOPEN_STREAM) stream_open(inode, file); else if (ff->open_flags & FOPEN_NONSEEKABLE) nonseekable_open(inode, file); + if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) { struct fuse_inode *fi = get_fuse_inode(inode); @@ -206,10 +205,14 @@ void fuse_finish_open(struct inode *inode, struct file *file) fi->attr_version = atomic64_inc_return(&fc->attr_version); i_size_write(inode, 0); spin_unlock(&fi->lock); + truncate_pagecache(inode, 0); fuse_invalidate_attr(inode); if (fc->writeback_cache) file_update_time(file); + } else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) { + invalidate_inode_pages2(inode->i_mapping); } + if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) fuse_link_write_file(file); } From 85b0726d5bd714fd968b434d46cdaea60c29131c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 31 Aug 2021 14:18:08 +0200 Subject: [PATCH 139/150] fuse: flush extending writes commit 59bda8ecee2ffc6a602b7bf2b9e43ca669cdbdcd upstream. Callers of fuse_writeback_range() assume that the file is ready for modification by the server in the supplied byte range after the call returns. If there's a write that extends the file beyond the end of the supplied range, then the file needs to be extended to at least the end of the range, but currently that's not done. There are at least two cases where this can cause problems: - copy_file_range() will return short count if the file is not extended up to end of the source range. - FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE will not extend the file, hence the region may not be fully allocated. Fix by flushing writes from the start of the range up to the end of the file. This could be optimized if the writes are non-extending, etc, but it's probably not worth the trouble. Fixes: a2bc92362941 ("fuse: fix copy_file_range() in the writeback case") Fixes: 6b1bdb56b17c ("fuse: allow fallocate(FALLOC_FL_ZERO_RANGE)") Cc: # v5.2 Signed-off-by: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- fs/fuse/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 682d668c28e9..1de59998e0e7 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3188,7 +3188,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) static int fuse_writeback_range(struct inode *inode, loff_t start, loff_t end) { - int err = filemap_write_and_wait_range(inode->i_mapping, start, end); + int err = filemap_write_and_wait_range(inode->i_mapping, start, -1); if (!err) fuse_sync_writes(inode); From c69935f0b0aa763fd2095e9a65945f5527059757 Mon Sep 17 00:00:00 2001 From: Austin Kim Date: Tue, 29 Jun 2021 14:50:50 +0100 Subject: [PATCH 140/150] IMA: remove -Wmissing-prototypes warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a32ad90426a9c8eb3915eed26e08ce133bd9e0da upstream. With W=1 build, the compiler throws warning message as below: security/integrity/ima/ima_mok.c:24:12: warning: no previous prototype for ‘ima_mok_init’ [-Wmissing-prototypes] __init int ima_mok_init(void) Silence the warning by adding static keyword to ima_mok_init(). Signed-off-by: Austin Kim Fixes: 41c89b64d718 ("IMA: create machine owner and blacklist keyrings") Cc: stable@vger.kernel.org Signed-off-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- security/integrity/ima/ima_mok.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index 1e5c01916173..95cc31525c57 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -21,7 +21,7 @@ struct key *ima_blacklist_keyring; /* * Allocate the IMA blacklist keyring */ -__init int ima_mok_init(void) +static __init int ima_mok_init(void) { struct key_restriction *restriction; From 4a95b04afab55ecac3f4b71a61e7ef6dcbfb892f Mon Sep 17 00:00:00 2001 From: THOBY Simon Date: Mon, 16 Aug 2021 08:10:59 +0000 Subject: [PATCH 141/150] IMA: remove the dependency on CRYPTO_MD5 commit 8510505d55e194d3f6c9644c9f9d12c4f6b0395a upstream. MD5 is a weak digest algorithm that shouldn't be used for cryptographic operation. It hinders the efficiency of a patch set that aims to limit the digests allowed for the extended file attribute namely security.ima. MD5 is no longer a requirement for IMA, nor should it be used there. The sole place where we still use the MD5 algorithm inside IMA is setting the ima_hash algorithm to MD5, if the user supplies 'ima_hash=md5' parameter on the command line. With commit ab60368ab6a4 ("ima: Fallback to the builtin hash algorithm"), setting "ima_hash=md5" fails gracefully when CRYPTO_MD5 is not set: ima: Can not allocate md5 (reason: -2) ima: Allocating md5 failed, going to use default hash algorithm sha256 Remove the CRYPTO_MD5 dependency for IMA. Signed-off-by: THOBY Simon Reviewed-by: Lakshmi Ramasubramanian [zohar@linux.ibm.com: include commit number in patch description for stable.] Cc: stable@vger.kernel.org # 4.17 Signed-off-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- security/integrity/ima/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index d2054bec4909..748f3ee27b23 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -6,7 +6,6 @@ config IMA select SECURITYFS select CRYPTO select CRYPTO_HMAC - select CRYPTO_MD5 select CRYPTO_SHA1 select CRYPTO_HASH_INFO select TCG_TPM if HAS_IOMEM && !UML From 5de2ee621bc48fc527f0ed51265eea4bed8b769a Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Wed, 8 Sep 2021 19:27:49 +0900 Subject: [PATCH 142/150] fbmem: don't allow too huge resolutions commit 8c28051cdcbe9dfcec6bd0a4709d67a09df6edae upstream. syzbot is reporting page fault at vga16fb_fillrect() [1], for vga16fb_check_var() is failing to detect multiplication overflow. if (vxres * vyres > maxmem) { vyres = maxmem / vxres; if (vyres < yres) return -ENOMEM; } Since no module would accept too huge resolutions where multiplication overflow happens, let's reject in the common path. Link: https://syzkaller.appspot.com/bug?extid=04168c8063cfdde1db5e [1] Reported-by: syzbot Debugged-by: Randy Dunlap Signed-off-by: Tetsuo Handa Reviewed-by: Geert Uytterhoeven Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/185175d6-227a-7b55-433d-b070929b262c@i-love.sakura.ne.jp Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/core/fbmem.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index d87de5d46718..03b1bf994cc9 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -957,6 +957,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) struct fb_var_screeninfo old_var; struct fb_videomode mode; struct fb_event event; + u32 unused; if (var->activate & FB_ACTIVATE_INV_MODE) { struct fb_videomode mode1, mode2; @@ -1003,6 +1004,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) if (var->xres < 8 || var->yres < 8) return -EINVAL; + /* Too huge resolution causes multiplication overflow. */ + if (check_mul_overflow(var->xres, var->yres, &unused) || + check_mul_overflow(var->xres_virtual, var->yres_virtual, &unused)) + return -EINVAL; + ret = info->fbops->fb_check_var(var, info); if (ret) From 8810c51077b0c11717c90cd7b4857a64a221579d Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Thu, 22 Jul 2021 15:46:23 +0100 Subject: [PATCH 143/150] backlight: pwm_bl: Improve bootloader/kernel device handover commit 79fad92f2e596f5a8dd085788a24f540263ef887 upstream. Currently there are (at least) two problems in the way pwm_bl starts managing the enable_gpio pin. Both occur when the backlight is initially off and the driver finds the pin not already in output mode and, as a result, unconditionally switches it to output-mode and asserts the signal. Problem 1: This could cause the backlight to flicker since, at this stage in driver initialisation, we have no idea what the PWM and regulator are doing (an unconfigured PWM could easily "rest" at 100% duty cycle). Problem 2: This will cause us not to correctly honour the post_pwm_on_delay (which also risks flickers). Fix this by moving the code to configure the GPIO output mode until after we have examines the handover state. That allows us to initialize enable_gpio to off if the backlight is currently off and on if the backlight is on. Cc: stable@vger.kernel.org Reported-by: Marek Vasut Signed-off-by: Daniel Thompson Acked-by: Marek Vasut Tested-by: Marek Vasut Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/video/backlight/pwm_bl.c | 54 +++++++++++++++++--------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 746eebc411df..047f80ee37e8 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -415,6 +415,33 @@ static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data) static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb) { struct device_node *node = pb->dev->of_node; + bool active = true; + + /* + * If the enable GPIO is present, observable (either as input + * or output) and off then the backlight is not currently active. + * */ + if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0) + active = false; + + if (!regulator_is_enabled(pb->power_supply)) + active = false; + + if (!pwm_is_enabled(pb->pwm)) + active = false; + + /* + * Synchronize the enable_gpio with the observed state of the + * hardware. + */ + if (pb->enable_gpio) + gpiod_direction_output(pb->enable_gpio, active); + + /* + * Do not change pb->enabled here! pb->enabled essentially + * tells us if we own one of the regulator's use counts and + * right now we do not. + */ /* Not booted with device tree or no phandle link to the node */ if (!node || !node->phandle) @@ -426,20 +453,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb) * assume that another driver will enable the backlight at the * appropriate time. Therefore, if it is disabled, keep it so. */ - - /* if the enable GPIO is disabled, do not enable the backlight */ - if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0) - return FB_BLANK_POWERDOWN; - - /* The regulator is disabled, do not enable the backlight */ - if (!regulator_is_enabled(pb->power_supply)) - return FB_BLANK_POWERDOWN; - - /* The PWM is disabled, keep it like this */ - if (!pwm_is_enabled(pb->pwm)) - return FB_BLANK_POWERDOWN; - - return FB_BLANK_UNBLANK; + return active ? FB_BLANK_UNBLANK: FB_BLANK_POWERDOWN; } static int pwm_backlight_probe(struct platform_device *pdev) @@ -508,18 +522,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->enable_gpio = gpio_to_desc(data->enable_gpio); } - /* - * If the GPIO is not known to be already configured as output, that - * is, if gpiod_get_direction returns either 1 or -EINVAL, change the - * direction to output and set the GPIO as active. - * Do not force the GPIO to active when it was already output as it - * could cause backlight flickering or we would enable the backlight too - * early. Leave the decision of the initial backlight state for later. - */ - if (pb->enable_gpio && - gpiod_get_direction(pb->enable_gpio) != 0) - gpiod_direction_output(pb->enable_gpio, 1); - pb->power_supply = devm_regulator_get(&pdev->dev, "power"); if (IS_ERR(pb->power_supply)) { ret = PTR_ERR(pb->power_supply); From b40facee46db042de2e594ba67fe4964b6340478 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 15 Aug 2021 01:55:14 +0200 Subject: [PATCH 144/150] clk: kirkwood: Fix a clocking boot regression commit aaedb9e00e5400220a8871180d23a83e67f29f63 upstream. Since a few kernel releases the Pogoplug 4 has crashed like this during boot: Unable to handle kernel NULL pointer dereference at virtual address 00000002 (...) [] (strlen) from [] (kstrdup+0x1c/0x4c) [] (kstrdup) from [] (__clk_register+0x44/0x37c) [] (__clk_register) from [] (clk_hw_register+0x20/0x44) [] (clk_hw_register) from [] (__clk_hw_register_mux+0x198/0x1e4) [] (__clk_hw_register_mux) from [] (clk_register_mux_table+0x5c/0x6c) [] (clk_register_mux_table) from [] (kirkwood_clk_muxing_setup.constprop.0+0x13c/0x1ac) [] (kirkwood_clk_muxing_setup.constprop.0) from [] (of_clk_init+0x12c/0x214) [] (of_clk_init) from [] (time_init+0x20/0x2c) [] (time_init) from [] (start_kernel+0x3dc/0x56c) [] (start_kernel) from [<00000000>] (0x0) Code: e3130020 1afffffb e12fff1e c08a1078 (e5d03000) This is because the "powersave" mux clock 0 was provided in an unterminated array, which is required by the loop in the driver: /* Count, allocate, and register clock muxes */ for (n = 0; desc[n].name;) n++; Here n will go out of bounds and then call clk_register_mux() on random memory contents after the mux clock. Fix this by terminating the array with a blank entry. Fixes: 105299381d87 ("cpufreq: kirkwood: use the powersave multiplexer") Cc: stable@vger.kernel.org Cc: Andrew Lunn Cc: Chris Packham Cc: Gregory CLEMENT Cc: Sebastian Hesselbarth Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20210814235514.403426-1-linus.walleij@linaro.org Reviewed-by: Andrew Lunn Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/clk/mvebu/kirkwood.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 47680237d0be..8bc893df4736 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -265,6 +265,7 @@ static const char *powersave_parents[] = { static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = { { "powersave", powersave_parents, ARRAY_SIZE(powersave_parents), 11, 1, 0 }, + { } }; static struct clk *clk_muxing_get_src( From 245f15a48cdc4d5a90902e140392dc151e528ab8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 15 Sep 2021 09:47:41 +0200 Subject: [PATCH 145/150] Linux 5.4.146 Link: https://lore.kernel.org/r/20210913131047.974309396@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Shuah Khan Tested-by: Jon Hunter Tested-by: Linux Kernel Functional Testing Tested-by: Guenter Roeck Tested-by: Sudip Mukherjee Tested-by: Hulk Robot Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c32a36c8ffc9..48d0c03acfc5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 145 +SUBLEVEL = 146 EXTRAVERSION = NAME = Kleptomaniac Octopus From 5f3ecbf4d586b0e78c6399c4f6bbd9dcd4fd6fa0 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 15 Sep 2021 21:16:27 -0400 Subject: [PATCH 146/150] Revert "Bluetooth: Move shutdown callback before flushing tx and rx queue" This reverts commit abbcd61d091f69ec98013dc0ae9c992e152fc303. Botched backport, dropping to reword for next release. Reported-by: Guenter Roeck Signed-off-by: Sasha Levin --- net/bluetooth/hci_core.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index bdd330527cfa..c50e3e8afbd3 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1691,14 +1691,6 @@ int hci_dev_do_close(struct hci_dev *hdev) hci_request_cancel_all(hdev); hci_req_sync_lock(hdev); - if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && - !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && - test_bit(HCI_UP, &hdev->flags)) { - /* Execute vendor specific shutdown routine */ - if (hdev->shutdown) - hdev->shutdown(hdev); - } - if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { cancel_delayed_work_sync(&hdev->cmd_timer); hci_req_sync_unlock(hdev); From 541e757944aa63af6409a3bb7d483fd5cf9fcab3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Sep 2021 10:17:11 +0200 Subject: [PATCH 147/150] Revert "block: nbd: add sanity check for first_minor" This reverts commit b3fa499d72a0db612f12645265a36751955c0037 which is commit b1a811633f7321cf1ae2bb76a66805b7720e44c9 upstream. The backport of this is reported to be causing some problems, so revert this for now until they are worked out. Link: https://lore.kernel.org/r/CACPK8XfUWoOHr-0RwRoYoskia4fbAbZ7DYf5wWBnv6qUnGq18w@mail.gmail.com Reported-by: Joel Stanley Cc: Christoph Hellwig Cc: Pavel Skripkin Cc: Jens Axboe Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/block/nbd.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index bc3ab98855cf..25e81b1a59a5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1744,17 +1744,7 @@ static int nbd_dev_add(int index) refcount_set(&nbd->refs, 1); INIT_LIST_HEAD(&nbd->list); disk->major = NBD_MAJOR; - - /* Too big first_minor can cause duplicate creation of - * sysfs files/links, since first_minor will be truncated to - * byte in __device_add_disk(). - */ disk->first_minor = index << part_shift; - if (disk->first_minor > 0xff) { - err = -EINVAL; - goto out_free_idr; - } - disk->fops = &nbd_fops; disk->private_data = nbd; sprintf(disk->disk_name, "nbd%d", index); From dc15f641c6ccf59b157c39a938b74298e6392b98 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Sep 2021 10:51:42 +0200 Subject: [PATCH 148/150] Revert "posix-cpu-timers: Force next expiration recalc after itimer reset" This reverts commit c322a963d522e9a4273e18c9d7bd6fd40a25160f which is commit 406dd42bd1ba0c01babf9cde169bb319e52f6147 upstream. It is reported to cause regressions. A proposed fix has been posted, but it is not in a released kernel yet. So just revert this from the stable release so that the bug is fixed. If it's really needed we can add it back in in a future release. Link: https://lore.kernel.org/r/87ilz1pwaq.fsf@wylie.me.uk Reported-by: "Alan J. Wylie" Cc: Linus Torvalds Cc: Frederic Weisbecker Cc: Thomas Gleixner Cc: Peter Zijlstra (Intel) Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- kernel/time/posix-cpu-timers.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 30e061b210b7..eacb0ca30193 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -1201,6 +1201,8 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clkid, } } + if (!*newval) + return; *newval += now; } From 1f8ee024498d00d4f20a34278c23a6d77dd37616 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Sep 2021 11:12:30 +0200 Subject: [PATCH 149/150] Revert "time: Handle negative seconds correctly in timespec64_to_ns()" This reverts commit 7a25a0a94c8b49759582ac6141c06af4f3e8ae8f which is commit 39ff83f2f6cc5cc1458dfcea9697f96338210beb upstream. Arnd reports that this needs more review before being merged into all of the trees. Link: https://lore.kernel.org/r/CAK8P3a0z5jE=Z3Ps5bFTCFT7CHZR1JQ8VhdntDJAfsUxSPCcEw@mail.gmail.com Reported-by: Arnd Bergmann Cc: Lukas Hannen Cc: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- include/linux/time64.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/linux/time64.h b/include/linux/time64.h index f6059c505986..5eab3f263518 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -33,9 +33,7 @@ struct itimerspec64 { #define TIME64_MIN (-TIME64_MAX - 1) #define KTIME_MAX ((s64)~((u64)1 << 63)) -#define KTIME_MIN (-KTIME_MAX - 1) #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) -#define KTIME_SEC_MIN (KTIME_MIN / NSEC_PER_SEC) /* * Limits for settimeofday(): @@ -134,13 +132,10 @@ static inline bool timespec64_valid_settod(const struct timespec64 *ts) */ static inline s64 timespec64_to_ns(const struct timespec64 *ts) { - /* Prevent multiplication overflow / underflow */ - if (ts->tv_sec >= KTIME_SEC_MAX) + /* Prevent multiplication overflow */ + if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) return KTIME_MAX; - if (ts->tv_sec <= KTIME_SEC_MIN) - return KTIME_MIN; - return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; } From 48a24510c328b3b3d7775377494b4ad4f58d189a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Sep 2021 12:56:14 +0200 Subject: [PATCH 150/150] Linux 5.4.147 Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 48d0c03acfc5..98227dae3494 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 146 +SUBLEVEL = 147 EXTRAVERSION = NAME = Kleptomaniac Octopus