From: Sasha Levin Date: Wed, 10 Feb 2021 16:35:01 +0000 (-0500) Subject: Fixes for 5.4 X-Git-Tag: v4.19.176~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=73dbde0cfbbe8b3788bf43c6634c4aa540f00e9a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/af_key-relax-availability-checks-for-skb-size-calcul.patch b/queue-5.4/af_key-relax-availability-checks-for-skb-size-calcul.patch new file mode 100644 index 00000000000..7f3c4725c83 --- /dev/null +++ b/queue-5.4/af_key-relax-availability-checks-for-skb-size-calcul.patch @@ -0,0 +1,64 @@ +From 96a69701c56be40a9a9cdf674a764c0e2bb6b5a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Dec 2020 16:50:20 -0800 +Subject: af_key: relax availability checks for skb size calculation + +From: Cong Wang + +[ Upstream commit afbc293add6466f8f3f0c3d944d85f53709c170f ] + +xfrm_probe_algs() probes kernel crypto modules and changes the +availability of struct xfrm_algo_desc. But there is a small window +where ealg->available and aalg->available get changed between +count_ah_combs()/count_esp_combs() and dump_ah_combs()/dump_esp_combs(), +in this case we may allocate a smaller skb but later put a larger +amount of data and trigger the panic in skb_put(). + +Fix this by relaxing the checks when counting the size, that is, +skipping the test of ->available. We may waste some memory for a few +of sizeof(struct sadb_comb), but it is still much better than a panic. + +Reported-by: syzbot+b2bf2652983d23734c5c@syzkaller.appspotmail.com +Cc: Steffen Klassert +Cc: Herbert Xu +Signed-off-by: Cong Wang +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/key/af_key.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/key/af_key.c b/net/key/af_key.c +index a915bc86620af..907d04a474597 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2902,7 +2902,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t) + break; + if (!aalg->pfkey_supported) + continue; +- if (aalg_tmpl_set(t, aalg) && aalg->available) ++ if (aalg_tmpl_set(t, aalg)) + sz += sizeof(struct sadb_comb); + } + return sz + sizeof(struct sadb_prop); +@@ -2920,7 +2920,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) + if (!ealg->pfkey_supported) + continue; + +- if (!(ealg_tmpl_set(t, ealg) && ealg->available)) ++ if (!(ealg_tmpl_set(t, ealg))) + continue; + + for (k = 1; ; k++) { +@@ -2931,7 +2931,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) + if (!aalg->pfkey_supported) + continue; + +- if (aalg_tmpl_set(t, aalg) && aalg->available) ++ if (aalg_tmpl_set(t, aalg)) + sz += sizeof(struct sadb_comb); + } + } +-- +2.27.0 + diff --git a/queue-5.4/asoc-ak4458-correct-reset-polarity.patch b/queue-5.4/asoc-ak4458-correct-reset-polarity.patch new file mode 100644 index 00000000000..92ed05b47dc --- /dev/null +++ b/queue-5.4/asoc-ak4458-correct-reset-polarity.patch @@ -0,0 +1,87 @@ +From ce8a29b5816e23eeef615a75e338fdbc7db57c54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 21:27:08 +1300 +Subject: ASoC: ak4458: correct reset polarity + +From: Eliot Blennerhassett + +[ Upstream commit e953daeb68b1abd8a7d44902786349fdeef5c297 ] + +Reset (aka power off) happens when the reset gpio is made active. +Change function name to ak4458_reset to match devicetree property "reset-gpios" + +Signed-off-by: Eliot Blennerhassett +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/ce650f47-4ff6-e486-7846-cc3d033f3601@blennerhassett.gen.nz +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/ak4458.c | 22 +++++++--------------- + 1 file changed, 7 insertions(+), 15 deletions(-) + +diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c +index 71562154c0b1e..217e8ce9a4ba4 100644 +--- a/sound/soc/codecs/ak4458.c ++++ b/sound/soc/codecs/ak4458.c +@@ -523,18 +523,10 @@ static struct snd_soc_dai_driver ak4497_dai = { + .ops = &ak4458_dai_ops, + }; + +-static void ak4458_power_off(struct ak4458_priv *ak4458) ++static void ak4458_reset(struct ak4458_priv *ak4458, bool active) + { + if (ak4458->reset_gpiod) { +- gpiod_set_value_cansleep(ak4458->reset_gpiod, 0); +- usleep_range(1000, 2000); +- } +-} +- +-static void ak4458_power_on(struct ak4458_priv *ak4458) +-{ +- if (ak4458->reset_gpiod) { +- gpiod_set_value_cansleep(ak4458->reset_gpiod, 1); ++ gpiod_set_value_cansleep(ak4458->reset_gpiod, active); + usleep_range(1000, 2000); + } + } +@@ -548,7 +540,7 @@ static int ak4458_init(struct snd_soc_component *component) + if (ak4458->mute_gpiod) + gpiod_set_value_cansleep(ak4458->mute_gpiod, 1); + +- ak4458_power_on(ak4458); ++ ak4458_reset(ak4458, false); + + ret = snd_soc_component_update_bits(component, AK4458_00_CONTROL1, + 0x80, 0x80); /* ACKS bit = 1; 10000000 */ +@@ -571,7 +563,7 @@ static void ak4458_remove(struct snd_soc_component *component) + { + struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component); + +- ak4458_power_off(ak4458); ++ ak4458_reset(ak4458, true); + } + + #ifdef CONFIG_PM +@@ -581,7 +573,7 @@ static int __maybe_unused ak4458_runtime_suspend(struct device *dev) + + regcache_cache_only(ak4458->regmap, true); + +- ak4458_power_off(ak4458); ++ ak4458_reset(ak4458, true); + + if (ak4458->mute_gpiod) + gpiod_set_value_cansleep(ak4458->mute_gpiod, 0); +@@ -596,8 +588,8 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev) + if (ak4458->mute_gpiod) + gpiod_set_value_cansleep(ak4458->mute_gpiod, 1); + +- ak4458_power_off(ak4458); +- ak4458_power_on(ak4458); ++ ak4458_reset(ak4458, true); ++ ak4458_reset(ak4458, false); + + regcache_cache_only(ak4458->regmap, false); + regcache_mark_dirty(ak4458->regmap); +-- +2.27.0 + diff --git a/queue-5.4/asoc-intel-skylake-zero-snd_ctl_elem_value.patch b/queue-5.4/asoc-intel-skylake-zero-snd_ctl_elem_value.patch new file mode 100644 index 00000000000..5478c5138a5 --- /dev/null +++ b/queue-5.4/asoc-intel-skylake-zero-snd_ctl_elem_value.patch @@ -0,0 +1,38 @@ +From 61a755ef69d38c1d65af0dd73839a736e2f85d0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 18:16:44 +0100 +Subject: ASoC: Intel: Skylake: Zero snd_ctl_elem_value + +From: Ricardo Ribalda + +[ Upstream commit 1d8fe0648e118fd495a2cb393a34eb8d428e7808 ] + +Clear struct snd_ctl_elem_value before calling ->put() to avoid any data +leak. + +Signed-off-by: Ricardo Ribalda +Reviewed-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20210121171644.131059-2-ribalda@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/skylake/skl-topology.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c +index 2cb719893324a..1940b17f27efa 100644 +--- a/sound/soc/intel/skylake/skl-topology.c ++++ b/sound/soc/intel/skylake/skl-topology.c +@@ -3632,7 +3632,7 @@ static void skl_tplg_complete(struct snd_soc_component *component) + sprintf(chan_text, "c%d", mach->mach_params.dmic_num); + + for (i = 0; i < se->items; i++) { +- struct snd_ctl_elem_value val; ++ struct snd_ctl_elem_value val = {}; + + if (strstr(texts[i], chan_text)) { + val.value.enumerated.item[0] = i; +-- +2.27.0 + diff --git a/queue-5.4/blk-cgroup-use-cond_resched-when-destroy-blkgs.patch b/queue-5.4/blk-cgroup-use-cond_resched-when-destroy-blkgs.patch new file mode 100644 index 00000000000..8dc05d78aa7 --- /dev/null +++ b/queue-5.4/blk-cgroup-use-cond_resched-when-destroy-blkgs.patch @@ -0,0 +1,79 @@ +From fc961d42e7003b7629aa1092fa7ccd678a082fbb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Jan 2021 13:58:15 +0800 +Subject: blk-cgroup: Use cond_resched() when destroy blkgs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Baolin Wang + +[ Upstream commit 6c635caef410aa757befbd8857c1eadde5cc22ed ] + +On !PREEMPT kernel, we can get below softlockup when doing stress +testing with creating and destroying block cgroup repeatly. The +reason is it may take a long time to acquire the queue's lock in +the loop of blkcg_destroy_blkgs(), or the system can accumulate a +huge number of blkgs in pathological cases. We can add a need_resched() +check on each loop and release locks and do cond_resched() if true +to avoid this issue, since the blkcg_destroy_blkgs() is not called +from atomic contexts. + +[ 4757.010308] watchdog: BUG: soft lockup - CPU#11 stuck for 94s! +[ 4757.010698] Call trace: +[ 4757.010700]  blkcg_destroy_blkgs+0x68/0x150 +[ 4757.010701]  cgwb_release_workfn+0x104/0x158 +[ 4757.010702]  process_one_work+0x1bc/0x3f0 +[ 4757.010704]  worker_thread+0x164/0x468 +[ 4757.010705]  kthread+0x108/0x138 + +Suggested-by: Tejun Heo +Signed-off-by: Baolin Wang +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-cgroup.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c +index 3d34ac02d76ef..cb3d44d200055 100644 +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -1089,6 +1089,8 @@ static void blkcg_css_offline(struct cgroup_subsys_state *css) + */ + void blkcg_destroy_blkgs(struct blkcg *blkcg) + { ++ might_sleep(); ++ + spin_lock_irq(&blkcg->lock); + + while (!hlist_empty(&blkcg->blkg_list)) { +@@ -1096,14 +1098,20 @@ void blkcg_destroy_blkgs(struct blkcg *blkcg) + struct blkcg_gq, blkcg_node); + struct request_queue *q = blkg->q; + +- if (spin_trylock(&q->queue_lock)) { +- blkg_destroy(blkg); +- spin_unlock(&q->queue_lock); +- } else { ++ if (need_resched() || !spin_trylock(&q->queue_lock)) { ++ /* ++ * Given that the system can accumulate a huge number ++ * of blkgs in pathological cases, check to see if we ++ * need to rescheduling to avoid softlockup. ++ */ + spin_unlock_irq(&blkcg->lock); +- cpu_relax(); ++ cond_resched(); + spin_lock_irq(&blkcg->lock); ++ continue; + } ++ ++ blkg_destroy(blkg); ++ spin_unlock(&q->queue_lock); + } + + spin_unlock_irq(&blkcg->lock); +-- +2.27.0 + diff --git a/queue-5.4/chtls-fix-potential-resource-leak.patch b/queue-5.4/chtls-fix-potential-resource-leak.patch new file mode 100644 index 00000000000..1ae86e25a02 --- /dev/null +++ b/queue-5.4/chtls-fix-potential-resource-leak.patch @@ -0,0 +1,51 @@ +From 6b8bf4f2ae23e0c3e83d9a48afdffcb99c88a344 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 06:57:38 -0800 +Subject: chtls: Fix potential resource leak + +From: Pan Bian + +[ Upstream commit b6011966ac6f402847eb5326beee8da3a80405c7 ] + +The dst entry should be released if no neighbour is found. Goto label +free_dst to fix the issue. Besides, the check of ndev against NULL is +redundant. + +Signed-off-by: Pan Bian +Link: https://lore.kernel.org/r/20210121145738.51091-1-bianpan2016@163.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/crypto/chelsio/chtls/chtls_cm.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c +index eddc6d1bdb2d1..82b76df43ae57 100644 +--- a/drivers/crypto/chelsio/chtls/chtls_cm.c ++++ b/drivers/crypto/chelsio/chtls/chtls_cm.c +@@ -1047,11 +1047,9 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + + n = dst_neigh_lookup(dst, &iph->saddr); + if (!n || !n->dev) +- goto free_sk; ++ goto free_dst; + + ndev = n->dev; +- if (!ndev) +- goto free_dst; + if (is_vlan_dev(ndev)) + ndev = vlan_dev_real_dev(ndev); + +@@ -1117,7 +1115,8 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + free_csk: + chtls_sock_release(&csk->kref); + free_dst: +- neigh_release(n); ++ if (n) ++ neigh_release(n); + dst_release(dst); + free_sk: + inet_csk_prepare_forced_close(newsk); +-- +2.27.0 + diff --git a/queue-5.4/i2c-mediatek-move-suspend-and-resume-handling-to-noi.patch b/queue-5.4/i2c-mediatek-move-suspend-and-resume-handling-to-noi.patch new file mode 100644 index 00000000000..58fdb3e7809 --- /dev/null +++ b/queue-5.4/i2c-mediatek-move-suspend-and-resume-handling-to-noi.patch @@ -0,0 +1,74 @@ +From 6e29b98ca6e24be4957ffc6629d29acde9da8292 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 9 Jan 2021 16:29:50 +0800 +Subject: i2c: mediatek: Move suspend and resume handling to NOIRQ phase + +From: Qii Wang + +[ Upstream commit de96c3943f591018727b862f51953c1b6c55bcc3 ] + +Some i2c device driver indirectly uses I2C driver when it is now +being suspended. The i2c devices driver is suspended during the +NOIRQ phase and this cannot be changed due to other dependencies. +Therefore, we also need to move the suspend handling for the I2C +controller driver to the NOIRQ phase as well. + +Signed-off-by: Qii Wang +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-mt65xx.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c +index 5a9f0d17f52c8..e1ef0122ef759 100644 +--- a/drivers/i2c/busses/i2c-mt65xx.c ++++ b/drivers/i2c/busses/i2c-mt65xx.c +@@ -1008,7 +1008,8 @@ static int mtk_i2c_probe(struct platform_device *pdev) + mtk_i2c_clock_disable(i2c); + + ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, +- IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); ++ IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, ++ I2C_DRV_NAME, i2c); + if (ret < 0) { + dev_err(&pdev->dev, + "Request I2C IRQ %d fail\n", irq); +@@ -1035,7 +1036,16 @@ static int mtk_i2c_remove(struct platform_device *pdev) + } + + #ifdef CONFIG_PM_SLEEP +-static int mtk_i2c_resume(struct device *dev) ++static int mtk_i2c_suspend_noirq(struct device *dev) ++{ ++ struct mtk_i2c *i2c = dev_get_drvdata(dev); ++ ++ i2c_mark_adapter_suspended(&i2c->adap); ++ ++ return 0; ++} ++ ++static int mtk_i2c_resume_noirq(struct device *dev) + { + int ret; + struct mtk_i2c *i2c = dev_get_drvdata(dev); +@@ -1050,12 +1060,15 @@ static int mtk_i2c_resume(struct device *dev) + + mtk_i2c_clock_disable(i2c); + ++ i2c_mark_adapter_resumed(&i2c->adap); ++ + return 0; + } + #endif + + static const struct dev_pm_ops mtk_i2c_pm = { +- SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume) ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq, ++ mtk_i2c_resume_noirq) + }; + + static struct platform_driver mtk_i2c_driver = { +-- +2.27.0 + diff --git a/queue-5.4/iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch b/queue-5.4/iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch new file mode 100644 index 00000000000..805e6203bb1 --- /dev/null +++ b/queue-5.4/iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch @@ -0,0 +1,49 @@ +From c386b6e711c2fba24ada439daf0f07c315fcb4cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 14:52:41 +0200 +Subject: iwlwifi: mvm: guard against device removal in reprobe + +From: Johannes Berg + +[ Upstream commit 7a21b1d4a728a483f07c638ccd8610d4b4f12684 ] + +If we get into a problem severe enough to attempt a reprobe, +we schedule a worker to do that. However, if the problem gets +more severe and the device is actually destroyed before this +worker has a chance to run, we use a free device. Bump up the +reference count of the device until the worker runs to avoid +this situation. + +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210122144849.871f0892e4b2.I94819e11afd68d875f3e242b98bef724b8236f1e@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +index bc25a59807c34..8b0576cde797e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -1242,6 +1242,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk) + reprobe = container_of(wk, struct iwl_mvm_reprobe, work); + if (device_reprobe(reprobe->dev)) + dev_err(reprobe->dev, "reprobe failed!\n"); ++ put_device(reprobe->dev); + kfree(reprobe); + module_put(THIS_MODULE); + } +@@ -1292,7 +1293,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) + module_put(THIS_MODULE); + return; + } +- reprobe->dev = mvm->trans->dev; ++ reprobe->dev = get_device(mvm->trans->dev); + INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); + schedule_work(&reprobe->work); + } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, +-- +2.27.0 + diff --git a/queue-5.4/iwlwifi-mvm-invalidate-ids-of-internal-stations-at-m.patch b/queue-5.4/iwlwifi-mvm-invalidate-ids-of-internal-stations-at-m.patch new file mode 100644 index 00000000000..21946ad4dc1 --- /dev/null +++ b/queue-5.4/iwlwifi-mvm-invalidate-ids-of-internal-stations-at-m.patch @@ -0,0 +1,70 @@ +From 5944928144876f7c9b0dbe933c6ebca18a0a3f1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 14:52:37 +0200 +Subject: iwlwifi: mvm: invalidate IDs of internal stations at mvm start + +From: Gregory Greenman + +[ Upstream commit e223e42aac30bf81f9302c676cdf58cf2bf36950 ] + +Having sta_id not set for aux_sta and snif_sta can potentially lead to a +hard to debug issue in case remove station is called without an add. In +this case sta_id 0, an unrelated regular station, will be removed. + +In fact, we do have a FW assert that occures rarely and from the debug +data analysis it looks like sta_id 0 is removed by mistake, though it's +hard to pinpoint the exact flow. The WARN_ON in this patch should help +to find it. + +Signed-off-by: Gregory Greenman +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210122144849.5dc6dd9b22d5.I2add1b5ad24d0d0a221de79d439c09f88fcaf15d@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ++++ + drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 6 ++++++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +index b04cc6214bac8..bc25a59807c34 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -838,6 +838,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, + if (!mvm->scan_cmd) + goto out_free; + ++ /* invalidate ids to prevent accidental removal of sta_id 0 */ ++ mvm->aux_sta.sta_id = IWL_MVM_INVALID_STA; ++ mvm->snif_sta.sta_id = IWL_MVM_INVALID_STA; ++ + /* Set EBS as successful as long as not stated otherwise by the FW. */ + mvm->last_ebs_successful = true; + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index a36aa9e85e0b3..40cafcf40ccf0 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -2070,6 +2070,9 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) + + lockdep_assert_held(&mvm->mutex); + ++ if (WARN_ON_ONCE(mvm->snif_sta.sta_id == IWL_MVM_INVALID_STA)) ++ return -EINVAL; ++ + iwl_mvm_disable_txq(mvm, NULL, mvm->snif_queue, IWL_MAX_TID_COUNT, 0); + ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id); + if (ret) +@@ -2084,6 +2087,9 @@ int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm) + + lockdep_assert_held(&mvm->mutex); + ++ if (WARN_ON_ONCE(mvm->aux_sta.sta_id == IWL_MVM_INVALID_STA)) ++ return -EINVAL; ++ + iwl_mvm_disable_txq(mvm, NULL, mvm->aux_queue, IWL_MAX_TID_COUNT, 0); + ret = iwl_mvm_rm_sta_common(mvm, mvm->aux_sta.sta_id); + if (ret) +-- +2.27.0 + diff --git a/queue-5.4/iwlwifi-mvm-skip-power-command-when-unbinding-vif-du.patch b/queue-5.4/iwlwifi-mvm-skip-power-command-when-unbinding-vif-du.patch new file mode 100644 index 00000000000..a841b9e0896 --- /dev/null +++ b/queue-5.4/iwlwifi-mvm-skip-power-command-when-unbinding-vif-du.patch @@ -0,0 +1,43 @@ +From 58093a557e64e3e750b4c9bec63ffda6df832977 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jan 2021 13:05:47 +0200 +Subject: iwlwifi: mvm: skip power command when unbinding vif during CSA + +From: Sara Sharon + +[ Upstream commit bf544e9aa570034e094a8a40d5f9e1e2c4916d18 ] + +In the new CSA flow, we remain associated during CSA, but +still do a unbind-bind to the vif. However, sending the power +command right after when vif is unbound but still associated +causes FW to assert (0x3400) since it cannot tell the LMAC id. + +Just skip this command, we will send it again in a bit, when +assigning the new context. + +Signed-off-by: Sara Sharon +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210115130252.64a2254ac5c3.Iaa3a9050bf3d7c9cd5beaf561e932e6defc12ec3@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index daae86cd61140..fc6430edd1107 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -4169,6 +4169,9 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, + iwl_mvm_binding_remove_vif(mvm, vif); + + out: ++ if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD) && ++ switching_chanctx) ++ return; + mvmvif->phy_ctxt = NULL; + iwl_mvm_power_update_mac(mvm); + } +-- +2.27.0 + diff --git a/queue-5.4/iwlwifi-mvm-take-mutex-for-calling-iwl_mvm_get_sync_.patch b/queue-5.4/iwlwifi-mvm-take-mutex-for-calling-iwl_mvm_get_sync_.patch new file mode 100644 index 00000000000..b206910db86 --- /dev/null +++ b/queue-5.4/iwlwifi-mvm-take-mutex-for-calling-iwl_mvm_get_sync_.patch @@ -0,0 +1,38 @@ +From 4b3f90bf062817923ae0cc3ec0324caf33d7f068 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jan 2021 13:05:48 +0200 +Subject: iwlwifi: mvm: take mutex for calling iwl_mvm_get_sync_time() + +From: Johannes Berg + +[ Upstream commit 5c56d862c749669d45c256f581eac4244be00d4d ] + +We need to take the mutex to call iwl_mvm_get_sync_time(), do it. + +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210115130252.4bb5ccf881a6.I62973cbb081e80aa5b0447a5c3b9c3251a65cf6b@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +index f043eefabb4ec..7b1d2dac6ceb8 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +@@ -514,7 +514,10 @@ static ssize_t iwl_dbgfs_os_device_timediff_read(struct file *file, + const size_t bufsz = sizeof(buf); + int pos = 0; + ++ mutex_lock(&mvm->mutex); + iwl_mvm_get_sync_time(mvm, &curr_gp2, &curr_os); ++ mutex_unlock(&mvm->mutex); ++ + do_div(curr_os, NSEC_PER_USEC); + diff = curr_os - curr_gp2; + pos += scnprintf(buf + pos, bufsz - pos, "diff=%lld\n", diff); +-- +2.27.0 + diff --git a/queue-5.4/iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch b/queue-5.4/iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch new file mode 100644 index 00000000000..9832341c111 --- /dev/null +++ b/queue-5.4/iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch @@ -0,0 +1,40 @@ +From 80c3337e5fef8a7b9f7c03de57d1f9295bcad94f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jan 2021 13:05:55 +0200 +Subject: iwlwifi: pcie: add a NULL check in iwl_pcie_txq_unmap + +From: Emmanuel Grumbach + +[ Upstream commit 98c7d21f957b10d9c07a3a60a3a5a8f326a197e5 ] + +I hit a NULL pointer exception in this function when the +init flow went really bad. + +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210115130252.2e8da9f2c132.I0234d4b8ddaf70aaa5028a20c863255e05bc1f84@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index d3b58334e13ea..e7dcf8bc99b7c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -657,6 +657,11 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_txq *txq = trans_pcie->txq[txq_id]; + ++ if (!txq) { ++ IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n"); ++ return; ++ } ++ + spin_lock_bh(&txq->lock); + while (txq->write_ptr != txq->read_ptr) { + IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", +-- +2.27.0 + diff --git a/queue-5.4/iwlwifi-pcie-fix-context-info-memory-leak.patch b/queue-5.4/iwlwifi-pcie-fix-context-info-memory-leak.patch new file mode 100644 index 00000000000..4f196460e3a --- /dev/null +++ b/queue-5.4/iwlwifi-pcie-fix-context-info-memory-leak.patch @@ -0,0 +1,53 @@ +From 96764e5993eb0ab07294299a6f1300295ff65a79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jan 2021 13:05:56 +0200 +Subject: iwlwifi: pcie: fix context info memory leak + +From: Johannes Berg + +[ Upstream commit 2d6bc752cc2806366d9a4fd577b3f6c1f7a7e04e ] + +If the image loader allocation fails, we leak all the previously +allocated memory. Fix this. + +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210115130252.97172cbaa67c.I3473233d0ad01a71aa9400832fb2b9f494d88a11@changeid +Signed-off-by: Sasha Levin +--- + .../net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +index 7a5b024a6d384..eab159205e48b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +@@ -164,8 +164,10 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, + /* Allocate IML */ + iml_img = dma_alloc_coherent(trans->dev, trans->iml_len, + &trans_pcie->iml_dma_addr, GFP_KERNEL); +- if (!iml_img) +- return -ENOMEM; ++ if (!iml_img) { ++ ret = -ENOMEM; ++ goto err_free_ctxt_info; ++ } + + memcpy(iml_img, trans->iml, trans->iml_len); + +@@ -207,6 +209,11 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, + + return 0; + ++err_free_ctxt_info: ++ dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3), ++ trans_pcie->ctxt_info_gen3, ++ trans_pcie->ctxt_info_dma_addr); ++ trans_pcie->ctxt_info_gen3 = NULL; + err_free_prph_info: + dma_free_coherent(trans->dev, + sizeof(*prph_info), +-- +2.27.0 + diff --git a/queue-5.4/mac80211-160mhz-with-extended-nss-bw-in-csa.patch b/queue-5.4/mac80211-160mhz-with-extended-nss-bw-in-csa.patch new file mode 100644 index 00000000000..9c299722411 --- /dev/null +++ b/queue-5.4/mac80211-160mhz-with-extended-nss-bw-in-csa.patch @@ -0,0 +1,53 @@ +From a2cd43c822e8f89b16e1638c33d5d879cbdd03d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Dec 2020 08:47:14 +0200 +Subject: mac80211: 160MHz with extended NSS BW in CSA + +From: Shay Bar + +[ Upstream commit dcf3c8fb32ddbfa3b8227db38aa6746405bd4527 ] + +Upon receiving CSA with 160MHz extended NSS BW from associated AP, +STA should set the HT operation_mode based on new_center_freq_seg1 +because it is later used as ccfs2 in ieee80211_chandef_vht_oper(). + +Signed-off-by: Aviad Brikman +Signed-off-by: Shay Bar +Link: https://lore.kernel.org/r/20201222064714.24888-1-shay.bar@celeno.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/spectmgmt.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c +index 5fe2b645912f6..132f8423addaa 100644 +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -132,16 +132,20 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, + } + + if (wide_bw_chansw_ie) { ++ u8 new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1; + struct ieee80211_vht_operation vht_oper = { + .chan_width = + wide_bw_chansw_ie->new_channel_width, + .center_freq_seg0_idx = + wide_bw_chansw_ie->new_center_freq_seg0, +- .center_freq_seg1_idx = +- wide_bw_chansw_ie->new_center_freq_seg1, ++ .center_freq_seg1_idx = new_seg1, + /* .basic_mcs_set doesn't matter */ + }; +- struct ieee80211_ht_operation ht_oper = {}; ++ struct ieee80211_ht_operation ht_oper = { ++ .operation_mode = ++ cpu_to_le16(new_seg1 << ++ IEEE80211_HT_OP_MODE_CCFS2_SHIFT), ++ }; + + /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT, + * to the previously parsed chandef +-- +2.27.0 + diff --git a/queue-5.4/pnfs-nfsv4-try-to-return-invalid-layout-in-pnfs_layo.patch b/queue-5.4/pnfs-nfsv4-try-to-return-invalid-layout-in-pnfs_layo.patch new file mode 100644 index 00000000000..4039540b537 --- /dev/null +++ b/queue-5.4/pnfs-nfsv4-try-to-return-invalid-layout-in-pnfs_layo.patch @@ -0,0 +1,42 @@ +From c12e3499ca3f4d7306d04ccf2b34dc820c3af6b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 17:11:42 -0500 +Subject: pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process() + +From: Trond Myklebust + +[ Upstream commit 08bd8dbe88825760e953759d7ec212903a026c75 ] + +If the server returns a new stateid that does not match the one in our +cache, then try to return the one we hold instead of just invalidating +it on the client side. This ensures that both client and server will +agree that the stateid is invalid. + +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/pnfs.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index ca1d98f274d12..e3a79e6958124 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2369,7 +2369,13 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) + * We got an entirely new state ID. Mark all segments for the + * inode invalid, and retry the layoutget + */ +- pnfs_mark_layout_stateid_invalid(lo, &free_me); ++ struct pnfs_layout_range range = { ++ .iomode = IOMODE_ANY, ++ .length = NFS4_MAX_UINT64, ++ }; ++ pnfs_set_plh_return_info(lo, IOMODE_ANY, 0); ++ pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, ++ &range, 0); + goto out_forget; + } + +-- +2.27.0 + diff --git a/queue-5.4/regulator-core-avoid-regulator_resolve_supply-race-c.patch b/queue-5.4/regulator-core-avoid-regulator_resolve_supply-race-c.patch new file mode 100644 index 00000000000..30c36075b92 --- /dev/null +++ b/queue-5.4/regulator-core-avoid-regulator_resolve_supply-race-c.patch @@ -0,0 +1,155 @@ +From 0ac97cd370de45f20c29193b28eb7e2ab543988a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Jan 2021 17:16:02 -0800 +Subject: regulator: core: avoid regulator_resolve_supply() race condition + +From: David Collins + +[ Upstream commit eaa7995c529b54d68d97a30f6344cc6ca2f214a7 ] + +The final step in regulator_register() is to call +regulator_resolve_supply() for each registered regulator +(including the one in the process of being registered). The +regulator_resolve_supply() function first checks if rdev->supply +is NULL, then it performs various steps to try to find the supply. +If successful, rdev->supply is set inside of set_supply(). + +This procedure can encounter a race condition if two concurrent +tasks call regulator_register() near to each other on separate CPUs +and one of the regulators has rdev->supply_name specified. There +is currently nothing guaranteeing atomicity between the rdev->supply +check and set steps. Thus, both tasks can observe rdev->supply==NULL +in their regulator_resolve_supply() calls. This then results in +both creating a struct regulator for the supply. One ends up +actually stored in rdev->supply and the other is lost (though still +present in the supply's consumer_list). + +Here is a kernel log snippet showing the issue: + +[ 12.421768] gpu_cc_gx_gdsc: supplied by pm8350_s5_level +[ 12.425854] gpu_cc_gx_gdsc: supplied by pm8350_s5_level +[ 12.429064] debugfs: Directory 'regulator.4-SUPPLY' with parent + '17a00000.rsc:rpmh-regulator-gfxlvl-pm8350_s5_level' + already present! + +Avoid this race condition by holding the rdev->mutex lock inside +of regulator_resolve_supply() while checking and setting +rdev->supply. + +Signed-off-by: David Collins +Link: https://lore.kernel.org/r/1610068562-4410-1-git-send-email-collinsd@codeaurora.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 39 ++++++++++++++++++++++++++++----------- + 1 file changed, 28 insertions(+), 11 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index c9b8613e69db2..5e0490e18b46a 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1772,23 +1772,34 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + { + struct regulator_dev *r; + struct device *dev = rdev->dev.parent; +- int ret; ++ int ret = 0; + + /* No supply to resolve? */ + if (!rdev->supply_name) + return 0; + +- /* Supply already resolved? */ ++ /* Supply already resolved? (fast-path without locking contention) */ + if (rdev->supply) + return 0; + ++ /* ++ * Recheck rdev->supply with rdev->mutex lock held to avoid a race ++ * between rdev->supply null check and setting rdev->supply in ++ * set_supply() from concurrent tasks. ++ */ ++ regulator_lock(rdev); ++ ++ /* Supply just resolved by a concurrent task? */ ++ if (rdev->supply) ++ goto out; ++ + r = regulator_dev_lookup(dev, rdev->supply_name); + if (IS_ERR(r)) { + ret = PTR_ERR(r); + + /* Did the lookup explicitly defer for us? */ + if (ret == -EPROBE_DEFER) +- return ret; ++ goto out; + + if (have_full_constraints()) { + r = dummy_regulator_rdev; +@@ -1796,15 +1807,18 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + } else { + dev_err(dev, "Failed to resolve %s-supply for %s\n", + rdev->supply_name, rdev->desc->name); +- return -EPROBE_DEFER; ++ ret = -EPROBE_DEFER; ++ goto out; + } + } + + if (r == rdev) { + dev_err(dev, "Supply for %s (%s) resolved to itself\n", + rdev->desc->name, rdev->supply_name); +- if (!have_full_constraints()) +- return -EINVAL; ++ if (!have_full_constraints()) { ++ ret = -EINVAL; ++ goto out; ++ } + r = dummy_regulator_rdev; + get_device(&r->dev); + } +@@ -1818,7 +1832,8 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + if (r->dev.parent && r->dev.parent != rdev->dev.parent) { + if (!device_is_bound(r->dev.parent)) { + put_device(&r->dev); +- return -EPROBE_DEFER; ++ ret = -EPROBE_DEFER; ++ goto out; + } + } + +@@ -1826,13 +1841,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + ret = regulator_resolve_supply(r); + if (ret < 0) { + put_device(&r->dev); +- return ret; ++ goto out; + } + + ret = set_supply(rdev, r); + if (ret < 0) { + put_device(&r->dev); +- return ret; ++ goto out; + } + + /* +@@ -1845,11 +1860,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + if (ret < 0) { + _regulator_put(rdev->supply); + rdev->supply = NULL; +- return ret; ++ goto out; + } + } + +- return 0; ++out: ++ regulator_unlock(rdev); ++ return ret; + } + + /* Internal regulator request function */ +-- +2.27.0 + diff --git a/queue-5.4/regulator-fix-lockdep-warning-resolving-supplies.patch b/queue-5.4/regulator-fix-lockdep-warning-resolving-supplies.patch new file mode 100644 index 00000000000..e36536cb3a5 --- /dev/null +++ b/queue-5.4/regulator-fix-lockdep-warning-resolving-supplies.patch @@ -0,0 +1,94 @@ +From c6660b34d123414351093392077abbf8399618bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 13:20:42 +0000 +Subject: regulator: Fix lockdep warning resolving supplies + +From: Mark Brown + +[ Upstream commit 14a71d509ac809dcf56d7e3ca376b15d17bd0ddd ] + +With commit eaa7995c529b54 (regulator: core: avoid +regulator_resolve_supply() race condition) we started holding the rdev +lock while resolving supplies, an operation that requires holding the +regulator_list_mutex. This results in lockdep warnings since in other +places we take the list mutex then the mutex on an individual rdev. + +Since the goal is to make sure that we don't call set_supply() twice +rather than a concern about the cost of resolution pull the rdev lock +and check for duplicate resolution down to immediately before we do the +set_supply() and drop it again once the allocation is done. + +Fixes: eaa7995c529b54 (regulator: core: avoid regulator_resolve_supply() race condition) +Reported-by: Marek Szyprowski +Tested-by: Marek Szyprowski +Signed-off-by: Mark Brown +Link: https://lore.kernel.org/r/20210122132042.10306-1-broonie@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 5e0490e18b46a..5b9d570df85cc 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1782,17 +1782,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + if (rdev->supply) + return 0; + +- /* +- * Recheck rdev->supply with rdev->mutex lock held to avoid a race +- * between rdev->supply null check and setting rdev->supply in +- * set_supply() from concurrent tasks. +- */ +- regulator_lock(rdev); +- +- /* Supply just resolved by a concurrent task? */ +- if (rdev->supply) +- goto out; +- + r = regulator_dev_lookup(dev, rdev->supply_name); + if (IS_ERR(r)) { + ret = PTR_ERR(r); +@@ -1844,12 +1833,29 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + goto out; + } + ++ /* ++ * Recheck rdev->supply with rdev->mutex lock held to avoid a race ++ * between rdev->supply null check and setting rdev->supply in ++ * set_supply() from concurrent tasks. ++ */ ++ regulator_lock(rdev); ++ ++ /* Supply just resolved by a concurrent task? */ ++ if (rdev->supply) { ++ regulator_unlock(rdev); ++ put_device(&r->dev); ++ goto out; ++ } ++ + ret = set_supply(rdev, r); + if (ret < 0) { ++ regulator_unlock(rdev); + put_device(&r->dev); + goto out; + } + ++ regulator_unlock(rdev); ++ + /* + * In set_machine_constraints() we may have turned this regulator on + * but we couldn't propagate to the supply if it hadn't been resolved +@@ -1865,7 +1871,6 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + } + + out: +- regulator_unlock(rdev); + return ret; + } + +-- +2.27.0 + diff --git a/queue-5.4/series b/queue-5.4/series index cd3ec3ba600..68cfb89f695 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -1 +1,19 @@ tracing-kprobe-fix-to-support-kretprobe-events-on-unloaded-modules.patch +af_key-relax-availability-checks-for-skb-size-calcul.patch +regulator-core-avoid-regulator_resolve_supply-race-c.patch +mac80211-160mhz-with-extended-nss-bw-in-csa.patch +asoc-intel-skylake-zero-snd_ctl_elem_value.patch +chtls-fix-potential-resource-leak.patch +pnfs-nfsv4-try-to-return-invalid-layout-in-pnfs_layo.patch +asoc-ak4458-correct-reset-polarity.patch +iwlwifi-mvm-skip-power-command-when-unbinding-vif-du.patch +iwlwifi-mvm-take-mutex-for-calling-iwl_mvm_get_sync_.patch +iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch +iwlwifi-pcie-fix-context-info-memory-leak.patch +iwlwifi-mvm-invalidate-ids-of-internal-stations-at-m.patch +iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch +sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch +sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch +i2c-mediatek-move-suspend-and-resume-handling-to-noi.patch +blk-cgroup-use-cond_resched-when-destroy-blkgs.patch +regulator-fix-lockdep-warning-resolving-supplies.patch diff --git a/queue-5.4/sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch b/queue-5.4/sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch new file mode 100644 index 00000000000..f1159d2cc7c --- /dev/null +++ b/queue-5.4/sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch @@ -0,0 +1,79 @@ +From a30fe7cf711a840f99cecbf3507086c149269f8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 16:17:24 -0500 +Subject: SUNRPC: Handle 0 length opaque XDR object data properly + +From: Dave Wysochanski + +[ Upstream commit e4a7d1f7707eb44fd953a31dd59eff82009d879c ] + +When handling an auth_gss downcall, it's possible to get 0-length +opaque object for the acceptor. In the case of a 0-length XDR +object, make sure simple_get_netobj() fills in dest->data = NULL, +and does not continue to kmemdup() which will set +dest->data = ZERO_SIZE_PTR for the acceptor. + +The trace event code can handle NULL but not ZERO_SIZE_PTR for a +string, and so without this patch the rpcgss_context trace event +will crash the kernel as follows: + +[ 162.887992] BUG: kernel NULL pointer dereference, address: 0000000000000010 +[ 162.898693] #PF: supervisor read access in kernel mode +[ 162.900830] #PF: error_code(0x0000) - not-present page +[ 162.902940] PGD 0 P4D 0 +[ 162.904027] Oops: 0000 [#1] SMP PTI +[ 162.905493] CPU: 4 PID: 4321 Comm: rpc.gssd Kdump: loaded Not tainted 5.10.0 #133 +[ 162.908548] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 +[ 162.910978] RIP: 0010:strlen+0x0/0x20 +[ 162.912505] Code: 48 89 f9 74 09 48 83 c1 01 80 39 00 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 0f 1f 80 00 00 00 00 <80> 3f 00 74 10 48 89 f8 48 83 c0 01 80 38 00 75 f7 48 29 f8 c3 31 +[ 162.920101] RSP: 0018:ffffaec900c77d90 EFLAGS: 00010202 +[ 162.922263] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000fffde697 +[ 162.925158] RDX: 000000000000002f RSI: 0000000000000080 RDI: 0000000000000010 +[ 162.928073] RBP: 0000000000000010 R08: 0000000000000e10 R09: 0000000000000000 +[ 162.930976] R10: ffff8e698a590cb8 R11: 0000000000000001 R12: 0000000000000e10 +[ 162.933883] R13: 00000000fffde697 R14: 000000010034d517 R15: 0000000000070028 +[ 162.936777] FS: 00007f1e1eb93700(0000) GS:ffff8e6ab7d00000(0000) knlGS:0000000000000000 +[ 162.940067] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 162.942417] CR2: 0000000000000010 CR3: 0000000104eba000 CR4: 00000000000406e0 +[ 162.945300] Call Trace: +[ 162.946428] trace_event_raw_event_rpcgss_context+0x84/0x140 [auth_rpcgss] +[ 162.949308] ? __kmalloc_track_caller+0x35/0x5a0 +[ 162.951224] ? gss_pipe_downcall+0x3a3/0x6a0 [auth_rpcgss] +[ 162.953484] gss_pipe_downcall+0x585/0x6a0 [auth_rpcgss] +[ 162.955953] rpc_pipe_write+0x58/0x70 [sunrpc] +[ 162.957849] vfs_write+0xcb/0x2c0 +[ 162.959264] ksys_write+0x68/0xe0 +[ 162.960706] do_syscall_64+0x33/0x40 +[ 162.962238] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 162.964346] RIP: 0033:0x7f1e1f1e57df + +Signed-off-by: Dave Wysochanski +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/auth_gss/auth_gss_internal.h | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h +index c5603242b54bf..f6d9631bd9d00 100644 +--- a/net/sunrpc/auth_gss/auth_gss_internal.h ++++ b/net/sunrpc/auth_gss/auth_gss_internal.h +@@ -34,9 +34,12 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) + q = (const void *)((const char *)p + len); + if (unlikely(q > end || q < p)) + return ERR_PTR(-EFAULT); +- dest->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(dest->data == NULL)) +- return ERR_PTR(-ENOMEM); ++ if (len) { ++ dest->data = kmemdup(p, len, GFP_NOFS); ++ if (unlikely(dest->data == NULL)) ++ return ERR_PTR(-ENOMEM); ++ } else ++ dest->data = NULL; + dest->len = len; + return q; + } +-- +2.27.0 + diff --git a/queue-5.4/sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch b/queue-5.4/sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch new file mode 100644 index 00000000000..606d19ff828 --- /dev/null +++ b/queue-5.4/sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch @@ -0,0 +1,190 @@ +From bfcc26e9a663b9bdaf1a8125327aadd44400d366 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 16:17:23 -0500 +Subject: SUNRPC: Move simple_get_bytes and simple_get_netobj into private + header + +From: Dave Wysochanski + +[ Upstream commit ba6dfce47c4d002d96cd02a304132fca76981172 ] + +Remove duplicated helper functions to parse opaque XDR objects +and place inside new file net/sunrpc/auth_gss/auth_gss_internal.h. +In the new file carry the license and copyright from the source file +net/sunrpc/auth_gss/auth_gss.c. Finally, update the comment inside +include/linux/sunrpc/xdr.h since lockd is not the only user of +struct xdr_netobj. + +Signed-off-by: Dave Wysochanski +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/xdr.h | 3 +- + net/sunrpc/auth_gss/auth_gss.c | 30 +----------------- + net/sunrpc/auth_gss/auth_gss_internal.h | 42 +++++++++++++++++++++++++ + net/sunrpc/auth_gss/gss_krb5_mech.c | 31 ++---------------- + 4 files changed, 46 insertions(+), 60 deletions(-) + create mode 100644 net/sunrpc/auth_gss/auth_gss_internal.h + +diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h +index 9db6097c22c5d..a8d68c5a4ca61 100644 +--- a/include/linux/sunrpc/xdr.h ++++ b/include/linux/sunrpc/xdr.h +@@ -27,8 +27,7 @@ struct rpc_rqst; + #define XDR_QUADLEN(l) (((l) + 3) >> 2) + + /* +- * Generic opaque `network object.' At the kernel level, this type +- * is used only by lockd. ++ * Generic opaque `network object.' + */ + #define XDR_MAX_NETOBJ 1024 + struct xdr_netobj { +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 5fc6c028f89c0..b7a71578bd986 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -29,6 +29,7 @@ + #include + #include + ++#include "auth_gss_internal.h" + #include "../netns.h" + + #include +@@ -125,35 +126,6 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) + clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); + } + +-static const void * +-simple_get_bytes(const void *p, const void *end, void *res, size_t len) +-{ +- const void *q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- memcpy(res, p, len); +- return q; +-} +- +-static inline const void * +-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) +-{ +- const void *q; +- unsigned int len; +- +- p = simple_get_bytes(p, end, &len, sizeof(len)); +- if (IS_ERR(p)) +- return p; +- q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- dest->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(dest->data == NULL)) +- return ERR_PTR(-ENOMEM); +- dest->len = len; +- return q; +-} +- + static struct gss_cl_ctx * + gss_cred_get_ctx(struct rpc_cred *cred) + { +diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h +new file mode 100644 +index 0000000000000..c5603242b54bf +--- /dev/null ++++ b/net/sunrpc/auth_gss/auth_gss_internal.h +@@ -0,0 +1,42 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * linux/net/sunrpc/auth_gss/auth_gss_internal.h ++ * ++ * Internal definitions for RPCSEC_GSS client authentication ++ * ++ * Copyright (c) 2000 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ */ ++#include ++#include ++#include ++ ++static inline const void * ++simple_get_bytes(const void *p, const void *end, void *res, size_t len) ++{ ++ const void *q = (const void *)((const char *)p + len); ++ if (unlikely(q > end || q < p)) ++ return ERR_PTR(-EFAULT); ++ memcpy(res, p, len); ++ return q; ++} ++ ++static inline const void * ++simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) ++{ ++ const void *q; ++ unsigned int len; ++ ++ p = simple_get_bytes(p, end, &len, sizeof(len)); ++ if (IS_ERR(p)) ++ return p; ++ q = (const void *)((const char *)p + len); ++ if (unlikely(q > end || q < p)) ++ return ERR_PTR(-EFAULT); ++ dest->data = kmemdup(p, len, GFP_NOFS); ++ if (unlikely(dest->data == NULL)) ++ return ERR_PTR(-ENOMEM); ++ dest->len = len; ++ return q; ++} +diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c +index 6e5d6d2402158..b552dd4f32f80 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -21,6 +21,8 @@ + #include + #include + ++#include "auth_gss_internal.h" ++ + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) + # define RPCDBG_FACILITY RPCDBG_AUTH + #endif +@@ -164,35 +166,6 @@ get_gss_krb5_enctype(int etype) + return NULL; + } + +-static const void * +-simple_get_bytes(const void *p, const void *end, void *res, int len) +-{ +- const void *q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- memcpy(res, p, len); +- return q; +-} +- +-static const void * +-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) +-{ +- const void *q; +- unsigned int len; +- +- p = simple_get_bytes(p, end, &len, sizeof(len)); +- if (IS_ERR(p)) +- return p; +- q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- res->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(res->data == NULL)) +- return ERR_PTR(-ENOMEM); +- res->len = len; +- return q; +-} +- + static inline const void * + get_key(const void *p, const void *end, + struct krb5_ctx *ctx, struct crypto_sync_skcipher **res) +-- +2.27.0 +