From 162631b7c1918ee98127a18eb21ee5d79ec1a714 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 5 Dec 2021 15:02:13 +0100 Subject: [PATCH] 5.10-stable patches added patches: alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch arm64-ftrace-add-missing-btis.patch asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch asoc-tegra-fix-wrong-value-type-in-admaif.patch asoc-tegra-fix-wrong-value-type-in-dmic.patch asoc-tegra-fix-wrong-value-type-in-dspk.patch asoc-tegra-fix-wrong-value-type-in-i2s.patch dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch drm-msm-do-hw_init-before-capturing-gpu-state.patch ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch net-annotate-data-races-on-txq-xmit_lock_owner.patch net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch net-smc-keep-smc_close_final-rc-during-active-close.patch net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch selftests-net-correct-case-name.patch --- ...or-cml-devices-based-on-es8336-codec.patch | 48 +++ .../arm64-ftrace-add-missing-btis.patch | 116 ++++++ ...-fix-kcontrol-put-callback-in-admaif.patch | 202 ++++++++++ ...ra-fix-kcontrol-put-callback-in-ahub.patch | 55 +++ ...ra-fix-kcontrol-put-callback-in-dmic.patch | 248 ++++++++++++ ...ra-fix-kcontrol-put-callback-in-dspk.patch | 243 +++++++++++ ...gra-fix-kcontrol-put-callback-in-i2s.patch | 379 ++++++++++++++++++ ...tegra-fix-wrong-value-type-in-admaif.patch | 43 ++ ...c-tegra-fix-wrong-value-type-in-dmic.patch | 73 ++++ ...c-tegra-fix-wrong-value-type-in-dspk.patch | 73 ++++ ...oc-tegra-fix-wrong-value-type-in-i2s.patch | 110 +++++ ...kqueue-at-the-end-of-remove-function.patch | 35 ++ ...ocate-enough-space-for-gmu-registers.patch | 72 ++++ ...o-hw_init-before-capturing-gpu-state.patch | 35 ++ ...t-fib_num_tclassid_users-to-atomic_t.patch | 102 +++++ ...r-dereference-in-mt7915_get_phy_mode.patch | 93 +++++ ...te-data-races-on-txq-xmit_lock_owner.patch | 193 +++++++++ ...2-fix-the-computation-of-shared-cpus.patch | 33 ++ ...e-bug-in-mlx4_en_try_alloc_resources.patch | 59 +++ ...socket-tunable-error-in-rds_tcp_tune.patch | 32 ++ ...ng-list_del-in-smc_lgr_cleanup_early.patch | 89 ++++ ...c_close_final-rc-during-active-close.patch | 53 +++ ...-instead-of-0-if-no-irq-is-available.patch | 33 ++ ...xrpc_local-leak-in-rxrpc_lookup_peer.patch | 69 ++++ ...pc_peer-leak-in-rxrpc_look_up_bundle.patch | 61 +++ .../selftests-net-correct-case-name.patch | 34 ++ queue-5.10/series | 26 ++ 27 files changed, 2609 insertions(+) create mode 100644 queue-5.10/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch create mode 100644 queue-5.10/arm64-ftrace-add-missing-btis.patch create mode 100644 queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch create mode 100644 queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch create mode 100644 queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch create mode 100644 queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch create mode 100644 queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch create mode 100644 queue-5.10/asoc-tegra-fix-wrong-value-type-in-admaif.patch create mode 100644 queue-5.10/asoc-tegra-fix-wrong-value-type-in-dmic.patch create mode 100644 queue-5.10/asoc-tegra-fix-wrong-value-type-in-dspk.patch create mode 100644 queue-5.10/asoc-tegra-fix-wrong-value-type-in-i2s.patch create mode 100644 queue-5.10/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch create mode 100644 queue-5.10/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch create mode 100644 queue-5.10/drm-msm-do-hw_init-before-capturing-gpu-state.patch create mode 100644 queue-5.10/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch create mode 100644 queue-5.10/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch create mode 100644 queue-5.10/net-annotate-data-races-on-txq-xmit_lock_owner.patch create mode 100644 queue-5.10/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch create mode 100644 queue-5.10/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch create mode 100644 queue-5.10/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch create mode 100644 queue-5.10/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch create mode 100644 queue-5.10/net-smc-keep-smc_close_final-rc-during-active-close.patch create mode 100644 queue-5.10/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch create mode 100644 queue-5.10/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch create mode 100644 queue-5.10/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch create mode 100644 queue-5.10/selftests-net-correct-case-name.patch diff --git a/queue-5.10/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch b/queue-5.10/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch new file mode 100644 index 00000000000..2e817d062f0 --- /dev/null +++ b/queue-5.10/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch @@ -0,0 +1,48 @@ +From ae26c08e6c8071ba8febb0c7c0829da96c75248c Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart +Date: Mon, 22 Nov 2021 17:22:54 -0600 +Subject: ALSA: intel-dsp-config: add quirk for CML devices based on ES8336 codec + +From: Pierre-Louis Bossart + +commit ae26c08e6c8071ba8febb0c7c0829da96c75248c upstream. + +We've added quirks for ESS8336 but missed CML, add quirks for both LP +and H versions. + +BugLink: https://github.com/thesofproject/linux/issues/3248 +Fixes: 9d36ceab9415 ("ALSA: intel-dsp-config: add quirk for APL/GLK/TGL devices based on ES8336 codec") +Signed-off-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20211122232254.23362-1-pierre-louis.bossart@linux.intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/hda/intel-dsp-config.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/sound/hda/intel-dsp-config.c ++++ b/sound/hda/intel-dsp-config.c +@@ -251,6 +251,11 @@ static const struct config_entry config_ + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = 0x02c8, + }, ++ { ++ .flags = FLAG_SOF, ++ .device = 0x02c8, ++ .codec_hid = "ESSX8336", ++ }, + /* Cometlake-H */ + { + .flags = FLAG_SOF, +@@ -275,6 +280,11 @@ static const struct config_entry config_ + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = 0x06c8, + }, ++ { ++ .flags = FLAG_SOF, ++ .device = 0x06c8, ++ .codec_hid = "ESSX8336", ++ }, + #endif + + /* Icelake */ diff --git a/queue-5.10/arm64-ftrace-add-missing-btis.patch b/queue-5.10/arm64-ftrace-add-missing-btis.patch new file mode 100644 index 00000000000..7c099143b71 --- /dev/null +++ b/queue-5.10/arm64-ftrace-add-missing-btis.patch @@ -0,0 +1,116 @@ +From 35b6b28e69985eafb20b3b2c7bd6eca452b56b53 Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Mon, 29 Nov 2021 13:57:09 +0000 +Subject: arm64: ftrace: add missing BTIs + +From: Mark Rutland + +commit 35b6b28e69985eafb20b3b2c7bd6eca452b56b53 upstream. + +When branch target identifiers are in use, code reachable via an +indirect branch requires a BTI landing pad at the branch target site. + +When building FTRACE_WITH_REGS atop patchable-function-entry, we miss +BTIs at the start start of the `ftrace_caller` and `ftrace_regs_caller` +trampolines, and when these are called from a module via a PLT (which +will use a `BR X16`), we will encounter a BTI failure, e.g. + +| # insmod lkdtm.ko +| lkdtm: No crash points registered, enable through debugfs +| # echo function_graph > /sys/kernel/debug/tracing/current_tracer +| # cat /sys/kernel/debug/provoke-crash/DIRECT +| Unhandled 64-bit el1h sync exception on CPU0, ESR 0x34000001 -- BTI +| CPU: 0 PID: 174 Comm: cat Not tainted 5.16.0-rc2-dirty #3 +| Hardware name: linux,dummy-virt (DT) +| pstate: 60400405 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=jc) +| pc : ftrace_caller+0x0/0x3c +| lr : lkdtm_debugfs_open+0xc/0x20 [lkdtm] +| sp : ffff800012e43b00 +| x29: ffff800012e43b00 x28: 0000000000000000 x27: ffff800012e43c88 +| x26: 0000000000000000 x25: 0000000000000000 x24: ffff0000c171f200 +| x23: ffff0000c27b1e00 x22: ffff0000c2265240 x21: ffff0000c23c8c30 +| x20: ffff8000090ba380 x19: 0000000000000000 x18: 0000000000000000 +| x17: 0000000000000000 x16: ffff80001002bb4c x15: 0000000000000000 +| x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000900ff0 +| x11: ffff0000c4166310 x10: ffff800012e43b00 x9 : ffff8000104f2384 +| x8 : 0000000000000001 x7 : 0000000000000000 x6 : 000000000000003f +| x5 : 0000000000000040 x4 : ffff800012e43af0 x3 : 0000000000000001 +| x2 : ffff8000090b0000 x1 : ffff0000c171f200 x0 : ffff0000c23c8c30 +| Kernel panic - not syncing: Unhandled exception +| CPU: 0 PID: 174 Comm: cat Not tainted 5.16.0-rc2-dirty #3 +| Hardware name: linux,dummy-virt (DT) +| Call trace: +| dump_backtrace+0x0/0x1a4 +| show_stack+0x24/0x30 +| dump_stack_lvl+0x68/0x84 +| dump_stack+0x1c/0x38 +| panic+0x168/0x360 +| arm64_exit_nmi.isra.0+0x0/0x80 +| el1h_64_sync_handler+0x68/0xd4 +| el1h_64_sync+0x78/0x7c +| ftrace_caller+0x0/0x3c +| do_dentry_open+0x134/0x3b0 +| vfs_open+0x38/0x44 +| path_openat+0x89c/0xe40 +| do_filp_open+0x8c/0x13c +| do_sys_openat2+0xbc/0x174 +| __arm64_sys_openat+0x6c/0xbc +| invoke_syscall+0x50/0x120 +| el0_svc_common.constprop.0+0xdc/0x100 +| do_el0_svc+0x84/0xa0 +| el0_svc+0x28/0x80 +| el0t_64_sync_handler+0xa8/0x130 +| el0t_64_sync+0x1a0/0x1a4 +| SMP: stopping secondary CPUs +| Kernel Offset: disabled +| CPU features: 0x0,00000f42,da660c5f +| Memory Limit: none +| ---[ end Kernel panic - not syncing: Unhandled exception ]--- + +Fix this by adding the required `BTI C`, as we only require these to be +reachable via BL for direct calls or BR X16/X17 for PLTs. For now, these +are open-coded in the function prologue, matching the style of the +`__hwasan_tag_mismatch` trampoline. + +In future we may wish to consider adding a new SYM_CODE_START_*() +variant which has an implicit BTI. + +When ftrace is built atop mcount, the trampolines are marked with +SYM_FUNC_START(), and so get an implicit BTI. We may need to change +these over to SYM_CODE_START() in future for RELIABLE_STACKTRACE, in +case we need to apply special care aroud the return address being +rewritten. + +Fixes: 97fed779f2a6 ("arm64: bti: Provide Kconfig for kernel mode BTI") +Signed-off-by: Mark Rutland +Cc: Catalin Marinas +Cc: Mark Brown +Cc: Will Deacon +Reviewed-by: Mark Brown +Link: https://lore.kernel.org/r/20211129135709.2274019-1-mark.rutland@arm.com +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/entry-ftrace.S | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/arm64/kernel/entry-ftrace.S ++++ b/arch/arm64/kernel/entry-ftrace.S +@@ -77,11 +77,17 @@ + .endm + + SYM_CODE_START(ftrace_regs_caller) ++#ifdef BTI_C ++ BTI_C ++#endif + ftrace_regs_entry 1 + b ftrace_common + SYM_CODE_END(ftrace_regs_caller) + + SYM_CODE_START(ftrace_caller) ++#ifdef BTI_C ++ BTI_C ++#endif + ftrace_regs_entry 0 + b ftrace_common + SYM_CODE_END(ftrace_caller) diff --git a/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch new file mode 100644 index 00000000000..7c7c5b1a3b6 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch @@ -0,0 +1,202 @@ +From e2b87a18a60c02d0dcd1de801d669587e516cc4d Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:37:02 +0530 +Subject: ASoC: tegra: Fix kcontrol put callback in ADMAIF + +From: Sameer Pujar + +commit e2b87a18a60c02d0dcd1de801d669587e516cc4d upstream. + +The kcontrol put callback is expected to return 1 when there is change +in HW or when the update is acknowledged by driver. This would ensure +that change notifications are sent to subscribed applications. Update +the ADMAIF driver accordingly. + +Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver") +Suggested-by: Jaroslav Kysela +Suggested-by: Mark Brown +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-8-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_admaif.c | 138 ++++++++++++++++++++++++++++++-------- + 1 file changed, 109 insertions(+), 29 deletions(-) + +--- a/sound/soc/tegra/tegra210_admaif.c ++++ b/sound/soc/tegra/tegra210_admaif.c +@@ -424,46 +424,122 @@ static const struct snd_soc_dai_ops tegr + .trigger = tegra_admaif_trigger, + }; + +-static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) ++static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ ++ ucontrol->value.enumerated.item[0] = ++ admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; ++ ++ return 0; ++} ++ ++static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); +- unsigned int *uctl_val = &ucontrol->value.enumerated.item[0]; ++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ unsigned int value = ucontrol->value.enumerated.item[0]; + +- if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) +- *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; +- else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) +- *uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; +- else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) +- *uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; +- else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) +- *uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; ++ if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]) ++ return 0; ++ ++ admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; ++ ++ return 1; ++} ++ ++static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); ++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ ++ ucontrol->value.enumerated.item[0] = ++ admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; + + return 0; + } + +-static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) ++static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]) ++ return 0; ++ ++ admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; ++ ++ return 1; ++} ++ ++static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); ++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ ++ ucontrol->value.enumerated.item[0] = ++ admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; ++ ++ return 0; ++} ++ ++static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); ++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; + unsigned int value = ucontrol->value.enumerated.item[0]; + +- if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) +- admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; +- else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) +- admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; +- else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) +- admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; +- else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) +- admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; ++ if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]) ++ return 0; ++ ++ admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; ++ ++ return 1; ++} ++ ++static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); ++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ ++ ucontrol->value.enumerated.item[0] = ++ admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; + + return 0; + } + ++static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); ++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]) ++ return 0; ++ ++ admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; ++ ++ return 1; ++} ++ + static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) + { + struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); +@@ -559,17 +635,21 @@ static const char * const tegra_admaif_m + } + + #define TEGRA_ADMAIF_CIF_CTRL(reg) \ +- NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,\ +- tegra_admaif_get_control, tegra_admaif_put_control, \ ++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \ ++ tegra210_admaif_pget_mono_to_stereo, \ ++ tegra210_admaif_pput_mono_to_stereo, \ + tegra_admaif_mono_conv_text), \ +- NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,\ +- tegra_admaif_get_control, tegra_admaif_put_control, \ ++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \ ++ tegra210_admaif_pget_stereo_to_mono, \ ++ tegra210_admaif_pput_stereo_to_mono, \ + tegra_admaif_stereo_conv_text), \ +- NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ +- tegra_admaif_get_control, tegra_admaif_put_control, \ ++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ ++ tegra210_admaif_cget_mono_to_stereo, \ ++ tegra210_admaif_cput_mono_to_stereo, \ + tegra_admaif_mono_conv_text), \ +- NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ +- tegra_admaif_get_control, tegra_admaif_put_control, \ ++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ ++ tegra210_admaif_cget_stereo_to_mono, \ ++ tegra210_admaif_cput_stereo_to_mono, \ + tegra_admaif_stereo_conv_text) + + static struct snd_kcontrol_new tegra210_admaif_controls[] = { diff --git a/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch new file mode 100644 index 00000000000..5a3d4657f10 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch @@ -0,0 +1,55 @@ +From a4e37950c9e9b126f9cbee79b8ab94a94646dcf1 Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:37:06 +0530 +Subject: ASoC: tegra: Fix kcontrol put callback in AHUB + +From: Sameer Pujar + +commit a4e37950c9e9b126f9cbee79b8ab94a94646dcf1 upstream. + +The kcontrol put callback is expected to return 1 when there is change +in HW or when the update is acknowledged by driver. This would ensure +that change notifications are sent to subscribed applications. Update +the AHUB driver accordingly. + +Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver") +Signed-off-by: Sameer Pujar +Suggested-by: Jaroslav Kysela +Suggested-by: Mark Brown +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-12-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_ahub.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/sound/soc/tegra/tegra210_ahub.c ++++ b/sound/soc/tegra/tegra210_ahub.c +@@ -62,6 +62,7 @@ static int tegra_ahub_put_value_enum(str + unsigned int *item = uctl->value.enumerated.item; + unsigned int value = e->values[item[0]]; + unsigned int i, bit_pos, reg_idx = 0, reg_val = 0; ++ int change = 0; + + if (item[0] >= e->items) + return -EINVAL; +@@ -86,12 +87,14 @@ static int tegra_ahub_put_value_enum(str + + /* Update widget power if state has changed */ + if (snd_soc_component_test_bits(cmpnt, update[i].reg, +- update[i].mask, update[i].val)) +- snd_soc_dapm_mux_update_power(dapm, kctl, item[0], e, +- &update[i]); ++ update[i].mask, ++ update[i].val)) ++ change |= snd_soc_dapm_mux_update_power(dapm, kctl, ++ item[0], e, ++ &update[i]); + } + +- return 0; ++ return change; + } + + static struct snd_soc_dai_driver tegra210_ahub_dais[] = { diff --git a/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch new file mode 100644 index 00000000000..118f8139fc8 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch @@ -0,0 +1,248 @@ +From a347dfa10262fa0a10e2b1970ea0194e3d4a3251 Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:37:04 +0530 +Subject: ASoC: tegra: Fix kcontrol put callback in DMIC + +From: Sameer Pujar + +commit a347dfa10262fa0a10e2b1970ea0194e3d4a3251 upstream. + +The kcontrol put callback is expected to return 1 when there is change +in HW or when the update is acknowledged by driver. This would ensure +that change notifications are sent to subscribed applications. Update +the DMIC driver accordingly. + +Fixes: 8c8ff982e9e2 ("ASoC: tegra: Add Tegra210 based DMIC driver") +Suggested-by: Jaroslav Kysela +Suggested-by: Mark Brown +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-10-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_dmic.c | 183 ++++++++++++++++++++++++++++++++-------- + 1 file changed, 149 insertions(+), 34 deletions(-) + +--- a/sound/soc/tegra/tegra210_dmic.c ++++ b/sound/soc/tegra/tegra210_dmic.c +@@ -156,50 +156,162 @@ static int tegra210_dmic_hw_params(struc + return 0; + } + +-static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol, ++static int tegra210_dmic_get_boost_gain(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ ++ ucontrol->value.integer.value[0] = dmic->boost_gain; ++ ++ return 0; ++} ++ ++static int tegra210_dmic_put_boost_gain(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ int value = ucontrol->value.integer.value[0]; ++ ++ if (value == dmic->boost_gain) ++ return 0; ++ ++ dmic->boost_gain = value; ++ ++ return 1; ++} ++ ++static int tegra210_dmic_get_ch_select(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ ++ ucontrol->value.enumerated.item[0] = dmic->ch_select; ++ ++ return 0; ++} ++ ++static int tegra210_dmic_put_ch_select(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dmic->ch_select) ++ return 0; ++ ++ dmic->ch_select = value; ++ ++ return 1; ++} ++ ++static int tegra210_dmic_get_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ ++ ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo; ++ ++ return 0; ++} ++ ++static int tegra210_dmic_put_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dmic->mono_to_stereo) ++ return 0; ++ ++ dmic->mono_to_stereo = value; ++ ++ return 1; ++} ++ ++static int tegra210_dmic_get_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ ++ ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono; ++ ++ return 0; ++} ++ ++static int tegra210_dmic_put_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dmic->stereo_to_mono) ++ return 0; ++ ++ dmic->stereo_to_mono = value; ++ ++ return 1; ++} ++ ++static int tegra210_dmic_get_osr_val(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); + +- if (strstr(kcontrol->id.name, "Boost Gain Volume")) +- ucontrol->value.integer.value[0] = dmic->boost_gain; +- else if (strstr(kcontrol->id.name, "Channel Select")) +- ucontrol->value.enumerated.item[0] = dmic->ch_select; +- else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo; +- else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono; +- else if (strstr(kcontrol->id.name, "OSR Value")) +- ucontrol->value.enumerated.item[0] = dmic->osr_val; +- else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- ucontrol->value.enumerated.item[0] = dmic->lrsel; ++ ucontrol->value.enumerated.item[0] = dmic->osr_val; + + return 0; + } + +-static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol, ++static int tegra210_dmic_put_osr_val(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dmic->osr_val) ++ return 0; ++ ++ dmic->osr_val = value; ++ ++ return 1; ++} ++ ++static int tegra210_dmic_get_pol_sel(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); + +- if (strstr(kcontrol->id.name, "Boost Gain Volume")) +- dmic->boost_gain = ucontrol->value.integer.value[0]; +- else if (strstr(kcontrol->id.name, "Channel Select")) +- dmic->ch_select = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- dmic->mono_to_stereo = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- dmic->stereo_to_mono = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "OSR Value")) +- dmic->osr_val = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- dmic->lrsel = ucontrol->value.enumerated.item[0]; ++ ucontrol->value.enumerated.item[0] = dmic->lrsel; + + return 0; + } + ++static int tegra210_dmic_put_pol_sel(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dmic->lrsel) ++ return 0; ++ ++ dmic->lrsel = value; ++ ++ return 1; ++} ++ + static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = { + .hw_params = tegra210_dmic_hw_params, + }; +@@ -286,19 +398,22 @@ static const struct soc_enum tegra210_dm + + static const struct snd_kcontrol_new tegra210_dmic_controls[] = { + SOC_SINGLE_EXT("Boost Gain Volume", 0, 0, MAX_BOOST_GAIN, 0, +- tegra210_dmic_get_control, tegra210_dmic_put_control), ++ tegra210_dmic_get_boost_gain, ++ tegra210_dmic_put_boost_gain), + SOC_ENUM_EXT("Channel Select", tegra210_dmic_ch_enum, +- tegra210_dmic_get_control, tegra210_dmic_put_control), ++ tegra210_dmic_get_ch_select, tegra210_dmic_put_ch_select), + SOC_ENUM_EXT("Mono To Stereo", +- tegra210_dmic_mono_conv_enum, tegra210_dmic_get_control, +- tegra210_dmic_put_control), ++ tegra210_dmic_mono_conv_enum, ++ tegra210_dmic_get_mono_to_stereo, ++ tegra210_dmic_put_mono_to_stereo), + SOC_ENUM_EXT("Stereo To Mono", +- tegra210_dmic_stereo_conv_enum, tegra210_dmic_get_control, +- tegra210_dmic_put_control), ++ tegra210_dmic_stereo_conv_enum, ++ tegra210_dmic_get_stereo_to_mono, ++ tegra210_dmic_put_stereo_to_mono), + SOC_ENUM_EXT("OSR Value", tegra210_dmic_osr_enum, +- tegra210_dmic_get_control, tegra210_dmic_put_control), ++ tegra210_dmic_get_osr_val, tegra210_dmic_put_osr_val), + SOC_ENUM_EXT("LR Polarity Select", tegra210_dmic_lrsel_enum, +- tegra210_dmic_get_control, tegra210_dmic_put_control), ++ tegra210_dmic_get_pol_sel, tegra210_dmic_put_pol_sel), + }; + + static const struct snd_soc_component_driver tegra210_dmic_compnt = { diff --git a/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch new file mode 100644 index 00000000000..8b4fafcc312 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch @@ -0,0 +1,243 @@ +From d6202a57e79d102271d38c34481fedc9d4c79694 Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:37:05 +0530 +Subject: ASoC: tegra: Fix kcontrol put callback in DSPK + +From: Sameer Pujar + +commit d6202a57e79d102271d38c34481fedc9d4c79694 upstream. + +The kcontrol put callback is expected to return 1 when there is change +in HW or when the update is acknowledged by driver. This would ensure +that change notifications are sent to subscribed applications. Update +the DSPK driver accordingly. + +Fixes: 327ef6470266 ("ASoC: tegra: Add Tegra186 based DSPK driver") +Suggested-by: Jaroslav Kysela +Suggested-by: Mark Brown +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-11-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra186_dspk.c | 178 ++++++++++++++++++++++++++++++++-------- + 1 file changed, 146 insertions(+), 32 deletions(-) + +--- a/sound/soc/tegra/tegra186_dspk.c ++++ b/sound/soc/tegra/tegra186_dspk.c +@@ -26,50 +26,162 @@ static const struct reg_default tegra186 + { TEGRA186_DSPK_CODEC_CTRL, 0x03000000 }, + }; + +-static int tegra186_dspk_get_control(struct snd_kcontrol *kcontrol, ++static int tegra186_dspk_get_fifo_th(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); + +- if (strstr(kcontrol->id.name, "FIFO Threshold")) +- ucontrol->value.integer.value[0] = dspk->rx_fifo_th; +- else if (strstr(kcontrol->id.name, "OSR Value")) +- ucontrol->value.enumerated.item[0] = dspk->osr_val; +- else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- ucontrol->value.enumerated.item[0] = dspk->lrsel; +- else if (strstr(kcontrol->id.name, "Channel Select")) +- ucontrol->value.enumerated.item[0] = dspk->ch_sel; +- else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo; +- else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono; ++ ucontrol->value.integer.value[0] = dspk->rx_fifo_th; + + return 0; + } + +-static int tegra186_dspk_put_control(struct snd_kcontrol *kcontrol, ++static int tegra186_dspk_put_fifo_th(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ int value = ucontrol->value.integer.value[0]; + +- if (strstr(kcontrol->id.name, "FIFO Threshold")) +- dspk->rx_fifo_th = ucontrol->value.integer.value[0]; +- else if (strstr(kcontrol->id.name, "OSR Value")) +- dspk->osr_val = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- dspk->lrsel = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "Channel Select")) +- dspk->ch_sel = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- dspk->mono_to_stereo = ucontrol->value.enumerated.item[0]; +- else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- dspk->stereo_to_mono = ucontrol->value.enumerated.item[0]; ++ if (value == dspk->rx_fifo_th) ++ return 0; ++ ++ dspk->rx_fifo_th = value; ++ ++ return 1; ++} ++ ++static int tegra186_dspk_get_osr_val(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ ++ ucontrol->value.enumerated.item[0] = dspk->osr_val; ++ ++ return 0; ++} ++ ++static int tegra186_dspk_put_osr_val(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dspk->osr_val) ++ return 0; ++ ++ dspk->osr_val = value; ++ ++ return 1; ++} ++ ++static int tegra186_dspk_get_pol_sel(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ ++ ucontrol->value.enumerated.item[0] = dspk->lrsel; ++ ++ return 0; ++} ++ ++static int tegra186_dspk_put_pol_sel(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dspk->lrsel) ++ return 0; ++ ++ dspk->lrsel = value; ++ ++ return 1; ++} ++ ++static int tegra186_dspk_get_ch_sel(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ ++ ucontrol->value.enumerated.item[0] = dspk->ch_sel; ++ ++ return 0; ++} ++ ++static int tegra186_dspk_put_ch_sel(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dspk->ch_sel) ++ return 0; ++ ++ dspk->ch_sel = value; ++ ++ return 1; ++} ++ ++static int tegra186_dspk_get_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ ++ ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo; ++ ++ return 0; ++} ++ ++static int tegra186_dspk_put_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dspk->mono_to_stereo) ++ return 0; ++ ++ dspk->mono_to_stereo = value; ++ ++ return 1; ++} ++ ++static int tegra186_dspk_get_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ ++ ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono; + + return 0; + } + ++static int tegra186_dspk_put_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); ++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == dspk->stereo_to_mono) ++ return 0; ++ ++ dspk->stereo_to_mono = value; ++ ++ return 1; ++} ++ + static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev) + { + struct tegra186_dspk *dspk = dev_get_drvdata(dev); +@@ -278,17 +390,19 @@ static const struct soc_enum tegra186_ds + static const struct snd_kcontrol_new tegrat186_dspk_controls[] = { + SOC_SINGLE_EXT("FIFO Threshold", SND_SOC_NOPM, 0, + TEGRA186_DSPK_RX_FIFO_DEPTH - 1, 0, +- tegra186_dspk_get_control, tegra186_dspk_put_control), ++ tegra186_dspk_get_fifo_th, tegra186_dspk_put_fifo_th), + SOC_ENUM_EXT("OSR Value", tegra186_dspk_osr_enum, +- tegra186_dspk_get_control, tegra186_dspk_put_control), ++ tegra186_dspk_get_osr_val, tegra186_dspk_put_osr_val), + SOC_ENUM_EXT("LR Polarity Select", tegra186_dspk_lrsel_enum, +- tegra186_dspk_get_control, tegra186_dspk_put_control), ++ tegra186_dspk_get_pol_sel, tegra186_dspk_put_pol_sel), + SOC_ENUM_EXT("Channel Select", tegra186_dspk_ch_sel_enum, +- tegra186_dspk_get_control, tegra186_dspk_put_control), ++ tegra186_dspk_get_ch_sel, tegra186_dspk_put_ch_sel), + SOC_ENUM_EXT("Mono To Stereo", tegra186_dspk_mono_conv_enum, +- tegra186_dspk_get_control, tegra186_dspk_put_control), ++ tegra186_dspk_get_mono_to_stereo, ++ tegra186_dspk_put_mono_to_stereo), + SOC_ENUM_EXT("Stereo To Mono", tegra186_dspk_stereo_conv_enum, +- tegra186_dspk_get_control, tegra186_dspk_put_control), ++ tegra186_dspk_get_stereo_to_mono, ++ tegra186_dspk_put_stereo_to_mono), + }; + + static const struct snd_soc_component_driver tegra186_dspk_cmpnt = { diff --git a/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch new file mode 100644 index 00000000000..486b0279728 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch @@ -0,0 +1,379 @@ +From f21a9df3f7cb0005947679d7b9237c90574e229a Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:37:03 +0530 +Subject: ASoC: tegra: Fix kcontrol put callback in I2S + +From: Sameer Pujar + +commit f21a9df3f7cb0005947679d7b9237c90574e229a upstream. + +The kcontrol put callback is expected to return 1 when there is change +in HW or when the update is acknowledged by driver. This would ensure +that change notifications are sent to subscribed applications. Update +the I2S driver accordingly. + +Fixes: c0bfa98349d1 ("ASoC: tegra: Add Tegra210 based I2S driver") +Suggested-by: Jaroslav Kysela +Suggested-by: Mark Brown +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-9-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_i2s.c | 322 ++++++++++++++++++++++++++++++----------- + 1 file changed, 236 insertions(+), 86 deletions(-) + +--- a/sound/soc/tegra/tegra210_i2s.c ++++ b/sound/soc/tegra/tegra210_i2s.c +@@ -302,91 +302,235 @@ static int tegra210_i2s_set_tdm_slot(str + return 0; + } + +-static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, +- unsigned int ratio) ++static int tegra210_i2s_get_loopback(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) + { +- struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); + +- i2s->bclk_ratio = ratio; ++ ucontrol->value.integer.value[0] = i2s->loopback; + + return 0; + } + +-static int tegra210_i2s_get_control(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) ++static int tegra210_i2s_put_loopback(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ int value = ucontrol->value.integer.value[0]; + +- if (strstr(kcontrol->id.name, "Loopback")) +- ucontrol->value.integer.value[0] = i2s->loopback; +- else if (strstr(kcontrol->id.name, "FSYNC Width")) +- ucontrol->value.integer.value[0] = i2s->fsync_width; +- else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) +- ucontrol->value.enumerated.item[0] = +- i2s->stereo_to_mono[I2S_TX_PATH]; +- else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) +- ucontrol->value.enumerated.item[0] = +- i2s->mono_to_stereo[I2S_TX_PATH]; +- else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) +- ucontrol->value.enumerated.item[0] = +- i2s->stereo_to_mono[I2S_RX_PATH]; +- else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) +- ucontrol->value.enumerated.item[0] = +- i2s->mono_to_stereo[I2S_RX_PATH]; +- else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) +- ucontrol->value.integer.value[0] = i2s->rx_fifo_th; +- else if (strstr(kcontrol->id.name, "BCLK Ratio")) +- ucontrol->value.integer.value[0] = i2s->bclk_ratio; +- +- return 0; +-} +- +-static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) +-{ +- struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); +- struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); +- +- if (strstr(kcontrol->id.name, "Loopback")) { +- i2s->loopback = ucontrol->value.integer.value[0]; +- +- regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, +- I2S_CTRL_LPBK_MASK, +- i2s->loopback << I2S_CTRL_LPBK_SHIFT); +- +- } else if (strstr(kcontrol->id.name, "FSYNC Width")) { +- /* +- * Frame sync width is used only for FSYNC modes and not +- * applicable for LRCK modes. Reset value for this field is "0", +- * which means the width is one bit clock wide. +- * The width requirement may depend on the codec and in such +- * cases mixer control is used to update custom values. A value +- * of "N" here means, width is "N + 1" bit clock wide. +- */ +- i2s->fsync_width = ucontrol->value.integer.value[0]; +- +- regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, +- I2S_CTRL_FSYNC_WIDTH_MASK, +- i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); +- +- } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) { +- i2s->stereo_to_mono[I2S_TX_PATH] = +- ucontrol->value.enumerated.item[0]; +- } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) { +- i2s->mono_to_stereo[I2S_TX_PATH] = +- ucontrol->value.enumerated.item[0]; +- } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) { +- i2s->stereo_to_mono[I2S_RX_PATH] = +- ucontrol->value.enumerated.item[0]; +- } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) { +- i2s->mono_to_stereo[I2S_RX_PATH] = +- ucontrol->value.enumerated.item[0]; +- } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) { +- i2s->rx_fifo_th = ucontrol->value.integer.value[0]; +- } else if (strstr(kcontrol->id.name, "BCLK Ratio")) { +- i2s->bclk_ratio = ucontrol->value.integer.value[0]; +- } ++ if (value == i2s->loopback) ++ return 0; ++ ++ i2s->loopback = value; ++ ++ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_LPBK_MASK, ++ i2s->loopback << I2S_CTRL_LPBK_SHIFT); ++ ++ return 1; ++} ++ ++static int tegra210_i2s_get_fsync_width(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.integer.value[0] = i2s->fsync_width; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_put_fsync_width(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ int value = ucontrol->value.integer.value[0]; ++ ++ if (value == i2s->fsync_width) ++ return 0; ++ ++ i2s->fsync_width = value; ++ ++ /* ++ * Frame sync width is used only for FSYNC modes and not ++ * applicable for LRCK modes. Reset value for this field is "0", ++ * which means the width is one bit clock wide. ++ * The width requirement may depend on the codec and in such ++ * cases mixer control is used to update custom values. A value ++ * of "N" here means, width is "N + 1" bit clock wide. ++ */ ++ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, ++ I2S_CTRL_FSYNC_WIDTH_MASK, ++ i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); ++ ++ return 1; ++} ++ ++static int tegra210_i2s_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_TX_PATH]; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == i2s->stereo_to_mono[I2S_TX_PATH]) ++ return 0; ++ ++ i2s->stereo_to_mono[I2S_TX_PATH] = value; ++ ++ return 1; ++} ++ ++static int tegra210_i2s_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_TX_PATH]; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == i2s->mono_to_stereo[I2S_TX_PATH]) ++ return 0; ++ ++ i2s->mono_to_stereo[I2S_TX_PATH] = value; ++ ++ return 1; ++} ++ ++static int tegra210_i2s_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_RX_PATH]; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == i2s->stereo_to_mono[I2S_RX_PATH]) ++ return 0; ++ ++ i2s->stereo_to_mono[I2S_RX_PATH] = value; ++ ++ return 1; ++} ++ ++static int tegra210_i2s_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_RX_PATH]; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ unsigned int value = ucontrol->value.enumerated.item[0]; ++ ++ if (value == i2s->mono_to_stereo[I2S_RX_PATH]) ++ return 0; ++ ++ i2s->mono_to_stereo[I2S_RX_PATH] = value; ++ ++ return 1; ++} ++ ++static int tegra210_i2s_pget_fifo_th(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.integer.value[0] = i2s->rx_fifo_th; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_pput_fifo_th(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ int value = ucontrol->value.integer.value[0]; ++ ++ if (value == i2s->rx_fifo_th) ++ return 0; ++ ++ i2s->rx_fifo_th = value; ++ ++ return 1; ++} ++ ++static int tegra210_i2s_get_bclk_ratio(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ ++ ucontrol->value.integer.value[0] = i2s->bclk_ratio; ++ ++ return 0; ++} ++ ++static int tegra210_i2s_put_bclk_ratio(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); ++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); ++ int value = ucontrol->value.integer.value[0]; ++ ++ if (value == i2s->bclk_ratio) ++ return 0; ++ ++ i2s->bclk_ratio = value; ++ ++ return 1; ++} ++ ++static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, ++ unsigned int ratio) ++{ ++ struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ ++ i2s->bclk_ratio = ratio; + + return 0; + } +@@ -604,22 +748,28 @@ static const struct soc_enum tegra210_i2 + tegra210_i2s_stereo_conv_text); + + static const struct snd_kcontrol_new tegra210_i2s_controls[] = { +- SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_control, +- tegra210_i2s_put_control), +- SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, tegra210_i2s_get_control, +- tegra210_i2s_put_control), ++ SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_loopback, ++ tegra210_i2s_put_loopback), ++ SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, ++ tegra210_i2s_get_fsync_width, ++ tegra210_i2s_put_fsync_width), + SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum, +- tegra210_i2s_get_control, tegra210_i2s_put_control), ++ tegra210_i2s_cget_stereo_to_mono, ++ tegra210_i2s_cput_stereo_to_mono), + SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum, +- tegra210_i2s_get_control, tegra210_i2s_put_control), ++ tegra210_i2s_cget_mono_to_stereo, ++ tegra210_i2s_cput_mono_to_stereo), + SOC_ENUM_EXT("Playback Stereo To Mono", tegra210_i2s_stereo_conv_enum, +- tegra210_i2s_get_control, tegra210_i2s_put_control), ++ tegra210_i2s_pget_mono_to_stereo, ++ tegra210_i2s_pput_mono_to_stereo), + SOC_ENUM_EXT("Playback Mono To Stereo", tegra210_i2s_mono_conv_enum, +- tegra210_i2s_get_control, tegra210_i2s_put_control), ++ tegra210_i2s_pget_stereo_to_mono, ++ tegra210_i2s_pput_stereo_to_mono), + SOC_SINGLE_EXT("Playback FIFO Threshold", 0, 0, I2S_RX_FIFO_DEPTH - 1, +- 0, tegra210_i2s_get_control, tegra210_i2s_put_control), +- SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, tegra210_i2s_get_control, +- tegra210_i2s_put_control), ++ 0, tegra210_i2s_pget_fifo_th, tegra210_i2s_pput_fifo_th), ++ SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, ++ tegra210_i2s_get_bclk_ratio, ++ tegra210_i2s_put_bclk_ratio), + }; + + static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = { diff --git a/queue-5.10/asoc-tegra-fix-wrong-value-type-in-admaif.patch b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-admaif.patch new file mode 100644 index 00000000000..0e991dbf1d6 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-admaif.patch @@ -0,0 +1,43 @@ +From 884c6cb3b7030f75c46e55b9e625d2372708c306 Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:36:56 +0530 +Subject: ASoC: tegra: Fix wrong value type in ADMAIF + +From: Sameer Pujar + +commit 884c6cb3b7030f75c46e55b9e625d2372708c306 upstream. + +The enum controls are expected to use enumerated value type. +Update relevant references in control get/put callbacks. + +Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver") +Suggested-by: Takashi Iwai +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-2-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_admaif.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/soc/tegra/tegra210_admaif.c ++++ b/sound/soc/tegra/tegra210_admaif.c +@@ -430,7 +430,7 @@ static int tegra_admaif_get_control(stru + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); +- long *uctl_val = &ucontrol->value.integer.value[0]; ++ unsigned int *uctl_val = &ucontrol->value.enumerated.item[0]; + + if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) + *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; +@@ -450,7 +450,7 @@ static int tegra_admaif_put_control(stru + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); +- int value = ucontrol->value.integer.value[0]; ++ unsigned int value = ucontrol->value.enumerated.item[0]; + + if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) + admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; diff --git a/queue-5.10/asoc-tegra-fix-wrong-value-type-in-dmic.patch b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-dmic.patch new file mode 100644 index 00000000000..73e8ae04eed --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-dmic.patch @@ -0,0 +1,73 @@ +From 559d234569a998a4004de1bd1f12da5487fb826e Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:36:58 +0530 +Subject: ASoC: tegra: Fix wrong value type in DMIC + +From: Sameer Pujar + +commit 559d234569a998a4004de1bd1f12da5487fb826e upstream. + +The enum controls are expected to use enumerated value type. +Update relevant references in control get/put callbacks. + +Fixes: 8c8ff982e9e2 ("ASoC: tegra: Add Tegra210 based DMIC driver") +Suggested-by: Takashi Iwai +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-4-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_dmic.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/sound/soc/tegra/tegra210_dmic.c ++++ b/sound/soc/tegra/tegra210_dmic.c +@@ -165,15 +165,15 @@ static int tegra210_dmic_get_control(str + if (strstr(kcontrol->id.name, "Boost Gain Volume")) + ucontrol->value.integer.value[0] = dmic->boost_gain; + else if (strstr(kcontrol->id.name, "Channel Select")) +- ucontrol->value.integer.value[0] = dmic->ch_select; ++ ucontrol->value.enumerated.item[0] = dmic->ch_select; + else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- ucontrol->value.integer.value[0] = dmic->mono_to_stereo; ++ ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo; + else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- ucontrol->value.integer.value[0] = dmic->stereo_to_mono; ++ ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono; + else if (strstr(kcontrol->id.name, "OSR Value")) +- ucontrol->value.integer.value[0] = dmic->osr_val; ++ ucontrol->value.enumerated.item[0] = dmic->osr_val; + else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- ucontrol->value.integer.value[0] = dmic->lrsel; ++ ucontrol->value.enumerated.item[0] = dmic->lrsel; + + return 0; + } +@@ -183,20 +183,19 @@ static int tegra210_dmic_put_control(str + { + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); +- int value = ucontrol->value.integer.value[0]; + + if (strstr(kcontrol->id.name, "Boost Gain Volume")) +- dmic->boost_gain = value; ++ dmic->boost_gain = ucontrol->value.integer.value[0]; + else if (strstr(kcontrol->id.name, "Channel Select")) +- dmic->ch_select = ucontrol->value.integer.value[0]; ++ dmic->ch_select = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- dmic->mono_to_stereo = value; ++ dmic->mono_to_stereo = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- dmic->stereo_to_mono = value; ++ dmic->stereo_to_mono = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "OSR Value")) +- dmic->osr_val = value; ++ dmic->osr_val = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- dmic->lrsel = value; ++ dmic->lrsel = ucontrol->value.enumerated.item[0]; + + return 0; + } diff --git a/queue-5.10/asoc-tegra-fix-wrong-value-type-in-dspk.patch b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-dspk.patch new file mode 100644 index 00000000000..c1bab5e1437 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-dspk.patch @@ -0,0 +1,73 @@ +From 3aa0d5c8bb3f5ef622ec2764823f551a1f630711 Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:36:59 +0530 +Subject: ASoC: tegra: Fix wrong value type in DSPK + +From: Sameer Pujar + +commit 3aa0d5c8bb3f5ef622ec2764823f551a1f630711 upstream. + +The enum controls are expected to use enumerated value type. +Update relevant references in control get/put callbacks. + +Fixes: 327ef6470266 ("ASoC: tegra: Add Tegra186 based DSPK driver") +Suggested-by: Takashi Iwai +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-5-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra186_dspk.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/sound/soc/tegra/tegra186_dspk.c ++++ b/sound/soc/tegra/tegra186_dspk.c +@@ -35,15 +35,15 @@ static int tegra186_dspk_get_control(str + if (strstr(kcontrol->id.name, "FIFO Threshold")) + ucontrol->value.integer.value[0] = dspk->rx_fifo_th; + else if (strstr(kcontrol->id.name, "OSR Value")) +- ucontrol->value.integer.value[0] = dspk->osr_val; ++ ucontrol->value.enumerated.item[0] = dspk->osr_val; + else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- ucontrol->value.integer.value[0] = dspk->lrsel; ++ ucontrol->value.enumerated.item[0] = dspk->lrsel; + else if (strstr(kcontrol->id.name, "Channel Select")) +- ucontrol->value.integer.value[0] = dspk->ch_sel; ++ ucontrol->value.enumerated.item[0] = dspk->ch_sel; + else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- ucontrol->value.integer.value[0] = dspk->mono_to_stereo; ++ ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo; + else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- ucontrol->value.integer.value[0] = dspk->stereo_to_mono; ++ ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono; + + return 0; + } +@@ -53,20 +53,19 @@ static int tegra186_dspk_put_control(str + { + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); +- int val = ucontrol->value.integer.value[0]; + + if (strstr(kcontrol->id.name, "FIFO Threshold")) +- dspk->rx_fifo_th = val; ++ dspk->rx_fifo_th = ucontrol->value.integer.value[0]; + else if (strstr(kcontrol->id.name, "OSR Value")) +- dspk->osr_val = val; ++ dspk->osr_val = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "LR Polarity Select")) +- dspk->lrsel = val; ++ dspk->lrsel = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "Channel Select")) +- dspk->ch_sel = val; ++ dspk->ch_sel = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "Mono To Stereo")) +- dspk->mono_to_stereo = val; ++ dspk->mono_to_stereo = ucontrol->value.enumerated.item[0]; + else if (strstr(kcontrol->id.name, "Stereo To Mono")) +- dspk->stereo_to_mono = val; ++ dspk->stereo_to_mono = ucontrol->value.enumerated.item[0]; + + return 0; + } diff --git a/queue-5.10/asoc-tegra-fix-wrong-value-type-in-i2s.patch b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-i2s.patch new file mode 100644 index 00000000000..b457a857111 --- /dev/null +++ b/queue-5.10/asoc-tegra-fix-wrong-value-type-in-i2s.patch @@ -0,0 +1,110 @@ +From 8a2c2fa0c5331445c801e9241f2bb4e0e2a895a8 Mon Sep 17 00:00:00 2001 +From: Sameer Pujar +Date: Thu, 18 Nov 2021 12:36:57 +0530 +Subject: ASoC: tegra: Fix wrong value type in I2S + +From: Sameer Pujar + +commit 8a2c2fa0c5331445c801e9241f2bb4e0e2a895a8 upstream. + +The enum controls are expected to use enumerated value type. +Update relevant references in control get/put callbacks. + +Fixes: c0bfa98349d1 ("ASoC: tegra: Add Tegra210 based I2S driver") +Suggested-by: Takashi Iwai +Signed-off-by: Sameer Pujar +Reviewed-by: Takashi Iwai +Link: https://lore.kernel.org/r/1637219231-406-3-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/tegra/tegra210_i2s.c | 42 +++++++++++++++++++++++------------------ + 1 file changed, 24 insertions(+), 18 deletions(-) + +--- a/sound/soc/tegra/tegra210_i2s.c ++++ b/sound/soc/tegra/tegra210_i2s.c +@@ -317,24 +317,27 @@ static int tegra210_i2s_get_control(stru + { + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); +- long *uctl_val = &ucontrol->value.integer.value[0]; + + if (strstr(kcontrol->id.name, "Loopback")) +- *uctl_val = i2s->loopback; ++ ucontrol->value.integer.value[0] = i2s->loopback; + else if (strstr(kcontrol->id.name, "FSYNC Width")) +- *uctl_val = i2s->fsync_width; ++ ucontrol->value.integer.value[0] = i2s->fsync_width; + else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) +- *uctl_val = i2s->stereo_to_mono[I2S_TX_PATH]; ++ ucontrol->value.enumerated.item[0] = ++ i2s->stereo_to_mono[I2S_TX_PATH]; + else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) +- *uctl_val = i2s->mono_to_stereo[I2S_TX_PATH]; ++ ucontrol->value.enumerated.item[0] = ++ i2s->mono_to_stereo[I2S_TX_PATH]; + else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) +- *uctl_val = i2s->stereo_to_mono[I2S_RX_PATH]; ++ ucontrol->value.enumerated.item[0] = ++ i2s->stereo_to_mono[I2S_RX_PATH]; + else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) +- *uctl_val = i2s->mono_to_stereo[I2S_RX_PATH]; ++ ucontrol->value.enumerated.item[0] = ++ i2s->mono_to_stereo[I2S_RX_PATH]; + else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) +- *uctl_val = i2s->rx_fifo_th; ++ ucontrol->value.integer.value[0] = i2s->rx_fifo_th; + else if (strstr(kcontrol->id.name, "BCLK Ratio")) +- *uctl_val = i2s->bclk_ratio; ++ ucontrol->value.integer.value[0] = i2s->bclk_ratio; + + return 0; + } +@@ -344,10 +347,9 @@ static int tegra210_i2s_put_control(stru + { + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); +- int value = ucontrol->value.integer.value[0]; + + if (strstr(kcontrol->id.name, "Loopback")) { +- i2s->loopback = value; ++ i2s->loopback = ucontrol->value.integer.value[0]; + + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, + I2S_CTRL_LPBK_MASK, +@@ -362,24 +364,28 @@ static int tegra210_i2s_put_control(stru + * cases mixer control is used to update custom values. A value + * of "N" here means, width is "N + 1" bit clock wide. + */ +- i2s->fsync_width = value; ++ i2s->fsync_width = ucontrol->value.integer.value[0]; + + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, + I2S_CTRL_FSYNC_WIDTH_MASK, + i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); + + } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) { +- i2s->stereo_to_mono[I2S_TX_PATH] = value; ++ i2s->stereo_to_mono[I2S_TX_PATH] = ++ ucontrol->value.enumerated.item[0]; + } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) { +- i2s->mono_to_stereo[I2S_TX_PATH] = value; ++ i2s->mono_to_stereo[I2S_TX_PATH] = ++ ucontrol->value.enumerated.item[0]; + } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) { +- i2s->stereo_to_mono[I2S_RX_PATH] = value; ++ i2s->stereo_to_mono[I2S_RX_PATH] = ++ ucontrol->value.enumerated.item[0]; + } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) { +- i2s->mono_to_stereo[I2S_RX_PATH] = value; ++ i2s->mono_to_stereo[I2S_RX_PATH] = ++ ucontrol->value.enumerated.item[0]; + } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) { +- i2s->rx_fifo_th = value; ++ i2s->rx_fifo_th = ucontrol->value.integer.value[0]; + } else if (strstr(kcontrol->id.name, "BCLK Ratio")) { +- i2s->bclk_ratio = value; ++ i2s->bclk_ratio = ucontrol->value.integer.value[0]; + } + + return 0; diff --git a/queue-5.10/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch b/queue-5.10/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch new file mode 100644 index 00000000000..2634759d11c --- /dev/null +++ b/queue-5.10/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch @@ -0,0 +1,35 @@ +From f4a8adbfe4841491b60c14fe610571e1422359f9 Mon Sep 17 00:00:00 2001 +From: Dongliang Mu +Date: Tue, 30 Nov 2021 12:05:54 +0800 +Subject: dpaa2-eth: destroy workqueue at the end of remove function + +From: Dongliang Mu + +commit f4a8adbfe4841491b60c14fe610571e1422359f9 upstream. + +The commit c55211892f46 ("dpaa2-eth: support PTP Sync packet one-step +timestamping") forgets to destroy workqueue at the end of remove +function. + +Fix this by adding destroy_workqueue before fsl_mc_portal_free and +free_netdev. + +Fixes: c55211892f46 ("dpaa2-eth: support PTP Sync packet one-step timestamping") +Signed-off-by: Dongliang Mu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +@@ -4432,6 +4432,8 @@ static int dpaa2_eth_remove(struct fsl_m + + fsl_mc_portal_free(priv->mc_io); + ++ destroy_workqueue(priv->dpaa2_ptp_wq); ++ + dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name); + + free_netdev(net_dev); diff --git a/queue-5.10/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch b/queue-5.10/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch new file mode 100644 index 00000000000..ef05a34885f --- /dev/null +++ b/queue-5.10/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch @@ -0,0 +1,72 @@ +From b4d25abf9720b69a03465b09d0d62d1998ed6708 Mon Sep 17 00:00:00 2001 +From: Douglas Anderson +Date: Wed, 3 Nov 2021 15:31:08 -0700 +Subject: drm/msm/a6xx: Allocate enough space for GMU registers + +From: Douglas Anderson + +commit b4d25abf9720b69a03465b09d0d62d1998ed6708 upstream. + +In commit 142639a52a01 ("drm/msm/a6xx: fix crashstate capture for +A650") we changed a6xx_get_gmu_registers() to read 3 sets of +registers. Unfortunately, we didn't change the memory allocation for +the array. That leads to a KASAN warning (this was on the chromeos-5.4 +kernel, which has the problematic commit backported to it): + + BUG: KASAN: slab-out-of-bounds in _a6xx_get_gmu_registers+0x144/0x430 + Write of size 8 at addr ffffff80c89432b0 by task A618-worker/209 + CPU: 5 PID: 209 Comm: A618-worker Tainted: G W 5.4.156-lockdep #22 + Hardware name: Google Lazor Limozeen without Touchscreen (rev5 - rev8) (DT) + Call trace: + dump_backtrace+0x0/0x248 + show_stack+0x20/0x2c + dump_stack+0x128/0x1ec + print_address_description+0x88/0x4a0 + __kasan_report+0xfc/0x120 + kasan_report+0x10/0x18 + __asan_report_store8_noabort+0x1c/0x24 + _a6xx_get_gmu_registers+0x144/0x430 + a6xx_gpu_state_get+0x330/0x25d4 + msm_gpu_crashstate_capture+0xa0/0x84c + recover_worker+0x328/0x838 + kthread_worker_fn+0x32c/0x574 + kthread+0x2dc/0x39c + ret_from_fork+0x10/0x18 + + Allocated by task 209: + __kasan_kmalloc+0xfc/0x1c4 + kasan_kmalloc+0xc/0x14 + kmem_cache_alloc_trace+0x1f0/0x2a0 + a6xx_gpu_state_get+0x164/0x25d4 + msm_gpu_crashstate_capture+0xa0/0x84c + recover_worker+0x328/0x838 + kthread_worker_fn+0x32c/0x574 + kthread+0x2dc/0x39c + ret_from_fork+0x10/0x18 + +Fixes: 142639a52a01 ("drm/msm/a6xx: fix crashstate capture for A650") +Signed-off-by: Douglas Anderson +Link: https://lore.kernel.org/r/20211103153049.1.Idfa574ccb529d17b69db3a1852e49b580132035c@changeid +Signed-off-by: Rob Clark +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +@@ -777,12 +777,12 @@ static void a6xx_get_gmu_registers(struc + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + + a6xx_state->gmu_registers = state_kcalloc(a6xx_state, +- 2, sizeof(*a6xx_state->gmu_registers)); ++ 3, sizeof(*a6xx_state->gmu_registers)); + + if (!a6xx_state->gmu_registers) + return; + +- a6xx_state->nr_gmu_registers = 2; ++ a6xx_state->nr_gmu_registers = 3; + + /* Get the CX GMU registers from AHB */ + _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0], diff --git a/queue-5.10/drm-msm-do-hw_init-before-capturing-gpu-state.patch b/queue-5.10/drm-msm-do-hw_init-before-capturing-gpu-state.patch new file mode 100644 index 00000000000..1fdbe03a726 --- /dev/null +++ b/queue-5.10/drm-msm-do-hw_init-before-capturing-gpu-state.patch @@ -0,0 +1,35 @@ +From e4840d537c2c6b1189d4de16ee0f4820e069dcea Mon Sep 17 00:00:00 2001 +From: Rob Clark +Date: Mon, 8 Nov 2021 10:01:22 -0800 +Subject: drm/msm: Do hw_init() before capturing GPU state + +From: Rob Clark + +commit e4840d537c2c6b1189d4de16ee0f4820e069dcea upstream. + +In particular, we need to ensure all the necessary blocks are switched +to 64b mode (a5xx+) otherwise the high bits of the address of the BO to +snapshot state into will be ignored, resulting in: + + *** gpu fault: ttbr0=0000000000000000 iova=0000000000012000 dir=READ type=TRANSLATION source=CP (0,0,0,0) + platform 506a000.gmu: [drm:a6xx_gmu_set_oob] *ERROR* Timeout waiting for GMU OOB set BOOT_SLUMBER: 0x0 + +Fixes: 4f776f4511c7 ("drm/msm/gpu: Convert the GPU show function to use the GPU state") +Signed-off-by: Rob Clark +Link: https://lore.kernel.org/r/20211108180122.487859-1-robdclark@gmail.com +Signed-off-by: Rob Clark +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/msm/msm_debugfs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/msm/msm_debugfs.c ++++ b/drivers/gpu/drm/msm/msm_debugfs.c +@@ -77,6 +77,7 @@ static int msm_gpu_open(struct inode *in + goto free_priv; + + pm_runtime_get_sync(&gpu->pdev->dev); ++ msm_gpu_hw_init(gpu); + show_priv->state = gpu->funcs->gpu_state_get(gpu); + pm_runtime_put_sync(&gpu->pdev->dev); + diff --git a/queue-5.10/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch b/queue-5.10/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch new file mode 100644 index 00000000000..20950e3a807 --- /dev/null +++ b/queue-5.10/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch @@ -0,0 +1,102 @@ +From 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 1 Dec 2021 18:26:35 -0800 +Subject: ipv4: convert fib_num_tclassid_users to atomic_t + +From: Eric Dumazet + +commit 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 upstream. + +Before commit faa041a40b9f ("ipv4: Create cleanup helper for fib_nh") +changes to net->ipv4.fib_num_tclassid_users were protected by RTNL. + +After the change, this is no longer the case, as free_fib_info_rcu() +runs after rcu grace period, without rtnl being held. + +Fixes: faa041a40b9f ("ipv4: Create cleanup helper for fib_nh") +Signed-off-by: Eric Dumazet +Cc: David Ahern +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/ip_fib.h | 2 +- + include/net/netns/ipv4.h | 2 +- + net/ipv4/fib_frontend.c | 2 +- + net/ipv4/fib_rules.c | 4 ++-- + net/ipv4/fib_semantics.c | 4 ++-- + 5 files changed, 7 insertions(+), 7 deletions(-) + +--- a/include/net/ip_fib.h ++++ b/include/net/ip_fib.h +@@ -437,7 +437,7 @@ int fib_validate_source(struct sk_buff * + #ifdef CONFIG_IP_ROUTE_CLASSID + static inline int fib_num_tclassid_users(struct net *net) + { +- return net->ipv4.fib_num_tclassid_users; ++ return atomic_read(&net->ipv4.fib_num_tclassid_users); + } + #else + static inline int fib_num_tclassid_users(struct net *net) +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -61,7 +61,7 @@ struct netns_ipv4 { + #endif + bool fib_has_custom_local_routes; + #ifdef CONFIG_IP_ROUTE_CLASSID +- int fib_num_tclassid_users; ++ atomic_t fib_num_tclassid_users; + #endif + struct hlist_head *fib_table_hash; + bool fib_offload_disabled; +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -1578,7 +1578,7 @@ static int __net_init fib_net_init(struc + int error; + + #ifdef CONFIG_IP_ROUTE_CLASSID +- net->ipv4.fib_num_tclassid_users = 0; ++ atomic_set(&net->ipv4.fib_num_tclassid_users, 0); + #endif + error = ip_fib_net_init(net); + if (error < 0) +--- a/net/ipv4/fib_rules.c ++++ b/net/ipv4/fib_rules.c +@@ -264,7 +264,7 @@ static int fib4_rule_configure(struct fi + if (tb[FRA_FLOW]) { + rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); + if (rule4->tclassid) +- net->ipv4.fib_num_tclassid_users++; ++ atomic_inc(&net->ipv4.fib_num_tclassid_users); + } + #endif + +@@ -296,7 +296,7 @@ static int fib4_rule_delete(struct fib_r + + #ifdef CONFIG_IP_ROUTE_CLASSID + if (((struct fib4_rule *)rule)->tclassid) +- net->ipv4.fib_num_tclassid_users--; ++ atomic_dec(&net->ipv4.fib_num_tclassid_users); + #endif + net->ipv4.fib_has_custom_rules = true; + +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -222,7 +222,7 @@ void fib_nh_release(struct net *net, str + { + #ifdef CONFIG_IP_ROUTE_CLASSID + if (fib_nh->nh_tclassid) +- net->ipv4.fib_num_tclassid_users--; ++ atomic_dec(&net->ipv4.fib_num_tclassid_users); + #endif + fib_nh_common_release(&fib_nh->nh_common); + } +@@ -633,7 +633,7 @@ int fib_nh_init(struct net *net, struct + #ifdef CONFIG_IP_ROUTE_CLASSID + nh->nh_tclassid = cfg->fc_flow; + if (nh->nh_tclassid) +- net->ipv4.fib_num_tclassid_users++; ++ atomic_inc(&net->ipv4.fib_num_tclassid_users); + #endif + #ifdef CONFIG_IP_ROUTE_MULTIPATH + nh->fib_nh_weight = nh_weight; diff --git a/queue-5.10/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch b/queue-5.10/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch new file mode 100644 index 00000000000..c37c5353b0a --- /dev/null +++ b/queue-5.10/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch @@ -0,0 +1,93 @@ +From 6e53d6d26920d5221d3f4d4f5ffdd629ea69aa5c Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Thu, 18 Nov 2021 13:47:48 +0100 +Subject: mt76: mt7915: fix NULL pointer dereference in mt7915_get_phy_mode + +From: Lorenzo Bianconi + +commit 6e53d6d26920d5221d3f4d4f5ffdd629ea69aa5c upstream. + +Fix the following NULL pointer dereference in mt7915_get_phy_mode +routine adding an ibss interface to the mt7915 driver. + +[ 101.137097] wlan0: Trigger new scan to find an IBSS to join +[ 102.827039] wlan0: Creating new IBSS network, BSSID 26:a4:50:1a:6e:69 +[ 103.064756] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 +[ 103.073670] Mem abort info: +[ 103.076520] ESR = 0x96000005 +[ 103.079614] EC = 0x25: DABT (current EL), IL = 32 bits +[ 103.084934] SET = 0, FnV = 0 +[ 103.088042] EA = 0, S1PTW = 0 +[ 103.091215] Data abort info: +[ 103.094104] ISV = 0, ISS = 0x00000005 +[ 103.098041] CM = 0, WnR = 0 +[ 103.101044] user pgtable: 4k pages, 39-bit VAs, pgdp=00000000460b1000 +[ 103.107565] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 +[ 103.116590] Internal error: Oops: 96000005 [#1] SMP +[ 103.189066] CPU: 1 PID: 333 Comm: kworker/u4:3 Not tainted 5.10.75 #0 +[ 103.195498] Hardware name: MediaTek MT7622 RFB1 board (DT) +[ 103.201124] Workqueue: phy0 ieee80211_iface_work [mac80211] +[ 103.206695] pstate: 20000005 (nzCv daif -PAN -UAO -TCO BTYPE=--) +[ 103.212705] pc : mt7915_get_phy_mode+0x68/0x120 [mt7915e] +[ 103.218103] lr : mt7915_mcu_add_bss_info+0x11c/0x760 [mt7915e] +[ 103.223927] sp : ffffffc011cdb9e0 +[ 103.227235] x29: ffffffc011cdb9e0 x28: ffffff8006563098 +[ 103.232545] x27: ffffff8005f4da22 x26: ffffff800685ac40 +[ 103.237855] x25: 0000000000000001 x24: 000000000000011f +[ 103.243165] x23: ffffff8005f4e260 x22: ffffff8006567918 +[ 103.248475] x21: ffffff8005f4df80 x20: ffffff800685ac58 +[ 103.253785] x19: ffffff8006744400 x18: 0000000000000000 +[ 103.259094] x17: 0000000000000000 x16: 0000000000000001 +[ 103.264403] x15: 000899c3a2d9d2e4 x14: 000899bdc3c3a1c8 +[ 103.269713] x13: 0000000000000000 x12: 0000000000000000 +[ 103.275024] x11: ffffffc010e30c20 x10: 0000000000000000 +[ 103.280333] x9 : 0000000000000050 x8 : ffffff8006567d88 +[ 103.285642] x7 : ffffff8006563b5c x6 : ffffff8006563b44 +[ 103.290952] x5 : 0000000000000002 x4 : 0000000000000001 +[ 103.296262] x3 : 0000000000000001 x2 : 0000000000000001 +[ 103.301572] x1 : 0000000000000000 x0 : 0000000000000011 +[ 103.306882] Call trace: +[ 103.309328] mt7915_get_phy_mode+0x68/0x120 [mt7915e] +[ 103.314378] mt7915_bss_info_changed+0x198/0x200 [mt7915e] +[ 103.319941] ieee80211_bss_info_change_notify+0x128/0x290 [mac80211] +[ 103.326360] __ieee80211_sta_join_ibss+0x308/0x6c4 [mac80211] +[ 103.332171] ieee80211_sta_create_ibss+0x8c/0x10c [mac80211] +[ 103.337895] ieee80211_ibss_work+0x3dc/0x614 [mac80211] +[ 103.343185] ieee80211_iface_work+0x388/0x3f0 [mac80211] +[ 103.348495] process_one_work+0x288/0x690 +[ 103.352499] worker_thread+0x70/0x464 +[ 103.356157] kthread+0x144/0x150 +[ 103.359380] ret_from_fork+0x10/0x18 +[ 103.362952] Code: 394008c3 52800220 394000e4 7100007f (39400023) + +Fixes: 37f4ca907c46 ("mt76: mt7915: register per-phy HE capabilities for each interface") +Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") +Signed-off-by: Lorenzo Bianconi +Acked-by: Felix Fietkau +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/ddae419a740f1fb9e48afd432035e9f394f512ee.1637239456.git.lorenzo@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +@@ -182,7 +182,7 @@ mt7915_get_phy_mode(struct mt7915_dev *d + if (ht_cap->ht_supported) + mode |= PHY_MODE_GN; + +- if (he_cap->has_he) ++ if (he_cap && he_cap->has_he) + mode |= PHY_MODE_AX_24G; + } else if (band == NL80211_BAND_5GHZ) { + mode |= PHY_MODE_A; +@@ -193,7 +193,7 @@ mt7915_get_phy_mode(struct mt7915_dev *d + if (vht_cap->vht_supported) + mode |= PHY_MODE_AC; + +- if (he_cap->has_he) ++ if (he_cap && he_cap->has_he) + mode |= PHY_MODE_AX_5G; + } + diff --git a/queue-5.10/net-annotate-data-races-on-txq-xmit_lock_owner.patch b/queue-5.10/net-annotate-data-races-on-txq-xmit_lock_owner.patch new file mode 100644 index 00000000000..cff935a663b --- /dev/null +++ b/queue-5.10/net-annotate-data-races-on-txq-xmit_lock_owner.patch @@ -0,0 +1,193 @@ +From 7a10d8c810cfad3e79372d7d1c77899d86cd6662 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 30 Nov 2021 09:01:55 -0800 +Subject: net: annotate data-races on txq->xmit_lock_owner + +From: Eric Dumazet + +commit 7a10d8c810cfad3e79372d7d1c77899d86cd6662 upstream. + +syzbot found that __dev_queue_xmit() is reading txq->xmit_lock_owner +without annotations. + +No serious issue there, let's document what is happening there. + +BUG: KCSAN: data-race in __dev_queue_xmit / __dev_queue_xmit + +write to 0xffff888139d09484 of 4 bytes by interrupt on cpu 0: + __netif_tx_unlock include/linux/netdevice.h:4437 [inline] + __dev_queue_xmit+0x948/0xf70 net/core/dev.c:4229 + dev_queue_xmit_accel+0x19/0x20 net/core/dev.c:4265 + macvlan_queue_xmit drivers/net/macvlan.c:543 [inline] + macvlan_start_xmit+0x2b3/0x3d0 drivers/net/macvlan.c:567 + __netdev_start_xmit include/linux/netdevice.h:4987 [inline] + netdev_start_xmit include/linux/netdevice.h:5001 [inline] + xmit_one+0x105/0x2f0 net/core/dev.c:3590 + dev_hard_start_xmit+0x72/0x120 net/core/dev.c:3606 + sch_direct_xmit+0x1b2/0x7c0 net/sched/sch_generic.c:342 + __dev_xmit_skb+0x83d/0x1370 net/core/dev.c:3817 + __dev_queue_xmit+0x590/0xf70 net/core/dev.c:4194 + dev_queue_xmit+0x13/0x20 net/core/dev.c:4259 + neigh_hh_output include/net/neighbour.h:511 [inline] + neigh_output include/net/neighbour.h:525 [inline] + ip6_finish_output2+0x995/0xbb0 net/ipv6/ip6_output.c:126 + __ip6_finish_output net/ipv6/ip6_output.c:191 [inline] + ip6_finish_output+0x444/0x4c0 net/ipv6/ip6_output.c:201 + NF_HOOK_COND include/linux/netfilter.h:296 [inline] + ip6_output+0x10e/0x210 net/ipv6/ip6_output.c:224 + dst_output include/net/dst.h:450 [inline] + NF_HOOK include/linux/netfilter.h:307 [inline] + ndisc_send_skb+0x486/0x610 net/ipv6/ndisc.c:508 + ndisc_send_rs+0x3b0/0x3e0 net/ipv6/ndisc.c:702 + addrconf_rs_timer+0x370/0x540 net/ipv6/addrconf.c:3898 + call_timer_fn+0x2e/0x240 kernel/time/timer.c:1421 + expire_timers+0x116/0x240 kernel/time/timer.c:1466 + __run_timers+0x368/0x410 kernel/time/timer.c:1734 + run_timer_softirq+0x2e/0x60 kernel/time/timer.c:1747 + __do_softirq+0x158/0x2de kernel/softirq.c:558 + __irq_exit_rcu kernel/softirq.c:636 [inline] + irq_exit_rcu+0x37/0x70 kernel/softirq.c:648 + sysvec_apic_timer_interrupt+0x3e/0xb0 arch/x86/kernel/apic/apic.c:1097 + asm_sysvec_apic_timer_interrupt+0x12/0x20 + +read to 0xffff888139d09484 of 4 bytes by interrupt on cpu 1: + __dev_queue_xmit+0x5e3/0xf70 net/core/dev.c:4213 + dev_queue_xmit_accel+0x19/0x20 net/core/dev.c:4265 + macvlan_queue_xmit drivers/net/macvlan.c:543 [inline] + macvlan_start_xmit+0x2b3/0x3d0 drivers/net/macvlan.c:567 + __netdev_start_xmit include/linux/netdevice.h:4987 [inline] + netdev_start_xmit include/linux/netdevice.h:5001 [inline] + xmit_one+0x105/0x2f0 net/core/dev.c:3590 + dev_hard_start_xmit+0x72/0x120 net/core/dev.c:3606 + sch_direct_xmit+0x1b2/0x7c0 net/sched/sch_generic.c:342 + __dev_xmit_skb+0x83d/0x1370 net/core/dev.c:3817 + __dev_queue_xmit+0x590/0xf70 net/core/dev.c:4194 + dev_queue_xmit+0x13/0x20 net/core/dev.c:4259 + neigh_resolve_output+0x3db/0x410 net/core/neighbour.c:1523 + neigh_output include/net/neighbour.h:527 [inline] + ip6_finish_output2+0x9be/0xbb0 net/ipv6/ip6_output.c:126 + __ip6_finish_output net/ipv6/ip6_output.c:191 [inline] + ip6_finish_output+0x444/0x4c0 net/ipv6/ip6_output.c:201 + NF_HOOK_COND include/linux/netfilter.h:296 [inline] + ip6_output+0x10e/0x210 net/ipv6/ip6_output.c:224 + dst_output include/net/dst.h:450 [inline] + NF_HOOK include/linux/netfilter.h:307 [inline] + ndisc_send_skb+0x486/0x610 net/ipv6/ndisc.c:508 + ndisc_send_rs+0x3b0/0x3e0 net/ipv6/ndisc.c:702 + addrconf_rs_timer+0x370/0x540 net/ipv6/addrconf.c:3898 + call_timer_fn+0x2e/0x240 kernel/time/timer.c:1421 + expire_timers+0x116/0x240 kernel/time/timer.c:1466 + __run_timers+0x368/0x410 kernel/time/timer.c:1734 + run_timer_softirq+0x2e/0x60 kernel/time/timer.c:1747 + __do_softirq+0x158/0x2de kernel/softirq.c:558 + __irq_exit_rcu kernel/softirq.c:636 [inline] + irq_exit_rcu+0x37/0x70 kernel/softirq.c:648 + sysvec_apic_timer_interrupt+0x8d/0xb0 arch/x86/kernel/apic/apic.c:1097 + asm_sysvec_apic_timer_interrupt+0x12/0x20 + kcsan_setup_watchpoint+0x94/0x420 kernel/kcsan/core.c:443 + folio_test_anon include/linux/page-flags.h:581 [inline] + PageAnon include/linux/page-flags.h:586 [inline] + zap_pte_range+0x5ac/0x10e0 mm/memory.c:1347 + zap_pmd_range mm/memory.c:1467 [inline] + zap_pud_range mm/memory.c:1496 [inline] + zap_p4d_range mm/memory.c:1517 [inline] + unmap_page_range+0x2dc/0x3d0 mm/memory.c:1538 + unmap_single_vma+0x157/0x210 mm/memory.c:1583 + unmap_vmas+0xd0/0x180 mm/memory.c:1615 + exit_mmap+0x23d/0x470 mm/mmap.c:3170 + __mmput+0x27/0x1b0 kernel/fork.c:1113 + mmput+0x3d/0x50 kernel/fork.c:1134 + exit_mm+0xdb/0x170 kernel/exit.c:507 + do_exit+0x608/0x17a0 kernel/exit.c:819 + do_group_exit+0xce/0x180 kernel/exit.c:929 + get_signal+0xfc3/0x1550 kernel/signal.c:2852 + arch_do_signal_or_restart+0x8c/0x2e0 arch/x86/kernel/signal.c:868 + handle_signal_work kernel/entry/common.c:148 [inline] + exit_to_user_mode_loop kernel/entry/common.c:172 [inline] + exit_to_user_mode_prepare+0x113/0x190 kernel/entry/common.c:207 + __syscall_exit_to_user_mode_work kernel/entry/common.c:289 [inline] + syscall_exit_to_user_mode+0x20/0x40 kernel/entry/common.c:300 + do_syscall_64+0x50/0xd0 arch/x86/entry/common.c:86 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +value changed: 0x00000000 -> 0xffffffff + +Reported by Kernel Concurrency Sanitizer on: +CPU: 1 PID: 28712 Comm: syz-executor.0 Tainted: G W 5.16.0-rc1-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Link: https://lore.kernel.org/r/20211130170155.2331929-1-eric.dumazet@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/netdevice.h | 19 +++++++++++++------ + net/core/dev.c | 5 ++++- + 2 files changed, 17 insertions(+), 7 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4212,7 +4212,8 @@ static inline u32 netif_msg_init(int deb + static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) + { + spin_lock(&txq->_xmit_lock); +- txq->xmit_lock_owner = cpu; ++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */ ++ WRITE_ONCE(txq->xmit_lock_owner, cpu); + } + + static inline bool __netif_tx_acquire(struct netdev_queue *txq) +@@ -4229,26 +4230,32 @@ static inline void __netif_tx_release(st + static inline void __netif_tx_lock_bh(struct netdev_queue *txq) + { + spin_lock_bh(&txq->_xmit_lock); +- txq->xmit_lock_owner = smp_processor_id(); ++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */ ++ WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id()); + } + + static inline bool __netif_tx_trylock(struct netdev_queue *txq) + { + bool ok = spin_trylock(&txq->_xmit_lock); +- if (likely(ok)) +- txq->xmit_lock_owner = smp_processor_id(); ++ ++ if (likely(ok)) { ++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */ ++ WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id()); ++ } + return ok; + } + + static inline void __netif_tx_unlock(struct netdev_queue *txq) + { +- txq->xmit_lock_owner = -1; ++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */ ++ WRITE_ONCE(txq->xmit_lock_owner, -1); + spin_unlock(&txq->_xmit_lock); + } + + static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) + { +- txq->xmit_lock_owner = -1; ++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */ ++ WRITE_ONCE(txq->xmit_lock_owner, -1); + spin_unlock_bh(&txq->_xmit_lock); + } + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4147,7 +4147,10 @@ static int __dev_queue_xmit(struct sk_bu + if (dev->flags & IFF_UP) { + int cpu = smp_processor_id(); /* ok because BHs are off */ + +- if (txq->xmit_lock_owner != cpu) { ++ /* Other cpus might concurrently change txq->xmit_lock_owner ++ * to -1 or to their cpu id, but not to our id. ++ */ ++ if (READ_ONCE(txq->xmit_lock_owner) != cpu) { + if (dev_xmit_recursion()) + goto recursion_alert; + diff --git a/queue-5.10/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch b/queue-5.10/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch new file mode 100644 index 00000000000..3940dc69f56 --- /dev/null +++ b/queue-5.10/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch @@ -0,0 +1,33 @@ +From b83f5ac7d922e69a109261f5f940eebbd4e514c4 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Mon, 29 Nov 2021 22:53:27 +0100 +Subject: net: marvell: mvpp2: Fix the computation of shared CPUs + +From: Christophe JAILLET + +commit b83f5ac7d922e69a109261f5f940eebbd4e514c4 upstream. + +'bitmap_fill()' fills a bitmap one 'long' at a time. +It is likely that an exact number of bits is expected. + +Use 'bitmap_set()' instead in order not to set unexpected bits. + +Fixes: e531f76757eb ("net: mvpp2: handle cases where more CPUs are available than s/w threads") +Signed-off-by: Christophe JAILLET +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -6918,7 +6918,7 @@ static int mvpp2_probe(struct platform_d + + shared = num_present_cpus() - priv->nthreads; + if (shared > 0) +- bitmap_fill(&priv->lock_map, ++ bitmap_set(&priv->lock_map, 0, + min_t(int, shared, MVPP2_MAX_THREADS)); + + for (i = 0; i < MVPP2_MAX_THREADS; i++) { diff --git a/queue-5.10/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch b/queue-5.10/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch new file mode 100644 index 00000000000..95f68b92bf4 --- /dev/null +++ b/queue-5.10/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch @@ -0,0 +1,59 @@ +From addad7643142f500080417dd7272f49b7a185570 Mon Sep 17 00:00:00 2001 +From: Zhou Qingyang +Date: Wed, 1 Dec 2021 00:44:38 +0800 +Subject: net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources() + +From: Zhou Qingyang + +commit addad7643142f500080417dd7272f49b7a185570 upstream. + +In mlx4_en_try_alloc_resources(), mlx4_en_copy_priv() is called and +tmp->tx_cq will be freed on the error path of mlx4_en_copy_priv(). +After that mlx4_en_alloc_resources() is called and there is a dereference +of &tmp->tx_cq[t][i] in mlx4_en_alloc_resources(), which could lead to +a use after free problem on failure of mlx4_en_copy_priv(). + +Fix this bug by adding a check of mlx4_en_copy_priv() + +This bug was found by a static analyzer. The analysis employs +differential checking to identify inconsistent security operations +(e.g., checks or kfrees) between two code paths and confirms that the +inconsistent operations are not recovered in the current function or +the callers, so they constitute bugs. + +Note that, as a bug found by static analysis, it can be a false +positive or hard to trigger. Multiple researchers have cross-reviewed +the bug. + +Builds with CONFIG_MLX4_EN=m show no new warnings, +and our static analyzer no longer warns about this code. + +Fixes: ec25bc04ed8e ("net/mlx4_en: Add resilience in low memory systems") +Signed-off-by: Zhou Qingyang +Reviewed-by: Leon Romanovsky +Link: https://lore.kernel.org/r/20211130164438.190591-1-zhou1615@umn.edu +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -2276,9 +2276,14 @@ int mlx4_en_try_alloc_resources(struct m + bool carry_xdp_prog) + { + struct bpf_prog *xdp_prog; +- int i, t; ++ int i, t, ret; + +- mlx4_en_copy_priv(tmp, priv, prof); ++ ret = mlx4_en_copy_priv(tmp, priv, prof); ++ if (ret) { ++ en_warn(priv, "%s: mlx4_en_copy_priv() failed, return\n", ++ __func__); ++ return ret; ++ } + + if (mlx4_en_alloc_resources(tmp)) { + en_warn(priv, diff --git a/queue-5.10/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch b/queue-5.10/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch new file mode 100644 index 00000000000..7d23aa3611c --- /dev/null +++ b/queue-5.10/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch @@ -0,0 +1,32 @@ +From 19f36edf14bcdb783aef3af8217df96f76a8ce34 Mon Sep 17 00:00:00 2001 +From: William Kucharski +Date: Wed, 1 Dec 2021 07:45:22 -0700 +Subject: net/rds: correct socket tunable error in rds_tcp_tune() + +From: William Kucharski + +commit 19f36edf14bcdb783aef3af8217df96f76a8ce34 upstream. + +Correct an error where setting /proc/sys/net/rds/tcp/rds_tcp_rcvbuf would +instead modify the socket's sk_sndbuf and would leave sk_rcvbuf untouched. + +Fixes: c6a58ffed536 ("RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket") +Signed-off-by: William Kucharski +Acked-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rds/tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/rds/tcp.c ++++ b/net/rds/tcp.c +@@ -500,7 +500,7 @@ void rds_tcp_tune(struct socket *sock) + sk->sk_userlocks |= SOCK_SNDBUF_LOCK; + } + if (rtn->rcvbuf_size > 0) { +- sk->sk_sndbuf = rtn->rcvbuf_size; ++ sk->sk_rcvbuf = rtn->rcvbuf_size; + sk->sk_userlocks |= SOCK_RCVBUF_LOCK; + } + release_sock(sk); diff --git a/queue-5.10/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch b/queue-5.10/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch new file mode 100644 index 00000000000..9fe65fc0921 --- /dev/null +++ b/queue-5.10/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch @@ -0,0 +1,89 @@ +From 789b6cc2a5f9123b9c549b886fdc47c865cfe0ba Mon Sep 17 00:00:00 2001 +From: Dust Li +Date: Wed, 1 Dec 2021 11:02:30 +0800 +Subject: net/smc: fix wrong list_del in smc_lgr_cleanup_early +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dust Li + +commit 789b6cc2a5f9123b9c549b886fdc47c865cfe0ba upstream. + +smc_lgr_cleanup_early() meant to delete the link +group from the link group list, but it deleted +the list head by mistake. + +This may cause memory corruption since we didn't +remove the real link group from the list and later +memseted the link group structure. +We got a list corruption panic when testing: + +[  231.277259] list_del corruption. prev->next should be ffff8881398a8000, but was 0000000000000000 +[  231.278222] ------------[ cut here ]------------ +[  231.278726] kernel BUG at lib/list_debug.c:53! +[  231.279326] invalid opcode: 0000 [#1] SMP NOPTI +[  231.279803] CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.10.46+ #435 +[  231.280466] Hardware name: Alibaba Cloud ECS, BIOS 8c24b4c 04/01/2014 +[  231.281248] Workqueue: events smc_link_down_work +[  231.281732] RIP: 0010:__list_del_entry_valid+0x70/0x90 +[  231.282258] Code: 4c 60 82 e8 7d cc 6a 00 0f 0b 48 89 fe 48 c7 c7 88 4c +60 82 e8 6c cc 6a 00 0f 0b 48 89 fe 48 c7 c7 c0 4c 60 82 e8 5b cc 6a 00 <0f> +0b 48 89 fe 48 c7 c7 00 4d 60 82 e8 4a cc 6a 00 0f 0b cc cc cc +[  231.284146] RSP: 0018:ffffc90000033d58 EFLAGS: 00010292 +[  231.284685] RAX: 0000000000000054 RBX: ffff8881398a8000 RCX: 0000000000000000 +[  231.285415] RDX: 0000000000000001 RSI: ffff88813bc18040 RDI: ffff88813bc18040 +[  231.286141] RBP: ffffffff8305ad40 R08: 0000000000000003 R09: 0000000000000001 +[  231.286873] R10: ffffffff82803da0 R11: ffffc90000033b90 R12: 0000000000000001 +[  231.287606] R13: 0000000000000000 R14: ffff8881398a8000 R15: 0000000000000003 +[  231.288337] FS:  0000000000000000(0000) GS:ffff88813bc00000(0000) knlGS:0000000000000000 +[  231.289160] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[  231.289754] CR2: 0000000000e72058 CR3: 000000010fa96006 CR4: 00000000003706f0 +[  231.290485] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[  231.291211] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[  231.291940] Call Trace: +[  231.292211]  smc_lgr_terminate_sched+0x53/0xa0 +[  231.292677]  smc_switch_conns+0x75/0x6b0 +[  231.293085]  ? update_load_avg+0x1a6/0x590 +[  231.293517]  ? ttwu_do_wakeup+0x17/0x150 +[  231.293907]  ? update_load_avg+0x1a6/0x590 +[  231.294317]  ? newidle_balance+0xca/0x3d0 +[  231.294716]  smcr_link_down+0x50/0x1a0 +[  231.295090]  ? __wake_up_common_lock+0x77/0x90 +[  231.295534]  smc_link_down_work+0x46/0x60 +[  231.295933]  process_one_work+0x18b/0x350 + +Fixes: a0a62ee15a829 ("net/smc: separate locks for SMCD and SMCR link group lists") +Signed-off-by: Dust Li +Acked-by: Karsten Graul +Reviewed-by: Tony Lu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/smc/smc_core.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/net/smc/smc_core.c ++++ b/net/smc/smc_core.c +@@ -204,18 +204,17 @@ static void smc_lgr_unregister_conn(stru + void smc_lgr_cleanup_early(struct smc_connection *conn) + { + struct smc_link_group *lgr = conn->lgr; +- struct list_head *lgr_list; + spinlock_t *lgr_lock; + + if (!lgr) + return; + + smc_conn_free(conn); +- lgr_list = smc_lgr_list_head(lgr, &lgr_lock); ++ smc_lgr_list_head(lgr, &lgr_lock); + spin_lock_bh(lgr_lock); + /* do not use this link group for new connections */ +- if (!list_empty(lgr_list)) +- list_del_init(lgr_list); ++ if (!list_empty(&lgr->list)) ++ list_del_init(&lgr->list); + spin_unlock_bh(lgr_lock); + __smc_lgr_terminate(lgr, true); + } diff --git a/queue-5.10/net-smc-keep-smc_close_final-rc-during-active-close.patch b/queue-5.10/net-smc-keep-smc_close_final-rc-during-active-close.patch new file mode 100644 index 00000000000..83daeebfaea --- /dev/null +++ b/queue-5.10/net-smc-keep-smc_close_final-rc-during-active-close.patch @@ -0,0 +1,53 @@ +From 00e158fb91dfaff3f94746f260d11f1a4853506e Mon Sep 17 00:00:00 2001 +From: Tony Lu +Date: Wed, 1 Dec 2021 14:42:16 +0800 +Subject: net/smc: Keep smc_close_final rc during active close + +From: Tony Lu + +commit 00e158fb91dfaff3f94746f260d11f1a4853506e upstream. + +When smc_close_final() returns error, the return code overwrites by +kernel_sock_shutdown() in smc_close_active(). The return code of +smc_close_final() is more important than kernel_sock_shutdown(), and it +will pass to userspace directly. + +Fix it by keeping both return codes, if smc_close_final() raises an +error, return it or kernel_sock_shutdown()'s. + +Link: https://lore.kernel.org/linux-s390/1f67548e-cbf6-0dce-82b5-10288a4583bd@linux.ibm.com/ +Fixes: 606a63c9783a ("net/smc: Ensure the active closing peer first closes clcsock") +Suggested-by: Karsten Graul +Signed-off-by: Tony Lu +Reviewed-by: Wen Gu +Acked-by: Karsten Graul +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/smc/smc_close.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/smc/smc_close.c ++++ b/net/smc/smc_close.c +@@ -195,6 +195,7 @@ int smc_close_active(struct smc_sock *sm + int old_state; + long timeout; + int rc = 0; ++ int rc1 = 0; + + timeout = current->flags & PF_EXITING ? + 0 : sock_flag(sk, SOCK_LINGER) ? +@@ -232,8 +233,11 @@ again: + /* actively shutdown clcsock before peer close it, + * prevent peer from entering TIME_WAIT state. + */ +- if (smc->clcsock && smc->clcsock->sk) +- rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); ++ if (smc->clcsock && smc->clcsock->sk) { ++ rc1 = kernel_sock_shutdown(smc->clcsock, ++ SHUT_RDWR); ++ rc = rc ? rc : rc1; ++ } + } else { + /* peer event has changed the state */ + goto again; diff --git a/queue-5.10/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch b/queue-5.10/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch new file mode 100644 index 00000000000..d092153d600 --- /dev/null +++ b/queue-5.10/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch @@ -0,0 +1,33 @@ +From 817b653160db9852d5a0498a31f047e18ce27e5b Mon Sep 17 00:00:00 2001 +From: Sven Schuchmann +Date: Sat, 27 Nov 2021 11:47:07 +0100 +Subject: net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ is available + +From: Sven Schuchmann + +commit 817b653160db9852d5a0498a31f047e18ce27e5b upstream. + +On most systems request for IRQ 0 will fail, phylib will print an error message +and fall back to polling. To fix this set the phydev->irq to PHY_POLL if no IRQ +is available. + +Fixes: cc89c323a30e ("lan78xx: Use irq_domain for phy interrupt from USB Int. EP") +Reviewed-by: Andrew Lunn +Signed-off-by: Sven Schuchmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/lan78xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2128,7 +2128,7 @@ static int lan78xx_phy_init(struct lan78 + if (dev->domain_data.phyirq > 0) + phydev->irq = dev->domain_data.phyirq; + else +- phydev->irq = 0; ++ phydev->irq = PHY_POLL; + netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq); + + /* set to AUTOMDIX */ diff --git a/queue-5.10/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch b/queue-5.10/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch new file mode 100644 index 00000000000..4082464ef4b --- /dev/null +++ b/queue-5.10/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch @@ -0,0 +1,69 @@ +From beacff50edbd6c9659a6f15fc7f6126909fade29 Mon Sep 17 00:00:00 2001 +From: Eiichi Tsukata +Date: Sun, 21 Nov 2021 04:16:08 +0000 +Subject: rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer() + +From: Eiichi Tsukata + +commit beacff50edbd6c9659a6f15fc7f6126909fade29 upstream. + +Need to call rxrpc_put_local() for peer candidate before kfree() as it +holds a ref to rxrpc_local. + +[DH: v2: Changed to abstract the peer freeing code out into a function] + +Fixes: 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record") +Signed-off-by: Eiichi Tsukata +Signed-off-by: David Howells +Reviewed-by: Marc Dionne +cc: linux-afs@lists.infradead.org +Link: https://lore.kernel.org/all/20211121041608.133740-2-eiichi.tsukata@nutanix.com/ # v1 +Signed-off-by: Greg Kroah-Hartman +--- + net/rxrpc/peer_object.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/net/rxrpc/peer_object.c ++++ b/net/rxrpc/peer_object.c +@@ -299,6 +299,12 @@ static struct rxrpc_peer *rxrpc_create_p + return peer; + } + ++static void rxrpc_free_peer(struct rxrpc_peer *peer) ++{ ++ rxrpc_put_local(peer->local); ++ kfree_rcu(peer, rcu); ++} ++ + /* + * Set up a new incoming peer. There shouldn't be any other matching peers + * since we've already done a search in the list from the non-reentrant context +@@ -365,7 +371,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(str + spin_unlock_bh(&rxnet->peer_hash_lock); + + if (peer) +- kfree(candidate); ++ rxrpc_free_peer(candidate); + else + peer = candidate; + } +@@ -420,8 +426,7 @@ static void __rxrpc_put_peer(struct rxrp + list_del_init(&peer->keepalive_link); + spin_unlock_bh(&rxnet->peer_hash_lock); + +- rxrpc_put_local(peer->local); +- kfree_rcu(peer, rcu); ++ rxrpc_free_peer(peer); + } + + /* +@@ -457,8 +462,7 @@ void rxrpc_put_peer_locked(struct rxrpc_ + if (n == 0) { + hash_del_rcu(&peer->hash_link); + list_del_init(&peer->keepalive_link); +- rxrpc_put_local(peer->local); +- kfree_rcu(peer, rcu); ++ rxrpc_free_peer(peer); + } + } + diff --git a/queue-5.10/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch b/queue-5.10/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch new file mode 100644 index 00000000000..6f4528dabbd --- /dev/null +++ b/queue-5.10/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch @@ -0,0 +1,61 @@ +From ca77fba821351190777b236ce749d7c4d353102e Mon Sep 17 00:00:00 2001 +From: Eiichi Tsukata +Date: Sun, 21 Nov 2021 04:16:07 +0000 +Subject: rxrpc: Fix rxrpc_peer leak in rxrpc_look_up_bundle() + +From: Eiichi Tsukata + +commit ca77fba821351190777b236ce749d7c4d353102e upstream. + +Need to call rxrpc_put_peer() for bundle candidate before kfree() as it +holds a ref to rxrpc_peer. + +[DH: v2: Changed to abstract out the bundle freeing code into a function] + +Fixes: 245500d853e9 ("rxrpc: Rewrite the client connection manager") +Signed-off-by: Eiichi Tsukata +Signed-off-by: David Howells +Reviewed-by: Marc Dionne +cc: linux-afs@lists.infradead.org +Link: https://lore.kernel.org/r/20211121041608.133740-1-eiichi.tsukata@nutanix.com/ # v1 +Signed-off-by: Greg Kroah-Hartman +--- + net/rxrpc/conn_client.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/net/rxrpc/conn_client.c ++++ b/net/rxrpc/conn_client.c +@@ -135,16 +135,20 @@ struct rxrpc_bundle *rxrpc_get_bundle(st + return bundle; + } + ++static void rxrpc_free_bundle(struct rxrpc_bundle *bundle) ++{ ++ rxrpc_put_peer(bundle->params.peer); ++ kfree(bundle); ++} ++ + void rxrpc_put_bundle(struct rxrpc_bundle *bundle) + { + unsigned int d = bundle->debug_id; + unsigned int u = atomic_dec_return(&bundle->usage); + + _debug("PUT B=%x %u", d, u); +- if (u == 0) { +- rxrpc_put_peer(bundle->params.peer); +- kfree(bundle); +- } ++ if (u == 0) ++ rxrpc_free_bundle(bundle); + } + + /* +@@ -334,7 +338,7 @@ static struct rxrpc_bundle *rxrpc_look_u + return candidate; + + found_bundle_free: +- kfree(candidate); ++ rxrpc_free_bundle(candidate); + found_bundle: + rxrpc_get_bundle(bundle); + spin_unlock(&local->client_bundles_lock); diff --git a/queue-5.10/selftests-net-correct-case-name.patch b/queue-5.10/selftests-net-correct-case-name.patch new file mode 100644 index 00000000000..4d327fba0f0 --- /dev/null +++ b/queue-5.10/selftests-net-correct-case-name.patch @@ -0,0 +1,34 @@ +From a05431b22be819d75db72ca3d44381d18a37b092 Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Thu, 2 Dec 2021 10:28:41 +0800 +Subject: selftests: net: Correct case name + +From: Li Zhijian + +commit a05431b22be819d75db72ca3d44381d18a37b092 upstream. + +ipv6_addr_bind/ipv4_addr_bind are function names. Previously, bind test +would not be run by default due to the wrong case names + +Fixes: 34d0302ab861 ("selftests: Add ipv6 address bind tests to fcnal-test") +Fixes: 75b2b2b3db4c ("selftests: Add ipv4 address bind tests to fcnal-test") +Signed-off-by: Li Zhijian +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/fcnal-test.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/tools/testing/selftests/net/fcnal-test.sh ++++ b/tools/testing/selftests/net/fcnal-test.sh +@@ -3911,8 +3911,8 @@ EOF + ################################################################################ + # main + +-TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime ipv4_netfilter" +-TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime ipv6_netfilter" ++TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_bind ipv4_runtime ipv4_netfilter" ++TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_bind ipv6_runtime ipv6_netfilter" + TESTS_OTHER="use_cases" + + PAUSE_ON_FAIL=no diff --git a/queue-5.10/series b/queue-5.10/series index c9422636709..05d36432298 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -67,3 +67,29 @@ tcp-fix-page-frag-corruption-on-page-fault.patch net-qlogic-qlcnic-fix-a-null-pointer-dereference-in-qlcnic_83xx_add_rings.patch net-mpls-fix-notifications-when-deleting-a-device.patch siphash-use-_unaligned-version-by-default.patch +arm64-ftrace-add-missing-btis.patch +net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch +selftests-net-correct-case-name.patch +mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch +asoc-tegra-fix-wrong-value-type-in-admaif.patch +asoc-tegra-fix-wrong-value-type-in-i2s.patch +asoc-tegra-fix-wrong-value-type-in-dmic.patch +asoc-tegra-fix-wrong-value-type-in-dspk.patch +asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch +asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch +asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch +asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch +asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch +rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch +rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch +alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch +net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch +net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch +dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch +net-annotate-data-races-on-txq-xmit_lock_owner.patch +ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch +net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch +net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch +net-smc-keep-smc_close_final-rc-during-active-close.patch +drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch +drm-msm-do-hw_init-before-capturing-gpu-state.patch -- 2.47.2