From: Greg Kroah-Hartman Date: Fri, 1 May 2020 13:10:03 +0000 (+0200) Subject: 5.6-stable patches X-Git-Tag: v5.4.37~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9b3477490854582a282329266c54ea6e16c73562;p=thirdparty%2Fkernel%2Fstable-queue.git 5.6-stable patches added patches: asoc-soc-core-disable-route-checks-for-legacy-devices.patch asoc-soc-pcm-fix-regression-in-soc_new_pcm.patch asoc-stm32-spdifrx-fix-regmap-status-check.patch crypto-chelsio-fixes-a-hang-issue-during-driver-registration.patch ext4-check-for-non-zero-journal-inum-in-ext4_calculate_overhead.patch net-use-indirect-call-wrappers-for-skb_copy_datagram_iter.patch qed-fix-race-condition-between-scheduling-and-destroying-the-slowpath-workqueue.patch qed-fix-use-after-free-in-qed_chain_free.patch sfc-fix-xdp-redirect-in-this-driver.patch taprio-do-not-use-bit-in-tca_taprio_attr_flag_-definitions.patch tipc-add-a-missing-case-of-tipc_direct_msg-type.patch --- diff --git a/queue-5.6/asoc-soc-core-disable-route-checks-for-legacy-devices.patch b/queue-5.6/asoc-soc-core-disable-route-checks-for-legacy-devices.patch new file mode 100644 index 00000000000..6d6b3124fae --- /dev/null +++ b/queue-5.6/asoc-soc-core-disable-route-checks-for-legacy-devices.patch @@ -0,0 +1,100 @@ +From a22ae72b86a4f754e8d25fbf9ea5a8f77365e531 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart +Date: Mon, 9 Mar 2020 14:27:43 -0500 +Subject: ASoC: soc-core: disable route checks for legacy devices + +From: Pierre-Louis Bossart + +commit a22ae72b86a4f754e8d25fbf9ea5a8f77365e531 upstream. + +v5.4 changes in soc-core tightened the checks on soc_dapm_add_routes, +which results in the ASoC card probe failing. + +Introduce a flag to be set in machine drivers to prevent the probe +from stopping in case of incomplete topologies or missing routes. This +flag is for backwards compatibility only and shall not be used for +newer machine drivers. + +Example with an HDaudio card with a bad topology: + +[ 236.177898] skl_hda_dsp_generic skl_hda_dsp_generic: ASoC: Failed to +add route iDisp1_out -> direct -> iDisp1 Tx + +[ 236.177902] skl_hda_dsp_generic skl_hda_dsp_generic: +snd_soc_bind_card: snd_soc_dapm_add_routes failed: -19 + +with the disable_route_checks set: + +[ 64.031657] skl_hda_dsp_generic skl_hda_dsp_generic: ASoC: Failed to +add route iDisp1_out -> direct -> iDisp1 Tx + +[ 64.031661] skl_hda_dsp_generic skl_hda_dsp_generic: +snd_soc_bind_card: disable_route_checks set, ignoring errors on +add_routes + +Fixes: daa480bde6b3a9 ("ASoC: soc-core: tidyup for snd_soc_dapm_add_routes()") +Signed-off-by: Pierre-Louis Bossart +Acked-by: Kuninori Morimoto +Link: https://lore.kernel.org/r/20200309192744.18380-2-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + include/sound/soc.h | 1 + + sound/soc/soc-core.c | 28 ++++++++++++++++++++++++---- + 2 files changed, 25 insertions(+), 4 deletions(-) + +--- a/include/sound/soc.h ++++ b/include/sound/soc.h +@@ -1058,6 +1058,7 @@ struct snd_soc_card { + const struct snd_soc_dapm_route *of_dapm_routes; + int num_of_dapm_routes; + bool fully_routed; ++ bool disable_route_checks; + + /* lists of probed devices belonging to this card */ + struct list_head component_dev_list; +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -1256,8 +1256,18 @@ static int soc_probe_component(struct sn + ret = snd_soc_dapm_add_routes(dapm, + component->driver->dapm_routes, + component->driver->num_dapm_routes); +- if (ret < 0) +- goto err_probe; ++ if (ret < 0) { ++ if (card->disable_route_checks) { ++ dev_info(card->dev, ++ "%s: disable_route_checks set, ignoring errors on add_routes\n", ++ __func__); ++ } else { ++ dev_err(card->dev, ++ "%s: snd_soc_dapm_add_routes failed: %d\n", ++ __func__, ret); ++ goto err_probe; ++ } ++ } + + /* see for_each_card_components */ + list_add(&component->card_list, &card->component_dev_list); +@@ -1938,8 +1948,18 @@ static int snd_soc_bind_card(struct snd_ + + ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, + card->num_dapm_routes); +- if (ret < 0) +- goto probe_end; ++ if (ret < 0) { ++ if (card->disable_route_checks) { ++ dev_info(card->dev, ++ "%s: disable_route_checks set, ignoring errors on add_routes\n", ++ __func__); ++ } else { ++ dev_err(card->dev, ++ "%s: snd_soc_dapm_add_routes failed: %d\n", ++ __func__, ret); ++ goto probe_end; ++ } ++ } + + ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, + card->num_of_dapm_routes); diff --git a/queue-5.6/asoc-soc-pcm-fix-regression-in-soc_new_pcm.patch b/queue-5.6/asoc-soc-pcm-fix-regression-in-soc_new_pcm.patch new file mode 100644 index 00000000000..b414082c642 --- /dev/null +++ b/queue-5.6/asoc-soc-pcm-fix-regression-in-soc_new_pcm.patch @@ -0,0 +1,72 @@ +From a4877a6fb2bd2e356a5eaacd86d6b6d69ff84e69 Mon Sep 17 00:00:00 2001 +From: Stephan Gerhold +Date: Tue, 18 Feb 2020 11:38:24 +0100 +Subject: ASoC: soc-pcm: fix regression in soc_new_pcm() + +From: Stephan Gerhold + +commit a4877a6fb2bd2e356a5eaacd86d6b6d69ff84e69 upstream. + +Commit af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") +swapped the SNDRV_PCM_STREAM_* parameter in the +snd_soc_dai_stream_valid(cpu_dai, ...) checks. But that works only +for codec2codec links. For normal links it breaks registration of +playback/capture-only PCM devices. + +E.g. on qcom/apq8016_sbc there is usually one playback-only and one +capture-only PCM device, but they disappeared after the commit. + +The codec2codec case was added in commit a342031cdd08 +("ASoC: create pcm for codec2codec links as well") as an extra check +(e.g. `playback = playback && cpu_playback->channels_min`). + +We should be able to simplify the code by checking directly for +the correct stream type in the loop. +This also fixes the regression because we check for PLAYBACK for +both codec and cpu dai again when codec2codec is not used. + +Fixes: af4bac11531f ("ASoC: soc-pcm: crash in snd_soc_dapm_new_dai") +Signed-off-by: Stephan Gerhold +Tested-by: Jerome Brunet +Reviewed-by: Jerome Brunet +Cc: Jerome Brunet +Cc: Sameer Pujar +Link: https://lore.kernel.org/r/20200218103824.26708-1-stephan@gerhold.net +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-pcm.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -2890,22 +2890,19 @@ int soc_new_pcm(struct snd_soc_pcm_runti + capture = rtd->dai_link->dpcm_capture; + } else { + /* Adapt stream for codec2codec links */ +- struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ? +- &cpu_dai->driver->playback : &cpu_dai->driver->capture; +- struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ? +- &cpu_dai->driver->capture : &cpu_dai->driver->playback; ++ int cpu_capture = rtd->dai_link->params ? ++ SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; ++ int cpu_playback = rtd->dai_link->params ? ++ SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + + for_each_rtd_codec_dai(rtd, i, codec_dai) { + if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && +- snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) ++ snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) + playback = 1; + if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && +- snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) ++ snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) + capture = 1; + } +- +- capture = capture && cpu_capture->channels_min; +- playback = playback && cpu_playback->channels_min; + } + + if (rtd->dai_link->playback_only) { diff --git a/queue-5.6/asoc-stm32-spdifrx-fix-regmap-status-check.patch b/queue-5.6/asoc-stm32-spdifrx-fix-regmap-status-check.patch new file mode 100644 index 00000000000..11888ab1547 --- /dev/null +++ b/queue-5.6/asoc-stm32-spdifrx-fix-regmap-status-check.patch @@ -0,0 +1,33 @@ +From a168dae5ea14283e8992d5282237bb0d6a3e1c06 Mon Sep 17 00:00:00 2001 +From: Olivier Moysan +Date: Wed, 18 Mar 2020 15:41:23 +0100 +Subject: ASoC: stm32: spdifrx: fix regmap status check + +From: Olivier Moysan + +commit a168dae5ea14283e8992d5282237bb0d6a3e1c06 upstream. + +Release resources when exiting on error. + +Fixes: 1a5c0b28fc56 ("ASoC: stm32: spdifrx: manage identification registers") + +Signed-off-by: Olivier Moysan +Link: https://lore.kernel.org/r/20200318144125.9163-2-olivier.moysan@st.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/stm/stm32_spdifrx.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/soc/stm/stm32_spdifrx.c ++++ b/sound/soc/stm/stm32_spdifrx.c +@@ -1009,6 +1009,8 @@ static int stm32_spdifrx_probe(struct pl + + if (idr == SPDIFRX_IPIDR_NUMBER) { + ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_VERR, &ver); ++ if (ret) ++ goto error; + + dev_dbg(&pdev->dev, "SPDIFRX version: %lu.%lu registered\n", + FIELD_GET(SPDIFRX_VERR_MAJ_MASK, ver), diff --git a/queue-5.6/crypto-chelsio-fixes-a-hang-issue-during-driver-registration.patch b/queue-5.6/crypto-chelsio-fixes-a-hang-issue-during-driver-registration.patch new file mode 100644 index 00000000000..c78e4227fd0 --- /dev/null +++ b/queue-5.6/crypto-chelsio-fixes-a-hang-issue-during-driver-registration.patch @@ -0,0 +1,42 @@ +From ad59ddd02de26271b89564962e74d689f1a30b49 Mon Sep 17 00:00:00 2001 +From: Ayush Sawal +Date: Mon, 30 Mar 2020 20:48:52 +0530 +Subject: Crypto: chelsio - Fixes a hang issue during driver registration + +From: Ayush Sawal + +commit ad59ddd02de26271b89564962e74d689f1a30b49 upstream. + +This issue occurs only when multiadapters are present. Hang +happens because assign_chcr_device returns u_ctx pointer of +adapter which is not yet initialized as for this adapter cxgb_up +is not been called yet. + +The last_dev pointer is used to determine u_ctx pointer and it +is initialized two times in chcr_uld_add in chcr_dev_add respectively. + +The fix here is don't initialize the last_dev pointer during +chcr_uld_add. Only assign to value to it when the adapter's +initialization is completed i.e in chcr_dev_add. + +Fixes: fef4912b66d62 ("crypto: chelsio - Handle PCI shutdown event"). + +Signed-off-by: Ayush Sawal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/chelsio/chcr_core.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/crypto/chelsio/chcr_core.c ++++ b/drivers/crypto/chelsio/chcr_core.c +@@ -125,8 +125,6 @@ static void chcr_dev_init(struct uld_ctx + atomic_set(&dev->inflight, 0); + mutex_lock(&drv_data.drv_mutex); + list_add_tail(&u_ctx->entry, &drv_data.inact_dev); +- if (!drv_data.last_dev) +- drv_data.last_dev = u_ctx; + mutex_unlock(&drv_data.drv_mutex); + } + diff --git a/queue-5.6/ext4-check-for-non-zero-journal-inum-in-ext4_calculate_overhead.patch b/queue-5.6/ext4-check-for-non-zero-journal-inum-in-ext4_calculate_overhead.patch new file mode 100644 index 00000000000..11d32450345 --- /dev/null +++ b/queue-5.6/ext4-check-for-non-zero-journal-inum-in-ext4_calculate_overhead.patch @@ -0,0 +1,73 @@ +From f1eec3b0d0a849996ebee733b053efa71803dad5 Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani +Date: Mon, 16 Mar 2020 15:00:38 +0530 +Subject: ext4: check for non-zero journal inum in ext4_calculate_overhead + +From: Ritesh Harjani + +commit f1eec3b0d0a849996ebee733b053efa71803dad5 upstream. + +While calculating overhead for internal journal, also check +that j_inum shouldn't be 0. Otherwise we get below error with +xfstests generic/050 with external journal (XXX_LOGDEV config) enabled. + +It could be simply reproduced with loop device with an external journal +and marking blockdev as RO before mounting. + +[ 3337.146838] EXT4-fs error (device pmem1p2): ext4_get_journal_inode:4634: comm mount: inode #0: comm mount: iget: illegal inode # +------------[ cut here ]------------ +generic_make_request: Trying to write to read-only block-device pmem1p2 (partno 2) +WARNING: CPU: 107 PID: 115347 at block/blk-core.c:788 generic_make_request_checks+0x6b4/0x7d0 +CPU: 107 PID: 115347 Comm: mount Tainted: G L --------- -t - 4.18.0-167.el8.ppc64le #1 +NIP: c0000000006f6d44 LR: c0000000006f6d40 CTR: 0000000030041dd4 +<...> +NIP [c0000000006f6d44] generic_make_request_checks+0x6b4/0x7d0 +LR [c0000000006f6d40] generic_make_request_checks+0x6b0/0x7d0 +<...> +Call Trace: +generic_make_request_checks+0x6b0/0x7d0 (unreliable) +generic_make_request+0x3c/0x420 +submit_bio+0xd8/0x200 +submit_bh_wbc+0x1e8/0x250 +__sync_dirty_buffer+0xd0/0x210 +ext4_commit_super+0x310/0x420 [ext4] +__ext4_error+0xa4/0x1e0 [ext4] +__ext4_iget+0x388/0xe10 [ext4] +ext4_get_journal_inode+0x40/0x150 [ext4] +ext4_calculate_overhead+0x5a8/0x610 [ext4] +ext4_fill_super+0x3188/0x3260 [ext4] +mount_bdev+0x778/0x8f0 +ext4_mount+0x28/0x50 [ext4] +mount_fs+0x74/0x230 +vfs_kern_mount.part.6+0x6c/0x250 +do_mount+0x2fc/0x1280 +sys_mount+0x158/0x180 +system_call+0x5c/0x70 +EXT4-fs (pmem1p2): no journal found +EXT4-fs (pmem1p2): can't get journal size +EXT4-fs (pmem1p2): mounted filesystem without journal. Opts: dax,norecovery + +Fixes: 3c816ded78bb ("ext4: use journal inode to determine journal overhead") +Reported-by: Harish Sriram +Signed-off-by: Ritesh Harjani +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20200316093038.25485-1-riteshh@linux.ibm.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3610,7 +3610,8 @@ int ext4_calculate_overhead(struct super + */ + if (sbi->s_journal && !sbi->journal_bdev) + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen); +- else if (ext4_has_feature_journal(sb) && !sbi->s_journal) { ++ else if (ext4_has_feature_journal(sb) && !sbi->s_journal && j_inum) { ++ /* j_inum for internal journal is non-zero */ + j_inode = ext4_get_journal_inode(sb, j_inum); + if (j_inode) { + j_blocks = j_inode->i_size >> sb->s_blocksize_bits; diff --git a/queue-5.6/net-use-indirect-call-wrappers-for-skb_copy_datagram_iter.patch b/queue-5.6/net-use-indirect-call-wrappers-for-skb_copy_datagram_iter.patch new file mode 100644 index 00000000000..8b3f209c8a1 --- /dev/null +++ b/queue-5.6/net-use-indirect-call-wrappers-for-skb_copy_datagram_iter.patch @@ -0,0 +1,75 @@ +From 29f3490ba9d2399d3d1b20c4aa74592d92bd4e11 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 24 Mar 2020 19:23:21 -0700 +Subject: net: use indirect call wrappers for skb_copy_datagram_iter() + +From: Eric Dumazet + +commit 29f3490ba9d2399d3d1b20c4aa74592d92bd4e11 upstream. + +TCP recvmsg() calls skb_copy_datagram_iter(), which +calls an indirect function (cb pointing to simple_copy_to_iter()) +for every MSS (fragment) present in the skb. + +CONFIG_RETPOLINE=y forces a very expensive operation +that we can avoid thanks to indirect call wrappers. + +This patch gives a 13% increase of performance on +a single flow, if the bottleneck is the thread reading +the TCP socket. + +Fixes: 950fcaecd5cc ("datagram: consolidate datagram copy to iter helpers") +Signed-off-by: Eric Dumazet +Acked-by: Paolo Abeni +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/datagram.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/net/core/datagram.c ++++ b/net/core/datagram.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -414,6 +415,11 @@ int skb_kill_datagram(struct sock *sk, s + } + EXPORT_SYMBOL(skb_kill_datagram); + ++INDIRECT_CALLABLE_DECLARE(static size_t simple_copy_to_iter(const void *addr, ++ size_t bytes, ++ void *data __always_unused, ++ struct iov_iter *i)); ++ + static int __skb_datagram_iter(const struct sk_buff *skb, int offset, + struct iov_iter *to, int len, bool fault_short, + size_t (*cb)(const void *, size_t, void *, +@@ -427,7 +433,8 @@ static int __skb_datagram_iter(const str + if (copy > 0) { + if (copy > len) + copy = len; +- n = cb(skb->data + offset, copy, data, to); ++ n = INDIRECT_CALL_1(cb, simple_copy_to_iter, ++ skb->data + offset, copy, data, to); + offset += n; + if (n != copy) + goto short_copy; +@@ -449,8 +456,9 @@ static int __skb_datagram_iter(const str + + if (copy > len) + copy = len; +- n = cb(vaddr + skb_frag_off(frag) + offset - start, +- copy, data, to); ++ n = INDIRECT_CALL_1(cb, simple_copy_to_iter, ++ vaddr + skb_frag_off(frag) + offset - start, ++ copy, data, to); + kunmap(page); + offset += n; + if (n != copy) diff --git a/queue-5.6/qed-fix-race-condition-between-scheduling-and-destroying-the-slowpath-workqueue.patch b/queue-5.6/qed-fix-race-condition-between-scheduling-and-destroying-the-slowpath-workqueue.patch new file mode 100644 index 00000000000..d7e6d49d3ca --- /dev/null +++ b/queue-5.6/qed-fix-race-condition-between-scheduling-and-destroying-the-slowpath-workqueue.patch @@ -0,0 +1,63 @@ +From 3b85720d3fd72e6ef4de252cd2f67548eb645eb4 Mon Sep 17 00:00:00 2001 +From: Yuval Basson +Date: Wed, 25 Mar 2020 22:50:43 +0200 +Subject: qed: Fix race condition between scheduling and destroying the slowpath workqueue + +From: Yuval Basson + +commit 3b85720d3fd72e6ef4de252cd2f67548eb645eb4 upstream. + +Calling queue_delayed_work concurrently with +destroy_workqueue might race to an unexpected outcome - +scheduled task after wq is destroyed or other resources +(like ptt_pool) are freed (yields NULL pointer dereference). +cancel_delayed_work prevents the race by cancelling +the timer triggered for scheduling a new task. + +Fixes: 59ccf86fe ("qed: Add driver infrastucture for handling mfw requests") +Signed-off-by: Denis Bolotin +Signed-off-by: Michal Kalderon +Signed-off-by: Yuval Basson +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/qlogic/qed/qed_main.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/qlogic/qed/qed_main.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_main.c +@@ -1087,9 +1087,6 @@ static void qed_update_pf_params(struct + #define QED_PERIODIC_DB_REC_INTERVAL_MS 100 + #define QED_PERIODIC_DB_REC_INTERVAL \ + msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS) +-#define QED_PERIODIC_DB_REC_WAIT_COUNT 10 +-#define QED_PERIODIC_DB_REC_WAIT_INTERVAL \ +- (QED_PERIODIC_DB_REC_INTERVAL_MS / QED_PERIODIC_DB_REC_WAIT_COUNT) + + static int qed_slowpath_delayed_work(struct qed_hwfn *hwfn, + enum qed_slowpath_wq_flag wq_flag, +@@ -1123,7 +1120,7 @@ void qed_periodic_db_rec_start(struct qe + + static void qed_slowpath_wq_stop(struct qed_dev *cdev) + { +- int i, sleep_count = QED_PERIODIC_DB_REC_WAIT_COUNT; ++ int i; + + if (IS_VF(cdev)) + return; +@@ -1135,13 +1132,7 @@ static void qed_slowpath_wq_stop(struct + /* Stop queuing new delayed works */ + cdev->hwfns[i].slowpath_wq_active = false; + +- /* Wait until the last periodic doorbell recovery is executed */ +- while (test_bit(QED_SLOWPATH_PERIODIC_DB_REC, +- &cdev->hwfns[i].slowpath_task_flags) && +- sleep_count--) +- msleep(QED_PERIODIC_DB_REC_WAIT_INTERVAL); +- +- flush_workqueue(cdev->hwfns[i].slowpath_wq); ++ cancel_delayed_work(&cdev->hwfns[i].slowpath_task); + destroy_workqueue(cdev->hwfns[i].slowpath_wq); + } + } diff --git a/queue-5.6/qed-fix-use-after-free-in-qed_chain_free.patch b/queue-5.6/qed-fix-use-after-free-in-qed_chain_free.patch new file mode 100644 index 00000000000..10c208329bb --- /dev/null +++ b/queue-5.6/qed-fix-use-after-free-in-qed_chain_free.patch @@ -0,0 +1,206 @@ +From 8063f761cd7c17fc1d0018728936e0c33a25388a Mon Sep 17 00:00:00 2001 +From: Yuval Basson +Date: Sun, 29 Mar 2020 20:32:49 +0300 +Subject: qed: Fix use after free in qed_chain_free + +From: Yuval Basson + +commit 8063f761cd7c17fc1d0018728936e0c33a25388a upstream. + +The qed_chain data structure was modified in +commit 1a4a69751f4d ("qed: Chain support for external PBL") to support +receiving an external pbl (due to iWARP FW requirements). +The pages pointed to by the pbl are allocated in qed_chain_alloc +and their virtual address are stored in an virtual addresses array to +enable accessing and freeing the data. The physical addresses however +weren't stored and were accessed directly from the external-pbl +during free. + +Destroy-qp flow, leads to freeing the external pbl before the chain is +freed, when the chain is freed it tries accessing the already freed +external pbl, leading to a use-after-free. Therefore we need to store +the physical addresses in additional to the virtual addresses in a +new data structure. + +Fixes: 1a4a69751f4d ("qed: Chain support for external PBL") +Signed-off-by: Michal Kalderon +Signed-off-by: Yuval Bason +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/qlogic/qed/qed_dev.c | 38 ++++++++++++------------------ + include/linux/qed/qed_chain.h | 24 +++++++++++------- + 2 files changed, 31 insertions(+), 31 deletions(-) + +--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c +@@ -4691,26 +4691,20 @@ static void qed_chain_free_single(struct + + static void qed_chain_free_pbl(struct qed_dev *cdev, struct qed_chain *p_chain) + { +- void **pp_virt_addr_tbl = p_chain->pbl.pp_virt_addr_tbl; ++ struct addr_tbl_entry *pp_addr_tbl = p_chain->pbl.pp_addr_tbl; + u32 page_cnt = p_chain->page_cnt, i, pbl_size; +- u8 *p_pbl_virt = p_chain->pbl_sp.p_virt_table; + +- if (!pp_virt_addr_tbl) ++ if (!pp_addr_tbl) + return; + +- if (!p_pbl_virt) +- goto out; +- + for (i = 0; i < page_cnt; i++) { +- if (!pp_virt_addr_tbl[i]) ++ if (!pp_addr_tbl[i].virt_addr || !pp_addr_tbl[i].dma_map) + break; + + dma_free_coherent(&cdev->pdev->dev, + QED_CHAIN_PAGE_SIZE, +- pp_virt_addr_tbl[i], +- *(dma_addr_t *)p_pbl_virt); +- +- p_pbl_virt += QED_CHAIN_PBL_ENTRY_SIZE; ++ pp_addr_tbl[i].virt_addr, ++ pp_addr_tbl[i].dma_map); + } + + pbl_size = page_cnt * QED_CHAIN_PBL_ENTRY_SIZE; +@@ -4720,9 +4714,9 @@ static void qed_chain_free_pbl(struct qe + pbl_size, + p_chain->pbl_sp.p_virt_table, + p_chain->pbl_sp.p_phys_table); +-out: +- vfree(p_chain->pbl.pp_virt_addr_tbl); +- p_chain->pbl.pp_virt_addr_tbl = NULL; ++ ++ vfree(p_chain->pbl.pp_addr_tbl); ++ p_chain->pbl.pp_addr_tbl = NULL; + } + + void qed_chain_free(struct qed_dev *cdev, struct qed_chain *p_chain) +@@ -4823,19 +4817,19 @@ qed_chain_alloc_pbl(struct qed_dev *cdev + { + u32 page_cnt = p_chain->page_cnt, size, i; + dma_addr_t p_phys = 0, p_pbl_phys = 0; +- void **pp_virt_addr_tbl = NULL; ++ struct addr_tbl_entry *pp_addr_tbl; + u8 *p_pbl_virt = NULL; + void *p_virt = NULL; + +- size = page_cnt * sizeof(*pp_virt_addr_tbl); +- pp_virt_addr_tbl = vzalloc(size); +- if (!pp_virt_addr_tbl) ++ size = page_cnt * sizeof(*pp_addr_tbl); ++ pp_addr_tbl = vzalloc(size); ++ if (!pp_addr_tbl) + return -ENOMEM; + + /* The allocation of the PBL table is done with its full size, since it + * is expected to be successive. + * qed_chain_init_pbl_mem() is called even in a case of an allocation +- * failure, since pp_virt_addr_tbl was previously allocated, and it ++ * failure, since tbl was previously allocated, and it + * should be saved to allow its freeing during the error flow. + */ + size = page_cnt * QED_CHAIN_PBL_ENTRY_SIZE; +@@ -4849,8 +4843,7 @@ qed_chain_alloc_pbl(struct qed_dev *cdev + p_chain->b_external_pbl = true; + } + +- qed_chain_init_pbl_mem(p_chain, p_pbl_virt, p_pbl_phys, +- pp_virt_addr_tbl); ++ qed_chain_init_pbl_mem(p_chain, p_pbl_virt, p_pbl_phys, pp_addr_tbl); + if (!p_pbl_virt) + return -ENOMEM; + +@@ -4869,7 +4862,8 @@ qed_chain_alloc_pbl(struct qed_dev *cdev + /* Fill the PBL table with the physical address of the page */ + *(dma_addr_t *)p_pbl_virt = p_phys; + /* Keep the virtual address of the page */ +- p_chain->pbl.pp_virt_addr_tbl[i] = p_virt; ++ p_chain->pbl.pp_addr_tbl[i].virt_addr = p_virt; ++ p_chain->pbl.pp_addr_tbl[i].dma_map = p_phys; + + p_pbl_virt += QED_CHAIN_PBL_ENTRY_SIZE; + } +--- a/include/linux/qed/qed_chain.h ++++ b/include/linux/qed/qed_chain.h +@@ -97,6 +97,11 @@ struct qed_chain_u32 { + u32 cons_idx; + }; + ++struct addr_tbl_entry { ++ void *virt_addr; ++ dma_addr_t dma_map; ++}; ++ + struct qed_chain { + /* fastpath portion of the chain - required for commands such + * as produce / consume. +@@ -107,10 +112,11 @@ struct qed_chain { + + /* Fastpath portions of the PBL [if exists] */ + struct { +- /* Table for keeping the virtual addresses of the chain pages, +- * respectively to the physical addresses in the pbl table. ++ /* Table for keeping the virtual and physical addresses of the ++ * chain pages, respectively to the physical addresses ++ * in the pbl table. + */ +- void **pp_virt_addr_tbl; ++ struct addr_tbl_entry *pp_addr_tbl; + + union { + struct qed_chain_pbl_u16 u16; +@@ -287,7 +293,7 @@ qed_chain_advance_page(struct qed_chain + *(u32 *)page_to_inc = 0; + page_index = *(u32 *)page_to_inc; + } +- *p_next_elem = p_chain->pbl.pp_virt_addr_tbl[page_index]; ++ *p_next_elem = p_chain->pbl.pp_addr_tbl[page_index].virt_addr; + } + } + +@@ -537,7 +543,7 @@ static inline void qed_chain_init_params + + p_chain->pbl_sp.p_phys_table = 0; + p_chain->pbl_sp.p_virt_table = NULL; +- p_chain->pbl.pp_virt_addr_tbl = NULL; ++ p_chain->pbl.pp_addr_tbl = NULL; + } + + /** +@@ -575,11 +581,11 @@ static inline void qed_chain_init_mem(st + static inline void qed_chain_init_pbl_mem(struct qed_chain *p_chain, + void *p_virt_pbl, + dma_addr_t p_phys_pbl, +- void **pp_virt_addr_tbl) ++ struct addr_tbl_entry *pp_addr_tbl) + { + p_chain->pbl_sp.p_phys_table = p_phys_pbl; + p_chain->pbl_sp.p_virt_table = p_virt_pbl; +- p_chain->pbl.pp_virt_addr_tbl = pp_virt_addr_tbl; ++ p_chain->pbl.pp_addr_tbl = pp_addr_tbl; + } + + /** +@@ -644,7 +650,7 @@ static inline void *qed_chain_get_last_e + break; + case QED_CHAIN_MODE_PBL: + last_page_idx = p_chain->page_cnt - 1; +- p_virt_addr = p_chain->pbl.pp_virt_addr_tbl[last_page_idx]; ++ p_virt_addr = p_chain->pbl.pp_addr_tbl[last_page_idx].virt_addr; + break; + } + /* p_virt_addr points at this stage to the last page of the chain */ +@@ -716,7 +722,7 @@ static inline void qed_chain_pbl_zero_me + page_cnt = qed_chain_get_page_cnt(p_chain); + + for (i = 0; i < page_cnt; i++) +- memset(p_chain->pbl.pp_virt_addr_tbl[i], 0, ++ memset(p_chain->pbl.pp_addr_tbl[i].virt_addr, 0, + QED_CHAIN_PAGE_SIZE); + } + diff --git a/queue-5.6/series b/queue-5.6/series index 145e1e3171c..e1bd255d629 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -93,3 +93,14 @@ irqchip-gic-v4.1-add-support-for-vpendbaser-s-dirty-.patch blk-mq-put-driver-tag-in-blk_mq_dispatch_rq_list-whe.patch irqchip-meson-gpio-fix-hardirq-safe-hardirq-unsafe-l.patch hwmon-jc42-fix-name-to-have-no-illegal-characters.patch +sfc-fix-xdp-redirect-in-this-driver.patch +taprio-do-not-use-bit-in-tca_taprio_attr_flag_-definitions.patch +tipc-add-a-missing-case-of-tipc_direct_msg-type.patch +qed-fix-race-condition-between-scheduling-and-destroying-the-slowpath-workqueue.patch +crypto-chelsio-fixes-a-hang-issue-during-driver-registration.patch +net-use-indirect-call-wrappers-for-skb_copy_datagram_iter.patch +qed-fix-use-after-free-in-qed_chain_free.patch +ext4-check-for-non-zero-journal-inum-in-ext4_calculate_overhead.patch +asoc-soc-pcm-fix-regression-in-soc_new_pcm.patch +asoc-soc-core-disable-route-checks-for-legacy-devices.patch +asoc-stm32-spdifrx-fix-regmap-status-check.patch diff --git a/queue-5.6/sfc-fix-xdp-redirect-in-this-driver.patch b/queue-5.6/sfc-fix-xdp-redirect-in-this-driver.patch new file mode 100644 index 00000000000..299bbad9769 --- /dev/null +++ b/queue-5.6/sfc-fix-xdp-redirect-in-this-driver.patch @@ -0,0 +1,121 @@ +From 86e85bf6981c0c265c427d6bfe9e2a0111797444 Mon Sep 17 00:00:00 2001 +From: Jesper Dangaard Brouer +Date: Fri, 13 Mar 2020 14:25:19 +0100 +Subject: sfc: fix XDP-redirect in this driver + +From: Jesper Dangaard Brouer + +commit 86e85bf6981c0c265c427d6bfe9e2a0111797444 upstream. + +XDP-redirect is broken in this driver sfc. XDP_REDIRECT requires +tailroom for skb_shared_info when creating an SKB based on the +redirected xdp_frame (both in cpumap and veth). + +The fix requires some initial explaining. The driver uses RX page-split +when possible. It reserves the top 64 bytes in the RX-page for storing +dma_addr (struct efx_rx_page_state). It also have the XDP recommended +headroom of XDP_PACKET_HEADROOM (256 bytes). As it doesn't reserve any +tailroom, it can still fit two standard MTU (1500) frames into one page. + +The sizeof struct skb_shared_info in 320 bytes. Thus drivers like ixgbe +and i40e, reduce their XDP headroom to 192 bytes, which allows them to +fit two frames with max 1536 bytes into a 4K page (192+1536+320=2048). + +The fix is to reduce this drivers headroom to 128 bytes and add the 320 +bytes tailroom. This account for reserved top 64 bytes in the page, and +still fit two frame in a page for normal MTUs. + +We must never go below 128 bytes of headroom for XDP, as one cacheline +is for xdp_frame area and next cacheline is reserved for metadata area. + +Fixes: eb9a36be7f3e ("sfc: perform XDP processing on received packets") +Signed-off-by: Jesper Dangaard Brouer +Acked-by: Edward Cree +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/sfc/efx_common.c | 9 +++++---- + drivers/net/ethernet/sfc/net_driver.h | 6 ++++++ + drivers/net/ethernet/sfc/rx.c | 2 +- + drivers/net/ethernet/sfc/rx_common.c | 6 +++--- + 4 files changed, 15 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/sfc/efx_common.c ++++ b/drivers/net/ethernet/sfc/efx_common.c +@@ -200,11 +200,11 @@ void efx_link_status_changed(struct efx_ + unsigned int efx_xdp_max_mtu(struct efx_nic *efx) + { + /* The maximum MTU that we can fit in a single page, allowing for +- * framing, overhead and XDP headroom. ++ * framing, overhead and XDP headroom + tailroom. + */ + int overhead = EFX_MAX_FRAME_LEN(0) + sizeof(struct efx_rx_page_state) + + efx->rx_prefix_size + efx->type->rx_buffer_padding + +- efx->rx_ip_align + XDP_PACKET_HEADROOM; ++ efx->rx_ip_align + EFX_XDP_HEADROOM + EFX_XDP_TAILROOM; + + return PAGE_SIZE - overhead; + } +@@ -302,8 +302,9 @@ static void efx_start_datapath(struct ef + efx->rx_dma_len = (efx->rx_prefix_size + + EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + + efx->type->rx_buffer_padding); +- rx_buf_len = (sizeof(struct efx_rx_page_state) + XDP_PACKET_HEADROOM + +- efx->rx_ip_align + efx->rx_dma_len); ++ rx_buf_len = (sizeof(struct efx_rx_page_state) + EFX_XDP_HEADROOM + ++ efx->rx_ip_align + efx->rx_dma_len + EFX_XDP_TAILROOM); ++ + if (rx_buf_len <= PAGE_SIZE) { + efx->rx_scatter = efx->type->always_rx_scatter; + efx->rx_buffer_order = 0; +--- a/drivers/net/ethernet/sfc/net_driver.h ++++ b/drivers/net/ethernet/sfc/net_driver.h +@@ -91,6 +91,12 @@ + #define EFX_RX_BUF_ALIGNMENT 4 + #endif + ++/* Non-standard XDP_PACKET_HEADROOM and tailroom to satisfy XDP_REDIRECT and ++ * still fit two standard MTU size packets into a single 4K page. ++ */ ++#define EFX_XDP_HEADROOM 128 ++#define EFX_XDP_TAILROOM SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) ++ + /* Forward declare Precision Time Protocol (PTP) support structure. */ + struct efx_ptp_data; + struct hwtstamp_config; +--- a/drivers/net/ethernet/sfc/rx.c ++++ b/drivers/net/ethernet/sfc/rx.c +@@ -302,7 +302,7 @@ static bool efx_do_xdp(struct efx_nic *e + efx->rx_prefix_size); + + xdp.data = *ehp; +- xdp.data_hard_start = xdp.data - XDP_PACKET_HEADROOM; ++ xdp.data_hard_start = xdp.data - EFX_XDP_HEADROOM; + + /* No support yet for XDP metadata */ + xdp_set_data_meta_invalid(&xdp); +--- a/drivers/net/ethernet/sfc/rx_common.c ++++ b/drivers/net/ethernet/sfc/rx_common.c +@@ -412,10 +412,10 @@ static int efx_init_rx_buffers(struct ef + index = rx_queue->added_count & rx_queue->ptr_mask; + rx_buf = efx_rx_buffer(rx_queue, index); + rx_buf->dma_addr = dma_addr + efx->rx_ip_align + +- XDP_PACKET_HEADROOM; ++ EFX_XDP_HEADROOM; + rx_buf->page = page; + rx_buf->page_offset = page_offset + efx->rx_ip_align + +- XDP_PACKET_HEADROOM; ++ EFX_XDP_HEADROOM; + rx_buf->len = efx->rx_dma_len; + rx_buf->flags = 0; + ++rx_queue->added_count; +@@ -433,7 +433,7 @@ static int efx_init_rx_buffers(struct ef + void efx_rx_config_page_split(struct efx_nic *efx) + { + efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align + +- XDP_PACKET_HEADROOM, ++ EFX_XDP_HEADROOM + EFX_XDP_TAILROOM, + EFX_RX_BUF_ALIGNMENT); + efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : + ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / diff --git a/queue-5.6/taprio-do-not-use-bit-in-tca_taprio_attr_flag_-definitions.patch b/queue-5.6/taprio-do-not-use-bit-in-tca_taprio_attr_flag_-definitions.patch new file mode 100644 index 00000000000..1a8abd964c0 --- /dev/null +++ b/queue-5.6/taprio-do-not-use-bit-in-tca_taprio_attr_flag_-definitions.patch @@ -0,0 +1,36 @@ +From 673040c3a82a7564423e09c791e242a846591e30 Mon Sep 17 00:00:00 2001 +From: Eugene Syromiatnikov +Date: Tue, 24 Mar 2020 05:19:20 +0100 +Subject: taprio: do not use BIT() in TCA_TAPRIO_ATTR_FLAG_* definitions + +From: Eugene Syromiatnikov + +commit 673040c3a82a7564423e09c791e242a846591e30 upstream. + +BIT() macro definition is internal to the Linux kernel and is not +to be used in UAPI headers; replace its usage with the _BITUL() macro +that is already used elsewhere in the header. + +Fixes: 9c66d1564676 ("taprio: Add support for hardware offloading") +Signed-off-by: Eugene Syromiatnikov +Acked-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/uapi/linux/pkt_sched.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/uapi/linux/pkt_sched.h ++++ b/include/uapi/linux/pkt_sched.h +@@ -1197,8 +1197,8 @@ enum { + * [TCA_TAPRIO_ATTR_SCHED_ENTRY_INTERVAL] + */ + +-#define TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST BIT(0) +-#define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD BIT(1) ++#define TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST _BITUL(0) ++#define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD _BITUL(1) + + enum { + TCA_TAPRIO_ATTR_UNSPEC, diff --git a/queue-5.6/tipc-add-a-missing-case-of-tipc_direct_msg-type.patch b/queue-5.6/tipc-add-a-missing-case-of-tipc_direct_msg-type.patch new file mode 100644 index 00000000000..6dda6e17bc2 --- /dev/null +++ b/queue-5.6/tipc-add-a-missing-case-of-tipc_direct_msg-type.patch @@ -0,0 +1,71 @@ +From 8b1e5b0a99f04bda2d6c85ecfe5e68a356c10914 Mon Sep 17 00:00:00 2001 +From: Hoang Le +Date: Thu, 26 Mar 2020 09:50:29 +0700 +Subject: tipc: Add a missing case of TIPC_DIRECT_MSG type + +From: Hoang Le + +commit 8b1e5b0a99f04bda2d6c85ecfe5e68a356c10914 upstream. + +In the commit f73b12812a3d +("tipc: improve throughput between nodes in netns"), we're missing a check +to handle TIPC_DIRECT_MSG type, it's still using old sending mechanism for +this message type. So, throughput improvement is not significant as +expected. + +Besides that, when sending a large message with that type, we're also +handle wrong receiving queue, it should be enqueued in socket receiving +instead of multicast messages. + +Fix this by adding the missing case for TIPC_DIRECT_MSG. + +Fixes: f73b12812a3d ("tipc: improve throughput between nodes in netns") +Reported-by: Tuong Lien +Signed-off-by: Hoang Le +Acked-by: Jon Maloy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/tipc/msg.h | 5 +++++ + net/tipc/node.c | 3 ++- + net/tipc/socket.c | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +--- a/net/tipc/msg.h ++++ b/net/tipc/msg.h +@@ -394,6 +394,11 @@ static inline u32 msg_connected(struct t + return msg_type(m) == TIPC_CONN_MSG; + } + ++static inline u32 msg_direct(struct tipc_msg *m) ++{ ++ return msg_type(m) == TIPC_DIRECT_MSG; ++} ++ + static inline u32 msg_errcode(struct tipc_msg *m) + { + return msg_bits(m, 1, 25, 0xf); +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -1586,7 +1586,8 @@ static void tipc_lxc_xmit(struct net *pe + case TIPC_MEDIUM_IMPORTANCE: + case TIPC_HIGH_IMPORTANCE: + case TIPC_CRITICAL_IMPORTANCE: +- if (msg_connected(hdr) || msg_named(hdr)) { ++ if (msg_connected(hdr) || msg_named(hdr) || ++ msg_direct(hdr)) { + tipc_loopback_trace(peer_net, list); + spin_lock_init(&list->lock); + tipc_sk_rcv(peer_net, list); +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -1461,7 +1461,7 @@ static int __tipc_sendmsg(struct socket + } + + __skb_queue_head_init(&pkts); +- mtu = tipc_node_get_mtu(net, dnode, tsk->portid, false); ++ mtu = tipc_node_get_mtu(net, dnode, tsk->portid, true); + rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts); + if (unlikely(rc != dlen)) + return rc;